mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git
synced 2025-01-01 10:42:11 +00:00
ARM: SoC driver updates for v4.14
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 -----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQIcBAABAgAGBQJZtdt7AAoJEIwa5zzehBx3EboP/jR2T9lrMavXR1zL48L14yJb S+fiJlrX1Kr42UF4PQvsfs+uTqOLmycrPVFkMb6IwoUPzQ9UCOSoiMzYm2b7ZPvt uIesHhdM3/xun6wKfieN8GmNA1yDVynTxo0TTYDw5ha7I6s2GHgw0GSFzy3wm0Qg KzerAO3gzf3L5XsKR0cai3IXNjHO9ubpFG1ReR09da28nPElP8ggWg0KnqdO76Ch BGpFj78EC875ZNqwHgnspUqgGDJnBjig3m/uA4FWA0G9Jl38tCyKTZfUR7cEraoV kyCgBlR/UrI8eXVTyEy5k5iTsQ3A1VhX4rGjyH+5NZHTs1yWr4+RDND/qeGl9tSo VASuOtH6Rc3vdUDpHPBNAFNQH8fwwDoKf96dvN1tiffsx6LSKb//NyOfkXzKOtR6 CP5raYfX4YktLtHq0XVTZ/6r3XmLcTHzElR/dCFpQOFcTOYii0pWtfcWouahbZ1w dhoBX/dbNq37MfzrxtHN2VTIEHpn2GU7u+ZGkp2ArokD58BAft/M3Xee1cDnF75g ZDwe5eNFT8aBZKaY7zwG8cdxiw9kACAivDRwW+zgpfUr39c+d0+QmVfnfJh4EGXK Ri6yr2EfBWK6jw3cwkdSyyt7iSzIkB+RiuuD1MjpYhWzAvoDpzqkXYukFGbpXnuy vUFHNuP1ocUsRtCs8mm1 =yBzS -----END PGP SIGNATURE----- Merge tag 'armsoc-drivers' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc Pull ARM SoC driver updates from Olof Johansson: "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 ...
This commit is contained in:
commit
ae46654bcf
@ -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;
|
||||
};
|
||||
|
@ -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.
|
||||
|
||||
|
@ -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.
|
||||
|
||||
|
||||
|
@ -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 ...
|
||||
};
|
||||
|
@ -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:
|
||||
|
@ -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.
|
||||
|
||||
|
@ -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
|
||||
---------------------------
|
||||
|
||||
|
@ -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>
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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:
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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);
|
137
drivers/reset/reset-hsdk-v1.c
Normal file
137
drivers/reset/reset-hsdk-v1.c
Normal file
@ -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");
|
@ -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;
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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,
|
||||
};
|
||||
|
@ -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"
|
||||
|
@ -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/
|
||||
|
12
drivers/soc/amlogic/Kconfig
Normal file
12
drivers/soc/amlogic/Kconfig
Normal file
@ -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
|
1
drivers/soc/amlogic/Makefile
Normal file
1
drivers/soc/amlogic/Makefile
Normal file
@ -0,0 +1 @@
|
||||
obj-$(CONFIG_MESON_GX_SOCINFO) += meson-gx-socinfo.o
|
177
drivers/soc/amlogic/meson-gx-socinfo.c
Normal file
177
drivers/soc/amlogic/meson-gx-socinfo.c
Normal file
@ -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);
|
@ -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 */
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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 */
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
@ -39,6 +40,11 @@
|
||||
#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
|
||||
@ -64,6 +70,10 @@
|
||||
#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;
|
||||
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},
|
||||
};
|
||||
|
||||
scp_reg.pwr_sta_offs = SPM_PWR_STATUS_MT6797;
|
||||
scp_reg.pwr_sta2nd_offs = SPM_PWR_STATUS_2ND_MT6797;
|
||||
/*
|
||||
* MT7622 power domain support
|
||||
*/
|
||||
|
||||
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);
|
||||
|
||||
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);
|
||||
|
||||
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 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},
|
||||
};
|
||||
|
||||
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;
|
||||
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
|
||||
}
|
||||
};
|
||||
|
||||
scp_reg.pwr_sta_offs = SPM_PWR_STATUS;
|
||||
scp_reg.pwr_sta2nd_offs = SPM_PWR_STATUS_2ND;
|
||||
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
|
||||
}
|
||||
};
|
||||
|
||||
scp = init_scp(pdev, scp_domain_data_mt8173, NUM_DOMAINS_MT8173,
|
||||
&scp_reg);
|
||||
if (IS_ERR(scp))
|
||||
return PTR_ERR(scp);
|
||||
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
|
||||
}
|
||||
};
|
||||
|
||||
mtk_register_power_domains(pdev, scp, NUM_DOMAINS_MT8173);
|
||||
|
||||
pd_data = &scp->pd_data;
|
||||
|
||||
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);
|
||||
|
||||
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);
|
||||
|
||||
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;
|
||||
|
||||
probe = of_id->data;
|
||||
scp = init_scp(pdev, soc->domains, soc->num_domains, &soc->regs);
|
||||
if (IS_ERR(scp))
|
||||
return PTR_ERR(scp);
|
||||
|
||||
return probe(pdev);
|
||||
mtk_register_power_domains(pdev, scp, soc->num_domains);
|
||||
|
||||
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 = {
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
31
drivers/soc/renesas/r8a77995-sysc.c
Normal file
31
drivers/soc/renesas/r8a77995-sysc.c
Normal file
@ -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),
|
||||
};
|
@ -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);
|
||||
|
@ -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++) {
|
||||
|
@ -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;
|
||||
|
||||
|
||||
/*
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -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 @@ static __init int exynos4_pm_init_power_domain(void)
|
||||
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;
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
||||
|
@ -19,10 +19,12 @@
|
||||
#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
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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,
|
||||
|
22
include/dt-bindings/power/mt7622-power.h
Normal file
22
include/dt-bindings/power/mt7622-power.h
Normal file
@ -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 */
|
23
include/dt-bindings/power/r8a77995-sysc.h
Normal file
23
include/dt-bindings/power/r8a77995-sysc.h
Normal file
@ -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__ */
|
24
include/dt-bindings/power/rk3366-power.h
Normal file
24
include/dt-bindings/power/rk3366-power.h
Normal file
@ -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
|
17
include/dt-bindings/reset/snps,hsdk-v1-reset.h
Normal file
17
include/dt-bindings/reset/snps,hsdk-v1-reset.h
Normal file
@ -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*/
|
@ -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
|
||||
|
@ -20,6 +20,13 @@
|
||||
#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);
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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__ */
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user