* [PATCH 1/4] dt-bindings: pinctrl: add bindings for MediaTek MT7622 SoC
From: sean.wang-NuS5LvNUpcJWk0Htik3J/w @ 2017-11-28 3:49 UTC (permalink / raw)
To: robh+dt-DgEjT+Ai2ygdnm+yROfE0A, mark.rutland-5wv7dgnIgG8,
linus.walleij-QSEj5FYQhm4dnm+yROfE0A,
matthias.bgg-Re5JQEeQqe8AvxtiuMwx3w,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-mediatek-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
Cc: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-gpio-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA, Sean Wang
In-Reply-To: <cover.1511840374.git.sean.wang-NuS5LvNUpcJWk0Htik3J/w@public.gmane.org>
From: Sean Wang <sean.wang-NuS5LvNUpcJWk0Htik3J/w@public.gmane.org>
Add devicetree bindings for MediaTek MT7622 pinctrl driver.
Signed-off-by: Sean Wang <sean.wang-NuS5LvNUpcJWk0Htik3J/w@public.gmane.org>
---
.../devicetree/bindings/pinctrl/pinctrl-mt7622.txt | 330 +++++++++++++++++++++
1 file changed, 330 insertions(+)
create mode 100644 Documentation/devicetree/bindings/pinctrl/pinctrl-mt7622.txt
diff --git a/Documentation/devicetree/bindings/pinctrl/pinctrl-mt7622.txt b/Documentation/devicetree/bindings/pinctrl/pinctrl-mt7622.txt
new file mode 100644
index 0000000..ce86d45
--- /dev/null
+++ b/Documentation/devicetree/bindings/pinctrl/pinctrl-mt7622.txt
@@ -0,0 +1,330 @@
+== MediaTek MT7622 pinctrl controller ==
+
+Required properties for the root node:
+ - compatible: Should be one of the following
+ "mediatek,mt7622-pinctrl" for MT7622 SoC
+ - reg: offset and length of the pinctrl space
+
+ - gpio-controller: Marks the device node as a GPIO controller.
+ - #gpio-cells: Should be two. The first cell is the pin number and the
+ second is the GPIO flags.
+
+Please refer to pinctrl-bindings.txt in this directory for details of the
+common pinctrl bindings used by client devices, including the meaning of the
+phrase "pin configuration node".
+
+MT7622 pin configuration nodes act as a container for an arbitrary number of
+subnodes. Each of these subnodes represents some desired configuration for a
+pin, a group, or a list of pins or groups. This configuration can include the
+mux function to select on those pin(s)/group(s), and various pin configuration
+parameters, such as pull-up, slew rate, etc.
+
+We support 2 types of configuration nodes. Those nodes can be either pinmux
+nodes or pinconf nodes. Each configuration node can consist of multiple nodes
+describing the pinmux and pinconf options.
+
+The name of each subnode is no matter as long as it is unique; all subnodes
+should be enumerated and processed purely based on their content.
+
+== pinmux nodes content ==
+
+The following generic properties as defined in pinctrl-bindings.txt are valid
+to specify in a pinmux subnode:
+
+Required properties are:
+ - groups: An array of strings. Each string contains the name of a group.
+ Valid values for these names are listed below.
+ - function: A string containing the name of the function to mux to the
+ group. Valid values for function names are listed below.
+
+== pinconf nodes content ==
+
+The following generic properties as defined in pinctrl-bindings.txt are valid
+to specify in a pinconf subnode:
+
+Required properties are:
+ - pins: An array of strings. Each string contains the name of a pin.
+ Valid values for these names are listed below.
+ - groups: An array of strings. Each string contains the name of a group.
+ Valid values for these names are listed below.
+
+Optional properies are:
+ bias-disable, bias-pull, bias-pull-down, input-enable,
+ input-schmitt-enable, input-schmitt-disable, output-enable
+ output-low, output-high, drive-strength, slew-rate
+
+ Valid arguments for 'slew-rate' are '0' and '1' to select between slow and
+ fast respectively.
+ Valid arguments for 'drive-strength', 4, 8, 12, or 16 in mA.
+
+The following specific properties as defined are valid to specify in a pinconf
+subnode:
+
+Optional properties are:
+ - mediatek,tdsel: Valid arguments are from 0 to 15
+ - mediatek,rdsel: Valid arguments are from 0 to 63
+
+== Valid values for pins, function and groups on MT7622 ==
+
+Valid values for pins are:
+pins can be referenced via the pin names as the below table shown and the
+related physical number is also put ahead of those names which helps cross
+references to pins between groups to know whether pins assignment conflict
+happens among devices try to acquire those available pins.
+
+ Pin #: Valid values for pins
+ -----------------------------
+ PIN 0: "GPIO_A"
+ PIN 1: "I2S1_IN"
+ PIN 2: "I2S1_OUT"
+ PIN 3: "I2S_BCLK"
+ PIN 4: "I2S_WS"
+ PIN 5: "I2S_MCLK"
+ PIN 6: "TXD0"
+ PIN 7: "RXD0"
+ PIN 8: "SPI_WP"
+ PIN 9: "SPI_HOLD"
+ PIN 10: "SPI_CLK"
+ PIN 11: "SPI_MOSI"
+ PIN 12: "SPI_MISO"
+ PIN 13: "SPI_CS"
+ PIN 14: "SPI_SDA"
+ PIN 15: "SPI_SCL"
+ PIN 16: "I2S2_IN"
+ PIN 17: "I2S3_IN"
+ PIN 18: "I2S4_IN"
+ PIN 19: "I2S2_OUT"
+ PIN 20: "I2S3_OUT"
+ PIN 21: "I2S4_OUT"
+ PIN 22: "GPIO_B"
+ PIN 23: "MDC"
+ PIN 24: "MDIO"
+ PIN 25: "G2_TXD0"
+ PIN 26: "G2_TXD1"
+ PIN 27: "G2_TXD2"
+ PIN 28: "G2_TXD3"
+ PIN 29: "G2_TXEN"
+ PIN 30: "G2_TXC"
+ PIN 31: "G2_RXD0"
+ PIN 32: "G2_RXD1"
+ PIN 33: "G2_RXD2"
+ PIN 34: "G2_RXD3"
+ PIN 35: "G2_RXDV"
+ PIN 36: "G2_RXC"
+ PIN 37: "NCEB"
+ PIN 38: "NWEB"
+ PIN 39: "NREB"
+ PIN 40: "NDL4"
+ PIN 41: "NDL5"
+ PIN 42: "NDL6"
+ PIN 43: "NDL7"
+ PIN 44: "NRB"
+ PIN 45: "NCLE"
+ PIN 46: "NALE"
+ PIN 47: "NDL0"
+ PIN 48: "NDL1"
+ PIN 49: "NDL2"
+ PIN 50: "NDL3"
+ PIN 51: "MDI_TP_P0"
+ PIN 52: "MDI_TN_P0"
+ PIN 53: "MDI_RP_P0"
+ PIN 54: "MDI_RN_P0"
+ PIN 55: "MDI_TP_P1"
+ PIN 56: "MDI_TN_P1"
+ PIN 57: "MDI_RP_P1"
+ PIN 58: "MDI_RN_P1"
+ PIN 59: "MDI_RP_P2"
+ PIN 60: "MDI_RN_P2"
+ PIN 61: "MDI_TP_P2"
+ PIN 62: "MDI_TN_P2"
+ PIN 63: "MDI_TP_P3"
+ PIN 64: "MDI_TN_P3"
+ PIN 65: "MDI_RP_P3"
+ PIN 66: "MDI_RN_P3"
+ PIN 67: "MDI_RP_P4"
+ PIN 68: "MDI_RN_P4"
+ PIN 69: "MDI_TP_P4"
+ PIN 70: "MDI_TN_P4"
+ PIN 71: "SPI2_CK"
+ PIN 72: "SPI2_DATA"
+ PIN 73: "SPIC1_CLK"
+ PIN 74: "SPIC1_MOSI"
+ PIN 75: "SPIC1_MISO"
+ PIN 76: "SPIC1_CS"
+ PIN 77: "GPIO_D"
+ PIN 78: "WATCHDOG"
+ PIN 79: "RTS3_N"
+ PIN 80: "CTS3_N"
+ PIN 81: "TXD3"
+ PIN 82: "RXD3"
+ PIN 83: "PERST0_N"
+ PIN 84: "PERST1_N"
+ PIN 85: "WLED_N"
+ PIN 86: "EPHY_LED0_N"
+ PIN 87: "AUXIN0"
+ PIN 88: "AUXIN1"
+ PIN 89: "AUXIN2"
+ PIN 90: "AUXIN3"
+ PIN 91: "TXD4"
+ PIN 92: "RXD4"
+ PIN 93: "RTS4_IN"
+ PIN 94: "CST4_IN"
+ PIN 95: "PWM1"
+ PIN 96: "PWM2"
+ PIN 97: "PWM3"
+ PIN 98: "PWM4"
+ PIN 99: "PWM5"
+ PIN 100: "PWM6"
+ PIN 101: "PWM7"
+ PIN 102: "GPIO_E"
+
+Valid values for function are:
+ "emmc", "eth", "i2c", "i2s", "ir", "led", "flash", "pcie",
+ "pwm", "sd", "spi", "tdm", "uart"
+
+Valid values for groups are:
+additional data is put followingly with valid value allowing us to know which
+applicable function and which relevant pins (in pin#) are able applied for that
+group.
+
+ Valid value function pins (in pin#)
+ -------------------------------------------------------------------------
+ "emmc" "emmc" 40, 41, 42, 43, 44, 45,
+ 47, 48, 49, 50
+ "esw" "eth" 59, 60, 61, 62, 63, 64,
+ 65, 66, 67, 68, 69, 70
+ "mdc_mdio" "eth" 23, 24
+ "gmac1" "eth" 59, 60, 61, 62, 63, 64,
+ 65, 66, 67, 68, 69, 70
+ "gmac2" "eth" 25, 26, 27, 28, 29, 30,
+ 31, 32, 33, 34, 35, 36
+ "i2c0" "i2c" 14, 15
+ "i2c1_0" "i2c" 55, 56
+ "i2c1_1" "i2c" 73, 74
+ "i2c1_2" "i2c" 87, 88
+ "i2c2_0" "i2c" 57, 58
+ "i2c2_1" "i2c" 75, 76
+ "i2c2_2" "i2c" 89, 90
+ "i2s_in_bclk_ws_mclk" "i2s" 3, 4, 5
+ "i2s1_in_data" "i2s" 1
+ "i2s2_in_data" "i2s" 16
+ "i2s3_in_data" "i2s" 17
+ "i2s4_in_data" "i2s" 18
+ "i2s_out_bclk_ws_mclk" "i2s" 3, 4, 5
+ "i2s1_out_data" "i2s" 2
+ "i2s2_out_data" "i2s" 19
+ "i2s3_out_data" "i2s" 20
+ "i2s4_out_data" "i2s" 21
+ "ir_0_tx" "ir" 16
+ "ir_1_tx" "ir" 59
+ "ir_2_tx" "ir" 99
+ "ir_0_rx" "ir" 17
+ "ir_1_rx" "ir" 60
+ "ir_2_rx" "ir" 100
+ "ephy0_led" "led" 86
+ "ephy1_led" "led" 91
+ "ephy2_led" "led" 92
+ "ephy3_led" "led" 93
+ "ephy4_led" "led" 94
+ "wled" "led" 85
+ "par_nand" "flash" 37, 38, 39, 40, 41, 42,
+ 43, 44, 45, 46, 47, 48,
+ 49, 50
+ "snfi" "flash" 8, 9, 10, 11, 12, 13
+ "spi_nor" "flash" 8, 9, 10, 11, 12, 13
+ "pcie0_0_waken_clkreq" "pcie" 14, 15
+ "pcie0_1_waken_clkreq" "pcie" 79, 80
+ "pcie1_0_waken_clkreq" "pcie" 14, 15
+ "pcie0_pad_perst" "pcie" 83
+ "pcie1_pad_perst" "pcie" 84
+ "pwm_ch1_0" "pwm" 51
+ "pwm_ch1_1" "pwm" 73
+ "pwm_ch1_2" "pwm" 95
+ "pwm_ch2_0" "pwm" 52
+ "pwm_ch2_1" "pwm" 74
+ "pwm_ch2_2" "pwm" 96
+ "pwm_ch3_0" "pwm" 53
+ "pwm_ch3_1" "pwm" 75
+ "pwm_ch3_2" "pwm" 97
+ "pwm_ch4_0" "pwm" 54
+ "pwm_ch4_1" "pwm" 67
+ "pwm_ch4_2" "pwm" 76
+ "pwm_ch4_3" "pwm" 98
+ "pwm_ch5_0" "pwm" 68
+ "pwm_ch5_1" "pwm" 77
+ "pwm_ch5_2" "pwm" 99
+ "pwm_ch6_0" "pwm" 69
+ "pwm_ch6_1" "pwm" 78
+ "pwm_ch6_2" "pwm" 81
+ "pwm_ch6_3" "pwm" 100
+ "pwm_ch7_0" "pwm" 70
+ "pwm_ch7_1" "pwm" 82
+ "pwm_ch7_2" "pwm" 101
+ "sd_0" "sd" 16, 17, 18, 19, 20, 21
+ "sd_1" "sd" 25, 26, 27, 28, 29, 30
+ "spic0_0" "spi" 63, 64, 65, 66
+ "spic0_1" "spi" 79, 80, 81, 82
+ "spic1_0" "spi" 67, 68, 69, 70
+ "spic1_1" "spi" 73, 74, 75, 76
+ "tdm_0_out_mclk_bclk" "tdm" 8, 9, 10
+ "tdm_0_in_mclk_bclk_ws" "tdm" 11, 12, 13
+ "tdm_0_out_data" "tdm" 20
+ "tdm_0_in_data" "tdm" 21
+ "tdm_1_out_mclk_bclk" "tdm" 57, 58, 59
+ "tdm_1_in_mclk_bclk_ws" "tdm" 60, 61, 62
+ "tdm_1_out_data" "tdm" 55
+ "tdm_1_in_data" "tdm" 56
+ "uart0_0_tx_rx" "uart" 6, 7
+ "uart1_0_tx_rx" "uart" 55, 56
+ "uart1_0_rts_cts" "uart" 57, 58
+ "uart1_1_tx_rx" "uart" 73, 74
+ "uart1_1_rts_cts" "uart" 75, 76
+ "uart2_0_tx_rx" "uart" 3, 4
+ "uart2_0_rts_cts" "uart" 1, 2
+ "uart2_1_tx_rx" "uart" 51, 52
+ "uart2_1_rts_cts" "uart" 53, 54
+ "uart2_2_tx_rx" "uart" 59, 60
+ "uart2_2_rts_cts" "uart" 61, 62
+ "uart2_3_tx_rx" "uart" 95, 96
+ "uart3_0_tx_rx" "uart" 57, 58
+ "uart3_1_tx_rx" "uart" 81, 82
+ "uart3_1_rts_cts" "uart" 79, 80
+ "uart4_0_tx_rx" "uart" 61, 62
+ "uart4_1_tx_rx" "uart" 91, 92
+ "uart4_1_rts_cts" "uart" 93, 94
+ "uart4_2_tx_rx" "uart" 97, 98
+ "uart4_2_rts_cts" "uart" 95, 96
+
+Example:
+
+ pio: pinctrl@10211000 {
+ compatible = "mediatek,mt7622-pinctrl";
+ reg = <0 0x10211000 0 0x1000>;
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ pinctrl_eth_default: eth-default {
+ mux_mdio {
+ groups = "mdc_mdio";
+ function = "eth";
+ drive-strength = <12>;
+ };
+
+ mux_gmac2 {
+ groups = "gmac2";
+ function = "eth";
+ drive-strength = <12>;
+ };
+
+ mux_esw {
+ groups = "esw";
+ function = "eth";
+ drive-strength = <8>;
+ };
+
+ conf_mdio {
+ pins = "MDC";
+ bias-pull-up;
+ };
+ };
+ };
--
2.7.4
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* [PATCH 0/4] add support of pinctrl to MT7622 SoC
From: sean.wang @ 2017-11-28 3:49 UTC (permalink / raw)
To: robh+dt, mark.rutland, linus.walleij, matthias.bgg, devicetree,
linux-mediatek
Cc: linux-arm-kernel, linux-gpio, linux-kernel, Sean Wang
From: Sean Wang <sean.wang@mediatek.com>
The patchset adds support for pinctrl on MT7622 SoC.
patch 1: describe the hardware, also including the defintion for pins,
groups and function.
patch 2: add cleanup for keep drivers inside the independent menu.
patch 3/4: add support for mt7622 SoC.
The IO core found on the SoC has the registers for pinctrl, pinconf and
gpio mixed up in the same register range.
However, the IO core for the MT7622 SoC is completely distinct from
anyone of previous MediaTek SoCs which already had support, such as the
hardware internal, register address map and register detailed definition
for each pin.
Therefore, instead, the driver is being newly implemented by reusing
generic methods provided from the core layer with GENERIC_PINCONF,
GENERIC_PINCTRL_GROUPS, and GENERIC_PINMUX_FUNCTIONS for the sake of code
simplicity and avoiding superfluous code. Where the function of pins
determined by groups is utilized in this driver which can help developers
less confused with what combinations of pins effective on the SoC and
even reducing the mistakes during the integration of those relevant
boards.
As the gpio_chip handling is also only a few lines, the driver also
implements the gpio functionality directly through GPIOLIB.
Sean Wang (4):
dt-bindings: pinctrl: add bindings for MediaTek MT7622 SoC
pinctrl: mediatek: cleanup for placing all drivers under the menu
pinctrl: mediatek: add pinctrl driver for MT7622 SoC
pinctrl: mediatek: update MAINTAINERS entry with MediaTek pinctrl
driver
.../devicetree/bindings/pinctrl/pinctrl-mt7622.txt | 330 +++++
MAINTAINERS | 10 +
drivers/pinctrl/Makefile | 2 +-
drivers/pinctrl/mediatek/Kconfig | 15 +-
drivers/pinctrl/mediatek/Makefile | 3 +-
drivers/pinctrl/mediatek/pinctrl-mt7622.c | 1536 ++++++++++++++++++++
6 files changed, 1892 insertions(+), 4 deletions(-)
create mode 100644 Documentation/devicetree/bindings/pinctrl/pinctrl-mt7622.txt
create mode 100644 drivers/pinctrl/mediatek/pinctrl-mt7622.c
--
2.7.4
^ permalink raw reply
* Re: [PATCH v2 29/35] dt-bindings: nds32 CPU Bindings
From: Greentime Hu @ 2017-11-28 3:18 UTC (permalink / raw)
To: Mark Rutland
Cc: Greentime, Linux Kernel Mailing List, Arnd Bergmann, linux-arch,
Thomas Gleixner, Jason Cooper, Marc Zyngier, Rob Herring, netdev,
Vincent Chen, DTML, Al Viro, David Howells, Will Deacon,
Daniel Lezcano, linux-serial-u79uwXL29TY76Z2rM5mHXA, Vincent Chen,
Rick Chen, Zong Li
In-Reply-To: <20171127134232.q343uymer47zt74m-agMKViyK24J5pKCnmE3YQBJ8xKzm50AiAL8bYrjMMd8@public.gmane.org>
2017-11-27 21:42 GMT+08:00 Mark Rutland <mark.rutland-5wv7dgnIgG8@public.gmane.org>:
> Him
>
> On Mon, Nov 27, 2017 at 08:28:16PM +0800, Greentime Hu wrote:
>> From: Greentime Hu <greentime-MUIXKm3Oiri1Z/+hSey0Gg@public.gmane.org>
>>
>> This patch adds nds32 CPU binding documents.
>>
>> Signed-off-by: Vincent Chen <vincentc-MUIXKm3Oiri1Z/+hSey0Gg@public.gmane.org>
>> Signed-off-by: Rick Chen <rick-MUIXKm3Oiri1Z/+hSey0Gg@public.gmane.org>
>> Signed-off-by: Zong Li <zong-MUIXKm3Oiri1Z/+hSey0Gg@public.gmane.org>
>> Signed-off-by: Greentime Hu <greentime-MUIXKm3Oiri1Z/+hSey0Gg@public.gmane.org>
>> ---
>> Documentation/devicetree/bindings/nds32/cpus.txt | 32 ++++++++++++++++++++++
>> 1 file changed, 32 insertions(+)
>> create mode 100644 Documentation/devicetree/bindings/nds32/cpus.txt
>>
>> diff --git a/Documentation/devicetree/bindings/nds32/cpus.txt b/Documentation/devicetree/bindings/nds32/cpus.txt
>> new file mode 100644
>> index 0000000..c302c89
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/nds32/cpus.txt
>> @@ -0,0 +1,32 @@
>> +* Andestech Processor Binding
>> +
>> +This binding specifies what properties must be available in the device tree
>> +representation of a Andestech Processor Core, which is the root node in the
>> +tree.
>> +
>> +Required properties:
>> +
>> + - compatible:
>> + Usage: required
>> + Value type: <string>
>> + Definition: should be one of:
>> + "andestech,n13"
>> + "andestech,n15"
>> + "andestech,d15"
>> + "andestech,n10"
>> + "andestech,d10"
>> + "andestech,nds32v3"
>
> Are these specific parts, or architecture versions?
>
> I guess "andestech,nds32v3" is an architecture version, and the rest are
> specific parts?
Yes, nds32v3 is an architecture version and the rest are nds32v3
compatible processor's name.
>> + - device_type
>> + Usage: required
>> + Value type: <string>
>> + Definition: must be "cpu"
>> + - clock-frequency: Contains the clock frequency for CPU, in Hz.
>> +
>> +* Examples
>> +
>> +/ {
>> + cpu {
>> + device_type = "cpu";
>> + compatible = "andestech,n13", "andestech,nds32v3";
>> + };
>
> This is missing the required clock-frequency property.
>
> There should be a /cpus node, with each CPU listed under that, to align
> with the devicetree spec. Even if you never support SMP, there's no
> reason to be different from other architectures.
>
> You should have something like:
>
> / {
> cpus {
> cpu {
> device_type = "cpu";
> compatible = "andestech,n13";
> clock-frequency = <...>;
> };
> };
> };
>
> Thanks,
> Mark.
Thanks.
I will modify it in the next version patch.
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [PATCH v2 30/35] net: faraday add nds32 support.
From: Greentime Hu @ 2017-11-28 2:55 UTC (permalink / raw)
To: Arnd Bergmann
Cc: Greentime, Linux Kernel Mailing List, linux-arch, Thomas Gleixner,
Jason Cooper, Marc Zyngier, Rob Herring, Networking, Vincent Chen,
DTML, Al Viro, David Howells, Will Deacon, Daniel Lezcano,
linux-serial-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <CAK8P3a2GJERt78uWgdDy+Azr-ZMcOcB+D6Akq99tSfwKmt2LiA-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2017-11-27 22:15 GMT+08:00 Arnd Bergmann <arnd-r2nGTMty4D4@public.gmane.org>:
> On Mon, Nov 27, 2017 at 1:28 PM, Greentime Hu <green.hu-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:
>> From: Greentime Hu <greentime-MUIXKm3Oiri1Z/+hSey0Gg@public.gmane.org>
>>
>> Signed-off-by: Greentime Hu <greentime-MUIXKm3Oiri1Z/+hSey0Gg@public.gmane.org>
>
> This is missing a patch description.
>
Thanks.
Sorry. I miss it. I will add the commit messages in the next version patch.
>> diff --git a/drivers/net/ethernet/faraday/Kconfig b/drivers/net/ethernet/faraday/Kconfig
>> index 040c7f1..0ae6e9a 100644
>> --- a/drivers/net/ethernet/faraday/Kconfig
>> +++ b/drivers/net/ethernet/faraday/Kconfig
>> @@ -5,7 +5,7 @@
>> config NET_VENDOR_FARADAY
>> bool "Faraday devices"
>> default y
>> - depends on ARM
>> + depends on ARM || NDS32
>> ---help---
>> If you have a network (Ethernet) card belonging to this class, say Y.
>>
>
> We probably want to make all three here
>
> depends on ARM || NDS32 || COMPILE_TEST
>
Thanks.
I will modify it in the next version patch.
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [PATCH v2 34/35] clocksource/drivers/Kconfig: Support andestech atcpit100 timer
From: Greentime Hu @ 2017-11-28 2:53 UTC (permalink / raw)
To: Arnd Bergmann
Cc: Greentime, Linux Kernel Mailing List, linux-arch, Thomas Gleixner,
Jason Cooper, Marc Zyngier, Rob Herring, Networking, Vincent Chen,
DTML, Al Viro, David Howells, Will Deacon, Daniel Lezcano,
linux-serial-u79uwXL29TY76Z2rM5mHXA, Rick Chen
In-Reply-To: <CAK8P3a2ovDuwWCq2HABZaCVGO04TX0VdgnQbK65RvHhsMEzsiw-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2017-11-27 22:11 GMT+08:00 Arnd Bergmann <arnd-r2nGTMty4D4@public.gmane.org>:
> On Mon, Nov 27, 2017 at 1:28 PM, Greentime Hu <green.hu-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:
>> From: Rick Chen <rickchen36-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
>>
>> Add CLKSRC_ATCPIT100 for Andestech atcpit100 timer selection.
>> It often be used in Andestech AE3XX platform.
>>
>> Signed-off-by: Rick Chen <rickchen36-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
>> Signed-off-by: Greentime Hu <green.hu-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
>
> No need to split out the Makefile patch from the actual driver, they
> clearly belong together.
> The binding change should be a separate patch, as you did.
>
> It's probably best to separate the driver patches from the
> architecture submission
> in the future, they can simply get merged by the respective subsystem
> maintainers,
> with a smaller Cc list.
>
Hi, Arnd:
Thanks.
We will merge these 2 patches together in the next version patch.
We will sent to clocksource subsystem with a seperate patchset.
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* [PATCH v2 2/2] clocksource: sprd: Add timer driver for Spreadtrum SC9860 platform
From: Baolin Wang @ 2017-11-28 2:45 UTC (permalink / raw)
To: daniel.lezcano, tglx, robh+dt, mark.rutland
Cc: devicetree, linux-kernel, broonie, baolin.wang, baolin.wang
In-Reply-To: <1b80566bd849d68b0fc8de54ecbbc7b4efbb1077.1511836284.git.baolin.wang@spreadtrum.com>
The Spreadtrum SC9860 platform will use the architected timers as local
clock events, but we also need a broadcast timer device to wakeup the
cpus when the cpus are in sleep mode.
Thus this patch registers the timer0 to be a broadcast timer supporting
periodic and oneshot events.
Signed-off-by: Baolin Wang <baolin.wang@spreadtrum.com>
---
Changes since v1:
- Change to 32bit counter to avoid build warning.
---
drivers/clocksource/Kconfig | 8 ++
drivers/clocksource/Makefile | 1 +
drivers/clocksource/sprd-timer.c | 211 ++++++++++++++++++++++++++++++++++++++
3 files changed, 220 insertions(+)
create mode 100644 drivers/clocksource/sprd-timer.c
diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
index c729a88..48c8702 100644
--- a/drivers/clocksource/Kconfig
+++ b/drivers/clocksource/Kconfig
@@ -441,6 +441,14 @@ config MTK_TIMER
help
Support for Mediatek timer driver.
+config SPRD_TIMER
+ bool "Spreadtrum timer driver"
+ depends on GENERIC_CLOCKEVENTS
+ depends on ARCH_SPRD || COMPILE_TEST
+ select TIMER_OF
+ help
+ Enables the support for the Spreadtrum timer driver.
+
config SYS_SUPPORTS_SH_MTU2
bool
diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile
index 72711f1..62bf264 100644
--- a/drivers/clocksource/Makefile
+++ b/drivers/clocksource/Makefile
@@ -54,6 +54,7 @@ obj-$(CONFIG_CLKSRC_TI_32K) += timer-ti-32k.o
obj-$(CONFIG_CLKSRC_NPS) += timer-nps.o
obj-$(CONFIG_OXNAS_RPS_TIMER) += timer-oxnas-rps.o
obj-$(CONFIG_OWL_TIMER) += owl-timer.o
+obj-$(CONFIG_SPRD_TIMER) += sprd-timer.o
obj-$(CONFIG_ARC_TIMERS) += arc_timer.o
obj-$(CONFIG_ARM_ARCH_TIMER) += arm_arch_timer.o
diff --git a/drivers/clocksource/sprd-timer.c b/drivers/clocksource/sprd-timer.c
new file mode 100644
index 0000000..e90f948
--- /dev/null
+++ b/drivers/clocksource/sprd-timer.c
@@ -0,0 +1,211 @@
+/*
+ * Copyright (C) 2017 Spreadtrum Communications Inc.
+ *
+ * SPDX-License-Identifier: GPL-2.0
+ */
+
+#include <linux/clocksource.h>
+#include <linux/clockchips.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/sched_clock.h>
+#include <linux/slab.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+
+#define TIMER_NAME "sprd_timer"
+
+#define TIMER_LOAD_LO 0x0
+#define TIMER_LOAD_HI 0x4
+#define TIMER_VALUE_LO 0x8
+#define TIMER_VALUE_HI 0xc
+
+#define TIMER_CTL 0x10
+#define TIMER_CTL_PERIOD_MODE BIT(0)
+#define TIMER_CTL_ENABLE BIT(1)
+#define TIMER_CTL_64BIT_WIDTH BIT(16)
+
+#define TIMER_INT 0x14
+#define TIMER_INT_EN BIT(0)
+#define TIMER_INT_RAW_STS BIT(1)
+#define TIMER_INT_MASK_STS BIT(2)
+#define TIMER_INT_CLR BIT(3)
+
+#define TIMER_VALUE_SHDW_LO 0x18
+#define TIMER_VALUE_SHDW_HI 0x1c
+
+#define TIMER_VALUE_LO_MASK GENMASK(31, 0)
+
+struct sprd_timer_device {
+ struct clock_event_device ce;
+ void __iomem *base;
+ u32 freq;
+ int irq;
+};
+
+static inline struct sprd_timer_device *
+to_sprd_timer(struct clock_event_device *c)
+{
+ return container_of(c, struct sprd_timer_device, ce);
+}
+
+static void sprd_timer_enable(struct sprd_timer_device *timer, u32 flag)
+{
+ u32 val = readl_relaxed(timer->base + TIMER_CTL);
+
+ val |= TIMER_CTL_ENABLE;
+ if (flag & TIMER_CTL_64BIT_WIDTH)
+ val |= TIMER_CTL_64BIT_WIDTH;
+ else
+ val &= ~TIMER_CTL_64BIT_WIDTH;
+
+ if (flag & TIMER_CTL_PERIOD_MODE)
+ val |= TIMER_CTL_PERIOD_MODE;
+ else
+ val &= ~TIMER_CTL_PERIOD_MODE;
+
+ writel_relaxed(val, timer->base + TIMER_CTL);
+}
+
+static void sprd_timer_disable(struct sprd_timer_device *timer)
+{
+ u32 val = readl_relaxed(timer->base + TIMER_CTL);
+
+ val &= ~TIMER_CTL_ENABLE;
+ writel_relaxed(val, timer->base + TIMER_CTL);
+}
+
+static void sprd_timer_update_counter(struct sprd_timer_device *timer,
+ unsigned long cycles)
+{
+ writel_relaxed(cycles & TIMER_VALUE_LO_MASK,
+ timer->base + TIMER_LOAD_LO);
+ writel_relaxed(0, timer->base + TIMER_LOAD_HI);
+}
+
+static void sprd_timer_enable_interrupt(struct sprd_timer_device *timer)
+{
+ writel_relaxed(TIMER_INT_EN, timer->base + TIMER_INT);
+}
+
+static void sprd_timer_clear_interrupt(struct sprd_timer_device *timer)
+{
+ u32 val = readl_relaxed(timer->base + TIMER_INT);
+
+ val |= TIMER_INT_CLR;
+ writel_relaxed(val, timer->base + TIMER_INT);
+}
+
+static int sprd_timer_set_next_event(unsigned long cycles,
+ struct clock_event_device *ce)
+{
+ struct sprd_timer_device *timer = to_sprd_timer(ce);
+
+ sprd_timer_disable(timer);
+ sprd_timer_update_counter(timer, cycles);
+ sprd_timer_enable(timer, 0);
+
+ return 0;
+}
+
+static int sprd_timer_set_periodic(struct clock_event_device *ce)
+{
+ struct sprd_timer_device *timer = to_sprd_timer(ce);
+ unsigned long cycles = DIV_ROUND_UP(timer->freq, HZ);
+
+ sprd_timer_disable(timer);
+ sprd_timer_update_counter(timer, cycles);
+ sprd_timer_enable(timer, TIMER_CTL_PERIOD_MODE);
+
+ return 0;
+}
+
+static int sprd_timer_shutdown(struct clock_event_device *ce)
+{
+ struct sprd_timer_device *timer = to_sprd_timer(ce);
+
+ sprd_timer_disable(timer);
+ return 0;
+}
+
+static irqreturn_t sprd_timer_interrupt(int irq, void *dev_id)
+{
+ struct sprd_timer_device *timer = dev_id;
+
+ sprd_timer_clear_interrupt(timer);
+
+ if (clockevent_state_oneshot(&timer->ce))
+ sprd_timer_disable(timer);
+
+ timer->ce.event_handler(&timer->ce);
+ return IRQ_HANDLED;
+}
+
+static void __init sprd_timer_clkevt_init(struct sprd_timer_device *timer)
+{
+ timer->ce.features = CLOCK_EVT_FEAT_DYNIRQ | CLOCK_EVT_FEAT_PERIODIC |
+ CLOCK_EVT_FEAT_ONESHOT;
+ timer->ce.set_next_event = sprd_timer_set_next_event;
+ timer->ce.set_state_periodic = sprd_timer_set_periodic;
+ timer->ce.set_state_shutdown = sprd_timer_shutdown;
+ timer->ce.name = TIMER_NAME;
+ timer->ce.rating = 300;
+ timer->ce.irq = timer->irq;
+ timer->ce.cpumask = cpu_possible_mask;
+
+ sprd_timer_enable_interrupt(timer);
+ clockevents_config_and_register(&timer->ce, timer->freq, 1, UINT_MAX);
+}
+
+static int __init sprd_timer_init(struct device_node *np)
+{
+ struct sprd_timer_device *timer;
+ int ret;
+
+ timer = kzalloc(sizeof(*timer), GFP_KERNEL);
+ if (!timer)
+ return -ENOMEM;
+
+ ret = of_property_read_u32(np, "clock-frequency", &timer->freq);
+ if (ret) {
+ pr_err("failed to get clock frequency\n");
+ goto err_freq;
+ }
+
+ timer->base = of_iomap(np, 0);
+ if (!timer->base) {
+ pr_err("%s: unable to map resource\n", np->name);
+ ret = -ENXIO;
+ goto err_freq;
+ }
+
+ timer->irq = irq_of_parse_and_map(np, 0);
+ if (timer->irq < 0) {
+ pr_crit("%s: unable to parse timer irq\n", np->name);
+ ret = timer->irq;
+ goto err_map_irq;
+ }
+
+ ret = request_irq(timer->irq, sprd_timer_interrupt, IRQF_TIMER,
+ TIMER_NAME, timer);
+ if (ret) {
+ pr_err("failed to setup irq %d\n", timer->irq);
+ goto err_request_irq;
+ }
+
+ sprd_timer_clkevt_init(timer);
+
+ return 0;
+
+err_request_irq:
+ irq_dispose_mapping(timer->irq);
+err_map_irq:
+ iounmap(timer->base);
+err_freq:
+ kfree(timer);
+
+ return ret;
+}
+
+TIMER_OF_DECLARE(sc9860_timer, "sprd,sc9860-timer", sprd_timer_init);
--
1.7.9.5
^ permalink raw reply related
* [PATCH v2 1/2] dt-bindings: clocksource: Add Spreadtrum SC9860 timer
From: Baolin Wang @ 2017-11-28 2:45 UTC (permalink / raw)
To: daniel.lezcano-QSEj5FYQhm4dnm+yROfE0A,
tglx-hfZtesqFncYOwBW4kG4KsQ, robh+dt-DgEjT+Ai2ygdnm+yROfE0A,
mark.rutland-5wv7dgnIgG8
Cc: devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
broonie-DgEjT+Ai2ygdnm+yROfE0A,
baolin.wang-QSEj5FYQhm4dnm+yROfE0A,
baolin.wang-lxIno14LUO0EEoCn2XhGlw
This patch adds documentation of device tree bindings for the timers
found on Spreadtrum SC9860 platform.
Signed-off-by: Baolin Wang <baolin.wang-lxIno14LUO0EEoCn2XhGlw@public.gmane.org>
Acked-by: Rob Herring <robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
---
Changes since v1:
- Add acked tag from Rob.
---
.../bindings/timer/spreadtrum,sprd-timer.txt | 20 ++++++++++++++++++++
1 file changed, 20 insertions(+)
create mode 100644 Documentation/devicetree/bindings/timer/spreadtrum,sprd-timer.txt
diff --git a/Documentation/devicetree/bindings/timer/spreadtrum,sprd-timer.txt b/Documentation/devicetree/bindings/timer/spreadtrum,sprd-timer.txt
new file mode 100644
index 0000000..f9d5eb9
--- /dev/null
+++ b/Documentation/devicetree/bindings/timer/spreadtrum,sprd-timer.txt
@@ -0,0 +1,20 @@
+Spreadtrum timers
+
+The Spreadtrum SC9860 platform provides 3 general-purpose timers.
+These timers can support 32bit or 64bit counter, as well as supporting
+period mode or one-shot mode, and they are can be wakeup source
+during deep sleep.
+
+Required properties:
+- compatible: should be "sprd,sc9860-timer" for SC9860 platform.
+- reg: The register address of the timer device.
+- interrupts: Should contain the interrupt for the timer device.
+- clock-frequency: The frequency of the clock that drives the counter, in Hz.
+
+Example:
+ timer@40050000 {
+ compatible = "sprd,sc9860-timer";
+ reg = <0 0x40050000 0 0x20>;
+ interrupts = <GIC_SPI 26 IRQ_TYPE_LEVEL_HIGH>;
+ clock-frequency = <32768>;
+ };
--
1.7.9.5
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* Re: [PATCH v2 18/35] nds32: Debugging support
From: Vincent Chen @ 2017-11-28 2:21 UTC (permalink / raw)
To: Arnd Bergmann
Cc: Greentime Hu, Greentime, Linux Kernel Mailing List, linux-arch,
Thomas Gleixner, Jason Cooper, Marc Zyngier, Rob Herring,
Networking, DTML, Al Viro, David Howells, Will Deacon,
Daniel Lezcano, linux-serial-u79uwXL29TY76Z2rM5mHXA, Vincent Chen
In-Reply-To: <CAK8P3a2czU7=jECXFOvtRNhrq3zyX7gV7sa3OFPQ-8A4U8iH0A-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2017-11-27 22:34 GMT+08:00 Arnd Bergmann <arnd-r2nGTMty4D4@public.gmane.org>:
> On Mon, Nov 27, 2017 at 1:28 PM, Greentime Hu <green.hu-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:
>> +struct user_pt_regs {
>> + long uregs[26];
>> + long fp;
>> + long gp;
>> + long lp;
>> + long sp;
>> + long ipc;
>> +#if defined(CONFIG_HWZOL)
>> + long lb;
>> + long le;
>> + long lc;
>> +#else
>> + long dummy[3];
>> +#endif
>> + long syscallno;
>> +};
>
> You cannot reference CONFIG_ symbols in a uapi header, since the
> configuration headers
> are not available.
>
Thanks
I will modify it in the next version patch.
> Arnd
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [PATCH v2 16/35] nds32: Signal handling support
From: Vincent Chen @ 2017-11-28 2:21 UTC (permalink / raw)
To: Arnd Bergmann
Cc: Greentime Hu, Greentime, Linux Kernel Mailing List, linux-arch,
Thomas Gleixner, Jason Cooper, Marc Zyngier, Rob Herring,
Networking, DTML, Al Viro, David Howells, Will Deacon,
Daniel Lezcano, linux-serial-u79uwXL29TY76Z2rM5mHXA, Vincent Chen
In-Reply-To: <CAK8P3a1sqhLwz3WqM0Qx4w0SBWqFWMuXVgX4p9StpacfWdSnUA-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2017-11-27 22:37 GMT+08:00 Arnd Bergmann <arnd-r2nGTMty4D4@public.gmane.org>:
> On Mon, Nov 27, 2017 at 1:28 PM, Greentime Hu <green.hu-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:
>
>> +#ifndef _ASMNDS32_SIGNAL_H
>> +#define _ASMNDS32_SIGNAL_H
>> +
>> +#define SA_RESTORER 0x04000000
>> +
>> +#include <asm-generic/signal.h>
>> +#endif
>
> As documented in asm-generic/signal.h, new architectures should not define
> SA_RESTORER.
>
Thanks.
I will remove it in the next version patch.
> Arnd
Vincent
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* [PATCH v7 2/2] watchdog: Add Spreadtrum watchdog driver
From: Eric Long @ 2017-11-28 2:18 UTC (permalink / raw)
To: Guenter Roeck, Rob Herring, Mark Rutland
Cc: baolin.wang, linux-watchdog, devicetree, linux-kernel, huitao.yue,
eric.long
In-Reply-To: <61f88b7f9c1ac8a2d4bd7dbab672ad913bd2707d.1511835645.git.eric.long@spreadtrum.com>
This patch adds the watchdog driver for Spreadtrum SC9860 platform.
Signed-off-by: Eric Long <eric.long@spreadtrum.com>
Reviewed-by: Guenter Roeck <linux@roeck-us.net>
---
Changes since v6:
- Add reviewed tag from Guenter.
Changes since v5:
- Modify the "irq" type as int type.
- Delete unused api sprd_wdt_is_running().
Changes since v4:
- Remove sprd_wdt_remove().
- Add devm_add_action() for sprd_wdt_disable().
Changes since v3:
- Update Kconfig SPRD_WATCHDOG help messages.
- Correct the wrong spell words.
- Rename SPRD_WDT_CNT_HIGH_VALUE as SPRD_WDT_CNT_HIGH_SHIFT.
- Remove unused macor.
- Update sprd_wdt_set_pretimeout() api.
- Add wdt->wdd.timeout default value.
- Use devm_watchdog_register_device() to register wdt device.
- If module does not support NOWAYOUT, disable wdt when remove this driver.
- Call sprd_wdt_disable() every wdt suspend.
Changes since v2:
- Rename all the macors, add SPRD tag at the head of the macro names.
- Rename SPRD_WDT_CLK as SPRD_WTC_CNT_STEP.
- Remove the code which check timeout value at the wrong place.
- Add min/max timeout value limit.
- Remove set WDOG_HW_RUNNING status at sprd_wdt_enable().
- Add timeout/pretimeout judgment when set them.
- Support WATCHDOG_NOWAYOUT status.
Changes since v1:
- Use pretimeout instead of own implementation.
- Fix timeout loop when loading timeout values.
- use the infrastructure to read and set "timeout-sec" property.
- Add conditions when start or stop watchdog.
- Change the position of enabling watchdog.
- Other optimization.
---
drivers/watchdog/Kconfig | 8 +
drivers/watchdog/Makefile | 1 +
drivers/watchdog/sprd_wdt.c | 399 ++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 408 insertions(+)
create mode 100644 drivers/watchdog/sprd_wdt.c
diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
index c722cbf..3367a8c 100644
--- a/drivers/watchdog/Kconfig
+++ b/drivers/watchdog/Kconfig
@@ -787,6 +787,14 @@ config UNIPHIER_WATCHDOG
To compile this driver as a module, choose M here: the
module will be called uniphier_wdt.
+config SPRD_WATCHDOG
+ tristate "Spreadtrum watchdog support"
+ depends on ARCH_SPRD || COMPILE_TEST
+ select WATCHDOG_CORE
+ help
+ Say Y here to include watchdog timer supported
+ by Spreadtrum system.
+
# AVR32 Architecture
config AT32AP700X_WDT
diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile
index 56adf9f..187cca2 100644
--- a/drivers/watchdog/Makefile
+++ b/drivers/watchdog/Makefile
@@ -87,6 +87,7 @@ obj-$(CONFIG_ASPEED_WATCHDOG) += aspeed_wdt.o
obj-$(CONFIG_ZX2967_WATCHDOG) += zx2967_wdt.o
obj-$(CONFIG_STM32_WATCHDOG) += stm32_iwdg.o
obj-$(CONFIG_UNIPHIER_WATCHDOG) += uniphier_wdt.o
+obj-$(CONFIG_SPRD_WATCHDOG) += sprd_wdt.o
# AVR32 Architecture
obj-$(CONFIG_AT32AP700X_WDT) += at32ap700x_wdt.o
diff --git a/drivers/watchdog/sprd_wdt.c b/drivers/watchdog/sprd_wdt.c
new file mode 100644
index 0000000..a8b280f
--- /dev/null
+++ b/drivers/watchdog/sprd_wdt.c
@@ -0,0 +1,399 @@
+/*
+ * Spreadtrum watchdog driver
+ * Copyright (C) 2017 Spreadtrum - http://www.spreadtrum.com
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ */
+
+#include <linux/bitops.h>
+#include <linux/clk.h>
+#include <linux/device.h>
+#include <linux/err.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/platform_device.h>
+#include <linux/watchdog.h>
+
+#define SPRD_WDT_LOAD_LOW 0x0
+#define SPRD_WDT_LOAD_HIGH 0x4
+#define SPRD_WDT_CTRL 0x8
+#define SPRD_WDT_INT_CLR 0xc
+#define SPRD_WDT_INT_RAW 0x10
+#define SPRD_WDT_INT_MSK 0x14
+#define SPRD_WDT_CNT_LOW 0x18
+#define SPRD_WDT_CNT_HIGH 0x1c
+#define SPRD_WDT_LOCK 0x20
+#define SPRD_WDT_IRQ_LOAD_LOW 0x2c
+#define SPRD_WDT_IRQ_LOAD_HIGH 0x30
+
+/* WDT_CTRL */
+#define SPRD_WDT_INT_EN_BIT BIT(0)
+#define SPRD_WDT_CNT_EN_BIT BIT(1)
+#define SPRD_WDT_NEW_VER_EN BIT(2)
+#define SPRD_WDT_RST_EN_BIT BIT(3)
+
+/* WDT_INT_CLR */
+#define SPRD_WDT_INT_CLEAR_BIT BIT(0)
+#define SPRD_WDT_RST_CLEAR_BIT BIT(3)
+
+/* WDT_INT_RAW */
+#define SPRD_WDT_INT_RAW_BIT BIT(0)
+#define SPRD_WDT_RST_RAW_BIT BIT(3)
+#define SPRD_WDT_LD_BUSY_BIT BIT(4)
+
+/* 1s equal to 32768 counter steps */
+#define SPRD_WDT_CNT_STEP 32768
+
+#define SPRD_WDT_UNLOCK_KEY 0xe551
+#define SPRD_WDT_MIN_TIMEOUT 3
+#define SPRD_WDT_MAX_TIMEOUT 60
+
+#define SPRD_WDT_CNT_HIGH_SHIFT 16
+#define SPRD_WDT_LOW_VALUE_MASK GENMASK(15, 0)
+#define SPRD_WDT_LOAD_TIMEOUT 1000
+
+struct sprd_wdt {
+ void __iomem *base;
+ struct watchdog_device wdd;
+ struct clk *enable;
+ struct clk *rtc_enable;
+ int irq;
+};
+
+static inline struct sprd_wdt *to_sprd_wdt(struct watchdog_device *wdd)
+{
+ return container_of(wdd, struct sprd_wdt, wdd);
+}
+
+static inline void sprd_wdt_lock(void __iomem *addr)
+{
+ writel_relaxed(0x0, addr + SPRD_WDT_LOCK);
+}
+
+static inline void sprd_wdt_unlock(void __iomem *addr)
+{
+ writel_relaxed(SPRD_WDT_UNLOCK_KEY, addr + SPRD_WDT_LOCK);
+}
+
+static irqreturn_t sprd_wdt_isr(int irq, void *dev_id)
+{
+ struct sprd_wdt *wdt = (struct sprd_wdt *)dev_id;
+
+ sprd_wdt_unlock(wdt->base);
+ writel_relaxed(SPRD_WDT_INT_CLEAR_BIT, wdt->base + SPRD_WDT_INT_CLR);
+ sprd_wdt_lock(wdt->base);
+ watchdog_notify_pretimeout(&wdt->wdd);
+ return IRQ_HANDLED;
+}
+
+static u32 sprd_wdt_get_cnt_value(struct sprd_wdt *wdt)
+{
+ u32 val;
+
+ val = readl_relaxed(wdt->base + SPRD_WDT_CNT_HIGH) <<
+ SPRD_WDT_CNT_HIGH_SHIFT;
+ val |= readl_relaxed(wdt->base + SPRD_WDT_CNT_LOW) &
+ SPRD_WDT_LOW_VALUE_MASK;
+
+ return val;
+}
+
+static int sprd_wdt_load_value(struct sprd_wdt *wdt, u32 timeout,
+ u32 pretimeout)
+{
+ u32 val, delay_cnt = 0;
+ u32 tmr_step = timeout * SPRD_WDT_CNT_STEP;
+ u32 prtmr_step = pretimeout * SPRD_WDT_CNT_STEP;
+
+ sprd_wdt_unlock(wdt->base);
+ writel_relaxed((tmr_step >> SPRD_WDT_CNT_HIGH_SHIFT) &
+ SPRD_WDT_LOW_VALUE_MASK, wdt->base + SPRD_WDT_LOAD_HIGH);
+ writel_relaxed((tmr_step & SPRD_WDT_LOW_VALUE_MASK),
+ wdt->base + SPRD_WDT_LOAD_LOW);
+ writel_relaxed((prtmr_step >> SPRD_WDT_CNT_HIGH_SHIFT) &
+ SPRD_WDT_LOW_VALUE_MASK,
+ wdt->base + SPRD_WDT_IRQ_LOAD_HIGH);
+ writel_relaxed(prtmr_step & SPRD_WDT_LOW_VALUE_MASK,
+ wdt->base + SPRD_WDT_IRQ_LOAD_LOW);
+ sprd_wdt_lock(wdt->base);
+
+ /*
+ * Waiting the load value operation done,
+ * it needs two or three RTC clock cycles.
+ */
+ do {
+ val = readl_relaxed(wdt->base + SPRD_WDT_INT_RAW);
+ if (!(val & SPRD_WDT_LD_BUSY_BIT))
+ break;
+
+ cpu_relax();
+ } while (delay_cnt++ < SPRD_WDT_LOAD_TIMEOUT);
+
+ if (delay_cnt >= SPRD_WDT_LOAD_TIMEOUT)
+ return -EBUSY;
+ return 0;
+}
+
+static int sprd_wdt_enable(struct sprd_wdt *wdt)
+{
+ u32 val;
+ int ret;
+
+ ret = clk_prepare_enable(wdt->enable);
+ if (ret)
+ return ret;
+ ret = clk_prepare_enable(wdt->rtc_enable);
+ if (ret)
+ return ret;
+
+ sprd_wdt_unlock(wdt->base);
+ val = readl_relaxed(wdt->base + SPRD_WDT_CTRL);
+ val |= SPRD_WDT_NEW_VER_EN;
+ writel_relaxed(val, wdt->base + SPRD_WDT_CTRL);
+ sprd_wdt_lock(wdt->base);
+ return 0;
+}
+
+static void sprd_wdt_disable(void *_data)
+{
+ struct sprd_wdt *wdt = _data;
+
+ sprd_wdt_unlock(wdt->base);
+ writel_relaxed(0x0, wdt->base + SPRD_WDT_CTRL);
+ sprd_wdt_lock(wdt->base);
+
+ clk_disable_unprepare(wdt->rtc_enable);
+ clk_disable_unprepare(wdt->enable);
+}
+
+static int sprd_wdt_start(struct watchdog_device *wdd)
+{
+ struct sprd_wdt *wdt = to_sprd_wdt(wdd);
+ u32 val;
+ int ret;
+
+ ret = sprd_wdt_load_value(wdt, wdd->timeout, wdd->pretimeout);
+ if (ret)
+ return ret;
+
+ sprd_wdt_unlock(wdt->base);
+ val = readl_relaxed(wdt->base + SPRD_WDT_CTRL);
+ val |= SPRD_WDT_CNT_EN_BIT | SPRD_WDT_INT_EN_BIT | SPRD_WDT_RST_EN_BIT;
+ writel_relaxed(val, wdt->base + SPRD_WDT_CTRL);
+ sprd_wdt_lock(wdt->base);
+ set_bit(WDOG_HW_RUNNING, &wdd->status);
+
+ return 0;
+}
+
+static int sprd_wdt_stop(struct watchdog_device *wdd)
+{
+ struct sprd_wdt *wdt = to_sprd_wdt(wdd);
+ u32 val;
+
+ sprd_wdt_unlock(wdt->base);
+ val = readl_relaxed(wdt->base + SPRD_WDT_CTRL);
+ val &= ~(SPRD_WDT_CNT_EN_BIT | SPRD_WDT_RST_EN_BIT |
+ SPRD_WDT_INT_EN_BIT);
+ writel_relaxed(val, wdt->base + SPRD_WDT_CTRL);
+ sprd_wdt_lock(wdt->base);
+ return 0;
+}
+
+static int sprd_wdt_set_timeout(struct watchdog_device *wdd,
+ u32 timeout)
+{
+ struct sprd_wdt *wdt = to_sprd_wdt(wdd);
+
+ if (timeout == wdd->timeout)
+ return 0;
+
+ wdd->timeout = timeout;
+
+ return sprd_wdt_load_value(wdt, timeout, wdd->pretimeout);
+}
+
+static int sprd_wdt_set_pretimeout(struct watchdog_device *wdd,
+ u32 new_pretimeout)
+{
+ struct sprd_wdt *wdt = to_sprd_wdt(wdd);
+
+ if (new_pretimeout < wdd->min_timeout)
+ return -EINVAL;
+
+ wdd->pretimeout = new_pretimeout;
+
+ return sprd_wdt_load_value(wdt, wdd->timeout, new_pretimeout);
+}
+
+static u32 sprd_wdt_get_timeleft(struct watchdog_device *wdd)
+{
+ struct sprd_wdt *wdt = to_sprd_wdt(wdd);
+ u32 val;
+
+ val = sprd_wdt_get_cnt_value(wdt);
+ val = val / SPRD_WDT_CNT_STEP;
+
+ return val;
+}
+
+static const struct watchdog_ops sprd_wdt_ops = {
+ .owner = THIS_MODULE,
+ .start = sprd_wdt_start,
+ .stop = sprd_wdt_stop,
+ .set_timeout = sprd_wdt_set_timeout,
+ .set_pretimeout = sprd_wdt_set_pretimeout,
+ .get_timeleft = sprd_wdt_get_timeleft,
+};
+
+static const struct watchdog_info sprd_wdt_info = {
+ .options = WDIOF_SETTIMEOUT |
+ WDIOF_PRETIMEOUT |
+ WDIOF_MAGICCLOSE |
+ WDIOF_KEEPALIVEPING,
+ .identity = "Spreadtrum Watchdog Timer",
+};
+
+static int sprd_wdt_probe(struct platform_device *pdev)
+{
+ struct resource *wdt_res;
+ struct sprd_wdt *wdt;
+ int ret;
+
+ wdt = devm_kzalloc(&pdev->dev, sizeof(*wdt), GFP_KERNEL);
+ if (!wdt)
+ return -ENOMEM;
+
+ wdt_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ wdt->base = devm_ioremap_resource(&pdev->dev, wdt_res);
+ if (IS_ERR(wdt->base)) {
+ dev_err(&pdev->dev, "failed to map memory resource\n");
+ return PTR_ERR(wdt->base);
+ }
+
+ wdt->enable = devm_clk_get(&pdev->dev, "enable");
+ if (IS_ERR(wdt->enable)) {
+ dev_err(&pdev->dev, "can't get the enable clock\n");
+ return PTR_ERR(wdt->enable);
+ }
+
+ wdt->rtc_enable = devm_clk_get(&pdev->dev, "rtc_enable");
+ if (IS_ERR(wdt->rtc_enable)) {
+ dev_err(&pdev->dev, "can't get the rtc enable clock\n");
+ return PTR_ERR(wdt->rtc_enable);
+ }
+
+ wdt->irq = platform_get_irq(pdev, 0);
+ if (wdt->irq < 0) {
+ dev_err(&pdev->dev, "failed to get IRQ resource\n");
+ return wdt->irq;
+ }
+
+ ret = devm_request_irq(&pdev->dev, wdt->irq, sprd_wdt_isr,
+ IRQF_NO_SUSPEND, "sprd-wdt", (void *)wdt);
+ if (ret) {
+ dev_err(&pdev->dev, "failed to register irq\n");
+ return ret;
+ }
+
+ wdt->wdd.info = &sprd_wdt_info;
+ wdt->wdd.ops = &sprd_wdt_ops;
+ wdt->wdd.parent = &pdev->dev;
+ wdt->wdd.min_timeout = SPRD_WDT_MIN_TIMEOUT;
+ wdt->wdd.max_timeout = SPRD_WDT_MAX_TIMEOUT;
+ wdt->wdd.timeout = SPRD_WDT_MAX_TIMEOUT;
+
+ ret = sprd_wdt_enable(wdt);
+ if (ret) {
+ dev_err(&pdev->dev, "failed to enable wdt\n");
+ return ret;
+ }
+ ret = devm_add_action(&pdev->dev, sprd_wdt_disable, wdt);
+ if (ret) {
+ sprd_wdt_disable(wdt);
+ dev_err(&pdev->dev, "Failed to add wdt disable action\n");
+ return ret;
+ }
+
+ watchdog_set_nowayout(&wdt->wdd, WATCHDOG_NOWAYOUT);
+ watchdog_init_timeout(&wdt->wdd, 0, &pdev->dev);
+
+ ret = devm_watchdog_register_device(&pdev->dev, &wdt->wdd);
+ if (ret) {
+ sprd_wdt_disable(wdt);
+ dev_err(&pdev->dev, "failed to register watchdog\n");
+ return ret;
+ }
+ platform_set_drvdata(pdev, wdt);
+
+ return 0;
+}
+
+static int __maybe_unused sprd_wdt_pm_suspend(struct device *dev)
+{
+ struct watchdog_device *wdd = dev_get_drvdata(dev);
+ struct sprd_wdt *wdt = dev_get_drvdata(dev);
+
+ if (watchdog_active(wdd))
+ sprd_wdt_stop(&wdt->wdd);
+ sprd_wdt_disable(wdt);
+
+ return 0;
+}
+
+static int __maybe_unused sprd_wdt_pm_resume(struct device *dev)
+{
+ struct watchdog_device *wdd = dev_get_drvdata(dev);
+ struct sprd_wdt *wdt = dev_get_drvdata(dev);
+ int ret;
+
+ ret = sprd_wdt_enable(wdt);
+ if (ret)
+ return ret;
+
+ if (watchdog_active(wdd)) {
+ ret = sprd_wdt_start(&wdt->wdd);
+ if (ret) {
+ sprd_wdt_disable(wdt);
+ return ret;
+ }
+ }
+
+ return 0;
+}
+
+static const struct dev_pm_ops sprd_wdt_pm_ops = {
+ SET_SYSTEM_SLEEP_PM_OPS(sprd_wdt_pm_suspend,
+ sprd_wdt_pm_resume)
+};
+
+static const struct of_device_id sprd_wdt_match_table[] = {
+ { .compatible = "sprd,sp9860-wdt", },
+ {},
+};
+MODULE_DEVICE_TABLE(of, sprd_wdt_match_table);
+
+static struct platform_driver sprd_watchdog_driver = {
+ .probe = sprd_wdt_probe,
+ .driver = {
+ .name = "sprd-wdt",
+ .of_match_table = sprd_wdt_match_table,
+ .pm = &sprd_wdt_pm_ops,
+ },
+};
+module_platform_driver(sprd_watchdog_driver);
+
+MODULE_AUTHOR("Eric Long <eric.long@spreadtrum.com>");
+MODULE_DESCRIPTION("Spreadtrum Watchdog Timer Controller Driver");
+MODULE_LICENSE("GPL v2");
--
1.9.1
^ permalink raw reply related
* [PATCH v7 1/2] dt-bindings: watchdog: Add Spreadtrum watchdog documentation
From: Eric Long @ 2017-11-28 2:18 UTC (permalink / raw)
To: Guenter Roeck, Rob Herring, Mark Rutland
Cc: baolin.wang-QSEj5FYQhm4dnm+yROfE0A,
linux-watchdog-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
huitao.yue-lxIno14LUO0EEoCn2XhGlw,
eric.long-lxIno14LUO0EEoCn2XhGlw
This patch adds the documentation for Spreadtrum watchdog driver.
Signed-off-by: Eric Long <eric.long-lxIno14LUO0EEoCn2XhGlw@public.gmane.org>
Acked-by: Rob Herring <robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
---
Changes since v6:
- No updates.
Changes since v5:
- No updates.
Changes since v4:
- No updates.
Changes since v3:
- No updates.
Changes since v2:
- Add acked tag from Rob.
Changes since v1:
- No updates.
---
.../devicetree/bindings/watchdog/sprd-wdt.txt | 19 +++++++++++++++++++
1 file changed, 19 insertions(+)
create mode 100644 Documentation/devicetree/bindings/watchdog/sprd-wdt.txt
diff --git a/Documentation/devicetree/bindings/watchdog/sprd-wdt.txt b/Documentation/devicetree/bindings/watchdog/sprd-wdt.txt
new file mode 100644
index 0000000..aeaf3e0
--- /dev/null
+++ b/Documentation/devicetree/bindings/watchdog/sprd-wdt.txt
@@ -0,0 +1,19 @@
+Spreadtrum SoCs Watchdog timer
+
+Required properties:
+- compatible : Should be "sprd,sp9860-wdt".
+- reg : Specifies base physical address and size of the registers.
+- interrupts : Exactly one interrupt specifier.
+- timeout-sec : Contain the default watchdog timeout in seconds.
+- clock-names : Contain the input clock names.
+- clocks : Phandles to input clocks.
+
+Example:
+ watchdog: watchdog@40310000 {
+ compatible = "sprd,sp9860-wdt";
+ reg = <0 0x40310000 0 0x1000>;
+ interrupts = <GIC_SPI 61 IRQ_TYPE_LEVEL_HIGH>;
+ timeout-sec = <12>;
+ clock-names = "enable", "rtc_enable";
+ clocks = <&clk_aon_apb_gates1 8>, <&clk_aon_apb_rtc_gates 9>;
+ };
--
1.9.1
--
To unsubscribe from this list: send the line "unsubscribe linux-watchdog" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* Re: [PATCH v2 14/35] nds32: System calls handling
From: Vincent Chen @ 2017-11-28 2:18 UTC (permalink / raw)
To: Arnd Bergmann
Cc: Greentime Hu, Greentime, Linux Kernel Mailing List, linux-arch,
Thomas Gleixner, Jason Cooper, Marc Zyngier, Rob Herring,
Networking, DTML, Al Viro, David Howells, Will Deacon,
Daniel Lezcano, linux-serial, Vincent Chen
In-Reply-To: <CAK8P3a3V7=4LjT38xT2VBQW4sTgpKergar2KoO8brbMZjR--1w@mail.gmail.com>
2017-11-27 22:46 GMT+08:00 Arnd Bergmann <arnd@arndb.de>:
> On Mon, Nov 27, 2017 at 1:28 PM, Greentime Hu <green.hu@gmail.com> wrote:
>
>> diff --git a/arch/nds32/include/asm/syscalls.h b/arch/nds32/include/asm/syscalls.h
>> new file mode 100644
>> index 0000000..741ccdc
>> --- /dev/null
>> +++ b/arch/nds32/include/asm/syscalls.h
>> @@ -0,0 +1,27 @@
>> +/*
>> + * Copyright (C) 2005-2017 Andes Technology Corporation
>> + *
>> + * 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.
>> + *
>> + * This program is distributed in the hope that it will be useful,
>> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
>> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
>> + * GNU General Public License for more details.
>> + *
>> + * You should have received a copy of the GNU General Public License
>> + * along with this program. If not, see <http://www.gnu.org/licenses/>.
>> + */
>> +
>> +#ifndef __ASM_NDS32_SYSCALLS_H
>> +#define __ASM_NDS32_SYSCALLS_H
>> +
>> +int sys_cacheflush(unsigned long addr, unsigned long len, unsigned int op);
>> +long sys_fadvise64_64_wrapper(int fd, int advice, loff_t offset, loff_t len);
>> +asmlinkage int sys_syscall(void);
>> +asmlinkage int sys_rt_sigreturn_wrapper(void);
>
> You mentioned that sys_syscall() should be removed in this version.
>
Sorry, I will remove it in next version patch.
> By convention, all syscall declarations should start with 'asmlinkage long',
> even though this has no effect in your architecture.
>
Thanks.
I will modify it in next version patch.
>> diff --git a/arch/nds32/include/uapi/asm/unistd.h b/arch/nds32/include/uapi/asm/unistd.h
>> new file mode 100644
>> index 0000000..2bad1e7
>> --- /dev/null
>> +++ b/arch/nds32/include/uapi/asm/unistd.h
>
>> +
>> +#define __ARCH_WANT_RENAMEAT
>> +#define __ARCH_WANT_SYSCALL_OFF_T
>
> These two should not be here.
>
Thanks.
But, I don't know I should move these two macro to which file.
In asm-generic/unistd.h, these two are used to decide whether relative
syscall number is defined or not.
Therefore, I put these two macros here in order that these two
definitions are available in user space.
>> +#define __ARCH_WANT_SYNC_FILE_RANGE2
>
> This one is fine though
>
>> +/* Use the standard ABI for syscalls */
>> +#include <asm-generic/unistd.h>
>> +
>> +__SYSCALL(__NR_fadvise64_64, sys_fadvise64_64_wrapper)
>> +__SYSCALL(__NR_rt_sigreturn, sys_rt_sigreturn_wrapper)
>
> I think you are overriding the array assignment here, this may cause a
> compiler warning when building with "make C=1 V=1" since you have
> the same index assigned to two pointers. A better way to do this
> is to override the name:
>
> #define sys_rt_sigreturn sys_rt_sigreturn_wrapper
> #define sys_fadvise64_64 sys_fadvise64_64_wrapper
> #include <asm-generic/unistd.h>
>
Thanks,
I will follow your suggestion to modify it in the next version patch.
>
> Arnd
Vincent
^ permalink raw reply
* [REBASED PATCH] ARM: dts: exynos: fix property values of LDO15/17 for ODROID-XU3/4
From: Dongjin Kim @ 2017-11-28 0:15 UTC (permalink / raw)
Cc: Dongjin Kim, Rob Herring, Mark Rutland, Russell King, Kukjin Kim,
Krzysztof Kozlowski, devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-samsung-soc-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA
Looking at the schematic, LDO15 and LDO17 are tied as a power source of a
builtin network chipset. The voltage on LDO15 is corrected to 3.3V and the
name of LDO17 is corrected to "vdd_ldo17".
Signed-off-by: Dongjin Kim <tobetter-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
---
arch/arm/boot/dts/exynos5422-odroid-core.dtsi | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/arch/arm/boot/dts/exynos5422-odroid-core.dtsi b/arch/arm/boot/dts/exynos5422-odroid-core.dtsi
index a5b8d0f0877e..81cbb77204a8 100644
--- a/arch/arm/boot/dts/exynos5422-odroid-core.dtsi
+++ b/arch/arm/boot/dts/exynos5422-odroid-core.dtsi
@@ -233,8 +233,8 @@
ldo15_reg: LDO15 {
regulator-name = "vdd_ldo15";
- regulator-min-microvolt = <3100000>;
- regulator-max-microvolt = <3100000>;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
regulator-always-on;
};
@@ -246,7 +246,7 @@
};
ldo17_reg: LDO17 {
- regulator-name = "tsp_avdd";
+ regulator-name = "vdd_ldo17";
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
regulator-always-on;
--
2.11.0
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* Re: [PATCH 01/13] ARM: dts: imx6qdl: SolidRun: remove redundant regulators node
From: Fabio Estevam @ 2017-11-27 23:55 UTC (permalink / raw)
To: Russell King - ARM Linux
Cc: Mark Rutland, devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
Jon Nettleton, Rob Herring, Sascha Hauer, Fabio Estevam,
Shawn Guo,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org
In-Reply-To: <20171127231406.GQ31757-l+eeeJia6m9URfEZ8mYm6t73F7V6hmMc@public.gmane.org>
On Mon, Nov 27, 2017 at 9:14 PM, Russell King - ARM Linux
<linux-I+IVW8TIWO2tmTQ+vhA3Yw@public.gmane.org> wrote:
> Again, this is not new code, such a change should be a separate patch,
> maybe even separate from this series.
Sounds good.
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [RFC v2 1/2] backlight: pwm_bl: linear interpolation between values of brightness-levels
From: Doug Anderson @ 2017-11-27 23:55 UTC (permalink / raw)
To: Enric Balletbo Serra
Cc: Rob Herring, Enric Balletbo i Serra, Daniel Thompson, Jingoo Han,
Richard Purdie, Jacek Anaszewski, Pavel Machek, Brian Norris,
Guenter Roeck, Lee Jones, Alexandru Stan,
linux-leds-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org, linux-kernel
In-Reply-To: <CAFqH_50VqFJ-p=gRp9md4eHDHM5NpD6zPFfjwPY4LKTh2x6sHQ-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
Hi,
On Mon, Nov 27, 2017 at 3:21 AM, Enric Balletbo Serra
<eballetbo-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:
> Hi Rob,
>
> 2017-11-20 19:58 GMT+01:00 Rob Herring <robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>:
>> On Thu, Nov 16, 2017 at 03:11:50PM +0100, Enric Balletbo i Serra wrote:
>>> Setting use-linear-interpolation in the dts will allow you to have linear
>>> interpolation between values of brightness-levels.
>>>
>>> There are now 256 between each of the values of brightness-levels. If
>>> something is requested halfway between 2 values, we'll use linear
>>> interpolation.
>>>
>>> This way a high resolution pwm duty cycle can be used without having to
>>> list out every possible value in the dts.
>>
>> I thought we already had a way to do that.
>>
>>> This system also allows for
>>> gamma corrected values (eg: "brightness-levels = <0 2 4 8 16 32>;").
>>>
>>> Patch based on the Alexandru M Stan work done for ChromeOS kernels.
>>>
>>> Signed-off-by: Enric Balletbo i Serra <enric.balletbo-ZGY8ohtN/8qB+jHODAdFcQ@public.gmane.org>
>>> ---
>>> .../bindings/leds/backlight/pwm-backlight.txt | 2 +
>>> drivers/video/backlight/pwm_bl.c | 55 +++++++++++++++++-----
>>> include/linux/pwm_backlight.h | 2 +
>>> 3 files changed, 47 insertions(+), 12 deletions(-)
>>>
>>> diff --git a/Documentation/devicetree/bindings/leds/backlight/pwm-backlight.txt b/Documentation/devicetree/bindings/leds/backlight/pwm-backlight.txt
>>> index 764db86..7c48f20 100644
>>> --- a/Documentation/devicetree/bindings/leds/backlight/pwm-backlight.txt
>>> +++ b/Documentation/devicetree/bindings/leds/backlight/pwm-backlight.txt
>>> @@ -17,6 +17,8 @@ Optional properties:
>>> "pwms" property (see PWM binding[0])
>>> - enable-gpios: contains a single GPIO specifier for the GPIO which enables
>>> and disables the backlight (see GPIO binding[1])
>>> + - use-linear-interpolation: set this propriety to enable linear interpolation
>>> + between each of the values of brightness-levels.
>>
>> Isn't this really just whether you allow values not listed because what
>> other kind of interpolation would you do?
>
> Yes, the idea behind this is just allow values not listed.
>
>> Seems like you should just be
>> able to query the resolution of the PWM and decide if it can take more
>> values than listed.
>>
>
> Without using a new DT propriety and let decide the driver when use
> intepolation and when not? Shouldn't this break current behavior then?
> You can have a high resolution PWM but I'm not sure if you want allow
> always more values than listed.
Right. The assumption is that it's _possible_ that only the exact
values listed are valid duty cycles. We don't want to break old
hardware by suddenly allowing other duty cycles to be used. However,
it's expected that on most hardware you can simply use any duty cycle
between any of the specified ones and it should be fine. Anyone
specifying this property would say that's OK for their hardware.
-Doug
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [RFC v2 1/2] backlight: pwm_bl: linear interpolation between values of brightness-levels
From: Doug Anderson @ 2017-11-27 23:52 UTC (permalink / raw)
To: Enric Balletbo i Serra
Cc: Daniel Thompson, Jingoo Han, Richard Purdie, Jacek Anaszewski,
Pavel Machek, Rob Herring, Brian Norris, Guenter Roeck, Lee Jones,
Alexandru Stan, linux-leds, devicetree, LKML
In-Reply-To: <20171116141151.21171-2-enric.balletbo@collabora.com>
Hi,
On Thu, Nov 16, 2017 at 6:11 AM, Enric Balletbo i Serra
<enric.balletbo@collabora.com> wrote:
> Setting use-linear-interpolation in the dts will allow you to have linear
> interpolation between values of brightness-levels.
>
> There are now 256 between each of the values of brightness-levels. If
> something is requested halfway between 2 values, we'll use linear
> interpolation.
>
> This way a high resolution pwm duty cycle can be used without having to
> list out every possible value in the dts. This system also allows for
> gamma corrected values (eg: "brightness-levels = <0 2 4 8 16 32>;").
>
> Patch based on the Alexandru M Stan work done for ChromeOS kernels.
>
> Signed-off-by: Enric Balletbo i Serra <enric.balletbo@collabora.com>
> ---
> .../bindings/leds/backlight/pwm-backlight.txt | 2 +
> drivers/video/backlight/pwm_bl.c | 55 +++++++++++++++++-----
> include/linux/pwm_backlight.h | 2 +
> 3 files changed, 47 insertions(+), 12 deletions(-)
>
> diff --git a/Documentation/devicetree/bindings/leds/backlight/pwm-backlight.txt b/Documentation/devicetree/bindings/leds/backlight/pwm-backlight.txt
> index 764db86..7c48f20 100644
> --- a/Documentation/devicetree/bindings/leds/backlight/pwm-backlight.txt
> +++ b/Documentation/devicetree/bindings/leds/backlight/pwm-backlight.txt
> @@ -17,6 +17,8 @@ Optional properties:
> "pwms" property (see PWM binding[0])
> - enable-gpios: contains a single GPIO specifier for the GPIO which enables
> and disables the backlight (see GPIO binding[1])
> + - use-linear-interpolation: set this propriety to enable linear interpolation
> + between each of the values of brightness-levels.
>
> [0]: Documentation/devicetree/bindings/pwm/pwm.txt
> [1]: Documentation/devicetree/bindings/gpio/gpio.txt
> diff --git a/drivers/video/backlight/pwm_bl.c b/drivers/video/backlight/pwm_bl.c
> index 9bd1768..59b1bfb 100644
> --- a/drivers/video/backlight/pwm_bl.c
> +++ b/drivers/video/backlight/pwm_bl.c
> @@ -24,6 +24,8 @@
> #include <linux/regulator/consumer.h>
> #include <linux/slab.h>
>
> +#define NSTEPS 256
I'm not sure this is quite the ideal way to specify it. I could sorta
imagine wanting to specify just:
brightness-levels = <0 65535>
...and in such a case you'll only give 256 steps in between. 256
isn't quite granular enough and the human eye can notice each step. I
could fake it by putting this in the device tree:
brightness-levels = <0 4095 8191 ... ... 61439 65535>
...but that's kinda silly. I'd rather just say that when we're using
interpolation we just say that there will be a certain number of steps
(like 32768). Is there really a huge advantage of picking 256 steps
between each specified value instead of just picking a fixed number of
brightness levels?
^ permalink raw reply
* Re: [PATCH V4 3/6] iommu/arm-smmu: Invoke pm_runtime during probe, add/remove device
From: Rob Clark @ 2017-11-27 23:43 UTC (permalink / raw)
To: Stephen Boyd
Cc: Mark Rutland, devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
Rafael J. Wysocki, Will Deacon, Linux Kernel Mailing List,
Stanimir Varbanov,
iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA@public.gmane.org,
Rob Herring, linux-arm-msm, linux-clk,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org
In-Reply-To: <20171127222238.GF18379-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
On Mon, Nov 27, 2017 at 5:22 PM, Stephen Boyd <sboyd-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org> wrote:
> On 11/15, Vivek Gautam wrote:
>> Hi,
>>
>>
>> On Mon, Aug 7, 2017 at 5:59 PM, Rob Clark <robdclark-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:
>> > On Mon, Aug 7, 2017 at 4:27 AM, Vivek Gautam
>> > <vivek.gautam-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org> wrote:
>> >> On Thu, Jul 13, 2017 at 5:20 PM, Rob Clark <robdclark-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:
>> >>> On Thu, Jul 13, 2017 at 1:35 AM, Sricharan R <sricharan-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org> wrote:
>> >>>> Hi Vivek,
>> >>>>
>> >>>> On 7/13/2017 10:43 AM, Vivek Gautam wrote:
>> >>>>> Hi Stephen,
>> >>>>>
>> >>>>>
>> >>>>> On 07/13/2017 04:24 AM, Stephen Boyd wrote:
>> >>>>>> On 07/06, Vivek Gautam wrote:
>> >>>>>>> @@ -1231,12 +1237,18 @@ static int arm_smmu_map(struct iommu_domain *domain, unsigned long iova,
>> >>>>>>> static size_t arm_smmu_unmap(struct iommu_domain *domain, unsigned long iova,
>> >>>>>>> size_t size)
>> >>>>>>> {
>> >>>>>>> - struct io_pgtable_ops *ops = to_smmu_domain(domain)->pgtbl_ops;
>> >>>>>>> + struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain);
>> >>>>>>> + struct io_pgtable_ops *ops = smmu_domain->pgtbl_ops;
>> >>>>>>> + size_t ret;
>> >>>>>>> if (!ops)
>> >>>>>>> return 0;
>> >>>>>>> - return ops->unmap(ops, iova, size);
>> >>>>>>> + pm_runtime_get_sync(smmu_domain->smmu->dev);
>> >>>>>> Can these map/unmap ops be called from an atomic context? I seem
>> >>>>>> to recall that being a problem before.
>> >>>>>
>> >>>>> That's something which was dropped in the following patch merged in master:
>> >>>>> 523d7423e21b iommu/arm-smmu: Remove io-pgtable spinlock
>> >>>>>
>> >>>>> Looks like we don't need locks here anymore?
>> >>>>
>> >>>> Apart from the locking, wonder why a explicit pm_runtime is needed
>> >>>> from unmap. Somehow looks like some path in the master using that
>> >>>> should have enabled the pm ?
>> >>>>
>> >>>
>> >>> Yes, there are a bunch of scenarios where unmap can happen with
>> >>> disabled master (but not in atomic context).
>> >>
>> >> I would like to understand whether there is a situation where an unmap is
>> >> called in atomic context without an enabled master?
>> >>
>> >> Let's say we have the case where all the unmap calls in atomic context happen
>> >> only from the master's context (in which case the device link should
>> >> take care of
>> >> the pm state of smmu), and the only unmap that happen in non-atomic context
>> >> is the one with master disabled. In such a case doesn it make sense to
>> >> distinguish
>> >> the atomic/non-atomic context and add pm_runtime_get_sync()/put_sync() only
>> >> for the non-atomic context since that would be the one with master disabled.
>> >>
>> >
>> > At least drm/msm needs to hold obj->lock (a mutex) in unmap, so it
>> > won't unmap anything in atomic ctx (but it can unmap w/ master
>> > disabled). I can't really comment about other non-gpu drivers. It
>> > seems like a reasonable constraint that either master is enabled or
>> > not in atomic ctx.
>> >
>> > Currently we actually wrap unmap w/ pm_runtime_get/put_sync(), but I'd
>> > like to drop that to avoid powering up the gpu.
>>
>> Since the deferring the TLB maintenance doesn't look like the best approach [1],
>> how about if we try to power-up only the smmu from different client
>> devices such as,
>> GPU in the unmap path. Then we won't need to add pm_runtime_get/put() calls in
>> arm_smmu_unmap().
>>
>> The client device can use something like - pm_runtime_get_supplier() since
>> we already have the device link in place with this patch series. This should
>> power-on the supplier (which is smmu) without turning on the consumer
>> (such as GPU).
>>
>> pm_runtime_get_supplier() however is not exported at this moment.
>> Will it be useful to export this API and use it in the drivers.
>>
>
> I'm not sure pm_runtime_get_supplier() is correct either. That
> feels like we're relying on the GPU driver knowing the internal
> details of how the device links are configured.
>
what does pm_runtime_get_supplier() do if IOMMU driver hasn't setup
device-link? If it is a no-op, then I guess the GPU driver calling
pm_runtime_get_supplier() seems reasonable, and less annoying than
having special cases in pm_resume path.. I don't feel too bad about
having "just in case" get/put_supplier() calls in the unmap path.
Also, presumably we still want to avoid powering up GPU even if we
short circuit the firmware loading and rest of "booting up the GPU"..
since presumably the GPU draws somewhat more power than the IOMMU..
having the pm_resume/suspend path know about the diff between waking
up / suspending the iommu and itself doesn't really feel less-bad than
just doing "just in case" get/put_supplier() calls.
BR,
-R
> Is there some way to have the GPU driver know in its runtime PM
> resume hook that it doesn't need to be powered on because it
> isn't actively drawing anything or processing commands? I'm
> thinking of the code calling pm_runtime_get() as proposed around
> the IOMMU unmap path in the GPU driver and then having the
> runtime PM resume hook in the GPU driver return some special
> value to indicate that it didn't really resume because it didn't
> need to and to treat the device as runtime suspended but not
> return an error. Then the runtime PM core can keep track of that
> and try to power the GPU on again when another pm_runtime_get()
> is called on the GPU device.
>
> This keeps the consumer API the same, always pm_runtime_get(),
> but leaves the device driver logic of what to do when the GPU
> doesn't need to power on to the runtime PM hook where the driver
> has all the information.
>
> --
> Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
> a Linux Foundation Collaborative Project
^ permalink raw reply
* Re: [PATCH 01/13] ARM: dts: imx6qdl: SolidRun: remove redundant regulators node
From: Russell King - ARM Linux @ 2017-11-27 23:14 UTC (permalink / raw)
To: Fabio Estevam
Cc: Mark Rutland, devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
Jon Nettleton, Rob Herring, Sascha Hauer, Fabio Estevam,
Shawn Guo,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org
In-Reply-To: <CAOMZO5B9GW26+3EfutnH4meUec3qq09Q6OBYHTtdvWG+DavJwg-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
On Mon, Nov 27, 2017 at 06:15:25PM -0200, Fabio Estevam wrote:
> On Mon, Nov 27, 2017 at 2:52 PM, Russell King
> <rmk+kernel-I+IVW8TIWO2tmTQ+vhA3Yw@public.gmane.org> wrote:
>
> > - };
> > + reg_usbh1_vbus: usb-h1-vbus {
> > + compatible = "regulator-fixed";
> > + enable-active-high;
> > + gpio = <&gpio1 0 0>;
>
> gpio = <&gpio1 0 GPIO_ACTIVE_HIGH>; would be easier to read.
>
> > + reg_usbotg_vbus: usb-otg-vbus {
> > + compatible = "regulator-fixed";
> > + enable-active-high;
> > + gpio = <&gpio3 22 0>;
>
> Ditto.
>
> > + reg_brcm: brcm-reg {
> > + compatible = "regulator-fixed";
> > + enable-active-high;
> > + gpio = <&gpio3 19 0>;
>
> Ditto.
Again, this is not new code, such a change should be a separate patch,
maybe even separate from this series.
--
RMK's Patch system: http://www.armlinux.org.uk/developer/patches/
FTTC broadband for 0.8mile line in suburbia: sync at 8.8Mbps down 630kbps up
According to speedtest.net: 8.21Mbps down 510kbps up
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [PATCH 02/13] ARM: dts: imx6qdl: SolidRun: move AR8035 into microsom
From: Russell King - ARM Linux @ 2017-11-27 23:13 UTC (permalink / raw)
To: Fabio Estevam
Cc: Mark Rutland, devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
Jon Nettleton, Rob Herring, Sascha Hauer, Fabio Estevam,
Shawn Guo,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org
In-Reply-To: <CAOMZO5C+z2nFv0pFz5XDY-DGtj2YvhU_kNh1H8mdq6GOUqc_Mg-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
On Mon, Nov 27, 2017 at 06:12:38PM -0200, Fabio Estevam wrote:
> On Mon, Nov 27, 2017 at 2:52 PM, Russell King
> <rmk+kernel-I+IVW8TIWO2tmTQ+vhA3Yw@public.gmane.org> wrote:
>
> > + pinctrl_microsom_enet_ar8035: microsom-enet-ar8035 {
> > + fsl,pins = <
> > + MX6QDL_PAD_ENET_MDIO__ENET_MDIO 0x1b8b0
> > + MX6QDL_PAD_ENET_MDC__ENET_MDC 0x1b0b0
> > + /* AR8035 reset */
> > + MX6QDL_PAD_KEY_ROW4__GPIO4_IO15 0x130b0
> > + /* AR8035 interrupt */
> > + MX6QDL_PAD_DI0_PIN2__GPIO4_IO18 0x80000000
>
> Please avoid 0x80000000 and use the real IOMUX value instead.
>
> > + /* GPIO16 -> AR8035 25MHz */
> > + MX6QDL_PAD_GPIO_16__ENET_REF_CLK 0xc0000000
>
> Ditto.
>
> > + MX6QDL_PAD_RGMII_TXC__RGMII_TXC 0x80000000
>
> Ditto.
This isn't new, this is merely moving the definition from an existing
file, and when moving definitions, the golden rule is you don't
modify them. If changes are required they should be a separate
patch.
I'll try to read the correct values from the registers, but I see
this as an entirely separate thing from this series, and not
something that this series should be concerned with.
--
RMK's Patch system: http://www.armlinux.org.uk/developer/patches/
FTTC broadband for 0.8mile line in suburbia: sync at 8.8Mbps down 630kbps up
According to speedtest.net: 8.21Mbps down 510kbps up
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [PATCH 1/3] dt-bindings: Add vendor prefix for Allo.com
From: Andreas Färber @ 2017-11-27 22:51 UTC (permalink / raw)
To: sudeep kumar, linux-arm-kernel, 'Rob Herring'
Cc: 'Thomas Liau', 'Jeff Chen',
'张东风', '刘炜',
'张天益', '梅利',
'Ioan B', linux-kernel, 'Mark Rutland',
devicetree
In-Reply-To: <00d801d364d8$fcd8da60$f68a8f20$@cem-solutions.net>
Am 24.11.2017 um 05:01 schrieb sudeep kumar:
> Acked-by : sudeep <sudeepkumar@cem-solutions.net>
Thanks, adjusted, and all three queued on v4.16/dt:
https://git.kernel.org/pub/scm/linux/kernel/git/afaerber/linux-actions.git/log/?h=v4.16/dt
> -----Original Message-----
> From: Andreas Färber [mailto:afaerber@suse.de]
> Sent: Tuesday, November 14, 2017 11:31 PM
> To: linux-arm-kernel@lists.infradead.org
> Cc: Thomas Liau <thomas.liau@actions-semi.com>; Jeff Chen <jeff.chen@actions-semi.com>; 张东风 <zhangdf@actions-semi.com>; 刘炜 <liuwei@actions-semi.com>; 张天益 <tyzhang@actions-semi.com>; 梅利 <harrymei@actions-semi.com>; Ioan B <ioan@allo.com>; Sudeep Kumar <sudeepkumar@cem-solutions.net>; linux-kernel@vger.kernel.org; Andreas Färber <afaerber@suse.de>; Rob Herring <robh+dt@kernel.org>; Mark Rutland <mark.rutland@arm.com>; devicetree@vger.kernel.org
> Subject: [PATCH 1/3] dt-bindings: Add vendor prefix for Allo.com
>
> ALLO is a Canadian-Indian manufacturer of telecommunications hardware.
>
> Cc: Ioan B. <ioan@allo.com>
> Signed-off-by: Andreas Färber <afaerber@suse.de>
> ---
> Documentation/devicetree/bindings/vendor-prefixes.txt | 1 +
> 1 file changed, 1 insertion(+)
Regards,
Andreas
--
SUSE Linux GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany
GF: Felix Imendörffer, Jane Smithard, Graham Norton
HRB 21284 (AG Nürnberg)
^ permalink raw reply
* Re: [PATCH V4 3/6] iommu/arm-smmu: Invoke pm_runtime during probe, add/remove device
From: Stephen Boyd @ 2017-11-27 22:22 UTC (permalink / raw)
To: Vivek Gautam
Cc: Mark Rutland, devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
Rafael J. Wysocki, Will Deacon,
iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA@public.gmane.org,
Linux Kernel Mailing List, Rob Herring, Stanimir Varbanov,
linux-arm-msm, linux-clk,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org
In-Reply-To: <CAFp+6iGyB-iVb+vyDr6Dzk1FG6baiNy_kZWjB3sm_GViDh6rnQ-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
On 11/15, Vivek Gautam wrote:
> Hi,
>
>
> On Mon, Aug 7, 2017 at 5:59 PM, Rob Clark <robdclark-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:
> > On Mon, Aug 7, 2017 at 4:27 AM, Vivek Gautam
> > <vivek.gautam-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org> wrote:
> >> On Thu, Jul 13, 2017 at 5:20 PM, Rob Clark <robdclark-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:
> >>> On Thu, Jul 13, 2017 at 1:35 AM, Sricharan R <sricharan-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org> wrote:
> >>>> Hi Vivek,
> >>>>
> >>>> On 7/13/2017 10:43 AM, Vivek Gautam wrote:
> >>>>> Hi Stephen,
> >>>>>
> >>>>>
> >>>>> On 07/13/2017 04:24 AM, Stephen Boyd wrote:
> >>>>>> On 07/06, Vivek Gautam wrote:
> >>>>>>> @@ -1231,12 +1237,18 @@ static int arm_smmu_map(struct iommu_domain *domain, unsigned long iova,
> >>>>>>> static size_t arm_smmu_unmap(struct iommu_domain *domain, unsigned long iova,
> >>>>>>> size_t size)
> >>>>>>> {
> >>>>>>> - struct io_pgtable_ops *ops = to_smmu_domain(domain)->pgtbl_ops;
> >>>>>>> + struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain);
> >>>>>>> + struct io_pgtable_ops *ops = smmu_domain->pgtbl_ops;
> >>>>>>> + size_t ret;
> >>>>>>> if (!ops)
> >>>>>>> return 0;
> >>>>>>> - return ops->unmap(ops, iova, size);
> >>>>>>> + pm_runtime_get_sync(smmu_domain->smmu->dev);
> >>>>>> Can these map/unmap ops be called from an atomic context? I seem
> >>>>>> to recall that being a problem before.
> >>>>>
> >>>>> That's something which was dropped in the following patch merged in master:
> >>>>> 523d7423e21b iommu/arm-smmu: Remove io-pgtable spinlock
> >>>>>
> >>>>> Looks like we don't need locks here anymore?
> >>>>
> >>>> Apart from the locking, wonder why a explicit pm_runtime is needed
> >>>> from unmap. Somehow looks like some path in the master using that
> >>>> should have enabled the pm ?
> >>>>
> >>>
> >>> Yes, there are a bunch of scenarios where unmap can happen with
> >>> disabled master (but not in atomic context).
> >>
> >> I would like to understand whether there is a situation where an unmap is
> >> called in atomic context without an enabled master?
> >>
> >> Let's say we have the case where all the unmap calls in atomic context happen
> >> only from the master's context (in which case the device link should
> >> take care of
> >> the pm state of smmu), and the only unmap that happen in non-atomic context
> >> is the one with master disabled. In such a case doesn it make sense to
> >> distinguish
> >> the atomic/non-atomic context and add pm_runtime_get_sync()/put_sync() only
> >> for the non-atomic context since that would be the one with master disabled.
> >>
> >
> > At least drm/msm needs to hold obj->lock (a mutex) in unmap, so it
> > won't unmap anything in atomic ctx (but it can unmap w/ master
> > disabled). I can't really comment about other non-gpu drivers. It
> > seems like a reasonable constraint that either master is enabled or
> > not in atomic ctx.
> >
> > Currently we actually wrap unmap w/ pm_runtime_get/put_sync(), but I'd
> > like to drop that to avoid powering up the gpu.
>
> Since the deferring the TLB maintenance doesn't look like the best approach [1],
> how about if we try to power-up only the smmu from different client
> devices such as,
> GPU in the unmap path. Then we won't need to add pm_runtime_get/put() calls in
> arm_smmu_unmap().
>
> The client device can use something like - pm_runtime_get_supplier() since
> we already have the device link in place with this patch series. This should
> power-on the supplier (which is smmu) without turning on the consumer
> (such as GPU).
>
> pm_runtime_get_supplier() however is not exported at this moment.
> Will it be useful to export this API and use it in the drivers.
>
I'm not sure pm_runtime_get_supplier() is correct either. That
feels like we're relying on the GPU driver knowing the internal
details of how the device links are configured.
Is there some way to have the GPU driver know in its runtime PM
resume hook that it doesn't need to be powered on because it
isn't actively drawing anything or processing commands? I'm
thinking of the code calling pm_runtime_get() as proposed around
the IOMMU unmap path in the GPU driver and then having the
runtime PM resume hook in the GPU driver return some special
value to indicate that it didn't really resume because it didn't
need to and to treat the device as runtime suspended but not
return an error. Then the runtime PM core can keep track of that
and try to power the GPU on again when another pm_runtime_get()
is called on the GPU device.
This keeps the consumer API the same, always pm_runtime_get(),
but leaves the device driver logic of what to do when the GPU
doesn't need to power on to the runtime PM hook where the driver
has all the information.
--
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project
^ permalink raw reply
* [PATCH] ARM: dts: imx6qdl-udoo: add support for powering off
From: Maciej S. Szmigiero @ 2017-11-27 22:22 UTC (permalink / raw)
To: Shawn Guo, Sascha Hauer
Cc: Fabio Estevam, linux-arm-kernel, devicetree, linux-kernel
UDOO board has a possibility to disable most of imx6 SoC power supplies via
"EN_5V" signal, which is connected to "NANDF_D4" pad.
This reduces current consumption after shutdown from ~350 mA to ~40 mA and
prevents a SoC watchdog from starting it again on its own after the
watchdog timeout expires (previously it was not possible to shut down the
SoC permanently if its watchdog was ever enabled since it was still ticking
after the shutdown).
Unfortunately, this does not extinguish the "Power" LED (as it is powered
from an always-on voltage regulator).
To power the SoC up again press the power button (SW2, the one with a long
shaft).
Signed-off-by: Maciej S. Szmigiero <mail@maciej.szmigiero.name>
---
arch/arm/boot/dts/imx6qdl-udoo.dtsi | 13 +++++++++++++
1 file changed, 13 insertions(+)
diff --git a/arch/arm/boot/dts/imx6qdl-udoo.dtsi b/arch/arm/boot/dts/imx6qdl-udoo.dtsi
index dd69e8397116..442a6d69ede8 100644
--- a/arch/arm/boot/dts/imx6qdl-udoo.dtsi
+++ b/arch/arm/boot/dts/imx6qdl-udoo.dtsi
@@ -30,6 +30,13 @@
status = "disabled";
};
+ gpio-poweroff {
+ compatible = "gpio-poweroff";
+ gpios = <&gpio2 4 0>;
+ pinctrl-0 = <&pinctrl_power_off>;
+ pinctrl-names = "default";
+ };
+
memory {
reg = <0x10000000 0x40000000>;
};
@@ -163,6 +170,12 @@
>;
};
+ pinctrl_power_off: poweroffgrp {
+ fsl,pins = <
+ MX6QDL_PAD_NANDF_D4__GPIO2_IO04 0x30
+ >;
+ };
+
pinctrl_touchscreenp7: touchscreenp7grp {
fsl,pins = <
MX6QDL_PAD_SD2_DAT0__GPIO1_IO15 0x70
^ permalink raw reply related
* Re: [PATCH v2 1/2] iio: light: add support for UVIS25 sensor
From: Lorenzo Bianconi @ 2017-11-27 22:09 UTC (permalink / raw)
To: Jonathan Cameron
Cc: linux-iio-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <20171125161110.256aafac@archlinux>
> On Thu, 23 Nov 2017 23:59:05 +0100
> Lorenzo Bianconi <lorenzo.bianconi83-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:
>
>> add support for STMicroelectronics UVIS25 uv sensor
>> http://www.st.com/resource/en/datasheet/uvis25.pdf
>>
>> - continuos mode support
>> - i2c support
>> - spi support
>> - trigger mode support
>> - system PM support
>>
>> Signed-off-by: Lorenzo Bianconi <lorenzo.bianconi83-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
> A couple of really trivial bits inline. I'll clean those up whilst
> applying...
>
> Applied to the togreg branch of iio.git and pushed out as testing
> for the autobuilders to play with it.
>
> Thanks,
>
> Jonathan
>
>> ---
>> drivers/iio/light/Kconfig | 24 +++
>> drivers/iio/light/Makefile | 3 +
>> drivers/iio/light/st_uvis25.h | 37 ++++
>> drivers/iio/light/st_uvis25_core.c | 360 +++++++++++++++++++++++++++++++++++++
>> drivers/iio/light/st_uvis25_i2c.c | 69 +++++++
>> drivers/iio/light/st_uvis25_spi.c | 68 +++++++
>> 6 files changed, 561 insertions(+)
>> create mode 100644 drivers/iio/light/st_uvis25.h
>> create mode 100644 drivers/iio/light/st_uvis25_core.c
>> create mode 100644 drivers/iio/light/st_uvis25_i2c.c
>> create mode 100644 drivers/iio/light/st_uvis25_spi.c
>>
>> diff --git a/drivers/iio/light/Kconfig b/drivers/iio/light/Kconfig
>> index 6a5835fab32e..93fd421b10d7 100644
>> --- a/drivers/iio/light/Kconfig
>> +++ b/drivers/iio/light/Kconfig
>> @@ -334,6 +334,30 @@ config STK3310
>> Choosing M will build the driver as a module. If so, the module
>> will be called stk3310.
>>
>> +config ST_UVIS25
>> + tristate "STMicroelectronics UVIS25 sensor driver"
>> + depends on (I2C || SPI)
>> + select IIO_BUFFER
>> + select IIO_TRIGGERED_BUFFER
>> + select ST_UVIS25_I2C if (I2C)
>> + select ST_UVIS25_SPI if (SPI_MASTER)
>> + help
>> + Say yes here to build support for STMicroelectronics UVIS25
>> + uv sensor
>> +
>> + To compile this driver as a module, choose M here: the module
>> + will be called st_uvis25.
>> +
>> +config ST_UVIS25_I2C
>> + tristate
>> + depends on ST_UVIS25
>> + select REGMAP_I2C
>> +
>> +config ST_UVIS25_SPI
>> + tristate
>> + depends on ST_UVIS25
>> + select REGMAP_SPI
>> +
>> config TCS3414
>> tristate "TAOS TCS3414 digital color sensor"
>> depends on I2C
>> diff --git a/drivers/iio/light/Makefile b/drivers/iio/light/Makefile
>> index f0176a800e14..f714067a7816 100644
>> --- a/drivers/iio/light/Makefile
>> +++ b/drivers/iio/light/Makefile
>> @@ -33,6 +33,9 @@ obj-$(CONFIG_RPR0521) += rpr0521.o
>> obj-$(CONFIG_SENSORS_TSL2563) += tsl2563.o
>> obj-$(CONFIG_SI1145) += si1145.o
>> obj-$(CONFIG_STK3310) += stk3310.o
>> +obj-$(CONFIG_ST_UVIS25) += st_uvis25_core.o
>> +obj-$(CONFIG_ST_UVIS25_I2C) += st_uvis25_i2c.o
>> +obj-$(CONFIG_ST_UVIS25_SPI) += st_uvis25_spi.o
>> obj-$(CONFIG_TCS3414) += tcs3414.o
>> obj-$(CONFIG_TCS3472) += tcs3472.o
>> obj-$(CONFIG_TSL2583) += tsl2583.o
>> diff --git a/drivers/iio/light/st_uvis25.h b/drivers/iio/light/st_uvis25.h
>> new file mode 100644
>> index 000000000000..5e970ab480cd
>> --- /dev/null
>> +++ b/drivers/iio/light/st_uvis25.h
>> @@ -0,0 +1,37 @@
>> +/*
>> + * STMicroelectronics uvis25 sensor driver
>> + *
>> + * Copyright 2017 STMicroelectronics Inc.
>> + *
>> + * Lorenzo Bianconi <lorenzo.bianconi83-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
>> + *
>> + * Licensed under the GPL-2.
>> + */
>> +
>> +#ifndef ST_UVIS25_H
>> +#define ST_UVIS25_H
>> +
>> +#define ST_UVIS25_DEV_NAME "uvis25"
>> +
>> +#include <linux/iio/iio.h>
>> +
>> +/**
>> + * struct st_uvis25_hw - ST UVIS25 sensor instance
>> + * @regmap: Register map of the device.
>> + * @trig: The trigger in use by the driver.
>> + * @enabled: Status of the sensor (false->off, true->on).
>> + * @irq: Device interrupt line (I2C or SPI).
>> + */
>> +struct st_uvis25_hw {
>> + struct regmap *regmap;
>> +
>> + struct iio_trigger *trig;
>> + bool enabled;
>> + int irq;
>> +};
>> +
>> +extern const struct dev_pm_ops st_uvis25_pm_ops;
>> +
>> +int st_uvis25_probe(struct device *dev, int irq, struct regmap *regmap);
>> +
>> +#endif /* ST_UVIS25_H */
>> diff --git a/drivers/iio/light/st_uvis25_core.c b/drivers/iio/light/st_uvis25_core.c
>> new file mode 100644
>> index 000000000000..013da48df571
>> --- /dev/null
>> +++ b/drivers/iio/light/st_uvis25_core.c
>> @@ -0,0 +1,360 @@
>> +/*
>> + * STMicroelectronics uvis25 sensor driver
>> + *
>> + * Copyright 2017 STMicroelectronics Inc.
>> + *
>> + * Lorenzo Bianconi <lorenzo.bianconi83-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
>> + *
>> + * Licensed under the GPL-2.
>> + */
>> +
>> +#include <linux/kernel.h>
>> +#include <linux/module.h>
>> +#include <linux/device.h>
>> +#include <linux/iio/sysfs.h>
>> +#include <linux/delay.h>
>> +#include <linux/pm.h>
>> +#include <linux/interrupt.h>
>> +#include <linux/irqreturn.h>
>> +#include <linux/iio/trigger.h>
>> +#include <linux/iio/trigger_consumer.h>
>> +#include <linux/iio/triggered_buffer.h>
>> +#include <linux/iio/buffer.h>
>> +#include <linux/regmap.h>
>> +
>> +#include "st_uvis25.h"
>> +
>> +#define ST_UVIS25_REG_WHOAMI_ADDR 0x0f
>> +#define ST_UVIS25_REG_WHOAMI_VAL 0xca
>> +#define ST_UVIS25_REG_CTRL1_ADDR 0x20
>> +#define ST_UVIS25_REG_ODR_MASK BIT(0)
>> +#define ST_UVIS25_REG_BDU_MASK BIT(1)
>> +#define ST_UVIS25_REG_CTRL2_ADDR 0x21
>> +#define ST_UVIS25_REG_BOOT_MASK BIT(7)
>> +#define ST_UVIS25_REG_CTRL3_ADDR 0x22
>> +#define ST_UVIS25_REG_HL_MASK BIT(7)
>> +#define ST_UVIS25_REG_STATUS_ADDR 0x27
>> +#define ST_UVIS25_REG_UV_DA_MASK BIT(0)
>> +#define ST_UVIS25_REG_OUT_ADDR 0x28
>> +
>> +static const struct iio_chan_spec st_uvis25_channels[] = {
>> + {
>> + .type = IIO_UVINDEX,
>> + .address = ST_UVIS25_REG_OUT_ADDR,
>> + .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED),
>> + .scan_index = 0,
>> + .scan_type = {
>> + .sign = 'u',
>> + .realbits = 8,
>> + .storagebits = 8,
>> + },
>> + },
>> + IIO_CHAN_SOFT_TIMESTAMP(1),
>> +};
>> +
>> +static int st_uvis25_check_whoami(struct st_uvis25_hw *hw)
>> +{
>> + int err, data;
>> +
>> + err = regmap_read(hw->regmap, ST_UVIS25_REG_WHOAMI_ADDR, &data);
>> + if (err < 0) {
>> + dev_err(regmap_get_device(hw->regmap),
>> + "failed to read whoami register\n");
>> + return err;
>> + }
>> +
>> + if (data != ST_UVIS25_REG_WHOAMI_VAL) {
>> + dev_err(regmap_get_device(hw->regmap),
>> + "wrong whoami {%02x vs %02x}\n",
>> + data, ST_UVIS25_REG_WHOAMI_VAL);
>> + return -ENODEV;
>> + }
>> +
>> + return 0;
>> +}
>> +
>> +static int st_uvis25_set_enable(struct st_uvis25_hw *hw, bool enable)
>> +{
>> + int err;
>> +
>> + err = regmap_update_bits(hw->regmap, ST_UVIS25_REG_CTRL1_ADDR,
>> + ST_UVIS25_REG_ODR_MASK, enable);
>> + if (err < 0)
>> + return err;
>> +
>> + hw->enabled = enable;
>> +
>> + return 0;
>> +}
>> +
>> +static int st_uvis25_read_oneshot(struct st_uvis25_hw *hw, u8 addr, int *val)
>> +{
>> + int err;
>> +
>> + err = st_uvis25_set_enable(hw, true);
>> + if (err < 0)
>> + return err;
>> +
>> + msleep(1500);
>> +
>> + /*
>> + * in order to avoid possible race conditions with interrupt
>> + * generation, disable the sensor first and then poll output
>> + * register. That sequence guarantees the interrupt will be reset
>> + * when irq line is unmasked
>> + */
>> + err = st_uvis25_set_enable(hw, false);
>> + if (err < 0)
>> + return err;
>> +
>> + err = regmap_read(hw->regmap, addr, val);
>> +
>> + return err < 0 ? err : IIO_VAL_INT;
>> +}
>> +
>> +static int st_uvis25_read_raw(struct iio_dev *iio_dev,
>> + struct iio_chan_spec const *ch,
>> + int *val, int *val2, long mask)
>> +{
>> + int ret;
>> +
>> + ret = iio_device_claim_direct_mode(iio_dev);
>> + if (ret)
>> + return ret;
>> +
>> + switch (mask) {
>> + case IIO_CHAN_INFO_PROCESSED: {
>> + struct st_uvis25_hw *hw = iio_priv(iio_dev);
>> +
>> + /*
>> + * mask irq line during oneshot read since the sensor
>> + * does not export the capability to disable data-ready line
>> + * in the register map and it is enabled by default.
>> + * If the line is unmasked during read_raw() it will be set
>> + * active and never reset since the trigger is disabled
>> + */
>> + if (hw->irq > 0)
>> + disable_irq(hw->irq);
>> + ret = st_uvis25_read_oneshot(hw, ch->address, val);
>> + if (hw->irq > 0)
>> + enable_irq(hw->irq);
>> + break;
>> + }
>> + default:
>> + ret = -EINVAL;
>> + break;
>> + }
>> +
>> + iio_device_release_direct_mode(iio_dev);
>> +
>> + return ret;
>> +}
>> +
>> +static irqreturn_t st_uvis25_trigger_handler_thread(int irq, void *private)
>> +{
>> + struct st_uvis25_hw *hw = private;
>> + int err, status;
>> +
>> + err = regmap_read(hw->regmap, ST_UVIS25_REG_STATUS_ADDR, &status);
>> + if (err < 0)
>> + return IRQ_HANDLED;
>> +
>> + if (!(status & ST_UVIS25_REG_UV_DA_MASK))
>> + return IRQ_NONE;
>> +
>> + iio_trigger_poll_chained(hw->trig);
>> +
>> + return IRQ_HANDLED;
>> +}
>> +
>> +static int st_uvis25_allocate_trigger(struct iio_dev *iio_dev)
>> +{
>> + struct st_uvis25_hw *hw = iio_priv(iio_dev);
>> + struct device *dev = regmap_get_device(hw->regmap);
>> + bool irq_active_low = false;
>> + unsigned long irq_type;
>> + int err;
>> +
>> + irq_type = irqd_get_trigger_type(irq_get_irq_data(hw->irq));
>> +
>> + switch (irq_type) {
>> + case IRQF_TRIGGER_HIGH:
>> + case IRQF_TRIGGER_RISING:
>> + break;
>> + case IRQF_TRIGGER_LOW:
>> + case IRQF_TRIGGER_FALLING:
>> + irq_active_low = true;
>> + break;
>> + default:
>> + dev_info(dev, "mode %lx unsupported\n", irq_type);
>> + return -EINVAL;
>> + }
>> +
>> + err = regmap_update_bits(hw->regmap, ST_UVIS25_REG_CTRL3_ADDR,
>> + ST_UVIS25_REG_HL_MASK, irq_active_low);
>> + if (err < 0)
>> + return err;
>> +
>> + err = devm_request_threaded_irq(dev, hw->irq, NULL,
>> + st_uvis25_trigger_handler_thread,
>> + irq_type | IRQF_ONESHOT,
>> + iio_dev->name, hw);
>> + if (err) {
>> + dev_err(dev, "failed to request trigger irq %d\n",
>> + hw->irq);
>> + return err;
>> + }
>> +
>> + hw->trig = devm_iio_trigger_alloc(dev, "%s-trigger",
>> + iio_dev->name);
>> + if (!hw->trig)
>> + return -ENOMEM;
>> +
>> + iio_trigger_set_drvdata(hw->trig, iio_dev);
>> + hw->trig->dev.parent = dev;
>> +
>> + return devm_iio_trigger_register(dev, hw->trig);
>> +}
>> +
>> +static int st_uvis25_buffer_preenable(struct iio_dev *iio_dev)
>> +{
>> + return st_uvis25_set_enable(iio_priv(iio_dev), true);
>> +}
>> +
>> +static int st_uvis25_buffer_postdisable(struct iio_dev *iio_dev)
>> +{
>> + return st_uvis25_set_enable(iio_priv(iio_dev), false);
>> +}
>> +
>> +static const struct iio_buffer_setup_ops st_uvis25_buffer_ops = {
>> + .preenable = st_uvis25_buffer_preenable,
>> + .postenable = iio_triggered_buffer_postenable,
>> + .predisable = iio_triggered_buffer_predisable,
>> + .postdisable = st_uvis25_buffer_postdisable,
>> +};
>> +
>> +static irqreturn_t st_uvis25_buffer_handler_thread(int irq, void *p)
>> +{
>> + u8 buffer[ALIGN(sizeof(u8), sizeof(s64)) + sizeof(s64)];
>
> I thought we were going to run into dma safe buffer issues but
> I see regmap-spi.c uses spi_write_then_read which uses bounce
> buffers so we are fine.
>
Very good hint, thanks :)
Regards,
Lorenzo
>
>> + struct iio_poll_func *pf = p;
>> + struct iio_dev *iio_dev = pf->indio_dev;
>> + struct st_uvis25_hw *hw = iio_priv(iio_dev);
>> + int err;
>> +
>> + err = regmap_read(hw->regmap, ST_UVIS25_REG_OUT_ADDR, (int *)buffer);
>> + if (err < 0)
>> + goto out;
>> +
>> + iio_push_to_buffers_with_timestamp(iio_dev, buffer,
>> + iio_get_time_ns(iio_dev));
>> +
>> +out:
>> + iio_trigger_notify_done(hw->trig);
>> +
>> + return IRQ_HANDLED;
>> +}
>> +
>> +static int st_uvis25_allocate_buffer(struct iio_dev *iio_dev)
>> +{
>> + struct st_uvis25_hw *hw = iio_priv(iio_dev);
>> +
>> + return devm_iio_triggered_buffer_setup(regmap_get_device(hw->regmap),
>> + iio_dev, NULL,
>> + st_uvis25_buffer_handler_thread,
>> + &st_uvis25_buffer_ops);
>> +}
>> +
>> +static const struct iio_info st_uvis25_info = {
>> + .read_raw = st_uvis25_read_raw,
>> +};
>> +
>> +static int st_uvis25_init_sensor(struct st_uvis25_hw *hw)
>> +{
>> + int err;
>> +
>> + err = regmap_update_bits(hw->regmap, ST_UVIS25_REG_CTRL2_ADDR,
>> + ST_UVIS25_REG_BOOT_MASK, 1);
>> + if (err < 0)
>> + return err;
>> +
>> + msleep(2000);
>> +
>> + return regmap_update_bits(hw->regmap, ST_UVIS25_REG_CTRL1_ADDR,
>> + ST_UVIS25_REG_BDU_MASK, 1);
>> +}
>> +
>> +int st_uvis25_probe(struct device *dev, int irq, struct regmap *regmap)
>> +{
>> + struct st_uvis25_hw *hw;
>> + struct iio_dev *iio_dev;
>> + int err;
>> +
>> + iio_dev = devm_iio_device_alloc(dev, sizeof(*hw));
>> + if (!iio_dev)
>> + return -ENOMEM;
>> +
>> + dev_set_drvdata(dev, (void *)iio_dev);
>
> Never any need to cast to a (void *) as it is always fine for any pointer
> type to do this implicitly (it's in the C spec somewhere...)
>
>> +
>> + hw = iio_priv(iio_dev);
>> + hw->irq = irq;
>> + hw->regmap = regmap;
>> +
>> + err = st_uvis25_check_whoami(hw);
>> + if (err < 0)
>> + return err;
>> +
>> + iio_dev->modes = INDIO_DIRECT_MODE;
>> + iio_dev->dev.parent = dev;
>> + iio_dev->channels = st_uvis25_channels;
>> + iio_dev->num_channels = ARRAY_SIZE(st_uvis25_channels);
>> + iio_dev->name = ST_UVIS25_DEV_NAME;
>> + iio_dev->info = &st_uvis25_info;
>> +
>> + err = st_uvis25_init_sensor(hw);
>> + if (err < 0)
>> + return err;
>> +
>> + if (hw->irq > 0) {
>> + err = st_uvis25_allocate_buffer(iio_dev);
>> + if (err < 0)
>> + return err;
>> +
>> + err = st_uvis25_allocate_trigger(iio_dev);
>> + if (err)
>> + return err;
>> + }
>> +
>> + return devm_iio_device_register(dev, iio_dev);
>> +}
>> +EXPORT_SYMBOL(st_uvis25_probe);
>> +
>> +static int __maybe_unused st_uvis25_suspend(struct device *dev)
>> +{
>> + struct iio_dev *iio_dev = dev_get_drvdata(dev);
>> + struct st_uvis25_hw *hw = iio_priv(iio_dev);
>> +
>> + return regmap_update_bits(hw->regmap, ST_UVIS25_REG_CTRL1_ADDR,
>> + ST_UVIS25_REG_ODR_MASK, 0);
>> +}
>> +
>> +static int __maybe_unused st_uvis25_resume(struct device *dev)
>> +{
>> + struct iio_dev *iio_dev = dev_get_drvdata(dev);
>> + struct st_uvis25_hw *hw = iio_priv(iio_dev);
>> + int err = 0;
>> +
>> + if (hw->enabled)
>> + err = regmap_update_bits(hw->regmap, ST_UVIS25_REG_CTRL1_ADDR,
>> + ST_UVIS25_REG_ODR_MASK, 1);
> if (hw->enabled)
> return regmap_...
>
> return 0;
>> +
>> + return err;
>> +}
>> +
>> +const struct dev_pm_ops st_uvis25_pm_ops = {
>> + SET_SYSTEM_SLEEP_PM_OPS(st_uvis25_suspend, st_uvis25_resume)
>> +};
>> +EXPORT_SYMBOL(st_uvis25_pm_ops);
>> +
>> +MODULE_AUTHOR("Lorenzo Bianconi <lorenzo.bianconi83-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>");
>> +MODULE_DESCRIPTION("STMicroelectronics uvis25 sensor driver");
>> +MODULE_LICENSE("GPL v2");
>> diff --git a/drivers/iio/light/st_uvis25_i2c.c b/drivers/iio/light/st_uvis25_i2c.c
>> new file mode 100644
>> index 000000000000..e49ec46e9bb8
>> --- /dev/null
>> +++ b/drivers/iio/light/st_uvis25_i2c.c
>> @@ -0,0 +1,69 @@
>> +/*
>> + * STMicroelectronics uvis25 i2c driver
>> + *
>> + * Copyright 2017 STMicroelectronics Inc.
>> + *
>> + * Lorenzo Bianconi <lorenzo.bianconi83-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
>> + *
>> + * Licensed under the GPL-2.
>> + */
>> +
>> +#include <linux/kernel.h>
>> +#include <linux/module.h>
>> +#include <linux/acpi.h>
>> +#include <linux/i2c.h>
>> +#include <linux/slab.h>
>> +#include <linux/regmap.h>
>> +
>> +#include "st_uvis25.h"
>> +
>> +#define I2C_AUTO_INCREMENT BIT(7)
> Hmm. I think the chances of that clashing with
> something defined in the future is a little too high.
>
> Needs a prefix to avoid possible issues...
>
>> +
>> +const struct regmap_config st_uvis25_i2c_regmap_config = {
>> + .reg_bits = 8,
>> + .val_bits = 8,
>> + .write_flag_mask = I2C_AUTO_INCREMENT,
>> + .read_flag_mask = I2C_AUTO_INCREMENT,
>> +};
>> +
>> +static int st_uvis25_i2c_probe(struct i2c_client *client,
>> + const struct i2c_device_id *id)
>> +{
>> + struct regmap *regmap;
>> +
>> + regmap = devm_regmap_init_i2c(client, &st_uvis25_i2c_regmap_config);
>> + if (IS_ERR(regmap)) {
>> + dev_err(&client->dev, "Failed to register i2c regmap %d\n",
>> + (int)PTR_ERR(regmap));
>> + return PTR_ERR(regmap);
>> + }
>> +
>> + return st_uvis25_probe(&client->dev, client->irq, regmap);
>> +}
>> +
>> +static const struct of_device_id st_uvis25_i2c_of_match[] = {
>> + { .compatible = "st,uvis25", },
>> + {},
>> +};
>> +MODULE_DEVICE_TABLE(of, st_uvis25_i2c_of_match);
>> +
>> +static const struct i2c_device_id st_uvis25_i2c_id_table[] = {
>> + { ST_UVIS25_DEV_NAME },
>> + {},
>> +};
>> +MODULE_DEVICE_TABLE(i2c, st_uvis25_i2c_id_table);
>> +
>> +static struct i2c_driver st_uvis25_driver = {
>> + .driver = {
>> + .name = "st_uvis25_i2c",
>> + .pm = &st_uvis25_pm_ops,
>> + .of_match_table = of_match_ptr(st_uvis25_i2c_of_match),
>> + },
>> + .probe = st_uvis25_i2c_probe,
>> + .id_table = st_uvis25_i2c_id_table,
>> +};
>> +module_i2c_driver(st_uvis25_driver);
>> +
>> +MODULE_AUTHOR("Lorenzo Bianconi <lorenzo.bianconi83-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>");
>> +MODULE_DESCRIPTION("STMicroelectronics uvis25 i2c driver");
>> +MODULE_LICENSE("GPL v2");
>> diff --git a/drivers/iio/light/st_uvis25_spi.c b/drivers/iio/light/st_uvis25_spi.c
>> new file mode 100644
>> index 000000000000..06e9f7cbe1e7
>> --- /dev/null
>> +++ b/drivers/iio/light/st_uvis25_spi.c
>> @@ -0,0 +1,68 @@
>> +/*
>> + * STMicroelectronics uvis25 spi driver
>> + *
>> + * Copyright 2017 STMicroelectronics Inc.
>> + *
>> + * Lorenzo Bianconi <lorenzo.bianconi83-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
>> + *
>> + * Licensed under the GPL-2.
>> + */
>> +
>> +#include <linux/kernel.h>
>> +#include <linux/module.h>
>> +#include <linux/spi/spi.h>
>> +#include <linux/slab.h>
>> +#include <linux/regmap.h>
>> +
>> +#include "st_uvis25.h"
>> +
>> +#define SENSORS_SPI_READ BIT(7)
>> +#define SPI_AUTO_INCREMENT BIT(6)
>> +
>> +const struct regmap_config st_uvis25_spi_regmap_config = {
>> + .reg_bits = 8,
>> + .val_bits = 8,
>> + .read_flag_mask = SENSORS_SPI_READ | SPI_AUTO_INCREMENT,
>> + .write_flag_mask = SPI_AUTO_INCREMENT,
>> +};
>> +
>> +static int st_uvis25_spi_probe(struct spi_device *spi)
>> +{
>> + struct regmap *regmap;
>> +
>> + regmap = devm_regmap_init_spi(spi, &st_uvis25_spi_regmap_config);
>> + if (IS_ERR(regmap)) {
>> + dev_err(&spi->dev, "Failed to register spi regmap %d\n",
>> + (int)PTR_ERR(regmap));
>> + return PTR_ERR(regmap);
>> + }
>> +
>> + return st_uvis25_probe(&spi->dev, spi->irq, regmap);
>> +}
>> +
>> +static const struct of_device_id st_uvis25_spi_of_match[] = {
>> + { .compatible = "st,uvis25", },
>> + {},
>> +};
>> +MODULE_DEVICE_TABLE(of, st_uvis25_spi_of_match);
>> +
>> +static const struct spi_device_id st_uvis25_spi_id_table[] = {
>> + { ST_UVIS25_DEV_NAME },
>> + {},
>> +};
>> +MODULE_DEVICE_TABLE(spi, st_uvis25_spi_id_table);
>> +
>> +static struct spi_driver st_uvis25_driver = {
>> + .driver = {
>> + .name = "st_uvis25_spi",
>> + .pm = &st_uvis25_pm_ops,
>> + .of_match_table = of_match_ptr(st_uvis25_spi_of_match),
>> + },
>> + .probe = st_uvis25_spi_probe,
>> + .id_table = st_uvis25_spi_id_table,
>> +};
>> +module_spi_driver(st_uvis25_driver);
>> +
>> +MODULE_AUTHOR("Lorenzo Bianconi <lorenzo.bianconi83-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>");
>> +MODULE_DESCRIPTION("STMicroelectronics uvis25 spi driver");
>> +MODULE_LICENSE("GPL v2");
>
--
UNIX is Sexy: who | grep -i blonde | talk; cd ~; wine; talk; touch;
unzip; touch; strip; gasp; finger; gasp; mount; fsck; more; yes; gasp;
umount; make clean; sleep
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* [RFC 2/2] fpga: of region: add of-fpga-region to whitelist
From: Alan Tull @ 2017-11-27 20:58 UTC (permalink / raw)
To: Rob Herring, Frank Rowand, Pantelis Antoniou
Cc: Moritz Fischer, Alan Tull, devicetree, linux-kernel, linux-fpga
In-Reply-To: <1511816284-12145-1-git-send-email-atull@kernel.org>
During each FPGA region's probe, add to whitelist. Remove
during driver remove.
Signed-off-by: Alan Tull <atull@kernel.org>
---
drivers/fpga/of-fpga-region.c | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/drivers/fpga/of-fpga-region.c b/drivers/fpga/of-fpga-region.c
index 7dfaa95..abb57a9 100644
--- a/drivers/fpga/of-fpga-region.c
+++ b/drivers/fpga/of-fpga-region.c
@@ -435,6 +435,10 @@ static int of_fpga_region_probe(struct platform_device *pdev)
/* Specify how to get bridges for this type of region. */
region->get_bridges = of_fpga_region_get_bridges;
+ ret = of_add_whitelist_node(np);
+ if (ret)
+ goto eprobe_wl_err;
+
ret = fpga_region_register(region);
if (ret)
goto eprobe_mgr_put;
@@ -447,6 +451,8 @@ static int of_fpga_region_probe(struct platform_device *pdev)
return 0;
eprobe_mgr_put:
+ of_remove_whitelist_node(np);
+eprobe_wl_err:
fpga_mgr_put(mgr);
return ret;
}
@@ -454,7 +460,10 @@ static int of_fpga_region_probe(struct platform_device *pdev)
static int of_fpga_region_remove(struct platform_device *pdev)
{
struct fpga_region *region = platform_get_drvdata(pdev);
+ struct device *dev = &pdev->dev;
+ struct device_node *np = dev->of_node;
+ of_remove_whitelist_node(np);
fpga_region_unregister(region);
fpga_mgr_put(region->mgr);
--
2.7.4
^ permalink raw reply related
* [RFC 1/2] of: overlay: add whitelist
From: Alan Tull @ 2017-11-27 20:58 UTC (permalink / raw)
To: Rob Herring, Frank Rowand, Pantelis Antoniou
Cc: Moritz Fischer, Alan Tull, devicetree, linux-kernel, linux-fpga
In-Reply-To: <1511816284-12145-1-git-send-email-atull@kernel.org>
Add simple whitelist. When an overlay is submitted, if any target in
the overlay is not in the whitelist, the overlay is rejected. Drivers
that support dynamic configuration can register their device node with:
int of_add_whitelist_node(struct device_node *np)
and remove themselves with:
void of_remove_whitelist_node(struct device_node *np)
Signed-off-by: Alan Tull <atull@kernel.org>
---
drivers/of/overlay.c | 73 ++++++++++++++++++++++++++++++++++++++++++++++++++++
include/linux/of.h | 12 +++++++++
2 files changed, 85 insertions(+)
diff --git a/drivers/of/overlay.c b/drivers/of/overlay.c
index c150abb..5f952a1 100644
--- a/drivers/of/overlay.c
+++ b/drivers/of/overlay.c
@@ -21,6 +21,7 @@
#include <linux/slab.h>
#include <linux/err.h>
#include <linux/idr.h>
+#include <linux/spinlock.h>
#include "of_private.h"
@@ -646,6 +647,74 @@ static void free_overlay_changeset(struct overlay_changeset *ovcs)
kfree(ovcs);
}
+/* lock for adding/removing device nodes to the whitelist */
+static spinlock_t whitelist_lock;
+
+static struct list_head whitelist_list = LIST_HEAD_INIT(whitelist_list);
+
+struct dt_overlay_whitelist {
+ struct device_node *np;
+ struct list_head node;
+};
+
+int of_add_whitelist_node(struct device_node *np)
+{
+ unsigned long flags;
+ struct dt_overlay_whitelist *wln;
+
+ wln = kzalloc(sizeof(*wln), GFP_KERNEL);
+ if (!wln)
+ return -ENOMEM;
+
+ wln->np = np;
+
+ spin_lock_irqsave(&whitelist_lock, flags);
+ list_add(&wln->node, &whitelist_list);
+ spin_unlock_irqrestore(&whitelist_lock, flags);
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(of_add_whitelist_node);
+
+void of_remove_whitelist_node(struct device_node *np)
+{
+ struct dt_overlay_whitelist *wln;
+ unsigned long flags;
+
+ list_for_each_entry(wln, &whitelist_list, node) {
+ if (np == wln->np) {
+ spin_lock_irqsave(&whitelist_lock, flags);
+ list_del(&wln->node);
+ spin_unlock_irqrestore(&whitelist_lock, flags);
+ kfree(wln);
+ return;
+ }
+ }
+}
+EXPORT_SYMBOL_GPL(of_remove_whitelist_node);
+
+static int of_check_whitelist(struct overlay_changeset *ovcs)
+{
+ struct dt_overlay_whitelist *wln;
+ struct device_node *target;
+ int i;
+
+ for (i = 0; i < ovcs->count; i++) {
+ target = ovcs->fragments[i].target;
+ if (!of_node_cmp(target->name, "__symbols__"))
+ continue;
+
+ list_for_each_entry(wln, &whitelist_list, node)
+ if (target == wln->np)
+ break;
+
+ if (target != wln->np)
+ return -ENODEV;
+ }
+
+ return 0;
+}
+
/**
* of_overlay_apply() - Create and apply an overlay changeset
* @tree: Expanded overlay device tree
@@ -717,6 +786,10 @@ int of_overlay_apply(struct device_node *tree, int *ovcs_id)
if (ret)
goto err_free_overlay_changeset;
+ ret = of_check_whitelist(ovcs);
+ if (ret)
+ goto err_free_overlay_changeset;
+
ret = overlay_notify(ovcs, OF_OVERLAY_PRE_APPLY);
if (ret) {
pr_err("overlay changeset pre-apply notify error %d\n", ret);
diff --git a/include/linux/of.h b/include/linux/of.h
index d3dea1d..5bf652a1 100644
--- a/include/linux/of.h
+++ b/include/linux/of.h
@@ -1364,6 +1364,9 @@ int of_overlay_remove_all(void);
int of_overlay_notifier_register(struct notifier_block *nb);
int of_overlay_notifier_unregister(struct notifier_block *nb);
+int of_add_whitelist_node(struct device_node *np);
+void of_remove_whitelist_node(struct device_node *np);
+
#else
static inline int of_overlay_apply(struct device_node *tree, int *ovcs_id)
@@ -1391,6 +1394,15 @@ static inline int of_overlay_notifier_unregister(struct notifier_block *nb)
return 0;
}
+static inline int of_add_whitelist_node(struct device_node *np)
+{
+ return 0;
+}
+
+static inline void of_remove_whitelist_node(struct device_node *np)
+{
+}
+
#endif
#endif /* _LINUX_OF_H */
--
2.7.4
^ 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