Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge branches 'clk-nvidia', 'clk-rockchip', 'clk-at91' and 'clk-vc5' into clk-next

- Support the SD/OE pin on IDT VersaClock 5 and 6 clock generators

* clk-nvidia:
clk: tegra: fix old-style declaration
clk: tegra: Remove CLK_IS_CRITICAL flag from fuse clock
soc/tegra: fuse: Enable fuse clock on suspend for Tegra124
soc/tegra: fuse: Add runtime PM support
soc/tegra: fuse: Clear fuse->clk on driver probe failure
soc/tegra: pmc: Prevent racing with cpuilde driver
soc/tegra: bpmp: Remove unused including <linux/version.h>

* clk-rockchip:
clk: rockchip: make rk3308 ddrphy4x clock critical
clk: rockchip: drop GRF dependency for rk3328/rk3036 pll types
dt-bindings: clk: Convert rockchip,rk3399-cru to DT schema
clk: rockchip: Add support for hclk_sfc on rk3036
clk: rockchip: rk3036: fix up the sclk_sfc parent error
clk: rockchip: add dt-binding clkid for hclk_sfc on rk3036

* clk-at91:
clk: at91: clk-generated: Limit the requested rate to our range

* clk-vc5:
clk: vc5: Add properties for configuring SD/OE behavior
clk: vc5: Use dev_err_probe
dt-bindings: clk: vc5: Add properties for configuring the SD/OE pin

+279 -106
+40
Documentation/devicetree/bindings/clock/idt,versaclock5.yaml
··· 30 30 3 -- OUT3 31 31 4 -- OUT4 32 32 33 + The idt,shutdown and idt,output-enable-active properties control the 34 + SH (en_global_shutdown) and SP bits of the Primary Source and Shutdown 35 + Register, respectively. Their behavior is summarized by the following 36 + table: 37 + 38 + SH SP Output when the SD/OE pin is Low/High 39 + == == ===================================== 40 + 0 0 Active/Inactive 41 + 0 1 Inactive/Active 42 + 1 0 Active/Shutdown 43 + 1 1 Inactive/Shutdown 44 + 45 + The case where SH and SP are both 1 is likely not very interesting. 46 + 33 47 maintainers: 34 48 - Luca Ceresoli <luca@lucaceresoli.net> 35 49 ··· 78 64 maximum: 22760 79 65 description: Optional load capacitor for XTAL1 and XTAL2 80 66 67 + idt,shutdown: 68 + $ref: /schemas/types.yaml#/definitions/uint32 69 + enum: [0, 1] 70 + description: | 71 + If 1, this enables the shutdown functionality: the chip will be 72 + shut down if the SD/OE pin is driven high. If 0, this disables the 73 + shutdown functionality: the chip will never be shut down based on 74 + the value of the SD/OE pin. This property corresponds to the SH 75 + bit of the Primary Source and Shutdown Register. 76 + 77 + idt,output-enable-active: 78 + $ref: /schemas/types.yaml#/definitions/uint32 79 + enum: [0, 1] 80 + description: | 81 + If 1, this enables output when the SD/OE pin is high, and disables 82 + output when the SD/OE pin is low. If 0, this disables output when 83 + the SD/OE pin is high, and enables output when the SD/OE pin is 84 + low. This corresponds to the SP bit of the Primary Source and 85 + Shutdown Register. 86 + 81 87 patternProperties: 82 88 "^OUT[1-4]$": 83 89 type: object ··· 124 90 - compatible 125 91 - reg 126 92 - '#clock-cells' 93 + - idt,shutdown 94 + - idt,output-enable-active 127 95 128 96 allOf: 129 97 - if: ··· 174 138 /* Connect XIN input to 25MHz reference */ 175 139 clocks = <&ref25m>; 176 140 clock-names = "xin"; 141 + 142 + /* Set the SD/OE pin's settings */ 143 + idt,shutdown = <0>; 144 + idt,output-enable-active = <0>; 177 145 178 146 OUT1 { 179 147 idt,mode = <VC5_CMOSD>;
-68
Documentation/devicetree/bindings/clock/rockchip,rk3399-cru.txt
··· 1 - * Rockchip RK3399 Clock and Reset Unit 2 - 3 - The RK3399 clock controller generates and supplies clock to various 4 - controllers within the SoC and also implements a reset controller for SoC 5 - peripherals. 6 - 7 - Required Properties: 8 - 9 - - compatible: PMU for CRU should be "rockchip,rk3399-pmucru" 10 - - compatible: CRU should be "rockchip,rk3399-cru" 11 - - reg: physical base address of the controller and length of memory mapped 12 - region. 13 - - #clock-cells: should be 1. 14 - - #reset-cells: should be 1. 15 - 16 - Optional Properties: 17 - 18 - - rockchip,grf: phandle to the syscon managing the "general register files". 19 - It is used for GRF muxes, if missing any muxes present in the GRF will not 20 - be available. 21 - 22 - Each clock is assigned an identifier and client nodes can use this identifier 23 - to specify the clock which they consume. All available clocks are defined as 24 - preprocessor macros in the dt-bindings/clock/rk3399-cru.h headers and can be 25 - used in device tree sources. Similar macros exist for the reset sources in 26 - these files. 27 - 28 - External clocks: 29 - 30 - There are several clocks that are generated outside the SoC. It is expected 31 - that they are defined using standard clock bindings with following 32 - clock-output-names: 33 - - "xin24m" - crystal input - required, 34 - - "xin32k" - rtc clock - optional, 35 - - "clkin_gmac" - external GMAC clock - optional, 36 - - "clkin_i2s" - external I2S clock - optional, 37 - - "pclkin_cif" - external ISP clock - optional, 38 - - "clk_usbphy0_480m" - output clock of the pll in the usbphy0 39 - - "clk_usbphy1_480m" - output clock of the pll in the usbphy1 40 - 41 - Example: Clock controller node: 42 - 43 - pmucru: pmu-clock-controller@ff750000 { 44 - compatible = "rockchip,rk3399-pmucru"; 45 - reg = <0x0 0xff750000 0x0 0x1000>; 46 - #clock-cells = <1>; 47 - #reset-cells = <1>; 48 - }; 49 - 50 - cru: clock-controller@ff760000 { 51 - compatible = "rockchip,rk3399-cru"; 52 - reg = <0x0 0xff760000 0x0 0x1000>; 53 - #clock-cells = <1>; 54 - #reset-cells = <1>; 55 - }; 56 - 57 - Example: UART controller node that consumes the clock generated by the clock 58 - controller: 59 - 60 - uart0: serial@ff1a0000 { 61 - compatible = "rockchip,rk3399-uart", "snps,dw-apb-uart"; 62 - reg = <0x0 0xff180000 0x0 0x100>; 63 - clocks = <&cru SCLK_UART0>, <&cru PCLK_UART0>; 64 - clock-names = "baudclk", "apb_pclk"; 65 - interrupts = <GIC_SPI 99 IRQ_TYPE_LEVEL_HIGH>; 66 - reg-shift = <2>; 67 - reg-io-width = <4>; 68 - };
+92
Documentation/devicetree/bindings/clock/rockchip,rk3399-cru.yaml
··· 1 + # SPDX-License-Identifier: GPL-2.0-only 2 + %YAML 1.2 3 + --- 4 + $id: http://devicetree.org/schemas/clock/rockchip,rk3399-cru.yaml# 5 + $schema: http://devicetree.org/meta-schemas/core.yaml# 6 + 7 + title: Rockchip RK3399 Clock and Reset Unit 8 + 9 + maintainers: 10 + - Xing Zheng <zhengxing@rock-chips.com> 11 + - Heiko Stuebner <heiko@sntech.de> 12 + 13 + description: | 14 + The RK3399 clock controller generates and supplies clock to various 15 + controllers within the SoC and also implements a reset controller for SoC 16 + peripherals. 17 + Each clock is assigned an identifier and client nodes can use this identifier 18 + to specify the clock which they consume. All available clocks are defined as 19 + preprocessor macros in the dt-bindings/clock/rk3399-cru.h headers and can be 20 + used in device tree sources. Similar macros exist for the reset sources in 21 + these files. 22 + There are several clocks that are generated outside the SoC. It is expected 23 + that they are defined using standard clock bindings with following 24 + clock-output-names: 25 + - "xin24m" - crystal input - required, 26 + - "xin32k" - rtc clock - optional, 27 + - "clkin_gmac" - external GMAC clock - optional, 28 + - "clkin_i2s" - external I2S clock - optional, 29 + - "pclkin_cif" - external ISP clock - optional, 30 + - "clk_usbphy0_480m" - output clock of the pll in the usbphy0 31 + - "clk_usbphy1_480m" - output clock of the pll in the usbphy1 32 + 33 + properties: 34 + compatible: 35 + enum: 36 + - rockchip,rk3399-pmucru 37 + - rockchip,rk3399-cru 38 + 39 + reg: 40 + maxItems: 1 41 + 42 + "#clock-cells": 43 + const: 1 44 + 45 + "#reset-cells": 46 + const: 1 47 + 48 + clocks: 49 + minItems: 1 50 + 51 + assigned-clocks: 52 + minItems: 1 53 + maxItems: 64 54 + 55 + assigned-clock-parents: 56 + minItems: 1 57 + maxItems: 64 58 + 59 + assigned-clock-rates: 60 + minItems: 1 61 + maxItems: 64 62 + 63 + rockchip,grf: 64 + $ref: /schemas/types.yaml#/definitions/phandle 65 + description: > 66 + phandle to the syscon managing the "general register files". It is used 67 + for GRF muxes, if missing any muxes present in the GRF will not be 68 + available. 69 + 70 + required: 71 + - compatible 72 + - reg 73 + - "#clock-cells" 74 + - "#reset-cells" 75 + 76 + additionalProperties: false 77 + 78 + examples: 79 + - | 80 + pmucru: pmu-clock-controller@ff750000 { 81 + compatible = "rockchip,rk3399-pmucru"; 82 + reg = <0xff750000 0x1000>; 83 + #clock-cells = <1>; 84 + #reset-cells = <1>; 85 + }; 86 + - | 87 + cru: clock-controller@ff760000 { 88 + compatible = "rockchip,rk3399-cru"; 89 + reg = <0xff760000 0x1000>; 90 + #clock-cells = <1>; 91 + #reset-cells = <1>; 92 + };
+1 -1
arch/arm/mach-tegra/pm.c
··· 403 403 .enter = tegra_suspend_enter, 404 404 }; 405 405 406 - void __init tegra_init_suspend(void) 406 + void tegra_pm_init_suspend(void) 407 407 { 408 408 enum tegra_suspend_mode mode = tegra_pmc_get_suspend_mode(); 409 409
-6
arch/arm/mach-tegra/pm.h
··· 25 25 26 26 extern void (*tegra_tear_down_cpu)(void); 27 27 28 - #ifdef CONFIG_PM_SLEEP 29 - void tegra_init_suspend(void); 30 - #else 31 - static inline void tegra_init_suspend(void) {} 32 - #endif 33 - 34 28 #endif /* _MACH_TEGRA_PM_H_ */
-2
arch/arm/mach-tegra/tegra.c
··· 84 84 85 85 static void __init tegra_dt_init_late(void) 86 86 { 87 - tegra_init_suspend(); 88 - 89 87 if (IS_ENABLED(CONFIG_ARCH_TEGRA_2x_SOC) && 90 88 of_machine_is_compatible("compal,paz00")) 91 89 tegra_paz00_wifikill_init();
+6
drivers/clk/at91/clk-generated.c
··· 128 128 int i; 129 129 u32 div; 130 130 131 + /* do not look for a rate that is outside of our range */ 132 + if (gck->range.max && req->rate > gck->range.max) 133 + req->rate = gck->range.max; 134 + if (gck->range.min && req->rate < gck->range.min) 135 + req->rate = gck->range.min; 136 + 131 137 for (i = 0; i < clk_hw_get_num_parents(hw); i++) { 132 138 if (gck->chg_pid == i) 133 139 continue;
+33 -9
drivers/clk/clk-versaclock5.c
··· 907 907 908 908 static int vc5_probe(struct i2c_client *client, const struct i2c_device_id *id) 909 909 { 910 + unsigned int oe, sd, src_mask = 0, src_val = 0; 910 911 struct vc5_driver_data *vc5; 911 912 struct clk_init_data init; 912 913 const char *parent_names[2]; ··· 931 930 return -EPROBE_DEFER; 932 931 933 932 vc5->regmap = devm_regmap_init_i2c(client, &vc5_regmap_config); 934 - if (IS_ERR(vc5->regmap)) { 935 - dev_err(&client->dev, "failed to allocate register map\n"); 936 - return PTR_ERR(vc5->regmap); 933 + if (IS_ERR(vc5->regmap)) 934 + return dev_err_probe(&client->dev, PTR_ERR(vc5->regmap), 935 + "failed to allocate register map\n"); 936 + 937 + ret = of_property_read_u32(client->dev.of_node, "idt,shutdown", &sd); 938 + if (!ret) { 939 + src_mask |= VC5_PRIM_SRC_SHDN_EN_GBL_SHDN; 940 + if (sd) 941 + src_val |= VC5_PRIM_SRC_SHDN_EN_GBL_SHDN; 942 + } else if (ret != -EINVAL) { 943 + return dev_err_probe(&client->dev, ret, 944 + "could not read idt,shutdown\n"); 937 945 } 946 + 947 + ret = of_property_read_u32(client->dev.of_node, 948 + "idt,output-enable-active", &oe); 949 + if (!ret) { 950 + src_mask |= VC5_PRIM_SRC_SHDN_SP; 951 + if (oe) 952 + src_val |= VC5_PRIM_SRC_SHDN_SP; 953 + } else if (ret != -EINVAL) { 954 + return dev_err_probe(&client->dev, ret, 955 + "could not read idt,output-enable-active\n"); 956 + } 957 + 958 + regmap_update_bits(vc5->regmap, VC5_PRIM_SRC_SHDN, src_mask, src_val); 938 959 939 960 /* Register clock input mux */ 940 961 memset(&init, 0, sizeof(init)); ··· 980 957 __clk_get_name(vc5->pin_clkin); 981 958 } 982 959 983 - if (!init.num_parents) { 984 - dev_err(&client->dev, "no input clock specified!\n"); 985 - return -EINVAL; 986 - } 960 + if (!init.num_parents) 961 + return dev_err_probe(&client->dev, -EINVAL, 962 + "no input clock specified!\n"); 987 963 988 964 /* Configure Optional Loading Capacitance for external XTAL */ 989 965 if (!(vc5->chip_info->flags & VC5_HAS_INTERNAL_XTAL)) { ··· 1121 1099 1122 1100 ret = of_clk_add_hw_provider(client->dev.of_node, vc5_of_clk_get, vc5); 1123 1101 if (ret) { 1124 - dev_err(&client->dev, "unable to add clk provider\n"); 1102 + dev_err_probe(&client->dev, ret, 1103 + "unable to add clk provider\n"); 1125 1104 goto err_clk; 1126 1105 } 1127 1106 1128 1107 return 0; 1129 1108 1130 1109 err_clk_register: 1131 - dev_err(&client->dev, "unable to register %s\n", init.name); 1110 + dev_err_probe(&client->dev, ret, 1111 + "unable to register %s\n", init.name); 1132 1112 kfree(init.name); /* clock framework made a copy of the name */ 1133 1113 err_clk: 1134 1114 if (vc5->chip_info->flags & VC5_HAS_INTERNAL_XTAL)
+1 -1
drivers/clk/rockchip/clk-pll.c
··· 940 940 switch (pll_type) { 941 941 case pll_rk3036: 942 942 case pll_rk3328: 943 - if (!pll->rate_table || IS_ERR(ctx->grf)) 943 + if (!pll->rate_table) 944 944 init.ops = &rockchip_rk3036_pll_clk_norate_ops; 945 945 else 946 946 init.ops = &rockchip_rk3036_pll_clk_ops;
+3 -2
drivers/clk/rockchip/clk-rk3036.c
··· 121 121 PNAME(mux_timer_p) = { "xin24m", "pclk_peri_src" }; 122 122 123 123 PNAME(mux_pll_src_apll_dpll_gpll_usb480m_p) = { "apll", "dpll", "gpll", "usb480m" }; 124 + PNAME(mux_pll_src_dmyapll_dpll_gpll_xin24_p) = { "dummy_apll", "dpll", "gpll", "xin24m" }; 124 125 125 126 PNAME(mux_mmc_src_p) = { "apll", "dpll", "gpll", "xin24m" }; 126 127 PNAME(mux_i2s_pre_p) = { "i2s_src", "i2s_frac", "ext_i2s", "xin12m" }; ··· 341 340 RK2928_CLKSEL_CON(16), 8, 2, MFLAGS, 10, 5, DFLAGS, 342 341 RK2928_CLKGATE_CON(10), 4, GFLAGS), 343 342 344 - COMPOSITE(SCLK_SFC, "sclk_sfc", mux_pll_src_apll_dpll_gpll_usb480m_p, 0, 343 + COMPOSITE(SCLK_SFC, "sclk_sfc", mux_pll_src_dmyapll_dpll_gpll_xin24_p, 0, 345 344 RK2928_CLKSEL_CON(16), 0, 2, MFLAGS, 2, 5, DFLAGS, 346 345 RK2928_CLKGATE_CON(10), 5, GFLAGS), 347 346 ··· 404 403 GATE(HCLK_OTG0, "hclk_otg0", "hclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(5), 13, GFLAGS), 405 404 GATE(HCLK_OTG1, "hclk_otg1", "hclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(7), 3, GFLAGS), 406 405 GATE(HCLK_I2S, "hclk_i2s", "hclk_peri", 0, RK2928_CLKGATE_CON(7), 2, GFLAGS), 407 - GATE(0, "hclk_sfc", "hclk_peri", CLK_IGNORE_UNUSED, RK2928_CLKGATE_CON(3), 14, GFLAGS), 406 + GATE(HCLK_SFC, "hclk_sfc", "hclk_peri", 0, RK2928_CLKGATE_CON(3), 14, GFLAGS), 408 407 GATE(HCLK_MAC, "hclk_mac", "hclk_peri", 0, RK2928_CLKGATE_CON(3), 5, GFLAGS), 409 408 410 409 /* pclk_peri gates */
+1
drivers/clk/rockchip/clk-rk3308.c
··· 911 911 "hclk_audio", 912 912 "pclk_audio", 913 913 "sclk_ddrc", 914 + "clk_ddrphy4x", 914 915 }; 915 916 916 917 static void __init rk3308_clk_init(struct device_node *np)
+1 -1
drivers/clk/tegra/clk-dfll.c
··· 1377 1377 } 1378 1378 1379 1379 #else 1380 - static void inline dfll_debug_init(struct tegra_dfll *td) { } 1380 + static inline void dfll_debug_init(struct tegra_dfll *td) { } 1381 1381 #endif /* CONFIG_DEBUG_FS */ 1382 1382 1383 1383 /*
+1 -5
drivers/clk/tegra/clk-tegra-periph.c
··· 777 777 GATE("ahbdma", "hclk", 33, 0, tegra_clk_ahbdma, 0), 778 778 GATE("apbdma", "pclk", 34, 0, tegra_clk_apbdma, 0), 779 779 GATE("kbc", "clk_32k", 36, TEGRA_PERIPH_ON_APB | TEGRA_PERIPH_NO_RESET, tegra_clk_kbc, 0), 780 - /* 781 - * Critical for RAM re-repair operation, which must occur on resume 782 - * from LP1 system suspend and as part of CCPLEX cluster switching. 783 - */ 784 - GATE("fuse", "clk_m", 39, TEGRA_PERIPH_ON_APB, tegra_clk_fuse, CLK_IS_CRITICAL), 780 + GATE("fuse", "clk_m", 39, TEGRA_PERIPH_ON_APB, tegra_clk_fuse, 0), 785 781 GATE("fuse_burn", "clk_m", 39, TEGRA_PERIPH_ON_APB, tegra_clk_fuse_burn, 0), 786 782 GATE("kfuse", "clk_m", 40, TEGRA_PERIPH_ON_APB, tegra_clk_kfuse, 0), 787 783 GATE("apbif", "clk_m", 107, TEGRA_PERIPH_ON_APB, tegra_clk_apbif, 0),
+60
drivers/soc/tegra/fuse/fuse-tegra.c
··· 13 13 #include <linux/of.h> 14 14 #include <linux/of_address.h> 15 15 #include <linux/platform_device.h> 16 + #include <linux/pm_runtime.h> 16 17 #include <linux/slab.h> 17 18 #include <linux/sys_soc.h> 18 19 ··· 211 210 platform_set_drvdata(pdev, fuse); 212 211 fuse->dev = &pdev->dev; 213 212 213 + pm_runtime_enable(&pdev->dev); 214 + 214 215 if (fuse->soc->probe) { 215 216 err = fuse->soc->probe(fuse); 216 217 if (err < 0) ··· 249 246 return 0; 250 247 251 248 restore: 249 + fuse->clk = NULL; 252 250 fuse->base = base; 251 + pm_runtime_disable(&pdev->dev); 253 252 return err; 254 253 } 254 + 255 + static int __maybe_unused tegra_fuse_runtime_resume(struct device *dev) 256 + { 257 + int err; 258 + 259 + err = clk_prepare_enable(fuse->clk); 260 + if (err < 0) { 261 + dev_err(dev, "failed to enable FUSE clock: %d\n", err); 262 + return err; 263 + } 264 + 265 + return 0; 266 + } 267 + 268 + static int __maybe_unused tegra_fuse_runtime_suspend(struct device *dev) 269 + { 270 + clk_disable_unprepare(fuse->clk); 271 + 272 + return 0; 273 + } 274 + 275 + static int __maybe_unused tegra_fuse_suspend(struct device *dev) 276 + { 277 + int ret; 278 + 279 + /* 280 + * Critical for RAM re-repair operation, which must occur on resume 281 + * from LP1 system suspend and as part of CCPLEX cluster switching. 282 + */ 283 + if (fuse->soc->clk_suspend_on) 284 + ret = pm_runtime_resume_and_get(dev); 285 + else 286 + ret = pm_runtime_force_suspend(dev); 287 + 288 + return ret; 289 + } 290 + 291 + static int __maybe_unused tegra_fuse_resume(struct device *dev) 292 + { 293 + int ret = 0; 294 + 295 + if (fuse->soc->clk_suspend_on) 296 + pm_runtime_put(dev); 297 + else 298 + ret = pm_runtime_force_resume(dev); 299 + 300 + return ret; 301 + } 302 + 303 + static const struct dev_pm_ops tegra_fuse_pm = { 304 + SET_RUNTIME_PM_OPS(tegra_fuse_runtime_suspend, tegra_fuse_runtime_resume, 305 + NULL) 306 + SET_SYSTEM_SLEEP_PM_OPS(tegra_fuse_suspend, tegra_fuse_resume) 307 + }; 255 308 256 309 static struct platform_driver tegra_fuse_driver = { 257 310 .driver = { 258 311 .name = "tegra-fuse", 259 312 .of_match_table = tegra_fuse_match, 313 + .pm = &tegra_fuse_pm, 260 314 .suppress_bind_attrs = true, 261 315 }, 262 316 .probe = tegra_fuse_probe,
+7 -4
drivers/soc/tegra/fuse/fuse-tegra20.c
··· 16 16 #include <linux/kobject.h> 17 17 #include <linux/of_device.h> 18 18 #include <linux/platform_device.h> 19 + #include <linux/pm_runtime.h> 19 20 #include <linux/random.h> 20 21 21 22 #include <soc/tegra/fuse.h> ··· 47 46 u32 value = 0; 48 47 int err; 49 48 49 + err = pm_runtime_resume_and_get(fuse->dev); 50 + if (err) 51 + return err; 52 + 50 53 mutex_lock(&fuse->apbdma.lock); 51 54 52 55 fuse->apbdma.config.src_addr = fuse->phys + FUSE_BEGIN + offset; ··· 71 66 72 67 reinit_completion(&fuse->apbdma.wait); 73 68 74 - clk_prepare_enable(fuse->clk); 75 - 76 69 dmaengine_submit(dma_desc); 77 70 dma_async_issue_pending(fuse->apbdma.chan); 78 71 time_left = wait_for_completion_timeout(&fuse->apbdma.wait, ··· 81 78 else 82 79 value = *fuse->apbdma.virt; 83 80 84 - clk_disable_unprepare(fuse->clk); 85 - 86 81 out: 87 82 mutex_unlock(&fuse->apbdma.lock); 83 + pm_runtime_put(fuse->dev); 88 84 return value; 89 85 } 90 86 ··· 167 165 .probe = tegra20_fuse_probe, 168 166 .info = &tegra20_fuse_info, 169 167 .soc_attr_group = &tegra_soc_attr_group, 168 + .clk_suspend_on = false, 170 169 };
+11 -5
drivers/soc/tegra/fuse/fuse-tegra30.c
··· 12 12 #include <linux/of_device.h> 13 13 #include <linux/of_address.h> 14 14 #include <linux/platform_device.h> 15 + #include <linux/pm_runtime.h> 15 16 #include <linux/random.h> 16 17 17 18 #include <soc/tegra/fuse.h> ··· 53 52 u32 value; 54 53 int err; 55 54 56 - err = clk_prepare_enable(fuse->clk); 57 - if (err < 0) { 58 - dev_err(fuse->dev, "failed to enable FUSE clock: %d\n", err); 55 + err = pm_runtime_resume_and_get(fuse->dev); 56 + if (err) 59 57 return 0; 60 - } 61 58 62 59 value = readl_relaxed(fuse->base + FUSE_BEGIN + offset); 63 60 64 - clk_disable_unprepare(fuse->clk); 61 + pm_runtime_put(fuse->dev); 65 62 66 63 return value; 67 64 } ··· 112 113 .speedo_init = tegra30_init_speedo_data, 113 114 .info = &tegra30_fuse_info, 114 115 .soc_attr_group = &tegra_soc_attr_group, 116 + .clk_suspend_on = false, 115 117 }; 116 118 #endif 117 119 ··· 128 128 .speedo_init = tegra114_init_speedo_data, 129 129 .info = &tegra114_fuse_info, 130 130 .soc_attr_group = &tegra_soc_attr_group, 131 + .clk_suspend_on = false, 131 132 }; 132 133 #endif 133 134 ··· 210 209 .lookups = tegra124_fuse_lookups, 211 210 .num_lookups = ARRAY_SIZE(tegra124_fuse_lookups), 212 211 .soc_attr_group = &tegra_soc_attr_group, 212 + .clk_suspend_on = true, 213 213 }; 214 214 #endif 215 215 ··· 297 295 .lookups = tegra210_fuse_lookups, 298 296 .num_lookups = ARRAY_SIZE(tegra210_fuse_lookups), 299 297 .soc_attr_group = &tegra_soc_attr_group, 298 + .clk_suspend_on = false, 300 299 }; 301 300 #endif 302 301 ··· 328 325 .lookups = tegra186_fuse_lookups, 329 326 .num_lookups = ARRAY_SIZE(tegra186_fuse_lookups), 330 327 .soc_attr_group = &tegra_soc_attr_group, 328 + .clk_suspend_on = false, 331 329 }; 332 330 #endif 333 331 ··· 359 355 .lookups = tegra194_fuse_lookups, 360 356 .num_lookups = ARRAY_SIZE(tegra194_fuse_lookups), 361 357 .soc_attr_group = &tegra194_soc_attr_group, 358 + .clk_suspend_on = false, 362 359 }; 363 360 #endif 364 361 ··· 390 385 .lookups = tegra234_fuse_lookups, 391 386 .num_lookups = ARRAY_SIZE(tegra234_fuse_lookups), 392 387 .soc_attr_group = &tegra194_soc_attr_group, 388 + .clk_suspend_on = false, 393 389 }; 394 390 #endif
+2
drivers/soc/tegra/fuse/fuse.h
··· 34 34 unsigned int num_lookups; 35 35 36 36 const struct attribute_group *soc_attr_group; 37 + 38 + bool clk_suspend_on; 37 39 }; 38 40 39 41 struct tegra_fuse {
+13 -1
drivers/soc/tegra/pmc.c
··· 436 436 437 437 static struct tegra_pmc *pmc = &(struct tegra_pmc) { 438 438 .base = NULL, 439 - .suspend_mode = TEGRA_SUSPEND_NONE, 439 + .suspend_mode = TEGRA_SUSPEND_NOT_READY, 440 440 }; 441 441 442 442 static inline struct tegra_powergate * ··· 1812 1812 u32 value, values[2]; 1813 1813 1814 1814 if (of_property_read_u32(np, "nvidia,suspend-mode", &value)) { 1815 + pmc->suspend_mode = TEGRA_SUSPEND_NONE; 1815 1816 } else { 1816 1817 switch (value) { 1817 1818 case 0: ··· 2786 2785 return 0; 2787 2786 } 2788 2787 2788 + static void tegra_pmc_reset_suspend_mode(void *data) 2789 + { 2790 + pmc->suspend_mode = TEGRA_SUSPEND_NOT_READY; 2791 + } 2792 + 2789 2793 static int tegra_pmc_probe(struct platform_device *pdev) 2790 2794 { 2791 2795 void __iomem *base; ··· 2807 2801 2808 2802 err = tegra_pmc_parse_dt(pmc, pdev->dev.of_node); 2809 2803 if (err < 0) 2804 + return err; 2805 + 2806 + err = devm_add_action_or_reset(&pdev->dev, tegra_pmc_reset_suspend_mode, 2807 + NULL); 2808 + if (err) 2810 2809 return err; 2811 2810 2812 2811 /* take over the memory region from the early initialization */ ··· 2920 2909 2921 2910 tegra_pmc_clock_register(pmc, pdev->dev.of_node); 2922 2911 platform_set_drvdata(pdev, pmc); 2912 + tegra_pm_init_suspend(); 2923 2913 2924 2914 return 0; 2925 2915
-1
drivers/soc/tegra/powergate-bpmp.c
··· 7 7 #include <linux/platform_device.h> 8 8 #include <linux/pm_domain.h> 9 9 #include <linux/slab.h> 10 - #include <linux/version.h> 11 10 12 11 #include <soc/tegra/bpmp.h> 13 12 #include <soc/tegra/bpmp-abi.h>
+1
include/dt-bindings/clock/rk3036-cru.h
··· 81 81 #define HCLK_OTG0 449 82 82 #define HCLK_OTG1 450 83 83 #define HCLK_NANDC 453 84 + #define HCLK_SFC 454 84 85 #define HCLK_SDMMC 456 85 86 #define HCLK_SDIO 457 86 87 #define HCLK_EMMC 459
+6
include/soc/tegra/pm.h
··· 14 14 TEGRA_SUSPEND_LP1, /* CPU voltage off, DRAM self-refresh */ 15 15 TEGRA_SUSPEND_LP0, /* CPU + core voltage off, DRAM self-refresh */ 16 16 TEGRA_MAX_SUSPEND_MODE, 17 + TEGRA_SUSPEND_NOT_READY, 17 18 }; 18 19 19 20 #if defined(CONFIG_PM_SLEEP) && defined(CONFIG_ARM) ··· 29 28 void tegra_pm_set_cpu_in_lp2(void); 30 29 int tegra_pm_enter_lp2(void); 31 30 int tegra_pm_park_secondary_cpu(unsigned long cpu); 31 + void tegra_pm_init_suspend(void); 32 32 #else 33 33 static inline enum tegra_suspend_mode 34 34 tegra_pm_validate_suspend_mode(enum tegra_suspend_mode mode) ··· 62 60 static inline int tegra_pm_park_secondary_cpu(unsigned long cpu) 63 61 { 64 62 return -ENOTSUPP; 63 + } 64 + 65 + static inline void tegra_pm_init_suspend(void) 66 + { 65 67 } 66 68 #endif /* CONFIG_PM_SLEEP */ 67 69