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

Merge tag 'armsoc-drivers' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc

Pull ARM SoC driver updates from Olof Johansson:
"Driver updates for ARM SoCs:

Reset subsystem, merged through arm-soc by tradition:
- Make bool drivers explicitly non-modular
- New support for i.MX7 and Arria10 reset controllers

PATA driver for Palmchip BK371 (acked by Tejun)

Power domain drivers for i.MX (GPC, GPCv2)
- Moved out of mach-imx for GPC
- Bunch of tweaks, fixes, etc

PMC support for Tegra186

SoC detection support for Renesas RZ/G1H and RZ/G1N

Move Tegra flow controller driver from mach directory to drivers/soc
- (Power management / CPU power driver)

Misc smaller tweaks for other platforms"

* tag 'armsoc-drivers' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc: (60 commits)
soc: pm-domain: Fix the mangled urls
soc: renesas: rcar-sysc: Add support for R-Car H3 ES2.0
soc: renesas: rcar-sysc: Add support for fixing up power area tables
soc: renesas: Register SoC device early
soc: imx: gpc: add workaround for i.MX6QP to the GPC PD driver
dt-bindings: imx-gpc: add i.MX6 QuadPlus compatible
soc: imx: gpc: add defines for domain index
soc: imx: Add GPCv2 power gating driver
dt-bindings: Add GPCv2 power gating driver
ARM/clk: move the ICST library to drivers/clk
ARM: plat-versatile: remove stale clock header
ARM: keystone: Drop PM domain support for k2g
soc: ti: Add ti_sci_pm_domains driver
dt-bindings: Add TI SCI PM Domains
PM / Domains: Do not check if simple providers have phandle cells
PM / Domains: Add generic data pointer to genpd data struct
soc/tegra: Add initial flowctrl support for Tegra132/210
soc/tegra: flowctrl: Add basic platform driver
soc/tegra: Move Tegra flowctrl driver
ARM: tegra: Remove unnecessary inclusion of flowctrl header
...

+2947 -438
+34
Documentation/devicetree/bindings/arm/tegra/nvidia,tegra186-pmc.txt
··· 1 + NVIDIA Tegra Power Management Controller (PMC) 2 + 3 + Required properties: 4 + - compatible: Should contain one of the following: 5 + - "nvidia,tegra186-pmc": for Tegra186 6 + - reg: Must contain an (offset, length) pair of the register set for each 7 + entry in reg-names. 8 + - reg-names: Must include the following entries: 9 + - "pmc" 10 + - "wake" 11 + - "aotag" 12 + - "scratch" 13 + 14 + Optional properties: 15 + - nvidia,invert-interrupt: If present, inverts the PMU interrupt signal. 16 + 17 + Example: 18 + 19 + SoC DTSI: 20 + 21 + pmc@c3600000 { 22 + compatible = "nvidia,tegra186-pmc"; 23 + reg = <0 0x0c360000 0 0x10000>, 24 + <0 0x0c370000 0 0x10000>, 25 + <0 0x0c380000 0 0x10000>, 26 + <0 0x0c390000 0 0x10000>; 27 + reg-names = "pmc", "wake", "aotag", "scratch"; 28 + }; 29 + 30 + Board DTS: 31 + 32 + pmc@c360000 { 33 + nvidia,invert-interrupt; 34 + };
+57 -28
Documentation/devicetree/bindings/power/fsl,imx-gpc.txt
··· 1 1 Freescale i.MX General Power Controller 2 2 ======================================= 3 3 4 - The i.MX6Q General Power Control (GPC) block contains DVFS load tracking 5 - counters and Power Gating Control (PGC) for the CPU and PU (GPU/VPU) power 6 - domains. 4 + The i.MX6 General Power Control (GPC) block contains DVFS load tracking 5 + counters and Power Gating Control (PGC). 7 6 8 7 Required properties: 9 - - compatible: Should be "fsl,imx6q-gpc" or "fsl,imx6sl-gpc" 8 + - compatible: Should be one of the following: 9 + - fsl,imx6q-gpc 10 + - fsl,imx6qp-gpc 11 + - fsl,imx6sl-gpc 10 12 - reg: should be register base and length as documented in the 11 13 datasheet 12 - - interrupts: Should contain GPC interrupt request 1 13 - - pu-supply: Link to the LDO regulator powering the PU power domain 14 - - clocks: Clock phandles to devices in the PU power domain that need 15 - to be enabled during domain power-up for reset propagation. 16 - - #power-domain-cells: Should be 1, see below: 14 + - interrupts: Should contain one interrupt specifier for the GPC interrupt 15 + - clocks: Must contain an entry for each entry in clock-names. 16 + See Documentation/devicetree/bindings/clocks/clock-bindings.txt for details. 17 + - clock-names: Must include the following entries: 18 + - ipg 17 19 18 - The gpc node is a power-controller as documented by the generic power domain 19 - bindings in Documentation/devicetree/bindings/power/power_domain.txt. 20 + The power domains are generic power domain providers as documented in 21 + Documentation/devicetree/bindings/power/power_domain.txt. They are described as 22 + subnodes of the power gating controller 'pgc' node of the GPC and should 23 + contain the following: 24 + 25 + Required properties: 26 + - reg: Must contain the DOMAIN_INDEX of this power domain 27 + The following DOMAIN_INDEX values are valid for i.MX6Q: 28 + ARM_DOMAIN 0 29 + PU_DOMAIN 1 30 + The following additional DOMAIN_INDEX value is valid for i.MX6SL: 31 + DISPLAY_DOMAIN 2 32 + 33 + - #power-domain-cells: Should be 0 34 + 35 + Optional properties: 36 + - clocks: a number of phandles to clocks that need to be enabled during domain 37 + power-up sequencing to ensure reset propagation into devices located inside 38 + this power domain 39 + - power-supply: a phandle to the regulator powering this domain 20 40 21 41 Example: 22 42 ··· 45 25 reg = <0x020dc000 0x4000>; 46 26 interrupts = <0 89 IRQ_TYPE_LEVEL_HIGH>, 47 27 <0 90 IRQ_TYPE_LEVEL_HIGH>; 48 - pu-supply = <&reg_pu>; 49 - clocks = <&clks IMX6QDL_CLK_GPU3D_CORE>, 50 - <&clks IMX6QDL_CLK_GPU3D_SHADER>, 51 - <&clks IMX6QDL_CLK_GPU2D_CORE>, 52 - <&clks IMX6QDL_CLK_GPU2D_AXI>, 53 - <&clks IMX6QDL_CLK_OPENVG_AXI>, 54 - <&clks IMX6QDL_CLK_VPU_AXI>; 55 - #power-domain-cells = <1>; 28 + clocks = <&clks IMX6QDL_CLK_IPG>; 29 + clock-names = "ipg"; 30 + 31 + pgc { 32 + #address-cells = <1>; 33 + #size-cells = <0>; 34 + 35 + power-domain@0 { 36 + reg = <0>; 37 + #power-domain-cells = <0>; 38 + }; 39 + 40 + pd_pu: power-domain@1 { 41 + reg = <1>; 42 + #power-domain-cells = <0>; 43 + power-supply = <&reg_pu>; 44 + clocks = <&clks IMX6QDL_CLK_GPU3D_CORE>, 45 + <&clks IMX6QDL_CLK_GPU3D_SHADER>, 46 + <&clks IMX6QDL_CLK_GPU2D_CORE>, 47 + <&clks IMX6QDL_CLK_GPU2D_AXI>, 48 + <&clks IMX6QDL_CLK_OPENVG_AXI>, 49 + <&clks IMX6QDL_CLK_VPU_AXI>; 50 + }; 51 + }; 56 52 }; 57 53 58 54 ··· 76 40 ====================================== 77 41 78 42 IP cores belonging to a power domain should contain a 'power-domains' property 79 - that is a phandle pointing to the gpc device node and a DOMAIN_INDEX specifying 80 - the power domain the device belongs to. 43 + that is a phandle pointing to the power domain the device belongs to. 81 44 82 45 Example of a device that is part of the PU power domain: 83 46 84 47 vpu: vpu@02040000 { 85 48 reg = <0x02040000 0x3c000>; 86 49 /* ... */ 87 - power-domains = <&gpc 1>; 50 + power-domains = <&pd_pu>; 88 51 /* ... */ 89 52 }; 90 - 91 - The following DOMAIN_INDEX values are valid for i.MX6Q: 92 - ARM_DOMAIN 0 93 - PU_DOMAIN 1 94 - The following additional DOMAIN_INDEX value is valid for i.MX6SL: 95 - DISPLAY_DOMAIN 2
+71
Documentation/devicetree/bindings/power/fsl,imx-gpcv2.txt
··· 1 + Freescale i.MX General Power Controller v2 2 + ========================================== 3 + 4 + The i.MX7S/D General Power Control (GPC) block contains Power Gating 5 + Control (PGC) for various power domains. 6 + 7 + Required properties: 8 + 9 + - compatible: Should be "fsl,imx7d-gpc" 10 + 11 + - reg: should be register base and length as documented in the 12 + datasheet 13 + 14 + - interrupts: Should contain GPC interrupt request 1 15 + 16 + Power domains contained within GPC node are generic power domain 17 + providers, documented in 18 + Documentation/devicetree/bindings/power/power_domain.txt, which are 19 + described as subnodes of the power gating controller 'pgc' node, 20 + which, in turn, is expected to contain the following: 21 + 22 + Required properties: 23 + 24 + - reg: Power domain index. Valid values are defined in 25 + include/dt-bindings/power/imx7-power.h 26 + 27 + - #power-domain-cells: Should be 0 28 + 29 + Optional properties: 30 + 31 + - power-supply: Power supply used to power the domain 32 + 33 + Example: 34 + 35 + gpc: gpc@303a0000 { 36 + compatible = "fsl,imx7d-gpc"; 37 + reg = <0x303a0000 0x1000>; 38 + interrupt-controller; 39 + interrupts = <GIC_SPI 87 IRQ_TYPE_LEVEL_HIGH>; 40 + #interrupt-cells = <3>; 41 + interrupt-parent = <&intc>; 42 + 43 + pgc { 44 + #address-cells = <1>; 45 + #size-cells = <0>; 46 + 47 + pgc_pcie_phy: power-domain@3 { 48 + #power-domain-cells = <0>; 49 + 50 + reg = <IMX7_POWER_DOMAIN_PCIE_PHY>; 51 + power-supply = <&reg_1p0d>; 52 + }; 53 + }; 54 + }; 55 + 56 + 57 + Specifying power domain for IP modules 58 + ====================================== 59 + 60 + IP cores belonging to a power domain should contain a 'power-domains' 61 + property that is a phandle for PGC node representing the domain. 62 + 63 + Example of a device that is part of the PCIE_PHY power domain: 64 + 65 + pcie: pcie@33800000 { 66 + reg = <0x33800000 0x4000>, 67 + <0x4ff00000 0x80000>; 68 + /* ... */ 69 + power-domains = <&pgc_pcie_phy>; 70 + /* ... */ 71 + };
+47
Documentation/devicetree/bindings/reset/fsl,imx7-src.txt
··· 1 + Freescale i.MX7 System Reset Controller 2 + ====================================== 3 + 4 + Please also refer to reset.txt in this directory for common reset 5 + controller binding usage. 6 + 7 + Required properties: 8 + - compatible: Should be "fsl,imx7-src", "syscon" 9 + - reg: should be register base and length as documented in the 10 + datasheet 11 + - interrupts: Should contain SRC interrupt 12 + - #reset-cells: 1, see below 13 + 14 + example: 15 + 16 + src: reset-controller@30390000 { 17 + compatible = "fsl,imx7d-src", "syscon"; 18 + reg = <0x30390000 0x2000>; 19 + interrupts = <GIC_SPI 89 IRQ_TYPE_LEVEL_HIGH>; 20 + #reset-cells = <1>; 21 + }; 22 + 23 + 24 + Specifying reset lines connected to IP modules 25 + ============================================== 26 + 27 + The system reset controller can be used to reset various set of 28 + peripherals. Device nodes that need access to reset lines should 29 + specify them as a reset phandle in their corresponding node as 30 + specified in reset.txt. 31 + 32 + Example: 33 + 34 + pcie: pcie@33800000 { 35 + 36 + ... 37 + 38 + resets = <&src IMX7_RESET_PCIEPHY>, 39 + <&src IMX7_RESET_PCIE_CTRL_APPS_EN>; 40 + reset-names = "pciephy", "apps"; 41 + 42 + ... 43 + }; 44 + 45 + 46 + For list of all valid reset indicies see 47 + <dt-bindings/reset/imx7-reset.h>
+57
Documentation/devicetree/bindings/soc/ti/sci-pm-domain.txt
··· 1 + Texas Instruments TI-SCI Generic Power Domain 2 + --------------------------------------------- 3 + 4 + Some TI SoCs contain a system controller (like the PMMC, etc...) that is 5 + responsible for controlling the state of the IPs that are present. 6 + Communication between the host processor running an OS and the system 7 + controller happens through a protocol known as TI-SCI [1]. 8 + 9 + [1] Documentation/devicetree/bindings/arm/keystone/ti,sci.txt 10 + 11 + PM Domain Node 12 + ============== 13 + The PM domain node represents the global PM domain managed by the PMMC, which 14 + in this case is the implementation as documented by the generic PM domain 15 + bindings in Documentation/devicetree/bindings/power/power_domain.txt. Because 16 + this relies on the TI SCI protocol to communicate with the PMMC it must be a 17 + child of the pmmc node. 18 + 19 + Required Properties: 20 + -------------------- 21 + - compatible: should be "ti,sci-pm-domain" 22 + - #power-domain-cells: Must be 1 so that an id can be provided in each 23 + device node. 24 + 25 + Example (K2G): 26 + ------------- 27 + pmmc: pmmc { 28 + compatible = "ti,k2g-sci"; 29 + ... 30 + 31 + k2g_pds: power-controller { 32 + compatible = "ti,sci-pm-domain"; 33 + #power-domain-cells = <1>; 34 + }; 35 + }; 36 + 37 + PM Domain Consumers 38 + =================== 39 + Hardware blocks belonging to a PM domain should contain a "power-domains" 40 + property that is a phandle pointing to the corresponding PM domain node 41 + along with an index representing the device id to be passed to the PMMC 42 + for device control. 43 + 44 + Required Properties: 45 + -------------------- 46 + - power-domains: phandle pointing to the corresponding PM domain node 47 + and an ID representing the device. 48 + 49 + See dt-bindings/genpd/k2g.h for the list of valid identifiers for k2g. 50 + 51 + Example (K2G): 52 + -------------------- 53 + uart0: serial@02530c00 { 54 + compatible = "ns16550a"; 55 + ... 56 + power-domains = <&k2g_pds K2G_DEV_UART0>; 57 + };
+6
MAINTAINERS
··· 653 653 S: Maintained 654 654 F: drivers/gpio/gpio-altera-a10sr.c 655 655 F: drivers/mfd/altera-a10sr.c 656 + F: drivers/reset/reset-a10sr.c 656 657 F: include/linux/mfd/altera-a10sr.h 658 + F: include/dt-bindings/reset/altr,rst-mgr-a10sr.h 657 659 658 660 ALTERA TRIPLE SPEED ETHERNET DRIVER 659 661 M: Vince Bridgers <vbridger@opensource.altera.com> ··· 1284 1282 F: arch/arm/boot/dts/imx* 1285 1283 F: arch/arm/configs/imx*_defconfig 1286 1284 F: drivers/clk/imx/ 1285 + F: drivers/soc/imx/ 1287 1286 F: include/soc/imx/ 1288 1287 1289 1288 ARM/FREESCALE VYBRID ARM ARCHITECTURE ··· 12607 12604 F: Documentation/devicetree/bindings/arm/keystone/ti,sci.txt 12608 12605 F: drivers/firmware/ti_sci* 12609 12606 F: include/linux/soc/ti/ti_sci_protocol.h 12607 + F: Documentation/devicetree/bindings/soc/ti/sci-pm-domain.txt 12608 + F: include/dt-bindings/genpd/k2g.h 12609 + F: drivers/soc/ti/ti_sci_pm_domains.c 12610 12610 12611 12611 THANKO'S RAREMONO AM/FM/SW RADIO RECEIVER USB DRIVER 12612 12612 M: Hans Verkuil <hverkuil@xs4all.nl>
-3
arch/arm/common/Kconfig
··· 1 - config ICST 2 - bool 3 - 4 1 config SA1111 5 2 bool 6 3 select DMABOUNCE if !ARCH_PXA
-1
arch/arm/common/Makefile
··· 4 4 5 5 obj-y += firmware.o 6 6 7 - obj-$(CONFIG_ICST) += icst.o 8 7 obj-$(CONFIG_SA1111) += sa1111.o 9 8 obj-$(CONFIG_DMABOUNCE) += dmabounce.o 10 9 obj-$(CONFIG_SHARP_LOCOMO) += locomo.o
+1 -1
arch/arm/common/icst.c drivers/clk/versatile/icst.c
··· 17 17 #include <linux/module.h> 18 18 #include <linux/kernel.h> 19 19 #include <asm/div64.h> 20 - #include <asm/hardware/icst.h> 20 + #include "icst.h" 21 21 22 22 /* 23 23 * Divisors for each OD setting.
+2 -4
arch/arm/include/asm/hardware/icst.h drivers/clk/versatile/icst.h
··· 1 1 /* 2 - * arch/arm/include/asm/hardware/icst.h 3 - * 4 2 * Copyright (C) 2003 Deep Blue Solutions, Ltd, All Rights Reserved. 5 3 * 6 4 * This program is free software; you can redistribute it and/or modify ··· 9 11 * clock generators. See http://www.idt.com/ for more information 10 12 * on these devices. 11 13 */ 12 - #ifndef ASMARM_HARDWARE_ICST_H 13 - #define ASMARM_HARDWARE_ICST_H 14 + #ifndef ICST_H 15 + #define ICST_H 14 16 15 17 struct icst_params { 16 18 unsigned long ref;
-217
arch/arm/mach-imx/gpc.c
··· 10 10 * http://www.gnu.org/copyleft/gpl.html 11 11 */ 12 12 13 - #include <linux/clk.h> 14 - #include <linux/delay.h> 15 13 #include <linux/io.h> 16 14 #include <linux/irq.h> 17 15 #include <linux/irqchip.h> 18 16 #include <linux/of.h> 19 17 #include <linux/of_address.h> 20 18 #include <linux/of_irq.h> 21 - #include <linux/platform_device.h> 22 - #include <linux/pm_domain.h> 23 - #include <linux/regulator/consumer.h> 24 19 #include <linux/irqchip/arm-gic.h> 25 20 #include "common.h" 26 21 #include "hardware.h" 27 22 28 - #define GPC_CNTR 0x000 29 23 #define GPC_IMR1 0x008 30 - #define GPC_PGC_GPU_PDN 0x260 31 - #define GPC_PGC_GPU_PUPSCR 0x264 32 - #define GPC_PGC_GPU_PDNSCR 0x268 33 24 #define GPC_PGC_CPU_PDN 0x2a0 34 25 #define GPC_PGC_CPU_PUPSCR 0x2a4 35 26 #define GPC_PGC_CPU_PDNSCR 0x2a8 ··· 29 38 30 39 #define IMR_NUM 4 31 40 #define GPC_MAX_IRQS (IMR_NUM * 32) 32 - 33 - #define GPU_VPU_PUP_REQ BIT(1) 34 - #define GPU_VPU_PDN_REQ BIT(0) 35 - 36 - #define GPC_CLK_MAX 6 37 - 38 - struct pu_domain { 39 - struct generic_pm_domain base; 40 - struct regulator *reg; 41 - struct clk *clk[GPC_CLK_MAX]; 42 - int num_clks; 43 - }; 44 41 45 42 static void __iomem *gpc_base; 46 43 static u32 gpc_wake_irqs[IMR_NUM]; ··· 275 296 gpc_base = of_iomap(np, 0); 276 297 } 277 298 } 278 - 279 - static void _imx6q_pm_pu_power_off(struct generic_pm_domain *genpd) 280 - { 281 - int iso, iso2sw; 282 - u32 val; 283 - 284 - /* Read ISO and ISO2SW power down delays */ 285 - val = readl_relaxed(gpc_base + GPC_PGC_GPU_PDNSCR); 286 - iso = val & 0x3f; 287 - iso2sw = (val >> 8) & 0x3f; 288 - 289 - /* Gate off PU domain when GPU/VPU when powered down */ 290 - writel_relaxed(0x1, gpc_base + GPC_PGC_GPU_PDN); 291 - 292 - /* Request GPC to power down GPU/VPU */ 293 - val = readl_relaxed(gpc_base + GPC_CNTR); 294 - val |= GPU_VPU_PDN_REQ; 295 - writel_relaxed(val, gpc_base + GPC_CNTR); 296 - 297 - /* Wait ISO + ISO2SW IPG clock cycles */ 298 - ndelay((iso + iso2sw) * 1000 / 66); 299 - } 300 - 301 - static int imx6q_pm_pu_power_off(struct generic_pm_domain *genpd) 302 - { 303 - struct pu_domain *pu = container_of(genpd, struct pu_domain, base); 304 - 305 - _imx6q_pm_pu_power_off(genpd); 306 - 307 - if (pu->reg) 308 - regulator_disable(pu->reg); 309 - 310 - return 0; 311 - } 312 - 313 - static int imx6q_pm_pu_power_on(struct generic_pm_domain *genpd) 314 - { 315 - struct pu_domain *pu = container_of(genpd, struct pu_domain, base); 316 - int i, ret, sw, sw2iso; 317 - u32 val; 318 - 319 - if (pu->reg) 320 - ret = regulator_enable(pu->reg); 321 - if (pu->reg && ret) { 322 - pr_err("%s: failed to enable regulator: %d\n", __func__, ret); 323 - return ret; 324 - } 325 - 326 - /* Enable reset clocks for all devices in the PU domain */ 327 - for (i = 0; i < pu->num_clks; i++) 328 - clk_prepare_enable(pu->clk[i]); 329 - 330 - /* Gate off PU domain when GPU/VPU when powered down */ 331 - writel_relaxed(0x1, gpc_base + GPC_PGC_GPU_PDN); 332 - 333 - /* Read ISO and ISO2SW power down delays */ 334 - val = readl_relaxed(gpc_base + GPC_PGC_GPU_PUPSCR); 335 - sw = val & 0x3f; 336 - sw2iso = (val >> 8) & 0x3f; 337 - 338 - /* Request GPC to power up GPU/VPU */ 339 - val = readl_relaxed(gpc_base + GPC_CNTR); 340 - val |= GPU_VPU_PUP_REQ; 341 - writel_relaxed(val, gpc_base + GPC_CNTR); 342 - 343 - /* Wait ISO + ISO2SW IPG clock cycles */ 344 - ndelay((sw + sw2iso) * 1000 / 66); 345 - 346 - /* Disable reset clocks for all devices in the PU domain */ 347 - for (i = 0; i < pu->num_clks; i++) 348 - clk_disable_unprepare(pu->clk[i]); 349 - 350 - return 0; 351 - } 352 - 353 - static struct generic_pm_domain imx6q_arm_domain = { 354 - .name = "ARM", 355 - }; 356 - 357 - static struct pu_domain imx6q_pu_domain = { 358 - .base = { 359 - .name = "PU", 360 - .power_off = imx6q_pm_pu_power_off, 361 - .power_on = imx6q_pm_pu_power_on, 362 - }, 363 - }; 364 - 365 - static struct generic_pm_domain imx6sl_display_domain = { 366 - .name = "DISPLAY", 367 - }; 368 - 369 - static struct generic_pm_domain *imx_gpc_domains[] = { 370 - &imx6q_arm_domain, 371 - &imx6q_pu_domain.base, 372 - &imx6sl_display_domain, 373 - }; 374 - 375 - static struct genpd_onecell_data imx_gpc_onecell_data = { 376 - .domains = imx_gpc_domains, 377 - .num_domains = ARRAY_SIZE(imx_gpc_domains), 378 - }; 379 - 380 - static int imx_gpc_genpd_init(struct device *dev, struct regulator *pu_reg) 381 - { 382 - struct clk *clk; 383 - int i, ret; 384 - 385 - imx6q_pu_domain.reg = pu_reg; 386 - 387 - for (i = 0; ; i++) { 388 - clk = of_clk_get(dev->of_node, i); 389 - if (IS_ERR(clk)) 390 - break; 391 - if (i >= GPC_CLK_MAX) { 392 - dev_err(dev, "more than %d clocks\n", GPC_CLK_MAX); 393 - goto clk_err; 394 - } 395 - imx6q_pu_domain.clk[i] = clk; 396 - } 397 - imx6q_pu_domain.num_clks = i; 398 - 399 - /* Enable power always in case bootloader disabled it. */ 400 - imx6q_pm_pu_power_on(&imx6q_pu_domain.base); 401 - 402 - if (!IS_ENABLED(CONFIG_PM_GENERIC_DOMAINS)) 403 - return 0; 404 - 405 - imx6q_pu_domain.base.states = devm_kzalloc(dev, 406 - sizeof(*imx6q_pu_domain.base.states), 407 - GFP_KERNEL); 408 - if (!imx6q_pu_domain.base.states) 409 - return -ENOMEM; 410 - 411 - imx6q_pu_domain.base.states[0].power_off_latency_ns = 25000; 412 - imx6q_pu_domain.base.states[0].power_on_latency_ns = 2000000; 413 - imx6q_pu_domain.base.state_count = 1; 414 - 415 - for (i = 0; i < ARRAY_SIZE(imx_gpc_domains); i++) 416 - pm_genpd_init(imx_gpc_domains[i], NULL, false); 417 - 418 - ret = of_genpd_add_provider_onecell(dev->of_node, 419 - &imx_gpc_onecell_data); 420 - if (ret) 421 - goto power_off; 422 - 423 - return 0; 424 - 425 - power_off: 426 - imx6q_pm_pu_power_off(&imx6q_pu_domain.base); 427 - clk_err: 428 - while (i--) 429 - clk_put(imx6q_pu_domain.clk[i]); 430 - imx6q_pu_domain.reg = NULL; 431 - return -EINVAL; 432 - } 433 - 434 - static int imx_gpc_probe(struct platform_device *pdev) 435 - { 436 - struct regulator *pu_reg; 437 - int ret; 438 - 439 - /* bail out if DT too old and doesn't provide the necessary info */ 440 - if (!of_property_read_bool(pdev->dev.of_node, "#power-domain-cells")) 441 - return 0; 442 - 443 - pu_reg = devm_regulator_get_optional(&pdev->dev, "pu"); 444 - if (PTR_ERR(pu_reg) == -ENODEV) 445 - pu_reg = NULL; 446 - if (IS_ERR(pu_reg)) { 447 - ret = PTR_ERR(pu_reg); 448 - dev_err(&pdev->dev, "failed to get pu regulator: %d\n", ret); 449 - return ret; 450 - } 451 - 452 - return imx_gpc_genpd_init(&pdev->dev, pu_reg); 453 - } 454 - 455 - static const struct of_device_id imx_gpc_dt_ids[] = { 456 - { .compatible = "fsl,imx6q-gpc" }, 457 - { .compatible = "fsl,imx6sl-gpc" }, 458 - { } 459 - }; 460 - 461 - static struct platform_driver imx_gpc_driver = { 462 - .driver = { 463 - .name = "imx-gpc", 464 - .of_match_table = imx_gpc_dt_ids, 465 - }, 466 - .probe = imx_gpc_probe, 467 - }; 468 - 469 - static int __init imx_pgc_init(void) 470 - { 471 - return platform_driver_register(&imx_gpc_driver); 472 - } 473 - subsys_initcall(imx_pgc_init);
+1
arch/arm/mach-keystone/Kconfig
··· 10 10 select ARCH_SUPPORTS_BIG_ENDIAN 11 11 select ZONE_DMA if ARM_LPAE 12 12 select PINCTRL 13 + select PM_GENERIC_DOMAINS if PM 13 14 help 14 15 Support for boards based on the Texas Instruments Keystone family of 15 16 SoCs.
+3 -1
arch/arm/mach-keystone/pm_domain.c
··· 32 32 }; 33 33 34 34 static const struct of_device_id of_keystone_table[] = { 35 - {.compatible = "ti,keystone"}, 35 + {.compatible = "ti,k2hk"}, 36 + {.compatible = "ti,k2e"}, 37 + {.compatible = "ti,k2l"}, 36 38 { /* end of list */ }, 37 39 }; 38 40
-1
arch/arm/mach-tegra/Makefile
··· 2 2 3 3 obj-y += io.o 4 4 obj-y += irq.o 5 - obj-y += flowctrl.o 6 5 obj-y += pm.o 7 6 obj-y += reset.o 8 7 obj-y += reset-handler.o
+2 -1
arch/arm/mach-tegra/cpuidle-tegra20.c
··· 26 26 #include <linux/kernel.h> 27 27 #include <linux/module.h> 28 28 29 + #include <soc/tegra/flowctrl.h> 30 + 29 31 #include <asm/cpuidle.h> 30 32 #include <asm/smp_plat.h> 31 33 #include <asm/suspend.h> 32 34 33 35 #include "cpuidle.h" 34 - #include "flowctrl.h" 35 36 #include "iomap.h" 36 37 #include "irq.h" 37 38 #include "pm.h"
+70 -17
arch/arm/mach-tegra/flowctrl.c drivers/soc/tegra/flowctrl.c
··· 1 1 /* 2 - * arch/arm/mach-tegra/flowctrl.c 2 + * drivers/soc/tegra/flowctrl.c 3 3 * 4 - * functions and macros to control the flowcontroller 4 + * Functions and macros to control the flowcontroller 5 5 * 6 6 * Copyright (c) 2010-2012, NVIDIA Corporation. All rights reserved. 7 7 * ··· 24 24 #include <linux/kernel.h> 25 25 #include <linux/of.h> 26 26 #include <linux/of_address.h> 27 + #include <linux/platform_device.h> 27 28 29 + #include <soc/tegra/common.h> 30 + #include <soc/tegra/flowctrl.h> 28 31 #include <soc/tegra/fuse.h> 29 - 30 - #include "flowctrl.h" 31 32 32 33 static u8 flowctrl_offset_halt_cpu[] = { 33 34 FLOW_CTRL_HALT_CPU0_EVENTS, ··· 48 47 49 48 static void flowctrl_update(u8 offset, u32 value) 50 49 { 50 + if (WARN_ONCE(IS_ERR_OR_NULL(tegra_flowctrl_base), 51 + "Tegra flowctrl not initialised!\n")) 52 + return; 53 + 51 54 writel(value, tegra_flowctrl_base + offset); 52 55 53 56 /* ensure the update has reached the flow controller */ ··· 62 57 u32 flowctrl_read_cpu_csr(unsigned int cpuid) 63 58 { 64 59 u8 offset = flowctrl_offset_cpu_csr[cpuid]; 60 + 61 + if (WARN_ONCE(IS_ERR_OR_NULL(tegra_flowctrl_base), 62 + "Tegra flowctrl not initialised!\n")) 63 + return 0; 65 64 66 65 return readl(tegra_flowctrl_base + offset); 67 66 } ··· 149 140 flowctrl_write_cpu_csr(cpuid, reg); 150 141 } 151 142 152 - static const struct of_device_id matches[] __initconst = { 143 + static int tegra_flowctrl_probe(struct platform_device *pdev) 144 + { 145 + void __iomem *base = tegra_flowctrl_base; 146 + struct resource *res; 147 + 148 + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 149 + tegra_flowctrl_base = devm_ioremap_resource(&pdev->dev, res); 150 + if (IS_ERR(tegra_flowctrl_base)) 151 + return PTR_ERR(base); 152 + 153 + iounmap(base); 154 + 155 + return 0; 156 + } 157 + 158 + static const struct of_device_id tegra_flowctrl_match[] = { 159 + { .compatible = "nvidia,tegra210-flowctrl" }, 153 160 { .compatible = "nvidia,tegra124-flowctrl" }, 154 161 { .compatible = "nvidia,tegra114-flowctrl" }, 155 162 { .compatible = "nvidia,tegra30-flowctrl" }, ··· 173 148 { } 174 149 }; 175 150 176 - void __init tegra_flowctrl_init(void) 151 + static struct platform_driver tegra_flowctrl_driver = { 152 + .driver = { 153 + .name = "tegra-flowctrl", 154 + .suppress_bind_attrs = true, 155 + .of_match_table = tegra_flowctrl_match, 156 + }, 157 + .probe = tegra_flowctrl_probe, 158 + }; 159 + builtin_platform_driver(tegra_flowctrl_driver); 160 + 161 + static int __init tegra_flowctrl_init(void) 177 162 { 178 - /* hardcoded fallback if device tree node is missing */ 179 - unsigned long base = 0x60007000; 180 - unsigned long size = SZ_4K; 163 + struct resource res; 181 164 struct device_node *np; 182 165 183 - np = of_find_matching_node(NULL, matches); 166 + if (!soc_is_tegra()) 167 + return 0; 168 + 169 + np = of_find_matching_node(NULL, tegra_flowctrl_match); 184 170 if (np) { 185 - struct resource res; 186 - 187 - if (of_address_to_resource(np, 0, &res) == 0) { 188 - size = resource_size(&res); 189 - base = res.start; 171 + if (of_address_to_resource(np, 0, &res) < 0) { 172 + pr_err("failed to get flowctrl register\n"); 173 + return -ENXIO; 190 174 } 191 - 192 175 of_node_put(np); 176 + } else if (IS_ENABLED(CONFIG_ARM)) { 177 + /* 178 + * Hardcoded fallback for 32-bit Tegra 179 + * devices if device tree node is missing. 180 + */ 181 + res.start = 0x60007000; 182 + res.end = 0x60007fff; 183 + res.flags = IORESOURCE_MEM; 184 + } else { 185 + /* 186 + * At this point we're running on a Tegra, 187 + * that doesn't support the flow controller 188 + * (eg. Tegra186), so just return. 189 + */ 190 + return 0; 193 191 } 194 192 195 - tegra_flowctrl_base = ioremap_nocache(base, size); 193 + tegra_flowctrl_base = ioremap_nocache(res.start, resource_size(&res)); 194 + if (!tegra_flowctrl_base) 195 + return -ENXIO; 196 + 197 + return 0; 196 198 } 199 + early_initcall(tegra_flowctrl_init);
+24 -8
arch/arm/mach-tegra/flowctrl.h include/soc/tegra/flowctrl.h
··· 1 1 /* 2 - * arch/arm/mach-tegra/flowctrl.h 3 - * 4 - * functions and macros to control the flowcontroller 2 + * Functions and macros to control the flowcontroller 5 3 * 6 4 * Copyright (c) 2010-2012, NVIDIA Corporation. All rights reserved. 7 5 * ··· 16 18 * along with this program. If not, see <http://www.gnu.org/licenses/>. 17 19 */ 18 20 19 - #ifndef __MACH_TEGRA_FLOWCTRL_H 20 - #define __MACH_TEGRA_FLOWCTRL_H 21 + #ifndef __SOC_TEGRA_FLOWCTRL_H__ 22 + #define __SOC_TEGRA_FLOWCTRL_H__ 21 23 22 24 #define FLOW_CTRL_HALT_CPU0_EVENTS 0x0 23 25 #define FLOW_CTRL_WAITEVENT (2 << 29) ··· 51 53 #define TEGRA30_FLOW_CTRL_CSR_WFI_BITMAP (0xF << 8) 52 54 53 55 #ifndef __ASSEMBLY__ 56 + #ifdef CONFIG_SOC_TEGRA_FLOWCTRL 54 57 u32 flowctrl_read_cpu_csr(unsigned int cpuid); 55 58 void flowctrl_write_cpu_csr(unsigned int cpuid, u32 value); 56 59 void flowctrl_write_cpu_halt(unsigned int cpuid, u32 value); 57 60 58 61 void flowctrl_cpu_suspend_enter(unsigned int cpuid); 59 62 void flowctrl_cpu_suspend_exit(unsigned int cpuid); 63 + #else 64 + static inline u32 flowctrl_read_cpu_csr(unsigned int cpuid) 65 + { 66 + return 0; 67 + } 60 68 61 - void tegra_flowctrl_init(void); 62 - #endif 69 + static inline void flowctrl_write_cpu_csr(unsigned int cpuid, u32 value) 70 + { 71 + } 63 72 64 - #endif 73 + static inline void flowctrl_write_cpu_halt(unsigned int cpuid, u32 value) {} 74 + 75 + static inline void flowctrl_cpu_suspend_enter(unsigned int cpuid) 76 + { 77 + } 78 + 79 + static inline void flowctrl_cpu_suspend_exit(unsigned int cpuid) 80 + { 81 + } 82 + #endif /* CONFIG_SOC_TEGRA_FLOWCTRL */ 83 + #endif /* __ASSEMBLY */ 84 + #endif /* __SOC_TEGRA_FLOWCTRL_H__ */
+1 -1
arch/arm/mach-tegra/platsmp.c
··· 21 21 #include <linux/jiffies.h> 22 22 #include <linux/smp.h> 23 23 24 + #include <soc/tegra/flowctrl.h> 24 25 #include <soc/tegra/fuse.h> 25 26 #include <soc/tegra/pmc.h> 26 27 ··· 31 30 #include <asm/smp_scu.h> 32 31 33 32 #include "common.h" 34 - #include "flowctrl.h" 35 33 #include "iomap.h" 36 34 #include "reset.h" 37 35
+1 -1
arch/arm/mach-tegra/pm.c
··· 27 27 #include <linux/spinlock.h> 28 28 #include <linux/suspend.h> 29 29 30 + #include <soc/tegra/flowctrl.h> 30 31 #include <soc/tegra/fuse.h> 31 32 #include <soc/tegra/pm.h> 32 33 #include <soc/tegra/pmc.h> ··· 39 38 #include <asm/suspend.h> 40 39 #include <asm/tlbflush.h> 41 40 42 - #include "flowctrl.h" 43 41 #include "iomap.h" 44 42 #include "pm.h" 45 43 #include "reset.h"
+1 -1
arch/arm/mach-tegra/reset-handler.S
··· 17 17 #include <linux/init.h> 18 18 #include <linux/linkage.h> 19 19 20 + #include <soc/tegra/flowctrl.h> 20 21 #include <soc/tegra/fuse.h> 21 22 22 23 #include <asm/asm-offsets.h> 23 24 #include <asm/cache.h> 24 25 25 - #include "flowctrl.h" 26 26 #include "iomap.h" 27 27 #include "reset.h" 28 28 #include "sleep.h"
+2 -1
arch/arm/mach-tegra/sleep-tegra20.S
··· 20 20 21 21 #include <linux/linkage.h> 22 22 23 + #include <soc/tegra/flowctrl.h> 24 + 23 25 #include <asm/assembler.h> 24 26 #include <asm/proc-fns.h> 25 27 #include <asm/cp15.h> ··· 29 27 30 28 #include "irammap.h" 31 29 #include "sleep.h" 32 - #include "flowctrl.h" 33 30 34 31 #define EMC_CFG 0xc 35 32 #define EMC_ADR_CFG 0x10
+1 -1
arch/arm/mach-tegra/sleep-tegra30.S
··· 16 16 17 17 #include <linux/linkage.h> 18 18 19 + #include <soc/tegra/flowctrl.h> 19 20 #include <soc/tegra/fuse.h> 20 21 21 22 #include <asm/asm-offsets.h> 22 23 #include <asm/assembler.h> 23 24 #include <asm/cache.h> 24 25 25 - #include "flowctrl.h" 26 26 #include "irammap.h" 27 27 #include "sleep.h" 28 28
-2
arch/arm/mach-tegra/sleep.S
··· 30 30 #include <asm/hardware/cache-l2x0.h> 31 31 32 32 #include "iomap.h" 33 - 34 - #include "flowctrl.h" 35 33 #include "sleep.h" 36 34 37 35 #define CLK_RESET_CCLK_BURST 0x20
-2
arch/arm/mach-tegra/tegra.c
··· 48 48 #include "board.h" 49 49 #include "common.h" 50 50 #include "cpuidle.h" 51 - #include "flowctrl.h" 52 51 #include "iomap.h" 53 52 #include "irq.h" 54 53 #include "pm.h" ··· 74 75 { 75 76 of_register_trusted_foundations(); 76 77 tegra_cpu_reset_handler_init(); 77 - tegra_flowctrl_init(); 78 78 } 79 79 80 80 static void __init tegra_dt_init_irq(void)
-15
arch/arm/plat-versatile/include/plat/clock.h
··· 1 - #ifndef PLAT_CLOCK_H 2 - #define PLAT_CLOCK_H 3 - 4 - #include <asm/hardware/icst.h> 5 - 6 - struct clk_ops { 7 - long (*round)(struct clk *, unsigned long); 8 - int (*set)(struct clk *, unsigned long); 9 - void (*setvco)(struct clk *, struct icst_vco); 10 - }; 11 - 12 - int icst_clk_set(struct clk *, unsigned long); 13 - long icst_clk_round(struct clk *, unsigned long); 14 - 15 - #endif
+9
drivers/ata/Kconfig
··· 518 518 519 519 If unsure, say N. 520 520 521 + config PATA_BK3710 522 + tristate "Palmchip BK3710 PATA support" 523 + depends on ARCH_DAVINCI 524 + help 525 + This option enables support for the integrated IDE controller on 526 + the TI DaVinci SoC. 527 + 528 + If unsure, say N. 529 + 521 530 config PATA_CMD64X 522 531 tristate "CMD64x PATA support" 523 532 depends on PCI
+1
drivers/ata/Makefile
··· 51 51 obj-$(CONFIG_PATA_ATIIXP) += pata_atiixp.o 52 52 obj-$(CONFIG_PATA_ATP867X) += pata_atp867x.o 53 53 obj-$(CONFIG_PATA_BF54X) += pata_bf54x.o 54 + obj-$(CONFIG_PATA_BK3710) += pata_bk3710.o 54 55 obj-$(CONFIG_PATA_CMD64X) += pata_cmd64x.o 55 56 obj-$(CONFIG_PATA_CS5520) += pata_cs5520.o 56 57 obj-$(CONFIG_PATA_CS5530) += pata_cs5530.o
+382
drivers/ata/pata_bk3710.c
··· 1 + /* 2 + * Palmchip BK3710 PATA controller driver 3 + * 4 + * Copyright (c) 2017 Samsung Electronics Co., Ltd. 5 + * http://www.samsung.com 6 + * 7 + * Based on palm_bk3710.c: 8 + * 9 + * Copyright (C) 2006 Texas Instruments. 10 + * Copyright (C) 2007 MontaVista Software, Inc., <source@mvista.com> 11 + * 12 + * This file is subject to the terms and conditions of the GNU General Public 13 + * License. See the file "COPYING" in the main directory of this archive 14 + * for more details. 15 + */ 16 + 17 + #include <linux/ata.h> 18 + #include <linux/clk.h> 19 + #include <linux/delay.h> 20 + #include <linux/init.h> 21 + #include <linux/ioport.h> 22 + #include <linux/kernel.h> 23 + #include <linux/libata.h> 24 + #include <linux/module.h> 25 + #include <linux/platform_device.h> 26 + #include <linux/types.h> 27 + 28 + #define DRV_NAME "pata_bk3710" 29 + 30 + #define BK3710_TF_OFFSET 0x1F0 31 + #define BK3710_CTL_OFFSET 0x3F6 32 + 33 + #define BK3710_BMISP 0x02 34 + #define BK3710_IDETIMP 0x40 35 + #define BK3710_UDMACTL 0x48 36 + #define BK3710_MISCCTL 0x50 37 + #define BK3710_REGSTB 0x54 38 + #define BK3710_REGRCVR 0x58 39 + #define BK3710_DATSTB 0x5C 40 + #define BK3710_DATRCVR 0x60 41 + #define BK3710_DMASTB 0x64 42 + #define BK3710_DMARCVR 0x68 43 + #define BK3710_UDMASTB 0x6C 44 + #define BK3710_UDMATRP 0x70 45 + #define BK3710_UDMAENV 0x74 46 + #define BK3710_IORDYTMP 0x78 47 + 48 + static struct scsi_host_template pata_bk3710_sht = { 49 + ATA_BMDMA_SHT(DRV_NAME), 50 + }; 51 + 52 + static unsigned int ideclk_period; /* in nanoseconds */ 53 + 54 + struct pata_bk3710_udmatiming { 55 + unsigned int rptime; /* tRP -- Ready to pause time (nsec) */ 56 + unsigned int cycletime; /* tCYCTYP2/2 -- avg Cycle Time (nsec) */ 57 + /* tENV is always a minimum of 20 nsec */ 58 + }; 59 + 60 + static const struct pata_bk3710_udmatiming pata_bk3710_udmatimings[6] = { 61 + { 160, 240 / 2 }, /* UDMA Mode 0 */ 62 + { 125, 160 / 2 }, /* UDMA Mode 1 */ 63 + { 100, 120 / 2 }, /* UDMA Mode 2 */ 64 + { 100, 90 / 2 }, /* UDMA Mode 3 */ 65 + { 100, 60 / 2 }, /* UDMA Mode 4 */ 66 + { 85, 40 / 2 }, /* UDMA Mode 5 */ 67 + }; 68 + 69 + static void pata_bk3710_setudmamode(void __iomem *base, unsigned int dev, 70 + unsigned int mode) 71 + { 72 + u32 val32; 73 + u16 val16; 74 + u8 tenv, trp, t0; 75 + 76 + /* DMA Data Setup */ 77 + t0 = DIV_ROUND_UP(pata_bk3710_udmatimings[mode].cycletime, 78 + ideclk_period) - 1; 79 + tenv = DIV_ROUND_UP(20, ideclk_period) - 1; 80 + trp = DIV_ROUND_UP(pata_bk3710_udmatimings[mode].rptime, 81 + ideclk_period) - 1; 82 + 83 + /* udmastb Ultra DMA Access Strobe Width */ 84 + val32 = ioread32(base + BK3710_UDMASTB) & (0xFF << (dev ? 0 : 8)); 85 + val32 |= t0 << (dev ? 8 : 0); 86 + iowrite32(val32, base + BK3710_UDMASTB); 87 + 88 + /* udmatrp Ultra DMA Ready to Pause Time */ 89 + val32 = ioread32(base + BK3710_UDMATRP) & (0xFF << (dev ? 0 : 8)); 90 + val32 |= trp << (dev ? 8 : 0); 91 + iowrite32(val32, base + BK3710_UDMATRP); 92 + 93 + /* udmaenv Ultra DMA envelop Time */ 94 + val32 = ioread32(base + BK3710_UDMAENV) & (0xFF << (dev ? 0 : 8)); 95 + val32 |= tenv << (dev ? 8 : 0); 96 + iowrite32(val32, base + BK3710_UDMAENV); 97 + 98 + /* Enable UDMA for Device */ 99 + val16 = ioread16(base + BK3710_UDMACTL) | (1 << dev); 100 + iowrite16(val16, base + BK3710_UDMACTL); 101 + } 102 + 103 + static void pata_bk3710_setmwdmamode(void __iomem *base, unsigned int dev, 104 + unsigned short min_cycle, 105 + unsigned int mode) 106 + { 107 + const struct ata_timing *t; 108 + int cycletime; 109 + u32 val32; 110 + u16 val16; 111 + u8 td, tkw, t0; 112 + 113 + t = ata_timing_find_mode(mode); 114 + cycletime = max_t(int, t->cycle, min_cycle); 115 + 116 + /* DMA Data Setup */ 117 + t0 = DIV_ROUND_UP(cycletime, ideclk_period); 118 + td = DIV_ROUND_UP(t->active, ideclk_period); 119 + tkw = t0 - td - 1; 120 + td--; 121 + 122 + val32 = ioread32(base + BK3710_DMASTB) & (0xFF << (dev ? 0 : 8)); 123 + val32 |= td << (dev ? 8 : 0); 124 + iowrite32(val32, base + BK3710_DMASTB); 125 + 126 + val32 = ioread32(base + BK3710_DMARCVR) & (0xFF << (dev ? 0 : 8)); 127 + val32 |= tkw << (dev ? 8 : 0); 128 + iowrite32(val32, base + BK3710_DMARCVR); 129 + 130 + /* Disable UDMA for Device */ 131 + val16 = ioread16(base + BK3710_UDMACTL) & ~(1 << dev); 132 + iowrite16(val16, base + BK3710_UDMACTL); 133 + } 134 + 135 + static void pata_bk3710_set_dmamode(struct ata_port *ap, 136 + struct ata_device *adev) 137 + { 138 + void __iomem *base = (void __iomem *)ap->ioaddr.bmdma_addr; 139 + int is_slave = adev->devno; 140 + const u8 xferspeed = adev->dma_mode; 141 + 142 + if (xferspeed >= XFER_UDMA_0) 143 + pata_bk3710_setudmamode(base, is_slave, 144 + xferspeed - XFER_UDMA_0); 145 + else 146 + pata_bk3710_setmwdmamode(base, is_slave, 147 + adev->id[ATA_ID_EIDE_DMA_MIN], 148 + xferspeed); 149 + } 150 + 151 + static void pata_bk3710_setpiomode(void __iomem *base, struct ata_device *pair, 152 + unsigned int dev, unsigned int cycletime, 153 + unsigned int mode) 154 + { 155 + const struct ata_timing *t; 156 + u32 val32; 157 + u8 t2, t2i, t0; 158 + 159 + t = ata_timing_find_mode(XFER_PIO_0 + mode); 160 + 161 + /* PIO Data Setup */ 162 + t0 = DIV_ROUND_UP(cycletime, ideclk_period); 163 + t2 = DIV_ROUND_UP(t->active, ideclk_period); 164 + 165 + t2i = t0 - t2 - 1; 166 + t2--; 167 + 168 + val32 = ioread32(base + BK3710_DATSTB) & (0xFF << (dev ? 0 : 8)); 169 + val32 |= t2 << (dev ? 8 : 0); 170 + iowrite32(val32, base + BK3710_DATSTB); 171 + 172 + val32 = ioread32(base + BK3710_DATRCVR) & (0xFF << (dev ? 0 : 8)); 173 + val32 |= t2i << (dev ? 8 : 0); 174 + iowrite32(val32, base + BK3710_DATRCVR); 175 + 176 + /* FIXME: this is broken also in the old driver */ 177 + if (pair) { 178 + u8 mode2 = pair->pio_mode - XFER_PIO_0; 179 + 180 + if (mode2 < mode) 181 + mode = mode2; 182 + } 183 + 184 + /* TASKFILE Setup */ 185 + t0 = DIV_ROUND_UP(t->cyc8b, ideclk_period); 186 + t2 = DIV_ROUND_UP(t->act8b, ideclk_period); 187 + 188 + t2i = t0 - t2 - 1; 189 + t2--; 190 + 191 + val32 = ioread32(base + BK3710_REGSTB) & (0xFF << (dev ? 0 : 8)); 192 + val32 |= t2 << (dev ? 8 : 0); 193 + iowrite32(val32, base + BK3710_REGSTB); 194 + 195 + val32 = ioread32(base + BK3710_REGRCVR) & (0xFF << (dev ? 0 : 8)); 196 + val32 |= t2i << (dev ? 8 : 0); 197 + iowrite32(val32, base + BK3710_REGRCVR); 198 + } 199 + 200 + static void pata_bk3710_set_piomode(struct ata_port *ap, 201 + struct ata_device *adev) 202 + { 203 + void __iomem *base = (void __iomem *)ap->ioaddr.bmdma_addr; 204 + struct ata_device *pair = ata_dev_pair(adev); 205 + const struct ata_timing *t = ata_timing_find_mode(adev->pio_mode); 206 + const u16 *id = adev->id; 207 + unsigned int cycle_time = 0; 208 + int is_slave = adev->devno; 209 + const u8 pio = adev->pio_mode - XFER_PIO_0; 210 + 211 + if (id[ATA_ID_FIELD_VALID] & 2) { 212 + if (ata_id_has_iordy(id)) 213 + cycle_time = id[ATA_ID_EIDE_PIO_IORDY]; 214 + else 215 + cycle_time = id[ATA_ID_EIDE_PIO]; 216 + 217 + /* conservative "downgrade" for all pre-ATA2 drives */ 218 + if (pio < 3 && cycle_time < t->cycle) 219 + cycle_time = 0; /* use standard timing */ 220 + } 221 + 222 + if (!cycle_time) 223 + cycle_time = t->cycle; 224 + 225 + pata_bk3710_setpiomode(base, pair, is_slave, cycle_time, pio); 226 + } 227 + 228 + static void pata_bk3710_chipinit(void __iomem *base) 229 + { 230 + /* 231 + * REVISIT: the ATA reset signal needs to be managed through a 232 + * GPIO, which means it should come from platform_data. Until 233 + * we get and use such information, we have to trust that things 234 + * have been reset before we get here. 235 + */ 236 + 237 + /* 238 + * Program the IDETIMP Register Value based on the following assumptions 239 + * 240 + * (ATA_IDETIMP_IDEEN , ENABLE ) | 241 + * (ATA_IDETIMP_PREPOST1 , DISABLE) | 242 + * (ATA_IDETIMP_PREPOST0 , DISABLE) | 243 + * 244 + * DM6446 silicon rev 2.1 and earlier have no observed net benefit 245 + * from enabling prefetch/postwrite. 246 + */ 247 + iowrite16(BIT(15), base + BK3710_IDETIMP); 248 + 249 + /* 250 + * UDMACTL Ultra-ATA DMA Control 251 + * (ATA_UDMACTL_UDMAP1 , 0 ) | 252 + * (ATA_UDMACTL_UDMAP0 , 0 ) 253 + * 254 + */ 255 + iowrite16(0, base + BK3710_UDMACTL); 256 + 257 + /* 258 + * MISCCTL Miscellaneous Conrol Register 259 + * (ATA_MISCCTL_HWNHLD1P , 1 cycle) 260 + * (ATA_MISCCTL_HWNHLD0P , 1 cycle) 261 + * (ATA_MISCCTL_TIMORIDE , 1) 262 + */ 263 + iowrite32(0x001, base + BK3710_MISCCTL); 264 + 265 + /* 266 + * IORDYTMP IORDY Timer for Primary Register 267 + * (ATA_IORDYTMP_IORDYTMP , DISABLE) 268 + */ 269 + iowrite32(0, base + BK3710_IORDYTMP); 270 + 271 + /* 272 + * Configure BMISP Register 273 + * (ATA_BMISP_DMAEN1 , DISABLE ) | 274 + * (ATA_BMISP_DMAEN0 , DISABLE ) | 275 + * (ATA_BMISP_IORDYINT , CLEAR) | 276 + * (ATA_BMISP_INTRSTAT , CLEAR) | 277 + * (ATA_BMISP_DMAERROR , CLEAR) 278 + */ 279 + iowrite16(0xE, base + BK3710_BMISP); 280 + 281 + pata_bk3710_setpiomode(base, NULL, 0, 600, 0); 282 + pata_bk3710_setpiomode(base, NULL, 1, 600, 0); 283 + } 284 + 285 + static struct ata_port_operations pata_bk3710_ports_ops = { 286 + .inherits = &ata_bmdma_port_ops, 287 + .cable_detect = ata_cable_80wire, 288 + 289 + .set_piomode = pata_bk3710_set_piomode, 290 + .set_dmamode = pata_bk3710_set_dmamode, 291 + }; 292 + 293 + static int __init pata_bk3710_probe(struct platform_device *pdev) 294 + { 295 + struct clk *clk; 296 + struct resource *mem; 297 + struct ata_host *host; 298 + struct ata_port *ap; 299 + void __iomem *base; 300 + unsigned long rate; 301 + int irq; 302 + 303 + clk = devm_clk_get(&pdev->dev, NULL); 304 + if (IS_ERR(clk)) 305 + return -ENODEV; 306 + 307 + clk_enable(clk); 308 + rate = clk_get_rate(clk); 309 + if (!rate) 310 + return -EINVAL; 311 + 312 + /* NOTE: round *down* to meet minimum timings; we count in clocks */ 313 + ideclk_period = 1000000000UL / rate; 314 + 315 + mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); 316 + 317 + irq = platform_get_irq(pdev, 0); 318 + if (irq < 0) { 319 + pr_err(DRV_NAME ": failed to get IRQ resource\n"); 320 + return irq; 321 + } 322 + 323 + base = devm_ioremap_resource(&pdev->dev, mem); 324 + if (IS_ERR(base)) 325 + return PTR_ERR(base); 326 + 327 + /* configure the Palmchip controller */ 328 + pata_bk3710_chipinit(base); 329 + 330 + /* allocate host */ 331 + host = ata_host_alloc(&pdev->dev, 1); 332 + if (!host) 333 + return -ENOMEM; 334 + ap = host->ports[0]; 335 + 336 + ap->ops = &pata_bk3710_ports_ops; 337 + ap->pio_mask = ATA_PIO4; 338 + ap->mwdma_mask = ATA_MWDMA2; 339 + ap->udma_mask = rate < 100000000 ? ATA_UDMA4 : ATA_UDMA5; 340 + ap->flags |= ATA_FLAG_SLAVE_POSS; 341 + 342 + ap->ioaddr.data_addr = base + BK3710_TF_OFFSET; 343 + ap->ioaddr.error_addr = base + BK3710_TF_OFFSET + 1; 344 + ap->ioaddr.feature_addr = base + BK3710_TF_OFFSET + 1; 345 + ap->ioaddr.nsect_addr = base + BK3710_TF_OFFSET + 2; 346 + ap->ioaddr.lbal_addr = base + BK3710_TF_OFFSET + 3; 347 + ap->ioaddr.lbam_addr = base + BK3710_TF_OFFSET + 4; 348 + ap->ioaddr.lbah_addr = base + BK3710_TF_OFFSET + 5; 349 + ap->ioaddr.device_addr = base + BK3710_TF_OFFSET + 6; 350 + ap->ioaddr.status_addr = base + BK3710_TF_OFFSET + 7; 351 + ap->ioaddr.command_addr = base + BK3710_TF_OFFSET + 7; 352 + 353 + ap->ioaddr.altstatus_addr = base + BK3710_CTL_OFFSET; 354 + ap->ioaddr.ctl_addr = base + BK3710_CTL_OFFSET; 355 + 356 + ap->ioaddr.bmdma_addr = base; 357 + 358 + ata_port_desc(ap, "cmd 0x%lx ctl 0x%lx", 359 + (unsigned long)base + BK3710_TF_OFFSET, 360 + (unsigned long)base + BK3710_CTL_OFFSET); 361 + 362 + /* activate */ 363 + return ata_host_activate(host, irq, ata_sff_interrupt, 0, 364 + &pata_bk3710_sht); 365 + } 366 + 367 + /* work with hotplug and coldplug */ 368 + MODULE_ALIAS("platform:palm_bk3710"); 369 + 370 + static struct platform_driver pata_bk3710_driver = { 371 + .driver = { 372 + .name = "palm_bk3710", 373 + }, 374 + }; 375 + 376 + static int __init pata_bk3710_init(void) 377 + { 378 + return platform_driver_probe(&pata_bk3710_driver, pata_bk3710_probe); 379 + } 380 + 381 + module_init(pata_bk3710_init); 382 + MODULE_LICENSE("GPL");
-2
drivers/base/power/domain.c
··· 1636 1636 struct of_phandle_args *genpdspec, 1637 1637 void *data) 1638 1638 { 1639 - if (genpdspec->args_count != 0) 1640 - return ERR_PTR(-EINVAL); 1641 1639 return data; 1642 1640 } 1643 1641
+44 -28
drivers/base/soc.c
··· 109 109 kfree(soc_dev); 110 110 } 111 111 112 + static struct soc_device_attribute *early_soc_dev_attr; 113 + 112 114 struct soc_device *soc_device_register(struct soc_device_attribute *soc_dev_attr) 113 115 { 114 116 struct soc_device *soc_dev; 115 117 int ret; 116 118 117 119 if (!soc_bus_type.p) { 118 - ret = bus_register(&soc_bus_type); 119 - if (ret) 120 - goto out1; 120 + if (early_soc_dev_attr) 121 + return ERR_PTR(-EBUSY); 122 + early_soc_dev_attr = soc_dev_attr; 123 + return NULL; 121 124 } 122 125 123 126 soc_dev = kzalloc(sizeof(*soc_dev), GFP_KERNEL); ··· 162 159 ida_simple_remove(&soc_ida, soc_dev->soc_dev_num); 163 160 164 161 device_unregister(&soc_dev->dev); 162 + early_soc_dev_attr = NULL; 165 163 } 166 164 167 165 static int __init soc_bus_register(void) 168 166 { 169 - if (soc_bus_type.p) 170 - return 0; 167 + int ret; 171 168 172 - return bus_register(&soc_bus_type); 169 + ret = bus_register(&soc_bus_type); 170 + if (ret) 171 + return ret; 172 + 173 + if (early_soc_dev_attr) 174 + return PTR_ERR(soc_device_register(early_soc_dev_attr)); 175 + 176 + return 0; 173 177 } 174 178 core_initcall(soc_bus_register); 179 + 180 + static int soc_device_match_attr(const struct soc_device_attribute *attr, 181 + const struct soc_device_attribute *match) 182 + { 183 + if (match->machine && 184 + (!attr->machine || !glob_match(match->machine, attr->machine))) 185 + return 0; 186 + 187 + if (match->family && 188 + (!attr->family || !glob_match(match->family, attr->family))) 189 + return 0; 190 + 191 + if (match->revision && 192 + (!attr->revision || !glob_match(match->revision, attr->revision))) 193 + return 0; 194 + 195 + if (match->soc_id && 196 + (!attr->soc_id || !glob_match(match->soc_id, attr->soc_id))) 197 + return 0; 198 + 199 + return 1; 200 + } 175 201 176 202 static int soc_device_match_one(struct device *dev, void *arg) 177 203 { 178 204 struct soc_device *soc_dev = container_of(dev, struct soc_device, dev); 179 - const struct soc_device_attribute *match = arg; 180 205 181 - if (match->machine && 182 - (!soc_dev->attr->machine || 183 - !glob_match(match->machine, soc_dev->attr->machine))) 184 - return 0; 185 - 186 - if (match->family && 187 - (!soc_dev->attr->family || 188 - !glob_match(match->family, soc_dev->attr->family))) 189 - return 0; 190 - 191 - if (match->revision && 192 - (!soc_dev->attr->revision || 193 - !glob_match(match->revision, soc_dev->attr->revision))) 194 - return 0; 195 - 196 - if (match->soc_id && 197 - (!soc_dev->attr->soc_id || 198 - !glob_match(match->soc_id, soc_dev->attr->soc_id))) 199 - return 0; 200 - 201 - return 1; 206 + return soc_device_match_attr(soc_dev->attr, arg); 202 207 } 203 208 204 209 /* ··· 241 230 break; 242 231 ret = bus_for_each_dev(&soc_bus_type, NULL, (void *)matches, 243 232 soc_device_match_one); 233 + if (ret < 0 && early_soc_dev_attr) 234 + ret = soc_device_match_attr(early_soc_dev_attr, 235 + matches); 236 + if (ret < 0) 237 + return NULL; 244 238 if (!ret) 245 239 matches++; 246 240 else
+3
drivers/clk/versatile/Kconfig
··· 1 + config ICST 2 + bool 3 + 1 4 config COMMON_CLK_VERSATILE 2 5 bool "Clock driver for ARM Reference designs" 3 6 depends on ARCH_INTEGRATOR || ARCH_REALVIEW || \
+1 -1
drivers/clk/versatile/Makefile
··· 1 1 # Makefile for Versatile-specific clocks 2 - obj-$(CONFIG_ICST) += clk-icst.o clk-versatile.o 2 + obj-$(CONFIG_ICST) += icst.o clk-icst.o clk-versatile.o 3 3 obj-$(CONFIG_INTEGRATOR_IMPD1) += clk-impd1.o 4 4 obj-$(CONFIG_ARCH_REALVIEW) += clk-realview.o 5 5 obj-$(CONFIG_CLK_SP810) += clk-sp810.o
+1
drivers/clk/versatile/clk-icst.c
··· 22 22 #include <linux/regmap.h> 23 23 #include <linux/mfd/syscon.h> 24 24 25 + #include "icst.h" 25 26 #include "clk-icst.h" 26 27 27 28 /* Magic unlocking token used on all Versatile boards */
-2
drivers/clk/versatile/clk-icst.h
··· 1 - #include <asm/hardware/icst.h> 2 - 3 1 /** 4 2 * struct clk_icst_desc - descriptor for the ICST VCO 5 3 * @params: ICST parameters
+1
drivers/clk/versatile/clk-impd1.c
··· 12 12 #include <linux/io.h> 13 13 #include <linux/platform_data/clk-integrator.h> 14 14 15 + #include "icst.h" 15 16 #include "clk-icst.h" 16 17 17 18 #define IMPD1_OSC1 0x00
+1
drivers/clk/versatile/clk-realview.c
··· 11 11 #include <linux/io.h> 12 12 #include <linux/clk-provider.h> 13 13 14 + #include "icst.h" 14 15 #include "clk-icst.h" 15 16 16 17 #define REALVIEW_SYS_OSC0_OFFSET 0x0C
+1
drivers/clk/versatile/clk-versatile.c
··· 12 12 #include <linux/of.h> 13 13 #include <linux/of_address.h> 14 14 15 + #include "icst.h" 15 16 #include "clk-icst.h" 16 17 17 18 #define INTEGRATOR_HDR_LOCK_OFFSET 0x14
+5 -2
drivers/firmware/arm_scpi.c
··· 538 538 msg->tx_len = tx_len; 539 539 msg->rx_buf = rx_buf; 540 540 msg->rx_len = rx_len; 541 - init_completion(&msg->done); 541 + reinit_completion(&msg->done); 542 542 543 543 ret = mbox_send_message(scpi_chan->chan, msg); 544 544 if (ret < 0 || !rx_buf) ··· 872 872 return -ENOMEM; 873 873 874 874 ch->xfers = xfers; 875 - for (i = 0; i < MAX_SCPI_XFERS; i++, xfers++) 875 + for (i = 0; i < MAX_SCPI_XFERS; i++, xfers++) { 876 + init_completion(&xfers->done); 876 877 list_add_tail(&xfers->node, &ch->xfers_list); 878 + } 879 + 877 880 return 0; 878 881 } 879 882
+16 -4
drivers/firmware/meson/meson_sm.c
··· 127 127 * meson_sm_call_read - retrieve data from secure-monitor 128 128 * 129 129 * @buffer: Buffer to store the retrieved data 130 + * @bsize: Size of the buffer 130 131 * @cmd_index: Index of the SMC32 function ID 131 132 * @arg0: SMC32 Argument 0 132 133 * @arg1: SMC32 Argument 1 ··· 136 135 * @arg4: SMC32 Argument 4 137 136 * 138 137 * Return: size of read data on success, a negative value on error 138 + * When 0 is returned there is no guarantee about the amount of 139 + * data read and bsize bytes are copied in buffer. 139 140 */ 140 - int meson_sm_call_read(void *buffer, unsigned int cmd_index, u32 arg0, 141 - u32 arg1, u32 arg2, u32 arg3, u32 arg4) 141 + int meson_sm_call_read(void *buffer, unsigned int bsize, unsigned int cmd_index, 142 + u32 arg0, u32 arg1, u32 arg2, u32 arg3, u32 arg4) 142 143 { 143 144 u32 size; 145 + int ret; 144 146 145 147 if (!fw.chip) 146 148 return -ENOENT; ··· 151 147 if (!fw.chip->cmd_shmem_out_base) 152 148 return -EINVAL; 153 149 150 + if (bsize > fw.chip->shmem_size) 151 + return -EINVAL; 152 + 154 153 if (meson_sm_call(cmd_index, &size, arg0, arg1, arg2, arg3, arg4) < 0) 155 154 return -EINVAL; 156 155 157 - if (!size || size > fw.chip->shmem_size) 156 + if (size > bsize) 158 157 return -EINVAL; 158 + 159 + ret = size; 160 + 161 + if (!size) 162 + size = bsize; 159 163 160 164 if (buffer) 161 165 memcpy(buffer, fw.sm_shmem_out_base, size); 162 166 163 - return size; 167 + return ret; 164 168 } 165 169 EXPORT_SYMBOL(meson_sm_call_read); 166 170
+18
drivers/firmware/qcom_scm-32.c
··· 578 578 579 579 return ret ? : le32_to_cpu(scm_ret); 580 580 } 581 + 582 + int __qcom_scm_restore_sec_cfg(struct device *dev, u32 device_id, 583 + u32 spare) 584 + { 585 + return -ENODEV; 586 + } 587 + 588 + int __qcom_scm_iommu_secure_ptbl_size(struct device *dev, u32 spare, 589 + size_t *size) 590 + { 591 + return -ENODEV; 592 + } 593 + 594 + int __qcom_scm_iommu_secure_ptbl_init(struct device *dev, u64 addr, u32 size, 595 + u32 spare) 596 + { 597 + return -ENODEV; 598 + }
+58
drivers/firmware/qcom_scm-64.c
··· 381 381 382 382 return ret ? : res.a1; 383 383 } 384 + 385 + int __qcom_scm_restore_sec_cfg(struct device *dev, u32 device_id, u32 spare) 386 + { 387 + struct qcom_scm_desc desc = {0}; 388 + struct arm_smccc_res res; 389 + int ret; 390 + 391 + desc.args[0] = device_id; 392 + desc.args[1] = spare; 393 + desc.arginfo = QCOM_SCM_ARGS(2); 394 + 395 + ret = qcom_scm_call(dev, QCOM_SCM_SVC_MP, QCOM_SCM_RESTORE_SEC_CFG, 396 + &desc, &res); 397 + 398 + return ret ? : res.a1; 399 + } 400 + 401 + int __qcom_scm_iommu_secure_ptbl_size(struct device *dev, u32 spare, 402 + size_t *size) 403 + { 404 + struct qcom_scm_desc desc = {0}; 405 + struct arm_smccc_res res; 406 + int ret; 407 + 408 + desc.args[0] = spare; 409 + desc.arginfo = QCOM_SCM_ARGS(1); 410 + 411 + ret = qcom_scm_call(dev, QCOM_SCM_SVC_MP, 412 + QCOM_SCM_IOMMU_SECURE_PTBL_SIZE, &desc, &res); 413 + 414 + if (size) 415 + *size = res.a1; 416 + 417 + return ret ? : res.a2; 418 + } 419 + 420 + int __qcom_scm_iommu_secure_ptbl_init(struct device *dev, u64 addr, u32 size, 421 + u32 spare) 422 + { 423 + struct qcom_scm_desc desc = {0}; 424 + struct arm_smccc_res res; 425 + int ret; 426 + 427 + desc.args[0] = addr; 428 + desc.args[1] = size; 429 + desc.args[2] = spare; 430 + desc.arginfo = QCOM_SCM_ARGS(3, QCOM_SCM_RW, QCOM_SCM_VAL, 431 + QCOM_SCM_VAL); 432 + 433 + ret = qcom_scm_call(dev, QCOM_SCM_SVC_MP, 434 + QCOM_SCM_IOMMU_SECURE_PTBL_INIT, &desc, &res); 435 + 436 + /* the pg table has been initialized already, ignore the error */ 437 + if (ret == -EPERM) 438 + ret = 0; 439 + 440 + return ret; 441 + }
+18
drivers/firmware/qcom_scm.c
··· 315 315 .deassert = qcom_scm_pas_reset_deassert, 316 316 }; 317 317 318 + int qcom_scm_restore_sec_cfg(u32 device_id, u32 spare) 319 + { 320 + return __qcom_scm_restore_sec_cfg(__scm->dev, device_id, spare); 321 + } 322 + EXPORT_SYMBOL(qcom_scm_restore_sec_cfg); 323 + 324 + int qcom_scm_iommu_secure_ptbl_size(u32 spare, size_t *size) 325 + { 326 + return __qcom_scm_iommu_secure_ptbl_size(__scm->dev, spare, size); 327 + } 328 + EXPORT_SYMBOL(qcom_scm_iommu_secure_ptbl_size); 329 + 330 + int qcom_scm_iommu_secure_ptbl_init(u64 addr, u32 size, u32 spare) 331 + { 332 + return __qcom_scm_iommu_secure_ptbl_init(__scm->dev, addr, size, spare); 333 + } 334 + EXPORT_SYMBOL(qcom_scm_iommu_secure_ptbl_init); 335 + 318 336 /** 319 337 * qcom_scm_is_available() - Checks if SCM is available 320 338 */
+11
drivers/firmware/qcom_scm.h
··· 85 85 return -EINVAL; 86 86 } 87 87 88 + #define QCOM_SCM_SVC_MP 0xc 89 + #define QCOM_SCM_RESTORE_SEC_CFG 2 90 + extern int __qcom_scm_restore_sec_cfg(struct device *dev, u32 device_id, 91 + u32 spare); 92 + #define QCOM_SCM_IOMMU_SECURE_PTBL_SIZE 3 93 + #define QCOM_SCM_IOMMU_SECURE_PTBL_INIT 4 94 + extern int __qcom_scm_iommu_secure_ptbl_size(struct device *dev, u32 spare, 95 + size_t *size); 96 + extern int __qcom_scm_iommu_secure_ptbl_init(struct device *dev, u64 addr, 97 + u32 size, u32 spare); 98 + 88 99 #endif
+1 -1
drivers/nvmem/meson-efuse.c
··· 27 27 u8 *buf = val; 28 28 int ret; 29 29 30 - ret = meson_sm_call_read(buf, SM_EFUSE_READ, offset, 30 + ret = meson_sm_call_read(buf, bytes, SM_EFUSE_READ, offset, 31 31 bytes, 0, 0, 0); 32 32 if (ret < 0) 33 33 return ret;
+14
drivers/reset/Kconfig
··· 14 14 15 15 if RESET_CONTROLLER 16 16 17 + config RESET_A10SR 18 + tristate "Altera Arria10 System Resource Reset" 19 + depends on MFD_ALTERA_A10SR 20 + help 21 + This option enables support for the external reset functions for 22 + peripheral PHYs on the Altera Arria10 System Resource Chip. 23 + 17 24 config RESET_ATH79 18 25 bool "AR71xx Reset Driver" if COMPILE_TEST 19 26 default ATH79 ··· 33 26 default ARCH_BERLIN 34 27 help 35 28 This enables the reset controller driver for Marvell Berlin SoCs. 29 + 30 + config RESET_IMX7 31 + bool "i.MX7 Reset Driver" if COMPILE_TEST 32 + default SOC_IMX7D 33 + select MFD_SYSCON 34 + help 35 + This enables the reset controller driver for i.MX7 SoCs. 36 36 37 37 config RESET_LPC18XX 38 38 bool "LPC18xx/43xx Reset Driver" if COMPILE_TEST
+3
drivers/reset/Makefile
··· 2 2 obj-y += hisilicon/ 3 3 obj-$(CONFIG_ARCH_STI) += sti/ 4 4 obj-$(CONFIG_ARCH_TEGRA) += tegra/ 5 + obj-$(CONFIG_RESET_A10SR) += reset-a10sr.o 5 6 obj-$(CONFIG_RESET_ATH79) += reset-ath79.o 6 7 obj-$(CONFIG_RESET_BERLIN) += reset-berlin.o 8 + obj-$(CONFIG_RESET_IMX7) += reset-imx7.o 7 9 obj-$(CONFIG_RESET_LPC18XX) += reset-lpc18xx.o 8 10 obj-$(CONFIG_RESET_MESON) += reset-meson.o 9 11 obj-$(CONFIG_RESET_OXNAS) += reset-oxnas.o ··· 17 15 obj-$(CONFIG_RESET_UNIPHIER) += reset-uniphier.o 18 16 obj-$(CONFIG_RESET_ZX2967) += reset-zx2967.o 19 17 obj-$(CONFIG_RESET_ZYNQ) += reset-zynq.o 18 +
+138
drivers/reset/reset-a10sr.c
··· 1 + /* 2 + * Copyright Intel Corporation (C) 2017. All Rights Reserved 3 + * 4 + * This program is free software; you can redistribute it and/or modify it 5 + * under the terms and conditions of the GNU General Public License, 6 + * version 2, as published by the Free Software Foundation. 7 + * 8 + * This program is distributed in the hope it will be useful, but WITHOUT 9 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 10 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 11 + * more details. 12 + * 13 + * You should have received a copy of the GNU General Public License along with 14 + * this program. If not, see <http://www.gnu.org/licenses/>. 15 + * 16 + * Reset driver for Altera Arria10 MAX5 System Resource Chip 17 + * 18 + * Adapted from reset-socfpga.c 19 + */ 20 + 21 + #include <linux/err.h> 22 + #include <linux/mfd/altera-a10sr.h> 23 + #include <linux/module.h> 24 + #include <linux/of.h> 25 + #include <linux/platform_device.h> 26 + #include <linux/reset-controller.h> 27 + 28 + #include <dt-bindings/reset/altr,rst-mgr-a10sr.h> 29 + 30 + struct a10sr_reset { 31 + struct reset_controller_dev rcdev; 32 + struct regmap *regmap; 33 + }; 34 + 35 + static inline struct a10sr_reset *to_a10sr_rst(struct reset_controller_dev *rc) 36 + { 37 + return container_of(rc, struct a10sr_reset, rcdev); 38 + } 39 + 40 + static inline int a10sr_reset_shift(unsigned long id) 41 + { 42 + switch (id) { 43 + case A10SR_RESET_ENET_HPS: 44 + return 1; 45 + case A10SR_RESET_PCIE: 46 + case A10SR_RESET_FILE: 47 + case A10SR_RESET_BQSPI: 48 + case A10SR_RESET_USB: 49 + return id + 11; 50 + default: 51 + return -EINVAL; 52 + } 53 + } 54 + 55 + static int a10sr_reset_update(struct reset_controller_dev *rcdev, 56 + unsigned long id, bool assert) 57 + { 58 + struct a10sr_reset *a10r = to_a10sr_rst(rcdev); 59 + int offset = a10sr_reset_shift(id); 60 + u8 mask = ALTR_A10SR_REG_BIT_MASK(offset); 61 + int index = ALTR_A10SR_HPS_RST_REG + ALTR_A10SR_REG_OFFSET(offset); 62 + 63 + return regmap_update_bits(a10r->regmap, index, mask, assert ? 0 : mask); 64 + } 65 + 66 + static int a10sr_reset_assert(struct reset_controller_dev *rcdev, 67 + unsigned long id) 68 + { 69 + return a10sr_reset_update(rcdev, id, true); 70 + } 71 + 72 + static int a10sr_reset_deassert(struct reset_controller_dev *rcdev, 73 + unsigned long id) 74 + { 75 + return a10sr_reset_update(rcdev, id, false); 76 + } 77 + 78 + static int a10sr_reset_status(struct reset_controller_dev *rcdev, 79 + unsigned long id) 80 + { 81 + int ret; 82 + struct a10sr_reset *a10r = to_a10sr_rst(rcdev); 83 + int offset = a10sr_reset_shift(id); 84 + u8 mask = ALTR_A10SR_REG_BIT_MASK(offset); 85 + int index = ALTR_A10SR_HPS_RST_REG + ALTR_A10SR_REG_OFFSET(offset); 86 + unsigned int value; 87 + 88 + ret = regmap_read(a10r->regmap, index, &value); 89 + if (ret < 0) 90 + return ret; 91 + 92 + return !!(value & mask); 93 + } 94 + 95 + static const struct reset_control_ops a10sr_reset_ops = { 96 + .assert = a10sr_reset_assert, 97 + .deassert = a10sr_reset_deassert, 98 + .status = a10sr_reset_status, 99 + }; 100 + 101 + static int a10sr_reset_probe(struct platform_device *pdev) 102 + { 103 + struct altr_a10sr *a10sr = dev_get_drvdata(pdev->dev.parent); 104 + struct a10sr_reset *a10r; 105 + 106 + a10r = devm_kzalloc(&pdev->dev, sizeof(struct a10sr_reset), 107 + GFP_KERNEL); 108 + if (!a10r) 109 + return -ENOMEM; 110 + 111 + a10r->rcdev.owner = THIS_MODULE; 112 + a10r->rcdev.nr_resets = A10SR_RESET_NUM; 113 + a10r->rcdev.ops = &a10sr_reset_ops; 114 + a10r->rcdev.of_node = pdev->dev.of_node; 115 + a10r->regmap = a10sr->regmap; 116 + 117 + platform_set_drvdata(pdev, a10r); 118 + 119 + return devm_reset_controller_register(&pdev->dev, &a10r->rcdev); 120 + } 121 + 122 + static const struct of_device_id a10sr_reset_of_match[] = { 123 + { .compatible = "altr,a10sr-reset" }, 124 + { }, 125 + }; 126 + MODULE_DEVICE_TABLE(of, a10sr_reset_of_match); 127 + 128 + static struct platform_driver a10sr_reset_driver = { 129 + .probe = a10sr_reset_probe, 130 + .driver = { 131 + .name = "altr_a10sr_reset", 132 + }, 133 + }; 134 + module_platform_driver(a10sr_reset_driver); 135 + 136 + MODULE_AUTHOR("Thor Thayer <thor.thayer@linux.intel.com>"); 137 + MODULE_DESCRIPTION("Altera Arria10 System Resource Reset Controller Driver"); 138 + MODULE_LICENSE("GPL v2");
+8 -19
drivers/reset/reset-ath79.c
··· 1 1 /* 2 + * AR71xx Reset Controller Driver 3 + * Author: Alban Bedel 4 + * 2 5 * Copyright (C) 2015 Alban Bedel <albeu@free.fr> 3 6 * 4 7 * This program is free software; you can redistribute it and/or modify ··· 16 13 */ 17 14 18 15 #include <linux/io.h> 19 - #include <linux/module.h> 16 + #include <linux/init.h> 20 17 #include <linux/platform_device.h> 21 18 #include <linux/reset-controller.h> 22 19 #include <linux/reboot.h> ··· 130 127 return 0; 131 128 } 132 129 133 - static int ath79_reset_remove(struct platform_device *pdev) 134 - { 135 - struct ath79_reset *ath79_reset = platform_get_drvdata(pdev); 136 - 137 - unregister_restart_handler(&ath79_reset->restart_nb); 138 - 139 - return 0; 140 - } 141 - 142 130 static const struct of_device_id ath79_reset_dt_ids[] = { 143 131 { .compatible = "qca,ar7100-reset", }, 144 132 { }, 145 133 }; 146 - MODULE_DEVICE_TABLE(of, ath79_reset_dt_ids); 147 134 148 135 static struct platform_driver ath79_reset_driver = { 149 136 .probe = ath79_reset_probe, 150 - .remove = ath79_reset_remove, 151 137 .driver = { 152 - .name = "ath79-reset", 153 - .of_match_table = ath79_reset_dt_ids, 138 + .name = "ath79-reset", 139 + .of_match_table = ath79_reset_dt_ids, 140 + .suppress_bind_attrs = true, 154 141 }, 155 142 }; 156 - module_platform_driver(ath79_reset_driver); 157 - 158 - MODULE_AUTHOR("Alban Bedel <albeu@free.fr>"); 159 - MODULE_DESCRIPTION("AR71xx Reset Controller Driver"); 160 - MODULE_LICENSE("GPL"); 143 + builtin_platform_driver(ath79_reset_driver);
+158
drivers/reset/reset-imx7.c
··· 1 + /* 2 + * Copyright (c) 2017, Impinj, Inc. 3 + * 4 + * i.MX7 System Reset Controller (SRC) driver 5 + * 6 + * Author: Andrey Smirnov <andrew.smirnov@gmail.com> 7 + * 8 + * This program is free software; you can redistribute it and/or modify 9 + * it under the terms of the GNU General Public License as published by 10 + * the Free Software Foundation; version 2 of the License. 11 + * 12 + * This program is distributed in the hope that it will be useful, 13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 + * GNU General Public License for more details. 16 + */ 17 + 18 + #include <linux/mfd/syscon.h> 19 + #include <linux/platform_device.h> 20 + #include <linux/reset-controller.h> 21 + #include <linux/regmap.h> 22 + #include <dt-bindings/reset/imx7-reset.h> 23 + 24 + struct imx7_src { 25 + struct reset_controller_dev rcdev; 26 + struct regmap *regmap; 27 + }; 28 + 29 + enum imx7_src_registers { 30 + SRC_A7RCR0 = 0x0004, 31 + SRC_M4RCR = 0x000c, 32 + SRC_ERCR = 0x0014, 33 + SRC_HSICPHY_RCR = 0x001c, 34 + SRC_USBOPHY1_RCR = 0x0020, 35 + SRC_USBOPHY2_RCR = 0x0024, 36 + SRC_MIPIPHY_RCR = 0x0028, 37 + SRC_PCIEPHY_RCR = 0x002c, 38 + SRC_DDRC_RCR = 0x1000, 39 + }; 40 + 41 + struct imx7_src_signal { 42 + unsigned int offset, bit; 43 + }; 44 + 45 + static const struct imx7_src_signal imx7_src_signals[IMX7_RESET_NUM] = { 46 + [IMX7_RESET_A7_CORE_POR_RESET0] = { SRC_A7RCR0, BIT(0) }, 47 + [IMX7_RESET_A7_CORE_POR_RESET1] = { SRC_A7RCR0, BIT(1) }, 48 + [IMX7_RESET_A7_CORE_RESET0] = { SRC_A7RCR0, BIT(4) }, 49 + [IMX7_RESET_A7_CORE_RESET1] = { SRC_A7RCR0, BIT(5) }, 50 + [IMX7_RESET_A7_DBG_RESET0] = { SRC_A7RCR0, BIT(8) }, 51 + [IMX7_RESET_A7_DBG_RESET1] = { SRC_A7RCR0, BIT(9) }, 52 + [IMX7_RESET_A7_ETM_RESET0] = { SRC_A7RCR0, BIT(12) }, 53 + [IMX7_RESET_A7_ETM_RESET1] = { SRC_A7RCR0, BIT(13) }, 54 + [IMX7_RESET_A7_SOC_DBG_RESET] = { SRC_A7RCR0, BIT(20) }, 55 + [IMX7_RESET_A7_L2RESET] = { SRC_A7RCR0, BIT(21) }, 56 + [IMX7_RESET_SW_M4C_RST] = { SRC_M4RCR, BIT(1) }, 57 + [IMX7_RESET_SW_M4P_RST] = { SRC_M4RCR, BIT(2) }, 58 + [IMX7_RESET_EIM_RST] = { SRC_ERCR, BIT(0) }, 59 + [IMX7_RESET_HSICPHY_PORT_RST] = { SRC_HSICPHY_RCR, BIT(1) }, 60 + [IMX7_RESET_USBPHY1_POR] = { SRC_USBOPHY1_RCR, BIT(0) }, 61 + [IMX7_RESET_USBPHY1_PORT_RST] = { SRC_USBOPHY1_RCR, BIT(1) }, 62 + [IMX7_RESET_USBPHY2_POR] = { SRC_USBOPHY2_RCR, BIT(0) }, 63 + [IMX7_RESET_USBPHY2_PORT_RST] = { SRC_USBOPHY2_RCR, BIT(1) }, 64 + [IMX7_RESET_MIPI_PHY_MRST] = { SRC_MIPIPHY_RCR, BIT(1) }, 65 + [IMX7_RESET_MIPI_PHY_SRST] = { SRC_MIPIPHY_RCR, BIT(2) }, 66 + [IMX7_RESET_PCIEPHY] = { SRC_PCIEPHY_RCR, BIT(2) | BIT(1) }, 67 + [IMX7_RESET_PCIEPHY_PERST] = { SRC_PCIEPHY_RCR, BIT(3) }, 68 + [IMX7_RESET_PCIE_CTRL_APPS_EN] = { SRC_PCIEPHY_RCR, BIT(6) }, 69 + [IMX7_RESET_DDRC_PRST] = { SRC_DDRC_RCR, BIT(0) }, 70 + [IMX7_RESET_DDRC_CORE_RST] = { SRC_DDRC_RCR, BIT(1) }, 71 + }; 72 + 73 + static struct imx7_src *to_imx7_src(struct reset_controller_dev *rcdev) 74 + { 75 + return container_of(rcdev, struct imx7_src, rcdev); 76 + } 77 + 78 + static int imx7_reset_set(struct reset_controller_dev *rcdev, 79 + unsigned long id, bool assert) 80 + { 81 + struct imx7_src *imx7src = to_imx7_src(rcdev); 82 + const struct imx7_src_signal *signal = &imx7_src_signals[id]; 83 + unsigned int value = 0; 84 + 85 + switch (id) { 86 + case IMX7_RESET_PCIEPHY: 87 + /* 88 + * wait for more than 10us to release phy g_rst and 89 + * btnrst 90 + */ 91 + if (!assert) 92 + udelay(10); 93 + break; 94 + 95 + case IMX7_RESET_PCIE_CTRL_APPS_EN: 96 + value = (assert) ? 0 : signal->bit; 97 + break; 98 + } 99 + 100 + return regmap_update_bits(imx7src->regmap, 101 + signal->offset, signal->bit, value); 102 + } 103 + 104 + static int imx7_reset_assert(struct reset_controller_dev *rcdev, 105 + unsigned long id) 106 + { 107 + return imx7_reset_set(rcdev, id, true); 108 + } 109 + 110 + static int imx7_reset_deassert(struct reset_controller_dev *rcdev, 111 + unsigned long id) 112 + { 113 + return imx7_reset_set(rcdev, id, false); 114 + } 115 + 116 + static const struct reset_control_ops imx7_reset_ops = { 117 + .assert = imx7_reset_assert, 118 + .deassert = imx7_reset_deassert, 119 + }; 120 + 121 + static int imx7_reset_probe(struct platform_device *pdev) 122 + { 123 + struct imx7_src *imx7src; 124 + struct device *dev = &pdev->dev; 125 + struct regmap_config config = { .name = "src" }; 126 + 127 + imx7src = devm_kzalloc(dev, sizeof(*imx7src), GFP_KERNEL); 128 + if (!imx7src) 129 + return -ENOMEM; 130 + 131 + imx7src->regmap = syscon_node_to_regmap(dev->of_node); 132 + if (IS_ERR(imx7src->regmap)) { 133 + dev_err(dev, "Unable to get imx7-src regmap"); 134 + return PTR_ERR(imx7src->regmap); 135 + } 136 + regmap_attach_dev(dev, imx7src->regmap, &config); 137 + 138 + imx7src->rcdev.owner = THIS_MODULE; 139 + imx7src->rcdev.nr_resets = IMX7_RESET_NUM; 140 + imx7src->rcdev.ops = &imx7_reset_ops; 141 + imx7src->rcdev.of_node = dev->of_node; 142 + 143 + return devm_reset_controller_register(dev, &imx7src->rcdev); 144 + } 145 + 146 + static const struct of_device_id imx7_reset_dt_ids[] = { 147 + { .compatible = "fsl,imx7d-src", }, 148 + { /* sentinel */ }, 149 + }; 150 + 151 + static struct platform_driver imx7_reset_driver = { 152 + .probe = imx7_reset_probe, 153 + .driver = { 154 + .name = KBUILD_MODNAME, 155 + .of_match_table = imx7_reset_dt_ids, 156 + }, 157 + }; 158 + builtin_platform_driver(imx7_reset_driver);
+4 -8
drivers/reset/reset-meson.c
··· 1 1 /* 2 + * Amlogic Meson Reset Controller driver 3 + * 2 4 * This file is provided under a dual BSD/GPLv2 license. When using or 3 5 * redistributing this file, you may do so under either license. 4 6 * ··· 55 53 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 56 54 */ 57 55 #include <linux/err.h> 58 - #include <linux/module.h> 56 + #include <linux/init.h> 59 57 #include <linux/io.h> 60 58 #include <linux/of.h> 61 59 #include <linux/platform_device.h> ··· 97 95 { .compatible = "amlogic,meson-gxbb-reset", }, 98 96 { /* sentinel */ }, 99 97 }; 100 - MODULE_DEVICE_TABLE(of, meson_reset_dt_ids); 101 98 102 99 static int meson_reset_probe(struct platform_device *pdev) 103 100 { ··· 129 128 .of_match_table = meson_reset_dt_ids, 130 129 }, 131 130 }; 132 - 133 - module_platform_driver(meson_reset_driver); 134 - 135 - MODULE_AUTHOR("Neil Armstrong <narmstrong@baylibre.com>"); 136 - MODULE_DESCRIPTION("Amlogic Meson Reset Controller driver"); 137 - MODULE_LICENSE("Dual BSD/GPL"); 131 + builtin_platform_driver(meson_reset_driver);
+2 -4
drivers/reset/reset-oxnas.c
··· 18 18 * along with this program. If not, see <http://www.gnu.org/licenses/>. 19 19 */ 20 20 #include <linux/err.h> 21 - #include <linux/module.h> 21 + #include <linux/init.h> 22 22 #include <linux/of.h> 23 23 #include <linux/platform_device.h> 24 24 #include <linux/reset-controller.h> ··· 83 83 { .compatible = "oxsemi,ox820-reset", }, 84 84 { /* sentinel */ }, 85 85 }; 86 - MODULE_DEVICE_TABLE(of, oxnas_reset_dt_ids); 87 86 88 87 static int oxnas_reset_probe(struct platform_device *pdev) 89 88 { ··· 122 123 .of_match_table = oxnas_reset_dt_ids, 123 124 }, 124 125 }; 125 - 126 - module_platform_driver(oxnas_reset_driver); 126 + builtin_platform_driver(oxnas_reset_driver);
+2 -7
drivers/reset/reset-pistachio.c
··· 10 10 * version 2, as published by the Free Software Foundation. 11 11 */ 12 12 13 - #include <linux/module.h> 13 + #include <linux/init.h> 14 14 #include <linux/of.h> 15 15 #include <linux/platform_device.h> 16 16 #include <linux/regmap.h> ··· 128 128 { .compatible = "img,pistachio-reset", }, 129 129 { /* sentinel */ }, 130 130 }; 131 - MODULE_DEVICE_TABLE(of, pistachio_reset_dt_ids); 132 131 133 132 static struct platform_driver pistachio_reset_driver = { 134 133 .probe = pistachio_reset_probe, ··· 136 137 .of_match_table = pistachio_reset_dt_ids, 137 138 }, 138 139 }; 139 - module_platform_driver(pistachio_reset_driver); 140 - 141 - MODULE_AUTHOR("Damien Horsley <Damien.Horsley@imgtec.com>"); 142 - MODULE_DESCRIPTION("Pistacho Reset Controller Driver"); 143 - MODULE_LICENSE("GPL v2"); 140 + builtin_platform_driver(pistachio_reset_driver);
+7 -6
drivers/reset/reset-socfpga.c
··· 25 25 #include <linux/spinlock.h> 26 26 #include <linux/types.h> 27 27 28 - #define NR_BANKS 4 28 + #define BANK_INCREMENT 4 29 + #define NR_BANKS 8 29 30 30 31 struct socfpga_reset_data { 31 32 spinlock_t lock; ··· 47 46 48 47 spin_lock_irqsave(&data->lock, flags); 49 48 50 - reg = readl(data->membase + (bank * NR_BANKS)); 51 - writel(reg | BIT(offset), data->membase + (bank * NR_BANKS)); 49 + reg = readl(data->membase + (bank * BANK_INCREMENT)); 50 + writel(reg | BIT(offset), data->membase + (bank * BANK_INCREMENT)); 52 51 spin_unlock_irqrestore(&data->lock, flags); 53 52 54 53 return 0; ··· 68 67 69 68 spin_lock_irqsave(&data->lock, flags); 70 69 71 - reg = readl(data->membase + (bank * NR_BANKS)); 72 - writel(reg & ~BIT(offset), data->membase + (bank * NR_BANKS)); 70 + reg = readl(data->membase + (bank * BANK_INCREMENT)); 71 + writel(reg & ~BIT(offset), data->membase + (bank * BANK_INCREMENT)); 73 72 74 73 spin_unlock_irqrestore(&data->lock, flags); 75 74 ··· 85 84 int offset = id % BITS_PER_LONG; 86 85 u32 reg; 87 86 88 - reg = readl(data->membase + (bank * NR_BANKS)); 87 + reg = readl(data->membase + (bank * BANK_INCREMENT)); 89 88 90 89 return !(reg & BIT(offset)); 91 90 }
+10 -8
drivers/reset/reset-sunxi.c
··· 34 34 struct sunxi_reset_data *data = container_of(rcdev, 35 35 struct sunxi_reset_data, 36 36 rcdev); 37 - int bank = id / BITS_PER_LONG; 38 - int offset = id % BITS_PER_LONG; 37 + int reg_width = sizeof(u32); 38 + int bank = id / (reg_width * BITS_PER_BYTE); 39 + int offset = id % (reg_width * BITS_PER_BYTE); 39 40 unsigned long flags; 40 41 u32 reg; 41 42 42 43 spin_lock_irqsave(&data->lock, flags); 43 44 44 - reg = readl(data->membase + (bank * 4)); 45 - writel(reg & ~BIT(offset), data->membase + (bank * 4)); 45 + reg = readl(data->membase + (bank * reg_width)); 46 + writel(reg & ~BIT(offset), data->membase + (bank * reg_width)); 46 47 47 48 spin_unlock_irqrestore(&data->lock, flags); 48 49 ··· 56 55 struct sunxi_reset_data *data = container_of(rcdev, 57 56 struct sunxi_reset_data, 58 57 rcdev); 59 - int bank = id / BITS_PER_LONG; 60 - int offset = id % BITS_PER_LONG; 58 + int reg_width = sizeof(u32); 59 + int bank = id / (reg_width * BITS_PER_BYTE); 60 + int offset = id % (reg_width * BITS_PER_BYTE); 61 61 unsigned long flags; 62 62 u32 reg; 63 63 64 64 spin_lock_irqsave(&data->lock, flags); 65 65 66 - reg = readl(data->membase + (bank * 4)); 67 - writel(reg | BIT(offset), data->membase + (bank * 4)); 66 + reg = readl(data->membase + (bank * reg_width)); 67 + writel(reg | BIT(offset), data->membase + (bank * reg_width)); 68 68 69 69 spin_unlock_irqrestore(&data->lock, flags); 70 70
+27 -10
drivers/reset/reset-uniphier.c
··· 50 50 } 51 51 52 52 /* System reset data */ 53 + #define UNIPHIER_SLD3_SYS_RESET_NAND(id) \ 54 + UNIPHIER_RESETX((id), 0x2004, 2) 55 + 56 + #define UNIPHIER_LD11_SYS_RESET_NAND(id) \ 57 + UNIPHIER_RESETX((id), 0x200c, 0) 58 + 59 + #define UNIPHIER_LD11_SYS_RESET_EMMC(id) \ 60 + UNIPHIER_RESETX((id), 0x200c, 2) 61 + 53 62 #define UNIPHIER_SLD3_SYS_RESET_STDMAC(id) \ 54 63 UNIPHIER_RESETX((id), 0x2000, 10) 55 64 ··· 74 65 #define UNIPHIER_PRO4_SYS_RESET_USB3(id, ch) \ 75 66 UNIPHIER_RESETX((id), 0x2000 + 0x4 * (ch), 17) 76 67 77 - const struct uniphier_reset_data uniphier_sld3_sys_reset_data[] = { 68 + static const struct uniphier_reset_data uniphier_sld3_sys_reset_data[] = { 69 + UNIPHIER_SLD3_SYS_RESET_NAND(2), 78 70 UNIPHIER_SLD3_SYS_RESET_STDMAC(8), /* Ether, HSC, MIO */ 79 71 UNIPHIER_RESET_END, 80 72 }; 81 73 82 - const struct uniphier_reset_data uniphier_pro4_sys_reset_data[] = { 74 + static const struct uniphier_reset_data uniphier_pro4_sys_reset_data[] = { 75 + UNIPHIER_SLD3_SYS_RESET_NAND(2), 83 76 UNIPHIER_SLD3_SYS_RESET_STDMAC(8), /* HSC, MIO, RLE */ 84 77 UNIPHIER_PRO4_SYS_RESET_GIO(12), /* Ether, SATA, USB3 */ 85 78 UNIPHIER_PRO4_SYS_RESET_USB3(14, 0), ··· 89 78 UNIPHIER_RESET_END, 90 79 }; 91 80 92 - const struct uniphier_reset_data uniphier_pro5_sys_reset_data[] = { 81 + static const struct uniphier_reset_data uniphier_pro5_sys_reset_data[] = { 82 + UNIPHIER_SLD3_SYS_RESET_NAND(2), 93 83 UNIPHIER_SLD3_SYS_RESET_STDMAC(8), /* HSC */ 94 84 UNIPHIER_PRO4_SYS_RESET_GIO(12), /* PCIe, USB3 */ 95 85 UNIPHIER_PRO4_SYS_RESET_USB3(14, 0), ··· 98 86 UNIPHIER_RESET_END, 99 87 }; 100 88 101 - const struct uniphier_reset_data uniphier_pxs2_sys_reset_data[] = { 89 + static const struct uniphier_reset_data uniphier_pxs2_sys_reset_data[] = { 90 + UNIPHIER_SLD3_SYS_RESET_NAND(2), 102 91 UNIPHIER_SLD3_SYS_RESET_STDMAC(8), /* HSC, RLE */ 103 92 UNIPHIER_PRO4_SYS_RESET_USB3(14, 0), 104 93 UNIPHIER_PRO4_SYS_RESET_USB3(15, 1), ··· 113 100 UNIPHIER_RESET_END, 114 101 }; 115 102 116 - const struct uniphier_reset_data uniphier_ld11_sys_reset_data[] = { 103 + static const struct uniphier_reset_data uniphier_ld11_sys_reset_data[] = { 104 + UNIPHIER_LD11_SYS_RESET_NAND(2), 105 + UNIPHIER_LD11_SYS_RESET_EMMC(4), 117 106 UNIPHIER_LD11_SYS_RESET_STDMAC(8), /* HSC, MIO */ 118 107 UNIPHIER_RESET_END, 119 108 }; 120 109 121 - const struct uniphier_reset_data uniphier_ld20_sys_reset_data[] = { 110 + static const struct uniphier_reset_data uniphier_ld20_sys_reset_data[] = { 111 + UNIPHIER_LD11_SYS_RESET_NAND(2), 112 + UNIPHIER_LD11_SYS_RESET_EMMC(4), 122 113 UNIPHIER_LD11_SYS_RESET_STDMAC(8), /* HSC */ 123 114 UNIPHIER_LD20_SYS_RESET_GIO(12), /* PCIe, USB3 */ 124 115 UNIPHIER_RESETX(16, 0x200c, 12), /* USB30-PHY0 */ ··· 151 134 #define UNIPHIER_MIO_RESET_DMAC(id) \ 152 135 UNIPHIER_RESETX((id), 0x110, 17) 153 136 154 - const struct uniphier_reset_data uniphier_sld3_mio_reset_data[] = { 137 + static const struct uniphier_reset_data uniphier_sld3_mio_reset_data[] = { 155 138 UNIPHIER_MIO_RESET_SD(0, 0), 156 139 UNIPHIER_MIO_RESET_SD(1, 1), 157 140 UNIPHIER_MIO_RESET_SD(2, 2), ··· 171 154 UNIPHIER_RESET_END, 172 155 }; 173 156 174 - const struct uniphier_reset_data uniphier_pro5_sd_reset_data[] = { 157 + static const struct uniphier_reset_data uniphier_pro5_sd_reset_data[] = { 175 158 UNIPHIER_MIO_RESET_SD(0, 0), 176 159 UNIPHIER_MIO_RESET_SD(1, 1), 177 160 UNIPHIER_MIO_RESET_EMMC_HW_RESET(6, 1), ··· 188 171 #define UNIPHIER_PERI_RESET_FI2C(id, ch) \ 189 172 UNIPHIER_RESETX((id), 0x114, 24 + (ch)) 190 173 191 - const struct uniphier_reset_data uniphier_ld4_peri_reset_data[] = { 174 + static const struct uniphier_reset_data uniphier_ld4_peri_reset_data[] = { 192 175 UNIPHIER_PERI_RESET_UART(0, 0), 193 176 UNIPHIER_PERI_RESET_UART(1, 1), 194 177 UNIPHIER_PERI_RESET_UART(2, 2), ··· 201 184 UNIPHIER_RESET_END, 202 185 }; 203 186 204 - const struct uniphier_reset_data uniphier_pro4_peri_reset_data[] = { 187 + static const struct uniphier_reset_data uniphier_pro4_peri_reset_data[] = { 205 188 UNIPHIER_PERI_RESET_UART(0, 0), 206 189 UNIPHIER_PERI_RESET_UART(1, 1), 207 190 UNIPHIER_PERI_RESET_UART(2, 2),
+1
drivers/soc/Kconfig
··· 3 3 source "drivers/soc/atmel/Kconfig" 4 4 source "drivers/soc/bcm/Kconfig" 5 5 source "drivers/soc/fsl/Kconfig" 6 + source "drivers/soc/imx/Kconfig" 6 7 source "drivers/soc/mediatek/Kconfig" 7 8 source "drivers/soc/qcom/Kconfig" 8 9 source "drivers/soc/rockchip/Kconfig"
+1
drivers/soc/Makefile
··· 7 7 obj-$(CONFIG_ARCH_DOVE) += dove/ 8 8 obj-$(CONFIG_MACH_DOVE) += dove/ 9 9 obj-y += fsl/ 10 + obj-$(CONFIG_ARCH_MXC) += imx/ 10 11 obj-$(CONFIG_ARCH_MEDIATEK) += mediatek/ 11 12 obj-$(CONFIG_ARCH_QCOM) += qcom/ 12 13 obj-$(CONFIG_ARCH_RENESAS) += renesas/
+9
drivers/soc/bcm/brcmstb/common.c
··· 41 41 } 42 42 43 43 static const struct of_device_id sun_top_ctrl_match[] = { 44 + { .compatible = "brcm,bcm7125-sun-top-ctrl", }, 45 + { .compatible = "brcm,bcm7346-sun-top-ctrl", }, 46 + { .compatible = "brcm,bcm7358-sun-top-ctrl", }, 47 + { .compatible = "brcm,bcm7360-sun-top-ctrl", }, 48 + { .compatible = "brcm,bcm7362-sun-top-ctrl", }, 49 + { .compatible = "brcm,bcm7420-sun-top-ctrl", }, 50 + { .compatible = "brcm,bcm7425-sun-top-ctrl", }, 51 + { .compatible = "brcm,bcm7429-sun-top-ctrl", }, 52 + { .compatible = "brcm,bcm7425-sun-top-ctrl", }, 44 53 { .compatible = "brcm,brcmstb-sun-top-ctrl", }, 45 54 { } 46 55 };
+9
drivers/soc/imx/Kconfig
··· 1 + menu "i.MX SoC drivers" 2 + 3 + config IMX7_PM_DOMAINS 4 + bool "i.MX7 PM domains" 5 + select PM_GENERIC_DOMAINS 6 + depends on SOC_IMX7D || (COMPILE_TEST && OF) 7 + default y if SOC_IMX7D 8 + 9 + endmenu
+2
drivers/soc/imx/Makefile
··· 1 + obj-y += gpc.o 2 + obj-$(CONFIG_IMX7_PM_DOMAINS) += gpcv2.o
+489
drivers/soc/imx/gpc.c
··· 1 + /* 2 + * Copyright 2015-2017 Pengutronix, Lucas Stach <kernel@pengutronix.de> 3 + * Copyright 2011-2013 Freescale Semiconductor, Inc. 4 + * 5 + * The code contained herein is licensed under the GNU General Public 6 + * License. You may obtain a copy of the GNU General Public License 7 + * Version 2 or later at the following locations: 8 + * 9 + * http://www.opensource.org/licenses/gpl-license.html 10 + * http://www.gnu.org/copyleft/gpl.html 11 + */ 12 + 13 + #include <linux/clk.h> 14 + #include <linux/delay.h> 15 + #include <linux/io.h> 16 + #include <linux/of_device.h> 17 + #include <linux/platform_device.h> 18 + #include <linux/pm_domain.h> 19 + #include <linux/regmap.h> 20 + #include <linux/regulator/consumer.h> 21 + 22 + #define GPC_CNTR 0x000 23 + 24 + #define GPC_PGC_CTRL_OFFS 0x0 25 + #define GPC_PGC_PUPSCR_OFFS 0x4 26 + #define GPC_PGC_PDNSCR_OFFS 0x8 27 + #define GPC_PGC_SW2ISO_SHIFT 0x8 28 + #define GPC_PGC_SW_SHIFT 0x0 29 + 30 + #define GPC_PGC_GPU_PDN 0x260 31 + #define GPC_PGC_GPU_PUPSCR 0x264 32 + #define GPC_PGC_GPU_PDNSCR 0x268 33 + 34 + #define GPU_VPU_PUP_REQ BIT(1) 35 + #define GPU_VPU_PDN_REQ BIT(0) 36 + 37 + #define GPC_CLK_MAX 6 38 + 39 + #define PGC_DOMAIN_FLAG_NO_PD BIT(0) 40 + 41 + struct imx_pm_domain { 42 + struct generic_pm_domain base; 43 + struct regmap *regmap; 44 + struct regulator *supply; 45 + struct clk *clk[GPC_CLK_MAX]; 46 + int num_clks; 47 + unsigned int reg_offs; 48 + signed char cntr_pdn_bit; 49 + unsigned int ipg_rate_mhz; 50 + unsigned int flags; 51 + }; 52 + 53 + static inline struct imx_pm_domain * 54 + to_imx_pm_domain(struct generic_pm_domain *genpd) 55 + { 56 + return container_of(genpd, struct imx_pm_domain, base); 57 + } 58 + 59 + static int imx6_pm_domain_power_off(struct generic_pm_domain *genpd) 60 + { 61 + struct imx_pm_domain *pd = to_imx_pm_domain(genpd); 62 + int iso, iso2sw; 63 + u32 val; 64 + 65 + if (pd->flags & PGC_DOMAIN_FLAG_NO_PD) 66 + return -EBUSY; 67 + 68 + /* Read ISO and ISO2SW power down delays */ 69 + regmap_read(pd->regmap, pd->reg_offs + GPC_PGC_PUPSCR_OFFS, &val); 70 + iso = val & 0x3f; 71 + iso2sw = (val >> 8) & 0x3f; 72 + 73 + /* Gate off domain when powered down */ 74 + regmap_update_bits(pd->regmap, pd->reg_offs + GPC_PGC_CTRL_OFFS, 75 + 0x1, 0x1); 76 + 77 + /* Request GPC to power down domain */ 78 + val = BIT(pd->cntr_pdn_bit); 79 + regmap_update_bits(pd->regmap, GPC_CNTR, val, val); 80 + 81 + /* Wait ISO + ISO2SW IPG clock cycles */ 82 + udelay(DIV_ROUND_UP(iso + iso2sw, pd->ipg_rate_mhz)); 83 + 84 + if (pd->supply) 85 + regulator_disable(pd->supply); 86 + 87 + return 0; 88 + } 89 + 90 + static int imx6_pm_domain_power_on(struct generic_pm_domain *genpd) 91 + { 92 + struct imx_pm_domain *pd = to_imx_pm_domain(genpd); 93 + int i, ret, sw, sw2iso; 94 + u32 val; 95 + 96 + if (pd->supply) { 97 + ret = regulator_enable(pd->supply); 98 + if (ret) { 99 + pr_err("%s: failed to enable regulator: %d\n", 100 + __func__, ret); 101 + return ret; 102 + } 103 + } 104 + 105 + /* Enable reset clocks for all devices in the domain */ 106 + for (i = 0; i < pd->num_clks; i++) 107 + clk_prepare_enable(pd->clk[i]); 108 + 109 + /* Gate off domain when powered down */ 110 + regmap_update_bits(pd->regmap, pd->reg_offs + GPC_PGC_CTRL_OFFS, 111 + 0x1, 0x1); 112 + 113 + /* Read ISO and ISO2SW power up delays */ 114 + regmap_read(pd->regmap, pd->reg_offs + GPC_PGC_PUPSCR_OFFS, &val); 115 + sw = val & 0x3f; 116 + sw2iso = (val >> 8) & 0x3f; 117 + 118 + /* Request GPC to power up domain */ 119 + val = BIT(pd->cntr_pdn_bit + 1); 120 + regmap_update_bits(pd->regmap, GPC_CNTR, val, val); 121 + 122 + /* Wait ISO + ISO2SW IPG clock cycles */ 123 + udelay(DIV_ROUND_UP(sw + sw2iso, pd->ipg_rate_mhz)); 124 + 125 + /* Disable reset clocks for all devices in the domain */ 126 + for (i = 0; i < pd->num_clks; i++) 127 + clk_disable_unprepare(pd->clk[i]); 128 + 129 + return 0; 130 + } 131 + 132 + static int imx_pgc_get_clocks(struct device *dev, struct imx_pm_domain *domain) 133 + { 134 + int i, ret; 135 + 136 + for (i = 0; ; i++) { 137 + struct clk *clk = of_clk_get(dev->of_node, i); 138 + if (IS_ERR(clk)) 139 + break; 140 + if (i >= GPC_CLK_MAX) { 141 + dev_err(dev, "more than %d clocks\n", GPC_CLK_MAX); 142 + ret = -EINVAL; 143 + goto clk_err; 144 + } 145 + domain->clk[i] = clk; 146 + } 147 + domain->num_clks = i; 148 + 149 + return 0; 150 + 151 + clk_err: 152 + while (i--) 153 + clk_put(domain->clk[i]); 154 + 155 + return ret; 156 + } 157 + 158 + static void imx_pgc_put_clocks(struct imx_pm_domain *domain) 159 + { 160 + int i; 161 + 162 + for (i = domain->num_clks - 1; i >= 0; i--) 163 + clk_put(domain->clk[i]); 164 + } 165 + 166 + static int imx_pgc_parse_dt(struct device *dev, struct imx_pm_domain *domain) 167 + { 168 + /* try to get the domain supply regulator */ 169 + domain->supply = devm_regulator_get_optional(dev, "power"); 170 + if (IS_ERR(domain->supply)) { 171 + if (PTR_ERR(domain->supply) == -ENODEV) 172 + domain->supply = NULL; 173 + else 174 + return PTR_ERR(domain->supply); 175 + } 176 + 177 + /* try to get all clocks needed for reset propagation */ 178 + return imx_pgc_get_clocks(dev, domain); 179 + } 180 + 181 + static int imx_pgc_power_domain_probe(struct platform_device *pdev) 182 + { 183 + struct imx_pm_domain *domain = pdev->dev.platform_data; 184 + struct device *dev = &pdev->dev; 185 + int ret; 186 + 187 + /* if this PD is associated with a DT node try to parse it */ 188 + if (dev->of_node) { 189 + ret = imx_pgc_parse_dt(dev, domain); 190 + if (ret) 191 + return ret; 192 + } 193 + 194 + /* initially power on the domain */ 195 + if (domain->base.power_on) 196 + domain->base.power_on(&domain->base); 197 + 198 + if (IS_ENABLED(CONFIG_PM_GENERIC_DOMAINS)) { 199 + pm_genpd_init(&domain->base, NULL, false); 200 + ret = of_genpd_add_provider_simple(dev->of_node, &domain->base); 201 + if (ret) 202 + goto genpd_err; 203 + } 204 + 205 + device_link_add(dev, dev->parent, DL_FLAG_AUTOREMOVE); 206 + 207 + return 0; 208 + 209 + genpd_err: 210 + pm_genpd_remove(&domain->base); 211 + imx_pgc_put_clocks(domain); 212 + 213 + return ret; 214 + } 215 + 216 + static int imx_pgc_power_domain_remove(struct platform_device *pdev) 217 + { 218 + struct imx_pm_domain *domain = pdev->dev.platform_data; 219 + 220 + if (IS_ENABLED(CONFIG_PM_GENERIC_DOMAINS)) { 221 + of_genpd_del_provider(pdev->dev.of_node); 222 + pm_genpd_remove(&domain->base); 223 + imx_pgc_put_clocks(domain); 224 + } 225 + 226 + return 0; 227 + } 228 + 229 + static const struct platform_device_id imx_pgc_power_domain_id[] = { 230 + { "imx-pgc-power-domain"}, 231 + { }, 232 + }; 233 + 234 + static struct platform_driver imx_pgc_power_domain_driver = { 235 + .driver = { 236 + .name = "imx-pgc-pd", 237 + }, 238 + .probe = imx_pgc_power_domain_probe, 239 + .remove = imx_pgc_power_domain_remove, 240 + .id_table = imx_pgc_power_domain_id, 241 + }; 242 + builtin_platform_driver(imx_pgc_power_domain_driver) 243 + 244 + #define GPC_PGC_DOMAIN_ARM 0 245 + #define GPC_PGC_DOMAIN_PU 1 246 + #define GPC_PGC_DOMAIN_DISPLAY 2 247 + 248 + static struct genpd_power_state imx6_pm_domain_pu_state = { 249 + .power_off_latency_ns = 25000, 250 + .power_on_latency_ns = 2000000, 251 + }; 252 + 253 + static struct imx_pm_domain imx_gpc_domains[] = { 254 + { 255 + .base = { 256 + .name = "ARM", 257 + }, 258 + }, { 259 + .base = { 260 + .name = "PU", 261 + .power_off = imx6_pm_domain_power_off, 262 + .power_on = imx6_pm_domain_power_on, 263 + .states = &imx6_pm_domain_pu_state, 264 + .state_count = 1, 265 + }, 266 + .reg_offs = 0x260, 267 + .cntr_pdn_bit = 0, 268 + }, { 269 + .base = { 270 + .name = "DISPLAY", 271 + .power_off = imx6_pm_domain_power_off, 272 + .power_on = imx6_pm_domain_power_on, 273 + }, 274 + .reg_offs = 0x240, 275 + .cntr_pdn_bit = 4, 276 + } 277 + }; 278 + 279 + struct imx_gpc_dt_data { 280 + int num_domains; 281 + bool err009619_present; 282 + }; 283 + 284 + static const struct imx_gpc_dt_data imx6q_dt_data = { 285 + .num_domains = 2, 286 + .err009619_present = false, 287 + }; 288 + 289 + static const struct imx_gpc_dt_data imx6qp_dt_data = { 290 + .num_domains = 2, 291 + .err009619_present = true, 292 + }; 293 + 294 + static const struct imx_gpc_dt_data imx6sl_dt_data = { 295 + .num_domains = 3, 296 + .err009619_present = false, 297 + }; 298 + 299 + static const struct of_device_id imx_gpc_dt_ids[] = { 300 + { .compatible = "fsl,imx6q-gpc", .data = &imx6q_dt_data }, 301 + { .compatible = "fsl,imx6qp-gpc", .data = &imx6qp_dt_data }, 302 + { .compatible = "fsl,imx6sl-gpc", .data = &imx6sl_dt_data }, 303 + { } 304 + }; 305 + 306 + static const struct regmap_config imx_gpc_regmap_config = { 307 + .reg_bits = 32, 308 + .val_bits = 32, 309 + .reg_stride = 4, 310 + .max_register = 0x2ac, 311 + }; 312 + 313 + static struct generic_pm_domain *imx_gpc_onecell_domains[] = { 314 + &imx_gpc_domains[0].base, 315 + &imx_gpc_domains[1].base, 316 + }; 317 + 318 + static struct genpd_onecell_data imx_gpc_onecell_data = { 319 + .domains = imx_gpc_onecell_domains, 320 + .num_domains = 2, 321 + }; 322 + 323 + static int imx_gpc_old_dt_init(struct device *dev, struct regmap *regmap, 324 + unsigned int num_domains) 325 + { 326 + struct imx_pm_domain *domain; 327 + int i, ret; 328 + 329 + for (i = 0; i < num_domains; i++) { 330 + domain = &imx_gpc_domains[i]; 331 + domain->regmap = regmap; 332 + domain->ipg_rate_mhz = 66; 333 + 334 + if (i == 1) { 335 + domain->supply = devm_regulator_get(dev, "pu"); 336 + if (IS_ERR(domain->supply)) 337 + return PTR_ERR(domain->supply);; 338 + 339 + ret = imx_pgc_get_clocks(dev, domain); 340 + if (ret) 341 + goto clk_err; 342 + 343 + domain->base.power_on(&domain->base); 344 + } 345 + } 346 + 347 + for (i = 0; i < num_domains; i++) 348 + pm_genpd_init(&imx_gpc_domains[i].base, NULL, false); 349 + 350 + if (IS_ENABLED(CONFIG_PM_GENERIC_DOMAINS)) { 351 + ret = of_genpd_add_provider_onecell(dev->of_node, 352 + &imx_gpc_onecell_data); 353 + if (ret) 354 + goto genpd_err; 355 + } 356 + 357 + return 0; 358 + 359 + genpd_err: 360 + for (i = 0; i < num_domains; i++) 361 + pm_genpd_remove(&imx_gpc_domains[i].base); 362 + imx_pgc_put_clocks(&imx_gpc_domains[GPC_PGC_DOMAIN_PU]); 363 + clk_err: 364 + return ret; 365 + } 366 + 367 + static int imx_gpc_probe(struct platform_device *pdev) 368 + { 369 + const struct of_device_id *of_id = 370 + of_match_device(imx_gpc_dt_ids, &pdev->dev); 371 + const struct imx_gpc_dt_data *of_id_data = of_id->data; 372 + struct device_node *pgc_node; 373 + struct regmap *regmap; 374 + struct resource *res; 375 + void __iomem *base; 376 + int ret; 377 + 378 + pgc_node = of_get_child_by_name(pdev->dev.of_node, "pgc"); 379 + 380 + /* bail out if DT too old and doesn't provide the necessary info */ 381 + if (!of_property_read_bool(pdev->dev.of_node, "#power-domain-cells") && 382 + !pgc_node) 383 + return 0; 384 + 385 + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 386 + base = devm_ioremap_resource(&pdev->dev, res); 387 + if (IS_ERR(base)) 388 + return PTR_ERR(base); 389 + 390 + regmap = devm_regmap_init_mmio_clk(&pdev->dev, NULL, base, 391 + &imx_gpc_regmap_config); 392 + if (IS_ERR(regmap)) { 393 + ret = PTR_ERR(regmap); 394 + dev_err(&pdev->dev, "failed to init regmap: %d\n", 395 + ret); 396 + return ret; 397 + } 398 + 399 + /* Disable PU power down in normal operation if ERR009619 is present */ 400 + if (of_id_data->err009619_present) 401 + imx_gpc_domains[GPC_PGC_DOMAIN_PU].flags |= 402 + PGC_DOMAIN_FLAG_NO_PD; 403 + 404 + if (!pgc_node) { 405 + ret = imx_gpc_old_dt_init(&pdev->dev, regmap, 406 + of_id_data->num_domains); 407 + if (ret) 408 + return ret; 409 + } else { 410 + struct imx_pm_domain *domain; 411 + struct platform_device *pd_pdev; 412 + struct device_node *np; 413 + struct clk *ipg_clk; 414 + unsigned int ipg_rate_mhz; 415 + int domain_index; 416 + 417 + ipg_clk = devm_clk_get(&pdev->dev, "ipg"); 418 + if (IS_ERR(ipg_clk)) 419 + return PTR_ERR(ipg_clk); 420 + ipg_rate_mhz = clk_get_rate(ipg_clk) / 1000000; 421 + 422 + for_each_child_of_node(pgc_node, np) { 423 + ret = of_property_read_u32(np, "reg", &domain_index); 424 + if (ret) { 425 + of_node_put(np); 426 + return ret; 427 + } 428 + if (domain_index >= of_id_data->num_domains) 429 + continue; 430 + 431 + domain = &imx_gpc_domains[domain_index]; 432 + domain->regmap = regmap; 433 + domain->ipg_rate_mhz = ipg_rate_mhz; 434 + 435 + pd_pdev = platform_device_alloc("imx-pgc-power-domain", 436 + domain_index); 437 + if (!pd_pdev) { 438 + of_node_put(np); 439 + return -ENOMEM; 440 + } 441 + pd_pdev->dev.platform_data = domain; 442 + pd_pdev->dev.parent = &pdev->dev; 443 + pd_pdev->dev.of_node = np; 444 + 445 + ret = platform_device_add(pd_pdev); 446 + if (ret) { 447 + platform_device_put(pd_pdev); 448 + of_node_put(np); 449 + return ret; 450 + } 451 + } 452 + } 453 + 454 + return 0; 455 + } 456 + 457 + static int imx_gpc_remove(struct platform_device *pdev) 458 + { 459 + int ret; 460 + 461 + /* 462 + * If the old DT binding is used the toplevel driver needs to 463 + * de-register the power domains 464 + */ 465 + if (!of_get_child_by_name(pdev->dev.of_node, "pgc")) { 466 + of_genpd_del_provider(pdev->dev.of_node); 467 + 468 + ret = pm_genpd_remove(&imx_gpc_domains[GPC_PGC_DOMAIN_PU].base); 469 + if (ret) 470 + return ret; 471 + imx_pgc_put_clocks(&imx_gpc_domains[GPC_PGC_DOMAIN_PU]); 472 + 473 + ret = pm_genpd_remove(&imx_gpc_domains[GPC_PGC_DOMAIN_ARM].base); 474 + if (ret) 475 + return ret; 476 + } 477 + 478 + return 0; 479 + } 480 + 481 + static struct platform_driver imx_gpc_driver = { 482 + .driver = { 483 + .name = "imx-gpc", 484 + .of_match_table = imx_gpc_dt_ids, 485 + }, 486 + .probe = imx_gpc_probe, 487 + .remove = imx_gpc_remove, 488 + }; 489 + builtin_platform_driver(imx_gpc_driver)
+363
drivers/soc/imx/gpcv2.c
··· 1 + /* 2 + * Copyright 2017 Impinj, Inc 3 + * Author: Andrey Smirnov <andrew.smirnov@gmail.com> 4 + * 5 + * Based on the code of analogus driver: 6 + * 7 + * Copyright 2015-2017 Pengutronix, Lucas Stach <kernel@pengutronix.de> 8 + * 9 + * The code contained herein is licensed under the GNU General Public 10 + * License. You may obtain a copy of the GNU General Public License 11 + * Version 2 or later at the following locations: 12 + * 13 + * http://www.opensource.org/licenses/gpl-license.html 14 + * http://www.gnu.org/copyleft/gpl.html 15 + */ 16 + 17 + #include <linux/platform_device.h> 18 + #include <linux/pm_domain.h> 19 + #include <linux/regmap.h> 20 + #include <linux/regulator/consumer.h> 21 + #include <dt-bindings/power/imx7-power.h> 22 + 23 + #define GPC_LPCR_A7_BSC 0x000 24 + 25 + #define GPC_PGC_CPU_MAPPING 0x0ec 26 + #define USB_HSIC_PHY_A7_DOMAIN BIT(6) 27 + #define USB_OTG2_PHY_A7_DOMAIN BIT(5) 28 + #define USB_OTG1_PHY_A7_DOMAIN BIT(4) 29 + #define PCIE_PHY_A7_DOMAIN BIT(3) 30 + #define MIPI_PHY_A7_DOMAIN BIT(2) 31 + 32 + #define GPC_PU_PGC_SW_PUP_REQ 0x0f8 33 + #define GPC_PU_PGC_SW_PDN_REQ 0x104 34 + #define USB_HSIC_PHY_SW_Pxx_REQ BIT(4) 35 + #define USB_OTG2_PHY_SW_Pxx_REQ BIT(3) 36 + #define USB_OTG1_PHY_SW_Pxx_REQ BIT(2) 37 + #define PCIE_PHY_SW_Pxx_REQ BIT(1) 38 + #define MIPI_PHY_SW_Pxx_REQ BIT(0) 39 + 40 + #define GPC_M4_PU_PDN_FLG 0x1bc 41 + 42 + 43 + #define PGC_MIPI 4 44 + #define PGC_PCIE 5 45 + #define PGC_USB_HSIC 8 46 + #define GPC_PGC_CTRL(n) (0x800 + (n) * 0x40) 47 + #define GPC_PGC_SR(n) (GPC_PGC_CTRL(n) + 0xc) 48 + 49 + #define GPC_PGC_CTRL_PCR BIT(0) 50 + 51 + struct imx7_pgc_domain { 52 + struct generic_pm_domain genpd; 53 + struct regmap *regmap; 54 + struct regulator *regulator; 55 + 56 + unsigned int pgc; 57 + 58 + const struct { 59 + u32 pxx; 60 + u32 map; 61 + } bits; 62 + 63 + const int voltage; 64 + struct device *dev; 65 + }; 66 + 67 + static int imx7_gpc_pu_pgc_sw_pxx_req(struct generic_pm_domain *genpd, 68 + bool on) 69 + { 70 + struct imx7_pgc_domain *domain = container_of(genpd, 71 + struct imx7_pgc_domain, 72 + genpd); 73 + unsigned int offset = on ? 74 + GPC_PU_PGC_SW_PUP_REQ : GPC_PU_PGC_SW_PDN_REQ; 75 + const bool enable_power_control = !on; 76 + const bool has_regulator = !IS_ERR(domain->regulator); 77 + unsigned long deadline; 78 + int ret = 0; 79 + 80 + regmap_update_bits(domain->regmap, GPC_PGC_CPU_MAPPING, 81 + domain->bits.map, domain->bits.map); 82 + 83 + if (has_regulator && on) { 84 + ret = regulator_enable(domain->regulator); 85 + if (ret) { 86 + dev_err(domain->dev, "failed to enable regulator\n"); 87 + goto unmap; 88 + } 89 + } 90 + 91 + if (enable_power_control) 92 + regmap_update_bits(domain->regmap, GPC_PGC_CTRL(domain->pgc), 93 + GPC_PGC_CTRL_PCR, GPC_PGC_CTRL_PCR); 94 + 95 + regmap_update_bits(domain->regmap, offset, 96 + domain->bits.pxx, domain->bits.pxx); 97 + 98 + /* 99 + * As per "5.5.9.4 Example Code 4" in IMX7DRM.pdf wait 100 + * for PUP_REQ/PDN_REQ bit to be cleared 101 + */ 102 + deadline = jiffies + msecs_to_jiffies(1); 103 + while (true) { 104 + u32 pxx_req; 105 + 106 + regmap_read(domain->regmap, offset, &pxx_req); 107 + 108 + if (!(pxx_req & domain->bits.pxx)) 109 + break; 110 + 111 + if (time_after(jiffies, deadline)) { 112 + dev_err(domain->dev, "falied to command PGC\n"); 113 + ret = -ETIMEDOUT; 114 + /* 115 + * If we were in a process of enabling a 116 + * domain and failed we might as well disable 117 + * the regulator we just enabled. And if it 118 + * was the opposite situation and we failed to 119 + * power down -- keep the regulator on 120 + */ 121 + on = !on; 122 + break; 123 + } 124 + 125 + cpu_relax(); 126 + } 127 + 128 + if (enable_power_control) 129 + regmap_update_bits(domain->regmap, GPC_PGC_CTRL(domain->pgc), 130 + GPC_PGC_CTRL_PCR, 0); 131 + 132 + if (has_regulator && !on) { 133 + int err; 134 + 135 + err = regulator_disable(domain->regulator); 136 + if (err) 137 + dev_err(domain->dev, 138 + "failed to disable regulator: %d\n", ret); 139 + /* Preserve earlier error code */ 140 + ret = ret ?: err; 141 + } 142 + unmap: 143 + regmap_update_bits(domain->regmap, GPC_PGC_CPU_MAPPING, 144 + domain->bits.map, 0); 145 + return ret; 146 + } 147 + 148 + static int imx7_gpc_pu_pgc_sw_pup_req(struct generic_pm_domain *genpd) 149 + { 150 + return imx7_gpc_pu_pgc_sw_pxx_req(genpd, true); 151 + } 152 + 153 + static int imx7_gpc_pu_pgc_sw_pdn_req(struct generic_pm_domain *genpd) 154 + { 155 + return imx7_gpc_pu_pgc_sw_pxx_req(genpd, false); 156 + } 157 + 158 + static struct imx7_pgc_domain imx7_pgc_domains[] = { 159 + [IMX7_POWER_DOMAIN_MIPI_PHY] = { 160 + .genpd = { 161 + .name = "mipi-phy", 162 + }, 163 + .bits = { 164 + .pxx = MIPI_PHY_SW_Pxx_REQ, 165 + .map = MIPI_PHY_A7_DOMAIN, 166 + }, 167 + .voltage = 1000000, 168 + .pgc = PGC_MIPI, 169 + }, 170 + 171 + [IMX7_POWER_DOMAIN_PCIE_PHY] = { 172 + .genpd = { 173 + .name = "pcie-phy", 174 + }, 175 + .bits = { 176 + .pxx = PCIE_PHY_SW_Pxx_REQ, 177 + .map = PCIE_PHY_A7_DOMAIN, 178 + }, 179 + .voltage = 1000000, 180 + .pgc = PGC_PCIE, 181 + }, 182 + 183 + [IMX7_POWER_DOMAIN_USB_HSIC_PHY] = { 184 + .genpd = { 185 + .name = "usb-hsic-phy", 186 + }, 187 + .bits = { 188 + .pxx = USB_HSIC_PHY_SW_Pxx_REQ, 189 + .map = USB_HSIC_PHY_A7_DOMAIN, 190 + }, 191 + .voltage = 1200000, 192 + .pgc = PGC_USB_HSIC, 193 + }, 194 + }; 195 + 196 + static int imx7_pgc_domain_probe(struct platform_device *pdev) 197 + { 198 + struct imx7_pgc_domain *domain = pdev->dev.platform_data; 199 + int ret; 200 + 201 + domain->dev = &pdev->dev; 202 + 203 + ret = pm_genpd_init(&domain->genpd, NULL, true); 204 + if (ret) { 205 + dev_err(domain->dev, "Failed to init power domain\n"); 206 + return ret; 207 + } 208 + 209 + domain->regulator = devm_regulator_get_optional(domain->dev, "power"); 210 + if (IS_ERR(domain->regulator)) { 211 + if (PTR_ERR(domain->regulator) != -ENODEV) { 212 + dev_err(domain->dev, "Failed to get domain's regulator\n"); 213 + return PTR_ERR(domain->regulator); 214 + } 215 + } else { 216 + regulator_set_voltage(domain->regulator, 217 + domain->voltage, domain->voltage); 218 + } 219 + 220 + ret = of_genpd_add_provider_simple(domain->dev->of_node, 221 + &domain->genpd); 222 + if (ret) { 223 + dev_err(domain->dev, "Failed to add genpd provider\n"); 224 + pm_genpd_remove(&domain->genpd); 225 + } 226 + 227 + return ret; 228 + } 229 + 230 + static int imx7_pgc_domain_remove(struct platform_device *pdev) 231 + { 232 + struct imx7_pgc_domain *domain = pdev->dev.platform_data; 233 + 234 + of_genpd_del_provider(domain->dev->of_node); 235 + pm_genpd_remove(&domain->genpd); 236 + 237 + return 0; 238 + } 239 + 240 + static const struct platform_device_id imx7_pgc_domain_id[] = { 241 + { "imx7-pgc-domain", }, 242 + { }, 243 + }; 244 + 245 + static struct platform_driver imx7_pgc_domain_driver = { 246 + .driver = { 247 + .name = "imx7-pgc", 248 + }, 249 + .probe = imx7_pgc_domain_probe, 250 + .remove = imx7_pgc_domain_remove, 251 + .id_table = imx7_pgc_domain_id, 252 + }; 253 + builtin_platform_driver(imx7_pgc_domain_driver) 254 + 255 + static int imx_gpcv2_probe(struct platform_device *pdev) 256 + { 257 + static const struct regmap_range yes_ranges[] = { 258 + regmap_reg_range(GPC_LPCR_A7_BSC, 259 + GPC_M4_PU_PDN_FLG), 260 + regmap_reg_range(GPC_PGC_CTRL(PGC_MIPI), 261 + GPC_PGC_SR(PGC_MIPI)), 262 + regmap_reg_range(GPC_PGC_CTRL(PGC_PCIE), 263 + GPC_PGC_SR(PGC_PCIE)), 264 + regmap_reg_range(GPC_PGC_CTRL(PGC_USB_HSIC), 265 + GPC_PGC_SR(PGC_USB_HSIC)), 266 + }; 267 + static const struct regmap_access_table access_table = { 268 + .yes_ranges = yes_ranges, 269 + .n_yes_ranges = ARRAY_SIZE(yes_ranges), 270 + }; 271 + static const struct regmap_config regmap_config = { 272 + .reg_bits = 32, 273 + .val_bits = 32, 274 + .reg_stride = 4, 275 + .rd_table = &access_table, 276 + .wr_table = &access_table, 277 + .max_register = SZ_4K, 278 + }; 279 + struct device *dev = &pdev->dev; 280 + struct device_node *pgc_np, *np; 281 + struct regmap *regmap; 282 + struct resource *res; 283 + void __iomem *base; 284 + int ret; 285 + 286 + pgc_np = of_get_child_by_name(dev->of_node, "pgc"); 287 + if (!pgc_np) { 288 + dev_err(dev, "No power domains specified in DT\n"); 289 + return -EINVAL; 290 + } 291 + 292 + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 293 + base = devm_ioremap_resource(dev, res); 294 + if (IS_ERR(base)) 295 + return PTR_ERR(base); 296 + 297 + regmap = devm_regmap_init_mmio(dev, base, &regmap_config); 298 + if (IS_ERR(regmap)) { 299 + ret = PTR_ERR(regmap); 300 + dev_err(dev, "failed to init regmap (%d)\n", ret); 301 + return ret; 302 + } 303 + 304 + for_each_child_of_node(pgc_np, np) { 305 + struct platform_device *pd_pdev; 306 + struct imx7_pgc_domain *domain; 307 + u32 domain_index; 308 + 309 + ret = of_property_read_u32(np, "reg", &domain_index); 310 + if (ret) { 311 + dev_err(dev, "Failed to read 'reg' property\n"); 312 + of_node_put(np); 313 + return ret; 314 + } 315 + 316 + if (domain_index >= ARRAY_SIZE(imx7_pgc_domains)) { 317 + dev_warn(dev, 318 + "Domain index %d is out of bounds\n", 319 + domain_index); 320 + continue; 321 + } 322 + 323 + domain = &imx7_pgc_domains[domain_index]; 324 + domain->regmap = regmap; 325 + domain->genpd.power_on = imx7_gpc_pu_pgc_sw_pup_req; 326 + domain->genpd.power_off = imx7_gpc_pu_pgc_sw_pdn_req; 327 + 328 + pd_pdev = platform_device_alloc("imx7-pgc-domain", 329 + domain_index); 330 + if (!pd_pdev) { 331 + dev_err(dev, "Failed to allocate platform device\n"); 332 + of_node_put(np); 333 + return -ENOMEM; 334 + } 335 + 336 + pd_pdev->dev.platform_data = domain; 337 + pd_pdev->dev.parent = dev; 338 + pd_pdev->dev.of_node = np; 339 + 340 + ret = platform_device_add(pd_pdev); 341 + if (ret) { 342 + platform_device_put(pd_pdev); 343 + of_node_put(np); 344 + return ret; 345 + } 346 + } 347 + 348 + return 0; 349 + } 350 + 351 + static const struct of_device_id imx_gpcv2_dt_ids[] = { 352 + { .compatible = "fsl,imx7d-gpc" }, 353 + { } 354 + }; 355 + 356 + static struct platform_driver imx_gpc_driver = { 357 + .driver = { 358 + .name = "imx-gpcv2", 359 + .of_match_table = imx_gpcv2_dt_ids, 360 + }, 361 + .probe = imx_gpcv2_probe, 362 + }; 363 + builtin_platform_driver(imx_gpc_driver)
+24 -2
drivers/soc/renesas/r8a7795-sysc.c
··· 1 1 /* 2 2 * Renesas R-Car H3 System Controller 3 3 * 4 - * Copyright (C) 2016 Glider bvba 4 + * Copyright (C) 2016-2017 Glider bvba 5 5 * 6 6 * This program is free software; you can redistribute it and/or modify 7 7 * it under the terms of the GNU General Public License as published by ··· 10 10 11 11 #include <linux/bug.h> 12 12 #include <linux/kernel.h> 13 + #include <linux/sys_soc.h> 13 14 14 15 #include <dt-bindings/power/r8a7795-sysc.h> 15 16 16 17 #include "rcar-sysc.h" 17 18 18 - static const struct rcar_sysc_area r8a7795_areas[] __initconst = { 19 + static struct rcar_sysc_area r8a7795_areas[] __initdata = { 19 20 { "always-on", 0, 0, R8A7795_PD_ALWAYS_ON, -1, PD_ALWAYS_ON }, 20 21 { "ca57-scu", 0x1c0, 0, R8A7795_PD_CA57_SCU, R8A7795_PD_ALWAYS_ON, 21 22 PD_SCU }, ··· 41 40 { "a3vp", 0x340, 0, R8A7795_PD_A3VP, R8A7795_PD_ALWAYS_ON }, 42 41 { "cr7", 0x240, 0, R8A7795_PD_CR7, R8A7795_PD_ALWAYS_ON }, 43 42 { "a3vc", 0x380, 0, R8A7795_PD_A3VC, R8A7795_PD_ALWAYS_ON }, 43 + /* A2VC0 exists on ES1.x only */ 44 44 { "a2vc0", 0x3c0, 0, R8A7795_PD_A2VC0, R8A7795_PD_A3VC }, 45 45 { "a2vc1", 0x3c0, 1, R8A7795_PD_A2VC1, R8A7795_PD_A3VC }, 46 46 { "3dg-a", 0x100, 0, R8A7795_PD_3DG_A, R8A7795_PD_ALWAYS_ON }, ··· 52 50 { "a3ir", 0x180, 0, R8A7795_PD_A3IR, R8A7795_PD_ALWAYS_ON }, 53 51 }; 54 52 53 + 54 + /* 55 + * Fixups for R-Car H3 revisions after ES1.x 56 + */ 57 + 58 + static const struct soc_device_attribute r8a7795es1[] __initconst = { 59 + { .soc_id = "r8a7795", .revision = "ES1.*" }, 60 + { /* sentinel */ } 61 + }; 62 + 63 + static int __init r8a7795_sysc_init(void) 64 + { 65 + if (!soc_device_match(r8a7795es1)) 66 + rcar_sysc_nullify(r8a7795_areas, ARRAY_SIZE(r8a7795_areas), 67 + R8A7795_PD_A2VC0); 68 + 69 + return 0; 70 + } 71 + 55 72 const struct rcar_sysc_info r8a7795_sysc_info __initconst = { 73 + .init = r8a7795_sysc_init, 56 74 .areas = r8a7795_areas, 57 75 .num_areas = ARRAY_SIZE(r8a7795_areas), 58 76 };
+24 -1
drivers/soc/renesas/rcar-sysc.c
··· 2 2 * R-Car SYSC Power management support 3 3 * 4 4 * Copyright (C) 2014 Magnus Damm 5 - * Copyright (C) 2015-2016 Glider bvba 5 + * Copyright (C) 2015-2017 Glider bvba 6 6 * 7 7 * This file is subject to the terms and conditions of the GNU General Public 8 8 * License. See the file "COPYING" in the main directory of this archive ··· 334 334 335 335 info = match->data; 336 336 337 + if (info->init) { 338 + error = info->init(); 339 + if (error) 340 + return error; 341 + } 342 + 337 343 has_cpg_mstp = of_find_compatible_node(NULL, NULL, 338 344 "renesas,cpg-mstp-clocks"); 339 345 ··· 383 377 const struct rcar_sysc_area *area = &info->areas[i]; 384 378 struct rcar_sysc_pd *pd; 385 379 380 + if (!area->name) { 381 + /* Skip NULLified area */ 382 + continue; 383 + } 384 + 386 385 pd = kzalloc(sizeof(*pd) + strlen(area->name) + 1, GFP_KERNEL); 387 386 if (!pd) { 388 387 error = -ENOMEM; ··· 416 405 return error; 417 406 } 418 407 early_initcall(rcar_sysc_pd_init); 408 + 409 + void __init rcar_sysc_nullify(struct rcar_sysc_area *areas, 410 + unsigned int num_areas, u8 id) 411 + { 412 + unsigned int i; 413 + 414 + for (i = 0; i < num_areas; i++) 415 + if (areas[i].isr_bit == id) { 416 + areas[i].name = NULL; 417 + return; 418 + } 419 + } 419 420 420 421 void __init rcar_sysc_init(phys_addr_t base, u32 syscier) 421 422 {
+10
drivers/soc/renesas/rcar-sysc.h
··· 46 46 */ 47 47 48 48 struct rcar_sysc_info { 49 + int (*init)(void); /* Optional */ 49 50 const struct rcar_sysc_area *areas; 50 51 unsigned int num_areas; 51 52 }; ··· 60 59 extern const struct rcar_sysc_info r8a7794_sysc_info; 61 60 extern const struct rcar_sysc_info r8a7795_sysc_info; 62 61 extern const struct rcar_sysc_info r8a7796_sysc_info; 62 + 63 + 64 + /* 65 + * Helpers for fixing up power area tables depending on SoC revision 66 + */ 67 + 68 + extern void rcar_sysc_nullify(struct rcar_sysc_area *areas, 69 + unsigned int num_areas, u8 id); 70 + 63 71 #endif /* __SOC_RENESAS_RCAR_SYSC_H__ */
+17 -1
drivers/soc/renesas/renesas-soc.c
··· 80 80 .id = 0x40, 81 81 }; 82 82 83 + static const struct renesas_soc soc_rz_g1h __initconst __maybe_unused = { 84 + .family = &fam_rzg, 85 + .id = 0x45, 86 + }; 87 + 83 88 static const struct renesas_soc soc_rz_g1m __initconst __maybe_unused = { 84 89 .family = &fam_rzg, 85 90 .id = 0x47, 91 + }; 92 + 93 + static const struct renesas_soc soc_rz_g1n __initconst __maybe_unused = { 94 + .family = &fam_rzg, 95 + .id = 0x4b, 86 96 }; 87 97 88 98 static const struct renesas_soc soc_rz_g1e __initconst __maybe_unused = { ··· 160 150 #ifdef CONFIG_ARCH_R8A7740 161 151 { .compatible = "renesas,r8a7740", .data = &soc_rmobile_a1 }, 162 152 #endif 153 + #ifdef CONFIG_ARCH_R8A7742 154 + { .compatible = "renesas,r8a7742", .data = &soc_rz_g1h }, 155 + #endif 163 156 #ifdef CONFIG_ARCH_R8A7743 164 157 { .compatible = "renesas,r8a7743", .data = &soc_rz_g1m }, 158 + #endif 159 + #ifdef CONFIG_ARCH_R8A7744 160 + { .compatible = "renesas,r8a7744", .data = &soc_rz_g1n }, 165 161 #endif 166 162 #ifdef CONFIG_ARCH_R8A7745 167 163 { .compatible = "renesas,r8a7745", .data = &soc_rz_g1e }, ··· 270 254 271 255 return 0; 272 256 } 273 - core_initcall(renesas_soc_init); 257 + early_initcall(renesas_soc_init);
+7 -1
drivers/soc/samsung/Kconfig
··· 8 8 9 9 config EXYNOS_PMU 10 10 bool "Exynos PMU controller driver" if COMPILE_TEST 11 - depends on (ARM && ARCH_EXYNOS) || ((ARM || ARM64) && COMPILE_TEST) 11 + depends on ARCH_EXYNOS || ((ARM || ARM64) && COMPILE_TEST) 12 + select EXYNOS_PMU_ARM_DRIVERS if ARM && ARCH_EXYNOS 13 + 14 + # There is no need to enable these drivers for ARMv8 15 + config EXYNOS_PMU_ARM_DRIVERS 16 + bool "Exynos PMU ARMv7-specific driver extensions" if COMPILE_TEST 17 + depends on EXYNOS_PMU 12 18 13 19 config EXYNOS_PM_DOMAINS 14 20 bool "Exynos PM domains" if COMPILE_TEST
+3 -1
drivers/soc/samsung/Makefile
··· 1 - obj-$(CONFIG_EXYNOS_PMU) += exynos-pmu.o exynos3250-pmu.o exynos4-pmu.o \ 1 + obj-$(CONFIG_EXYNOS_PMU) += exynos-pmu.o 2 + 3 + obj-$(CONFIG_EXYNOS_PMU_ARM_DRIVERS) += exynos3250-pmu.o exynos4-pmu.o \ 2 4 exynos5250-pmu.o exynos5420-pmu.o 3 5 obj-$(CONFIG_EXYNOS_PM_DOMAINS) += pm_domains.o
+16 -6
drivers/soc/samsung/exynos-pmu.c
··· 69 69 } 70 70 71 71 /* 72 + * Split the data between ARM architectures because it is relatively big 73 + * and useless on other arch. 74 + */ 75 + #ifdef CONFIG_EXYNOS_PMU_ARM_DRIVERS 76 + #define exynos_pmu_data_arm_ptr(data) (&data) 77 + #else 78 + #define exynos_pmu_data_arm_ptr(data) NULL 79 + #endif 80 + 81 + /* 72 82 * PMU platform driver and devicetree bindings. 73 83 */ 74 84 static const struct of_device_id exynos_pmu_of_device_ids[] = { 75 85 { 76 86 .compatible = "samsung,exynos3250-pmu", 77 - .data = &exynos3250_pmu_data, 87 + .data = exynos_pmu_data_arm_ptr(exynos3250_pmu_data), 78 88 }, { 79 89 .compatible = "samsung,exynos4210-pmu", 80 - .data = &exynos4210_pmu_data, 90 + .data = exynos_pmu_data_arm_ptr(exynos4210_pmu_data), 81 91 }, { 82 92 .compatible = "samsung,exynos4212-pmu", 83 - .data = &exynos4212_pmu_data, 93 + .data = exynos_pmu_data_arm_ptr(exynos4212_pmu_data), 84 94 }, { 85 95 .compatible = "samsung,exynos4412-pmu", 86 - .data = &exynos4412_pmu_data, 96 + .data = exynos_pmu_data_arm_ptr(exynos4412_pmu_data), 87 97 }, { 88 98 .compatible = "samsung,exynos5250-pmu", 89 - .data = &exynos5250_pmu_data, 99 + .data = exynos_pmu_data_arm_ptr(exynos5250_pmu_data), 90 100 }, { 91 101 .compatible = "samsung,exynos5420-pmu", 92 - .data = &exynos5420_pmu_data, 102 + .data = exynos_pmu_data_arm_ptr(exynos5420_pmu_data), 93 103 }, { 94 104 .compatible = "samsung,exynos5433-pmu", 95 105 },
+3
drivers/soc/samsung/exynos-pmu.h
··· 31 31 }; 32 32 33 33 extern void __iomem *pmu_base_addr; 34 + 35 + #ifdef CONFIG_EXYNOS_PMU_ARM_DRIVERS 34 36 /* list of all exported SoC specific data */ 35 37 extern const struct exynos_pmu_data exynos3250_pmu_data; 36 38 extern const struct exynos_pmu_data exynos4210_pmu_data; ··· 40 38 extern const struct exynos_pmu_data exynos4412_pmu_data; 41 39 extern const struct exynos_pmu_data exynos5250_pmu_data; 42 40 extern const struct exynos_pmu_data exynos5420_pmu_data; 41 + #endif 43 42 44 43 extern void pmu_raw_writel(u32 val, u32 offset); 45 44 extern u32 pmu_raw_readl(u32 offset);
+22
drivers/soc/tegra/Kconfig
··· 12 12 select PINCTRL_TEGRA20 13 13 select PL310_ERRATA_727915 if CACHE_L2X0 14 14 select PL310_ERRATA_769419 if CACHE_L2X0 15 + select SOC_TEGRA_FLOWCTRL 16 + select SOC_TEGRA_PMC 15 17 select TEGRA_TIMER 16 18 help 17 19 Support for NVIDIA Tegra AP20 and T20 processors, based on the ··· 25 23 select ARM_ERRATA_764369 if SMP 26 24 select PINCTRL_TEGRA30 27 25 select PL310_ERRATA_769419 if CACHE_L2X0 26 + select SOC_TEGRA_FLOWCTRL 27 + select SOC_TEGRA_PMC 28 28 select TEGRA_TIMER 29 29 help 30 30 Support for NVIDIA Tegra T30 processor family, based on the ··· 37 33 select ARM_ERRATA_798181 if SMP 38 34 select HAVE_ARM_ARCH_TIMER 39 35 select PINCTRL_TEGRA114 36 + select SOC_TEGRA_FLOWCTRL 37 + select SOC_TEGRA_PMC 40 38 select TEGRA_TIMER 41 39 help 42 40 Support for NVIDIA Tegra T114 processor family, based on the ··· 48 42 bool "Enable support for Tegra124 family" 49 43 select HAVE_ARM_ARCH_TIMER 50 44 select PINCTRL_TEGRA124 45 + select SOC_TEGRA_FLOWCTRL 46 + select SOC_TEGRA_PMC 51 47 select TEGRA_TIMER 52 48 help 53 49 Support for NVIDIA Tegra T124 processor family, based on the ··· 63 55 config ARCH_TEGRA_132_SOC 64 56 bool "NVIDIA Tegra132 SoC" 65 57 select PINCTRL_TEGRA124 58 + select SOC_TEGRA_FLOWCTRL 59 + select SOC_TEGRA_PMC 66 60 help 67 61 Enable support for NVIDIA Tegra132 SoC, based on the Denver 68 62 ARMv8 CPU. The Tegra132 SoC is similar to the Tegra124 SoC, ··· 74 64 config ARCH_TEGRA_210_SOC 75 65 bool "NVIDIA Tegra210 SoC" 76 66 select PINCTRL_TEGRA210 67 + select SOC_TEGRA_FLOWCTRL 68 + select SOC_TEGRA_PMC 77 69 help 78 70 Enable support for the NVIDIA Tegra210 SoC. Also known as Tegra X1, 79 71 the Tegra210 has four Cortex-A57 cores paired with four Cortex-A53 ··· 95 83 select TEGRA_BPMP 96 84 select TEGRA_HSP_MBOX 97 85 select TEGRA_IVC 86 + select SOC_TEGRA_PMC_TEGRA186 98 87 help 99 88 Enable support for the NVIDIA Tegar186 SoC. The Tegra186 features a 100 89 combination of Denver and Cortex-A57 CPU cores and a GPU based on ··· 106 93 107 94 endif 108 95 endif 96 + 97 + config SOC_TEGRA_FLOWCTRL 98 + bool 99 + 100 + config SOC_TEGRA_PMC 101 + bool 102 + 103 + config SOC_TEGRA_PMC_TEGRA186 104 + bool
+3 -1
drivers/soc/tegra/Makefile
··· 1 1 obj-y += fuse/ 2 2 3 3 obj-y += common.o 4 - obj-y += pmc.o 4 + obj-$(CONFIG_SOC_TEGRA_FLOWCTRL) += flowctrl.o 5 + obj-$(CONFIG_SOC_TEGRA_PMC) += pmc.o 6 + obj-$(CONFIG_SOC_TEGRA_PMC_TEGRA186) += pmc-tegra186.o
+2 -2
drivers/soc/tegra/fuse/fuse-tegra.c
··· 18 18 #include <linux/clk.h> 19 19 #include <linux/device.h> 20 20 #include <linux/kobject.h> 21 - #include <linux/module.h> 21 + #include <linux/init.h> 22 22 #include <linux/platform_device.h> 23 23 #include <linux/of.h> 24 24 #include <linux/of_address.h> ··· 168 168 }, 169 169 .probe = tegra_fuse_probe, 170 170 }; 171 - module_platform_driver(tegra_fuse_driver); 171 + builtin_platform_driver(tegra_fuse_driver); 172 172 173 173 bool __init tegra_fuse_read_spare(unsigned int spare) 174 174 {
+169
drivers/soc/tegra/pmc-tegra186.c
··· 1 + /* 2 + * Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved. 3 + * 4 + * This program is free software; you can redistribute it and/or modify it 5 + * under the terms and conditions of the GNU General Public License, 6 + * version 2, as published by the Free Software Foundation. 7 + * 8 + * This program is distributed in the hope it will be useful, but WITHOUT 9 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 10 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 11 + * more details. 12 + */ 13 + 14 + #define pr_fmt(fmt) "tegra-pmc: " fmt 15 + 16 + #include <linux/io.h> 17 + #include <linux/module.h> 18 + #include <linux/of.h> 19 + #include <linux/platform_device.h> 20 + #include <linux/reboot.h> 21 + 22 + #include <asm/system_misc.h> 23 + 24 + #define PMC_CNTRL 0x000 25 + #define PMC_CNTRL_MAIN_RST BIT(4) 26 + 27 + #define PMC_RST_STATUS 0x070 28 + 29 + #define WAKE_AOWAKE_CTRL 0x4f4 30 + #define WAKE_AOWAKE_CTRL_INTR_POLARITY BIT(0) 31 + 32 + #define SCRATCH_SCRATCH0 0x2000 33 + #define SCRATCH_SCRATCH0_MODE_RECOVERY BIT(31) 34 + #define SCRATCH_SCRATCH0_MODE_BOOTLOADER BIT(30) 35 + #define SCRATCH_SCRATCH0_MODE_RCM BIT(1) 36 + #define SCRATCH_SCRATCH0_MODE_MASK (SCRATCH_SCRATCH0_MODE_RECOVERY | \ 37 + SCRATCH_SCRATCH0_MODE_BOOTLOADER | \ 38 + SCRATCH_SCRATCH0_MODE_RCM) 39 + 40 + struct tegra_pmc { 41 + struct device *dev; 42 + void __iomem *regs; 43 + void __iomem *wake; 44 + void __iomem *aotag; 45 + void __iomem *scratch; 46 + 47 + void (*system_restart)(enum reboot_mode mode, const char *cmd); 48 + struct notifier_block restart; 49 + }; 50 + 51 + static int tegra186_pmc_restart_notify(struct notifier_block *nb, 52 + unsigned long action, 53 + void *data) 54 + { 55 + struct tegra_pmc *pmc = container_of(nb, struct tegra_pmc, restart); 56 + const char *cmd = data; 57 + u32 value; 58 + 59 + value = readl(pmc->scratch + SCRATCH_SCRATCH0); 60 + value &= ~SCRATCH_SCRATCH0_MODE_MASK; 61 + 62 + if (cmd) { 63 + if (strcmp(cmd, "recovery") == 0) 64 + value |= SCRATCH_SCRATCH0_MODE_RECOVERY; 65 + 66 + if (strcmp(cmd, "bootloader") == 0) 67 + value |= SCRATCH_SCRATCH0_MODE_BOOTLOADER; 68 + 69 + if (strcmp(cmd, "forced-recovery") == 0) 70 + value |= SCRATCH_SCRATCH0_MODE_RCM; 71 + } 72 + 73 + writel(value, pmc->scratch + SCRATCH_SCRATCH0); 74 + 75 + /* 76 + * If available, call the system restart implementation that was 77 + * registered earlier (typically PSCI). 78 + */ 79 + if (pmc->system_restart) { 80 + pmc->system_restart(reboot_mode, cmd); 81 + return NOTIFY_DONE; 82 + } 83 + 84 + /* reset everything but SCRATCH0_SCRATCH0 and PMC_RST_STATUS */ 85 + value = readl(pmc->regs + PMC_CNTRL); 86 + value |= PMC_CNTRL_MAIN_RST; 87 + writel(value, pmc->regs + PMC_CNTRL); 88 + 89 + return NOTIFY_DONE; 90 + } 91 + 92 + static int tegra186_pmc_setup(struct tegra_pmc *pmc) 93 + { 94 + struct device_node *np = pmc->dev->of_node; 95 + bool invert; 96 + u32 value; 97 + 98 + invert = of_property_read_bool(np, "nvidia,invert-interrupt"); 99 + 100 + value = readl(pmc->wake + WAKE_AOWAKE_CTRL); 101 + 102 + if (invert) 103 + value |= WAKE_AOWAKE_CTRL_INTR_POLARITY; 104 + else 105 + value &= ~WAKE_AOWAKE_CTRL_INTR_POLARITY; 106 + 107 + writel(value, pmc->wake + WAKE_AOWAKE_CTRL); 108 + 109 + /* 110 + * We need to hook any system restart implementation registered 111 + * previously so we can write SCRATCH_SCRATCH0 before reset. 112 + */ 113 + pmc->system_restart = arm_pm_restart; 114 + arm_pm_restart = NULL; 115 + 116 + pmc->restart.notifier_call = tegra186_pmc_restart_notify; 117 + pmc->restart.priority = 128; 118 + 119 + return register_restart_handler(&pmc->restart); 120 + } 121 + 122 + static int tegra186_pmc_probe(struct platform_device *pdev) 123 + { 124 + struct tegra_pmc *pmc; 125 + struct resource *res; 126 + 127 + pmc = devm_kzalloc(&pdev->dev, sizeof(*pmc), GFP_KERNEL); 128 + if (!pmc) 129 + return -ENOMEM; 130 + 131 + pmc->dev = &pdev->dev; 132 + 133 + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "pmc"); 134 + pmc->regs = devm_ioremap_resource(&pdev->dev, res); 135 + if (IS_ERR(pmc->regs)) 136 + return PTR_ERR(pmc->regs); 137 + 138 + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "wake"); 139 + pmc->wake = devm_ioremap_resource(&pdev->dev, res); 140 + if (IS_ERR(pmc->wake)) 141 + return PTR_ERR(pmc->wake); 142 + 143 + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "aotag"); 144 + pmc->aotag = devm_ioremap_resource(&pdev->dev, res); 145 + if (IS_ERR(pmc->aotag)) 146 + return PTR_ERR(pmc->aotag); 147 + 148 + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "scratch"); 149 + pmc->scratch = devm_ioremap_resource(&pdev->dev, res); 150 + if (IS_ERR(pmc->scratch)) 151 + return PTR_ERR(pmc->scratch); 152 + 153 + return tegra186_pmc_setup(pmc); 154 + } 155 + 156 + static const struct of_device_id tegra186_pmc_of_match[] = { 157 + { .compatible = "nvidia,tegra186-pmc" }, 158 + { /* sentinel */ } 159 + }; 160 + MODULE_DEVICE_TABLE(of, tegra186_pmc_of_match); 161 + 162 + static struct platform_driver tegra186_pmc_driver = { 163 + .driver = { 164 + .name = "tegra186-pmc", 165 + .of_match_table = tegra186_pmc_of_match, 166 + }, 167 + .probe = tegra186_pmc_probe, 168 + }; 169 + builtin_platform_driver(tegra186_pmc_driver);
+12
drivers/soc/ti/Kconfig
··· 38 38 to communicate and use the Wakeup M3 for PM features like suspend 39 39 resume and boots it using wkup_m3_rproc driver. 40 40 41 + config TI_SCI_PM_DOMAINS 42 + tristate "TI SCI PM Domains Driver" 43 + depends on TI_SCI_PROTOCOL 44 + depends on PM_GENERIC_DOMAINS 45 + help 46 + Generic power domain implementation for TI device implementing 47 + the TI SCI protocol. 48 + 49 + To compile this as a module, choose M here. The module will be 50 + called ti_sci_pm_domains. Note this is needed early in boot before 51 + rootfs may be available. 52 + 41 53 endif # SOC_TI
+1
drivers/soc/ti/Makefile
··· 5 5 knav_qmss-y := knav_qmss_queue.o knav_qmss_acc.o 6 6 obj-$(CONFIG_KEYSTONE_NAVIGATOR_DMA) += knav_dma.o 7 7 obj-$(CONFIG_WKUP_M3_IPC) += wkup_m3_ipc.o 8 + obj-$(CONFIG_TI_SCI_PM_DOMAINS) += ti_sci_pm_domains.o
+202
drivers/soc/ti/ti_sci_pm_domains.c
··· 1 + /* 2 + * TI SCI Generic Power Domain Driver 3 + * 4 + * Copyright (C) 2015-2017 Texas Instruments Incorporated - http://www.ti.com/ 5 + * J Keerthy <j-keerthy@ti.com> 6 + * Dave Gerlach <d-gerlach@ti.com> 7 + * 8 + * This program is free software; you can redistribute it and/or 9 + * modify it under the terms of the GNU General Public License 10 + * version 2 as published by the Free Software Foundation. 11 + * 12 + * This program is distributed in the hope that it will be useful, 13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 + * GNU General Public License for more details. 16 + */ 17 + 18 + #include <linux/err.h> 19 + #include <linux/module.h> 20 + #include <linux/mutex.h> 21 + #include <linux/of.h> 22 + #include <linux/platform_device.h> 23 + #include <linux/pm_domain.h> 24 + #include <linux/slab.h> 25 + #include <linux/soc/ti/ti_sci_protocol.h> 26 + 27 + /** 28 + * struct ti_sci_genpd_dev_data: holds data needed for every device attached 29 + * to this genpd 30 + * @idx: index of the device that identifies it with the system 31 + * control processor. 32 + */ 33 + struct ti_sci_genpd_dev_data { 34 + int idx; 35 + }; 36 + 37 + /** 38 + * struct ti_sci_pm_domain: TI specific data needed for power domain 39 + * @ti_sci: handle to TI SCI protocol driver that provides ops to 40 + * communicate with system control processor. 41 + * @dev: pointer to dev for the driver for devm allocs 42 + * @pd: generic_pm_domain for use with the genpd framework 43 + */ 44 + struct ti_sci_pm_domain { 45 + const struct ti_sci_handle *ti_sci; 46 + struct device *dev; 47 + struct generic_pm_domain pd; 48 + }; 49 + 50 + #define genpd_to_ti_sci_pd(gpd) container_of(gpd, struct ti_sci_pm_domain, pd) 51 + 52 + /** 53 + * ti_sci_dev_id(): get prepopulated ti_sci id from struct dev 54 + * @dev: pointer to device associated with this genpd 55 + * 56 + * Returns device_id stored from ti,sci_id property 57 + */ 58 + static int ti_sci_dev_id(struct device *dev) 59 + { 60 + struct generic_pm_domain_data *genpd_data = dev_gpd_data(dev); 61 + struct ti_sci_genpd_dev_data *sci_dev_data = genpd_data->data; 62 + 63 + return sci_dev_data->idx; 64 + } 65 + 66 + /** 67 + * ti_sci_dev_to_sci_handle(): get pointer to ti_sci_handle 68 + * @dev: pointer to device associated with this genpd 69 + * 70 + * Returns ti_sci_handle to be used to communicate with system 71 + * control processor. 72 + */ 73 + static const struct ti_sci_handle *ti_sci_dev_to_sci_handle(struct device *dev) 74 + { 75 + struct generic_pm_domain *pd = pd_to_genpd(dev->pm_domain); 76 + struct ti_sci_pm_domain *ti_sci_genpd = genpd_to_ti_sci_pd(pd); 77 + 78 + return ti_sci_genpd->ti_sci; 79 + } 80 + 81 + /** 82 + * ti_sci_dev_start(): genpd device start hook called to turn device on 83 + * @dev: pointer to device associated with this genpd to be powered on 84 + */ 85 + static int ti_sci_dev_start(struct device *dev) 86 + { 87 + const struct ti_sci_handle *ti_sci = ti_sci_dev_to_sci_handle(dev); 88 + int idx = ti_sci_dev_id(dev); 89 + 90 + return ti_sci->ops.dev_ops.get_device(ti_sci, idx); 91 + } 92 + 93 + /** 94 + * ti_sci_dev_stop(): genpd device stop hook called to turn device off 95 + * @dev: pointer to device associated with this genpd to be powered off 96 + */ 97 + static int ti_sci_dev_stop(struct device *dev) 98 + { 99 + const struct ti_sci_handle *ti_sci = ti_sci_dev_to_sci_handle(dev); 100 + int idx = ti_sci_dev_id(dev); 101 + 102 + return ti_sci->ops.dev_ops.put_device(ti_sci, idx); 103 + } 104 + 105 + static int ti_sci_pd_attach_dev(struct generic_pm_domain *domain, 106 + struct device *dev) 107 + { 108 + struct device_node *np = dev->of_node; 109 + struct of_phandle_args pd_args; 110 + struct ti_sci_pm_domain *ti_sci_genpd = genpd_to_ti_sci_pd(domain); 111 + const struct ti_sci_handle *ti_sci = ti_sci_genpd->ti_sci; 112 + struct ti_sci_genpd_dev_data *sci_dev_data; 113 + struct generic_pm_domain_data *genpd_data; 114 + int idx, ret = 0; 115 + 116 + ret = of_parse_phandle_with_args(np, "power-domains", 117 + "#power-domain-cells", 0, &pd_args); 118 + if (ret < 0) 119 + return ret; 120 + 121 + if (pd_args.args_count != 1) 122 + return -EINVAL; 123 + 124 + idx = pd_args.args[0]; 125 + 126 + /* 127 + * Check the validity of the requested idx, if the index is not valid 128 + * the PMMC will return a NAK here and we will not allocate it. 129 + */ 130 + ret = ti_sci->ops.dev_ops.is_valid(ti_sci, idx); 131 + if (ret) 132 + return -EINVAL; 133 + 134 + sci_dev_data = kzalloc(sizeof(*sci_dev_data), GFP_KERNEL); 135 + if (!sci_dev_data) 136 + return -ENOMEM; 137 + 138 + sci_dev_data->idx = idx; 139 + 140 + genpd_data = dev_gpd_data(dev); 141 + genpd_data->data = sci_dev_data; 142 + 143 + return 0; 144 + } 145 + 146 + static void ti_sci_pd_detach_dev(struct generic_pm_domain *domain, 147 + struct device *dev) 148 + { 149 + struct generic_pm_domain_data *genpd_data = dev_gpd_data(dev); 150 + struct ti_sci_genpd_dev_data *sci_dev_data = genpd_data->data; 151 + 152 + kfree(sci_dev_data); 153 + genpd_data->data = NULL; 154 + } 155 + 156 + static const struct of_device_id ti_sci_pm_domain_matches[] = { 157 + { .compatible = "ti,sci-pm-domain", }, 158 + { }, 159 + }; 160 + MODULE_DEVICE_TABLE(of, ti_sci_pm_domain_matches); 161 + 162 + static int ti_sci_pm_domain_probe(struct platform_device *pdev) 163 + { 164 + struct device *dev = &pdev->dev; 165 + struct device_node *np = dev->of_node; 166 + struct ti_sci_pm_domain *ti_sci_pd; 167 + int ret; 168 + 169 + ti_sci_pd = devm_kzalloc(dev, sizeof(*ti_sci_pd), GFP_KERNEL); 170 + if (!ti_sci_pd) 171 + return -ENOMEM; 172 + 173 + ti_sci_pd->ti_sci = devm_ti_sci_get_handle(dev); 174 + if (IS_ERR(ti_sci_pd->ti_sci)) 175 + return PTR_ERR(ti_sci_pd->ti_sci); 176 + 177 + ti_sci_pd->dev = dev; 178 + 179 + ti_sci_pd->pd.attach_dev = ti_sci_pd_attach_dev; 180 + ti_sci_pd->pd.detach_dev = ti_sci_pd_detach_dev; 181 + 182 + ti_sci_pd->pd.dev_ops.start = ti_sci_dev_start; 183 + ti_sci_pd->pd.dev_ops.stop = ti_sci_dev_stop; 184 + 185 + pm_genpd_init(&ti_sci_pd->pd, NULL, true); 186 + 187 + ret = of_genpd_add_provider_simple(np, &ti_sci_pd->pd); 188 + 189 + return ret; 190 + } 191 + 192 + static struct platform_driver ti_sci_pm_domains_driver = { 193 + .probe = ti_sci_pm_domain_probe, 194 + .driver = { 195 + .name = "ti_sci_pm_domains", 196 + .of_match_table = ti_sci_pm_domain_matches, 197 + }, 198 + }; 199 + module_platform_driver(ti_sci_pm_domains_driver); 200 + MODULE_LICENSE("GPL v2"); 201 + MODULE_DESCRIPTION("TI System Control Interface (SCI) Power Domain driver"); 202 + MODULE_AUTHOR("Dave Gerlach");
-1
drivers/soc/zte/zx296718_pm_domains.c
··· 169 169 static struct platform_driver zx296718_pd_driver = { 170 170 .driver = { 171 171 .name = "zx296718-powerdomain", 172 - .owner = THIS_MODULE, 173 172 .of_match_table = zx296718_pm_domain_matches, 174 173 }, 175 174 .probe = zx296718_pd_probe,
+1 -3
drivers/soc/zte/zx2967_pm_domains.c
··· 125 125 126 126 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 127 127 pcubase = devm_ioremap_resource(&pdev->dev, res); 128 - if (IS_ERR(pcubase)) { 129 - dev_err(&pdev->dev, "ioremap fail.\n"); 128 + if (IS_ERR(pcubase)) 130 129 return PTR_ERR(pcubase); 131 - } 132 130 133 131 for (i = 0; i < domain_num; ++i) { 134 132 zx_pm_domains[i]->power_on = zx2967_power_on;
+90
include/dt-bindings/genpd/k2g.h
··· 1 + /* 2 + * TI K2G SoC Device definitions 3 + * 4 + * Copyright (C) 2015-2017 Texas Instruments Incorporated - http://www.ti.com/ 5 + * 6 + * This program is free software; you can redistribute it and/or modify 7 + * it under the terms of the GNU General Public License as published by 8 + * the Free Software Foundation; either version 2 of the License, or 9 + * (at your option) any later version. 10 + * 11 + * This program is distributed in the hope that it will be useful, 12 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 + * GNU General Public License for more details. 15 + */ 16 + 17 + #ifndef _DT_BINDINGS_GENPD_K2G_H 18 + #define _DT_BINDINGS_GENPD_K2G_H 19 + 20 + /* Documented in http://processors.wiki.ti.com/index.php/TISCI */ 21 + 22 + #define K2G_DEV_PMMC0 0x0000 23 + #define K2G_DEV_MLB0 0x0001 24 + #define K2G_DEV_DSS0 0x0002 25 + #define K2G_DEV_MCBSP0 0x0003 26 + #define K2G_DEV_MCASP0 0x0004 27 + #define K2G_DEV_MCASP1 0x0005 28 + #define K2G_DEV_MCASP2 0x0006 29 + #define K2G_DEV_DCAN0 0x0008 30 + #define K2G_DEV_DCAN1 0x0009 31 + #define K2G_DEV_EMIF0 0x000a 32 + #define K2G_DEV_MMCHS0 0x000b 33 + #define K2G_DEV_MMCHS1 0x000c 34 + #define K2G_DEV_GPMC0 0x000d 35 + #define K2G_DEV_ELM0 0x000e 36 + #define K2G_DEV_SPI0 0x0010 37 + #define K2G_DEV_SPI1 0x0011 38 + #define K2G_DEV_SPI2 0x0012 39 + #define K2G_DEV_SPI3 0x0013 40 + #define K2G_DEV_ICSS0 0x0014 41 + #define K2G_DEV_ICSS1 0x0015 42 + #define K2G_DEV_USB0 0x0016 43 + #define K2G_DEV_USB1 0x0017 44 + #define K2G_DEV_NSS0 0x0018 45 + #define K2G_DEV_PCIE0 0x0019 46 + #define K2G_DEV_GPIO0 0x001b 47 + #define K2G_DEV_GPIO1 0x001c 48 + #define K2G_DEV_TIMER64_0 0x001d 49 + #define K2G_DEV_TIMER64_1 0x001e 50 + #define K2G_DEV_TIMER64_2 0x001f 51 + #define K2G_DEV_TIMER64_3 0x0020 52 + #define K2G_DEV_TIMER64_4 0x0021 53 + #define K2G_DEV_TIMER64_5 0x0022 54 + #define K2G_DEV_TIMER64_6 0x0023 55 + #define K2G_DEV_MSGMGR0 0x0025 56 + #define K2G_DEV_BOOTCFG0 0x0026 57 + #define K2G_DEV_ARM_BOOTROM0 0x0027 58 + #define K2G_DEV_DSP_BOOTROM0 0x0029 59 + #define K2G_DEV_DEBUGSS0 0x002b 60 + #define K2G_DEV_UART0 0x002c 61 + #define K2G_DEV_UART1 0x002d 62 + #define K2G_DEV_UART2 0x002e 63 + #define K2G_DEV_EHRPWM0 0x002f 64 + #define K2G_DEV_EHRPWM1 0x0030 65 + #define K2G_DEV_EHRPWM2 0x0031 66 + #define K2G_DEV_EHRPWM3 0x0032 67 + #define K2G_DEV_EHRPWM4 0x0033 68 + #define K2G_DEV_EHRPWM5 0x0034 69 + #define K2G_DEV_EQEP0 0x0035 70 + #define K2G_DEV_EQEP1 0x0036 71 + #define K2G_DEV_EQEP2 0x0037 72 + #define K2G_DEV_ECAP0 0x0038 73 + #define K2G_DEV_ECAP1 0x0039 74 + #define K2G_DEV_I2C0 0x003a 75 + #define K2G_DEV_I2C1 0x003b 76 + #define K2G_DEV_I2C2 0x003c 77 + #define K2G_DEV_EDMA0 0x003f 78 + #define K2G_DEV_SEMAPHORE0 0x0040 79 + #define K2G_DEV_INTC0 0x0041 80 + #define K2G_DEV_GIC0 0x0042 81 + #define K2G_DEV_QSPI0 0x0043 82 + #define K2G_DEV_ARM_64B_COUNTER0 0x0044 83 + #define K2G_DEV_TETRIS0 0x0045 84 + #define K2G_DEV_CGEM0 0x0046 85 + #define K2G_DEV_MSMC0 0x0047 86 + #define K2G_DEV_CBASS0 0x0049 87 + #define K2G_DEV_BOARD0 0x004c 88 + #define K2G_DEV_EDMA1 0x004f 89 + 90 + #endif
+16
include/dt-bindings/power/imx7-power.h
··· 1 + /* 2 + * Copyright (C) 2017 Impinj 3 + * 4 + * This program is free software; you can redistribute it and/or modify 5 + * it under the terms of the GNU General Public License version 2 as 6 + * published by the Free Software Foundation. 7 + */ 8 + 9 + #ifndef __DT_BINDINGS_IMX7_POWER_H__ 10 + #define __DT_BINDINGS_IMX7_POWER_H__ 11 + 12 + #define IMX7_POWER_DOMAIN_MIPI_PHY 0 13 + #define IMX7_POWER_DOMAIN_PCIE_PHY 1 14 + #define IMX7_POWER_DOMAIN_USB_HSIC_PHY 2 15 + 16 + #endif
+1 -1
include/dt-bindings/power/r8a7795-sysc.h
··· 33 33 #define R8A7795_PD_CA53_SCU 21 34 34 #define R8A7795_PD_3DG_E 22 35 35 #define R8A7795_PD_A3IR 24 36 - #define R8A7795_PD_A2VC0 25 36 + #define R8A7795_PD_A2VC0 25 /* ES1.x only */ 37 37 #define R8A7795_PD_A2VC1 26 38 38 39 39 /* Always-on power area */
+33
include/dt-bindings/reset/altr,rst-mgr-a10sr.h
··· 1 + /* 2 + * Copyright Intel Corporation (C) 2017. All Rights Reserved 3 + * 4 + * This program is free software; you can redistribute it and/or modify it 5 + * under the terms and conditions of the GNU General Public License, 6 + * version 2, as published by the Free Software Foundation. 7 + * 8 + * This program is distributed in the hope it will be useful, but WITHOUT 9 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 10 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 11 + * more details. 12 + * 13 + * You should have received a copy of the GNU General Public License along with 14 + * this program. If not, see <http://www.gnu.org/licenses/>. 15 + * 16 + * Reset binding definitions for Altera Arria10 MAX5 System Resource Chip 17 + * 18 + * Adapted from altr,rst-mgr-a10.h 19 + */ 20 + 21 + #ifndef _DT_BINDINGS_RESET_ALTR_RST_MGR_A10SR_H 22 + #define _DT_BINDINGS_RESET_ALTR_RST_MGR_A10SR_H 23 + 24 + /* Peripheral PHY resets */ 25 + #define A10SR_RESET_ENET_HPS 0 26 + #define A10SR_RESET_PCIE 1 27 + #define A10SR_RESET_FILE 2 28 + #define A10SR_RESET_BQSPI 3 29 + #define A10SR_RESET_USB 4 30 + 31 + #define A10SR_RESET_NUM 5 32 + 33 + #endif
+62
include/dt-bindings/reset/imx7-reset.h
··· 1 + /* 2 + * Copyright (C) 2017 Impinj, Inc. 3 + * 4 + * Author: Andrey Smirnov <andrew.smirnov@gmail.com> 5 + * 6 + * This program is free software; you can redistribute it and/or modify it 7 + * under the terms and conditions of the GNU General Public License, 8 + * version 2, as published by the Free Software Foundation. 9 + * 10 + * This program is distributed in the hope it will be useful, but WITHOUT 11 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 12 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 13 + * more details. 14 + * 15 + * You should have received a copy of the GNU General Public License 16 + * along with this program. If not, see <http://www.gnu.org/licenses/>. 17 + */ 18 + 19 + #ifndef DT_BINDING_RESET_IMX7_H 20 + #define DT_BINDING_RESET_IMX7_H 21 + 22 + #define IMX7_RESET_A7_CORE_POR_RESET0 0 23 + #define IMX7_RESET_A7_CORE_POR_RESET1 1 24 + #define IMX7_RESET_A7_CORE_RESET0 2 25 + #define IMX7_RESET_A7_CORE_RESET1 3 26 + #define IMX7_RESET_A7_DBG_RESET0 4 27 + #define IMX7_RESET_A7_DBG_RESET1 5 28 + #define IMX7_RESET_A7_ETM_RESET0 6 29 + #define IMX7_RESET_A7_ETM_RESET1 7 30 + #define IMX7_RESET_A7_SOC_DBG_RESET 8 31 + #define IMX7_RESET_A7_L2RESET 9 32 + #define IMX7_RESET_SW_M4C_RST 10 33 + #define IMX7_RESET_SW_M4P_RST 11 34 + #define IMX7_RESET_EIM_RST 12 35 + #define IMX7_RESET_HSICPHY_PORT_RST 13 36 + #define IMX7_RESET_USBPHY1_POR 14 37 + #define IMX7_RESET_USBPHY1_PORT_RST 15 38 + #define IMX7_RESET_USBPHY2_POR 16 39 + #define IMX7_RESET_USBPHY2_PORT_RST 17 40 + #define IMX7_RESET_MIPI_PHY_MRST 18 41 + #define IMX7_RESET_MIPI_PHY_SRST 19 42 + 43 + /* 44 + * IMX7_RESET_PCIEPHY is a logical reset line combining PCIEPHY_BTN 45 + * and PCIEPHY_G_RST 46 + */ 47 + #define IMX7_RESET_PCIEPHY 20 48 + #define IMX7_RESET_PCIEPHY_PERST 21 49 + 50 + /* 51 + * IMX7_RESET_PCIE_CTRL_APPS_EN is not strictly a reset line, but it 52 + * can be used to inhibit PCIe LTTSM, so, in a way, it can be thoguht 53 + * of as one 54 + */ 55 + #define IMX7_RESET_PCIE_CTRL_APPS_EN 22 56 + #define IMX7_RESET_DDRC_PRST 23 57 + #define IMX7_RESET_DDRC_CORE_RST 24 58 + 59 + #define IMX7_RESET_NUM 25 60 + 61 + #endif 62 +
+2 -2
include/linux/firmware/meson/meson_sm.h
··· 25 25 u32 arg2, u32 arg3, u32 arg4); 26 26 int meson_sm_call_write(void *buffer, unsigned int b_size, unsigned int cmd_index, 27 27 u32 arg0, u32 arg1, u32 arg2, u32 arg3, u32 arg4); 28 - int meson_sm_call_read(void *buffer, unsigned int cmd_index, u32 arg0, u32 arg1, 29 - u32 arg2, u32 arg3, u32 arg4); 28 + int meson_sm_call_read(void *buffer, unsigned int bsize, unsigned int cmd_index, 29 + u32 arg0, u32 arg1, u32 arg2, u32 arg3, u32 arg4); 30 30 31 31 #endif /* _MESON_SM_FW_H_ */
+1
include/linux/pm_domain.h
··· 118 118 struct pm_domain_data base; 119 119 struct gpd_timing_data td; 120 120 struct notifier_block nb; 121 + void *data; 121 122 }; 122 123 123 124 #ifdef CONFIG_PM_GENERIC_DOMAINS
+6
include/linux/qcom_scm.h
··· 40 40 extern void qcom_scm_cpu_power_down(u32 flags); 41 41 extern u32 qcom_scm_get_version(void); 42 42 extern int qcom_scm_set_remote_state(u32 state, u32 id); 43 + extern int qcom_scm_restore_sec_cfg(u32 device_id, u32 spare); 44 + extern int qcom_scm_iommu_secure_ptbl_size(u32 spare, size_t *size); 45 + extern int qcom_scm_iommu_secure_ptbl_init(u64 addr, u32 size, u32 spare); 43 46 #else 44 47 static inline 45 48 int qcom_scm_set_cold_boot_addr(void *entry, const cpumask_t *cpus) ··· 70 67 static inline u32 qcom_scm_get_version(void) { return 0; } 71 68 static inline u32 72 69 qcom_scm_set_remote_state(u32 state,u32 id) { return -ENODEV; } 70 + static inline int qcom_scm_restore_sec_cfg(u32 device_id, u32 spare) { return -ENODEV; } 71 + static inline int qcom_scm_iommu_secure_ptbl_size(u32 spare, size_t *size) { return -ENODEV; } 72 + static inline int qcom_scm_iommu_secure_ptbl_init(u64 addr, u32 size, u32 spare) { return -ENODEV; } 73 73 #endif 74 74 #endif
+21 -8
include/soc/tegra/pmc.h
··· 26 26 struct clk; 27 27 struct reset_control; 28 28 29 - #ifdef CONFIG_PM_SLEEP 30 - enum tegra_suspend_mode tegra_pmc_get_suspend_mode(void); 31 - void tegra_pmc_set_suspend_mode(enum tegra_suspend_mode mode); 32 - void tegra_pmc_enter_suspend_mode(enum tegra_suspend_mode mode); 33 - #endif /* CONFIG_PM_SLEEP */ 34 - 35 29 #ifdef CONFIG_SMP 36 30 bool tegra_pmc_cpu_is_powered(unsigned int cpuid); 37 31 int tegra_pmc_cpu_power_on(unsigned int cpuid); ··· 138 144 TEGRA_IO_PAD_3300000UV, 139 145 }; 140 146 141 - #ifdef CONFIG_ARCH_TEGRA 147 + #ifdef CONFIG_SOC_TEGRA_PMC 142 148 int tegra_powergate_is_powered(unsigned int id); 143 149 int tegra_powergate_power_on(unsigned int id); 144 150 int tegra_powergate_power_off(unsigned int id); ··· 157 163 /* deprecated, use tegra_io_pad_power_{enable,disable}() instead */ 158 164 int tegra_io_rail_power_on(unsigned int id); 159 165 int tegra_io_rail_power_off(unsigned int id); 166 + 167 + enum tegra_suspend_mode tegra_pmc_get_suspend_mode(void); 168 + void tegra_pmc_set_suspend_mode(enum tegra_suspend_mode mode); 169 + void tegra_pmc_enter_suspend_mode(enum tegra_suspend_mode mode); 170 + 160 171 #else 161 172 static inline int tegra_powergate_is_powered(unsigned int id) 162 173 { ··· 220 221 { 221 222 return -ENOSYS; 222 223 } 223 - #endif /* CONFIG_ARCH_TEGRA */ 224 + 225 + static inline enum tegra_suspend_mode tegra_pmc_get_suspend_mode(void) 226 + { 227 + return TEGRA_SUSPEND_NONE; 228 + } 229 + 230 + static inline void tegra_pmc_set_suspend_mode(enum tegra_suspend_mode mode) 231 + { 232 + } 233 + 234 + static inline void tegra_pmc_enter_suspend_mode(enum tegra_suspend_mode mode) 235 + { 236 + } 237 + 238 + #endif /* CONFIG_SOC_TEGRA_PMC */ 224 239 225 240 #endif /* __SOC_TEGRA_PMC_H__ */