Merge tag 'armsoc-drivers' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc
authorLinus Torvalds <torvalds@linux-foundation.org>
Mon, 11 Sep 2017 03:40:00 +0000 (20:40 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Mon, 11 Sep 2017 03:40:00 +0000 (20:40 -0700)
Pull ARM SoC driver updates from Olof Johansson:
 "This branch contains platform-related driver updates for ARM and ARM64.

  Among them:

   - Reset driver updates:
     + New API for dealing with arrays of resets
     + Make unimplemented {de,}assert return success on shared resets
     + MSDKv1 driver
     + Removal of obsolete Gemini reset driver
     + Misc updates for sunxi and Uniphier

   - SoC drivers:
     + Platform SoC driver registration on Tegra
     + Shuffle of Qualcomm drivers into a submenu
     + Allwinner A64 support for SRAM
     + Renesas R-Car R3 support
     + Power domains for Rockchip RK3366

   - Misc updates and smaller fixes for TEE and memory driver
     subsystems"

* tag 'armsoc-drivers' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc: (54 commits)
  firmware: arm_scpi: fix endianness of dev_id in struct dev_pstate_set
  soc/tegra: fuse: Add missing semi-colon
  soc/tegra: Restrict SoC device registration to Tegra
  drivers: soc: sunxi: add support for A64 and its SRAM C
  drivers: soc: sunxi: add support for remapping func value to reg value
  drivers: soc: sunxi: fix error processing on base address when claiming
  dt-bindings: add binding for Allwinner A64 SRAM controller and SRAM C
  bus: sunxi-rsb: Enable by default for ARM64
  soc/tegra: Register SoC device
  firmware: tegra: set drvdata earlier
  memory: Convert to using %pOF instead of full_name
  soc: Convert to using %pOF instead of full_name
  bus: Convert to using %pOF instead of full_name
  firmware: Convert to using %pOF instead of full_name
  soc: mediatek: add SCPSYS power domain driver for MediaTek MT7622 SoC
  soc: mediatek: add header files required for MT7622 SCPSYS dt-binding
  soc: mediatek: reduce code duplication of scpsys_probe across all SoCs
  dt-bindings: soc: update the binding document for SCPSYS on MediaTek MT7622 SoC
  reset: uniphier: add analog amplifiers reset control
  reset: uniphier: add video input subsystem reset control
  ...

74 files changed:
Documentation/devicetree/bindings/arm/amlogic.txt
Documentation/devicetree/bindings/power/renesas,rcar-sysc.txt
Documentation/devicetree/bindings/reset/renesas,rst.txt
Documentation/devicetree/bindings/reset/uniphier-reset.txt
Documentation/devicetree/bindings/soc/mediatek/scpsys.txt
Documentation/devicetree/bindings/soc/rockchip/power_domain.txt
Documentation/devicetree/bindings/sram/sunxi-sram.txt
MAINTAINERS
arch/arm/mach-mediatek/mediatek.c
arch/arm/mach-mediatek/platsmp.c
arch/arm/mach-tegra/tegra.c
drivers/bus/Kconfig
drivers/bus/arm-cci.c
drivers/bus/imx-weim.c
drivers/bus/sunxi-rsb.c
drivers/firmware/arm_scpi.c
drivers/firmware/psci.c
drivers/firmware/tegra/bpmp.c
drivers/memory/atmel-ebi.c
drivers/memory/jz4780-nemc.c
drivers/memory/mvebu-devbus.c
drivers/memory/omap-gpmc.c
drivers/reset/Kconfig
drivers/reset/Makefile
drivers/reset/core.c
drivers/reset/reset-gemini.c [deleted file]
drivers/reset/reset-hsdk-v1.c [new file with mode: 0644]
drivers/reset/reset-sunxi.c
drivers/reset/reset-uniphier.c
drivers/reset/reset-zx2967.c
drivers/soc/Kconfig
drivers/soc/Makefile
drivers/soc/amlogic/Kconfig [new file with mode: 0644]
drivers/soc/amlogic/Makefile [new file with mode: 0644]
drivers/soc/amlogic/meson-gx-socinfo.c [new file with mode: 0644]
drivers/soc/fsl/qbman/bman_ccsr.c
drivers/soc/fsl/qbman/bman_portal.c
drivers/soc/fsl/qbman/qman_ccsr.c
drivers/soc/fsl/qbman/qman_portal.c
drivers/soc/fsl/qe/gpio.c
drivers/soc/mediatek/mtk-pmic-wrap.c
drivers/soc/mediatek/mtk-scpsys.c
drivers/soc/qcom/Kconfig
drivers/soc/qcom/mdt_loader.c
drivers/soc/qcom/smsm.c
drivers/soc/qcom/wcnss_ctrl.c
drivers/soc/renesas/Kconfig
drivers/soc/renesas/Makefile
drivers/soc/renesas/r8a77995-sysc.c [new file with mode: 0644]
drivers/soc/renesas/rcar-rst.c
drivers/soc/renesas/rcar-sysc.c
drivers/soc/renesas/rcar-sysc.h
drivers/soc/renesas/renesas-soc.c
drivers/soc/rockchip/grf.c
drivers/soc/rockchip/pm_domains.c
drivers/soc/samsung/pm_domains.c
drivers/soc/sunxi/sunxi_sram.c
drivers/soc/tegra/Kconfig
drivers/soc/tegra/fuse/fuse-tegra.c
drivers/soc/tegra/pmc.c
drivers/tee/optee/core.c
drivers/tee/optee/optee_smc.h
drivers/tee/optee/rpc.c
drivers/tee/tee_core.c
drivers/tee/tee_shm.c
include/dt-bindings/power/mt7622-power.h [new file with mode: 0644]
include/dt-bindings/power/r8a77995-sysc.h [new file with mode: 0644]
include/dt-bindings/power/rk3366-power.h [new file with mode: 0644]
include/dt-bindings/reset/snps,hsdk-v1-reset.h [new file with mode: 0644]
include/linux/reset.h
include/linux/soc/mediatek/infracfg.h
include/linux/tee_drv.h
include/soc/tegra/fuse.h
include/uapi/linux/tee.h

index 0fff40a6330dd851f76424b88b4e116567f11b9e..520cdd2127cf8e864cc7975b0aab505922d88b13 100644 (file)
@@ -61,3 +61,32 @@ Board compatible values (alphabetically, grouped by SoC):
   - "amlogic,q201" (Meson gxm s912)
   - "kingnovel,r-box-pro" (Meson gxm S912)
   - "nexbox,a1" (Meson gxm s912)
+
+Amlogic Meson Firmware registers Interface
+------------------------------------------
+
+The Meson SoCs have a register bank with status and data shared with the
+secure firmware.
+
+Required properties:
+ - compatible: For Meson GX SoCs, must be "amlogic,meson-gx-ao-secure", "syscon"
+
+Properties should indentify components of this register interface :
+
+Meson GX SoC Information
+------------------------
+A firmware register encodes the SoC type, package and revision information on
+the Meson GX SoCs.
+If present, the following property should be added :
+
+Optional properties:
+  - amlogic,has-chip-id: If present, the interface gives the current SoC version.
+
+Example
+-------
+
+ao-secure@140 {
+       compatible = "amlogic,meson-gx-ao-secure", "syscon";
+       reg = <0x0 0x140 0x0 0x140>;
+       amlogic,has-chip-id;
+};
index d91715bc8d52c22e7f159b6bca96f35fa5a68111..98cc8c09d02d5d857992250fd61a0199359e5933 100644 (file)
@@ -17,6 +17,7 @@ Required properties:
       - "renesas,r8a7794-sysc" (R-Car E2)
       - "renesas,r8a7795-sysc" (R-Car H3)
       - "renesas,r8a7796-sysc" (R-Car M3-W)
+      - "renesas,r8a77995-sysc" (R-Car D3)
   - reg: Address start and address range for the device.
   - #power-domain-cells: Must be 1.
 
index fe5e0f37b3c935794428cbe950e50dde3628ac89..e5a03ffe04fb2af74ed41b7aa36aee284edc437a 100644 (file)
@@ -26,6 +26,7 @@ Required properties:
                  - "renesas,r8a7794-rst" (R-Car E2)
                  - "renesas,r8a7795-rst" (R-Car H3)
                  - "renesas,r8a7796-rst" (R-Car M3-W)
+                 - "renesas,r8a77995-rst" (R-Car D3)
   - reg: Address start and address range for the device.
 
 
index 83ab0f599c4090712bb4c8bd4f52d8a5d5701947..68a6f487c4092f205eb4cae09ca962195c15c06e 100644 (file)
@@ -6,7 +6,6 @@ System reset
 
 Required properties:
 - compatible: should be one of the following:
-    "socionext,uniphier-sld3-reset" - for sLD3 SoC
     "socionext,uniphier-ld4-reset"  - for LD4 SoC
     "socionext,uniphier-pro4-reset" - for Pro4 SoC
     "socionext,uniphier-sld8-reset" - for sLD8 SoC
@@ -37,7 +36,6 @@ Media I/O (MIO) reset, SD reset
 
 Required properties:
 - compatible: should be one of the following:
-    "socionext,uniphier-sld3-mio-reset" - for sLD3 SoC
     "socionext,uniphier-ld4-mio-reset"  - for LD4 SoC
     "socionext,uniphier-pro4-mio-reset" - for Pro4 SoC
     "socionext,uniphier-sld8-mio-reset" - for sLD8 SoC
@@ -92,3 +90,28 @@ Example:
 
                other nodes ...
        };
+
+
+Analog signal amplifier reset
+-----------------------------
+
+Required properties:
+- compatible: should be one of the following:
+    "socionext,uniphier-ld11-adamv-reset" - for LD11 SoC
+    "socionext,uniphier-ld20-adamv-reset" - for LD20 SoC
+- #reset-cells: should be 1.
+
+Example:
+
+       adamv@57920000 {
+               compatible = "socionext,uniphier-ld11-adamv",
+                            "simple-mfd", "syscon";
+               reg = <0x57920000 0x1000>;
+
+               adamv_rst: reset {
+                       compatible = "socionext,uniphier-ld11-adamv-reset";
+                       #reset-cells = <1>;
+               };
+
+               other nodes ...
+       };
index b1d165b4d4b31104e4c137c18ad8079ff66943e9..40056f7990f86f337296fe9bc13343c5c6b2f446 100644 (file)
@@ -12,11 +12,13 @@ power/power_domain.txt. It provides the power domains defined in
 - include/dt-bindings/power/mt8173-power.h
 - include/dt-bindings/power/mt6797-power.h
 - include/dt-bindings/power/mt2701-power.h
+- include/dt-bindings/power/mt7622-power.h
 
 Required properties:
 - compatible: Should be one of:
        - "mediatek,mt2701-scpsys"
        - "mediatek,mt6797-scpsys"
+       - "mediatek,mt7622-scpsys"
        - "mediatek,mt8173-scpsys"
 - #power-domain-cells: Must be 1
 - reg: Address range of the SCPSYS unit
@@ -26,6 +28,7 @@ Required properties:
                       enabled before enabling certain power domains.
        Required clocks for MT2701: "mm", "mfg", "ethif"
        Required clocks for MT6797: "mm", "mfg", "vdec"
+       Required clocks for MT7622: "hif_sel"
        Required clocks for MT8173: "mm", "mfg", "venc", "venc_lt"
 
 Optional properties:
index 01bfb6745fbd79d77251392beb719d22fe73aef2..301d2a9bc1b8bb2ab0e213e6656b03691c2c71e8 100644 (file)
@@ -7,6 +7,7 @@ Required properties for power domain controller:
 - compatible: Should be one of the following.
        "rockchip,rk3288-power-controller" - for RK3288 SoCs.
        "rockchip,rk3328-power-controller" - for RK3328 SoCs.
+       "rockchip,rk3366-power-controller" - for RK3366 SoCs.
        "rockchip,rk3368-power-controller" - for RK3368 SoCs.
        "rockchip,rk3399-power-controller" - for RK3399 SoCs.
 - #power-domain-cells: Number of cells in a power-domain specifier.
@@ -18,6 +19,7 @@ Required properties for power domain sub nodes:
 - reg: index of the power domain, should use macros in:
        "include/dt-bindings/power/rk3288-power.h" - for RK3288 type power domain.
        "include/dt-bindings/power/rk3328-power.h" - for RK3328 type power domain.
+       "include/dt-bindings/power/rk3366-power.h" - for RK3366 type power domain.
        "include/dt-bindings/power/rk3368-power.h" - for RK3368 type power domain.
        "include/dt-bindings/power/rk3399-power.h" - for RK3399 type power domain.
 - clocks (optional): phandles to clocks which need to be enabled while power domain
@@ -93,6 +95,7 @@ power domain to use.
 The index should use macros in:
        "include/dt-bindings/power/rk3288-power.h" - for rk3288 type power domain.
        "include/dt-bindings/power/rk3328-power.h" - for rk3328 type power domain.
+       "include/dt-bindings/power/rk3366-power.h" - for rk3366 type power domain.
        "include/dt-bindings/power/rk3368-power.h" - for rk3368 type power domain.
        "include/dt-bindings/power/rk3399-power.h" - for rk3399 type power domain.
 
index 170034e6c8b0e3927f5a4d8b41b3b8cc1ba8ec36..6bb92a1df753e5ae7b74f17b435a511210acbe19 100644 (file)
@@ -9,7 +9,9 @@ Controller Node
 ---------------
 
 Required properties:
-- compatible : "allwinner,sun4i-a10-sram-controller"
+- compatible : should be:
+    - "allwinner,sun4i-a10-sram-controller"
+    - "allwinner,sun50i-a64-sram-controller"
 - reg : sram controller register offset + length
 
 SRAM nodes
@@ -22,10 +24,13 @@ Each SRAM will have SRAM sections that are going to be handled by the
 SRAM controller as subnodes. These sections are represented following
 once again the representation described in the mmio-sram binding.
 
-The valid sections compatible are:
+The valid sections compatible for A10 are:
     - allwinner,sun4i-a10-sram-a3-a4
     - allwinner,sun4i-a10-sram-d
 
+The valid sections compatible for A64 are:
+    - allwinner,sun50i-a64-sram-c
+
 Devices using SRAM sections
 ---------------------------
 
index 1c767c1e796256aa5a666cdee09a9bccf2ac001d..fbb269415f0672c408558289ec5c4a5d5cdafcc5 100644 (file)
@@ -12867,6 +12867,13 @@ L:     linux-mmc@vger.kernel.org
 S:     Maintained
 F:     drivers/mmc/host/dw_mmc*
 
+SYNOPSYS HSDK RESET CONTROLLER DRIVER
+M:     Eugeniy Paltsev <Eugeniy.Paltsev@synopsys.com>
+S:     Supported
+F:     drivers/reset/reset-hsdk-v1.c
+F:     include/dt-bindings/reset/snps,hsdk-v1-reset.h
+F:     Documentation/devicetree/bindings/reset/snps,hsdk-v1-reset.txt
+
 SYSTEM CONFIGURATION (SYSCON)
 M:     Lee Jones <lee.jones@linaro.org>
 M:     Arnd Bergmann <arnd@arndb.de>
index c3cf215773b2de6228abbd27cc89ca234512f7f8..6910b4e0d913bc9f3e02a7f846c42d32676306bd 100644 (file)
@@ -30,6 +30,7 @@ static void __init mediatek_timer_init(void)
 
        if (of_machine_is_compatible("mediatek,mt6589") ||
            of_machine_is_compatible("mediatek,mt7623") ||
+           of_machine_is_compatible("mediatek,mt7623a") ||
            of_machine_is_compatible("mediatek,mt8135") ||
            of_machine_is_compatible("mediatek,mt8127")) {
                /* turn on GPT6 which ungates arch timer clocks */
@@ -49,6 +50,7 @@ static const char * const mediatek_board_dt_compat[] = {
        "mediatek,mt6589",
        "mediatek,mt6592",
        "mediatek,mt7623",
+       "mediatek,mt7623a",
        "mediatek,mt8127",
        "mediatek,mt8135",
        NULL,
index 726eb69bb655decfbd7a817bdddcb8946c761dc4..27d78c945cafc60c87b4e9913d749855f7bfdba1 100644 (file)
@@ -59,6 +59,7 @@ static const struct of_device_id mtk_tz_smp_boot_infos[] __initconst = {
 static const struct of_device_id mtk_smp_boot_infos[] __initconst = {
        { .compatible   = "mediatek,mt6589", .data = &mtk_mt6589_boot },
        { .compatible   = "mediatek,mt7623", .data = &mtk_mt7623_boot },
+       { .compatible   = "mediatek,mt7623a", .data = &mtk_mt7623_boot },
 };
 
 static void __iomem *mtk_smp_base;
index 649e9e8c7bccdf2e566ec0ad05c52c8a85a4fc04..02e712d2ea300b2040efefbfab43cc8cd9cab2e0 100644 (file)
@@ -84,35 +84,8 @@ static void __init tegra_dt_init_irq(void)
 
 static void __init tegra_dt_init(void)
 {
-       struct soc_device_attribute *soc_dev_attr;
-       struct soc_device *soc_dev;
-       struct device *parent = NULL;
+       struct device *parent = tegra_soc_device_register();
 
-       soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL);
-       if (!soc_dev_attr)
-               goto out;
-
-       soc_dev_attr->family = kasprintf(GFP_KERNEL, "Tegra");
-       soc_dev_attr->revision = kasprintf(GFP_KERNEL, "%d",
-                                          tegra_sku_info.revision);
-       soc_dev_attr->soc_id = kasprintf(GFP_KERNEL, "%u", tegra_get_chip_id());
-
-       soc_dev = soc_device_register(soc_dev_attr);
-       if (IS_ERR(soc_dev)) {
-               kfree(soc_dev_attr->family);
-               kfree(soc_dev_attr->revision);
-               kfree(soc_dev_attr->soc_id);
-               kfree(soc_dev_attr);
-               goto out;
-       }
-
-       parent = soc_device_to_device(soc_dev);
-
-       /*
-        * Finished with the static registrations now; fill in the missing
-        * devices
-        */
-out:
        of_platform_default_populate(NULL, NULL, parent);
 }
 
index 2408ea38a39c2b5d681218188ab80d77fae751c7..ae3d8f3444b9bd3741cd0160b47600231aa8aba4 100644 (file)
@@ -132,7 +132,7 @@ config SIMPLE_PM_BUS
 
 config SUNXI_RSB
        tristate "Allwinner sunXi Reduced Serial Bus Driver"
-         default MACH_SUN8I || MACH_SUN9I
+         default MACH_SUN8I || MACH_SUN9I || ARM64
          depends on ARCH_SUNXI
          select REGMAP
          help
index c49da15d979013bb5b890e5cdd4db9296e1508fa..3c29d36702a8eceb4eabd5ed36cf3188adeb1694 100644 (file)
@@ -2124,8 +2124,8 @@ int notrace __cci_control_port_by_device(struct device_node *dn, bool enable)
                return -ENODEV;
 
        port = __cci_ace_get_port(dn, ACE_LITE_PORT);
-       if (WARN_ONCE(port < 0, "node %s ACE lite port look-up failure\n",
-                               dn->full_name))
+       if (WARN_ONCE(port < 0, "node %pOF ACE lite port look-up failure\n",
+                               dn))
                return -ENODEV;
        cci_port_control(port, enable);
        return 0;
@@ -2200,14 +2200,14 @@ static int cci_probe_ports(struct device_node *np)
 
                if (of_property_read_string(cp, "interface-type",
                                        &match_str)) {
-                       WARN(1, "node %s missing interface-type property\n",
-                                 cp->full_name);
+                       WARN(1, "node %pOF missing interface-type property\n",
+                                 cp);
                        continue;
                }
                is_ace = strcmp(match_str, "ace") == 0;
                if (!is_ace && strcmp(match_str, "ace-lite")) {
-                       WARN(1, "node %s containing invalid interface-type property, skipping it\n",
-                                       cp->full_name);
+                       WARN(1, "node %pOF containing invalid interface-type property, skipping it\n",
+                                       cp);
                        continue;
                }
 
index 4bd361d6427032e80434ed1889ef237d42520850..3d56ebcda72007f26ce821da28f23b8d8e7c0994 100644 (file)
@@ -156,8 +156,8 @@ static int __init weim_parse_dt(struct platform_device *pdev,
 
                ret = weim_timing_setup(child, base, devtype);
                if (ret)
-                       dev_warn(&pdev->dev, "%s set timing failed.\n",
-                               child->full_name);
+                       dev_warn(&pdev->dev, "%pOF set timing failed.\n",
+                               child);
                else
                        have_child = 1;
        }
@@ -166,8 +166,8 @@ static int __init weim_parse_dt(struct platform_device *pdev,
                ret = of_platform_default_populate(pdev->dev.of_node,
                                                   NULL, &pdev->dev);
        if (ret)
-               dev_err(&pdev->dev, "%s fail to create devices.\n",
-                       pdev->dev.of_node->full_name);
+               dev_err(&pdev->dev, "%pOF fail to create devices.\n",
+                       pdev->dev.of_node);
        return ret;
 }
 
index 795c9d9c96a6d5ae08c036a221ae1f9a4b1f9c1b..328ca93781cf2691fb692b64e86ec4c203ca5b47 100644 (file)
@@ -556,20 +556,20 @@ static int of_rsb_register_devices(struct sunxi_rsb *rsb)
 
        /* Runtime addresses for all slaves should be set first */
        for_each_available_child_of_node(np, child) {
-               dev_dbg(dev, "setting child %s runtime address\n",
-                       child->full_name);
+               dev_dbg(dev, "setting child %pOF runtime address\n",
+                       child);
 
                ret = of_property_read_u32(child, "reg", &hwaddr);
                if (ret) {
-                       dev_err(dev, "%s: invalid 'reg' property: %d\n",
-                               child->full_name, ret);
+                       dev_err(dev, "%pOF: invalid 'reg' property: %d\n",
+                               child, ret);
                        continue;
                }
 
                rtaddr = sunxi_rsb_get_rtaddr(hwaddr);
                if (!rtaddr) {
-                       dev_err(dev, "%s: unknown hardware device address\n",
-                               child->full_name);
+                       dev_err(dev, "%pOF: unknown hardware device address\n",
+                               child);
                        continue;
                }
 
@@ -586,15 +586,15 @@ static int of_rsb_register_devices(struct sunxi_rsb *rsb)
                /* send command */
                ret = _sunxi_rsb_run_xfer(rsb);
                if (ret)
-                       dev_warn(dev, "%s: set runtime address failed: %d\n",
-                                child->full_name, ret);
+                       dev_warn(dev, "%pOF: set runtime address failed: %d\n",
+                                child, ret);
        }
 
        /* Then we start adding devices and probing them */
        for_each_available_child_of_node(np, child) {
                struct sunxi_rsb_device *rdev;
 
-               dev_dbg(dev, "adding child %s\n", child->full_name);
+               dev_dbg(dev, "adding child %pOF\n", child);
 
                ret = of_property_read_u32(child, "reg", &hwaddr);
                if (ret)
@@ -606,8 +606,8 @@ static int of_rsb_register_devices(struct sunxi_rsb *rsb)
 
                rdev = sunxi_rsb_device_create(rsb, child, hwaddr, rtaddr);
                if (IS_ERR(rdev))
-                       dev_err(dev, "failed to add child device %s: %ld\n",
-                               child->full_name, PTR_ERR(rdev));
+                       dev_err(dev, "failed to add child device %pOF: %ld\n",
+                               child, PTR_ERR(rdev));
        }
 
        return 0;
index 8043e51de89730367d7f36d3c058e8bd123354bc..7da9f1b83ebecf3641da1e87f35e5e9ec6621df8 100644 (file)
@@ -357,7 +357,7 @@ struct sensor_value {
 } __packed;
 
 struct dev_pstate_set {
-       u16 dev_id;
+       __le16 dev_id;
        u8 pstate;
 } __packed;
 
@@ -965,7 +965,7 @@ static int scpi_probe(struct platform_device *pdev)
 
        count = of_count_phandle_with_args(np, "mboxes", "#mbox-cells");
        if (count < 0) {
-               dev_err(dev, "no mboxes property in '%s'\n", np->full_name);
+               dev_err(dev, "no mboxes property in '%pOF'\n", np);
                return -ENODEV;
        }
 
index 493a56a4cfc4a83694db0dcbba37b469aeae8e42..d687ca3d5049b82467d25e89e66e8a34a305995c 100644 (file)
@@ -280,8 +280,8 @@ static int psci_dt_cpu_init_idle(struct device_node *cpu_node, int cpu)
                                           "arm,psci-suspend-param",
                                           &state);
                if (ret) {
-                       pr_warn(" * %s missing arm,psci-suspend-param property\n",
-                               state_node->full_name);
+                       pr_warn(" * %pOF missing arm,psci-suspend-param property\n",
+                               state_node);
                        of_node_put(state_node);
                        goto free_mem;
                }
index b25179517cc5a51951333d9c9dceb4625140b823..73ca55b7b7ec456b63c835940c477dd89fb7ff0b 100644 (file)
@@ -806,6 +806,8 @@ static int tegra_bpmp_probe(struct platform_device *pdev)
 
        dev_info(&pdev->dev, "firmware: %s\n", tag);
 
+       platform_set_drvdata(pdev, bpmp);
+
        err = of_platform_default_populate(pdev->dev.of_node, NULL, &pdev->dev);
        if (err < 0)
                goto free_mrq;
@@ -822,8 +824,6 @@ static int tegra_bpmp_probe(struct platform_device *pdev)
        if (err < 0)
                goto free_mrq;
 
-       platform_set_drvdata(pdev, bpmp);
-
        return 0;
 
 free_mrq:
index c00a7c7f460a51209ef49e9c96a0773d5eb85e00..b907865d4664db167a4931edb3479cf11069de70 100644 (file)
@@ -159,8 +159,8 @@ static int atmel_ebi_xslate_smc_timings(struct atmel_ebi_dev *ebid,
 out:
        if (ret) {
                dev_err(ebid->ebi->dev,
-                       "missing or invalid timings definition in %s",
-                       np->full_name);
+                       "missing or invalid timings definition in %pOF",
+                       np);
                return ret;
        }
 
@@ -270,8 +270,8 @@ static int atmel_ebi_xslate_smc_config(struct atmel_ebi_dev *ebid,
                return -EINVAL;
 
        if ((ret > 0 && !required) || (!ret && required)) {
-               dev_err(ebid->ebi->dev, "missing atmel,smc- properties in %s",
-                       np->full_name);
+               dev_err(ebid->ebi->dev, "missing atmel,smc- properties in %pOF",
+                       np);
                return -EINVAL;
        }
 
@@ -314,8 +314,7 @@ static int atmel_ebi_dev_setup(struct atmel_ebi *ebi, struct device_node *np,
 
                if (cs >= AT91_MATRIX_EBI_NUM_CS ||
                    !(ebi->caps->available_cs & BIT(cs))) {
-                       dev_err(dev, "invalid reg property in %s\n",
-                               np->full_name);
+                       dev_err(dev, "invalid reg property in %pOF\n", np);
                        return -EINVAL;
                }
 
@@ -324,7 +323,7 @@ static int atmel_ebi_dev_setup(struct atmel_ebi *ebi, struct device_node *np,
        }
 
        if (!numcs) {
-               dev_err(dev, "invalid reg property in %s\n", np->full_name);
+               dev_err(dev, "invalid reg property in %pOF\n", np);
                return -EINVAL;
        }
 
@@ -576,8 +575,8 @@ static int atmel_ebi_probe(struct platform_device *pdev)
 
                ret = atmel_ebi_dev_setup(ebi, child, reg_cells);
                if (ret) {
-                       dev_err(dev, "failed to configure EBI bus for %s, disabling the device",
-                               child->full_name);
+                       dev_err(dev, "failed to configure EBI bus for %pOF, disabling the device",
+                               child);
 
                        ret = atmel_ebi_dev_disable(ebi, child);
                        if (ret)
index 919d1925acb961d3a038d5a2d9125500ef2dbf7d..bcf06adefc96c1c99c5dce6e79f1582c937a4a56 100644 (file)
@@ -322,8 +322,8 @@ static int jz4780_nemc_probe(struct platform_device *pdev)
                        bank = of_read_number(prop, 1);
                        if (bank < 1 || bank >= JZ4780_NEMC_NUM_BANKS) {
                                dev_err(nemc->dev,
-                                       "%s requests invalid bank %u\n",
-                                       child->full_name, bank);
+                                       "%pOF requests invalid bank %u\n",
+                                       child, bank);
 
                                /* Will continue the outer loop below. */
                                referenced = 0;
@@ -334,12 +334,12 @@ static int jz4780_nemc_probe(struct platform_device *pdev)
                }
 
                if (!referenced) {
-                       dev_err(nemc->dev, "%s has no addresses\n",
-                               child->full_name);
+                       dev_err(nemc->dev, "%pOF has no addresses\n",
+                               child);
                        continue;
                } else if (nemc->banks_present & referenced) {
-                       dev_err(nemc->dev, "%s conflicts with another node\n",
-                               child->full_name);
+                       dev_err(nemc->dev, "%pOF conflicts with another node\n",
+                               child);
                        continue;
                }
 
index 24852812fd44fce5f70f1bcb35d409be77a66e7d..981860879d02e88f0266dfc5367280520b53cda4 100644 (file)
@@ -105,8 +105,8 @@ static int get_timing_param_ps(struct devbus *devbus,
 
        err = of_property_read_u32(node, name, &time_ps);
        if (err < 0) {
-               dev_err(devbus->dev, "%s has no '%s' property\n",
-                       name, node->full_name);
+               dev_err(devbus->dev, "%pOF has no '%s' property\n",
+                       node, name);
                return err;
        }
 
@@ -127,8 +127,8 @@ static int devbus_get_timing_params(struct devbus *devbus,
        err = of_property_read_u32(node, "devbus,bus-width", &r->bus_width);
        if (err < 0) {
                dev_err(devbus->dev,
-                       "%s has no 'devbus,bus-width' property\n",
-                       node->full_name);
+                       "%pOF has no 'devbus,bus-width' property\n",
+                       node);
                return err;
        }
 
@@ -180,8 +180,8 @@ static int devbus_get_timing_params(struct devbus *devbus,
                                           &w->sync_enable);
                if (err < 0) {
                        dev_err(devbus->dev,
-                               "%s has no 'devbus,sync-enable' property\n",
-                               node->full_name);
+                               "%pOF has no 'devbus,sync-enable' property\n",
+                               node);
                        return err;
                }
        }
index a80e17de906db42c16b7d2c2919009b6dee2ebb5..7059bbda2faca0d2b7e672781bdd1056b8beef75 100644 (file)
@@ -1930,8 +1930,8 @@ static int gpmc_probe_onenand_child(struct platform_device *pdev,
        struct omap_onenand_platform_data *gpmc_onenand_data;
 
        if (of_property_read_u32(child, "reg", &val) < 0) {
-               dev_err(&pdev->dev, "%s has no 'reg' property\n",
-                       child->full_name);
+               dev_err(&pdev->dev, "%pOF has no 'reg' property\n",
+                       child);
                return -ENODEV;
        }
 
@@ -1979,14 +1979,14 @@ static int gpmc_probe_generic_child(struct platform_device *pdev,
        struct gpmc_device *gpmc = platform_get_drvdata(pdev);
 
        if (of_property_read_u32(child, "reg", &cs) < 0) {
-               dev_err(&pdev->dev, "%s has no 'reg' property\n",
-                       child->full_name);
+               dev_err(&pdev->dev, "%pOF has no 'reg' property\n",
+                       child);
                return -ENODEV;
        }
 
        if (of_address_to_resource(child, 0, &res) < 0) {
-               dev_err(&pdev->dev, "%s has malformed 'reg' property\n",
-                       child->full_name);
+               dev_err(&pdev->dev, "%pOF has malformed 'reg' property\n",
+                       child);
                return -ENODEV;
        }
 
@@ -2084,8 +2084,8 @@ static int gpmc_probe_generic_child(struct platform_device *pdev,
                ret = of_property_read_u32(child, "bank-width",
                                           &gpmc_s.device_width);
                if (ret < 0) {
-                       dev_err(&pdev->dev, "%s has no 'bank-width' property\n",
-                               child->full_name);
+                       dev_err(&pdev->dev, "%pOF has no 'bank-width' property\n",
+                               child);
                        goto err;
                }
        }
index 608c071e4bbfd2239d59ac5ca9866db5746a8ddf..52d5251660b9b51c3c55710d38c90716c2c47976 100644 (file)
@@ -34,12 +34,11 @@ config RESET_BERLIN
        help
          This enables the reset controller driver for Marvell Berlin SoCs.
 
-config RESET_GEMINI
-       bool "Gemini Reset Driver" if COMPILE_TEST
-       default ARCH_GEMINI
-       select MFD_SYSCON
+config RESET_HSDK_V1
+       bool "HSDK v1 Reset Driver"
+       default n
        help
-         This enables the reset controller driver for Cortina Systems Gemini.
+         This enables the reset controller driver for HSDK v1.
 
 config RESET_IMX7
        bool "i.MX7 Reset Driver" if COMPILE_TEST
index 7081f9da2599bca21e1825c8825f76f30592f315..b62783f50fe5b0c0b29b6152c2ddbd3f5e06cc21 100644 (file)
@@ -5,7 +5,7 @@ obj-$(CONFIG_ARCH_TEGRA) += tegra/
 obj-$(CONFIG_RESET_A10SR) += reset-a10sr.o
 obj-$(CONFIG_RESET_ATH79) += reset-ath79.o
 obj-$(CONFIG_RESET_BERLIN) += reset-berlin.o
-obj-$(CONFIG_RESET_GEMINI) += reset-gemini.o
+obj-$(CONFIG_RESET_HSDK_V1) += reset-hsdk-v1.o
 obj-$(CONFIG_RESET_IMX7) += reset-imx7.o
 obj-$(CONFIG_RESET_LPC18XX) += reset-lpc18xx.o
 obj-$(CONFIG_RESET_MESON) += reset-meson.o
index 0090784ff41059ffee6dd50caaee43684ad24a66..1d21c6f7d56cbdec09bd9b9324665d146f67c26f 100644 (file)
@@ -43,10 +43,23 @@ struct reset_control {
        unsigned int id;
        struct kref refcnt;
        bool shared;
+       bool array;
        atomic_t deassert_count;
        atomic_t triggered_count;
 };
 
+/**
+ * struct reset_control_array - an array of reset controls
+ * @base: reset control for compatibility with reset control API functions
+ * @num_rstcs: number of reset controls
+ * @rstc: array of reset controls
+ */
+struct reset_control_array {
+       struct reset_control base;
+       unsigned int num_rstcs;
+       struct reset_control *rstc[];
+};
+
 /**
  * of_reset_simple_xlate - translate reset_spec to the reset line number
  * @rcdev: a pointer to the reset controller device
@@ -135,6 +148,65 @@ int devm_reset_controller_register(struct device *dev,
 }
 EXPORT_SYMBOL_GPL(devm_reset_controller_register);
 
+static inline struct reset_control_array *
+rstc_to_array(struct reset_control *rstc) {
+       return container_of(rstc, struct reset_control_array, base);
+}
+
+static int reset_control_array_reset(struct reset_control_array *resets)
+{
+       int ret, i;
+
+       for (i = 0; i < resets->num_rstcs; i++) {
+               ret = reset_control_reset(resets->rstc[i]);
+               if (ret)
+                       return ret;
+       }
+
+       return 0;
+}
+
+static int reset_control_array_assert(struct reset_control_array *resets)
+{
+       int ret, i;
+
+       for (i = 0; i < resets->num_rstcs; i++) {
+               ret = reset_control_assert(resets->rstc[i]);
+               if (ret)
+                       goto err;
+       }
+
+       return 0;
+
+err:
+       while (i--)
+               reset_control_deassert(resets->rstc[i]);
+       return ret;
+}
+
+static int reset_control_array_deassert(struct reset_control_array *resets)
+{
+       int ret, i;
+
+       for (i = 0; i < resets->num_rstcs; i++) {
+               ret = reset_control_deassert(resets->rstc[i]);
+               if (ret)
+                       goto err;
+       }
+
+       return 0;
+
+err:
+       while (i--)
+               reset_control_assert(resets->rstc[i]);
+       return ret;
+}
+
+static inline bool reset_control_is_array(struct reset_control *rstc)
+{
+       return rstc->array;
+}
+
 /**
  * reset_control_reset - reset the controlled device
  * @rstc: reset controller
@@ -158,6 +230,9 @@ int reset_control_reset(struct reset_control *rstc)
        if (WARN_ON(IS_ERR(rstc)))
                return -EINVAL;
 
+       if (reset_control_is_array(rstc))
+               return reset_control_array_reset(rstc_to_array(rstc));
+
        if (!rstc->rcdev->ops->reset)
                return -ENOTSUPP;
 
@@ -202,8 +277,8 @@ int reset_control_assert(struct reset_control *rstc)
        if (WARN_ON(IS_ERR(rstc)))
                return -EINVAL;
 
-       if (!rstc->rcdev->ops->assert)
-               return -ENOTSUPP;
+       if (reset_control_is_array(rstc))
+               return reset_control_array_assert(rstc_to_array(rstc));
 
        if (rstc->shared) {
                if (WARN_ON(atomic_read(&rstc->triggered_count) != 0))
@@ -214,6 +289,21 @@ int reset_control_assert(struct reset_control *rstc)
 
                if (atomic_dec_return(&rstc->deassert_count) != 0)
                        return 0;
+
+               /*
+                * Shared reset controls allow the reset line to be in any state
+                * after this call, so doing nothing is a valid option.
+                */
+               if (!rstc->rcdev->ops->assert)
+                       return 0;
+       } else {
+               /*
+                * If the reset controller does not implement .assert(), there
+                * is no way to guarantee that the reset line is asserted after
+                * this call.
+                */
+               if (!rstc->rcdev->ops->assert)
+                       return -ENOTSUPP;
        }
 
        return rstc->rcdev->ops->assert(rstc->rcdev, rstc->id);
@@ -240,8 +330,8 @@ int reset_control_deassert(struct reset_control *rstc)
        if (WARN_ON(IS_ERR(rstc)))
                return -EINVAL;
 
-       if (!rstc->rcdev->ops->deassert)
-               return -ENOTSUPP;
+       if (reset_control_is_array(rstc))
+               return reset_control_array_deassert(rstc_to_array(rstc));
 
        if (rstc->shared) {
                if (WARN_ON(atomic_read(&rstc->triggered_count) != 0))
@@ -251,6 +341,16 @@ int reset_control_deassert(struct reset_control *rstc)
                        return 0;
        }
 
+       /*
+        * If the reset controller does not implement .deassert(), we assume
+        * that it handles self-deasserting reset lines via .reset(). In that
+        * case, the reset lines are deasserted by default. If that is not the
+        * case, the reset controller driver should implement .deassert() and
+        * return -ENOTSUPP.
+        */
+       if (!rstc->rcdev->ops->deassert)
+               return 0;
+
        return rstc->rcdev->ops->deassert(rstc->rcdev, rstc->id);
 }
 EXPORT_SYMBOL_GPL(reset_control_deassert);
@@ -266,7 +366,7 @@ int reset_control_status(struct reset_control *rstc)
        if (!rstc)
                return 0;
 
-       if (WARN_ON(IS_ERR(rstc)))
+       if (WARN_ON(IS_ERR(rstc)) || reset_control_is_array(rstc))
                return -EINVAL;
 
        if (rstc->rcdev->ops->status)
@@ -404,6 +504,16 @@ struct reset_control *__reset_control_get(struct device *dev, const char *id,
 }
 EXPORT_SYMBOL_GPL(__reset_control_get);
 
+static void reset_control_array_put(struct reset_control_array *resets)
+{
+       int i;
+
+       mutex_lock(&reset_list_mutex);
+       for (i = 0; i < resets->num_rstcs; i++)
+               __reset_control_put_internal(resets->rstc[i]);
+       mutex_unlock(&reset_list_mutex);
+}
+
 /**
  * reset_control_put - free the reset controller
  * @rstc: reset controller
@@ -413,6 +523,11 @@ void reset_control_put(struct reset_control *rstc)
        if (IS_ERR_OR_NULL(rstc))
                return;
 
+       if (reset_control_is_array(rstc)) {
+               reset_control_array_put(rstc_to_array(rstc));
+               return;
+       }
+
        mutex_lock(&reset_list_mutex);
        __reset_control_put_internal(rstc);
        mutex_unlock(&reset_list_mutex);
@@ -472,3 +587,116 @@ int device_reset(struct device *dev)
        return ret;
 }
 EXPORT_SYMBOL_GPL(device_reset);
+
+/**
+ * APIs to manage an array of reset controls.
+ */
+/**
+ * of_reset_control_get_count - Count number of resets available with a device
+ *
+ * @node: device node that contains 'resets'.
+ *
+ * Returns positive reset count on success, or error number on failure and
+ * on count being zero.
+ */
+static int of_reset_control_get_count(struct device_node *node)
+{
+       int count;
+
+       if (!node)
+               return -EINVAL;
+
+       count = of_count_phandle_with_args(node, "resets", "#reset-cells");
+       if (count == 0)
+               count = -ENOENT;
+
+       return count;
+}
+
+/**
+ * of_reset_control_array_get - Get a list of reset controls using
+ *                             device node.
+ *
+ * @np: device node for the device that requests the reset controls array
+ * @shared: whether reset controls are shared or not
+ * @optional: whether it is optional to get the reset controls
+ *
+ * Returns pointer to allocated reset_control_array on success or
+ * error on failure
+ */
+struct reset_control *
+of_reset_control_array_get(struct device_node *np, bool shared, bool optional)
+{
+       struct reset_control_array *resets;
+       struct reset_control *rstc;
+       int num, i;
+
+       num = of_reset_control_get_count(np);
+       if (num < 0)
+               return optional ? NULL : ERR_PTR(num);
+
+       resets = kzalloc(sizeof(*resets) + sizeof(resets->rstc[0]) * num,
+                        GFP_KERNEL);
+       if (!resets)
+               return ERR_PTR(-ENOMEM);
+
+       for (i = 0; i < num; i++) {
+               rstc = __of_reset_control_get(np, NULL, i, shared, optional);
+               if (IS_ERR(rstc))
+                       goto err_rst;
+               resets->rstc[i] = rstc;
+       }
+       resets->num_rstcs = num;
+       resets->base.array = true;
+
+       return &resets->base;
+
+err_rst:
+       mutex_lock(&reset_list_mutex);
+       while (--i >= 0)
+               __reset_control_put_internal(resets->rstc[i]);
+       mutex_unlock(&reset_list_mutex);
+
+       kfree(resets);
+
+       return rstc;
+}
+EXPORT_SYMBOL_GPL(of_reset_control_array_get);
+
+/**
+ * devm_reset_control_array_get - Resource managed reset control array get
+ *
+ * @dev: device that requests the list of reset controls
+ * @shared: whether reset controls are shared or not
+ * @optional: whether it is optional to get the reset controls
+ *
+ * The reset control array APIs are intended for a list of resets
+ * that just have to be asserted or deasserted, without any
+ * requirements on the order.
+ *
+ * Returns pointer to allocated reset_control_array on success or
+ * error on failure
+ */
+struct reset_control *
+devm_reset_control_array_get(struct device *dev, bool shared, bool optional)
+{
+       struct reset_control **devres;
+       struct reset_control *rstc;
+
+       devres = devres_alloc(devm_reset_control_release, sizeof(*devres),
+                             GFP_KERNEL);
+       if (!devres)
+               return ERR_PTR(-ENOMEM);
+
+       rstc = of_reset_control_array_get(dev->of_node, shared, optional);
+       if (IS_ERR(rstc)) {
+               devres_free(devres);
+               return rstc;
+       }
+
+       *devres = rstc;
+       devres_add(dev, devres);
+
+       return rstc;
+}
+EXPORT_SYMBOL_GPL(devm_reset_control_array_get);
diff --git a/drivers/reset/reset-gemini.c b/drivers/reset/reset-gemini.c
deleted file mode 100644 (file)
index a247899..0000000
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * Cortina Gemini Reset controller driver
- * Copyright (C) 2017 Linus Walleij <linus.walleij@linaro.org>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/err.h>
-#include <linux/init.h>
-#include <linux/mfd/syscon.h>
-#include <linux/regmap.h>
-#include <linux/of.h>
-#include <linux/platform_device.h>
-#include <linux/reset-controller.h>
-#include <dt-bindings/reset/cortina,gemini-reset.h>
-
-/**
- * struct gemini_reset - gemini reset controller
- * @map: regmap to access the containing system controller
- * @rcdev: reset controller device
- */
-struct gemini_reset {
-       struct regmap *map;
-       struct reset_controller_dev rcdev;
-};
-
-#define GEMINI_GLOBAL_SOFT_RESET 0x0c
-
-#define to_gemini_reset(p) \
-       container_of((p), struct gemini_reset, rcdev)
-
-/*
- * This is a self-deasserting reset controller.
- */
-static int gemini_reset(struct reset_controller_dev *rcdev,
-                       unsigned long id)
-{
-       struct gemini_reset *gr = to_gemini_reset(rcdev);
-
-       /* Manual says to always set BIT 30 (CPU1) to 1 */
-       return regmap_write(gr->map,
-                           GEMINI_GLOBAL_SOFT_RESET,
-                           BIT(GEMINI_RESET_CPU1) | BIT(id));
-}
-
-static int gemini_reset_status(struct reset_controller_dev *rcdev,
-                            unsigned long id)
-{
-       struct gemini_reset *gr = to_gemini_reset(rcdev);
-       u32 val;
-       int ret;
-
-       ret = regmap_read(gr->map, GEMINI_GLOBAL_SOFT_RESET, &val);
-       if (ret)
-               return ret;
-
-       return !!(val & BIT(id));
-}
-
-static const struct reset_control_ops gemini_reset_ops = {
-       .reset = gemini_reset,
-       .status = gemini_reset_status,
-};
-
-static int gemini_reset_probe(struct platform_device *pdev)
-{
-       struct gemini_reset *gr;
-       struct device *dev = &pdev->dev;
-       struct device_node *np = dev->of_node;
-       int ret;
-
-       gr = devm_kzalloc(dev, sizeof(*gr), GFP_KERNEL);
-       if (!gr)
-               return -ENOMEM;
-
-       gr->map = syscon_node_to_regmap(np);
-       if (IS_ERR(gr->map)) {
-               ret = PTR_ERR(gr->map);
-               dev_err(dev, "unable to get regmap (%d)", ret);
-               return ret;
-       }
-       gr->rcdev.owner = THIS_MODULE;
-       gr->rcdev.nr_resets = 32;
-       gr->rcdev.ops = &gemini_reset_ops;
-       gr->rcdev.of_node = pdev->dev.of_node;
-
-       ret = devm_reset_controller_register(&pdev->dev, &gr->rcdev);
-       if (ret)
-               return ret;
-
-       dev_info(dev, "registered Gemini reset controller\n");
-       return 0;
-}
-
-static const struct of_device_id gemini_reset_dt_ids[] = {
-       { .compatible = "cortina,gemini-syscon", },
-       { /* sentinel */ },
-};
-
-static struct platform_driver gemini_reset_driver = {
-       .probe  = gemini_reset_probe,
-       .driver = {
-               .name           = "gemini-reset",
-               .of_match_table = gemini_reset_dt_ids,
-               .suppress_bind_attrs = true,
-       },
-};
-builtin_platform_driver(gemini_reset_driver);
diff --git a/drivers/reset/reset-hsdk-v1.c b/drivers/reset/reset-hsdk-v1.c
new file mode 100644 (file)
index 0000000..bca13e4
--- /dev/null
@@ -0,0 +1,137 @@
+/*
+ * Copyright (C) 2017 Synopsys.
+ *
+ * Synopsys HSDKv1 SDP reset driver.
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/iopoll.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/reset-controller.h>
+#include <linux/slab.h>
+#include <linux/types.h>
+
+#define to_hsdkv1_rst(p)       container_of((p), struct hsdkv1_rst, rcdev)
+
+struct hsdkv1_rst {
+       void __iomem                    *regs_ctl;
+       void __iomem                    *regs_rst;
+       spinlock_t                      lock;
+       struct reset_controller_dev     rcdev;
+};
+
+static const u32 rst_map[] = {
+       BIT(16), /* APB_RST  */
+       BIT(17), /* AXI_RST  */
+       BIT(18), /* ETH_RST  */
+       BIT(19), /* USB_RST  */
+       BIT(20), /* SDIO_RST */
+       BIT(21), /* HDMI_RST */
+       BIT(22), /* GFX_RST  */
+       BIT(25), /* DMAC_RST */
+       BIT(31), /* EBI_RST  */
+};
+
+#define HSDK_MAX_RESETS                        ARRAY_SIZE(rst_map)
+
+#define CGU_SYS_RST_CTRL               0x0
+#define CGU_IP_SW_RESET                        0x0
+#define CGU_IP_SW_RESET_DELAY_SHIFT    16
+#define CGU_IP_SW_RESET_DELAY_MASK     GENMASK(31, CGU_IP_SW_RESET_DELAY_SHIFT)
+#define CGU_IP_SW_RESET_DELAY          0
+#define CGU_IP_SW_RESET_RESET          BIT(0)
+#define SW_RESET_TIMEOUT               10000
+
+static void hsdkv1_reset_config(struct hsdkv1_rst *rst, unsigned long id)
+{
+       writel(rst_map[id], rst->regs_ctl + CGU_SYS_RST_CTRL);
+}
+
+static int hsdkv1_reset_do(struct hsdkv1_rst *rst)
+{
+       u32 reg;
+
+       reg = readl(rst->regs_rst + CGU_IP_SW_RESET);
+       reg &= ~CGU_IP_SW_RESET_DELAY_MASK;
+       reg |= CGU_IP_SW_RESET_DELAY << CGU_IP_SW_RESET_DELAY_SHIFT;
+       reg |= CGU_IP_SW_RESET_RESET;
+       writel(reg, rst->regs_rst + CGU_IP_SW_RESET);
+
+       /* wait till reset bit is back to 0 */
+       return readl_poll_timeout_atomic(rst->regs_rst + CGU_IP_SW_RESET, reg,
+               !(reg & CGU_IP_SW_RESET_RESET), 5, SW_RESET_TIMEOUT);
+}
+
+static int hsdkv1_reset_reset(struct reset_controller_dev *rcdev,
+                             unsigned long id)
+{
+       struct hsdkv1_rst *rst = to_hsdkv1_rst(rcdev);
+       unsigned long flags;
+       int ret;
+
+       spin_lock_irqsave(&rst->lock, flags);
+       hsdkv1_reset_config(rst, id);
+       ret = hsdkv1_reset_do(rst);
+       spin_unlock_irqrestore(&rst->lock, flags);
+
+       return ret;
+}
+
+static const struct reset_control_ops hsdkv1_reset_ops = {
+       .reset  = hsdkv1_reset_reset,
+};
+
+static int hsdkv1_reset_probe(struct platform_device *pdev)
+{
+       struct hsdkv1_rst *rst;
+       struct resource *mem;
+
+       rst = devm_kzalloc(&pdev->dev, sizeof(*rst), GFP_KERNEL);
+       if (!rst)
+               return -ENOMEM;
+
+       mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       rst->regs_ctl = devm_ioremap_resource(&pdev->dev, mem);
+       if (IS_ERR(rst->regs_ctl))
+               return PTR_ERR(rst->regs_ctl);
+
+       mem = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+       rst->regs_rst = devm_ioremap_resource(&pdev->dev, mem);
+       if (IS_ERR(rst->regs_rst))
+               return PTR_ERR(rst->regs_rst);
+
+       spin_lock_init(&rst->lock);
+
+       rst->rcdev.owner = THIS_MODULE;
+       rst->rcdev.ops = &hsdkv1_reset_ops;
+       rst->rcdev.of_node = pdev->dev.of_node;
+       rst->rcdev.nr_resets = HSDK_MAX_RESETS;
+       rst->rcdev.of_reset_n_cells = 1;
+
+       return reset_controller_register(&rst->rcdev);
+}
+
+static const struct of_device_id hsdkv1_reset_dt_match[] = {
+       { .compatible = "snps,hsdk-v1.0-reset" },
+       { },
+};
+
+static struct platform_driver hsdkv1_reset_driver = {
+       .probe  = hsdkv1_reset_probe,
+       .driver = {
+               .name = "hsdk-v1.0-reset",
+               .of_match_table = hsdkv1_reset_dt_match,
+       },
+};
+builtin_platform_driver(hsdkv1_reset_driver);
+
+MODULE_AUTHOR("Eugeniy Paltsev <Eugeniy.Paltsev@synopsys.com>");
+MODULE_DESCRIPTION("Synopsys HSDKv1 SDP reset driver");
+MODULE_LICENSE("GPL v2");
index cd585cd2f04dd1b2677fa8c2cf5ac95200792b70..2c7dd1fd08df626c28e78744441804dfef6ce123 100644 (file)
@@ -107,7 +107,7 @@ static int sunxi_reset_init(struct device_node *np)
        spin_lock_init(&data->lock);
 
        data->rcdev.owner = THIS_MODULE;
-       data->rcdev.nr_resets = size * 32;
+       data->rcdev.nr_resets = size * 8;
        data->rcdev.ops = &sunxi_reset_ops;
        data->rcdev.of_node = np;
 
@@ -162,7 +162,7 @@ static int sunxi_reset_probe(struct platform_device *pdev)
        spin_lock_init(&data->lock);
 
        data->rcdev.owner = THIS_MODULE;
-       data->rcdev.nr_resets = resource_size(res) * 32;
+       data->rcdev.nr_resets = resource_size(res) * 8;
        data->rcdev.ops = &sunxi_reset_ops;
        data->rcdev.of_node = pdev->dev.of_node;
 
index c4ba89832796b767debc204d41513dc563c96c81..bda2dd196ae5d1bdd21412a4604defcc7d4db350 100644 (file)
@@ -50,59 +50,35 @@ struct uniphier_reset_data {
        }
 
 /* System reset data */
-#define UNIPHIER_SLD3_SYS_RESET_NAND(id)               \
-       UNIPHIER_RESETX((id), 0x2004, 2)
-
-#define UNIPHIER_LD11_SYS_RESET_NAND(id)               \
-       UNIPHIER_RESETX((id), 0x200c, 0)
-
-#define UNIPHIER_LD11_SYS_RESET_EMMC(id)               \
-       UNIPHIER_RESETX((id), 0x200c, 2)
-
-#define UNIPHIER_SLD3_SYS_RESET_STDMAC(id)             \
-       UNIPHIER_RESETX((id), 0x2000, 10)
-
-#define UNIPHIER_LD11_SYS_RESET_STDMAC(id)             \
-       UNIPHIER_RESETX((id), 0x200c, 8)
-
-#define UNIPHIER_PRO4_SYS_RESET_GIO(id)                        \
-       UNIPHIER_RESETX((id), 0x2000, 6)
-
-#define UNIPHIER_LD20_SYS_RESET_GIO(id)                        \
-       UNIPHIER_RESETX((id), 0x200c, 5)
-
-#define UNIPHIER_PRO4_SYS_RESET_USB3(id, ch)           \
-       UNIPHIER_RESETX((id), 0x2000 + 0x4 * (ch), 17)
-
-static const struct uniphier_reset_data uniphier_sld3_sys_reset_data[] = {
-       UNIPHIER_SLD3_SYS_RESET_NAND(2),
-       UNIPHIER_SLD3_SYS_RESET_STDMAC(8),      /* Ether, HSC, MIO */
+static const struct uniphier_reset_data uniphier_ld4_sys_reset_data[] = {
+       UNIPHIER_RESETX(2, 0x2000, 2),          /* NAND */
+       UNIPHIER_RESETX(8, 0x2000, 10),         /* STDMAC (Ether, HSC, MIO) */
        UNIPHIER_RESET_END,
 };
 
 static const struct uniphier_reset_data uniphier_pro4_sys_reset_data[] = {
-       UNIPHIER_SLD3_SYS_RESET_NAND(2),
-       UNIPHIER_SLD3_SYS_RESET_STDMAC(8),      /* HSC, MIO, RLE */
-       UNIPHIER_PRO4_SYS_RESET_GIO(12),        /* Ether, SATA, USB3 */
-       UNIPHIER_PRO4_SYS_RESET_USB3(14, 0),
-       UNIPHIER_PRO4_SYS_RESET_USB3(15, 1),
+       UNIPHIER_RESETX(2, 0x2000, 2),          /* NAND */
+       UNIPHIER_RESETX(8, 0x2000, 10),         /* STDMAC (HSC, MIO, RLE) */
+       UNIPHIER_RESETX(12, 0x2000, 6),         /* GIO (Ether, SATA, USB3) */
+       UNIPHIER_RESETX(14, 0x2000, 17),        /* USB30 */
+       UNIPHIER_RESETX(15, 0x2004, 17),        /* USB31 */
        UNIPHIER_RESET_END,
 };
 
 static const struct uniphier_reset_data uniphier_pro5_sys_reset_data[] = {
-       UNIPHIER_SLD3_SYS_RESET_NAND(2),
-       UNIPHIER_SLD3_SYS_RESET_STDMAC(8),      /* HSC */
-       UNIPHIER_PRO4_SYS_RESET_GIO(12),        /* PCIe, USB3 */
-       UNIPHIER_PRO4_SYS_RESET_USB3(14, 0),
-       UNIPHIER_PRO4_SYS_RESET_USB3(15, 1),
+       UNIPHIER_RESETX(2, 0x2000, 2),          /* NAND */
+       UNIPHIER_RESETX(8, 0x2000, 10),         /* STDMAC (HSC) */
+       UNIPHIER_RESETX(12, 0x2000, 6),         /* GIO (PCIe, USB3) */
+       UNIPHIER_RESETX(14, 0x2000, 17),        /* USB30 */
+       UNIPHIER_RESETX(15, 0x2004, 17),        /* USB31 */
        UNIPHIER_RESET_END,
 };
 
 static const struct uniphier_reset_data uniphier_pxs2_sys_reset_data[] = {
-       UNIPHIER_SLD3_SYS_RESET_NAND(2),
-       UNIPHIER_SLD3_SYS_RESET_STDMAC(8),      /* HSC, RLE */
-       UNIPHIER_PRO4_SYS_RESET_USB3(14, 0),
-       UNIPHIER_PRO4_SYS_RESET_USB3(15, 1),
+       UNIPHIER_RESETX(2, 0x2000, 2),          /* NAND */
+       UNIPHIER_RESETX(8, 0x2000, 10),         /* STDMAC (HSC, RLE) */
+       UNIPHIER_RESETX(14, 0x2000, 17),        /* USB30 */
+       UNIPHIER_RESETX(15, 0x2004, 17),        /* USB31 */
        UNIPHIER_RESETX(16, 0x2014, 4),         /* USB30-PHY0 */
        UNIPHIER_RESETX(17, 0x2014, 0),         /* USB30-PHY1 */
        UNIPHIER_RESETX(18, 0x2014, 2),         /* USB30-PHY2 */
@@ -114,21 +90,27 @@ static const struct uniphier_reset_data uniphier_pxs2_sys_reset_data[] = {
 };
 
 static const struct uniphier_reset_data uniphier_ld11_sys_reset_data[] = {
-       UNIPHIER_LD11_SYS_RESET_NAND(2),
-       UNIPHIER_LD11_SYS_RESET_EMMC(4),
-       UNIPHIER_LD11_SYS_RESET_STDMAC(8),      /* HSC, MIO */
+       UNIPHIER_RESETX(2, 0x200c, 0),          /* NAND */
+       UNIPHIER_RESETX(4, 0x200c, 2),          /* eMMC */
+       UNIPHIER_RESETX(8, 0x200c, 8),          /* STDMAC (HSC, MIO) */
+       UNIPHIER_RESETX(40, 0x2008, 0),         /* AIO */
+       UNIPHIER_RESETX(41, 0x2008, 1),         /* EVEA */
+       UNIPHIER_RESETX(42, 0x2010, 2),         /* EXIV */
        UNIPHIER_RESET_END,
 };
 
 static const struct uniphier_reset_data uniphier_ld20_sys_reset_data[] = {
-       UNIPHIER_LD11_SYS_RESET_NAND(2),
-       UNIPHIER_LD11_SYS_RESET_EMMC(4),
-       UNIPHIER_LD11_SYS_RESET_STDMAC(8),      /* HSC */
-       UNIPHIER_LD20_SYS_RESET_GIO(12),        /* PCIe, USB3 */
+       UNIPHIER_RESETX(2, 0x200c, 0),          /* NAND */
+       UNIPHIER_RESETX(4, 0x200c, 2),          /* eMMC */
+       UNIPHIER_RESETX(8, 0x200c, 8),          /* STDMAC (HSC) */
+       UNIPHIER_RESETX(12, 0x200c, 5),         /* GIO (PCIe, USB3) */
        UNIPHIER_RESETX(16, 0x200c, 12),        /* USB30-PHY0 */
        UNIPHIER_RESETX(17, 0x200c, 13),        /* USB30-PHY1 */
        UNIPHIER_RESETX(18, 0x200c, 14),        /* USB30-PHY2 */
        UNIPHIER_RESETX(19, 0x200c, 15),        /* USB30-PHY3 */
+       UNIPHIER_RESETX(40, 0x2008, 0),         /* AIO */
+       UNIPHIER_RESETX(41, 0x2008, 1),         /* EVEA */
+       UNIPHIER_RESETX(42, 0x2010, 2),         /* EXIV */
        UNIPHIER_RESET_END,
 };
 
@@ -151,7 +133,7 @@ static const struct uniphier_reset_data uniphier_ld20_sys_reset_data[] = {
 #define UNIPHIER_MIO_RESET_DMAC(id)                    \
        UNIPHIER_RESETX((id), 0x110, 17)
 
-static const struct uniphier_reset_data uniphier_sld3_mio_reset_data[] = {
+static const struct uniphier_reset_data uniphier_ld4_mio_reset_data[] = {
        UNIPHIER_MIO_RESET_SD(0, 0),
        UNIPHIER_MIO_RESET_SD(1, 1),
        UNIPHIER_MIO_RESET_SD(2, 2),
@@ -163,11 +145,9 @@ static const struct uniphier_reset_data uniphier_sld3_mio_reset_data[] = {
        UNIPHIER_MIO_RESET_USB2(8, 0),
        UNIPHIER_MIO_RESET_USB2(9, 1),
        UNIPHIER_MIO_RESET_USB2(10, 2),
-       UNIPHIER_MIO_RESET_USB2(11, 3),
        UNIPHIER_MIO_RESET_USB2_BRIDGE(12, 0),
        UNIPHIER_MIO_RESET_USB2_BRIDGE(13, 1),
        UNIPHIER_MIO_RESET_USB2_BRIDGE(14, 2),
-       UNIPHIER_MIO_RESET_USB2_BRIDGE(15, 3),
        UNIPHIER_RESET_END,
 };
 
@@ -216,6 +196,12 @@ static const struct uniphier_reset_data uniphier_pro4_peri_reset_data[] = {
        UNIPHIER_RESET_END,
 };
 
+/* Analog signal amplifiers reset data */
+static const struct uniphier_reset_data uniphier_ld11_adamv_reset_data[] = {
+       UNIPHIER_RESETX(0, 0x10, 6), /* EVEA */
+       UNIPHIER_RESET_END,
+};
+
 /* core implementaton */
 struct uniphier_reset_priv {
        struct reset_controller_dev rcdev;
@@ -345,13 +331,9 @@ static int uniphier_reset_probe(struct platform_device *pdev)
 
 static const struct of_device_id uniphier_reset_match[] = {
        /* System reset */
-       {
-               .compatible = "socionext,uniphier-sld3-reset",
-               .data = uniphier_sld3_sys_reset_data,
-       },
        {
                .compatible = "socionext,uniphier-ld4-reset",
-               .data = uniphier_sld3_sys_reset_data,
+               .data = uniphier_ld4_sys_reset_data,
        },
        {
                .compatible = "socionext,uniphier-pro4-reset",
@@ -359,7 +341,7 @@ static const struct of_device_id uniphier_reset_match[] = {
        },
        {
                .compatible = "socionext,uniphier-sld8-reset",
-               .data = uniphier_sld3_sys_reset_data,
+               .data = uniphier_ld4_sys_reset_data,
        },
        {
                .compatible = "socionext,uniphier-pro5-reset",
@@ -378,21 +360,17 @@ static const struct of_device_id uniphier_reset_match[] = {
                .data = uniphier_ld20_sys_reset_data,
        },
        /* Media I/O reset, SD reset */
-       {
-               .compatible = "socionext,uniphier-sld3-mio-reset",
-               .data = uniphier_sld3_mio_reset_data,
-       },
        {
                .compatible = "socionext,uniphier-ld4-mio-reset",
-               .data = uniphier_sld3_mio_reset_data,
+               .data = uniphier_ld4_mio_reset_data,
        },
        {
                .compatible = "socionext,uniphier-pro4-mio-reset",
-               .data = uniphier_sld3_mio_reset_data,
+               .data = uniphier_ld4_mio_reset_data,
        },
        {
                .compatible = "socionext,uniphier-sld8-mio-reset",
-               .data = uniphier_sld3_mio_reset_data,
+               .data = uniphier_ld4_mio_reset_data,
        },
        {
                .compatible = "socionext,uniphier-pro5-sd-reset",
@@ -404,7 +382,7 @@ static const struct of_device_id uniphier_reset_match[] = {
        },
        {
                .compatible = "socionext,uniphier-ld11-mio-reset",
-               .data = uniphier_sld3_mio_reset_data,
+               .data = uniphier_ld4_mio_reset_data,
        },
        {
                .compatible = "socionext,uniphier-ld11-sd-reset",
@@ -443,6 +421,15 @@ static const struct of_device_id uniphier_reset_match[] = {
                .compatible = "socionext,uniphier-ld20-peri-reset",
                .data = uniphier_pro4_peri_reset_data,
        },
+       /* Analog signal amplifiers reset */
+       {
+               .compatible = "socionext,uniphier-ld11-adamv-reset",
+               .data = uniphier_ld11_adamv_reset_data,
+       },
+       {
+               .compatible = "socionext,uniphier-ld20-adamv-reset",
+               .data = uniphier_ld11_adamv_reset_data,
+       },
        { /* sentinel */ }
 };
 MODULE_DEVICE_TABLE(of, uniphier_reset_match);
index 4dabb9ec48418011d55a3dc6b96a513bb2ae54cd..4f319f7753d4db0d2ee430e2d67a05090c77adbb 100644 (file)
@@ -55,7 +55,7 @@ static int zx2967_reset_deassert(struct reset_controller_dev *rcdev,
        return zx2967_reset_act(rcdev, id, false);
 }
 
-static struct reset_control_ops zx2967_reset_ops = {
+static const struct reset_control_ops zx2967_reset_ops = {
        .assert         = zx2967_reset_assert,
        .deassert       = zx2967_reset_deassert,
 };
index 07fc0ac51c5280902c0935fe9175d819797e519d..fc9e9804742194ffb6b8559f5ba77d94e19fd1ac 100644 (file)
@@ -1,6 +1,7 @@
 menu "SOC (System On Chip) specific Drivers"
 
 source "drivers/soc/actions/Kconfig"
+source "drivers/soc/amlogic/Kconfig"
 source "drivers/soc/atmel/Kconfig"
 source "drivers/soc/bcm/Kconfig"
 source "drivers/soc/fsl/Kconfig"
index 9241125416bae359874c51e984bcb8dba5dfdfd7..280a6a91a9e26f1f8aa07b510d07ae698fde07b4 100644 (file)
@@ -10,6 +10,7 @@ obj-$(CONFIG_MACH_DOVE)               += dove/
 obj-y                          += fsl/
 obj-$(CONFIG_ARCH_MXC)         += imx/
 obj-$(CONFIG_ARCH_MEDIATEK)    += mediatek/
+obj-$(CONFIG_ARCH_MESON)       += amlogic/
 obj-$(CONFIG_ARCH_QCOM)                += qcom/
 obj-y                          += renesas/
 obj-$(CONFIG_ARCH_ROCKCHIP)    += rockchip/
diff --git a/drivers/soc/amlogic/Kconfig b/drivers/soc/amlogic/Kconfig
new file mode 100644 (file)
index 0000000..22acf06
--- /dev/null
@@ -0,0 +1,12 @@
+menu "Amlogic SoC drivers"
+
+config MESON_GX_SOCINFO
+       bool "Amlogic Meson GX SoC Information driver"
+       depends on ARCH_MESON || COMPILE_TEST
+       default ARCH_MESON
+       select SOC_BUS
+       help
+         Say yes to support decoding of Amlogic Meson GX SoC family
+         information about the type, package and version.
+
+endmenu
diff --git a/drivers/soc/amlogic/Makefile b/drivers/soc/amlogic/Makefile
new file mode 100644 (file)
index 0000000..3e85fc4
--- /dev/null
@@ -0,0 +1 @@
+obj-$(CONFIG_MESON_GX_SOCINFO) += meson-gx-socinfo.o
diff --git a/drivers/soc/amlogic/meson-gx-socinfo.c b/drivers/soc/amlogic/meson-gx-socinfo.c
new file mode 100644 (file)
index 0000000..89f4cf5
--- /dev/null
@@ -0,0 +1,177 @@
+/*
+ * Copyright (c) 2017 BayLibre, SAS
+ * Author: Neil Armstrong <narmstrong@baylibre.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_platform.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/sys_soc.h>
+#include <linux/bitfield.h>
+#include <linux/regmap.h>
+#include <linux/mfd/syscon.h>
+
+#define AO_SEC_SD_CFG8         0xe0
+#define AO_SEC_SOCINFO_OFFSET  AO_SEC_SD_CFG8
+
+#define SOCINFO_MAJOR  GENMASK(31, 24)
+#define SOCINFO_MINOR  GENMASK(23, 16)
+#define SOCINFO_PACK   GENMASK(15, 8)
+#define SOCINFO_MISC   GENMASK(7, 0)
+
+static const struct meson_gx_soc_id {
+       const char *name;
+       unsigned int id;
+} soc_ids[] = {
+       { "GXBB", 0x1f },
+       { "GXTVBB", 0x20 },
+       { "GXL", 0x21 },
+       { "GXM", 0x22 },
+       { "TXL", 0x23 },
+};
+
+static const struct meson_gx_package_id {
+       const char *name;
+       unsigned int major_id;
+       unsigned int pack_id;
+} soc_packages[] = {
+       { "S905", 0x1f, 0 },
+       { "S905M", 0x1f, 0x20 },
+       { "S905D", 0x21, 0 },
+       { "S905X", 0x21, 0x80 },
+       { "S905L", 0x21, 0xc0 },
+       { "S905M2", 0x21, 0xe0 },
+       { "S912", 0x22, 0 },
+};
+
+static inline unsigned int socinfo_to_major(u32 socinfo)
+{
+       return FIELD_GET(SOCINFO_MAJOR, socinfo);
+}
+
+static inline unsigned int socinfo_to_minor(u32 socinfo)
+{
+       return FIELD_GET(SOCINFO_MINOR, socinfo);
+}
+
+static inline unsigned int socinfo_to_pack(u32 socinfo)
+{
+       return FIELD_GET(SOCINFO_PACK, socinfo);
+}
+
+static inline unsigned int socinfo_to_misc(u32 socinfo)
+{
+       return FIELD_GET(SOCINFO_MISC, socinfo);
+}
+
+static const char *socinfo_to_package_id(u32 socinfo)
+{
+       unsigned int pack = socinfo_to_pack(socinfo) & 0xf0;
+       unsigned int major = socinfo_to_major(socinfo);
+       int i;
+
+       for (i = 0 ; i < ARRAY_SIZE(soc_packages) ; ++i) {
+               if (soc_packages[i].major_id == major &&
+                   soc_packages[i].pack_id == pack)
+                       return soc_packages[i].name;
+       }
+
+       return "Unknown";
+}
+
+static const char *socinfo_to_soc_id(u32 socinfo)
+{
+       unsigned int id = socinfo_to_major(socinfo);
+       int i;
+
+       for (i = 0 ; i < ARRAY_SIZE(soc_ids) ; ++i) {
+               if (soc_ids[i].id == id)
+                       return soc_ids[i].name;
+       }
+
+       return "Unknown";
+}
+
+int __init meson_gx_socinfo_init(void)
+{
+       struct soc_device_attribute *soc_dev_attr;
+       struct soc_device *soc_dev;
+       struct device_node *np;
+       struct regmap *regmap;
+       unsigned int socinfo;
+       struct device *dev;
+       int ret;
+
+       /* look up for chipid node */
+       np = of_find_compatible_node(NULL, NULL, "amlogic,meson-gx-ao-secure");
+       if (!np)
+               return -ENODEV;
+
+       /* check if interface is enabled */
+       if (!of_device_is_available(np))
+               return -ENODEV;
+
+       /* check if chip-id is available */
+       if (!of_property_read_bool(np, "amlogic,has-chip-id"))
+               return -ENODEV;
+
+       /* node should be a syscon */
+       regmap = syscon_node_to_regmap(np);
+       of_node_put(np);
+       if (IS_ERR(regmap)) {
+               pr_err("%s: failed to get regmap\n", __func__);
+               return -ENODEV;
+       }
+
+       ret = regmap_read(regmap, AO_SEC_SOCINFO_OFFSET, &socinfo);
+       if (ret < 0)
+               return ret;
+
+       if (!socinfo) {
+               pr_err("%s: invalid chipid value\n", __func__);
+               return -EINVAL;
+       }
+
+       soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL);
+       if (!soc_dev_attr)
+               return -ENODEV;
+
+       soc_dev_attr->family = "Amlogic Meson";
+
+       np = of_find_node_by_path("/");
+       of_property_read_string(np, "model", &soc_dev_attr->machine);
+       of_node_put(np);
+
+       soc_dev_attr->revision = kasprintf(GFP_KERNEL, "%x:%x - %x:%x",
+                                          socinfo_to_major(socinfo),
+                                          socinfo_to_minor(socinfo),
+                                          socinfo_to_pack(socinfo),
+                                          socinfo_to_misc(socinfo));
+       soc_dev_attr->soc_id = kasprintf(GFP_KERNEL, "%s (%s)",
+                                        socinfo_to_soc_id(socinfo),
+                                        socinfo_to_package_id(socinfo));
+
+       soc_dev = soc_device_register(soc_dev_attr);
+       if (IS_ERR(soc_dev)) {
+               kfree(soc_dev_attr->revision);
+               kfree_const(soc_dev_attr->soc_id);
+               kfree(soc_dev_attr);
+               return PTR_ERR(soc_dev);
+       }
+       dev = soc_device_to_device(soc_dev);
+
+       dev_info(dev, "Amlogic Meson %s Revision %x:%x (%x:%x) Detected\n",
+                       soc_dev_attr->soc_id,
+                       socinfo_to_major(socinfo),
+                       socinfo_to_minor(socinfo),
+                       socinfo_to_pack(socinfo),
+                       socinfo_to_misc(socinfo));
+
+       return 0;
+}
+device_initcall(meson_gx_socinfo_init);
index a8e8389a6894fbd5c277f9cc87f10de413d210df..eaa9585c7347518f3054e6b176b9521d05e7c01a 100644 (file)
@@ -177,8 +177,8 @@ static int fsl_bman_probe(struct platform_device *pdev)
 
        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
        if (!res) {
-               dev_err(dev, "Can't get %s property 'IORESOURCE_MEM'\n",
-                       node->full_name);
+               dev_err(dev, "Can't get %pOF property 'IORESOURCE_MEM'\n",
+                       node);
                return -ENXIO;
        }
        bm_ccsr_start = devm_ioremap(dev, res->start, resource_size(res));
@@ -205,14 +205,14 @@ static int fsl_bman_probe(struct platform_device *pdev)
 
        err_irq = platform_get_irq(pdev, 0);
        if (err_irq <= 0) {
-               dev_info(dev, "Can't get %s IRQ\n", node->full_name);
+               dev_info(dev, "Can't get %pOF IRQ\n", node);
                return -ENODEV;
        }
        ret = devm_request_irq(dev, err_irq, bman_isr, IRQF_SHARED, "bman-err",
                               dev);
        if (ret)  {
-               dev_err(dev, "devm_request_irq() failed %d for '%s'\n",
-                       ret, node->full_name);
+               dev_err(dev, "devm_request_irq() failed %d for '%pOF'\n",
+                       ret, node);
                return ret;
        }
        /* Disable Buffer Pool State Change */
index 8354d4dabdadf50dbf685738a61db4e98f4176f2..39b39c8f1399b8d12cfb0a569b6f051ece995f26 100644 (file)
@@ -103,16 +103,14 @@ static int bman_portal_probe(struct platform_device *pdev)
        addr_phys[0] = platform_get_resource(pdev, IORESOURCE_MEM,
                                             DPAA_PORTAL_CE);
        if (!addr_phys[0]) {
-               dev_err(dev, "Can't get %s property 'reg::CE'\n",
-                       node->full_name);
+               dev_err(dev, "Can't get %pOF property 'reg::CE'\n", node);
                return -ENXIO;
        }
 
        addr_phys[1] = platform_get_resource(pdev, IORESOURCE_MEM,
                                             DPAA_PORTAL_CI);
        if (!addr_phys[1]) {
-               dev_err(dev, "Can't get %s property 'reg::CI'\n",
-                       node->full_name);
+               dev_err(dev, "Can't get %pOF property 'reg::CI'\n", node);
                return -ENXIO;
        }
 
@@ -120,7 +118,7 @@ static int bman_portal_probe(struct platform_device *pdev)
 
        irq = platform_get_irq(pdev, 0);
        if (irq <= 0) {
-               dev_err(dev, "Can't get %s IRQ'\n", node->full_name);
+               dev_err(dev, "Can't get %pOF IRQ'\n", node);
                return -ENXIO;
        }
        pcfg->irq = irq;
index 90bc40c48675484b03d48a6fba743b7b2719945e..835ce947ffca599b0fcb013202b6608a7e889732 100644 (file)
@@ -695,8 +695,8 @@ static int fsl_qman_probe(struct platform_device *pdev)
 
        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
        if (!res) {
-               dev_err(dev, "Can't get %s property 'IORESOURCE_MEM'\n",
-                       node->full_name);
+               dev_err(dev, "Can't get %pOF property 'IORESOURCE_MEM'\n",
+                       node);
                return -ENXIO;
        }
        qm_ccsr_start = devm_ioremap(dev, res->start, resource_size(res));
@@ -740,15 +740,15 @@ static int fsl_qman_probe(struct platform_device *pdev)
 
        err_irq = platform_get_irq(pdev, 0);
        if (err_irq <= 0) {
-               dev_info(dev, "Can't get %s property 'interrupts'\n",
-                        node->full_name);
+               dev_info(dev, "Can't get %pOF property 'interrupts'\n",
+                        node);
                return -ENODEV;
        }
        ret = devm_request_irq(dev, err_irq, qman_isr, IRQF_SHARED, "qman-err",
                               dev);
        if (ret)  {
-               dev_err(dev, "devm_request_irq() failed %d for '%s'\n",
-                       ret, node->full_name);
+               dev_err(dev, "devm_request_irq() failed %d for '%pOF'\n",
+                       ret, node);
                return ret;
        }
 
index adbaa30d3c5ad12aadf5bfa3c01829c392657f1a..cbacdf4f98edaf63bd0c9c80e3c5c8c750464153 100644 (file)
@@ -237,30 +237,27 @@ static int qman_portal_probe(struct platform_device *pdev)
        addr_phys[0] = platform_get_resource(pdev, IORESOURCE_MEM,
                                             DPAA_PORTAL_CE);
        if (!addr_phys[0]) {
-               dev_err(dev, "Can't get %s property 'reg::CE'\n",
-                       node->full_name);
+               dev_err(dev, "Can't get %pOF property 'reg::CE'\n", node);
                return -ENXIO;
        }
 
        addr_phys[1] = platform_get_resource(pdev, IORESOURCE_MEM,
                                             DPAA_PORTAL_CI);
        if (!addr_phys[1]) {
-               dev_err(dev, "Can't get %s property 'reg::CI'\n",
-                       node->full_name);
+               dev_err(dev, "Can't get %pOF property 'reg::CI'\n", node);
                return -ENXIO;
        }
 
        err = of_property_read_u32(node, "cell-index", &val);
        if (err) {
-               dev_err(dev, "Can't get %s property 'cell-index'\n",
-                       node->full_name);
+               dev_err(dev, "Can't get %pOF property 'cell-index'\n", node);
                return err;
        }
        pcfg->channel = val;
        pcfg->cpu = -1;
        irq = platform_get_irq(pdev, 0);
        if (irq <= 0) {
-               dev_err(dev, "Can't get %s IRQ\n", node->full_name);
+               dev_err(dev, "Can't get %pOF IRQ\n", node);
                return -ENXIO;
        }
        pcfg->irq = irq;
index 0aaf429f31d571f569fe0916b52d10cf3dadfd49..3b27075c21a7f41e6fdd2cdd591cac2da8713600 100644 (file)
@@ -304,8 +304,8 @@ static int __init qe_add_gpiochips(void)
                        goto err;
                continue;
 err:
-               pr_err("%s: registration failed with status %d\n",
-                      np->full_name, ret);
+               pr_err("%pOF: registration failed with status %d\n",
+                      np, ret);
                kfree(qe_gc);
                /* try others anyway */
        }
index c80a04e1b2b16f83c60759b74f26fa9ad44727e4..c2048382830f74739ca2763b4360911f91d6e4b6 100644 (file)
@@ -1067,7 +1067,7 @@ static const struct pmic_wrapper_type pwrap_mt2701 = {
        .init_soc_specific = pwrap_mt2701_init_soc_specific,
 };
 
-static struct pmic_wrapper_type pwrap_mt8135 = {
+static const struct pmic_wrapper_type pwrap_mt8135 = {
        .regs = mt8135_regs,
        .type = PWRAP_MT8135,
        .arb_en_all = 0x1ff,
@@ -1079,7 +1079,7 @@ static struct pmic_wrapper_type pwrap_mt8135 = {
        .init_soc_specific = pwrap_mt8135_init_soc_specific,
 };
 
-static struct pmic_wrapper_type pwrap_mt8173 = {
+static const struct pmic_wrapper_type pwrap_mt8173 = {
        .regs = mt8173_regs,
        .type = PWRAP_MT8173,
        .arb_en_all = 0x3f,
@@ -1091,7 +1091,7 @@ static struct pmic_wrapper_type pwrap_mt8173 = {
        .init_soc_specific = pwrap_mt8173_init_soc_specific,
 };
 
-static struct of_device_id of_pwrap_match_tbl[] = {
+static const struct of_device_id of_pwrap_match_tbl[] = {
        {
                .compatible = "mediatek,mt2701-pwrap",
                .data = &pwrap_mt2701,
@@ -1233,8 +1233,8 @@ static int pwrap_probe(struct platform_device *pdev)
 
        ret = of_platform_populate(np, NULL, NULL, wrp->dev);
        if (ret) {
-               dev_dbg(wrp->dev, "failed to create child devices at %s\n",
-                               np->full_name);
+               dev_dbg(wrp->dev, "failed to create child devices at %pOF\n",
+                               np);
                goto err_out2;
        }
 
index ceb2cc495cd0d3f47d2882419566553fec6c3e87..e1ce8b1b5090aa0a7b91b6abcd73ad7fa0760261 100644 (file)
@@ -22,6 +22,7 @@
 
 #include <dt-bindings/power/mt2701-power.h>
 #include <dt-bindings/power/mt6797-power.h>
+#include <dt-bindings/power/mt7622-power.h>
 #include <dt-bindings/power/mt8173-power.h>
 
 #define SPM_VDE_PWR_CON                        0x0210
 #define SPM_MFG_2D_PWR_CON             0x02c0
 #define SPM_MFG_ASYNC_PWR_CON          0x02c4
 #define SPM_USB_PWR_CON                        0x02cc
+#define SPM_ETHSYS_PWR_CON             0x02e0  /* MT7622 */
+#define SPM_HIF0_PWR_CON               0x02e4  /* MT7622 */
+#define SPM_HIF1_PWR_CON               0x02e8  /* MT7622 */
+#define SPM_WB_PWR_CON                 0x02ec  /* MT7622 */
+
 
 #define SPM_PWR_STATUS                 0x060c
 #define SPM_PWR_STATUS_2ND             0x0610
 #define PWR_STATUS_MFG_ASYNC           BIT(23)
 #define PWR_STATUS_AUDIO               BIT(24)
 #define PWR_STATUS_USB                 BIT(25)
+#define PWR_STATUS_ETHSYS              BIT(24) /* MT7622 */
+#define PWR_STATUS_HIF0                        BIT(25) /* MT7622 */
+#define PWR_STATUS_HIF1                        BIT(26) /* MT7622 */
+#define PWR_STATUS_WB                  BIT(27) /* MT7622 */
 
 enum clk_id {
        CLK_NONE,
@@ -73,6 +83,7 @@ enum clk_id {
        CLK_VENC_LT,
        CLK_ETHIF,
        CLK_VDEC,
+       CLK_HIFSEL,
        CLK_MAX,
 };
 
@@ -84,6 +95,7 @@ static const char * const clk_names[] = {
        "venc_lt",
        "ethif",
        "vdec",
+       "hif_sel",
        NULL,
 };
 
@@ -124,6 +136,19 @@ struct scp {
        struct scp_ctrl_reg ctrl_reg;
 };
 
+struct scp_subdomain {
+       int origin;
+       int subdomain;
+};
+
+struct scp_soc_data {
+       const struct scp_domain_data *domains;
+       int num_domains;
+       const struct scp_subdomain *subdomains;
+       int num_subdomains;
+       const struct scp_ctrl_reg regs;
+};
+
 static int scpsys_domain_is_on(struct scp_domain *scpd)
 {
        struct scp *scp = scpd->scp;
@@ -357,7 +382,7 @@ static void init_clks(struct platform_device *pdev, struct clk **clk)
 
 static struct scp *init_scp(struct platform_device *pdev,
                        const struct scp_domain_data *scp_domain_data, int num,
-                       struct scp_ctrl_reg *scp_ctrl_reg)
+                       const struct scp_ctrl_reg *scp_ctrl_reg)
 {
        struct genpd_onecell_data *pd_data;
        struct resource *res;
@@ -565,26 +590,6 @@ static const struct scp_domain_data scp_domain_data_mt2701[] = {
        },
 };
 
-#define NUM_DOMAINS_MT2701     ARRAY_SIZE(scp_domain_data_mt2701)
-
-static int __init scpsys_probe_mt2701(struct platform_device *pdev)
-{
-       struct scp *scp;
-       struct scp_ctrl_reg scp_reg;
-
-       scp_reg.pwr_sta_offs = SPM_PWR_STATUS;
-       scp_reg.pwr_sta2nd_offs = SPM_PWR_STATUS_2ND;
-
-       scp = init_scp(pdev, scp_domain_data_mt2701, NUM_DOMAINS_MT2701,
-                      &scp_reg);
-       if (IS_ERR(scp))
-               return PTR_ERR(scp);
-
-       mtk_register_power_domains(pdev, scp, NUM_DOMAINS_MT2701);
-
-       return 0;
-}
-
 /*
  * MT6797 power domain support
  */
@@ -649,51 +654,62 @@ static const struct scp_domain_data scp_domain_data_mt6797[] = {
        },
 };
 
-#define NUM_DOMAINS_MT6797     ARRAY_SIZE(scp_domain_data_mt6797)
 #define SPM_PWR_STATUS_MT6797          0x0180
 #define SPM_PWR_STATUS_2ND_MT6797      0x0184
 
-static int __init scpsys_probe_mt6797(struct platform_device *pdev)
-{
-       struct scp *scp;
-       struct genpd_onecell_data *pd_data;
-       int ret;
-       struct scp_ctrl_reg scp_reg;
-
-       scp_reg.pwr_sta_offs = SPM_PWR_STATUS_MT6797;
-       scp_reg.pwr_sta2nd_offs = SPM_PWR_STATUS_2ND_MT6797;
-
-       scp = init_scp(pdev, scp_domain_data_mt6797, NUM_DOMAINS_MT6797,
-                      &scp_reg);
-       if (IS_ERR(scp))
-               return PTR_ERR(scp);
-
-       mtk_register_power_domains(pdev, scp, NUM_DOMAINS_MT6797);
-
-       pd_data = &scp->pd_data;
-
-       ret = pm_genpd_add_subdomain(pd_data->domains[MT6797_POWER_DOMAIN_MM],
-                                    pd_data->domains[MT6797_POWER_DOMAIN_VDEC]);
-       if (ret && IS_ENABLED(CONFIG_PM))
-               dev_err(&pdev->dev, "Failed to add subdomain: %d\n", ret);
-
-       ret = pm_genpd_add_subdomain(pd_data->domains[MT6797_POWER_DOMAIN_MM],
-                                    pd_data->domains[MT6797_POWER_DOMAIN_ISP]);
-       if (ret && IS_ENABLED(CONFIG_PM))
-               dev_err(&pdev->dev, "Failed to add subdomain: %d\n", ret);
-
-       ret = pm_genpd_add_subdomain(pd_data->domains[MT6797_POWER_DOMAIN_MM],
-                                    pd_data->domains[MT6797_POWER_DOMAIN_VENC]);
-       if (ret && IS_ENABLED(CONFIG_PM))
-               dev_err(&pdev->dev, "Failed to add subdomain: %d\n", ret);
+static const struct scp_subdomain scp_subdomain_mt6797[] = {
+       {MT6797_POWER_DOMAIN_MM, MT6797_POWER_DOMAIN_VDEC},
+       {MT6797_POWER_DOMAIN_MM, MT6797_POWER_DOMAIN_ISP},
+       {MT6797_POWER_DOMAIN_MM, MT6797_POWER_DOMAIN_VENC},
+       {MT6797_POWER_DOMAIN_MM, MT6797_POWER_DOMAIN_MJC},
+};
 
-       ret = pm_genpd_add_subdomain(pd_data->domains[MT6797_POWER_DOMAIN_MM],
-                                    pd_data->domains[MT6797_POWER_DOMAIN_MJC]);
-       if (ret && IS_ENABLED(CONFIG_PM))
-               dev_err(&pdev->dev, "Failed to add subdomain: %d\n", ret);
+/*
+ * MT7622 power domain support
+ */
 
-       return 0;
-}
+static const struct scp_domain_data scp_domain_data_mt7622[] = {
+       [MT7622_POWER_DOMAIN_ETHSYS] = {
+               .name = "ethsys",
+               .sta_mask = PWR_STATUS_ETHSYS,
+               .ctl_offs = SPM_ETHSYS_PWR_CON,
+               .sram_pdn_bits = GENMASK(11, 8),
+               .sram_pdn_ack_bits = GENMASK(15, 12),
+               .clk_id = {CLK_NONE},
+               .bus_prot_mask = MT7622_TOP_AXI_PROT_EN_ETHSYS,
+               .active_wakeup = true,
+       },
+       [MT7622_POWER_DOMAIN_HIF0] = {
+               .name = "hif0",
+               .sta_mask = PWR_STATUS_HIF0,
+               .ctl_offs = SPM_HIF0_PWR_CON,
+               .sram_pdn_bits = GENMASK(11, 8),
+               .sram_pdn_ack_bits = GENMASK(15, 12),
+               .clk_id = {CLK_HIFSEL},
+               .bus_prot_mask = MT7622_TOP_AXI_PROT_EN_HIF0,
+               .active_wakeup = true,
+       },
+       [MT7622_POWER_DOMAIN_HIF1] = {
+               .name = "hif1",
+               .sta_mask = PWR_STATUS_HIF1,
+               .ctl_offs = SPM_HIF1_PWR_CON,
+               .sram_pdn_bits = GENMASK(11, 8),
+               .sram_pdn_ack_bits = GENMASK(15, 12),
+               .clk_id = {CLK_HIFSEL},
+               .bus_prot_mask = MT7622_TOP_AXI_PROT_EN_HIF1,
+               .active_wakeup = true,
+       },
+       [MT7622_POWER_DOMAIN_WB] = {
+               .name = "wb",
+               .sta_mask = PWR_STATUS_WB,
+               .ctl_offs = SPM_WB_PWR_CON,
+               .sram_pdn_bits = 0,
+               .sram_pdn_ack_bits = 0,
+               .clk_id = {CLK_NONE},
+               .bus_prot_mask = MT7622_TOP_AXI_PROT_EN_WB,
+               .active_wakeup = true,
+       },
+};
 
 /*
  * MT8173 power domain support
@@ -789,39 +805,50 @@ static const struct scp_domain_data scp_domain_data_mt8173[] = {
        },
 };
 
-#define NUM_DOMAINS_MT8173     ARRAY_SIZE(scp_domain_data_mt8173)
-
-static int __init scpsys_probe_mt8173(struct platform_device *pdev)
-{
-       struct scp *scp;
-       struct genpd_onecell_data *pd_data;
-       int ret;
-       struct scp_ctrl_reg scp_reg;
-
-       scp_reg.pwr_sta_offs = SPM_PWR_STATUS;
-       scp_reg.pwr_sta2nd_offs = SPM_PWR_STATUS_2ND;
-
-       scp = init_scp(pdev, scp_domain_data_mt8173, NUM_DOMAINS_MT8173,
-                      &scp_reg);
-       if (IS_ERR(scp))
-               return PTR_ERR(scp);
-
-       mtk_register_power_domains(pdev, scp, NUM_DOMAINS_MT8173);
+static const struct scp_subdomain scp_subdomain_mt8173[] = {
+       {MT8173_POWER_DOMAIN_MFG_ASYNC, MT8173_POWER_DOMAIN_MFG_2D},
+       {MT8173_POWER_DOMAIN_MFG_2D, MT8173_POWER_DOMAIN_MFG},
+};
 
-       pd_data = &scp->pd_data;
+static const struct scp_soc_data mt2701_data = {
+       .domains = scp_domain_data_mt2701,
+       .num_domains = ARRAY_SIZE(scp_domain_data_mt2701),
+       .regs = {
+               .pwr_sta_offs = SPM_PWR_STATUS,
+               .pwr_sta2nd_offs = SPM_PWR_STATUS_2ND
+       }
+};
 
-       ret = pm_genpd_add_subdomain(pd_data->domains[MT8173_POWER_DOMAIN_MFG_ASYNC],
-               pd_data->domains[MT8173_POWER_DOMAIN_MFG_2D]);
-       if (ret && IS_ENABLED(CONFIG_PM))
-               dev_err(&pdev->dev, "Failed to add subdomain: %d\n", ret);
+static const struct scp_soc_data mt6797_data = {
+       .domains = scp_domain_data_mt6797,
+       .num_domains = ARRAY_SIZE(scp_domain_data_mt6797),
+       .subdomains = scp_subdomain_mt6797,
+       .num_subdomains = ARRAY_SIZE(scp_subdomain_mt6797),
+       .regs = {
+               .pwr_sta_offs = SPM_PWR_STATUS_MT6797,
+               .pwr_sta2nd_offs = SPM_PWR_STATUS_2ND_MT6797
+       }
+};
 
-       ret = pm_genpd_add_subdomain(pd_data->domains[MT8173_POWER_DOMAIN_MFG_2D],
-               pd_data->domains[MT8173_POWER_DOMAIN_MFG]);
-       if (ret && IS_ENABLED(CONFIG_PM))
-               dev_err(&pdev->dev, "Failed to add subdomain: %d\n", ret);
+static const struct scp_soc_data mt7622_data = {
+       .domains = scp_domain_data_mt7622,
+       .num_domains = ARRAY_SIZE(scp_domain_data_mt7622),
+       .regs = {
+               .pwr_sta_offs = SPM_PWR_STATUS,
+               .pwr_sta2nd_offs = SPM_PWR_STATUS_2ND
+       }
+};
 
-       return 0;
-}
+static const struct scp_soc_data mt8173_data = {
+       .domains = scp_domain_data_mt8173,
+       .num_domains = ARRAY_SIZE(scp_domain_data_mt8173),
+       .subdomains = scp_subdomain_mt8173,
+       .num_subdomains = ARRAY_SIZE(scp_subdomain_mt8173),
+       .regs = {
+               .pwr_sta_offs = SPM_PWR_STATUS,
+               .pwr_sta2nd_offs = SPM_PWR_STATUS_2ND
+       }
+};
 
 /*
  * scpsys driver init
@@ -830,13 +857,16 @@ static int __init scpsys_probe_mt8173(struct platform_device *pdev)
 static const struct of_device_id of_scpsys_match_tbl[] = {
        {
                .compatible = "mediatek,mt2701-scpsys",
-               .data = scpsys_probe_mt2701,
+               .data = &mt2701_data,
        }, {
                .compatible = "mediatek,mt6797-scpsys",
-               .data = scpsys_probe_mt6797,
+               .data = &mt6797_data,
+       }, {
+               .compatible = "mediatek,mt7622-scpsys",
+               .data = &mt7622_data,
        }, {
                .compatible = "mediatek,mt8173-scpsys",
-               .data = scpsys_probe_mt8173,
+               .data = &mt8173_data,
        }, {
                /* sentinel */
        }
@@ -844,16 +874,33 @@ static const struct of_device_id of_scpsys_match_tbl[] = {
 
 static int scpsys_probe(struct platform_device *pdev)
 {
-       int (*probe)(struct platform_device *);
-       const struct of_device_id *of_id;
+       const struct of_device_id *match;
+       const struct scp_subdomain *sd;
+       const struct scp_soc_data *soc;
+       struct scp *scp;
+       struct genpd_onecell_data *pd_data;
+       int i, ret;
 
-       of_id = of_match_node(of_scpsys_match_tbl, pdev->dev.of_node);
-       if (!of_id || !of_id->data)
-               return -EINVAL;
+       match = of_match_device(of_scpsys_match_tbl, &pdev->dev);
+       soc = (const struct scp_soc_data *)match->data;
+
+       scp = init_scp(pdev, soc->domains, soc->num_domains, &soc->regs);
+       if (IS_ERR(scp))
+               return PTR_ERR(scp);
 
-       probe = of_id->data;
+       mtk_register_power_domains(pdev, scp, soc->num_domains);
 
-       return probe(pdev);
+       pd_data = &scp->pd_data;
+
+       for (i = 0, sd = soc->subdomains ; i < soc->num_subdomains ; i++) {
+               ret = pm_genpd_add_subdomain(pd_data->domains[sd->origin],
+                                            pd_data->domains[sd->subdomain]);
+               if (ret && IS_ENABLED(CONFIG_PM))
+                       dev_err(&pdev->dev, "Failed to add subdomain: %d\n",
+                               ret);
+       }
+
+       return 0;
 }
 
 static struct platform_driver scpsys_drv = {
index d0fc331972d20bafd37d9f507e30830a91875e44..b00bccddcd3b81b15f3ea71ebeafde3376efee5d 100644 (file)
@@ -1,6 +1,8 @@
 #
 # QCOM Soc drivers
 #
+menu "Qualcomm SoC drivers"
+
 config QCOM_GLINK_SSR
        tristate "Qualcomm Glink SSR driver"
        depends on RPMSG
@@ -83,3 +85,5 @@ config QCOM_WCNSS_CTRL
        help
          Client driver for the WCNSS_CTRL SMD channel, used to download nv
          firmware to a newly booted WCNSS chip.
+
+endmenu
index bd63df0d14e09f9d0bbc8244c2f0e582ea98dc26..08bd8549242a9d2445ac7aca845f716a97b54ac8 100644 (file)
@@ -178,14 +178,13 @@ int qcom_mdt_load(struct device *dev, const struct firmware *fw,
 
                if (phdr->p_filesz) {
                        sprintf(fw_name + fw_name_len - 3, "b%02d", i);
-                       ret = request_firmware(&seg_fw, fw_name, dev);
+                       ret = request_firmware_into_buf(&seg_fw, fw_name, dev,
+                                                       ptr, phdr->p_filesz);
                        if (ret) {
                                dev_err(dev, "failed to load %s\n", fw_name);
                                break;
                        }
 
-                       memcpy(ptr, seg_fw->data, seg_fw->size);
-
                        release_firmware(seg_fw);
                }
 
index dc540ea92e9d8649de0ef405eca6a146b452a886..403bea9d546bbc947eaa5cbbe22bd3a974668980 100644 (file)
@@ -496,7 +496,8 @@ static int qcom_smsm_probe(struct platform_device *pdev)
        if (!smsm->hosts)
                return -ENOMEM;
 
-       local_node = of_find_node_with_property(pdev->dev.of_node, "#qcom,smem-state-cells");
+       local_node = of_find_node_with_property(of_node_get(pdev->dev.of_node),
+                                               "#qcom,smem-state-cells");
        if (!local_node) {
                dev_err(&pdev->dev, "no state entry\n");
                return -EINVAL;
index b9069184df193f34aa6d9c8bfa4f6502d6764574..d008e5b82db4bc411f889409c4e7e39d11907cbc 100644 (file)
@@ -347,6 +347,7 @@ static const struct of_device_id wcnss_ctrl_of_match[] = {
        { .compatible = "qcom,wcnss", },
        {}
 };
+MODULE_DEVICE_TABLE(of, wcnss_ctrl_of_match);
 
 static struct rpmsg_driver wcnss_ctrl_driver = {
        .probe = wcnss_ctrl_probe,
index 87a4be46bd9834c13d9a09c3dc81b90e2b175e61..567414cb42ba20757ed1590d458ec826593314cd 100644 (file)
@@ -3,7 +3,7 @@ config SOC_RENESAS
        default y if ARCH_RENESAS
        select SOC_BUS
        select RST_RCAR if ARCH_RCAR_GEN1 || ARCH_RCAR_GEN2 || \
-                          ARCH_R8A7795 || ARCH_R8A7796
+                          ARCH_R8A7795 || ARCH_R8A7796 || ARCH_R8A77995
        select SYSC_R8A7743 if ARCH_R8A7743
        select SYSC_R8A7745 if ARCH_R8A7745
        select SYSC_R8A7779 if ARCH_R8A7779
@@ -13,6 +13,7 @@ config SOC_RENESAS
        select SYSC_R8A7794 if ARCH_R8A7794
        select SYSC_R8A7795 if ARCH_R8A7795
        select SYSC_R8A7796 if ARCH_R8A7796
+       select SYSC_R8A77995 if ARCH_R8A77995
 
 if SOC_RENESAS
 
@@ -53,6 +54,10 @@ config SYSC_R8A7796
        bool "R-Car M3-W System Controller support" if COMPILE_TEST
        select SYSC_RCAR
 
+config SYSC_R8A77995
+       bool "R-Car D3 System Controller support" if COMPILE_TEST
+       select SYSC_RCAR
+
 # Family
 config RST_RCAR
        bool "R-Car Reset Controller support" if COMPILE_TEST
index 1a1a297b26a796133977f2f6c99b9b5febdffa83..6b6e7f16104c8dbbf8f489db35c780afe7e9aa9b 100644 (file)
@@ -11,6 +11,7 @@ obj-$(CONFIG_SYSC_R8A7792)    += r8a7792-sysc.o
 obj-$(CONFIG_SYSC_R8A7794)     += r8a7794-sysc.o
 obj-$(CONFIG_SYSC_R8A7795)     += r8a7795-sysc.o
 obj-$(CONFIG_SYSC_R8A7796)     += r8a7796-sysc.o
+obj-$(CONFIG_SYSC_R8A77995)    += r8a77995-sysc.o
 
 # Family
 obj-$(CONFIG_RST_RCAR)         += rcar-rst.o
diff --git a/drivers/soc/renesas/r8a77995-sysc.c b/drivers/soc/renesas/r8a77995-sysc.c
new file mode 100644 (file)
index 0000000..f718429
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+ * Renesas R-Car D3 System Controller
+ *
+ * Copyright (C) 2017 Glider bvba
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ */
+
+#include <linux/bug.h>
+#include <linux/kernel.h>
+#include <linux/sys_soc.h>
+
+#include <dt-bindings/power/r8a77995-sysc.h>
+
+#include "rcar-sysc.h"
+
+static struct rcar_sysc_area r8a77995_areas[] __initdata = {
+       { "always-on",     0, 0, R8A77995_PD_ALWAYS_ON, -1, PD_ALWAYS_ON },
+       { "ca53-scu",  0x140, 0, R8A77995_PD_CA53_SCU,  R8A77995_PD_ALWAYS_ON,
+         PD_SCU },
+       { "ca53-cpu0", 0x200, 0, R8A77995_PD_CA53_CPU0, R8A77995_PD_CA53_SCU,
+         PD_CPU_NOCR },
+};
+
+
+const struct rcar_sysc_info r8a77995_sysc_info __initconst = {
+       .areas = r8a77995_areas,
+       .num_areas = ARRAY_SIZE(r8a77995_areas),
+};
index a6d1c26d31675cf36ebc311a17a993704e0af688..baa47014e96b54b9aeda3798257ce6a0cdea12c7 100644 (file)
@@ -41,6 +41,7 @@ static const struct of_device_id rcar_rst_matches[] __initconst = {
        /* R-Car Gen3 is handled like R-Car Gen2 */
        { .compatible = "renesas,r8a7795-rst", .data = &rcar_rst_gen2 },
        { .compatible = "renesas,r8a7796-rst", .data = &rcar_rst_gen2 },
+       { .compatible = "renesas,r8a77995-rst", .data = &rcar_rst_gen2 },
        { /* sentinel */ }
 };
 
@@ -61,7 +62,7 @@ static int __init rcar_rst_init(void)
 
        base = of_iomap(np, 0);
        if (!base) {
-               pr_warn("%s: Cannot map regs\n", np->full_name);
+               pr_warn("%pOF: Cannot map regs\n", np);
                error = -ENOMEM;
                goto out_put;
        }
@@ -70,7 +71,7 @@ static int __init rcar_rst_init(void)
        cfg = match->data;
        saved_mode = ioread32(base + cfg->modemr);
 
-       pr_debug("%s: MODE = 0x%08x\n", np->full_name, saved_mode);
+       pr_debug("%pOF: MODE = 0x%08x\n", np, saved_mode);
 
 out_put:
        of_node_put(np);
index 7c8da3c90011422fdec0404fc97a6b5c36949be5..c8406e81640f6560f94b8914597ab91a7e30950e 100644 (file)
@@ -283,6 +283,9 @@ static const struct of_device_id rcar_sysc_matches[] = {
 #endif
 #ifdef CONFIG_SYSC_R8A7796
        { .compatible = "renesas,r8a7796-sysc", .data = &r8a7796_sysc_info },
+#endif
+#ifdef CONFIG_SYSC_R8A77995
+       { .compatible = "renesas,r8a77995-sysc", .data = &r8a77995_sysc_info },
 #endif
        { /* sentinel */ }
 };
@@ -323,7 +326,7 @@ static int __init rcar_sysc_pd_init(void)
 
        base = of_iomap(np, 0);
        if (!base) {
-               pr_warn("%s: Cannot map regs\n", np->full_name);
+               pr_warn("%pOF: Cannot map regs\n", np);
                error = -ENOMEM;
                goto out_put;
        }
@@ -348,13 +351,13 @@ static int __init rcar_sysc_pd_init(void)
         */
        syscimr = ioread32(base + SYSCIMR);
        syscimr |= syscier;
-       pr_debug("%s: syscimr = 0x%08x\n", np->full_name, syscimr);
+       pr_debug("%pOF: syscimr = 0x%08x\n", np, syscimr);
        iowrite32(syscimr, base + SYSCIMR);
 
        /*
         * SYSC needs all interrupt sources enabled to control power.
         */
-       pr_debug("%s: syscier = 0x%08x\n", np->full_name, syscier);
+       pr_debug("%pOF: syscier = 0x%08x\n", np, syscier);
        iowrite32(syscier, base + SYSCIER);
 
        for (i = 0; i < info->num_areas; i++) {
index 1a5bebaf54ba191c3fae00842a5dbe6c63447cc2..2f524922c4d261bfb14d52937eb4b1e5cf65678a 100644 (file)
@@ -58,6 +58,7 @@ extern const struct rcar_sysc_info r8a7792_sysc_info;
 extern const struct rcar_sysc_info r8a7794_sysc_info;
 extern const struct rcar_sysc_info r8a7795_sysc_info;
 extern const struct rcar_sysc_info r8a7796_sysc_info;
+extern const struct rcar_sysc_info r8a77995_sysc_info;
 
 
     /*
index ca26f13d399cf4c12bb2a8e92b2ab526cdee049c..90d6b7a4340a6ee3b7226c1c0a562b874efc79ef 100644 (file)
@@ -144,6 +144,11 @@ static const struct renesas_soc soc_rcar_m3_w __initconst __maybe_unused = {
        .id     = 0x52,
 };
 
+static const struct renesas_soc soc_rcar_d3 __initconst __maybe_unused = {
+       .family = &fam_rcar_gen3,
+       .id     = 0x58,
+};
+
 static const struct renesas_soc soc_shmobile_ag5 __initconst __maybe_unused = {
        .family = &fam_shmobile,
        .id     = 0x37,
@@ -199,6 +204,9 @@ static const struct of_device_id renesas_socs[] __initconst = {
 #ifdef CONFIG_ARCH_R8A7796
        { .compatible = "renesas,r8a7796",      .data = &soc_rcar_m3_w },
 #endif
+#ifdef CONFIG_ARCH_R8A77995
+       { .compatible = "renesas,r8a77995",     .data = &soc_rcar_d3 },
+#endif
 #ifdef CONFIG_ARCH_SH73A0
        { .compatible = "renesas,sh73a0",       .data = &soc_shmobile_ag5 },
 #endif
index d61db34ad6ddf68d2fc442fa70e3f87ac78f7887..15e71fd6c5133ff3c8a1670c7a012a37213b3c51 100644 (file)
@@ -54,6 +54,17 @@ static const struct rockchip_grf_info rk3288_grf __initconst = {
        .num_values = ARRAY_SIZE(rk3288_defaults),
 };
 
+#define RK3328_GRF_SOC_CON4            0x410
+
+static const struct rockchip_grf_value rk3328_defaults[] __initconst = {
+       { "jtag switching", RK3328_GRF_SOC_CON4, HIWORD_UPDATE(0, 1, 12) },
+};
+
+static const struct rockchip_grf_info rk3328_grf __initconst = {
+       .values = rk3328_defaults,
+       .num_values = ARRAY_SIZE(rk3328_defaults),
+};
+
 #define RK3368_GRF_SOC_CON15           0x43c
 
 static const struct rockchip_grf_value rk3368_defaults[] __initconst = {
@@ -83,6 +94,9 @@ static const struct of_device_id rockchip_grf_dt_match[] __initconst = {
        }, {
                .compatible = "rockchip,rk3288-grf",
                .data = (void *)&rk3288_grf,
+       }, {
+               .compatible = "rockchip,rk3328-grf",
+               .data = (void *)&rk3328_grf,
        }, {
                .compatible = "rockchip,rk3368-grf",
                .data = (void *)&rk3368_grf,
index 796c46a6cbe70315ec8c890fe5b1df173a892c55..40b75748835f552cd4f5a08525a770f839c69d4e 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/mfd/syscon.h>
 #include <dt-bindings/power/rk3288-power.h>
 #include <dt-bindings/power/rk3328-power.h>
+#include <dt-bindings/power/rk3366-power.h>
 #include <dt-bindings/power/rk3368-power.h>
 #include <dt-bindings/power/rk3399-power.h>
 
@@ -730,6 +731,16 @@ static const struct rockchip_domain_info rk3328_pm_domains[] = {
        [RK3328_PD_VPU]         = DOMAIN_RK3328(-1, 9, 9, false),
 };
 
+static const struct rockchip_domain_info rk3366_pm_domains[] = {
+       [RK3366_PD_PERI]        = DOMAIN_RK3368(10, 10, 6, true),
+       [RK3366_PD_VIO]         = DOMAIN_RK3368(14, 14, 8, false),
+       [RK3366_PD_VIDEO]       = DOMAIN_RK3368(13, 13, 7, false),
+       [RK3366_PD_RKVDEC]      = DOMAIN_RK3368(11, 11, 7, false),
+       [RK3366_PD_WIFIBT]      = DOMAIN_RK3368(8, 8, 9, false),
+       [RK3366_PD_VPU]         = DOMAIN_RK3368(12, 12, 7, false),
+       [RK3366_PD_GPU]         = DOMAIN_RK3368(15, 15, 2, false),
+};
+
 static const struct rockchip_domain_info rk3368_pm_domains[] = {
        [RK3368_PD_PERI]        = DOMAIN_RK3368(13, 12, 6, true),
        [RK3368_PD_VIO]         = DOMAIN_RK3368(15, 14, 8, false),
@@ -794,6 +805,23 @@ static const struct rockchip_pmu_info rk3328_pmu = {
        .domain_info = rk3328_pm_domains,
 };
 
+static const struct rockchip_pmu_info rk3366_pmu = {
+       .pwr_offset = 0x0c,
+       .status_offset = 0x10,
+       .req_offset = 0x3c,
+       .idle_offset = 0x40,
+       .ack_offset = 0x40,
+
+       .core_pwrcnt_offset = 0x48,
+       .gpu_pwrcnt_offset = 0x50,
+
+       .core_power_transition_time = 24,
+       .gpu_power_transition_time = 24,
+
+       .num_domains = ARRAY_SIZE(rk3366_pm_domains),
+       .domain_info = rk3366_pm_domains,
+};
+
 static const struct rockchip_pmu_info rk3368_pmu = {
        .pwr_offset = 0x0c,
        .status_offset = 0x10,
@@ -833,6 +861,10 @@ static const struct of_device_id rockchip_pm_domain_dt_match[] = {
                .compatible = "rockchip,rk3328-power-controller",
                .data = (void *)&rk3328_pmu,
        },
+       {
+               .compatible = "rockchip,rk3366-power-controller",
+               .data = (void *)&rk3366_pmu,
+       },
        {
                .compatible = "rockchip,rk3368-power-controller",
                .data = (void *)&rk3368_pmu,
index a6a5d807cc2bae5a1b2cc4fbbc7c39136fe12e20..7c4fec1f93b57420b5417da9ef35adda8de69e11 100644 (file)
@@ -147,7 +147,7 @@ static __init const char *exynos_get_domain_name(struct device_node *node)
        const char *name;
 
        if (of_property_read_string(node, "label", &name) < 0)
-               name = strrchr(node->full_name, '/') + 1;
+               name = kbasename(node->full_name);
        return kstrdup_const(name, GFP_KERNEL);
 }
 
@@ -237,11 +237,11 @@ no_clk:
                        continue;
 
                if (of_genpd_add_subdomain(&parent, &child))
-                       pr_warn("%s failed to add subdomain: %s\n",
-                               parent.np->full_name, child.np->full_name);
+                       pr_warn("%pOF failed to add subdomain: %pOF\n",
+                               parent.np, child.np);
                else
-                       pr_info("%s has as child subdomain: %s.\n",
-                               parent.np->full_name, child.np->full_name);
+                       pr_info("%pOF has as child subdomain: %pOF.\n",
+                               parent.np, child.np);
        }
 
        return 0;
index 99e354c8f53f8cdff0c34c4285a42cef4021565c..882be5ed7e84fea1b160da834fe51c3247dbb4ba 100644 (file)
@@ -23,6 +23,7 @@
 struct sunxi_sram_func {
        char    *func;
        u8      val;
+       u32     reg_val;
 };
 
 struct sunxi_sram_data {
@@ -39,10 +40,11 @@ struct sunxi_sram_desc {
        bool                    claimed;
 };
 
-#define SUNXI_SRAM_MAP(_val, _func)                            \
+#define SUNXI_SRAM_MAP(_reg_val, _val, _func)                  \
        {                                                       \
                .func = _func,                                  \
                .val = _val,                                    \
+               .reg_val = _reg_val,                            \
        }
 
 #define SUNXI_SRAM_DATA(_name, _reg, _off, _width, ...)                \
@@ -57,14 +59,20 @@ struct sunxi_sram_desc {
 
 static struct sunxi_sram_desc sun4i_a10_sram_a3_a4 = {
        .data   = SUNXI_SRAM_DATA("A3-A4", 0x4, 0x4, 2,
-                                 SUNXI_SRAM_MAP(0, "cpu"),
-                                 SUNXI_SRAM_MAP(1, "emac")),
+                                 SUNXI_SRAM_MAP(0, 0, "cpu"),
+                                 SUNXI_SRAM_MAP(1, 1, "emac")),
 };
 
 static struct sunxi_sram_desc sun4i_a10_sram_d = {
        .data   = SUNXI_SRAM_DATA("D", 0x4, 0x0, 1,
-                                 SUNXI_SRAM_MAP(0, "cpu"),
-                                 SUNXI_SRAM_MAP(1, "usb-otg")),
+                                 SUNXI_SRAM_MAP(0, 0, "cpu"),
+                                 SUNXI_SRAM_MAP(1, 1, "usb-otg")),
+};
+
+static struct sunxi_sram_desc sun50i_a64_sram_c = {
+       .data   = SUNXI_SRAM_DATA("C", 0x4, 24, 1,
+                                 SUNXI_SRAM_MAP(0, 1, "cpu"),
+                                 SUNXI_SRAM_MAP(1, 0, "de2")),
 };
 
 static const struct of_device_id sunxi_sram_dt_ids[] = {
@@ -76,6 +84,10 @@ static const struct of_device_id sunxi_sram_dt_ids[] = {
                .compatible     = "allwinner,sun4i-a10-sram-d",
                .data           = &sun4i_a10_sram_d.data,
        },
+       {
+               .compatible     = "allwinner,sun50i-a64-sram-c",
+               .data           = &sun50i_a64_sram_c.data,
+       },
        {}
 };
 
@@ -121,7 +133,8 @@ static int sunxi_sram_show(struct seq_file *s, void *data)
 
                        for (func = sram_data->func; func->func; func++) {
                                seq_printf(s, "\t\t%s%c\n", func->func,
-                                          func->val == val ? '*' : ' ');
+                                          func->reg_val == val ?
+                                          '*' : ' ');
                        }
                }
 
@@ -149,10 +162,13 @@ static inline struct sunxi_sram_desc *to_sram_desc(const struct sunxi_sram_data
 }
 
 static const struct sunxi_sram_data *sunxi_sram_of_parse(struct device_node *node,
-                                                        unsigned int *value)
+                                                        unsigned int *reg_value)
 {
        const struct of_device_id *match;
+       const struct sunxi_sram_data *data;
+       struct sunxi_sram_func *func;
        struct of_phandle_args args;
+       u8 val;
        int ret;
 
        ret = of_parse_phandle_with_fixed_args(node, "allwinner,sram", 1, 0,
@@ -165,8 +181,7 @@ static const struct sunxi_sram_data *sunxi_sram_of_parse(struct device_node *nod
                goto err;
        }
 
-       if (value)
-               *value = args.args[0];
+       val = args.args[0];
 
        match = of_match_node(sunxi_sram_dt_ids, args.np);
        if (!match) {
@@ -174,6 +189,26 @@ static const struct sunxi_sram_data *sunxi_sram_of_parse(struct device_node *nod
                goto err;
        }
 
+       data = match->data;
+       if (!data) {
+               ret = -EINVAL;
+               goto err;
+       };
+
+       for (func = data->func; func->func; func++) {
+               if (val == func->val) {
+                       if (reg_value)
+                               *reg_value = func->reg_val;
+
+                       break;
+               }
+       }
+
+       if (!func->func) {
+               ret = -EINVAL;
+               goto err;
+       }
+
        of_node_put(args.np);
        return match->data;
 
@@ -190,6 +225,9 @@ int sunxi_sram_claim(struct device *dev)
        u32 val, mask;
 
        if (IS_ERR(base))
+               return PTR_ERR(base);
+
+       if (!base)
                return -EPROBE_DEFER;
 
        if (!dev || !dev->of_node)
@@ -267,6 +305,7 @@ static int sunxi_sram_probe(struct platform_device *pdev)
 
 static const struct of_device_id sunxi_sram_dt_match[] = {
        { .compatible = "allwinner,sun4i-a10-sram-controller" },
+       { .compatible = "allwinner,sun50i-a64-sram-controller" },
        { },
 };
 MODULE_DEVICE_TABLE(of, sunxi_sram_dt_match);
index 1beb7c347344ab59170a59d1fe7cb1c1003d387a..e9e277178c940042b0f086006cfb8d82da0d8620 100644 (file)
@@ -107,6 +107,11 @@ config ARCH_TEGRA_186_SOC
 endif
 endif
 
+config SOC_TEGRA_FUSE
+       def_bool y
+       depends on ARCH_TEGRA
+       select SOC_BUS
+
 config SOC_TEGRA_FLOWCTRL
        bool
 
index 7413f60fa855d7f128efe604a972ee361fdfea4b..b7c552e3133ca2bde10d6699e235151f2b60db31 100644 (file)
 #include <linux/device.h>
 #include <linux/kobject.h>
 #include <linux/init.h>
-#include <linux/platform_device.h>
+#include <linux/io.h>
 #include <linux/of.h>
 #include <linux/of_address.h>
-#include <linux/io.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/sys_soc.h>
 
 #include <soc/tegra/common.h>
 #include <soc/tegra/fuse.h>
@@ -210,6 +212,31 @@ static void tegra_enable_fuse_clk(void __iomem *base)
        writel(reg, base + 0x14);
 }
 
+struct device * __init tegra_soc_device_register(void)
+{
+       struct soc_device_attribute *attr;
+       struct soc_device *dev;
+
+       attr = kzalloc(sizeof(*attr), GFP_KERNEL);
+       if (!attr)
+               return NULL;
+
+       attr->family = kasprintf(GFP_KERNEL, "Tegra");
+       attr->revision = kasprintf(GFP_KERNEL, "%d", tegra_sku_info.revision);
+       attr->soc_id = kasprintf(GFP_KERNEL, "%u", tegra_get_chip_id());
+
+       dev = soc_device_register(attr);
+       if (IS_ERR(dev)) {
+               kfree(attr->soc_id);
+               kfree(attr->revision);
+               kfree(attr->family);
+               kfree(attr);
+               return ERR_CAST(dev);
+       }
+
+       return soc_device_to_device(dev);
+}
+
 static int __init tegra_init_fuse(void)
 {
        const struct of_device_id *match;
@@ -311,6 +338,31 @@ static int __init tegra_init_fuse(void)
        pr_debug("Tegra CPU Speedo ID %d, SoC Speedo ID %d\n",
                 tegra_sku_info.cpu_speedo_id, tegra_sku_info.soc_speedo_id);
 
+
        return 0;
 }
 early_initcall(tegra_init_fuse);
+
+#ifdef CONFIG_ARM64
+static int __init tegra_init_soc(void)
+{
+       struct device_node *np;
+       struct device *soc;
+
+       /* make sure we're running on Tegra */
+       np = of_find_matching_node(NULL, tegra_fuse_match);
+       if (!np)
+               return 0;
+
+       of_node_put(np);
+
+       soc = tegra_soc_device_register();
+       if (IS_ERR(soc)) {
+               pr_err("failed to register SoC device: %ld\n", PTR_ERR(soc));
+               return PTR_ERR(soc);
+       }
+
+       return 0;
+}
+device_initcall(tegra_init_soc);
+#endif
index e233dd5dcab3d711f9c5573ffdb918436f4853df..0453ff6839a7eb68c8cede521d5004daaed0e6b2 100644 (file)
@@ -918,10 +918,8 @@ static void tegra_powergate_init(struct tegra_pmc *pmc,
        if (!np)
                return;
 
-       for_each_child_of_node(np, child) {
+       for_each_child_of_node(np, child)
                tegra_powergate_add(pmc, child);
-               of_node_put(child);
-       }
 
        of_node_put(np);
 }
index 58169e519422d36f28c93d8aa8e24acd70c93d43..7952357df9c862c9d9558522c3664d3d5059a572 100644 (file)
@@ -224,13 +224,14 @@ static void optee_release(struct tee_context *ctx)
        if (!IS_ERR(shm)) {
                arg = tee_shm_get_va(shm, 0);
                /*
-                * If va2pa fails for some reason, we can't call
-                * optee_close_session(), only free the memory. Secure OS
-                * will leak sessions and finally refuse more sessions, but
-                * we will at least let normal world reclaim its memory.
+                * If va2pa fails for some reason, we can't call into
+                * secure world, only free the memory. Secure OS will leak
+                * sessions and finally refuse more sessions, but we will
+                * at least let normal world reclaim its memory.
                 */
                if (!IS_ERR(arg))
-                       tee_shm_va2pa(shm, arg, &parg);
+                       if (tee_shm_va2pa(shm, arg, &parg))
+                               arg = NULL; /* prevent usage of parg below */
        }
 
        list_for_each_entry_safe(sess, sess_tmp, &ctxdata->sess_list,
@@ -258,7 +259,7 @@ static void optee_release(struct tee_context *ctx)
        }
 }
 
-static struct tee_driver_ops optee_ops = {
+static const struct tee_driver_ops optee_ops = {
        .get_version = optee_get_version,
        .open = optee_open,
        .release = optee_release,
@@ -268,13 +269,13 @@ static struct tee_driver_ops optee_ops = {
        .cancel_req = optee_cancel_req,
 };
 
-static struct tee_desc optee_desc = {
+static const struct tee_desc optee_desc = {
        .name = DRIVER_NAME "-clnt",
        .ops = &optee_ops,
        .owner = THIS_MODULE,
 };
 
-static struct tee_driver_ops optee_supp_ops = {
+static const struct tee_driver_ops optee_supp_ops = {
        .get_version = optee_get_version,
        .open = optee_open,
        .release = optee_release,
@@ -282,7 +283,7 @@ static struct tee_driver_ops optee_supp_ops = {
        .supp_send = optee_supp_send,
 };
 
-static struct tee_desc optee_supp_desc = {
+static const struct tee_desc optee_supp_desc = {
        .name = DRIVER_NAME "-supp",
        .ops = &optee_supp_ops,
        .owner = THIS_MODULE,
index 13b7c98cdf25372dc8af14f6038b79181da42853..069c8e1429de8d2aaeb57e1cc51df58293d1d932 100644 (file)
@@ -298,7 +298,7 @@ struct optee_smc_disable_shm_cache_result {
        OPTEE_SMC_FAST_CALL_VAL(OPTEE_SMC_FUNCID_ENABLE_SHM_CACHE)
 
 /*
- * Resume from RPC (for example after processing an IRQ)
+ * Resume from RPC (for example after processing a foreign interrupt)
  *
  * Call register usage:
  * a0  SMC Function ID, OPTEE_SMC_CALL_RETURN_FROM_RPC
@@ -383,19 +383,19 @@ struct optee_smc_disable_shm_cache_result {
        OPTEE_SMC_RPC_VAL(OPTEE_SMC_RPC_FUNC_FREE)
 
 /*
- * Deliver an IRQ in normal world.
+ * Deliver foreign interrupt to normal world.
  *
  * "Call" register usage:
- * a0  OPTEE_SMC_RETURN_RPC_IRQ
+ * a0  OPTEE_SMC_RETURN_RPC_FOREIGN_INTR
  * a1-7        Resume information, must be preserved
  *
  * "Return" register usage:
  * a0  SMC Function ID, OPTEE_SMC_CALL_RETURN_FROM_RPC.
  * a1-7        Preserved
  */
-#define OPTEE_SMC_RPC_FUNC_IRQ         4
-#define OPTEE_SMC_RETURN_RPC_IRQ \
-       OPTEE_SMC_RPC_VAL(OPTEE_SMC_RPC_FUNC_IRQ)
+#define OPTEE_SMC_RPC_FUNC_FOREIGN_INTR                4
+#define OPTEE_SMC_RETURN_RPC_FOREIGN_INTR \
+       OPTEE_SMC_RPC_VAL(OPTEE_SMC_RPC_FUNC_FOREIGN_INTR)
 
 /*
  * Do an RPC request. The supplied struct optee_msg_arg tells which
index 8814eca060216a05c0b53cabc1c81fe74bc288a8..cef417f4f4d286768ea1733168d7bf04d90df462 100644 (file)
@@ -140,11 +140,8 @@ static void handle_rpc_func_cmd_wait(struct optee_msg_arg *arg)
 
        msec_to_wait = arg->params[0].u.value.a;
 
-       /* set task's state to interruptible sleep */
-       set_current_state(TASK_INTERRUPTIBLE);
-
-       /* take a nap */
-       msleep(msec_to_wait);
+       /* Go to interruptible sleep */
+       msleep_interruptible(msec_to_wait);
 
        arg->ret = TEEC_SUCCESS;
        return;
@@ -374,11 +371,11 @@ void optee_handle_rpc(struct tee_context *ctx, struct optee_rpc_param *param)
                shm = reg_pair_to_ptr(param->a1, param->a2);
                tee_shm_free(shm);
                break;
-       case OPTEE_SMC_RPC_FUNC_IRQ:
+       case OPTEE_SMC_RPC_FUNC_FOREIGN_INTR:
                /*
-                * An IRQ was raised while secure world was executing,
-                * since all IRQs are handled in Linux a dummy RPC is
-                * performed to let Linux take the IRQ through the normal
+                * A foreign interrupt was raised while secure world was
+                * executing, since they are handled in Linux a dummy RPC is
+                * performed to let Linux take the interrupt through the normal
                 * vector.
                 */
                break;
index 5c60bf4423e68d4c7bf0b1b27f78c60bf72478bd..58a5009eacc388b45231d747e7d142163f38e627 100644 (file)
@@ -90,8 +90,13 @@ static int tee_ioctl_version(struct tee_context *ctx,
        struct tee_ioctl_version_data vers;
 
        ctx->teedev->desc->ops->get_version(ctx->teedev, &vers);
+
+       if (ctx->teedev->desc->flags & TEE_DESC_PRIVILEGED)
+               vers.gen_caps |= TEE_GEN_CAP_PRIVILEGED;
+
        if (copy_to_user(uvers, &vers, sizeof(vers)))
                return -EFAULT;
+
        return 0;
 }
 
index d356d7f025eb4cf92cc3c2f6615a2b8dad6f7e36..4bc7956cefc4afcde8e724f47346c2937e45e3e3 100644 (file)
@@ -80,7 +80,7 @@ static int tee_shm_op_mmap(struct dma_buf *dmabuf, struct vm_area_struct *vma)
                               size, vma->vm_page_prot);
 }
 
-static struct dma_buf_ops tee_shm_dma_buf_ops = {
+static const struct dma_buf_ops tee_shm_dma_buf_ops = {
        .map_dma_buf = tee_shm_op_map_dma_buf,
        .unmap_dma_buf = tee_shm_op_unmap_dma_buf,
        .release = tee_shm_op_release,
diff --git a/include/dt-bindings/power/mt7622-power.h b/include/dt-bindings/power/mt7622-power.h
new file mode 100644 (file)
index 0000000..1b63926
--- /dev/null
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2017 MediaTek Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See http://www.gnu.org/licenses/gpl-2.0.html for more details.
+ */
+
+#ifndef _DT_BINDINGS_POWER_MT7622_POWER_H
+#define _DT_BINDINGS_POWER_MT7622_POWER_H
+
+#define MT7622_POWER_DOMAIN_ETHSYS     0
+#define MT7622_POWER_DOMAIN_HIF0       1
+#define MT7622_POWER_DOMAIN_HIF1       2
+#define MT7622_POWER_DOMAIN_WB         3
+
+#endif /* _DT_BINDINGS_POWER_MT7622_POWER_H */
diff --git a/include/dt-bindings/power/r8a77995-sysc.h b/include/dt-bindings/power/r8a77995-sysc.h
new file mode 100644 (file)
index 0000000..09d0ed5
--- /dev/null
@@ -0,0 +1,23 @@
+/*
+ * Copyright (C) 2017 Glider bvba
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ */
+#ifndef __DT_BINDINGS_POWER_R8A77995_SYSC_H__
+#define __DT_BINDINGS_POWER_R8A77995_SYSC_H__
+
+/*
+ * These power domain indices match the numbers of the interrupt bits
+ * representing the power areas in the various Interrupt Registers
+ * (e.g. SYSCISR, Interrupt Status Register)
+ */
+
+#define R8A77995_PD_CA53_CPU0           5
+#define R8A77995_PD_CA53_SCU           21
+
+/* Always-on power area */
+#define R8A77995_PD_ALWAYS_ON          32
+
+#endif /* __DT_BINDINGS_POWER_R8A77995_SYSC_H__ */
diff --git a/include/dt-bindings/power/rk3366-power.h b/include/dt-bindings/power/rk3366-power.h
new file mode 100644 (file)
index 0000000..223a3dc
--- /dev/null
@@ -0,0 +1,24 @@
+#ifndef __DT_BINDINGS_POWER_RK3366_POWER_H__
+#define __DT_BINDINGS_POWER_RK3366_POWER_H__
+
+/* VD_CORE */
+#define RK3366_PD_A53_0                0
+#define RK3366_PD_A53_1                1
+#define RK3366_PD_A53_2                2
+#define RK3366_PD_A53_3                3
+
+/* VD_LOGIC */
+#define RK3366_PD_BUS          4
+#define RK3366_PD_PERI         5
+#define RK3366_PD_VIO          6
+#define RK3366_PD_VIDEO                7
+#define RK3366_PD_RKVDEC       8
+#define RK3366_PD_WIFIBT       9
+#define RK3366_PD_VPU          10
+#define RK3366_PD_GPU          11
+#define RK3366_PD_ALIVE                12
+
+/* VD_PMU */
+#define RK3366_PD_PMU          13
+
+#endif
diff --git a/include/dt-bindings/reset/snps,hsdk-v1-reset.h b/include/dt-bindings/reset/snps,hsdk-v1-reset.h
new file mode 100644 (file)
index 0000000..d898c89
--- /dev/null
@@ -0,0 +1,17 @@
+/**
+ * This header provides index for the HSDK v1 reset controller.
+ */
+#ifndef _DT_BINDINGS_RESET_CONTROLLER_HSDK_V1
+#define _DT_BINDINGS_RESET_CONTROLLER_HSDK_V1
+
+#define HSDK_V1_APB_RESET      0
+#define HSDK_V1_AXI_RESET      1
+#define HSDK_V1_ETH_RESET      2
+#define HSDK_V1_USB_RESET      3
+#define HSDK_V1_SDIO_RESET     4
+#define HSDK_V1_HDMI_RESET     5
+#define HSDK_V1_GFX_RESET      6
+#define HSDK_V1_DMAC_RESET     7
+#define HSDK_V1_EBI_RESET      8
+
+#endif /*_DT_BINDINGS_RESET_CONTROLLER_HSDK_V1*/
index 13d8681210d545ab2dcedb472fa127b408446eae..56463f37f3e67ec03e0f594a331bf62eb2d70722 100644 (file)
@@ -25,6 +25,11 @@ struct reset_control *__devm_reset_control_get(struct device *dev,
 
 int __must_check device_reset(struct device *dev);
 
+struct reset_control *devm_reset_control_array_get(struct device *dev,
+                                                  bool shared, bool optional);
+struct reset_control *of_reset_control_array_get(struct device_node *np,
+                                                bool shared, bool optional);
+
 static inline int device_reset_optional(struct device *dev)
 {
        return device_reset(dev);
@@ -89,6 +94,18 @@ static inline struct reset_control *__devm_reset_control_get(
        return optional ? NULL : ERR_PTR(-ENOTSUPP);
 }
 
+static inline struct reset_control *
+devm_reset_control_array_get(struct device *dev, bool shared, bool optional)
+{
+       return optional ? NULL : ERR_PTR(-ENOTSUPP);
+}
+
+static inline struct reset_control *
+of_reset_control_array_get(struct device_node *np, bool shared, bool optional)
+{
+       return optional ? NULL : ERR_PTR(-ENOTSUPP);
+}
+
 #endif /* CONFIG_RESET_CONTROLLER */
 
 /**
@@ -374,4 +391,55 @@ static inline struct reset_control *devm_reset_control_get_by_index(
 {
        return devm_reset_control_get_exclusive_by_index(dev, index);
 }
+
+/*
+ * APIs to manage a list of reset controllers
+ */
+static inline struct reset_control *
+devm_reset_control_array_get_exclusive(struct device *dev)
+{
+       return devm_reset_control_array_get(dev, false, false);
+}
+
+static inline struct reset_control *
+devm_reset_control_array_get_shared(struct device *dev)
+{
+       return devm_reset_control_array_get(dev, true, false);
+}
+
+static inline struct reset_control *
+devm_reset_control_array_get_optional_exclusive(struct device *dev)
+{
+       return devm_reset_control_array_get(dev, false, true);
+}
+
+static inline struct reset_control *
+devm_reset_control_array_get_optional_shared(struct device *dev)
+{
+       return devm_reset_control_array_get(dev, true, true);
+}
+
+static inline struct reset_control *
+of_reset_control_array_get_exclusive(struct device_node *node)
+{
+       return of_reset_control_array_get(node, false, false);
+}
+
+static inline struct reset_control *
+of_reset_control_array_get_shared(struct device_node *node)
+{
+       return of_reset_control_array_get(node, true, false);
+}
+
+static inline struct reset_control *
+of_reset_control_array_get_optional_exclusive(struct device_node *node)
+{
+       return of_reset_control_array_get(node, false, true);
+}
+
+static inline struct reset_control *
+of_reset_control_array_get_optional_shared(struct device_node *node)
+{
+       return of_reset_control_array_get(node, true, true);
+}
 #endif
index a5714e93fb34189820342e23a93000f7f2265956..a0182ec2a621c2044208b8a780847e58bb066ad5 100644 (file)
 #define MT8173_TOP_AXI_PROT_EN_MFG_M1          BIT(22)
 #define MT8173_TOP_AXI_PROT_EN_MFG_SNOOP_OUT   BIT(23)
 
+#define MT7622_TOP_AXI_PROT_EN_ETHSYS          (BIT(3) | BIT(17))
+#define MT7622_TOP_AXI_PROT_EN_HIF0            (BIT(24) | BIT(25))
+#define MT7622_TOP_AXI_PROT_EN_HIF1            (BIT(26) | BIT(27) | \
+                                                BIT(28))
+#define MT7622_TOP_AXI_PROT_EN_WB              (BIT(2) | BIT(6) | \
+                                                BIT(7) | BIT(8))
+
 int mtk_infracfg_set_bus_protection(struct regmap *infracfg, u32 mask);
 int mtk_infracfg_clear_bus_protection(struct regmap *infracfg, u32 mask);
 
index 0f175b8f6456c1d5ad14538deb66b9c3a9f3c5c7..cb889afe576b34db3c4293fa431c1eab28dcc4de 100644 (file)
@@ -28,6 +28,7 @@
 #define TEE_SHM_MAPPED         0x1     /* Memory mapped by the kernel */
 #define TEE_SHM_DMA_BUF                0x2     /* Memory with dma-buf handle */
 
+struct device;
 struct tee_device;
 struct tee_shm;
 struct tee_shm_pool;
index b4c9219e7f95659b803d1c7cd3f042ef7aa61022..9b6ea0c7211780182c4cce20735ade7ef673695d 100644 (file)
@@ -65,6 +65,8 @@ int tegra_fuse_readl(unsigned long offset, u32 *value);
 
 extern struct tegra_sku_info tegra_sku_info;
 
+struct device *tegra_soc_device_register(void);
+
 #endif /* __ASSEMBLY__ */
 
 #endif /* __SOC_TEGRA_FUSE_H__ */
index 370d8845ab2173a733ccbf7091f9ce560024bb0e..688782e901407cb7baf5238b2281f8a38bdf2016 100644 (file)
@@ -49,6 +49,7 @@
 #define TEE_MAX_ARG_SIZE       1024
 
 #define TEE_GEN_CAP_GP         (1 << 0)/* GlobalPlatform compliant TEE */
+#define TEE_GEN_CAP_PRIVILEGED (1 << 1)/* Privileged device (for supplicant) */
 
 /*
  * TEE Implementation ID