* [PATCH 4/4] ARM: dts: imx: drop 'clocks' container for board level clocks
From: Shawn Guo @ 2018-05-04 0:57 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1525395446-1953-1-git-send-email-shawnguo@kernel.org>
For soc level of clocks which are input to Clock Control Module, clock
driver expects them to be under 'clocks' container node. But for board
level clocks, this container is not really necessary. Let's drop it and
use an unique name for fixed rate clock, so that 'reg' property can be
saved as well.
Signed-off-by: Shawn Guo <shawnguo@kernel.org>
---
arch/arm/boot/dts/imx28-tx28.dts | 13 ++++---------
arch/arm/boot/dts/imx53-tx53.dtsi | 11 +++++------
arch/arm/boot/dts/imx6dl-colibri-eval-v3.dts | 15 ++++++---------
arch/arm/boot/dts/imx6q-bx50v3.dtsi | 11 ++++-------
4 files changed, 19 insertions(+), 31 deletions(-)
diff --git a/arch/arm/boot/dts/imx28-tx28.dts b/arch/arm/boot/dts/imx28-tx28.dts
index 687186358c18..e4f19f9be6d0 100644
--- a/arch/arm/boot/dts/imx28-tx28.dts
+++ b/arch/arm/boot/dts/imx28-tx28.dts
@@ -140,15 +140,10 @@
regulator-boot-on;
};
- clocks {
- #address-cells = <1>;
- #size-cells = <0>;
- mclk: clock at 0 {
- compatible = "fixed-clock";
- reg = <0>;
- #clock-cells = <0>;
- clock-frequency = <26000000>;
- };
+ mclk: clock-mclk {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <26000000>;
};
sound {
diff --git a/arch/arm/boot/dts/imx53-tx53.dtsi b/arch/arm/boot/dts/imx53-tx53.dtsi
index 77f2ce9f1e41..5dd3dd3a2fd0 100644
--- a/arch/arm/boot/dts/imx53-tx53.dtsi
+++ b/arch/arm/boot/dts/imx53-tx53.dtsi
@@ -67,13 +67,12 @@
ckih1 {
clock-frequency = <0>;
};
+ };
- mclk: clock at 0 {
- compatible = "fixed-clock";
- reg = <0>;
- #clock-cells = <0>;
- clock-frequency = <26000000>;
- };
+ mclk: clock-mclk {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <26000000>;
};
gpio-keys {
diff --git a/arch/arm/boot/dts/imx6dl-colibri-eval-v3.dts b/arch/arm/boot/dts/imx6dl-colibri-eval-v3.dts
index ea184d108491..3dee3af1a4c1 100644
--- a/arch/arm/boot/dts/imx6dl-colibri-eval-v3.dts
+++ b/arch/arm/boot/dts/imx6dl-colibri-eval-v3.dts
@@ -72,15 +72,12 @@
stdout-path = "serial0:115200n8";
};
- clocks {
- /* Fixed crystal dedicated to mcp251x */
- clk16m: clk at 1 {
- compatible = "fixed-clock";
- reg = <1>;
- #clock-cells = <0>;
- clock-frequency = <16000000>;
- clock-output-names = "clk16m";
- };
+ /* Fixed crystal dedicated to mcp251x */
+ clk16m: clock-16m {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <16000000>;
+ clock-output-names = "clk16m";
};
gpio-keys {
diff --git a/arch/arm/boot/dts/imx6q-bx50v3.dtsi b/arch/arm/boot/dts/imx6q-bx50v3.dtsi
index d0e7dab4d72b..d3cba09be0cb 100644
--- a/arch/arm/boot/dts/imx6q-bx50v3.dtsi
+++ b/arch/arm/boot/dts/imx6q-bx50v3.dtsi
@@ -43,13 +43,10 @@
#include "imx6q-ba16.dtsi"
/ {
- clocks {
- mclk: clock at 0 {
- compatible = "fixed-clock";
- reg = <0>;
- #clock-cells = <0>;
- clock-frequency = <22000000>;
- };
+ mclk: clock-mclk {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <22000000>;
};
gpio-poweroff {
--
1.9.1
^ permalink raw reply related
* [PATCH v9 0/2] Initial Allwinner V3s CSI Support
From: Yong @ 2018-05-04 1:19 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180503171410.q52ak27u47gycy6o@flea>
Hi Maxime,
On Thu, 3 May 2018 19:14:10 +0200
Maxime Ripard <maxime.ripard@bootlin.com> wrote:
> Hi Yong,
>
> On Tue, Mar 06, 2018 at 09:51:10AM +0800, Yong Deng wrote:
> > This patchset add initial support for Allwinner V3s CSI.
> >
> > Allwinner V3s SoC features two CSI module. CSI0 is used for MIPI CSI-2
> > interface and CSI1 is used for parallel interface. This is not
> > documented in datasheet but by test and guess.
> >
> > This patchset implement a v4l2 framework driver and add a binding
> > documentation for it.
> >
> > Currently, the driver only support the parallel interface. And has been
> > tested with a BT1120 signal which generating from FPGA. The following
> > fetures are not support with this patchset:
> > - ISP
> > - MIPI-CSI2
> > - Master clock for camera sensor
> > - Power regulator for the front end IC
>
> Do you plan on sending another version some time soon? It would be
> awesome to have this in 4.18.
I was waiting for Sakari Ailus's feedback. But ...
I will send a new version soon. But not all suggestion from Sakari Ailus
would be accepted.
>
> Thanks!
> Maxime
>
> --
> Maxime Ripard, Bootlin (formerly Free Electrons)
> Embedded Linux and Kernel engineering
> https://bootlin.com
Thanks,
Yong
^ permalink raw reply
* [PATCH v7 07/24] ASoC: qdsp6: q6common: Add qdsp6 helper functions
From: Banajit Goswami @ 2018-05-04 1:35 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180501120820.11016-8-srinivas.kandagatla@linaro.org>
On 5/1/2018 5:08 AM, Srinivas Kandagatla wrote:
> This patch adds some common helper functions like translating dsp error
> to linux error codes and channel mappings etc.
>
> These functions are used in all the following qdsp6 drivers.
>
> Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
> Reviewed-and-tested-by: Rohit kumar <rohitkr@codeaurora.org>
> ---
> sound/soc/qcom/Kconfig | 13 ++++++++
> sound/soc/qcom/Makefile | 3 ++
> sound/soc/qcom/qdsp6/Makefile | 1 +
> sound/soc/qcom/qdsp6/q6dsp-common.c | 66 +++++++++++++++++++++++++++++++++++++
> sound/soc/qcom/qdsp6/q6dsp-common.h | 24 ++++++++++++++
> sound/soc/qcom/qdsp6/q6dsp-errno.h | 51 ++++++++++++++++++++++++++++
> 6 files changed, 158 insertions(+)
> create mode 100644 sound/soc/qcom/qdsp6/Makefile
> create mode 100644 sound/soc/qcom/qdsp6/q6dsp-common.c
> create mode 100644 sound/soc/qcom/qdsp6/q6dsp-common.h
> create mode 100644 sound/soc/qcom/qdsp6/q6dsp-errno.h
Acked-by: Banajit Goswami <bgoswami@codeaurora.org>
--
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project
^ permalink raw reply
* [PATCH] ARM64: dts: meson-axg: enable AP6255 wifi module
From: Yixun Lan @ 2018-05-04 1:44 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CAOi56cXKmv_Us1wDcMOYbdjFzZcLVu_t210Yrv891wKi22hV8A@mail.gmail.com>
HI Kevin
On 04/30/18 23:35, Kevin Hilman wrote:
> On Fri, Apr 27, 2018 at 6:56 PM, Yixun Lan <yixun.lan@amlogic.com> wrote:
>> On 04/28/18 03:09, Kevin Hilman wrote:
>>> Yixun Lan <yixun.lan@amlogic.com> writes:
>>>
>>>> The Meson-AXG S400 board is shipped with AP6255 wifi module,
>>>> which is actually using the brcmfmac 43455 driver.
>>>>
>>>> Signed-off-by: Yixun Lan <yixun.lan@amlogic.com>
>>>> ---
>>>> .../arm64/boot/dts/amlogic/meson-axg-s400.dts | 44 ++++++++++++++++++-
>>>> 1 file changed, 43 insertions(+), 1 deletion(-)
>>>>
>>>> diff --git a/arch/arm64/boot/dts/amlogic/meson-axg-s400.dts b/arch/arm64/boot/dts/amlogic/meson-axg-s400.dts
>>>> index f67d4e47e641..b3e1bdca32bb 100644
>>>> --- a/arch/arm64/boot/dts/amlogic/meson-axg-s400.dts
>>>> +++ b/arch/arm64/boot/dts/amlogic/meson-axg-s400.dts
>>>> @@ -51,7 +51,16 @@
>>>>
>>>> sdio_pwrseq: sdio-pwrseq {
>>>> compatible = "mmc-pwrseq-simple";
>>>> - reset-gpios = <&gpio GPIOX_6 GPIO_ACTIVE_LOW>;
>>>> + reset-gpios = <&gpio GPIOX_7 GPIO_ACTIVE_LOW>;
>>>
>>> You didn't mention this GPIO change in the changelog. Is it
>>> intentional?
>>
>> Yes, the 'sdio_pwrseq' is used by wifi driver till now
>> previous the reset-gpio is wrongly configured (copy & paste error),
>> according to the schematics, it's GPIOX_7 which need to be fixed here.
>>
>> to be clean, in s400 board
>> GPIOX_6 is WIFI_WAKE_HOST pin
>> GPIOX_7 is WIFI_PWREN pin
>>
>> do you want me to put a note into the commit message? and resend this patch?
>
> OK, thanks for the explanation.
>
> I'd prefer the GPIO pin fix as a separate, standalone patch.
>
> Thanks,
>
> Kevin
>
> .
>
As we already talked offline, this error was introduced exactly in the
v4.18 cycle, so I will send a fix which can be squashed into the old commit
Yixun
^ permalink raw reply
* [PATCH 1/3] spi: meson-axg: support MAX 80M clock
From: Yixun Lan @ 2018-05-04 1:56 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180503231305.GC13402@sirena.org.uk>
Hi Mark
On 05/04/18 07:13, Mark Brown wrote:
> On Thu, May 03, 2018 at 09:36:42PM +0000, Yixun Lan wrote:
>
>> static const struct of_device_id meson_spicc_of_match[] = {
>> - { .compatible = "amlogic,meson-gx-spicc", },
>> - { .compatible = "amlogic,meson-axg-spicc", },
>> + {
>> + .compatible = "amlogic,meson-gx-spicc",
>> + .data = &meson_spicc_gx_data,
>> + },
>> + {
>> + .compatible = "amlogic,meson-axg-spicc",
>> + .data = &meson_spicc_axg_data,
>> + },
>> { /* sentinel */ }
>> };
>> MODULE_DEVICE_TABLE(of, meson_spicc_of_match);
>
> This is changing the DT bindings but there's no update to the DT binding
> documentation, please add an update there.
>
thanks for your comments, but I actually didn't get what's your point here.
Here I only introduce the dt compatible data to differentiate the
old/new controller, the compatible name is not changed, and none of the
property is introduced.
Yixun
^ permalink raw reply
* [RFC PATCH] ARM: dts: imx: replace underscore with hyphen in aliases name
From: Shawn Guo @ 2018-05-04 1:58 UTC (permalink / raw)
To: linux-arm-kernel
It replaces underscore with hyphen in aliases name to fix DTC
alias_paths warning below, which is seen with various i.MX board dts
files when W=1 switch is on.
Warning (alias_paths): /aliases: aliases property name must include only lowercase and '-'
Cc: Lothar Wa?mann <LW@KARO-electronics.de>
Cc: Gary Bisson <gary.bisson@boundarydevices.com>
Signed-off-by: Shawn Guo <shawnguo@kernel.org>
---
Hi Lothar, Gary,
Per my search on kernel code, this change will not break anything on
kernel support. But I'm not really sure about the case of bootloaders
running on the boards. That's why I'm sending it as RFC.
We really want i.MX to be the first-class citizen in the community.
After a few cycles efforts on cleaning up DTC warnings, this alias_paths
warning is the last one we see with i.MX dts files. We really want to
get rid of it and make i.MX dts be DTC warning free.
So please comment whether we can merge this patch.
Shawn
arch/arm/boot/dts/imx53-tx53.dtsi | 2 +-
arch/arm/boot/dts/imx6qdl-tx6.dtsi | 6 +++---
arch/arm/boot/dts/imx6sx-nitrogen6sx.dts | 4 ++--
arch/arm/boot/dts/imx6ul-tx6ul-mainboard.dts | 2 +-
arch/arm/boot/dts/imx6ul-tx6ul.dtsi | 6 +++---
arch/arm/boot/dts/imx7d-nitrogen7.dts | 4 ++--
6 files changed, 12 insertions(+), 12 deletions(-)
diff --git a/arch/arm/boot/dts/imx53-tx53.dtsi b/arch/arm/boot/dts/imx53-tx53.dtsi
index 5dd3dd3a2fd0..54cf3e67069a 100644
--- a/arch/arm/boot/dts/imx53-tx53.dtsi
+++ b/arch/arm/boot/dts/imx53-tx53.dtsi
@@ -58,7 +58,7 @@
can0 = &can2; /* Make the can interface indices consistent with TX28/TX48 modules */
can1 = &can1;
ipu = &ipu;
- reg_can_xcvr = ®_can_xcvr;
+ reg-can-xcvr = ®_can_xcvr;
usbh1 = &usbh1;
usbotg = &usbotg;
};
diff --git a/arch/arm/boot/dts/imx6qdl-tx6.dtsi b/arch/arm/boot/dts/imx6qdl-tx6.dtsi
index f015e2d1cf35..a98fb2564c63 100644
--- a/arch/arm/boot/dts/imx6qdl-tx6.dtsi
+++ b/arch/arm/boot/dts/imx6qdl-tx6.dtsi
@@ -50,11 +50,11 @@
can0 = &can2;
can1 = &can1;
ethernet0 = &fec;
- lcdif_23bit_pins_a = &pinctrl_disp0_1;
- lcdif_24bit_pins_a = &pinctrl_disp0_2;
+ lcdif-23bit-pins-a = &pinctrl_disp0_1;
+ lcdif-24bit-pins-a = &pinctrl_disp0_2;
pwm0 = &pwm1;
pwm1 = &pwm2;
- reg_can_xcvr = ®_can_xcvr;
+ reg-can-xcvr = ®_can_xcvr;
stk5led = &user_led;
usbotg = &usbotg;
sdhc0 = &usdhc1;
diff --git a/arch/arm/boot/dts/imx6sx-nitrogen6sx.dts b/arch/arm/boot/dts/imx6sx-nitrogen6sx.dts
index b58f770c40d9..59e52f504922 100644
--- a/arch/arm/boot/dts/imx6sx-nitrogen6sx.dts
+++ b/arch/arm/boot/dts/imx6sx-nitrogen6sx.dts
@@ -48,8 +48,8 @@
compatible = "boundary,imx6sx-nitrogen6sx", "fsl,imx6sx";
aliases {
- fb_lcd = &lcdif1;
- t_lcd = &t_lcd;
+ fb-lcd = &lcdif1;
+ t-lcd = &t_lcd;
};
memory at 80000000 {
diff --git a/arch/arm/boot/dts/imx6ul-tx6ul-mainboard.dts b/arch/arm/boot/dts/imx6ul-tx6ul-mainboard.dts
index 2d80f7b50bc0..97686097a86e 100644
--- a/arch/arm/boot/dts/imx6ul-tx6ul-mainboard.dts
+++ b/arch/arm/boot/dts/imx6ul-tx6ul-mainboard.dts
@@ -48,7 +48,7 @@
compatible = "karo,imx6ul-tx6ul", "fsl,imx6ul";
aliases {
- lcdif_24bit_pins_a = &pinctrl_disp0_3;
+ lcdif-24bit-pins-a = &pinctrl_disp0_3;
mmc0 = &usdhc1;
/delete-property/ mmc1;
serial2 = &uart3;
diff --git a/arch/arm/boot/dts/imx6ul-tx6ul.dtsi b/arch/arm/boot/dts/imx6ul-tx6ul.dtsi
index f678d18ad44a..02b5ba42cd59 100644
--- a/arch/arm/boot/dts/imx6ul-tx6ul.dtsi
+++ b/arch/arm/boot/dts/imx6ul-tx6ul.dtsi
@@ -53,10 +53,10 @@
i2c2 = &i2c1;
i2c3 = &i2c3;
i2c4 = &i2c4;
- lcdif_23bit_pins_a = &pinctrl_disp0_1;
- lcdif_24bit_pins_a = &pinctrl_disp0_2;
+ lcdif-23bit-pins-a = &pinctrl_disp0_1;
+ lcdif-24bit-pins-a = &pinctrl_disp0_2;
pwm0 = &pwm5;
- reg_can_xcvr = ®_can_xcvr;
+ reg-can-xcvr = ®_can_xcvr;
serial2 = &uart5;
serial4 = &uart3;
spi0 = &ecspi2;
diff --git a/arch/arm/boot/dts/imx7d-nitrogen7.dts b/arch/arm/boot/dts/imx7d-nitrogen7.dts
index 52167298984d..b8e73b46cddb 100644
--- a/arch/arm/boot/dts/imx7d-nitrogen7.dts
+++ b/arch/arm/boot/dts/imx7d-nitrogen7.dts
@@ -49,8 +49,8 @@
compatible = "boundary,imx7d-nitrogen7", "fsl,imx7d";
aliases {
- fb_lcd = &lcdif;
- t_lcd = &t_lcd;
+ fb-lcd = &lcdif;
+ t-lcd = &t_lcd;
};
memory at 80000000 {
--
1.9.1
^ permalink raw reply related
* [PATCH 3/3] spi: meson-axg: add a linear clock divider support
From: Yixun Lan @ 2018-05-04 2:07 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180503231604.GD13402@sirena.org.uk>
Hi Mark
On 05/04/18 07:16, Mark Brown wrote:
> On Thu, May 03, 2018 at 09:36:44PM +0000, Yixun Lan wrote:
>> From: Sunny Luo <sunny.luo@amlogic.com>
>>
>> The SPICC controller in Meson-AXG SoC is capable of using
>> a linear clock divider to reach a much fine tuned range of clocks,
>> while the old controller only use a power of two clock divider,
>> result at a more coarse clock range.
>>
>> Also convert the clock registeration into Common Clock Framework.
>
> This would be better split into two patches - one adding the new linear
> clock divider and the other one doing the CCF conversion. Splitting
> things out like that makes them much easier to review as each change is
> only doing one thing.
>
it's maybe obscure in my previous commit message, the clock divider
support is actually achieved via CCF framework, it can be split as two
independent patches..
I'm CCing clock mailing list (will do if I need to send a v2)
Yixun
^ permalink raw reply
* [PATCH 3/3] spi: meson-axg: add a linear clock divider support
From: kbuild test robot @ 2018-05-04 2:22 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180503213645.20694-4-yixun.lan@amlogic.com>
Hi Sunny,
Thank you for the patch! Yet something to improve:
[auto build test ERROR on v4.17-rc3]
[also build test ERROR on next-20180503]
[cannot apply to spi/for-next]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]
url: https://github.com/0day-ci/linux/commits/Yixun-Lan/spi-meson-axg-add-few-enhanced-features/20180504-083512
config: sparc64-allmodconfig (attached as .config)
compiler: sparc64-linux-gnu-gcc (Debian 7.2.0-11) 7.2.0
reproduce:
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# save the attached .config to linux build tree
make.cross ARCH=sparc64
All error/warnings (new ones prefixed by >>):
>> drivers//spi/spi-meson-spicc.c:517:15: error: variable 'meson_spicc_div0' has initializer but incomplete type
static struct clk_fixed_factor meson_spicc_div0 = {
^~~~~~~~~~~~~~~~
>> drivers//spi/spi-meson-spicc.c:518:3: error: 'struct clk_fixed_factor' has no member named 'mult'
.mult = 1,
^~~~
>> drivers//spi/spi-meson-spicc.c:518:10: warning: excess elements in struct initializer
.mult = 1,
^
drivers//spi/spi-meson-spicc.c:518:10: note: (near initialization for 'meson_spicc_div0')
>> drivers//spi/spi-meson-spicc.c:519:3: error: 'struct clk_fixed_factor' has no member named 'div'
.div = 4,
^~~
drivers//spi/spi-meson-spicc.c:519:9: warning: excess elements in struct initializer
.div = 4,
^
drivers//spi/spi-meson-spicc.c:519:9: note: (near initialization for 'meson_spicc_div0')
>> drivers//spi/spi-meson-spicc.c:522:15: error: variable 'meson_spicc_div1' has initializer but incomplete type
static struct clk_divider meson_spicc_div1 = {
^~~~~~~~~~~
>> drivers//spi/spi-meson-spicc.c:523:3: error: 'struct clk_divider' has no member named 'reg'
.reg = (void *) SPICC_CONREG,
^~~
drivers//spi/spi-meson-spicc.c:523:9: warning: excess elements in struct initializer
.reg = (void *) SPICC_CONREG,
^
drivers//spi/spi-meson-spicc.c:523:9: note: (near initialization for 'meson_spicc_div1')
>> drivers//spi/spi-meson-spicc.c:524:3: error: 'struct clk_divider' has no member named 'shift'
.shift = 16,
^~~~~
drivers//spi/spi-meson-spicc.c:524:11: warning: excess elements in struct initializer
.shift = 16,
^~
drivers//spi/spi-meson-spicc.c:524:11: note: (near initialization for 'meson_spicc_div1')
>> drivers//spi/spi-meson-spicc.c:525:3: error: 'struct clk_divider' has no member named 'width'
.width = 3,
^~~~~
drivers//spi/spi-meson-spicc.c:525:11: warning: excess elements in struct initializer
.width = 3,
^
drivers//spi/spi-meson-spicc.c:525:11: note: (near initialization for 'meson_spicc_div1')
>> drivers//spi/spi-meson-spicc.c:526:3: error: 'struct clk_divider' has no member named 'flags'
.flags = CLK_DIVIDER_POWER_OF_TWO,
^~~~~
>> drivers//spi/spi-meson-spicc.c:526:11: error: 'CLK_DIVIDER_POWER_OF_TWO' undeclared here (not in a function)
.flags = CLK_DIVIDER_POWER_OF_TWO,
^~~~~~~~~~~~~~~~~~~~~~~~
drivers//spi/spi-meson-spicc.c:526:11: warning: excess elements in struct initializer
drivers//spi/spi-meson-spicc.c:526:11: note: (near initialization for 'meson_spicc_div1')
>> drivers//spi/spi-meson-spicc.c:530:15: error: variable 'meson_spicc_div2' has initializer but incomplete type
static struct clk_fixed_factor meson_spicc_div2 = {
^~~~~~~~~~~~~~~~
drivers//spi/spi-meson-spicc.c:531:3: error: 'struct clk_fixed_factor' has no member named 'mult'
.mult = 1,
^~~~
drivers//spi/spi-meson-spicc.c:531:10: warning: excess elements in struct initializer
.mult = 1,
^
drivers//spi/spi-meson-spicc.c:531:10: note: (near initialization for 'meson_spicc_div2')
drivers//spi/spi-meson-spicc.c:532:3: error: 'struct clk_fixed_factor' has no member named 'div'
.div = 2,
^~~
drivers//spi/spi-meson-spicc.c:532:9: warning: excess elements in struct initializer
.div = 2,
^
drivers//spi/spi-meson-spicc.c:532:9: note: (near initialization for 'meson_spicc_div2')
>> drivers//spi/spi-meson-spicc.c:535:15: error: variable 'meson_spicc_div3' has initializer but incomplete type
static struct clk_divider meson_spicc_div3 = {
^~~~~~~~~~~
drivers//spi/spi-meson-spicc.c:536:3: error: 'struct clk_divider' has no member named 'reg'
.reg = (void *) SPICC_ENH_CTL0,
^~~
drivers//spi/spi-meson-spicc.c:536:9: warning: excess elements in struct initializer
.reg = (void *) SPICC_ENH_CTL0,
^
drivers//spi/spi-meson-spicc.c:536:9: note: (near initialization for 'meson_spicc_div3')
drivers//spi/spi-meson-spicc.c:537:3: error: 'struct clk_divider' has no member named 'shift'
.shift = 16,
^~~~~
drivers//spi/spi-meson-spicc.c:537:11: warning: excess elements in struct initializer
.shift = 16,
^~
drivers//spi/spi-meson-spicc.c:537:11: note: (near initialization for 'meson_spicc_div3')
drivers//spi/spi-meson-spicc.c:538:3: error: 'struct clk_divider' has no member named 'width'
.width = 8,
^~~~~
drivers//spi/spi-meson-spicc.c:538:11: warning: excess elements in struct initializer
.width = 8,
^
drivers//spi/spi-meson-spicc.c:538:11: note: (near initialization for 'meson_spicc_div3')
>> drivers//spi/spi-meson-spicc.c:541:15: error: variable 'meson_spicc_sel' has initializer but incomplete type
static struct clk_mux meson_spicc_sel = {
^~~~~~~
>> drivers//spi/spi-meson-spicc.c:542:3: error: 'struct clk_mux' has no member named 'reg'
.reg = (void *) SPICC_ENH_CTL0,
^~~
drivers//spi/spi-meson-spicc.c:542:9: warning: excess elements in struct initializer
.reg = (void *) SPICC_ENH_CTL0,
^
drivers//spi/spi-meson-spicc.c:542:9: note: (near initialization for 'meson_spicc_sel')
>> drivers//spi/spi-meson-spicc.c:543:3: error: 'struct clk_mux' has no member named 'mask'
.mask = 0x1,
^~~~
drivers//spi/spi-meson-spicc.c:543:10: warning: excess elements in struct initializer
.mask = 0x1,
^~~
drivers//spi/spi-meson-spicc.c:543:10: note: (near initialization for 'meson_spicc_sel')
>> drivers//spi/spi-meson-spicc.c:544:3: error: 'struct clk_mux' has no member named 'shift'
.shift = 24,
^~~~~
drivers//spi/spi-meson-spicc.c:544:11: warning: excess elements in struct initializer
.shift = 24,
^~
drivers//spi/spi-meson-spicc.c:544:11: note: (near initialization for 'meson_spicc_sel')
drivers//spi/spi-meson-spicc.c: In function 'meson_spicc_clk_init':
>> drivers//spi/spi-meson-spicc.c:553:23: error: storage size of 'init' isn't known
struct clk_init_data init;
^~~~
>> drivers//spi/spi-meson-spicc.c:562:14: error: 'clk_fixed_factor_ops' undeclared (first use in this function); did you mean 'clk_fixed_factor'?
init.ops = &clk_fixed_factor_ops;
^~~~~~~~~~~~~~~~~~~~
clk_fixed_factor
drivers//spi/spi-meson-spicc.c:562:14: note: each undeclared identifier is reported only once for each function it appears in
>> drivers//spi/spi-meson-spicc.c:564:20: error: implicit declaration of function '__clk_get_name'; did you mean 'clk_get_rate'? [-Werror=implicit-function-declaration]
parent_names[0] = __clk_get_name(spicc->core);
^~~~~~~~~~~~~~
clk_get_rate
>> drivers//spi/spi-meson-spicc.c:564:18: warning: assignment makes pointer from integer without a cast [-Wint-conversion]
parent_names[0] = __clk_get_name(spicc->core);
^
vim +/meson_spicc_div0 +517 drivers//spi/spi-meson-spicc.c
497
498 /*
499 * The Clock Mux
500 * x-----------------x x------------x x------\
501 * |---| 0) fixed factor |---| 1) old div |----| |
502 * | x-----------------x x------------x | |
503 * src ---| |5) mux|-- out
504 * | x-----------------x x------------x | |
505 * |---| 2) fixed factor |---| 3) new div |0---| |
506 * x-----------------x x------------x x------/
507 *
508 * Clk path for GX series:
509 * src -> 0 -> 1 -> out
510 *
511 * Clk path for AXG series:
512 * src -> 0 -> 1 -> 5 -> out
513 * src -> 2 -> 3 -> 5 -> out
514 */
515
516 /* algorithm for div0 + div1: rate = freq / 4 / (2 ^ N) */
> 517 static struct clk_fixed_factor meson_spicc_div0 = {
> 518 .mult = 1,
> 519 .div = 4,
520 };
521
> 522 static struct clk_divider meson_spicc_div1 = {
> 523 .reg = (void *) SPICC_CONREG,
> 524 .shift = 16,
> 525 .width = 3,
> 526 .flags = CLK_DIVIDER_POWER_OF_TWO,
527 };
528
529 /* algorithm for div2 + div3: rate = freq / 2 / (N + 1) */
> 530 static struct clk_fixed_factor meson_spicc_div2 = {
> 531 .mult = 1,
532 .div = 2,
533 };
534
> 535 static struct clk_divider meson_spicc_div3 = {
536 .reg = (void *) SPICC_ENH_CTL0,
> 537 .shift = 16,
> 538 .width = 8,
539 };
540
> 541 static struct clk_mux meson_spicc_sel = {
> 542 .reg = (void *) SPICC_ENH_CTL0,
> 543 .mask = 0x1,
> 544 .shift = 24,
545 };
546
547 static int meson_spicc_clk_init(struct meson_spicc_device *spicc)
548 {
549 struct device *dev = &spicc->pdev->dev;
550 struct clk_fixed_factor *div0;
551 struct clk_divider *div1;
552 struct clk_mux *mux;
> 553 struct clk_init_data init;
554 struct clk *clk;
555 const char *parent_names[1];
556 const char *mux_parent_names[2];
557 char name[32];
558
559 div0 = &meson_spicc_div0;
560 snprintf(name, sizeof(name), "%s#_div0", dev_name(dev));
561 init.name = name;
> 562 init.ops = &clk_fixed_factor_ops;
563 init.flags = 0;
> 564 parent_names[0] = __clk_get_name(spicc->core);
565 init.parent_names = parent_names;
566 init.num_parents = 1;
567
> 568 div0->hw.init = &init;
569
> 570 clk = devm_clk_register(dev, &div0->hw);
571 if (WARN_ON(IS_ERR(clk)))
572 return PTR_ERR(clk);
573
574 div1 = &meson_spicc_div1;
575 snprintf(name, sizeof(name), "%s#_div1", dev_name(dev));
576 init.name = name;
> 577 init.ops = &clk_divider_ops;
> 578 init.flags = CLK_SET_RATE_PARENT;
579 parent_names[0] = __clk_get_name(clk);
580 init.parent_names = parent_names;
581 init.num_parents = 1;
582
> 583 div1->reg = spicc->base + (u64) div1->reg;
584 div1->hw.init = &init;
585
586 clk = devm_clk_register(dev, &div1->hw);
587 if (WARN_ON(IS_ERR(clk)))
588 return PTR_ERR(clk);
589
590 if (spicc->data->has_enhance_clk_div == false) {
591 spicc->clk = clk;
592 return 0;
593 }
594
595 mux_parent_names[0] = __clk_get_name(clk);
596
597 div0 = &meson_spicc_div2;
598 snprintf(name, sizeof(name), "%s#_div2", dev_name(dev));
599 init.name = name;
600 init.ops = &clk_fixed_factor_ops;
601 init.flags = 0;
> 602 parent_names[0] = __clk_get_name(spicc->core);
603 init.parent_names = parent_names;
604 init.num_parents = 1;
605
606 div0->hw.init = &init;
607
608 clk = devm_clk_register(dev, &div0->hw);
609 if (WARN_ON(IS_ERR(clk)))
610 return PTR_ERR(clk);
611
612 div1 = &meson_spicc_div3;
613 snprintf(name, sizeof(name), "%s#_div3", dev_name(dev));
614 init.name = name;
615 init.ops = &clk_divider_ops;
616 init.flags = CLK_SET_RATE_PARENT;
617 parent_names[0] = __clk_get_name(clk);
618 init.parent_names = parent_names;
619 init.num_parents = 1;
620
621 div1->reg = spicc->base + (u64) div1->reg;
622 div1->hw.init = &init;
623
624 clk = devm_clk_register(dev, &div1->hw);
625 if (WARN_ON(IS_ERR(clk)))
626 return PTR_ERR(clk);
627
> 628 mux_parent_names[1] = __clk_get_name(clk);
629
630 mux = &meson_spicc_sel;
631 snprintf(name, sizeof(name), "%s#_sel", dev_name(dev));
632 init.name = name;
> 633 init.ops = &clk_mux_ops;
634 init.parent_names = mux_parent_names;
635 init.num_parents = 2;
> 636 init.flags = CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT;
637
> 638 mux->reg = spicc->base + (u64) mux->reg;
639 mux->hw.init = &init;
640
641 spicc->clk = devm_clk_register(dev, &mux->hw);
642 if (WARN_ON(IS_ERR(spicc->clk)))
643 return PTR_ERR(spicc->clk);
644
645 clk_set_parent(spicc->clk, clk);
646 return 0;
647 }
648
---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation
-------------- next part --------------
A non-text attachment was scrubbed...
Name: .config.gz
Type: application/gzip
Size: 53170 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20180504/00b4c323/attachment-0001.gz>
^ permalink raw reply
* [linux-sunxi] [PATCH 3/3] arm64: allwinner: h6: enable MMC0/2 on Pine H64
From: Chen-Yu Tsai @ 2018-05-04 2:44 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <add8a505-9daa-43d6-eada-b5925d58f1a1@arm.com>
On Wed, May 2, 2018 at 7:01 PM, Andre Przywara <andre.przywara@arm.com> wrote:
> Hi,
>
> On 01/05/18 16:52, Chen-Yu Tsai wrote:
>> On Mon, Apr 30, 2018 at 6:44 PM, Andre Przywara <andre.przywara@arm.com> wrote:
>>> Hi,
>>>
>>> On 30/04/18 10:51, Icenowy Zheng wrote:
>>>>
>>>>
>>>> ? 2018?4?30? GMT+08:00 ??5:47:35, Andre Przywara <andre.przywara@arm.com> ??:
>>>>> Hi Icenowy,
>>>>>
>>>>> On 27/04/18 08:12, Icenowy Zheng wrote:
>>>>>>
>>>>>>
>>>>>> ? 2018?4?27? GMT+08:00 ??12:46:26, Andre Przywara
>>>>> <andre.przywara@arm.com> ??:
>>>>>>> Hi,
>>>>>>>
>>>>>>> On 26/04/18 15:07, Icenowy Zheng wrote:
>>>>>>>> The Pine H64 board have a MicroSD slot connected to MMC0 controller
>>>>>>> of
>>>>>>>> the H6 SoC and a eMMC slot connected to MMC2.
>>>>>>>>
>>>>>>>> Enable them in the device tree.
>>>>>>>>
>>>>>>>> Signed-off-by: Icenowy Zheng <icenowy@aosc.io>
>>>>>>>> ---
>>>>>>>> .../boot/dts/allwinner/sun50i-h6-pine-h64.dts | 32
>>>>>>> ++++++++++++++++++++++
>>>>>>>> 1 file changed, 32 insertions(+)
>>>>>>>>
>>>>>>>> diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h6-pine-h64.dts
>>>>>>> b/arch/arm64/boot/dts/allwinner/sun50i-h6-pine-h64.dts
>>>>>>>> index d36de5eb81f3..78b1cd54687c 100644
>>>>>>>> --- a/arch/arm64/boot/dts/allwinner/sun50i-h6-pine-h64.dts
>>>>>>>> +++ b/arch/arm64/boot/dts/allwinner/sun50i-h6-pine-h64.dts
>>>>>>>> @@ -20,6 +20,38 @@
>>>>>>>> chosen {
>>>>>>>> stdout-path = "serial0:115200n8";
>>>>>>>> };
>>>>>>>> +
>>>>>>>> + reg_vcc3v3: vcc3v3 {
>>>>>>>> + compatible = "regulator-fixed";
>>>>>>>> + regulator-name = "vcc3v3";
>>>>>>>> + regulator-min-microvolt = <3300000>;
>>>>>>>> + regulator-max-microvolt = <3300000>;
>>>>>>>> + };
>>>>>>>> +
>>>>>>>> + reg_vcc1v8: vcc1v8 {
>>>>>>>> + compatible = "regulator-fixed";
>>>>>>>> + regulator-name = "vcc1v8";
>>>>>>>> + regulator-min-microvolt = <1800000>;
>>>>>>>> + regulator-max-microvolt = <1800000>;
>>>>>>>> + };
>>>>>>>> +};
>>>>>>>> +
>>>>>>>> +&mmc0 {
>>>>>>>> + pinctrl-names = "default";
>>>>>>>> + pinctrl-0 = <&mmc0_pins>;
>>>>>>>> + vmmc-supply = <®_vcc3v3>;
>>>>>>>
>>>>>>> So this is actually CLDO1 on the AXP, correct?
>>>>>>
>>>>>> I remember it's coupled between two LDOs, to provide enough power.
>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>> + cd-gpios = <&pio 5 6 GPIO_ACTIVE_LOW>;
>>>>>>>> + status = "okay";
>>>>>>>> +};
>>>>>>>> +
>>>>>>>> +&mmc2 {
>>>>>>>> + pinctrl-names = "default";
>>>>>>>> + pinctrl-0 = <&mmc2_pins>;
>>>>>>>> + vmmc-supply = <®_vcc3v3>;
>>>>>>>> + vqmmc-supply = <®_vcc1v8>;
>>>>>>>
>>>>>>> And this is BLDO2?
>>>>>>
>>>>>> Yes.
>>>>>>
>>>>>>>
>>>>>>> I am just asking because I want to avoid running into the same
>>>>> problem
>>>>>>> as with the A64 before: that future DTs become incompatible with
>>>>> older
>>>>>>> kernels, because we change the power supply to point to the AXP
>>>>>>> regulators, which this kernel does not support yet.
>>>>>>
>>>>>> The answer is just not to keep this compatibility, as it's not
>>>>>> supported option to update DT without updating kernel.
>>>>>
>>>>> Well, I recognise that statement.. ;-) and I understand that it's far
>>>>> easier to handle it this way. But:
>>>>> - Which .dtb are we going to write into the SPI flash? An older one,
>>>>> which covers all kernels, but lacks features? Or a newer one, which
>>>>> limits the bootable kernels to recent versions?
>>>>> - Which DT are we going to give to EFI applications?
>>>>> - Which DT are the BSDs suspected to take? They don't ship their own
>>>>> DTs
>>>>> (which is good!).
>>>>>
>>>>> So I understand that "shipping the DT with the kernel" is the old
>>>>> (embedded!) way of doing things, but I really believe we should stop
>>>>> relying on this and try to come up with backwards compatible DTs, which
>>>>> live in the firmware and get updated there. Because this is what the
>>>>> distros seem to expect from ARM64 boards these days.
>>>>
>>>> I think in this way we should change the way to submit
>>>> patches -- let DT binding patch be merged when it's ready,
>>>> and do not wait for driver.
>>>
>>> Yes, I agree. Ideally we would look at the hardware description, create
>>> a binding just based on that and submit it.
>>>
>>> Then the actual DTs and the drivers (for Linux, U-Boot, *BSD,
>>> you-name-it) could be done independently from each other.
>>>
>>> I think we should really aim for that. The only question is whether this
>>> is really practical, since the documentation is sometimes lacking and we
>>> may discover missing properties during driver development.
>>> So when we meanwhile do hand-in-hand development, we should make sure we
>>> don't break anything in the future.
>>
>> We could do that, but for critical regulators it's a bit tricky. Like the
>> issue with vmmc and vqmmc, where the driver for the regulator is missing,
>> leading to an unusable system.
>
> Yes, that was my original point. We can already anticipate that we will
> break forward compatibility, so we can try to do something about that
> now to avoid that, either by staying with fixed regulators, or by adding
> the PMIC early.
>
>>>>>> P.S. I think the DT will update twice on the kernel side, the
>>>>>> first time keep reg_vcc3v3 (as it's coupled) but use real
>>>>>> regulator for reg_vcc1v8, the second time use the real
>>>>>> coupled regulator for reg_vcc3v3.
>>>>>>
>>>>>>>
>>>>>>> It looks like there are more users of those power rails, so we could
>>>>>>> keep those supplies connected to these fixed regulators here, even
>>>>> with
>>>>>>> AXP-805 support in the kernel.
>>>>>>
>>>>>> It's not a good choice.
>>>>>>
>>>>>>>
>>>>>>> Or we keep this back until we get proper AXP support in the kernel?
>>>>> I
>>>>>>> guess it's quite close to the existing PMICs, so it might be more a
>>>>>>> copy&paste exercise to support the AXP-805?
>>>>>>
>>>>>> It's not a reason to keep it back.
>>>>>
>>>>> So I compared the manuals of the AXP806 and the AXP805, the register
>>>>> interface looks identical to me. I only have a (somewhat) Chinese
>>>>> version of the AXP806 manual, so couldn't really find the difference
>>>>> between the two. Do you know more about it? Is it just maybe the
>>>>> packaging and the electrical properties (like max current supported)?
>>>>>
>>>>> If the I2C register interface is really the same, we could just add the
>>>>> DT nodes for the regulator and be done.
>>>>
>>>> They're the same. My following patchset adds AXP805
>>>> compatible just to use AXP806 code. I have asked Wink
>>>> and the answer is that they have only preset difference.
>>>
>>> Ah, thanks for that, that's good info!
>>> So in this case we don't even need to add the compatible name to the
>>> driver, just add it to the binding doc and create (or copy) the DT
>>> snippets. See last week's discussion ;-)
>>
>> We need to add the compatible to the I2C side of the AXP driver.
>
> Why? If it's really 100% compatible, we just add it to the binding doc
> and use compatible = "x-powers,axp805", "x-powers,axp806"; in the DT.
> That would immediately enable other OSes, for instance.
I meant the implementation side, not the DT. The AXP I2C driver only
binds to the earlier (up to AXP221) PMICs. So just having the device
tree correctly set up does not guarantee a working system for the
current release, or the one in -rc.
>> Also the property for "standalone mode".
>
> Are you referring to what the manual refers to as "self-work" mode?
> In this case I don't see why we need a property: this mode is set up on
> the board side by leaving the MODESET pin floating. And it can be
> queried by checking bits[7:6] of REG 00, so doesn't need a DT property.
> If we care about this mode (do we?), we can check for this in the driver.
>
> (Curious if you meant something else ...)
Yes this is what I was referring to. If you look at the last two registers
you'll see that self-work mode, along with master mode, require the address
extension register be programmed before access to any other register can
happen.
We already have the "x-powers,master-mode" property. The driver will program
the registers correctly when it sees this property. I'm arguing that we
should have another "x-powers,self-work-mode", because these two modes are
not the same: The enable pin works as a power key under self-work mode, while
it acts as a level triggered enable pi, as the name describes. There are
some other minor differences described in the datasheet. The device tree,
being a hardware description, should not conflate the two and leave it up
to the driver to figure things out.
ChenYu
^ permalink raw reply
* [PATCH v8 0/6] optimize memblock_next_valid_pfn and early_pfn_valid on arm and arm64
From: Jia He @ 2018-05-04 2:45 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1523431317-30612-1-git-send-email-hejianet@gmail.com>
Ping
Sorry if I am a little bit verbose, but it can speedup the arm64 booting time
indeed.
--
Cheers,
Jia
On 4/11/2018 3:21 PM, Jia He Wrote:
> Commit b92df1de5d28 ("mm: page_alloc: skip over regions of invalid pfns
> where possible") tried to optimize the loop in memmap_init_zone(). But
> there is still some room for improvement.
>
> Patch 1 introduce new config to make codes more generic
> Patch 2 remain the memblock_next_valid_pfn on arm and arm64
> Patch 3 optimizes the memblock_next_valid_pfn()
> Patch 4~6 optimizes the early_pfn_valid()
>
> As for the performance improvement, after this set, I can see the time
> overhead of memmap_init() is reduced from 41313 us to 24389 us in my
> armv8a server(QDF2400 with 96G memory).
>
> Without this patchset:
> [ 117.113677] before memmap_init
> [ 117.118195] after memmap_init
>>>> memmap_init takes 4518 us
> [ 117.121446] before memmap_init
> [ 117.154992] after memmap_init
>>>> memmap_init takes 33546 us
> [ 117.158241] before memmap_init
> [ 117.161490] after memmap_init
>>>> memmap_init takes 3249 us
>>>> totally takes 41313 us
> With this patchset:
> [ 123.222962] before memmap_init
> [ 123.226819] after memmap_init
>>>> memmap_init takes 3857
> [ 123.230070] before memmap_init
> [ 123.247354] after memmap_init
>>>> memmap_init takes 17284
> [ 123.250604] before memmap_init
> [ 123.253852] after memmap_init
>>>> memmap_init takes 3248
>>>> totally takes 24389 us
> Attached the memblock region information in my server.
> [ 86.956758] Zone ranges:
> [ 86.959452] DMA [mem 0x0000000000200000-0x00000000ffffffff]
> [ 86.966041] Normal [mem 0x0000000100000000-0x00000017ffffffff]
> [ 86.972631] Movable zone start for each node
> [ 86.977179] Early memory node ranges
> [ 86.980985] node 0: [mem 0x0000000000200000-0x000000000021ffff]
> [ 86.987666] node 0: [mem 0x0000000000820000-0x000000000307ffff]
> [ 86.994348] node 0: [mem 0x0000000003080000-0x000000000308ffff]
> [ 87.001029] node 0: [mem 0x0000000003090000-0x00000000031fffff]
> [ 87.007710] node 0: [mem 0x0000000003200000-0x00000000033fffff]
> [ 87.014392] node 0: [mem 0x0000000003410000-0x000000000563ffff]
> [ 87.021073] node 0: [mem 0x0000000005640000-0x000000000567ffff]
> [ 87.027754] node 0: [mem 0x0000000005680000-0x00000000056dffff]
> [ 87.034435] node 0: [mem 0x00000000056e0000-0x00000000086fffff]
> [ 87.041117] node 0: [mem 0x0000000008700000-0x000000000871ffff]
> [ 87.047798] node 0: [mem 0x0000000008720000-0x000000000894ffff]
> [ 87.054479] node 0: [mem 0x0000000008950000-0x0000000008baffff]
> [ 87.061161] node 0: [mem 0x0000000008bb0000-0x0000000008bcffff]
> [ 87.067842] node 0: [mem 0x0000000008bd0000-0x0000000008c4ffff]
> [ 87.074524] node 0: [mem 0x0000000008c50000-0x0000000008e2ffff]
> [ 87.081205] node 0: [mem 0x0000000008e30000-0x0000000008e4ffff]
> [ 87.087886] node 0: [mem 0x0000000008e50000-0x0000000008fcffff]
> [ 87.094568] node 0: [mem 0x0000000008fd0000-0x000000000910ffff]
> [ 87.101249] node 0: [mem 0x0000000009110000-0x00000000092effff]
> [ 87.107930] node 0: [mem 0x00000000092f0000-0x000000000930ffff]
> [ 87.114612] node 0: [mem 0x0000000009310000-0x000000000963ffff]
> [ 87.121293] node 0: [mem 0x0000000009640000-0x000000000e61ffff]
> [ 87.127975] node 0: [mem 0x000000000e620000-0x000000000e64ffff]
> [ 87.134657] node 0: [mem 0x000000000e650000-0x000000000fffffff]
> [ 87.141338] node 0: [mem 0x0000000010800000-0x0000000017feffff]
> [ 87.148019] node 0: [mem 0x000000001c000000-0x000000001c00ffff]
> [ 87.154701] node 0: [mem 0x000000001c010000-0x000000001c7fffff]
> [ 87.161383] node 0: [mem 0x000000001c810000-0x000000007efbffff]
> [ 87.168064] node 0: [mem 0x000000007efc0000-0x000000007efdffff]
> [ 87.174746] node 0: [mem 0x000000007efe0000-0x000000007efeffff]
> [ 87.181427] node 0: [mem 0x000000007eff0000-0x000000007effffff]
> [ 87.188108] node 0: [mem 0x000000007f000000-0x00000017ffffffff]
> [ 87.194791] Initmem setup node 0 [mem 0x0000000000200000-0x00000017ffffffff]
>
> Changelog:
> V8: - introduce new config and move generic code to early_pfn.h
> - optimize memblock_next_valid_pfn as suggested by Matthew Wilcox
> V7: - fix i386 compilation error. refine the commit description
> V6: - simplify the codes, move arm/arm64 common codes to one file.
> - refine patches as suggested by Danial Vacek and Ard Biesheuvel
> V5: - further refining as suggested by Danial Vacek. Make codes
> arm/arm64 more arch specific
> V4: - refine patches as suggested by Danial Vacek and Wei Yang
> - optimized on arm besides arm64
> V3: - fix 2 issues reported by kbuild test robot
> V2: - rebase to mmotm latest
> - remain memblock_next_valid_pfn on arm64
> - refine memblock_search_pfn_regions and pfn_valid_region
>
> Jia He (6):
> arm: arm64: introduce CONFIG_HAVE_MEMBLOCK_PFN_VALID
> mm: page_alloc: remain memblock_next_valid_pfn() on arm/arm64
> arm: arm64: page_alloc: reduce unnecessary binary search in
> memblock_next_valid_pfn()
> mm/memblock: introduce memblock_search_pfn_regions()
> arm: arm64: introduce pfn_valid_region()
> mm: page_alloc: reduce unnecessary binary search in early_pfn_valid()
>
> arch/arm/Kconfig | 4 +++
> arch/arm/mm/init.c | 1 +
> arch/arm64/Kconfig | 4 +++
> arch/arm64/mm/init.c | 1 +
> include/linux/early_pfn.h | 79 +++++++++++++++++++++++++++++++++++++++++++++++
> include/linux/memblock.h | 2 ++
> include/linux/mmzone.h | 18 ++++++++++-
> mm/Kconfig | 3 ++
> mm/memblock.c | 9 ++++++
> mm/page_alloc.c | 5 ++-
> 10 files changed, 124 insertions(+), 2 deletions(-)
> create mode 100644 include/linux/early_pfn.h
>
^ permalink raw reply
* [PATCH 3/3] spi: meson-axg: add a linear clock divider support
From: kbuild test robot @ 2018-05-04 2:46 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180503213645.20694-4-yixun.lan@amlogic.com>
Hi Sunny,
Thank you for the patch! Perhaps something to improve:
[auto build test WARNING on v4.17-rc3]
[also build test WARNING on next-20180503]
[cannot apply to spi/for-next]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]
url: https://github.com/0day-ci/linux/commits/Yixun-Lan/spi-meson-axg-add-few-enhanced-features/20180504-083512
config: xtensa-allmodconfig (attached as .config)
compiler: xtensa-linux-gcc (GCC) 7.2.0
reproduce:
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# save the attached .config to linux build tree
make.cross ARCH=xtensa
All warnings (new ones prefixed by >>):
drivers/spi/spi-meson-spicc.c: In function 'meson_spicc_clk_init':
>> drivers/spi/spi-meson-spicc.c:583:28: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
div1->reg = spicc->base + (u64) div1->reg;
^
drivers/spi/spi-meson-spicc.c:621:28: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
div1->reg = spicc->base + (u64) div1->reg;
^
drivers/spi/spi-meson-spicc.c:638:27: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
mux->reg = spicc->base + (u64) mux->reg;
^
vim +583 drivers/spi/spi-meson-spicc.c
546
547 static int meson_spicc_clk_init(struct meson_spicc_device *spicc)
548 {
549 struct device *dev = &spicc->pdev->dev;
550 struct clk_fixed_factor *div0;
551 struct clk_divider *div1;
552 struct clk_mux *mux;
553 struct clk_init_data init;
554 struct clk *clk;
555 const char *parent_names[1];
556 const char *mux_parent_names[2];
557 char name[32];
558
559 div0 = &meson_spicc_div0;
560 snprintf(name, sizeof(name), "%s#_div0", dev_name(dev));
561 init.name = name;
562 init.ops = &clk_fixed_factor_ops;
563 init.flags = 0;
564 parent_names[0] = __clk_get_name(spicc->core);
565 init.parent_names = parent_names;
566 init.num_parents = 1;
567
568 div0->hw.init = &init;
569
570 clk = devm_clk_register(dev, &div0->hw);
571 if (WARN_ON(IS_ERR(clk)))
572 return PTR_ERR(clk);
573
574 div1 = &meson_spicc_div1;
575 snprintf(name, sizeof(name), "%s#_div1", dev_name(dev));
576 init.name = name;
577 init.ops = &clk_divider_ops;
578 init.flags = CLK_SET_RATE_PARENT;
579 parent_names[0] = __clk_get_name(clk);
580 init.parent_names = parent_names;
581 init.num_parents = 1;
582
> 583 div1->reg = spicc->base + (u64) div1->reg;
584 div1->hw.init = &init;
585
586 clk = devm_clk_register(dev, &div1->hw);
587 if (WARN_ON(IS_ERR(clk)))
588 return PTR_ERR(clk);
589
590 if (spicc->data->has_enhance_clk_div == false) {
591 spicc->clk = clk;
592 return 0;
593 }
594
595 mux_parent_names[0] = __clk_get_name(clk);
596
597 div0 = &meson_spicc_div2;
598 snprintf(name, sizeof(name), "%s#_div2", dev_name(dev));
599 init.name = name;
600 init.ops = &clk_fixed_factor_ops;
601 init.flags = 0;
602 parent_names[0] = __clk_get_name(spicc->core);
603 init.parent_names = parent_names;
604 init.num_parents = 1;
605
606 div0->hw.init = &init;
607
608 clk = devm_clk_register(dev, &div0->hw);
609 if (WARN_ON(IS_ERR(clk)))
610 return PTR_ERR(clk);
611
612 div1 = &meson_spicc_div3;
613 snprintf(name, sizeof(name), "%s#_div3", dev_name(dev));
614 init.name = name;
615 init.ops = &clk_divider_ops;
616 init.flags = CLK_SET_RATE_PARENT;
617 parent_names[0] = __clk_get_name(clk);
618 init.parent_names = parent_names;
619 init.num_parents = 1;
620
621 div1->reg = spicc->base + (u64) div1->reg;
622 div1->hw.init = &init;
623
624 clk = devm_clk_register(dev, &div1->hw);
625 if (WARN_ON(IS_ERR(clk)))
626 return PTR_ERR(clk);
627
628 mux_parent_names[1] = __clk_get_name(clk);
629
630 mux = &meson_spicc_sel;
631 snprintf(name, sizeof(name), "%s#_sel", dev_name(dev));
632 init.name = name;
633 init.ops = &clk_mux_ops;
634 init.parent_names = mux_parent_names;
635 init.num_parents = 2;
636 init.flags = CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT;
637
638 mux->reg = spicc->base + (u64) mux->reg;
639 mux->hw.init = &init;
640
641 spicc->clk = devm_clk_register(dev, &mux->hw);
642 if (WARN_ON(IS_ERR(spicc->clk)))
643 return PTR_ERR(spicc->clk);
644
645 clk_set_parent(spicc->clk, clk);
646 return 0;
647 }
648
---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation
-------------- next part --------------
A non-text attachment was scrubbed...
Name: .config.gz
Type: application/gzip
Size: 52913 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20180504/53be491b/attachment-0001.gz>
^ permalink raw reply
* [PATCH V4 5/8] soc: mediatek: pwrap: add pwrap for mt6797 SoCs
From: Sean Wang @ 2018-05-04 3:04 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1525328436.6214.10.camel@mtkswgap22>
On Thu, 2018-05-03 at 14:20 +0800, Argus Lin wrote:
> On Thu, 2018-05-03 at 12:01 +0800, Sean Wang wrote:
> > };
[...]
> > > @@ -1503,11 +1581,13 @@ static int pwrap_probe(struct platform_device *pdev)
> > > if (IS_ERR(wrp->base))
> > > return PTR_ERR(wrp->base);
> > >
> > > - wrp->rstc = devm_reset_control_get(wrp->dev, "pwrap");
> > > - if (IS_ERR(wrp->rstc)) {
> > > - ret = PTR_ERR(wrp->rstc);
> > > - dev_dbg(wrp->dev, "cannot get pwrap reset: %d\n", ret);
> > > - return ret;
> > > + if (HAS_CAP(wrp->master->caps, PWRAP_CAP_RESET)) {
> > > + wrp->rstc = devm_reset_control_get(wrp->dev, "pwrap");
> >
> > there should be a reset bit present for pwrap on infrasys.
> >
> > the specific condition can be dropped when the reset cell is exported from infrasys and then the device has a reference to it.
> hmm, I think it need to keep here.
> because after pwrap initialized, it can't be reset alone.
> It needs to reset PMIC simultaneously, too.
Reset a pair, either a master or its slave, all had been a part of
pwrap_init.
The reset controller provided here is just to reset pwrap device.
And for its slave reset, it should be done by pwrap_reset_spislave.
So for MT6397, it should be able to fall into the same procedure.
> >
> > > + if (IS_ERR(wrp->rstc)) {
> > > + ret = PTR_ERR(wrp->rstc);
> > > + dev_dbg(wrp->dev, "cannot get pwrap reset: %d\n", ret);
> > > + return ret;
> > > + }
> > > }
> > >
> > > if (HAS_CAP(wrp->master->caps, PWRAP_CAP_BRIDGE)) {
> > > @@ -1549,9 +1629,17 @@ static int pwrap_probe(struct platform_device *pdev)
> > > if (ret)
> > > goto err_out1;
> > >
> > > - /* Enable internal dynamic clock */
> > > - pwrap_writel(wrp, 1, PWRAP_DCM_EN);
> > > - pwrap_writel(wrp, 0, PWRAP_DCM_DBC_PRD);
> > > + /*
> > > + * add dcm capability check
> > > + */
> > > + if (HAS_CAP(wrp->master->caps, PWRAP_CAP_DCM)) {
> >
> > the specific condition can be dropped since so far all devices the driver can support are owning PWRAP_CAP_DCM
> We did not support DCM for future chips.
> MT6797 is the last one.
> This why I want to add judgement here.
The series is only for MT6797 pwrap, so it's fine with only adding these
things the SoC actually relies on.
PWRAP_CAP_DCM should not be added until a new SoC without dcm is really
introduced.
> >
> > > + if (wrp->master->type == PWRAP_MT6797)
> > > + pwrap_writel(wrp, 3, PWRAP_DCM_EN);
> >
> > the setup for MT6797 can be moved into .init_soc_specific callback ?
>
> I think put it here is more generally.
> >
> > > + else
> > > + pwrap_writel(wrp, 1, PWRAP_DCM_EN);
> > > +
> > > + pwrap_writel(wrp, 0, PWRAP_DCM_DBC_PRD);
> > > + }
> > >
> > > /*
> > > * The PMIC could already be initialized by the bootloader.
> > > @@ -1580,6 +1668,12 @@ static int pwrap_probe(struct platform_device *pdev)
> > > pwrap_writel(wrp, wrp->master->wdt_src, PWRAP_WDT_SRC_EN);
> > > pwrap_writel(wrp, 0x1, PWRAP_TIMER_EN);
> > > pwrap_writel(wrp, wrp->master->int_en_all, PWRAP_INT_EN);
> > > + /*
> > > + * We add INT1 interrupt to handle starvation and request exception
> > > + * If we support it, we should enable them here.
> > > + */
> > > + if (HAS_CAP(wrp->master->caps, PWRAP_CAP_INT1_EN))
> > > + pwrap_writel(wrp, wrp->master->int1_en_all, PWRAP_INT1_EN);
> > >
> >
> > if there is no explicitly enabling on INT1, then ISR handling for INT1 is also unnecessary
>
> It's ok for me.
> >
> > > irq = platform_get_irq(pdev, 0);
> > > ret = devm_request_irq(wrp->dev, irq, pwrap_interrupt,
> >
> >
> >
>
>
^ permalink raw reply
* [PATCH 1/2] pinctrl: mvebu: update use "nand" function for "rb" pin
From: Chris Packham @ 2018-05-04 3:06 UTC (permalink / raw)
To: linux-arm-kernel
The Armada 98dx3236 SoCs don't have a different MPP sel value for nand
specific pins so "dev" was technically correct. But all the other Armada
SoCs use "nand" in their dts and the pin is specific to the nand
interface so use "nand" for the function name.
Signed-off-by: Chris Packham <chris.packham@alliedtelesis.co.nz>
---
drivers/pinctrl/mvebu/pinctrl-armada-xp.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/pinctrl/mvebu/pinctrl-armada-xp.c b/drivers/pinctrl/mvebu/pinctrl-armada-xp.c
index b854f1ee5de5..28b199796fae 100644
--- a/drivers/pinctrl/mvebu/pinctrl-armada-xp.c
+++ b/drivers/pinctrl/mvebu/pinctrl-armada-xp.c
@@ -431,7 +431,7 @@ static struct mvebu_mpp_mode mv98dx3236_mpp_modes[] = {
MPP_MODE(19,
MPP_VAR_FUNCTION(0x0, "gpio", NULL, V_98DX3236_PLUS),
MPP_VAR_FUNCTION(0x3, "uart1", "rxd", V_98DX3236_PLUS),
- MPP_VAR_FUNCTION(0x4, "dev", "rb", V_98DX3236_PLUS)),
+ MPP_VAR_FUNCTION(0x4, "nand", "rb", V_98DX3236_PLUS)),
MPP_MODE(20,
MPP_VAR_FUNCTION(0x0, "gpo", NULL, V_98DX3236_PLUS),
MPP_VAR_FUNCTION(0x4, "dev", "we0", V_98DX3236_PLUS)),
--
2.17.0
^ permalink raw reply related
* [PATCH 2/2] ARM: dts: armada-xp-98dx: Add NAND pinctrl information
From: Chris Packham @ 2018-05-04 3:06 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180504030638.31521-1-chris.packham@alliedtelesis.co.nz>
Add pin control information for the NAND interface on the Armada
98DX3236 and variants.
Signed-off-by: Chris Packham <chris.packham@alliedtelesis.co.nz>
---
arch/arm/boot/dts/armada-xp-98dx3236.dtsi | 13 +++++++++++++
1 file changed, 13 insertions(+)
diff --git a/arch/arm/boot/dts/armada-xp-98dx3236.dtsi b/arch/arm/boot/dts/armada-xp-98dx3236.dtsi
index 9a589abd0379..099dc2520082 100644
--- a/arch/arm/boot/dts/armada-xp-98dx3236.dtsi
+++ b/arch/arm/boot/dts/armada-xp-98dx3236.dtsi
@@ -312,6 +312,19 @@
&pinctrl {
compatible = "marvell,98dx3236-pinctrl";
+ nand_pins: nand-pins {
+ marvell,pins = "mpp20", "mpp21", "mpp22",
+ "mpp23", "mpp24", "mpp25",
+ "mpp26", "mpp27", "mpp28",
+ "mpp29", "mpp30";
+ marvell,function = "dev";
+ };
+
+ nand_rb: nand-rb {
+ marvell,pins = "mpp19";
+ marvell,function = "nand";
+ };
+
spi0_pins: spi0-pins {
marvell,pins = "mpp0", "mpp1",
"mpp2", "mpp3";
--
2.17.0
^ permalink raw reply related
* [PATCH 2/2] PCI: mediatek: Using chained IRQ to setup IRQ handle
From: Honghui Zhang @ 2018-05-04 3:25 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <7efd1486-9f65-a647-5ab0-9a97b10c2ec7@arm.com>
On Thu, 2018-05-03 at 14:05 +0100, Marc Zyngier wrote:
> On 03/05/18 10:41, Honghui Zhang wrote:
> > On Wed, 2018-05-02 at 11:09 +0100, Marc Zyngier wrote:
> >> On 02/05/18 10:41, Honghui Zhang wrote:
> >>> On Mon, 2018-04-30 at 12:03 +0100, Marc Zyngier wrote:
> >>>> Hi Zhang,
> >>>>
> >>>> On 20/04/18 06:25, honghui.zhang at mediatek.com wrote:
> >>>>> From: Honghui Zhang <honghui.zhang@mediatek.com>
> >>>>>
> >>>>> Using irq_chip solution to setup IRQs for the consistent with IRQ framework.
> >>>>>
> >>>>> Signed-off-by: Honghui Zhang <honghui.zhang@mediatek.com>
> >>>>> ---
> >>>>> drivers/pci/host/pcie-mediatek.c | 192 +++++++++++++++++++++------------------
> >>>>> 1 file changed, 105 insertions(+), 87 deletions(-)
> >>>>>
> >>>>> diff --git a/drivers/pci/host/pcie-mediatek.c b/drivers/pci/host/pcie-mediatek.c
> >>>>> index c3dc549..1d9c6f1 100644
> >>>>> --- a/drivers/pci/host/pcie-mediatek.c
> >>>>> +++ b/drivers/pci/host/pcie-mediatek.c
> >>>>> @@ -11,8 +11,10 @@
> >>>>> #include <linux/delay.h>
> >>>>> #include <linux/iopoll.h>
> >>>>> #include <linux/irq.h>
> >>>>> +#include <linux/irqchip/chained_irq.h>
> >>>>> #include <linux/irqdomain.h>
> >>>>> #include <linux/kernel.h>
> >>>>> +#include <linux/msi.h>
> >>>>> #include <linux/of_address.h>
> >>>>> #include <linux/of_pci.h>
> >>>>> #include <linux/of_platform.h>
> >>>>> @@ -130,14 +132,12 @@ struct mtk_pcie_port;
> >>>>> /**
> >>>>> * struct mtk_pcie_soc - differentiate between host generations
> >>>>> * @need_fix_class_id: whether this host's class ID needed to be fixed or not
> >>>>> - * @has_msi: whether this host supports MSI interrupts or not
> >>>>> * @ops: pointer to configuration access functions
> >>>>> * @startup: pointer to controller setting functions
> >>>>> * @setup_irq: pointer to initialize IRQ functions
> >>>>> */
> >>>>> struct mtk_pcie_soc {
> >>>>> bool need_fix_class_id;
> >>>>> - bool has_msi;
> >>>>> struct pci_ops *ops;
> >>>>> int (*startup)(struct mtk_pcie_port *port);
> >>>>> int (*setup_irq)(struct mtk_pcie_port *port, struct device_node *node);
> >>>>> @@ -161,7 +161,9 @@ struct mtk_pcie_soc {
> >>>>> * @lane: lane count
> >>>>> * @slot: port slot
> >>>>> * @irq_domain: legacy INTx IRQ domain
> >>>>> + * @inner_domain: inner IRQ domain
> >>>>> * @msi_domain: MSI IRQ domain
> >>>>> + * @lock: protect the msi_irq_in_use bitmap
> >>>>> * @msi_irq_in_use: bit map for assigned MSI IRQ
> >>>>> */
> >>>>> struct mtk_pcie_port {
> >>>>> @@ -179,7 +181,9 @@ struct mtk_pcie_port {
> >>>>> u32 lane;
> >>>>> u32 slot;
> >>>>> struct irq_domain *irq_domain;
> >>>>> + struct irq_domain *inner_domain;
> >>>>> struct irq_domain *msi_domain;
> >>>>> + struct mutex lock;
> >>>>> DECLARE_BITMAP(msi_irq_in_use, MTK_MSI_IRQS_NUM);
> >>>>> };
> >>>>>
> >>>>> @@ -446,103 +450,122 @@ static int mtk_pcie_startup_port_v2(struct mtk_pcie_port *port)
> >>>>> return 0;
> >>>>> }
> >>>>>
> >>>>> -static int mtk_pcie_msi_alloc(struct mtk_pcie_port *port)
> >>>>> +static void mtk_compose_msi_msg(struct irq_data *data, struct msi_msg *msg)
> >>>>> {
> >>>>> - int msi;
> >>>>> + struct mtk_pcie_port *port = irq_data_get_irq_chip_data(data);
> >>>>> + phys_addr_t addr;
> >>>>>
> >>>>> - msi = find_first_zero_bit(port->msi_irq_in_use, MTK_MSI_IRQS_NUM);
> >>>>> - if (msi < MTK_MSI_IRQS_NUM)
> >>>>> - set_bit(msi, port->msi_irq_in_use);
> >>>>> - else
> >>>>> - return -ENOSPC;
> >>>>> + /* MT2712/MT7622 only support 32-bit MSI addresses */
> >>>>> + addr = virt_to_phys(port->base + PCIE_MSI_VECTOR);
> >>>>> + msg->address_hi = 0;
> >>>>> + msg->address_lo = lower_32_bits(addr);
> >>>>>
> >>>>> - return msi;
> >>>>> + msg->data = data->hwirq;
> >>>>> +
> >>>>> + dev_dbg(port->pcie->dev, "msi#%d address_hi %#x address_lo %#x\n",
> >>>>> + (int)data->hwirq, msg->address_hi, msg->address_lo);
> >>>>> }
> >>>>>
> >>>>> -static void mtk_pcie_msi_free(struct mtk_pcie_port *port, unsigned long hwirq)
> >>>>> +static int mtk_msi_set_affinity(struct irq_data *irq_data,
> >>>>> + const struct cpumask *mask, bool force)
> >>>>> {
> >>>>> - clear_bit(hwirq, port->msi_irq_in_use);
> >>>>> + return -EINVAL;
> >>>>> }
> >>>>>
> >>>>> -static int mtk_pcie_msi_setup_irq(struct msi_controller *chip,
> >>>>> - struct pci_dev *pdev, struct msi_desc *desc)
> >>>>> -{
> >>>>> - struct mtk_pcie_port *port;
> >>>>> - struct msi_msg msg;
> >>>>> - unsigned int irq;
> >>>>> - int hwirq;
> >>>>> - phys_addr_t msg_addr;
> >>>>> +static struct irq_chip mtk_msi_bottom_irq_chip = {
> >>>>> + .name = "MTK MSI",
> >>>>> + .irq_compose_msi_msg = mtk_compose_msi_msg,
> >>>>> + .irq_set_affinity = mtk_msi_set_affinity,
> >>>>> + .irq_mask = pci_msi_mask_irq,
> >>>>> + .irq_unmask = pci_msi_unmask_irq,
> >>>>> +};
> >>>>>
> >>>>> - port = mtk_pcie_find_port(pdev->bus, pdev->devfn);
> >>>>> - if (!port)
> >>>>> - return -EINVAL;
> >>>>> +static int mtk_pcie_irq_domain_alloc(struct irq_domain *domain, unsigned int virq,
> >>>>> + unsigned int nr_irqs, void *args)
> >>>>> +{
> >>>>> + struct mtk_pcie_port *port = domain->host_data;
> >>>>> + unsigned long bit;
> >>>>>
> >>>>> - hwirq = mtk_pcie_msi_alloc(port);
> >>>>> - if (hwirq < 0)
> >>>>> - return hwirq;
> >>>>> + WARN_ON(nr_irqs != 1);
> >>>>> + mutex_lock(&port->lock);
> >>>>>
> >>>>> - irq = irq_create_mapping(port->msi_domain, hwirq);
> >>>>> - if (!irq) {
> >>>>> - mtk_pcie_msi_free(port, hwirq);
> >>>>> - return -EINVAL;
> >>>>> + bit = find_first_zero_bit(port->msi_irq_in_use, MTK_MSI_IRQS_NUM);
> >>>>> + if (bit >= MTK_MSI_IRQS_NUM) {
> >>>>> + mutex_unlock(&port->lock);
> >>>>> + return -ENOSPC;
> >>>>> }
> >>>>>
> >>>>> - chip->dev = &pdev->dev;
> >>>>> -
> >>>>> - irq_set_msi_desc(irq, desc);
> >>>>> + __set_bit(bit, port->msi_irq_in_use);
> >>>>>
> >>>>> - /* MT2712/MT7622 only support 32-bit MSI addresses */
> >>>>> - msg_addr = virt_to_phys(port->base + PCIE_MSI_VECTOR);
> >>>>> - msg.address_hi = 0;
> >>>>> - msg.address_lo = lower_32_bits(msg_addr);
> >>>>> - msg.data = hwirq;
> >>>>> + mutex_unlock(&port->lock);
> >>>>>
> >>>>> - pci_write_msi_msg(irq, &msg);
> >>>>> + irq_domain_set_info(domain, virq, bit, &mtk_msi_bottom_irq_chip,
> >>>>> + domain->host_data, handle_simple_irq,
> >>>>
> >>>> Why don't you handle the interrupt as an edge interrupt
> >>>> (handle_edge_irq)? That's what it really is, and the fact that you use
> >>>> "handle_simple_irq" makes me think that wou're papering over some other
> >>>> issue (see below).
> >>>
> >>> Hi, Marc,
> >>>
> >>> Thanks very much for your comments.
> >>>
> >>> I guess the MSI irq is more like a level IRQ instead of edge IRQ.
> >>> When a MSI IRQ arrived, the corresponding bit of MSI status register
> >>> will be asserted and stay asserted until it's been cleared by software.
> >>
> >> There is some confusion here. The MSI itself is always edge-triggered.
> >> That's by definition, and you cannot change it. The interrupt that is
> >> used to signal that MSIs are pending (the multiplexing interrupt) can
> >> itself be level triggered (and goes low once all the MSIs have been
> >> acknowledged).
> >
> > Hi, Marc, thanks for your comments.
> >
> > Yes, PCIe SPEC have defined that the MSI must be edge trigged. But I'm
> > not sure whether the HW design needed to following some edge irq
> > standard.
>
>
> Given that the device is writing to the MSI doorbell, this can only be
> an edge (one way to look at it is that you cannot "unwrite" something,
> so you can't drop the level).
>
Thanks for your explain in this point of view. I will handle it as edge
IRQ in the next version.
> > In our design, when there's MSI irq trigged(which may is edge
> > trigged in hw implemented), the corresponding msi irq status bits will
> > be asserted until it's been cleared by software. It's more like that the
> > HW IP have translate the edge irq to level status. Do you think using
> > handle_level_irq or handle_simple_irq(which most of the pci host driver
> > now doing) is acceptable in this case?
>
> This is how it is supposed to work:
>
> Device --edge--> MSI-controller --level--> primary controller
>
> When you're handling the MSI, it has to be edge. When handling the
> interrupt between the MSI controller and the main irqchip, this is level.
>
> At the moment, you have handle that first interrupt as level, which is
> wrong.
>
> > BTW, I'm still struggling in trying the handle_edge_irq solution. Seems
> > that I could not get the msi index in irq_ack callback from
> > irq_data->hwirq, the hwirq was set by pci_msi_domain_calc_hwirq() which
> > I'm still try to figure out the proper routine in my driver.
>
> That's because you've plugged it in the wrong irqchip. Your top-level
> irqchip (the one backing the PCI domain) must be implemented with
> irq_chip_ack_parent, and you them implement the ack logic in the
> HW-specific irqchip.
>
Thanks very much for your advise, that's exactly the mistake that I
made. Now it's works fine, I will check it again and send the next
version.
thanks.
> M.
^ permalink raw reply
* [BUGFIX PATCH v3 0/4] arm: kprobes: Fix to prohibit probing on unsafe functions
From: Masami Hiramatsu @ 2018-05-04 4:14 UTC (permalink / raw)
To: linux-arm-kernel
Hi,
This is the 3rd version of bugfix series for kprobes on arm.
This series fixes 4 different issues which I found.
- Fix to use smp_processor_id() after disabling preemption.
- Prohibit probing on optimized_callback() for avoiding
recursive probe.
- Prohibit kprobes on do_undefinstr() by same reason.
- Prohibit kprobes on get_user() by same reason.
>From v2, I included another 2 bugfixes (1/4 and 2/4)
which are not merged yet, and added "Cc: stable at vger.kernel.org",
since there are obvious bugs.
Thanks,
---
Masami Hiramatsu (4):
arm: kprobes: Fix to use get_kprobe_ctlblk after irq-disabed
arm: kprobes: Prohibit probing on optimized_callback
arm: kprobes: Prohibit kprobes on do_undefinstr
arm: kprobes: Prohibit kprobes on get_user functions
arch/arm/include/asm/assembler.h | 10 ++++++++++
arch/arm/kernel/traps.c | 5 ++++-
arch/arm/lib/getuser.S | 10 ++++++++++
arch/arm/probes/kprobes/opt-arm.c | 4 +++-
4 files changed, 27 insertions(+), 2 deletions(-)
--
Masami Hiramatsu (Linaro) <mhiramat@kernel.org>
^ permalink raw reply
* [BUGFIX PATCH v3 1/4] arm: kprobes: Fix to use get_kprobe_ctlblk after irq-disabed
From: Masami Hiramatsu @ 2018-05-04 4:15 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <152540727123.29650.13679359124038587629.stgit@devbox>
Since get_kprobe_ctlblk() uses smp_processor_id() to access
per-cpu variable, it hits smp_processor_id sanity check as below.
[ 7.006928] BUG: using smp_processor_id() in preemptible [00000000] code: swapper/0/1
[ 7.007859] caller is debug_smp_processor_id+0x20/0x24
[ 7.008438] CPU: 0 PID: 1 Comm: swapper/0 Not tainted 4.16.0-rc1-00192-g4eb17253e4b5 #1
[ 7.008890] Hardware name: Generic DT based system
[ 7.009917] [<c0313f0c>] (unwind_backtrace) from [<c030e6d8>] (show_stack+0x20/0x24)
[ 7.010473] [<c030e6d8>] (show_stack) from [<c0c64694>] (dump_stack+0x84/0x98)
[ 7.010990] [<c0c64694>] (dump_stack) from [<c071ca5c>] (check_preemption_disabled+0x138/0x13c)
[ 7.011592] [<c071ca5c>] (check_preemption_disabled) from [<c071ca80>] (debug_smp_processor_id+0x20/0x24)
[ 7.012214] [<c071ca80>] (debug_smp_processor_id) from [<c03335e0>] (optimized_callback+0x2c/0xe4)
[ 7.013077] [<c03335e0>] (optimized_callback) from [<bf0021b0>] (0xbf0021b0)
To fix this issue, call get_kprobe_ctlblk() right after
irq-disabled since that disables preemption.
Fixes: 0dc016dbd820 ("ARM: kprobes: enable OPTPROBES for ARM 32")
Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org>
Cc: stable at vger.kernel.org
---
arch/arm/probes/kprobes/opt-arm.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/arch/arm/probes/kprobes/opt-arm.c b/arch/arm/probes/kprobes/opt-arm.c
index bcdecc25461b..ddc5a82eb10d 100644
--- a/arch/arm/probes/kprobes/opt-arm.c
+++ b/arch/arm/probes/kprobes/opt-arm.c
@@ -165,13 +165,14 @@ optimized_callback(struct optimized_kprobe *op, struct pt_regs *regs)
{
unsigned long flags;
struct kprobe *p = &op->kp;
- struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
+ struct kprobe_ctlblk *kcb;
/* Save skipped registers */
regs->ARM_pc = (unsigned long)op->kp.addr;
regs->ARM_ORIG_r0 = ~0UL;
local_irq_save(flags);
+ kcb = get_kprobe_ctlblk();
if (kprobe_running()) {
kprobes_inc_nmissed_count(&op->kp);
^ permalink raw reply related
* [BUGFIX PATCH v3 2/4] arm: kprobes: Prohibit probing on optimized_callback
From: Masami Hiramatsu @ 2018-05-04 4:15 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <152540727123.29650.13679359124038587629.stgit@devbox>
Prohibit probing on optimized_callback() because
it is called from kprobes itself. If we put a kprobes
on it, that will cause a recursive call loop.
Mark it NOKPROBE_SYMBOL.
Fixes: 0dc016dbd820 ("ARM: kprobes: enable OPTPROBES for ARM 32")
Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org>
Cc: stable at vger.kernel.org
---
arch/arm/probes/kprobes/opt-arm.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/arch/arm/probes/kprobes/opt-arm.c b/arch/arm/probes/kprobes/opt-arm.c
index ddc5a82eb10d..b2aa9b32bff2 100644
--- a/arch/arm/probes/kprobes/opt-arm.c
+++ b/arch/arm/probes/kprobes/opt-arm.c
@@ -192,6 +192,7 @@ optimized_callback(struct optimized_kprobe *op, struct pt_regs *regs)
local_irq_restore(flags);
}
+NOKPROBE_SYMBOL(optimized_callback)
int arch_prepare_optimized_kprobe(struct optimized_kprobe *op, struct kprobe *orig)
{
^ permalink raw reply related
* [BUGFIX PATCH v3 3/4] arm: kprobes: Prohibit kprobes on do_undefinstr
From: Masami Hiramatsu @ 2018-05-04 4:15 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <152540727123.29650.13679359124038587629.stgit@devbox>
Prohibit kprobes on do_undefinstr because kprobes on
arm is implemented by undefined instruction. This means
if we probe do_undefinstr(), it can cause infinit
recursive exception.
Fixes: 24ba613c9d6c ("ARM kprobes: core code")
Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org>
Cc: stable at vger.kernel.org
---
arch/arm/kernel/traps.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c
index 5e3633c24e63..2fe87109ae46 100644
--- a/arch/arm/kernel/traps.c
+++ b/arch/arm/kernel/traps.c
@@ -19,6 +19,7 @@
#include <linux/uaccess.h>
#include <linux/hardirq.h>
#include <linux/kdebug.h>
+#include <linux/kprobes.h>
#include <linux/module.h>
#include <linux/kexec.h>
#include <linux/bug.h>
@@ -417,7 +418,8 @@ void unregister_undef_hook(struct undef_hook *hook)
raw_spin_unlock_irqrestore(&undef_lock, flags);
}
-static int call_undef_hook(struct pt_regs *regs, unsigned int instr)
+static nokprobe_inline
+int call_undef_hook(struct pt_regs *regs, unsigned int instr)
{
struct undef_hook *hook;
unsigned long flags;
@@ -490,6 +492,7 @@ asmlinkage void do_undefinstr(struct pt_regs *regs)
arm_notify_die("Oops - undefined instruction", regs, &info, 0, 6);
}
+NOKPROBE_SYMBOL(do_undefinstr)
/*
* Handle FIQ similarly to NMI on x86 systems.
^ permalink raw reply related
* [BUGFIX PATCH v3 4/4] arm: kprobes: Prohibit kprobes on get_user functions
From: Masami Hiramatsu @ 2018-05-04 4:16 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <152540727123.29650.13679359124038587629.stgit@devbox>
Since do_undefinstr() uses get_user to get the undefined
instruction, it can be called before kprobes processes
recursive check. This can cause an infinit recursive
exception.
Prohibit probing on get_user functions.
Fixes: 24ba613c9d6c ("ARM kprobes: core code")
Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org>
Cc: stable at vger.kernel.org
---
Changes in v2:
- Fix to add _ASM_NOKPROBE() definition for
!CONFIG_KPROBES.
---
arch/arm/include/asm/assembler.h | 10 ++++++++++
arch/arm/lib/getuser.S | 10 ++++++++++
2 files changed, 20 insertions(+)
diff --git a/arch/arm/include/asm/assembler.h b/arch/arm/include/asm/assembler.h
index bc8d4bbd82e2..9342904cccca 100644
--- a/arch/arm/include/asm/assembler.h
+++ b/arch/arm/include/asm/assembler.h
@@ -536,4 +536,14 @@ THUMB( orr \reg , \reg , #PSR_T_BIT )
#endif
.endm
+#ifdef CONFIG_KPROBES
+#define _ASM_NOKPROBE(entry) \
+ .pushsection "_kprobe_blacklist", "aw" ; \
+ .balign 4 ; \
+ .long entry; \
+ .popsection
+#else
+#define _ASM_NOKPROBE(entry)
+#endif
+
#endif /* __ASM_ASSEMBLER_H__ */
diff --git a/arch/arm/lib/getuser.S b/arch/arm/lib/getuser.S
index df73914e81c8..746e7801dcdf 100644
--- a/arch/arm/lib/getuser.S
+++ b/arch/arm/lib/getuser.S
@@ -38,6 +38,7 @@ ENTRY(__get_user_1)
mov r0, #0
ret lr
ENDPROC(__get_user_1)
+_ASM_NOKPROBE(__get_user_1)
ENTRY(__get_user_2)
check_uaccess r0, 2, r1, r2, __get_user_bad
@@ -58,6 +59,7 @@ rb .req r0
mov r0, #0
ret lr
ENDPROC(__get_user_2)
+_ASM_NOKPROBE(__get_user_2)
ENTRY(__get_user_4)
check_uaccess r0, 4, r1, r2, __get_user_bad
@@ -65,6 +67,7 @@ ENTRY(__get_user_4)
mov r0, #0
ret lr
ENDPROC(__get_user_4)
+_ASM_NOKPROBE(__get_user_4)
ENTRY(__get_user_8)
check_uaccess r0, 8, r1, r2, __get_user_bad8
@@ -78,6 +81,7 @@ ENTRY(__get_user_8)
mov r0, #0
ret lr
ENDPROC(__get_user_8)
+_ASM_NOKPROBE(__get_user_8)
#ifdef __ARMEB__
ENTRY(__get_user_32t_8)
@@ -91,6 +95,7 @@ ENTRY(__get_user_32t_8)
mov r0, #0
ret lr
ENDPROC(__get_user_32t_8)
+_ASM_NOKPROBE(__get_user_32t_8)
ENTRY(__get_user_64t_1)
check_uaccess r0, 1, r1, r2, __get_user_bad8
@@ -98,6 +103,7 @@ ENTRY(__get_user_64t_1)
mov r0, #0
ret lr
ENDPROC(__get_user_64t_1)
+_ASM_NOKPROBE(__get_user_64t_1)
ENTRY(__get_user_64t_2)
check_uaccess r0, 2, r1, r2, __get_user_bad8
@@ -114,6 +120,7 @@ rb .req r0
mov r0, #0
ret lr
ENDPROC(__get_user_64t_2)
+_ASM_NOKPROBE(__get_user_64t_2)
ENTRY(__get_user_64t_4)
check_uaccess r0, 4, r1, r2, __get_user_bad8
@@ -121,6 +128,7 @@ ENTRY(__get_user_64t_4)
mov r0, #0
ret lr
ENDPROC(__get_user_64t_4)
+_ASM_NOKPROBE(__get_user_64t_4)
#endif
__get_user_bad8:
@@ -131,6 +139,8 @@ __get_user_bad:
ret lr
ENDPROC(__get_user_bad)
ENDPROC(__get_user_bad8)
+_ASM_NOKPROBE(__get_user_bad)
+_ASM_NOKPROBE(__get_user_bad8)
.pushsection __ex_table, "a"
.long 1b, __get_user_bad
^ permalink raw reply related
* [PATCH v7 0/2] PCI: mediatek: Fixups for the IRQ handle routine and MT7622's class code
From: honghui.zhang at mediatek.com @ 2018-05-04 5:47 UTC (permalink / raw)
To: linux-arm-kernel
From: Honghui Zhang <honghui.zhang@mediatek.com>
Two fixups for mediatek's host bridge:
The first patch fixup class type and vendor ID for MT7622.
The second patch fixup the IRQ handle routine by using irq_chip solution
to avoid IRQ reentry which may exist for both MT2712 and MT7622.
Change since v6:
- Remove the irq_mask, irq_unmask callback in lower layer irq_chip since we
have set the MSI_FLAG_USE_DEF_CHIP_OPS flags.
- Add irq_ack callback in irq_chip to handle edge IRQ.
- Uing handle_edge_irq to handle the MSI IRQs.
Change since v5:
- Make the comments consistend with the code modification in the first patch.
- Using writew to performing a 16-bit write.
- Using irq_chip solution to fix the IRQ issue.
The v5 patchset could be found in:
https://patchwork.kernel.org/patch/10133303
https://patchwork.kernel.org/patch/10133305
Change since v4:
- Only setup vendor ID for MT7622, igorning the device ID since mediatek's
host bridge driver does not cares about the device ID.
Change since v3:
- Setup the class type and vendor ID at the beginning of startup instead
of in a quirk.
- Add mediatek's vendor ID, it could be found in:
https://pcisig.com/membership/member-companies?combine=&page=4
Change since v2:
- Move the initialize of the iterate before the loop to fix an
INTx IRQ issue in the first patch
Change since v1:
- Add the second patch.
- Make the first patch's commit message more standard.
Honghui Zhang (2):
PCI: mediatek: Set up vendor ID and class type for MT7622
PCI: mediatek: Using chained IRQ to setup IRQ handle
drivers/pci/host/pcie-mediatek.c | 234 +++++++++++++++++++++++----------------
include/linux/pci_ids.h | 2 +
2 files changed, 143 insertions(+), 93 deletions(-)
--
2.6.4
^ permalink raw reply
* [PATCH v7 1/2] PCI: mediatek: Set up vendor ID and class type for MT7622
From: honghui.zhang at mediatek.com @ 2018-05-04 5:47 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1525412853-24367-1-git-send-email-honghui.zhang@mediatek.com>
From: Honghui Zhang <honghui.zhang@mediatek.com>
MT7622's hardware default value of vendor ID and class type is not correct,
fix that by setup the correct values before linkup with Endpoint.
Signed-off-by: Honghui Zhang <honghui.zhang@mediatek.com>
Acked-by: Ryder Lee <ryder.lee@mediatek.com>
---
drivers/pci/host/pcie-mediatek.c | 30 +++++++++++++++++++++++++++---
include/linux/pci_ids.h | 2 ++
2 files changed, 29 insertions(+), 3 deletions(-)
diff --git a/drivers/pci/host/pcie-mediatek.c b/drivers/pci/host/pcie-mediatek.c
index a8b20c5..c3dc549 100644
--- a/drivers/pci/host/pcie-mediatek.c
+++ b/drivers/pci/host/pcie-mediatek.c
@@ -66,6 +66,10 @@
/* PCIe V2 per-port registers */
#define PCIE_MSI_VECTOR 0x0c0
+
+#define PCIE_CONF_VEND_ID 0x100
+#define PCIE_CONF_CLASS_ID 0x106
+
#define PCIE_INT_MASK 0x420
#define INTX_MASK GENMASK(19, 16)
#define INTX_SHIFT 16
@@ -125,12 +129,14 @@ struct mtk_pcie_port;
/**
* struct mtk_pcie_soc - differentiate between host generations
+ * @need_fix_class_id: whether this host's class ID needed to be fixed or not
* @has_msi: whether this host supports MSI interrupts or not
* @ops: pointer to configuration access functions
* @startup: pointer to controller setting functions
* @setup_irq: pointer to initialize IRQ functions
*/
struct mtk_pcie_soc {
+ bool need_fix_class_id;
bool has_msi;
struct pci_ops *ops;
int (*startup)(struct mtk_pcie_port *port);
@@ -375,6 +381,7 @@ static int mtk_pcie_startup_port_v2(struct mtk_pcie_port *port)
{
struct mtk_pcie *pcie = port->pcie;
struct resource *mem = &pcie->mem;
+ const struct mtk_pcie_soc *soc = port->pcie->soc;
u32 val;
size_t size;
int err;
@@ -403,6 +410,15 @@ static int mtk_pcie_startup_port_v2(struct mtk_pcie_port *port)
PCIE_MAC_SRSTB | PCIE_CRSTB;
writel(val, port->base + PCIE_RST_CTRL);
+ /* Set up vendor ID and class code */
+ if (soc->need_fix_class_id) {
+ val = PCI_VENDOR_ID_MEDIATEK;
+ writew(val, port->base + PCIE_CONF_VEND_ID);
+
+ val = PCI_CLASS_BRIDGE_HOST;
+ writew(val, port->base + PCIE_CONF_CLASS_ID);
+ }
+
/* 100ms timeout value should be enough for Gen1/2 training */
err = readl_poll_timeout(port->base + PCIE_LINK_STATUS_V2, val,
!!(val & PCIE_PORT_LINKUP_V2), 20,
@@ -1142,7 +1158,15 @@ static const struct mtk_pcie_soc mtk_pcie_soc_v1 = {
.startup = mtk_pcie_startup_port,
};
-static const struct mtk_pcie_soc mtk_pcie_soc_v2 = {
+static const struct mtk_pcie_soc mtk_pcie_soc_mt2712 = {
+ .has_msi = true,
+ .ops = &mtk_pcie_ops_v2,
+ .startup = mtk_pcie_startup_port_v2,
+ .setup_irq = mtk_pcie_setup_irq,
+};
+
+static const struct mtk_pcie_soc mtk_pcie_soc_mt7622 = {
+ .need_fix_class_id = true,
.has_msi = true,
.ops = &mtk_pcie_ops_v2,
.startup = mtk_pcie_startup_port_v2,
@@ -1152,8 +1176,8 @@ static const struct mtk_pcie_soc mtk_pcie_soc_v2 = {
static const struct of_device_id mtk_pcie_ids[] = {
{ .compatible = "mediatek,mt2701-pcie", .data = &mtk_pcie_soc_v1 },
{ .compatible = "mediatek,mt7623-pcie", .data = &mtk_pcie_soc_v1 },
- { .compatible = "mediatek,mt2712-pcie", .data = &mtk_pcie_soc_v2 },
- { .compatible = "mediatek,mt7622-pcie", .data = &mtk_pcie_soc_v2 },
+ { .compatible = "mediatek,mt2712-pcie", .data = &mtk_pcie_soc_mt2712 },
+ { .compatible = "mediatek,mt7622-pcie", .data = &mtk_pcie_soc_mt7622 },
{},
};
diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h
index a6b3066..9d4fca5 100644
--- a/include/linux/pci_ids.h
+++ b/include/linux/pci_ids.h
@@ -2115,6 +2115,8 @@
#define PCI_VENDOR_ID_MYRICOM 0x14c1
+#define PCI_VENDOR_ID_MEDIATEK 0x14c3
+
#define PCI_VENDOR_ID_TITAN 0x14D2
#define PCI_DEVICE_ID_TITAN_010L 0x8001
#define PCI_DEVICE_ID_TITAN_100L 0x8010
--
2.6.4
^ permalink raw reply related
* [PATCH v7 2/2] PCI: mediatek: Using chained IRQ to setup IRQ handle
From: honghui.zhang at mediatek.com @ 2018-05-04 5:47 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1525412853-24367-1-git-send-email-honghui.zhang@mediatek.com>
From: Honghui Zhang <honghui.zhang@mediatek.com>
Using irq_chip solution to setup IRQs in order to consist
with IRQ framework.
Signed-off-by: Honghui Zhang <honghui.zhang@mediatek.com>
Acked-by: Ryder Lee <ryder.lee@mediatek.com>
---
drivers/pci/host/pcie-mediatek.c | 206 ++++++++++++++++++++++-----------------
1 file changed, 115 insertions(+), 91 deletions(-)
diff --git a/drivers/pci/host/pcie-mediatek.c b/drivers/pci/host/pcie-mediatek.c
index c3dc549..dabf1086 100644
--- a/drivers/pci/host/pcie-mediatek.c
+++ b/drivers/pci/host/pcie-mediatek.c
@@ -11,8 +11,10 @@
#include <linux/delay.h>
#include <linux/iopoll.h>
#include <linux/irq.h>
+#include <linux/irqchip/chained_irq.h>
#include <linux/irqdomain.h>
#include <linux/kernel.h>
+#include <linux/msi.h>
#include <linux/of_address.h>
#include <linux/of_pci.h>
#include <linux/of_platform.h>
@@ -130,14 +132,12 @@ struct mtk_pcie_port;
/**
* struct mtk_pcie_soc - differentiate between host generations
* @need_fix_class_id: whether this host's class ID needed to be fixed or not
- * @has_msi: whether this host supports MSI interrupts or not
* @ops: pointer to configuration access functions
* @startup: pointer to controller setting functions
* @setup_irq: pointer to initialize IRQ functions
*/
struct mtk_pcie_soc {
bool need_fix_class_id;
- bool has_msi;
struct pci_ops *ops;
int (*startup)(struct mtk_pcie_port *port);
int (*setup_irq)(struct mtk_pcie_port *port, struct device_node *node);
@@ -161,7 +161,9 @@ struct mtk_pcie_soc {
* @lane: lane count
* @slot: port slot
* @irq_domain: legacy INTx IRQ domain
+ * @inner_domain: inner IRQ domain
* @msi_domain: MSI IRQ domain
+ * @lock: protect the msi_irq_in_use bitmap
* @msi_irq_in_use: bit map for assigned MSI IRQ
*/
struct mtk_pcie_port {
@@ -179,7 +181,9 @@ struct mtk_pcie_port {
u32 lane;
u32 slot;
struct irq_domain *irq_domain;
+ struct irq_domain *inner_domain;
struct irq_domain *msi_domain;
+ struct mutex lock;
DECLARE_BITMAP(msi_irq_in_use, MTK_MSI_IRQS_NUM);
};
@@ -446,103 +450,130 @@ static int mtk_pcie_startup_port_v2(struct mtk_pcie_port *port)
return 0;
}
-static int mtk_pcie_msi_alloc(struct mtk_pcie_port *port)
+static void mtk_compose_msi_msg(struct irq_data *data, struct msi_msg *msg)
{
- int msi;
+ struct mtk_pcie_port *port = irq_data_get_irq_chip_data(data);
+ phys_addr_t addr;
- msi = find_first_zero_bit(port->msi_irq_in_use, MTK_MSI_IRQS_NUM);
- if (msi < MTK_MSI_IRQS_NUM)
- set_bit(msi, port->msi_irq_in_use);
- else
- return -ENOSPC;
+ /* MT2712/MT7622 only support 32-bit MSI addresses */
+ addr = virt_to_phys(port->base + PCIE_MSI_VECTOR);
+ msg->address_hi = 0;
+ msg->address_lo = lower_32_bits(addr);
+
+ msg->data = data->hwirq;
- return msi;
+ dev_dbg(port->pcie->dev, "msi#%d address_hi %#x address_lo %#x\n",
+ (int)data->hwirq, msg->address_hi, msg->address_lo);
}
-static void mtk_pcie_msi_free(struct mtk_pcie_port *port, unsigned long hwirq)
+static int mtk_msi_set_affinity(struct irq_data *irq_data,
+ const struct cpumask *mask, bool force)
{
- clear_bit(hwirq, port->msi_irq_in_use);
+ return -EINVAL;
}
-static int mtk_pcie_msi_setup_irq(struct msi_controller *chip,
- struct pci_dev *pdev, struct msi_desc *desc)
+static void mtk_msi_ack_irq(struct irq_data *data)
{
- struct mtk_pcie_port *port;
- struct msi_msg msg;
- unsigned int irq;
- int hwirq;
- phys_addr_t msg_addr;
+ struct mtk_pcie_port *port = irq_data_get_irq_chip_data(data);
+ u32 hwirq = data->hwirq;
- port = mtk_pcie_find_port(pdev->bus, pdev->devfn);
- if (!port)
- return -EINVAL;
+ writel(1 << hwirq, port->base + PCIE_IMSI_STATUS);
+}
- hwirq = mtk_pcie_msi_alloc(port);
- if (hwirq < 0)
- return hwirq;
+static struct irq_chip mtk_msi_bottom_irq_chip = {
+ .name = "MTK MSI",
+ .irq_compose_msi_msg = mtk_compose_msi_msg,
+ .irq_set_affinity = mtk_msi_set_affinity,
+ .irq_ack = mtk_msi_ack_irq,
+};
- irq = irq_create_mapping(port->msi_domain, hwirq);
- if (!irq) {
- mtk_pcie_msi_free(port, hwirq);
- return -EINVAL;
- }
+static int mtk_pcie_irq_domain_alloc(struct irq_domain *domain, unsigned int virq,
+ unsigned int nr_irqs, void *args)
+{
+ struct mtk_pcie_port *port = domain->host_data;
+ unsigned long bit;
- chip->dev = &pdev->dev;
+ WARN_ON(nr_irqs != 1);
+ mutex_lock(&port->lock);
- irq_set_msi_desc(irq, desc);
+ bit = find_first_zero_bit(port->msi_irq_in_use, MTK_MSI_IRQS_NUM);
+ if (bit >= MTK_MSI_IRQS_NUM) {
+ mutex_unlock(&port->lock);
+ return -ENOSPC;
+ }
- /* MT2712/MT7622 only support 32-bit MSI addresses */
- msg_addr = virt_to_phys(port->base + PCIE_MSI_VECTOR);
- msg.address_hi = 0;
- msg.address_lo = lower_32_bits(msg_addr);
- msg.data = hwirq;
+ __set_bit(bit, port->msi_irq_in_use);
+
+ mutex_unlock(&port->lock);
- pci_write_msi_msg(irq, &msg);
+ irq_domain_set_info(domain, virq, bit, &mtk_msi_bottom_irq_chip,
+ domain->host_data, handle_edge_irq,
+ NULL, NULL);
return 0;
}
-static void mtk_msi_teardown_irq(struct msi_controller *chip, unsigned int irq)
+static void mtk_pcie_irq_domain_free(struct irq_domain *domain,
+ unsigned int virq, unsigned int nr_irqs)
{
- struct pci_dev *pdev = to_pci_dev(chip->dev);
- struct irq_data *d = irq_get_irq_data(irq);
- irq_hw_number_t hwirq = irqd_to_hwirq(d);
- struct mtk_pcie_port *port;
+ struct irq_data *d = irq_domain_get_irq_data(domain, virq);
+ struct mtk_pcie_port *port = irq_data_get_irq_chip_data(d);
- port = mtk_pcie_find_port(pdev->bus, pdev->devfn);
- if (!port)
- return;
+ mutex_lock(&port->lock);
+
+ if (!test_bit(d->hwirq, port->msi_irq_in_use))
+ dev_err(port->pcie->dev, "trying to free unused MSI#%lu\n",
+ d->hwirq);
+ else
+ __clear_bit(d->hwirq, port->msi_irq_in_use);
+
+ mutex_unlock(&port->lock);
- irq_dispose_mapping(irq);
- mtk_pcie_msi_free(port, hwirq);
+ irq_domain_free_irqs_parent(domain, virq, nr_irqs);
}
-static struct msi_controller mtk_pcie_msi_chip = {
- .setup_irq = mtk_pcie_msi_setup_irq,
- .teardown_irq = mtk_msi_teardown_irq,
+static const struct irq_domain_ops msi_domain_ops = {
+ .alloc = mtk_pcie_irq_domain_alloc,
+ .free = mtk_pcie_irq_domain_free,
};
static struct irq_chip mtk_msi_irq_chip = {
- .name = "MTK PCIe MSI",
- .irq_enable = pci_msi_unmask_irq,
- .irq_disable = pci_msi_mask_irq,
- .irq_mask = pci_msi_mask_irq,
- .irq_unmask = pci_msi_unmask_irq,
+ .name = "MTK PCIe MSI",
+ .irq_ack = irq_chip_ack_parent,
+ .irq_mask = pci_msi_mask_irq,
+ .irq_unmask = pci_msi_unmask_irq,
};
-static int mtk_pcie_msi_map(struct irq_domain *domain, unsigned int irq,
- irq_hw_number_t hwirq)
+static struct msi_domain_info mtk_msi_domain_info = {
+ .flags = (MSI_FLAG_USE_DEF_DOM_OPS | MSI_FLAG_USE_DEF_CHIP_OPS |
+ MSI_FLAG_PCI_MSIX),
+ .chip = &mtk_msi_irq_chip,
+};
+
+static int mtk_pcie_allocate_msi_domains(struct mtk_pcie_port *port)
{
- irq_set_chip_and_handler(irq, &mtk_msi_irq_chip, handle_simple_irq);
- irq_set_chip_data(irq, domain->host_data);
+ struct fwnode_handle *fwnode = of_node_to_fwnode(port->pcie->dev->of_node);
+
+ mutex_init(&port->lock);
+
+ port->inner_domain = irq_domain_create_linear(fwnode, MTK_MSI_IRQS_NUM,
+ &msi_domain_ops, port);
+ if (!port->inner_domain) {
+ dev_err(port->pcie->dev, "failed to create IRQ domain\n");
+ return -ENOMEM;
+ }
+
+ port->msi_domain = pci_msi_create_irq_domain(fwnode, &mtk_msi_domain_info,
+ port->inner_domain);
+ if (!port->msi_domain) {
+ dev_err(port->pcie->dev, "failed to create MSI domain\n");
+ irq_domain_remove(port->inner_domain);
+ return -ENOMEM;
+ }
return 0;
}
-static const struct irq_domain_ops msi_domain_ops = {
- .map = mtk_pcie_msi_map,
-};
-
static void mtk_pcie_enable_msi(struct mtk_pcie_port *port)
{
u32 val;
@@ -575,6 +606,7 @@ static int mtk_pcie_init_irq_domain(struct mtk_pcie_port *port,
{
struct device *dev = port->pcie->dev;
struct device_node *pcie_intc_node;
+ int ret;
/* Setup INTx */
pcie_intc_node = of_get_next_child(node, NULL);
@@ -591,27 +623,28 @@ static int mtk_pcie_init_irq_domain(struct mtk_pcie_port *port,
}
if (IS_ENABLED(CONFIG_PCI_MSI)) {
- port->msi_domain = irq_domain_add_linear(node, MTK_MSI_IRQS_NUM,
- &msi_domain_ops,
- &mtk_pcie_msi_chip);
- if (!port->msi_domain) {
- dev_err(dev, "failed to create MSI IRQ domain\n");
- return -ENODEV;
- }
+ ret = mtk_pcie_allocate_msi_domains(port);
+ if (ret)
+ return ret;
+
mtk_pcie_enable_msi(port);
}
return 0;
}
-static irqreturn_t mtk_pcie_intr_handler(int irq, void *data)
+static void mtk_pcie_intr_handler(struct irq_desc *desc)
{
- struct mtk_pcie_port *port = (struct mtk_pcie_port *)data;
+ struct mtk_pcie_port *port = irq_desc_get_handler_data(desc);
+ struct irq_chip *irqchip = irq_desc_get_chip(desc);
unsigned long status;
u32 virq;
u32 bit = INTX_SHIFT;
- while ((status = readl(port->base + PCIE_INT_STATUS)) & INTX_MASK) {
+ chained_irq_enter(irqchip, desc);
+
+ status = readl(port->base + PCIE_INT_STATUS);
+ if (status & INTX_MASK) {
for_each_set_bit_from(bit, &status, PCI_NUM_INTX + INTX_SHIFT) {
/* Clear the INTx */
writel(1 << bit, port->base + PCIE_INT_STATUS);
@@ -622,14 +655,12 @@ static irqreturn_t mtk_pcie_intr_handler(int irq, void *data)
}
if (IS_ENABLED(CONFIG_PCI_MSI)) {
- while ((status = readl(port->base + PCIE_INT_STATUS)) & MSI_STATUS) {
+ if (status & MSI_STATUS){
unsigned long imsi_status;
while ((imsi_status = readl(port->base + PCIE_IMSI_STATUS))) {
for_each_set_bit(bit, &imsi_status, MTK_MSI_IRQS_NUM) {
- /* Clear the MSI */
- writel(1 << bit, port->base + PCIE_IMSI_STATUS);
- virq = irq_find_mapping(port->msi_domain, bit);
+ virq = irq_find_mapping(port->inner_domain, bit);
generic_handle_irq(virq);
}
}
@@ -638,7 +669,9 @@ static irqreturn_t mtk_pcie_intr_handler(int irq, void *data)
}
}
- return IRQ_HANDLED;
+ chained_irq_exit(irqchip, desc);
+
+ return;
}
static int mtk_pcie_setup_irq(struct mtk_pcie_port *port,
@@ -649,20 +682,15 @@ static int mtk_pcie_setup_irq(struct mtk_pcie_port *port,
struct platform_device *pdev = to_platform_device(dev);
int err, irq;
- irq = platform_get_irq(pdev, port->slot);
- err = devm_request_irq(dev, irq, mtk_pcie_intr_handler,
- IRQF_SHARED, "mtk-pcie", port);
- if (err) {
- dev_err(dev, "unable to request IRQ %d\n", irq);
- return err;
- }
-
err = mtk_pcie_init_irq_domain(port, node);
if (err) {
dev_err(dev, "failed to init PCIe IRQ domain\n");
return err;
}
+ irq = platform_get_irq(pdev, port->slot);
+ irq_set_chained_handler_and_data(irq, mtk_pcie_intr_handler, port);
+
return 0;
}
@@ -1096,8 +1124,6 @@ static int mtk_pcie_register_host(struct pci_host_bridge *host)
host->map_irq = of_irq_parse_and_map_pci;
host->swizzle_irq = pci_common_swizzle;
host->sysdata = pcie;
- if (IS_ENABLED(CONFIG_PCI_MSI) && pcie->soc->has_msi)
- host->msi = &mtk_pcie_msi_chip;
err = pci_scan_root_bus_bridge(host);
if (err < 0)
@@ -1159,7 +1185,6 @@ static const struct mtk_pcie_soc mtk_pcie_soc_v1 = {
};
static const struct mtk_pcie_soc mtk_pcie_soc_mt2712 = {
- .has_msi = true,
.ops = &mtk_pcie_ops_v2,
.startup = mtk_pcie_startup_port_v2,
.setup_irq = mtk_pcie_setup_irq,
@@ -1167,7 +1192,6 @@ static const struct mtk_pcie_soc mtk_pcie_soc_mt2712 = {
static const struct mtk_pcie_soc mtk_pcie_soc_mt7622 = {
.need_fix_class_id = true,
- .has_msi = true,
.ops = &mtk_pcie_ops_v2,
.startup = mtk_pcie_startup_port_v2,
.setup_irq = mtk_pcie_setup_irq,
--
2.6.4
^ permalink raw reply related
* [PATCH v5 00/14] CPU scaling support for msm8996
From: Viresh Kumar @ 2018-05-04 6:00 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1525348355-25471-1-git-send-email-ilialin@codeaurora.org>
On 03-05-18, 14:52, Ilia Lin wrote:
> [v5]
> * Rebased
> * Adressed comments from Bjorn
> * Adressed comments from Viresh
> * Adressed comments from Sricharan
> * Adressed comments from Nicolas
> * Adressed comments from Rob
> * Adressed comments from Mark
s/Adressed/Addressed/
And that's not how the history should be present here. I don't have
any clue on what I commented on in the previous versions. Now that
there is no clear history available, I need to go look at my previous
replies to understand that. That's not right.
You should mention the exact changes here and you can include the name
of the reviewer in parenthesis. Like this:
* Replaced kmalloc with kzalloc (Viresh).
--
viresh
^ permalink raw reply
* [PATCH v4 08/14] dt: qcom: Add opp and thermal to the msm8996
From: Viresh Kumar @ 2018-05-04 6:04 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180402091617.GA3572@vireshk-i7>
On 2 April 2018 at 14:46, Viresh Kumar <viresh.kumar@linaro.org> wrote:
>> + cluster0_opp: opp_table0 {
>> + compatible = "operating-points-v2";
>> + opp-shared;
>
> Is Kryo like krait where CPUs do DVFS independently ? If yes, then opp-shared
> thing should be dropped.
Have you ever replied to this question ? Sorry, but I am not able to
find it in my inbox :(
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox