diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2017-09-10 20:40:00 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2017-09-10 20:40:00 -0700 |
commit | ae46654bcff303b33facbbd04a3ad9c21d303f9b (patch) | |
tree | b0027d47d6c949162fa6ae306f34abeb76c559a9 /drivers/soc | |
parent | 7f1b9be13a7dbe8e51ea541bbcd6c47adae39c71 (diff) | |
parent | a48a7b6b54927159bac77735df00e5b9fc3415fb (diff) | |
download | linux-stable-ae46654bcff303b33facbbd04a3ad9c21d303f9b.tar.gz linux-stable-ae46654bcff303b33facbbd04a3ad9c21d303f9b.tar.bz2 linux-stable-ae46654bcff303b33facbbd04a3ad9c21d303f9b.zip |
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
...
Diffstat (limited to 'drivers/soc')
30 files changed, 588 insertions, 159 deletions
diff --git a/drivers/soc/Kconfig b/drivers/soc/Kconfig index 07fc0ac51c52..fc9e98047421 100644 --- a/drivers/soc/Kconfig +++ b/drivers/soc/Kconfig @@ -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" diff --git a/drivers/soc/Makefile b/drivers/soc/Makefile index 9241125416ba..280a6a91a9e2 100644 --- a/drivers/soc/Makefile +++ b/drivers/soc/Makefile @@ -10,6 +10,7 @@ obj-$(CONFIG_MACH_DOVE) += dove/ obj-y += fsl/ obj-$(CONFIG_ARCH_MXC) += imx/ obj-$(CONFIG_ARCH_MEDIATEK) += mediatek/ +obj-$(CONFIG_ARCH_MESON) += amlogic/ obj-$(CONFIG_ARCH_QCOM) += qcom/ obj-y += renesas/ obj-$(CONFIG_ARCH_ROCKCHIP) += rockchip/ diff --git a/drivers/soc/amlogic/Kconfig b/drivers/soc/amlogic/Kconfig new file mode 100644 index 000000000000..22acf064531f --- /dev/null +++ b/drivers/soc/amlogic/Kconfig @@ -0,0 +1,12 @@ +menu "Amlogic SoC drivers" + +config MESON_GX_SOCINFO + bool "Amlogic Meson GX SoC Information driver" + depends on ARCH_MESON || COMPILE_TEST + default ARCH_MESON + select SOC_BUS + help + Say yes to support decoding of Amlogic Meson GX SoC family + information about the type, package and version. + +endmenu diff --git a/drivers/soc/amlogic/Makefile b/drivers/soc/amlogic/Makefile new file mode 100644 index 000000000000..3e85fc462c21 --- /dev/null +++ b/drivers/soc/amlogic/Makefile @@ -0,0 +1 @@ +obj-$(CONFIG_MESON_GX_SOCINFO) += meson-gx-socinfo.o diff --git a/drivers/soc/amlogic/meson-gx-socinfo.c b/drivers/soc/amlogic/meson-gx-socinfo.c new file mode 100644 index 000000000000..89f4cf507be6 --- /dev/null +++ b/drivers/soc/amlogic/meson-gx-socinfo.c @@ -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); diff --git a/drivers/soc/fsl/qbman/bman_ccsr.c b/drivers/soc/fsl/qbman/bman_ccsr.c index a8e8389a6894..eaa9585c7347 100644 --- a/drivers/soc/fsl/qbman/bman_ccsr.c +++ b/drivers/soc/fsl/qbman/bman_ccsr.c @@ -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 */ diff --git a/drivers/soc/fsl/qbman/bman_portal.c b/drivers/soc/fsl/qbman/bman_portal.c index 8354d4dabdad..39b39c8f1399 100644 --- a/drivers/soc/fsl/qbman/bman_portal.c +++ b/drivers/soc/fsl/qbman/bman_portal.c @@ -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; diff --git a/drivers/soc/fsl/qbman/qman_ccsr.c b/drivers/soc/fsl/qbman/qman_ccsr.c index 90bc40c48675..835ce947ffca 100644 --- a/drivers/soc/fsl/qbman/qman_ccsr.c +++ b/drivers/soc/fsl/qbman/qman_ccsr.c @@ -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; } diff --git a/drivers/soc/fsl/qbman/qman_portal.c b/drivers/soc/fsl/qbman/qman_portal.c index adbaa30d3c5a..cbacdf4f98ed 100644 --- a/drivers/soc/fsl/qbman/qman_portal.c +++ b/drivers/soc/fsl/qbman/qman_portal.c @@ -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; diff --git a/drivers/soc/fsl/qe/gpio.c b/drivers/soc/fsl/qe/gpio.c index 0aaf429f31d5..3b27075c21a7 100644 --- a/drivers/soc/fsl/qe/gpio.c +++ b/drivers/soc/fsl/qe/gpio.c @@ -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 */ } diff --git a/drivers/soc/mediatek/mtk-pmic-wrap.c b/drivers/soc/mediatek/mtk-pmic-wrap.c index c80a04e1b2b1..c2048382830f 100644 --- a/drivers/soc/mediatek/mtk-pmic-wrap.c +++ b/drivers/soc/mediatek/mtk-pmic-wrap.c @@ -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; } diff --git a/drivers/soc/mediatek/mtk-scpsys.c b/drivers/soc/mediatek/mtk-scpsys.c index ceb2cc495cd0..e1ce8b1b5090 100644 --- a/drivers/soc/mediatek/mtk-scpsys.c +++ b/drivers/soc/mediatek/mtk-scpsys.c @@ -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; - - scp_reg.pwr_sta_offs = SPM_PWR_STATUS_MT6797; - scp_reg.pwr_sta2nd_offs = SPM_PWR_STATUS_2ND_MT6797; - - scp = init_scp(pdev, scp_domain_data_mt6797, NUM_DOMAINS_MT6797, - &scp_reg); - if (IS_ERR(scp)) - return PTR_ERR(scp); - - mtk_register_power_domains(pdev, scp, NUM_DOMAINS_MT6797); - - pd_data = &scp->pd_data; - - ret = pm_genpd_add_subdomain(pd_data->domains[MT6797_POWER_DOMAIN_MM], - pd_data->domains[MT6797_POWER_DOMAIN_VDEC]); - if (ret && IS_ENABLED(CONFIG_PM)) - dev_err(&pdev->dev, "Failed to add subdomain: %d\n", ret); - - ret = pm_genpd_add_subdomain(pd_data->domains[MT6797_POWER_DOMAIN_MM], - pd_data->domains[MT6797_POWER_DOMAIN_ISP]); - if (ret && IS_ENABLED(CONFIG_PM)) - dev_err(&pdev->dev, "Failed to add subdomain: %d\n", ret); - - ret = pm_genpd_add_subdomain(pd_data->domains[MT6797_POWER_DOMAIN_MM], - pd_data->domains[MT6797_POWER_DOMAIN_VENC]); - if (ret && IS_ENABLED(CONFIG_PM)) - dev_err(&pdev->dev, "Failed to add subdomain: %d\n", ret); +static const struct scp_subdomain scp_subdomain_mt6797[] = { + {MT6797_POWER_DOMAIN_MM, MT6797_POWER_DOMAIN_VDEC}, + {MT6797_POWER_DOMAIN_MM, MT6797_POWER_DOMAIN_ISP}, + {MT6797_POWER_DOMAIN_MM, MT6797_POWER_DOMAIN_VENC}, + {MT6797_POWER_DOMAIN_MM, MT6797_POWER_DOMAIN_MJC}, +}; - ret = pm_genpd_add_subdomain(pd_data->domains[MT6797_POWER_DOMAIN_MM], - pd_data->domains[MT6797_POWER_DOMAIN_MJC]); - if (ret && IS_ENABLED(CONFIG_PM)) - dev_err(&pdev->dev, "Failed to add subdomain: %d\n", ret); +/* + * MT7622 power domain support + */ - return 0; -} +static const struct scp_domain_data scp_domain_data_mt7622[] = { + [MT7622_POWER_DOMAIN_ETHSYS] = { + .name = "ethsys", + .sta_mask = PWR_STATUS_ETHSYS, + .ctl_offs = SPM_ETHSYS_PWR_CON, + .sram_pdn_bits = GENMASK(11, 8), + .sram_pdn_ack_bits = GENMASK(15, 12), + .clk_id = {CLK_NONE}, + .bus_prot_mask = MT7622_TOP_AXI_PROT_EN_ETHSYS, + .active_wakeup = true, + }, + [MT7622_POWER_DOMAIN_HIF0] = { + .name = "hif0", + .sta_mask = PWR_STATUS_HIF0, + .ctl_offs = SPM_HIF0_PWR_CON, + .sram_pdn_bits = GENMASK(11, 8), + .sram_pdn_ack_bits = GENMASK(15, 12), + .clk_id = {CLK_HIFSEL}, + .bus_prot_mask = MT7622_TOP_AXI_PROT_EN_HIF0, + .active_wakeup = true, + }, + [MT7622_POWER_DOMAIN_HIF1] = { + .name = "hif1", + .sta_mask = PWR_STATUS_HIF1, + .ctl_offs = SPM_HIF1_PWR_CON, + .sram_pdn_bits = GENMASK(11, 8), + .sram_pdn_ack_bits = GENMASK(15, 12), + .clk_id = {CLK_HIFSEL}, + .bus_prot_mask = MT7622_TOP_AXI_PROT_EN_HIF1, + .active_wakeup = true, + }, + [MT7622_POWER_DOMAIN_WB] = { + .name = "wb", + .sta_mask = PWR_STATUS_WB, + .ctl_offs = SPM_WB_PWR_CON, + .sram_pdn_bits = 0, + .sram_pdn_ack_bits = 0, + .clk_id = {CLK_NONE}, + .bus_prot_mask = MT7622_TOP_AXI_PROT_EN_WB, + .active_wakeup = true, + }, +}; /* * MT8173 power domain support @@ -789,39 +805,50 @@ static const struct scp_domain_data scp_domain_data_mt8173[] = { }, }; -#define NUM_DOMAINS_MT8173 ARRAY_SIZE(scp_domain_data_mt8173) - -static int __init scpsys_probe_mt8173(struct platform_device *pdev) -{ - struct scp *scp; - struct genpd_onecell_data *pd_data; - int ret; - struct scp_ctrl_reg scp_reg; - - scp_reg.pwr_sta_offs = SPM_PWR_STATUS; - scp_reg.pwr_sta2nd_offs = SPM_PWR_STATUS_2ND; - - scp = init_scp(pdev, scp_domain_data_mt8173, NUM_DOMAINS_MT8173, - &scp_reg); - if (IS_ERR(scp)) - return PTR_ERR(scp); - - mtk_register_power_domains(pdev, scp, NUM_DOMAINS_MT8173); +static const struct scp_subdomain scp_subdomain_mt8173[] = { + {MT8173_POWER_DOMAIN_MFG_ASYNC, MT8173_POWER_DOMAIN_MFG_2D}, + {MT8173_POWER_DOMAIN_MFG_2D, MT8173_POWER_DOMAIN_MFG}, +}; - pd_data = &scp->pd_data; +static const struct scp_soc_data mt2701_data = { + .domains = scp_domain_data_mt2701, + .num_domains = ARRAY_SIZE(scp_domain_data_mt2701), + .regs = { + .pwr_sta_offs = SPM_PWR_STATUS, + .pwr_sta2nd_offs = SPM_PWR_STATUS_2ND + } +}; - ret = pm_genpd_add_subdomain(pd_data->domains[MT8173_POWER_DOMAIN_MFG_ASYNC], - pd_data->domains[MT8173_POWER_DOMAIN_MFG_2D]); - if (ret && IS_ENABLED(CONFIG_PM)) - dev_err(&pdev->dev, "Failed to add subdomain: %d\n", ret); +static const struct scp_soc_data mt6797_data = { + .domains = scp_domain_data_mt6797, + .num_domains = ARRAY_SIZE(scp_domain_data_mt6797), + .subdomains = scp_subdomain_mt6797, + .num_subdomains = ARRAY_SIZE(scp_subdomain_mt6797), + .regs = { + .pwr_sta_offs = SPM_PWR_STATUS_MT6797, + .pwr_sta2nd_offs = SPM_PWR_STATUS_2ND_MT6797 + } +}; - ret = pm_genpd_add_subdomain(pd_data->domains[MT8173_POWER_DOMAIN_MFG_2D], - pd_data->domains[MT8173_POWER_DOMAIN_MFG]); - if (ret && IS_ENABLED(CONFIG_PM)) - dev_err(&pdev->dev, "Failed to add subdomain: %d\n", ret); +static const struct scp_soc_data mt7622_data = { + .domains = scp_domain_data_mt7622, + .num_domains = ARRAY_SIZE(scp_domain_data_mt7622), + .regs = { + .pwr_sta_offs = SPM_PWR_STATUS, + .pwr_sta2nd_offs = SPM_PWR_STATUS_2ND + } +}; - return 0; -} +static const struct scp_soc_data mt8173_data = { + .domains = scp_domain_data_mt8173, + .num_domains = ARRAY_SIZE(scp_domain_data_mt8173), + .subdomains = scp_subdomain_mt8173, + .num_subdomains = ARRAY_SIZE(scp_subdomain_mt8173), + .regs = { + .pwr_sta_offs = SPM_PWR_STATUS, + .pwr_sta2nd_offs = SPM_PWR_STATUS_2ND + } +}; /* * scpsys driver init @@ -830,13 +857,16 @@ static int __init scpsys_probe_mt8173(struct platform_device *pdev) static const struct of_device_id of_scpsys_match_tbl[] = { { .compatible = "mediatek,mt2701-scpsys", - .data = scpsys_probe_mt2701, + .data = &mt2701_data, }, { .compatible = "mediatek,mt6797-scpsys", - .data = scpsys_probe_mt6797, + .data = &mt6797_data, + }, { + .compatible = "mediatek,mt7622-scpsys", + .data = &mt7622_data, }, { .compatible = "mediatek,mt8173-scpsys", - .data = scpsys_probe_mt8173, + .data = &mt8173_data, }, { /* sentinel */ } @@ -844,16 +874,33 @@ static const struct of_device_id of_scpsys_match_tbl[] = { static int scpsys_probe(struct platform_device *pdev) { - int (*probe)(struct platform_device *); - const struct of_device_id *of_id; + const struct of_device_id *match; + const struct scp_subdomain *sd; + const struct scp_soc_data *soc; + struct scp *scp; + struct genpd_onecell_data *pd_data; + int i, ret; - of_id = of_match_node(of_scpsys_match_tbl, pdev->dev.of_node); - if (!of_id || !of_id->data) - return -EINVAL; + match = of_match_device(of_scpsys_match_tbl, &pdev->dev); + soc = (const struct scp_soc_data *)match->data; + + scp = init_scp(pdev, soc->domains, soc->num_domains, &soc->regs); + if (IS_ERR(scp)) + return PTR_ERR(scp); - probe = of_id->data; + mtk_register_power_domains(pdev, scp, soc->num_domains); - return probe(pdev); + pd_data = &scp->pd_data; + + for (i = 0, sd = soc->subdomains ; i < soc->num_subdomains ; i++) { + ret = pm_genpd_add_subdomain(pd_data->domains[sd->origin], + pd_data->domains[sd->subdomain]); + if (ret && IS_ENABLED(CONFIG_PM)) + dev_err(&pdev->dev, "Failed to add subdomain: %d\n", + ret); + } + + return 0; } static struct platform_driver scpsys_drv = { diff --git a/drivers/soc/qcom/Kconfig b/drivers/soc/qcom/Kconfig index d0fc331972d2..b00bccddcd3b 100644 --- a/drivers/soc/qcom/Kconfig +++ b/drivers/soc/qcom/Kconfig @@ -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 diff --git a/drivers/soc/qcom/mdt_loader.c b/drivers/soc/qcom/mdt_loader.c index bd63df0d14e0..08bd8549242a 100644 --- a/drivers/soc/qcom/mdt_loader.c +++ b/drivers/soc/qcom/mdt_loader.c @@ -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); } diff --git a/drivers/soc/qcom/smsm.c b/drivers/soc/qcom/smsm.c index dc540ea92e9d..403bea9d546b 100644 --- a/drivers/soc/qcom/smsm.c +++ b/drivers/soc/qcom/smsm.c @@ -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; diff --git a/drivers/soc/qcom/wcnss_ctrl.c b/drivers/soc/qcom/wcnss_ctrl.c index b9069184df19..d008e5b82db4 100644 --- a/drivers/soc/qcom/wcnss_ctrl.c +++ b/drivers/soc/qcom/wcnss_ctrl.c @@ -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, diff --git a/drivers/soc/renesas/Kconfig b/drivers/soc/renesas/Kconfig index 87a4be46bd98..567414cb42ba 100644 --- a/drivers/soc/renesas/Kconfig +++ b/drivers/soc/renesas/Kconfig @@ -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 diff --git a/drivers/soc/renesas/Makefile b/drivers/soc/renesas/Makefile index 1a1a297b26a7..6b6e7f16104c 100644 --- a/drivers/soc/renesas/Makefile +++ b/drivers/soc/renesas/Makefile @@ -11,6 +11,7 @@ obj-$(CONFIG_SYSC_R8A7792) += r8a7792-sysc.o obj-$(CONFIG_SYSC_R8A7794) += r8a7794-sysc.o obj-$(CONFIG_SYSC_R8A7795) += r8a7795-sysc.o obj-$(CONFIG_SYSC_R8A7796) += r8a7796-sysc.o +obj-$(CONFIG_SYSC_R8A77995) += r8a77995-sysc.o # Family obj-$(CONFIG_RST_RCAR) += rcar-rst.o diff --git a/drivers/soc/renesas/r8a77995-sysc.c b/drivers/soc/renesas/r8a77995-sysc.c new file mode 100644 index 000000000000..f718429cab02 --- /dev/null +++ b/drivers/soc/renesas/r8a77995-sysc.c @@ -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), +}; diff --git a/drivers/soc/renesas/rcar-rst.c b/drivers/soc/renesas/rcar-rst.c index a6d1c26d3167..baa47014e96b 100644 --- a/drivers/soc/renesas/rcar-rst.c +++ b/drivers/soc/renesas/rcar-rst.c @@ -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); diff --git a/drivers/soc/renesas/rcar-sysc.c b/drivers/soc/renesas/rcar-sysc.c index 7c8da3c90011..c8406e81640f 100644 --- a/drivers/soc/renesas/rcar-sysc.c +++ b/drivers/soc/renesas/rcar-sysc.c @@ -284,6 +284,9 @@ static const struct of_device_id rcar_sysc_matches[] = { #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++) { diff --git a/drivers/soc/renesas/rcar-sysc.h b/drivers/soc/renesas/rcar-sysc.h index 1a5bebaf54ba..2f524922c4d2 100644 --- a/drivers/soc/renesas/rcar-sysc.h +++ b/drivers/soc/renesas/rcar-sysc.h @@ -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; /* diff --git a/drivers/soc/renesas/renesas-soc.c b/drivers/soc/renesas/renesas-soc.c index ca26f13d399c..90d6b7a4340a 100644 --- a/drivers/soc/renesas/renesas-soc.c +++ b/drivers/soc/renesas/renesas-soc.c @@ -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 diff --git a/drivers/soc/rockchip/grf.c b/drivers/soc/rockchip/grf.c index d61db34ad6dd..15e71fd6c513 100644 --- a/drivers/soc/rockchip/grf.c +++ b/drivers/soc/rockchip/grf.c @@ -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 = { @@ -84,6 +95,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, }, { diff --git a/drivers/soc/rockchip/pm_domains.c b/drivers/soc/rockchip/pm_domains.c index 796c46a6cbe7..40b75748835f 100644 --- a/drivers/soc/rockchip/pm_domains.c +++ b/drivers/soc/rockchip/pm_domains.c @@ -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, @@ -834,6 +862,10 @@ static const struct of_device_id rockchip_pm_domain_dt_match[] = { .data = (void *)&rk3328_pmu, }, { + .compatible = "rockchip,rk3366-power-controller", + .data = (void *)&rk3366_pmu, + }, + { .compatible = "rockchip,rk3368-power-controller", .data = (void *)&rk3368_pmu, }, diff --git a/drivers/soc/samsung/pm_domains.c b/drivers/soc/samsung/pm_domains.c index a6a5d807cc2b..7c4fec1f93b5 100644 --- a/drivers/soc/samsung/pm_domains.c +++ b/drivers/soc/samsung/pm_domains.c @@ -147,7 +147,7 @@ static __init const char *exynos_get_domain_name(struct device_node *node) const char *name; if (of_property_read_string(node, "label", &name) < 0) - name = strrchr(node->full_name, '/') + 1; + name = kbasename(node->full_name); return kstrdup_const(name, GFP_KERNEL); } @@ -237,11 +237,11 @@ no_clk: continue; if (of_genpd_add_subdomain(&parent, &child)) - pr_warn("%s failed to add subdomain: %s\n", - parent.np->full_name, child.np->full_name); + pr_warn("%pOF failed to add subdomain: %pOF\n", + parent.np, child.np); else - pr_info("%s has as child subdomain: %s.\n", - parent.np->full_name, child.np->full_name); + pr_info("%pOF has as child subdomain: %pOF.\n", + parent.np, child.np); } return 0; diff --git a/drivers/soc/sunxi/sunxi_sram.c b/drivers/soc/sunxi/sunxi_sram.c index 99e354c8f53f..882be5ed7e84 100644 --- a/drivers/soc/sunxi/sunxi_sram.c +++ b/drivers/soc/sunxi/sunxi_sram.c @@ -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); diff --git a/drivers/soc/tegra/Kconfig b/drivers/soc/tegra/Kconfig index 1beb7c347344..e9e277178c94 100644 --- a/drivers/soc/tegra/Kconfig +++ b/drivers/soc/tegra/Kconfig @@ -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 diff --git a/drivers/soc/tegra/fuse/fuse-tegra.c b/drivers/soc/tegra/fuse/fuse-tegra.c index 7413f60fa855..b7c552e3133c 100644 --- a/drivers/soc/tegra/fuse/fuse-tegra.c +++ b/drivers/soc/tegra/fuse/fuse-tegra.c @@ -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 diff --git a/drivers/soc/tegra/pmc.c b/drivers/soc/tegra/pmc.c index e233dd5dcab3..0453ff6839a7 100644 --- a/drivers/soc/tegra/pmc.c +++ b/drivers/soc/tegra/pmc.c @@ -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); } |