From 20793d3f5de67c5d9b4559f5af067c2daebf5e16 Mon Sep 17 00:00:00 2001 From: qwx495460 Date: Thu, 15 Mar 2018 15:59:32 +0800 Subject: [PATCH] support ip regulator add ip power driver based on regulator framework for hikey970 --- .../dts/hisilicon/hisi_power_ip_test.dtsi | 12 + .../boot/dts/hisilicon/kirin970-hikey970.dts | 2 + .../boot/dts/hisilicon/kirin970_powerip.dtsi | 158 ++ arch/arm64/configs/hikey970_defconfig | 2 + drivers/mfd/Kconfig | 6 + drivers/mfd/Makefile | 1 + drivers/mfd/hisi_ip_core.c | 124 ++ drivers/regulator/Kconfig | 11 + drivers/regulator/Makefile | 2 + drivers/regulator/hisi_ip_regulator.c | 858 ++++++++++ drivers/regulator/hisi_regulator_ip_debug.c | 1444 +++++++++++++++++ include/linux/mfd/hisi_ip_core.h | 42 + 12 files changed, 2662 insertions(+) create mode 100644 arch/arm64/boot/dts/hisilicon/hisi_power_ip_test.dtsi create mode 100644 arch/arm64/boot/dts/hisilicon/kirin970_powerip.dtsi create mode 100644 drivers/mfd/hisi_ip_core.c create mode 100644 drivers/regulator/hisi_ip_regulator.c create mode 100644 drivers/regulator/hisi_regulator_ip_debug.c create mode 100644 include/linux/mfd/hisi_ip_core.h diff --git a/arch/arm64/boot/dts/hisilicon/hisi_power_ip_test.dtsi b/arch/arm64/boot/dts/hisilicon/hisi_power_ip_test.dtsi new file mode 100644 index 000000000000..5caec387002e --- /dev/null +++ b/arch/arm64/boot/dts/hisilicon/hisi_power_ip_test.dtsi @@ -0,0 +1,12 @@ + / { + regu_ip: test_regu_ip@0xFFF35000 { + compatible = "hisilicon,regulator-ip-test"; + reg = <0x0 0xFFF35000 0x0 0x1000>; /* 4K */ + vivobustest-supply = <&vivobus>; + dsssubsystest-supply = <&dsssubsys>; + vcodecsubsystest-supply = <&vcodecsubsys>; + vdectest-supply = <&vdec>; + venctest-supply = <&venc>; + ispsubsystest-supply = <&ispsubsys>; + }; +}; diff --git a/arch/arm64/boot/dts/hisilicon/kirin970-hikey970.dts b/arch/arm64/boot/dts/hisilicon/kirin970-hikey970.dts index b350ed53176f..2b4992b5c708 100755 --- a/arch/arm64/boot/dts/hisilicon/kirin970-hikey970.dts +++ b/arch/arm64/boot/dts/hisilicon/kirin970-hikey970.dts @@ -13,6 +13,8 @@ #include #include "kirin970_spmi.dtsi" #include "hisi_6421v600_pmic_spmi.dtsi" +#include "kirin970_powerip.dtsi" +#include "hisi_power_ip_test.dtsi" #include "kirin970-gpu.dtsi" #include "kirin970-ion.dtsi" #include "kirin970_ipc.dtsi" diff --git a/arch/arm64/boot/dts/hisilicon/kirin970_powerip.dtsi b/arch/arm64/boot/dts/hisilicon/kirin970_powerip.dtsi new file mode 100644 index 000000000000..57010047d3f8 --- /dev/null +++ b/arch/arm64/boot/dts/hisilicon/kirin970_powerip.dtsi @@ -0,0 +1,158 @@ +/* + * Copyright (C) 2012-2013 Linaro Ltd. + * + * 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 + * publishhed by the Free Software Foundation. + */ + +/{ + regulators_ip: regulator_ip@0xFFF35000 { + compatible = "hisilicon,hisi_regulator_ip_atf_core"; + reg = <0x00 0xE87FF000 0x00 0x1000>; + + media1_subsys: ip@0 { + compatible = "ip-regulator-atf"; + regulator-name = "media1_subsys"; + hisilicon,hisi-regulator-id = <0>; + hisilicon,hisi-regulator-type = <1>;/*0:pmu;1:ip;2:scharger*/ + hisilicon,hisi-regulator-clk-num = <0>; + hisilicon,hisi-regulator-clk-check-flag = <0>;/*0:not check clock state;1:check clock state*/ + hisilicon,hisi-need-to-enable-clock = <0>;/*0:donot enable clock;1:enable clock*/ + hisilicon,hisi-clock-rate-set-flag = <0>;/*low frequency clock set flag:0:donot set clock rate;1:set clock rate*/ + hisilicon,hisi-clock-rate-set = <0>;/*frequency:0:not set frequency;*/ + hisilicon,hisi-ppll0-clock-rate-set-flag = <0>;/*switch to ppll0 flag:0:donot set clock rate;1:set clock rate*/ + hisilicon,hisi-ppll0-clock-rate-set = <0>;/*ppll0 frequency:0:not set frequency;*/ + hisilicon,hisi-regulator-is-fake = <0>;/*0:this ip is effective;1:this ip is ineffective*/ + }; + vivobus: ip@1 { + compatible = "ip-regulator-atf"; + regulator-name = "vivobus"; + hisilicon,hisi-regulator-id = <1>; + hisilicon,hisi-regulator-type = <1>;/*0:pmu;1:ip;2:scharger*/ + vivobus-supply = <&media1_subsys>; + hisilicon,supply_name = "vivobus"; + hisilicon,hisi-regulator-clk-num = <0>; + hisilicon,hisi-regulator-clk-check-flag = <0>;/*0:not check clock state;1:check clock state*/ + hisilicon,hisi-need-to-enable-clock = <0>;/*0:donot enable clock;1:enable clock*/ + hisilicon,hisi-clock-rate-set-flag = <0>;/*low frequency clock set flag:0:donot set clock rate;1:set clock rate*/ + hisilicon,hisi-ppll0-clock-rate-set-flag = <0>; + hisilicon,hisi-ppll0-clock-rate-set = <0>; + hisilicon,hisi-regulator-is-fake = <0>;/*0:this ip is effective;1:this ip is ineffective*/ + }; + + media2_subsys: ip@8 { + compatible = "ip-regulator-atf"; + regulator-name = "media2_subsys"; + hisilicon,hisi-regulator-id = <8>; + hisilicon,hisi-regulator-type = <1>; + hisilicon,hisi-regulator-clk-num = <0>; + hisilicon,hisi-regulator-clk-check-flag = <0>; + hisilicon,hisi-need-to-enable-clock = <0>; + hisilicon,hisi-clock-rate-set-flag = <0>; + hisilicon,hisi-clock-rate-set = <0>; + hisilicon,hisi-ppll0-clock-rate-set-flag = <0>; + hisilicon,hisi-ppll0-clock-rate-set = <0>; + hisilicon,hisi-regulator-is-fake = <0>; + }; + + vcodecsubsys: ip@2 { + compatible = "ip-regulator-atf"; + regulator-name = "vcodecsubsys"; + hisi,noc-node-name = "peri_vcodec_bus"; + hisilicon,hisi-regulator-id = <2>; + vcodecsubsys-supply = <&media2_subsys>; + hisilicon,supply_name = "vcodecsubsys"; + hisilicon,hisi-regulator-type = <1>; + hisilicon,hisi-regulator-clk-num = <0>; + hisilicon,hisi-regulator-clk-check-flag = <0>; + hisilicon,hisi-need-to-enable-clock = <0>; + hisilicon,hisi-clock-rate-set-flag = <0>; + hisilicon,hisi-clock-rate-set = <0>; + hisilicon,hisi-ppll0-clock-rate-set-flag = <0>; + hisilicon,hisi-ppll0-clock-rate-set = <0>; + hisilicon,hisi-regulator-is-fake = <0>; + }; + dsssubsys: ip@3 { + compatible = "ip-regulator-atf"; + regulator-name = "dsssubsys"; + hisilicon,hisi-regulator-id = <3>; + dsssubsys-supply = <&vivobus>; + hisilicon,supply_name = "dsssubsys"; + hisilicon,hisi-regulator-type = <1>; + hisilicon,hisi-regulator-clk-num = <0>; + hisilicon,hisi-regulator-clk-check-flag = <0>; + hisilicon,hisi-need-to-enable-clock = <0>; + hisilicon,hisi-clock-rate-set-flag = <0>; + hisilicon,hisi-clock-rate-set = <0>; + hisilicon,hisi-ppll0-clock-rate-set-flag = <0>; + hisilicon,hisi-ppll0-clock-rate-set = <0>; + hisilicon,hisi-regulator-is-fake = <0>; + hisilicon,hisi-regulator-dss-boot-check = <0x38 0xC0>; + }; + ispsubsys: ip@4 { + compatible = "ip-regulator-atf"; + regulator-name = "ispsubsys"; + hisilicon,hisi-regulator-id = <4>; + ispsubsys-supply = <&vivobus>; + hisilicon,supply_name = "ispsubsys"; + hisilicon,hisi-regulator-type = <1>; + hisilicon,hisi-regulator-clk-num = <0>; + hisilicon,hisi-regulator-clk-check-flag = <0>; + hisilicon,hisi-need-to-enable-clock = <0>; + hisilicon,hisi-clock-rate-set-flag = <0>; + hisilicon,hisi-clock-rate-set = <0>; + hisilicon,hisi-ppll0-clock-rate-set-flag = <0>; + hisilicon,hisi-ppll0-clock-rate-set = <0>; + hisilicon,hisi-regulator-is-fake = <0>; + }; + vdec: ip@5 { + compatible = "ip-regulator-atf"; + regulator-name = "vdec"; + hisilicon,hisi-regulator-id = <5>; + vdec-supply = <&vcodecsubsys>; + hisilicon,supply_name = "vdec"; + hisilicon,hisi-regulator-type = <1>; + hisilicon,hisi-regulator-clk-num = <0>; + hisilicon,hisi-regulator-clk-check-flag = <0>; + hisilicon,hisi-need-to-enable-clock = <0>; + hisilicon,hisi-clock-rate-set-flag = <0>; + hisilicon,hisi-clock-rate-set = <0>; + hisilicon,hisi-ppll0-clock-rate-set-flag = <0>; + hisilicon,hisi-ppll0-clock-rate-set = <0>; + hisilicon,hisi-regulator-is-fake = <0>; + }; + venc: ip@6 { + compatible = "ip-regulator-atf"; + regulator-name = "venc"; + hisilicon,hisi-regulator-id = <6>; + venc-supply = <&vcodecsubsys>; + hisilicon,supply_name = "venc"; + hisilicon,hisi-regulator-type = <1>; + hisilicon,hisi-regulator-clk-num = <0>; + hisilicon,hisi-regulator-clk-check-flag = <0>; + hisilicon,hisi-need-to-enable-clock = <0>; + hisilicon,hisi-clock-rate-set-flag = <0>; + hisilicon,hisi-clock-rate-set = <0>; + hisilicon,hisi-ppll0-clock-rate-set-flag = <0>; + hisilicon,hisi-ppll0-clock-rate-set = <0>; + hisilicon,hisi-regulator-is-fake = <0>; + }; + isp_srt: ip@7 { + compatible = "ip-regulator-atf"; + regulator-name = "isp_srt"; + hisilicon,hisi-regulator-id = <7>; + isp_srt-supply = <&ispsubsys>; + hisilicon,supply_name = "isp_srt"; + hisilicon,hisi-regulator-type = <1>; + hisilicon,hisi-regulator-clk-num = <0>; + hisilicon,hisi-regulator-clk-check-flag = <0>; + hisilicon,hisi-need-to-enable-clock = <0>; + hisilicon,hisi-clock-rate-set-flag = <0>; + hisilicon,hisi-clock-rate-set = <0>; + hisilicon,hisi-ppll0-clock-rate-set-flag = <0>; + hisilicon,hisi-ppll0-clock-rate-set = <0>; + hisilicon,hisi-regulator-is-fake = <0>; + }; + }; +}; diff --git a/arch/arm64/configs/hikey970_defconfig b/arch/arm64/configs/hikey970_defconfig index c77d7ca03ddb..0c57a5573180 100644 --- a/arch/arm64/configs/hikey970_defconfig +++ b/arch/arm64/configs/hikey970_defconfig @@ -398,6 +398,8 @@ CONFIG_SPI_SPIDEV=m CONFIG_SPMI=y CONFIG_HISI_PMIC_PMU_SPMI=y CONFIG_HISI_REGULATOR_SPMI=y +CONFIG_MFD_HISI_IP_CORE=y +CONFIG_DRV_HISI_IP_REGULATOR=y CONFIG_PINCTRL_SINGLE=y CONFIG_PINCTRL_MAX77620=y CONFIG_PINCTRL_MSM8916=y diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig index 2c0f89c24b8b..66236ce35ced 100644 --- a/drivers/mfd/Kconfig +++ b/drivers/mfd/Kconfig @@ -367,6 +367,12 @@ config HISI_PMIC_PMU_SPMI mapped I/O ports are the way of communication with it. and use spmi passageway read pmu address. +config MFD_HISI_IP_CORE + tristate "Control HiSilicon system interior area Bus on and off" + depends on OF + help + This driver control HiSilicon system interior area power management from atf. + config HTC_PASIC3 tristate "HTC PASIC3 LED/DS1WM chip support" select MFD_CORE diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile index ab3ebbbb758b..96fc7a2cd508 100644 --- a/drivers/mfd/Makefile +++ b/drivers/mfd/Makefile @@ -202,6 +202,7 @@ obj-$(CONFIG_MFD_MENF21BMC) += menf21bmc.o obj-$(CONFIG_MFD_HI6421_PMIC) += hi6421-pmic-core.o obj-$(CONFIG_MFD_HI655X_PMIC) += hi655x-pmic.o obj-$(CONFIG_HISI_PMIC_PMU_SPMI) += hisi_pmic_spmi.o +obj-$(CONFIG_MFD_HISI_IP_CORE) += hisi_ip_core.o obj-$(CONFIG_MFD_DLN2) += dln2.o obj-$(CONFIG_MFD_RT5033) += rt5033.o obj-$(CONFIG_MFD_SKY81452) += sky81452.o diff --git a/drivers/mfd/hisi_ip_core.c b/drivers/mfd/hisi_ip_core.c new file mode 100644 index 000000000000..99742927c9b7 --- /dev/null +++ b/drivers/mfd/hisi_ip_core.c @@ -0,0 +1,124 @@ +/* + * Device driver for hi3xxx power manger + * + * Copyright (c) 2013 Linaro Ltd. + * Copyright (c) 2011 Hisilicon. + * + * + * 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 the + * GNU General Public License for more details. + * + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static DEFINE_MUTEX(reg_lock_mutex); + +static struct of_device_id of_hisi_regulator_ip_core_child_match_tbl[] = { + /* regulators */ + { + .compatible = "ip-regulator-atf", + }, + { /* end */ } +}; + +static struct of_device_id of_hisi_regulator_ip_core_match_tbl[] = { + { + .compatible = "hisilicon,hisi_regulator_ip_atf_core", + }, + { /* end */ } +}; + +static int hisi_regulator_ip_core_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct device_node *np = dev->of_node; + struct hisi_regulator_ip_core *pmic = NULL; + int ret = 0; + + pmic = devm_kzalloc(dev, sizeof(*pmic), GFP_KERNEL); + if (!pmic) { + dev_err(dev, "cannot allocate hisi_regulator_ip_core device info\n"); + return -ENOMEM; + } + + /* get resources */ + pmic->res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!pmic->res) { + dev_err(dev, "platform_get_resource err !\n"); + return -ENOENT;/*lint !e429*/ + } + + if (!devm_request_mem_region(dev, pmic->res->start, + resource_size(pmic->res), + pdev->name)) { + dev_err(dev, "cannot claim register memory\n"); + return -ENOMEM;/*lint !e429*/ + } + + pmic->regs = devm_ioremap(dev, pmic->res->start, + resource_size(pmic->res)); + if (!pmic->regs) { + dev_err(dev, "cannot map register memory\n"); + return -ENOMEM;/*lint !e429*/ + } + platform_set_drvdata(pdev, pmic); + + of_platform_populate(np, of_hisi_regulator_ip_core_child_match_tbl, NULL, dev); + + return ret;/*lint !e429*/ + +} + +static int hisi_regulator_ip_core_remove(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct hisi_regulator_ip_core *pmic = platform_get_drvdata(pdev); + + devm_iounmap(dev, pmic->regs); + devm_release_mem_region(dev, pmic->res->start, + resource_size(pmic->res)); + devm_kfree(dev, pmic); + platform_set_drvdata(pdev, NULL); + + return 0; +} + +static struct platform_driver hisi_regulator_ip_core_driver = { + .driver = { + .name = "hisi_regulator_ip_core", + .owner = THIS_MODULE, + .of_match_table = of_hisi_regulator_ip_core_match_tbl, + }, + .probe = hisi_regulator_ip_core_probe, + .remove = hisi_regulator_ip_core_remove, +}; + +static int __init hisi_regulator_ip_core_init(void) +{ + return platform_driver_register(&hisi_regulator_ip_core_driver); +} +fs_initcall(hisi_regulator_ip_core_init); + +static void __exit hisi_regulator_ip_core_exit(void) +{ + platform_driver_unregister(&hisi_regulator_ip_core_driver); +} +module_exit(hisi_regulator_ip_core_exit); + +MODULE_DESCRIPTION("Hisi regulator ip driver"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig index 3dd13da15658..764a12a91c5b 100755 --- a/drivers/regulator/Kconfig +++ b/drivers/regulator/Kconfig @@ -295,6 +295,17 @@ config HISI_REGULATOR_SPMI This driver provides support for the voltage regulators on the HiSilicon Hisi PMU / Codec IC. +config DRV_HISI_IP_REGULATOR + tristate "HiSilicon system interior bus mtcmos control" + depends on MFD_HISI_IP_CORE + help + This driver provides system interior bus switch support for the IP regulator on the HiSilicon system. + +config REGULATOR_IP_DEBUG + tristate "HiSilicon system regulator ip debug" + help + This driver provides support for system ip control test. + config REGULATOR_ISL9305 tristate "Intersil ISL9305 regulator" depends on I2C diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile index b359fecb7ec6..fb74dd34e98f 100755 --- a/drivers/regulator/Makefile +++ b/drivers/regulator/Makefile @@ -38,6 +38,8 @@ obj-$(CONFIG_REGULATOR_HI6421) += hi6421-regulator.o obj-$(CONFIG_REGULATOR_HI6421V530) += hi6421v530-regulator.o obj-$(CONFIG_REGULATOR_HI655X) += hi655x-regulator.o obj-$(CONFIG_HISI_REGULATOR_SPMI) += hisi_regulator_spmi.o +obj-$(CONFIG_DRV_HISI_IP_REGULATOR) += hisi_ip_regulator.o +obj-$(CONFIG_REGULATOR_IP_DEBUG) += hisi_regulator_ip_debug.o obj-$(CONFIG_REGULATOR_ISL6271A) += isl6271a-regulator.o obj-$(CONFIG_REGULATOR_ISL9305) += isl9305.o obj-$(CONFIG_REGULATOR_LM363X) += lm363x-regulator.o diff --git a/drivers/regulator/hisi_ip_regulator.c b/drivers/regulator/hisi_ip_regulator.c new file mode 100644 index 000000000000..83040632a0ab --- /dev/null +++ b/drivers/regulator/hisi_ip_regulator.c @@ -0,0 +1,858 @@ +/* + * Device driver for regulators in Hi3xxx IC + * + * Copyright (c) 2013 Linaro Ltd. + * Copyright (c) 2011 Hisilicon. + * + * + * 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 the + * GNU General Public License for more details. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 13, 0)) +#include +#endif +#include +#include +#include +#include + +#include +#include + +#if CONFIG_DEBUG_FS +#define IP_REGULATOR_DEBUG(args...) pr_err(args); +#else +#define IP_REGULATOR_DEBUG(args...) +#endif + +enum ip_regulator_id { + MEDIA1_SUBSYS_ID = 0, + VIVOBUS_ID, + VCODECSUBSYS_ID, + DSSSUBSYS_ID, + ISPSUBSYS_ID, + VDEC_ID, + VENC_ID, + ISP_SRT_ID, + MEDIA2_SUBSYS_ID, + IP_REGULATOR_ID_MAX, +}; + +/******************************macro parameter*********************************/ +enum { + REGULATOR_DISABLE = 0, + REGULATOR_ENABLE +}; + +#define REGULATOR_HWLOCK_TIMEOUT 1000 +#define AP_AOD_EN 0 +#define SENSORHUB_AOD_EN 1 + +static struct hwspinlock *regulator_hwlock_29; + +/*****************************ip struct parameter*****************************/ +struct hisi_regulator_ip { + const char *name; + struct device_node *np; + struct regulator_desc rdesc; + int (*dt_parse)(struct hisi_regulator_ip *, struct platform_device *); + int regulator_id; + struct mutex regulator_lock; + u32 regulator_enalbe_flag; + int regulator_fake; + int regulator_type; + int clock_num; + int clock_check_flag; + int enable_clock; + int clock_set_rate_flag; + unsigned int *clock_rate_value; + unsigned int *clock_org_rate; + unsigned int ppll0_clock_set_rate_flag; + unsigned int ppll0_clock_rate_value; + void __iomem *sctrl_reg; + int hwlock_seq; /* aod hwlock sequnce*/ + u32 aod_sc_offset; /* SC offset */ + u32 dss_boot_check[2]; +}; + +#define DSS_SOFTRESET_STATE_CHECK_BIT 0 + +/*Always on display need to vote media1,vivobus power on/off in sctrl*/ +static int aod_set_and_get_poweron_state(struct hisi_regulator_ip *sreg, u32 control_flag) +{ + int ret = 0; + int bit_mask = 0; + int val = 0; + /*sctrl 0x438 : power state vote + *bit[0]:AP media1 vote + *bit[1]:Sensorhub media1 vote + *bit[2]:AP vivobus vote + *bit[3]:Sensorhub vivobus vote + *bit[4]:AP dss vote + *bit[5]:Sensorhub dss vote + */ + if (VIVOBUS_ID == sreg->regulator_id) { + bit_mask = 2; + } else if (DSSSUBSYS_ID == sreg->regulator_id) { + bit_mask = 4; + } + + val = readl(sreg->sctrl_reg + sreg->aod_sc_offset); + if (0 == (val & (BIT(SENSORHUB_AOD_EN)<sctrl_reg + sreg->aod_sc_offset); + + return ret; +} + +static inline struct hisi_regulator_ip_core *rdev_to_ip_core(struct regulator_dev *dev) +{ + /* regulator_dev parent to-> + * hisi ip regulator platform device_dev parent to-> + * hisi ip pmic platform device_dev + */ + return dev_get_drvdata(rdev_get_dev(dev)->parent->parent); +} + +extern bool __clk_is_enabled(struct clk *clk); +static struct clk *of_regulator_clk_get(struct device_node *node, int index) +{ + struct clk *clk; + const char *clk_name; + int ret = 0; + IP_REGULATOR_DEBUG("<[%s]: begin>\n", __func__); + ret = of_property_read_string_index(node, "clock-names", index, &clk_name); + if (ret != 0) { + pr_err("failed to get regulator clk resource! ret=%d.\n", ret); + return ERR_PTR(-EINVAL); + } + clk = clk_get(NULL, clk_name); + if (IS_ERR(clk)) { + pr_err(" %s: %s %d get failed!\n", __func__, clk_name, __LINE__); + return ERR_PTR(-EINVAL); + } + IP_REGULATOR_DEBUG("<[%s]: end>\n", __func__); + return clk; +} + +static int hisi_clock_state_check(struct hisi_regulator_ip *sreg) +{ + struct clk *temp_clock; + int i; + bool clock_flag; + IP_REGULATOR_DEBUG("<[%s]: begin regulator_id=%d>\n", __func__, sreg->regulator_id); + for (i = 0; i < sreg->clock_num; i++) { + temp_clock = of_regulator_clk_get(sreg->np, i); + if (IS_ERR(temp_clock)) { + temp_clock = NULL; + return -EINVAL; + } + IP_REGULATOR_DEBUG("<[%s]: clock_name=%s>\n", __func__, __clk_get_name(temp_clock)); + clock_flag = __clk_is_enabled(temp_clock); + if (false == clock_flag) { + pr_err("<[%s]: clock_name=%s had closed!>\n", __func__, __clk_get_name(temp_clock)); + } + } + IP_REGULATOR_DEBUG("<[%s]: end regulator_id=%d>\n", __func__, sreg->regulator_id); + return 0; +} + +static int get_softreset_state(struct hisi_regulator_ip_core *pmic, struct hisi_regulator_ip *sreg, unsigned int value) +{ + int ret = 0; + int val = 0; + /*First boot and AOD to camera need check DSS poweron status*/ + if (sreg->hwlock_seq > 0) { + if (NULL == regulator_hwlock_29) { + pr_err("[%s]regulator hwlock_29 hwspinlock is null!\n", __func__); + return -ENOENT; + } + + if (hwspin_lock_timeout(regulator_hwlock_29, REGULATOR_HWLOCK_TIMEOUT)) { + pr_err("Aod regulator enable hwspinlock timout!\n"); + return -ENOENT; + } + } + IP_REGULATOR_DEBUG("<[%s]: sreg->dss_boot_check[0]=0x%x>\n", __func__, sreg->dss_boot_check[0]); + IP_REGULATOR_DEBUG("<[%s]: regulator_id[%d] softreset_value=0x%x softreset_state3 = 0x%x>\n", __func__, + sreg->regulator_id, sreg->dss_boot_check[1], readl((sreg->dss_boot_check[0]+ pmic->regs))); + if (((sreg->dss_boot_check[1]) & (readl(sreg->dss_boot_check[0]+ pmic->regs)))) + ret = 0;/*softreset*/ + else + ret = 1;/*unreset*/ + if (sreg->hwlock_seq > 0) { + if(ret == 1){ + val = readl(sreg->sctrl_reg + sreg->aod_sc_offset); + val |= (BIT(4)); + pr_err("[%s]AOD DSS vote val = 0x%x !\n", __func__, val); + writel(val, sreg->sctrl_reg + sreg->aod_sc_offset);/*vote aod dss enable*/ + } + hwspin_unlock(regulator_hwlock_29); + } + return ret; +}/*lint !e715*/ + +static int hisi_ppll0_clock_rate_set(struct hisi_regulator_ip *sreg) +{ + struct clk *temp_clock; + int ret; + + IP_REGULATOR_DEBUG("<[%s]: begin regulator_id=%d clock_num=%d>\n", __func__, sreg->regulator_id, sreg->clock_num); + /*0:get current clock*/ + temp_clock = of_regulator_clk_get(sreg->np, 0); + if (IS_ERR(temp_clock)) { + temp_clock = NULL; + return -EINVAL; + } + IP_REGULATOR_DEBUG("<[%s]: clock_name=%s, clock_rate=0x%x>\n", __func__, __clk_get_name(temp_clock), sreg->ppll0_clock_rate_value); + /*1:set freq rate to clock*/ + ret = clk_set_rate(temp_clock, sreg->ppll0_clock_rate_value); + if (ret < 0) { + pr_err("file:%s line:%d temp clock[%s] set rate fail!\n", __func__, __LINE__, __clk_get_name(temp_clock)); + return -EINVAL; + } + IP_REGULATOR_DEBUG("<[%s]: end regulator_id=%d>\n", __func__, sreg->regulator_id); + return 0; +} + +static int hisi_clock_rate_set(struct hisi_regulator_ip *sreg, int flag) +{ + struct clk *temp_clock; + int i; + int ret; + + IP_REGULATOR_DEBUG("<[%s]: begin regulator_id=%d clock_num=%d>\n", __func__, sreg->regulator_id, sreg->clock_num); + if (0 == flag) {/*save*/ + for (i = 0; i < sreg->clock_num; i++) { + if (0 == sreg->clock_rate_value[i]) + continue; + /*0:get current clock*/ + temp_clock = of_regulator_clk_get(sreg->np, i); + if (IS_ERR(temp_clock)) { + temp_clock = NULL; + return -EINVAL; + } + IP_REGULATOR_DEBUG("<[%s]: clock_name=%s>\n", __func__, __clk_get_name(temp_clock)); + /*1:get clock org value*/ + sreg->clock_org_rate[i] = clk_get_rate(temp_clock); + /*2:set low freq rate to clock*/ + ret = clk_set_rate(temp_clock, sreg->clock_rate_value[i]); + if (ret < 0) { + pr_err("file:%s line:%d temp clock[%s] set rate fail!\n", __func__, __LINE__, __clk_get_name(temp_clock)); + return -EINVAL; + } + IP_REGULATOR_DEBUG("<[%s]: begin clock_name = %s clock_org_rate[%d]=%d, clock_current_rate[%d]=%d>\n", + __func__, __clk_get_name(temp_clock), i, sreg->clock_org_rate[i], i, sreg->clock_rate_value[i]); + IP_REGULATOR_DEBUG("<[%s]: current clock_name[%s] rate[%ld]>\n", __func__, + __clk_get_name(temp_clock), clk_get_rate(temp_clock)); + } + } else { + for (i = 0; i < sreg->clock_num; i++) { + if (0 == sreg->clock_rate_value[i]) + continue; + /*0:get current clock*/ + temp_clock = of_regulator_clk_get(sreg->np, i); + if (IS_ERR(temp_clock)) { + temp_clock = NULL; + return -EINVAL; + } + /*1:resume org clock rate*/ + ret = clk_set_rate(temp_clock, sreg->clock_org_rate[i]); + if (ret < 0) { + pr_err("file:%s line:%d temp clock[%s] set rate fail!\n", __func__, __LINE__, __clk_get_name(temp_clock)); + return -EINVAL; + } + IP_REGULATOR_DEBUG("<[%s]: end clock_name = %s clock_org_rate[%d]=%d>\n", + __func__, __clk_get_name(temp_clock), i, sreg->clock_org_rate[i]); + IP_REGULATOR_DEBUG("<[%s]: current clock_name[%s] rate[%ld]>\n", __func__, + __clk_get_name(temp_clock), clk_get_rate(temp_clock)); + + } + } + IP_REGULATOR_DEBUG("<[%s]: end regulator_id=%d>\n", __func__, sreg->regulator_id); + return 0; +} + +static int hisi_ip_clock_work(struct hisi_regulator_ip *sreg, int flag) +{ + struct clk *temp_clock; + int i, ret = 0; + IP_REGULATOR_DEBUG("<[%s]: begin regulator_id=%d, clock_num = %d>\n", __func__, sreg->regulator_id, sreg->clock_num); + for (i = 0; i < sreg->clock_num; i++) { + temp_clock = of_regulator_clk_get(sreg->np, i); + if (IS_ERR(temp_clock)) { + temp_clock = NULL; + return -EINVAL; + } + IP_REGULATOR_DEBUG("<[%s]: clock_name = %s>\n", __func__, __clk_get_name(temp_clock)); + /*flag: 0 disable clock; 1 enable clock*/ + if (flag == REGULATOR_ENABLE) { + ret = clk_prepare_enable(temp_clock); + if (ret) { + pr_err("Regulator hi3630:regulator_id[%d],clock_id[%d] enable failed\r\n", sreg->regulator_id, i); + clk_put(temp_clock); + return ret; + } + IP_REGULATOR_DEBUG("<[%s]: clock_name = %s enable>\n", __func__, __clk_get_name(temp_clock)); + } else { + IP_REGULATOR_DEBUG("<[%s]: clock_name = %s disable>\n", __func__, __clk_get_name(temp_clock)); + clk_disable_unprepare(temp_clock); + clk_put(temp_clock); + } + } + IP_REGULATOR_DEBUG("<[%s]: end regulator_id=%d>\n", __func__, sreg->regulator_id); + return ret; +} + +/**************************arm trust firmware****************************************/ +#define IP_REGULATOR_REGISTER_FN_ID (0xc500fff0) +noinline int atfd_hisi_service_ip_regulator_smc(u64 function_id, u64 arg0, u64 arg1, u64 arg2) +{ + asm volatile( + __asmeq("%0", "x0") + __asmeq("%1", "x1") + __asmeq("%2", "x2") + __asmeq("%3", "x3") + "smc #0\n" + : "+r" (function_id) + : "r" (arg0), "r" (arg1), "r" (arg2)); + + return (int)function_id; +} + +static int hisi_ip_to_atf_is_enabled(struct regulator_dev *dev) +{ + struct hisi_regulator_ip *sreg = rdev_get_drvdata(dev); + struct hisi_regulator_ip_core *pmic = rdev_to_ip_core(dev); + + if (sreg == NULL || pmic == NULL) { + pr_err("[%s]regulator get para is err!\n", __func__); + return -EINVAL; + } + IP_REGULATOR_DEBUG("<[%s]:regulator_id=%d>\n", __func__, sreg->regulator_id); + return sreg->regulator_enalbe_flag; +} + +static int hisi_ip_power_on(struct hisi_regulator_ip *sreg) +{ + int ret = 0; + int aod_ret = 0; + if (sreg->hwlock_seq > 0) { + if (NULL == regulator_hwlock_29) { + pr_err("[%s] regulator hwlock_29 hwspinlock is null!\n", __func__); + return -ENOENT; + } + + if (hwspin_lock_timeout(regulator_hwlock_29, REGULATOR_HWLOCK_TIMEOUT)) { + pr_err("Aod regulator enable hwspinlock timout!\n"); + return -ENOENT; + } + aod_ret = aod_set_and_get_poweron_state(sreg, REGULATOR_ENABLE); + if (0 == aod_ret) { + ret = atfd_hisi_service_ip_regulator_smc(IP_REGULATOR_REGISTER_FN_ID, sreg->regulator_id, REGULATOR_ENABLE, 0); + } else if (1 == aod_ret) { + ret = 0; + } else { + pr_err("%s:aod set and get poweron state [%s] failled!\n\r", __func__, sreg->name); + } + hwspin_unlock(regulator_hwlock_29); + } else { + ret = atfd_hisi_service_ip_regulator_smc(IP_REGULATOR_REGISTER_FN_ID, sreg->regulator_id, REGULATOR_ENABLE, 0); + } + IP_REGULATOR_DEBUG("%s:hisi ip enable ldo[%s] to atf, ret=%d\n\r", __func__, sreg->name, ret); + return ret; +} + +static int hisi_ip_power_off(struct hisi_regulator_ip *sreg) +{ + int ret = 0; + int aod_ret = 0; + if (sreg->hwlock_seq > 0) { + if (NULL == regulator_hwlock_29) { + pr_err("[%s] regulator hwlock_29 hwspinlock is null!\n", __func__); + return -ENOENT; + } + if (hwspin_lock_timeout(regulator_hwlock_29, REGULATOR_HWLOCK_TIMEOUT)) { + pr_err("Aod regulator enable hwspinlock timout!\n"); + return -ENOENT; + } + aod_ret = aod_set_and_get_poweron_state(sreg, REGULATOR_DISABLE); + if (0 == aod_ret) + ret = atfd_hisi_service_ip_regulator_smc(IP_REGULATOR_REGISTER_FN_ID, sreg->regulator_id, REGULATOR_DISABLE, 0); + else if (1 == aod_ret) + ret = 0; + else + pr_err("%s:aod set and get poweroff state [%s] failled!\n\r", __func__, sreg->name); + hwspin_unlock(regulator_hwlock_29); + } else { + ret = atfd_hisi_service_ip_regulator_smc(IP_REGULATOR_REGISTER_FN_ID, sreg->regulator_id, REGULATOR_DISABLE, 0); + } + return ret; +} + +static int hisi_ip_to_atf_enabled(struct regulator_dev *dev) +{ + struct hisi_regulator_ip *sreg = rdev_get_drvdata(dev); + struct hisi_regulator_ip_core *pmic = rdev_to_ip_core(dev); + int ret = 0; + int softreset_value; + int dss_poweron_flag = 0; + + if (sreg == NULL || pmic == NULL) { + pr_err("[%s]regulator get para is err!\n", __func__); + return -EINVAL; + } + + IP_REGULATOR_DEBUG("\n<[%s]: begin regulator_id=%d>\n", __func__, sreg->regulator_id); + if (sreg->regulator_fake) { + sreg->regulator_enalbe_flag = 1; + return 0; + } + + /*this patch was resolved for dss power on in fastboot phase*/ + if ((DSSSUBSYS_ID == sreg->regulator_id)) { + softreset_value = get_softreset_state(pmic, sreg, DSS_SOFTRESET_STATE_CHECK_BIT); + IP_REGULATOR_DEBUG("<[%s]: regulator_id[%d] softreset_bit=%d>\n", __func__, sreg->regulator_id, softreset_value); + if (softreset_value) { + IP_REGULATOR_DEBUG("<[%s]: regulator_id[%d] was poweron in fastboot phase>\n", __func__, sreg->regulator_id); + dss_poweron_flag = 1; + sreg->regulator_enalbe_flag = 1; + return 0; + } + } + + if ((1 == sreg->clock_set_rate_flag) && (dss_poweron_flag == 0)) { + ret = hisi_clock_rate_set(sreg, 0); + if (ret) + pr_err("%s:hisi clock rate set fail!\n", __func__); + } + + if (1 == sreg->clock_check_flag) { + ret = hisi_clock_state_check(sreg); + if (ret) + pr_err("%s:hisi clock state check fail!\n", __func__); + + } + + if (1 == sreg->enable_clock) { + ret = hisi_ip_clock_work(sreg, REGULATOR_ENABLE); + if (ret) { + pr_err("[%s]hisi hisi_ip_clock_work is failed. ret[%d]!\n", __func__, ret); + } + } + + ret = hisi_ip_power_on(sreg); + if (0 == ret) { + sreg->regulator_enalbe_flag = 1; + } else { + pr_err("%s:hisi ip send enable ldo[%s] to atf failled!\n\r", __func__, sreg->name); + } + + if ((1 == sreg->clock_set_rate_flag) && (dss_poweron_flag == 0)) { + ret = hisi_clock_rate_set(sreg, 1); + if (ret) + pr_err("%s:hisi clock rate set fail!\n", __func__); + } + + IP_REGULATOR_DEBUG("<[%s]: end regulator_id=%d>\n", __func__, sreg->regulator_id); + return ret; +} + +static int hisi_ip_to_atf_disabled(struct regulator_dev *dev) +{ + struct hisi_regulator_ip *sreg = rdev_get_drvdata(dev); + int ret = 0; + + if (sreg == NULL) { + pr_err("[%s]regulator get para is err!\n", __func__); + return -EINVAL; + } + + IP_REGULATOR_DEBUG("\n<[%s]: begin regulator_id=%d>\n", __func__, sreg->regulator_id); + + if (sreg->regulator_fake) { + sreg->regulator_enalbe_flag = 0; + return 0; + } + + if (sreg->clock_check_flag) { + ret = hisi_clock_state_check(sreg); + if (ret) + pr_err("%s:hisi clock state check fail!\n", __func__); + } + + ret = hisi_ip_power_off(sreg); + if (!ret) { + sreg->regulator_enalbe_flag = 0; + ret = 0; + } else { + pr_err("%s:hisi ip send disable ldo[%s] to atf failled!\n\r", __func__, sreg->name); + } + + if (1 == sreg->ppll0_clock_set_rate_flag) { + ret = hisi_ppll0_clock_rate_set(sreg); + if (ret) { + pr_err("[%s]hisi ppll0_clock_set_rate_flag set failed. ret[%d]!\n", __func__, ret); + } + } + /*AOD need vivobus always on*/ + if (1 == sreg->enable_clock) { + ret = hisi_ip_clock_work(sreg, REGULATOR_DISABLE); + if (ret) { + pr_err("[%s]hisi hisi_ip_clock_work is failed. ret[%d]!\n", __func__, ret); + } + } + + IP_REGULATOR_DEBUG("<[%s]: end regulator_id=%d>\n", __func__, sreg->regulator_id); + return ret; +} + +static int hisi_dt_parse_aod_atf(struct hisi_regulator_ip *sreg, struct device_node *np) +{ + u32 aod_resource[2] = {0}; + if (NULL != of_find_property(np, "hisilicon,hisi-need-to-hwlock", NULL)) { + if (of_property_read_u32_array(np, "hisilicon,hisi-need-to-hwlock", aod_resource, 2)) { + pr_err("[%s]get hisilicon,hisi-need-to-hwlock attribute failed.\n", __func__); + return -ENODEV; + } + } + sreg->hwlock_seq = aod_resource[0]; + sreg->aod_sc_offset= aod_resource[1]; + if (sreg->hwlock_seq > 0) { + if (NULL == regulator_hwlock_29) { + regulator_hwlock_29 = hwspin_lock_request_specific(sreg->hwlock_seq); + if (NULL == regulator_hwlock_29) { + pr_err("Aod regulator request hwspin lock failed !\n"); + return -ENODEV; + } + } + } + return 0; +} + +static int hisi_dt_parse_ip_atf(struct hisi_regulator_ip *sreg, + struct platform_device *pdev) +{ + struct device *dev = NULL; + struct device_node *np = NULL; + int id = 0, fake = 0, type = 0; + int ret = 0; + unsigned int register_info[2] = {0}; + + if (sreg == NULL || pdev == NULL) { + pr_err("[%s]regulator get dt para is err!\n", __func__); + return -EINVAL; + } + + dev = &pdev->dev; + np = dev->of_node; + + /* regulator-id */ + ret = of_property_read_u32_array(np, "hisilicon,hisi-regulator-id", + &id, 1);/*lint !e64*/ + if (ret) { + dev_err(dev, "no hisilicon,hisi-regulator-id property set\n"); + goto dt_parse_common_end; + } + sreg->regulator_id = id; + + /* regulator-type */ + ret = of_property_read_u32_array(np, "hisilicon,hisi-regulator-type", + &type, 1);/*lint !e64*/ + if (ret) { + dev_err(dev, "no hisilicon,hisi-regulator-type property set\n"); + goto dt_parse_common_end; + } + sreg->regulator_type = type; + + /* regulator-fake */ + ret = of_property_read_u32_array(np, "hisilicon,hisi-regulator-is-fake", + &fake, 1);/*lint !e64*/ + if (ret) { + dev_err(dev, "no hisilicon,hisi-regulator-is-fake property set\n"); + goto dt_parse_common_end; + } + sreg->regulator_fake = fake; + + /* clock_check_flag */ + ret = of_property_read_u32_array(np, "hisilicon,hisi-regulator-clk-check-flag", + &sreg->clock_check_flag, 1);/*lint !e64*/ + if (ret) { + dev_err(dev, "no hisilicon,hisi-regulator-clk-check-flag property set\n"); + goto dt_parse_common_end; + } + + /* clock_num*/ + ret = of_property_read_u32_array(np, "hisilicon,hisi-regulator-clk-num", + &sreg->clock_num, 1);/*lint !e64*/ + if (ret) { + dev_err(dev, "no hisilicon,hisi-regulator-clk-num property set\n"); + goto dt_parse_common_end; + } + + /* enable clock flag*/ + ret = of_property_read_u32_array(np, "hisilicon,hisi-need-to-enable-clock", + &sreg->enable_clock, 1);/*lint !e64*/ + if (ret) { + dev_err(dev, "no hisilicon,hisi-need-to-enable-clock property set\n"); + goto dt_parse_common_end; + } + + /* clock set rate flag*/ + ret = of_property_read_u32_array(np, "hisilicon,hisi-clock-rate-set-flag", + &sreg->clock_set_rate_flag, 1);/*lint !e64*/ + if (ret) { + dev_err(dev, "no hisilicon,hisi-clock-rate-set-flag property set\n"); + goto dt_parse_common_end; + } + + if (1 == sreg->clock_set_rate_flag) { + /* clock rate*/ + sreg->clock_rate_value = (u32 *)devm_kzalloc(dev, sizeof(u32)*sreg->clock_num, GFP_KERNEL); + if (!sreg->clock_rate_value) { + dev_err(dev, "[%s]kzalloc clock_rate_value buffer failed.\n", __func__); + return -ENOMEM; + } + + sreg->clock_org_rate = (u32 *)devm_kzalloc(dev, sizeof(u32)*sreg->clock_num, GFP_KERNEL); + if (!sreg->clock_org_rate) { + dev_err(dev, "[%s]kzalloc clock_org_rate buffer failed.\n", __func__); + return -ENOMEM; + } + + ret = of_property_read_u32_array(np, "hisilicon,hisi-clock-rate-set", + sreg->clock_rate_value, sreg->clock_num); + if (ret) { + dev_err(dev, "[%s]get hisilicon,hisi-clock-rate-set-flag attribute failed.\n", __func__); + return -ENODEV; + } + } + /*ppll0 clock set rate flag*/ + ret = of_property_read_u32_array(np, "hisilicon,hisi-ppll0-clock-rate-set-flag", + &sreg->ppll0_clock_set_rate_flag, 1); + if (ret) { + sreg->ppll0_clock_set_rate_flag = 0; + ret = 0; + } + + IP_REGULATOR_DEBUG("<[%s]: regulator_id=%d, ppll0_clock_set_rate_flag=%d>\n", + __func__, sreg->regulator_id, sreg->ppll0_clock_set_rate_flag); + if (1 == sreg->ppll0_clock_set_rate_flag) { + /* clock rate*/ + ret = of_property_read_u32_array(np, "hisilicon,hisi-ppll0-clock-rate-set", + &sreg->ppll0_clock_rate_value, 1); + if (ret) { + dev_err(dev, "[%s]get hisilicon,hisi-ppll0-clock-rate-set-flag attribute failed.\n", __func__); + return -ENODEV; + } + } + + if ((DSSSUBSYS_ID == sreg->regulator_id)) { + of_property_read_u32_array(np, "hisilicon,hisi-regulator-dss-boot-check", + register_info, 2); + sreg->dss_boot_check[0] = register_info[0]; + sreg->dss_boot_check[1] = register_info[1]; + } + + hisi_dt_parse_aod_atf(sreg, np); +dt_parse_common_end: + return ret; +} + +/******************************ip voltage region ops*************************/ +struct regulator_ops hisi_ip_atf_rops = { + .is_enabled = hisi_ip_to_atf_is_enabled, + .enable = hisi_ip_to_atf_enabled, + .disable = hisi_ip_to_atf_disabled, +}; + +/******************************hisi_regulator_ip******************************/ +static const struct hisi_regulator_ip hisi_regulator_ip_atf = { + .rdesc = { + .ops = &hisi_ip_atf_rops, + .type = REGULATOR_VOLTAGE, + .owner = THIS_MODULE, + }, + .dt_parse = hisi_dt_parse_ip_atf, +}; + +/*********************of_hisi_regulator_ip_match_tbl***************************/ +static struct of_device_id of_hisi_regulator_ip_match_tbl[] = { + { + .compatible = "ip-regulator-atf", + .data = &hisi_regulator_ip_atf, + }, + { /* end */ } +}; + +static int hisi_regulator_ip_probe(struct platform_device *pdev) +{ + struct device *dev = NULL; + struct device_node *np = NULL; + struct regulator_desc *rdesc; + struct regulator_dev *rdev; + struct hisi_regulator_ip *sreg = NULL; + struct regulator_init_data *initdata; + struct regulator_config config = { }; + const struct of_device_id *match; + const struct hisi_regulator_ip *temp = NULL; + int ret = 0; + const char *supplyname = NULL; + + if (pdev == NULL) { + pr_err("[%s]regulator get platform device para is err!\n", __func__); + return -EINVAL; + } + + dev = &pdev->dev; + np = dev->of_node; + + /* to check which type of regulator this is */ + match = of_match_device(of_hisi_regulator_ip_match_tbl, &pdev->dev); + if (NULL == match) { + pr_err("get hi6421 regulator fail!\n\r"); + return -EINVAL; + } + + temp = match->data; +#if (LINUX_VERSION_CODE > KERNEL_VERSION(3, 13, 0)) + initdata = of_get_regulator_init_data(dev, np, NULL); +#else + initdata = of_get_regulator_init_data(dev, np); +#endif + if (NULL == initdata) { + pr_err("get regulator init data error !\n"); + return -EINVAL; + } + + sreg = kmemdup(temp, sizeof(*sreg), GFP_KERNEL); + if (!sreg) + return -ENOMEM; + + sreg->name = initdata->constraints.name; + rdesc = &sreg->rdesc; + rdesc->name = sreg->name; + + supplyname = of_get_property(np, "hisilicon,supply_name", NULL); + if (supplyname != NULL) { + initdata->supply_regulator = supplyname; + } + + mutex_init(&(sreg->regulator_lock)); + /* to parse device tree data for regulator specific */ + ret = sreg->dt_parse(sreg, pdev); + if (ret) { + dev_err(dev, "device tree parameter parse error!\n"); + goto hisi_ip_probe_end; + } + + config.dev = &pdev->dev; + config.init_data = initdata; + config.driver_data = sreg; + config.of_node = pdev->dev.of_node; + sreg->np = np; + sreg->regulator_enalbe_flag = 0; + np = NULL; + np = of_find_compatible_node(NULL, NULL, "hisilicon,kirin970-sctrl"); + if (!np) + pr_err("[%s] node doesn't have sysctrl node!\n", __func__); + else + sreg->sctrl_reg = of_iomap(np, 0); + if (!sreg->sctrl_reg) + pr_err("[%s] sysctrl iomap fail!\n", __func__); + + /* register regulator */ + rdev = regulator_register(rdesc, &config); + if (IS_ERR(rdev)) { + dev_err(dev, "failed to register %s\n", + rdesc->name); + ret = PTR_ERR(rdev); + goto hisi_ip_probe_end; + } + + platform_set_drvdata(pdev, rdev); + + return 0; + +hisi_ip_probe_end: + kfree(sreg); + return ret; +} + +static int hisi_regulator_ip_remove(struct platform_device *pdev) +{ + struct regulator_dev *rdev = platform_get_drvdata(pdev); + struct hisi_regulator_ip *sreg = rdev_get_drvdata(rdev); + + + regulator_unregister(rdev); + /* TODO: should i worry about that? devm_kzalloc */ + if (sreg->rdesc.volt_table) + devm_kfree(&pdev->dev, (unsigned int *)sreg->rdesc.volt_table); + + kfree(sreg); + return 0; +} + +static struct platform_driver hisi_regulator_ip_driver = { + .driver = { + .name = "hisi_regulator_ip", + .owner = THIS_MODULE, + .of_match_table = of_hisi_regulator_ip_match_tbl, + }, + .probe = hisi_regulator_ip_probe, + .remove = hisi_regulator_ip_remove, +}; + +static int __init hisi_regulator_ip_init(void) +{ + return platform_driver_register(&hisi_regulator_ip_driver); +} +fs_initcall(hisi_regulator_ip_init); + +static void __exit hisi_regulator_ip_exit(void) +{ + platform_driver_unregister(&hisi_regulator_ip_driver); +} +module_exit(hisi_regulator_ip_exit); + +MODULE_DESCRIPTION("Hisi regulator ip driver"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/regulator/hisi_regulator_ip_debug.c b/drivers/regulator/hisi_regulator_ip_debug.c new file mode 100644 index 000000000000..7e4d90f65de9 --- /dev/null +++ b/drivers/regulator/hisi_regulator_ip_debug.c @@ -0,0 +1,1444 @@ +/* + * Device driver for tests in IP regulator IC + * + * Copyright (c) 2013 Linaro Ltd. + * Copyright (c) 2011 Hisilicon. + * + * + * 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 the + * GNU General Public License for more details. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#define REGULATOR_VIVOBUS_ENA 100 +#define REGULATOR_VIVOBUS_DIS 101 +#define REGULATOR_DSSSUBSYS_ENA 102 +#define REGULATOR_DSSSUBSYS_DIS 103 +#define REGULATOR_VCODECSUBSYS_ENA 104 +#define REGULATOR_VCODECSUBSYS_DIS 105 +#define REGULATOR_VDEC_ENA 106 +#define REGULATOR_VDEC_DIS 107 +#define REGULATOR_VENC_ENA 108 +#define REGULATOR_VENC_DIS 109 +#define REGULATOR_ISPSUBSYS_ENA 110 +#define REGULATOR_ISPSUBSYS_DIS 111 +#define REGULATOR_IVP_ENA 112 +#define REGULATOR_IVP_DIS 113 + +#define REGULATOR_DEBUG_ENA 114 +#define REGULATOR_DEBUG_DIS 115 +#define REGULATOR_SEC_P_ENA 116 +#define REGULATOR_SEC_P_DIS 117 +#define REGULATOR_PERF_ENA 118 +#define REGULATOR_PERF_DIS 119 +#define REGULATOR_CSSYS_ENA 120 +#define REGULATOR_CSSYS_DIS 121 +#define REGULATOR_USBOTG_ENA 122 +#define REGULATOR_USBOTG_DIS 123 +#define REGULATOR_SEC_S_ENA 124 +#define REGULATOR_SEC_S_DIS 125 +#define REGULATOR_SOCP_ENA 126 +#define REGULATOR_SOCP_DIS 127 +#define REGULATOR_G3D_ENA 128 +#define REGULATOR_G3D_DIS 129 +#define REGULATOR_ASP_ENA 130 +#define REGULATOR_ASP_DIS 131 +#define REGULATOR_HIFI_ENA 132 +#define REGULATOR_HIFI_DIS 133 +#define REGULATOR_MMBUF_ENA 134 +#define REGULATOR_MMBUF_DIS 135 +#define REGULATOR_LDO8_ENA 136 +#define REGULATOR_LDO8_DIS 137 +#define REGULATOR_LDO26_ENA 138 +#define REGULATOR_LDO26_DIS 139 +#define REGULATOR_ISPSRT_ENA 140 +#define REGULATOR_ISPSRT_DIS 141 +/***************************ADDR begin*******************************/ +#define DSSSUBSYS_BASE_ADDR 0xE8600000 +#define ISPSUBSYS_BASE_ADDR 0xE8400000 +#define VDEC_BASE_ADDR 0xE8800000 +#define VENC_BASE_ADDR 0xE8900000 +#define PERF_BASE_ADDR 0xFF012000 +#define TOP_CSSYS_BASE_ADDR 0xEC000000 +#define SOCP_BASE_ADDR 0xFF030000 +#define SEC_S_BASE_ADDR 0xFF011000 +#define SEC_P_BASE_ADDR 0xFF010000 +#define ASP_BASE_ADDR 0xE804E000 +#define G3D_BASE_ADDR 0xE8970000 +#define MMBUF_BASE_ADDR 0xFFF02000 +#define IVP32_BASE_ADDR 0xE8D80000 + +/***************************ADDR end********************************/ + +struct regulator_ip_test { + struct resource *res; + struct device *dev; + void __iomem *regs; + + spinlock_t lock; + + struct regulator *vivobus_ip; + struct regulator *dsssubsys_ip; + struct regulator *vcodecsubsys_ip; + struct regulator *vdec_ip; + struct regulator *venc_ip; + struct regulator *ispsubsys_ip; + struct regulator *ivp_ip; + struct regulator *debugsubsys_ip; + struct regulator *sec_p_ip; + struct regulator *perf_ip; + struct regulator *top_cssys_ip; + struct regulator *usbotg_ip; + struct regulator *sec_s_ip; + struct regulator *socp_ip; + struct regulator *g3d_ip; + struct regulator *asp_ip; + struct regulator *hifi_ip; + struct regulator *mmbuf_ip; + struct regulator *ldo8_ip; + struct regulator *ldo26_ip; + struct regulator *ispsrt_ip; + struct regulator *geterror_ip; + + void __iomem *dsssubsys_reg; + void __iomem *ispsubsys_reg; + void __iomem *vdec_reg; + void __iomem *venc_reg; + void __iomem *sec_p_reg; + void __iomem *perf_reg; + + void __iomem *g3d_reg; + void __iomem *top_cssys_reg; + void __iomem *socp_reg; + void __iomem *sec_s_reg; + void __iomem *asp_reg; + void __iomem *mmbuf_reg; + void __iomem *ivp_reg; +}; +struct regulator_ip_test *g_regulator_ip_test; +static struct kobject *regulatoriptestobj; +#define MODULE_NAME "regulatoriptest" +/*const char *regulator_supply;*/ +static void regulator_ip_vivobus_enable_test(void) +{ + int ret; + static int ip_get_flag; + pr_info("\n<-----------------------[%s] test begin------------------------>\n", __func__); + if (0 == ip_get_flag) { + + /*regulator_supply = "vivobustest";*/ + g_regulator_ip_test->vivobus_ip = devm_regulator_get(g_regulator_ip_test->dev, "vivobustest"); + if (IS_ERR(g_regulator_ip_test->vivobus_ip)) { + pr_err("Couldn't get regulator ip [%s]! \n", __func__); + return; + } else { + pr_info("Get regulator ip [%s] succuse!\n", __func__); + } + ip_get_flag = 1; + } + /*-----------------control ip enable-----------------------*/ + ret = regulator_enable(g_regulator_ip_test->vivobus_ip); + if (ret != 0) { + pr_err("Failed to enable %s: %d\n", __func__, ret); + return ; + } + pr_info("<-----------------------[%s] test end------------------------>\n", __func__); +} + +static void regulator_ip_vivobus_disable_test(void) +{ + int ret; + pr_info("\n<-----------------------[%s] test begin------------------------>\n", __func__); + /*-----------------control ip disable-----------------------*/ + ret = regulator_disable(g_regulator_ip_test->vivobus_ip); + if (ret != 0) { + pr_err("Failed to disable %s: %d\n", __func__, ret); + return ; + } + pr_info("\n<-----------------------[%s] test end------------------------>\n", __func__); +} + +static void regulator_ip_dsssubsys_enable_test(void) +{ + int ret; + static int ip_get_flag; + pr_info("\n<-----------------------[%s] test begin------------------------>\n", __func__); + if (0 == ip_get_flag) { + + g_regulator_ip_test->dsssubsys_ip = devm_regulator_get(g_regulator_ip_test->dev, "dsssubsystest"); + if (IS_ERR(g_regulator_ip_test->dsssubsys_ip)) { + pr_err("Couldn't get regulator ip [%s]! \n", __func__); + return; + } else { + pr_info("Get regulator ip [%s] succuse!\n", __func__); + } + ip_get_flag = 1; + } + /*-----------------control ip enable-----------------------*/ + ret = regulator_enable(g_regulator_ip_test->dsssubsys_ip); + if (ret != 0) { + pr_err("Failed to enable %s: %d\n", __func__, ret); + return ; + } + + pr_info("<-----------------------[%s] test end------------------------>\n", __func__); +} + +static void regulator_ip_dsssubsys_disable_test(void) +{ + int ret; + pr_info("\n<-----------------------[%s] test begin------------------------>\n", __func__); + /*-----------------control ip disable-----------------------*/ + ret = regulator_disable(g_regulator_ip_test->dsssubsys_ip); + if (ret != 0) { + pr_err("Failed to disable %s: %d\n", __func__, ret); + return ; + } + pr_info("<-----------------------[%s] test end------------------------>\n", __func__); +} + +static void regulator_ip_vcodecsubsys_enable_test(void) +{ + int ret; + static int ip_get_flag; + pr_info("\n<-----------------------[%s] test begin------------------------>\n", __func__); + if (0 == ip_get_flag) { + + g_regulator_ip_test->vcodecsubsys_ip = devm_regulator_get(g_regulator_ip_test->dev, "vcodecsubsystest"); + if (IS_ERR(g_regulator_ip_test->vcodecsubsys_ip)) { + pr_err("Couldn't get regulator ip [%s]! \n", __func__); + return; + } else { + pr_info("Get regulator ip [%s] succuse!\n", __func__); + } + ip_get_flag = 1; + } + /*-----------------control ip enable-----------------------*/ + ret = regulator_enable(g_regulator_ip_test->vcodecsubsys_ip); + if (ret != 0) { + pr_err("Failed to enable %s: %d\n", __func__, ret); + return ; + } + + pr_info("<-----------------------[%s] test end------------------------>\n", __func__); +} +static void regulator_ip_vcodecsubsys_disable_test(void) +{ + int ret; + pr_info("\n<-----------------------[%s] test begin------------------------>\n", __func__); + /*-----------------control ip disable-----------------------*/ + ret = regulator_disable(g_regulator_ip_test->vcodecsubsys_ip); + if (ret != 0) { + pr_err("Failed to disable %s: %d\n", __func__, ret); + return ; + } + pr_info("<-----------------------[%s] test end------------------------>\n", __func__); +} +static void regulator_ip_vdec_enable_test(void) +{ + int ret; + static int ip_get_flag; + pr_info("\n<-----------------------[%s] test begin------------------------>\n", __func__); + if (0 == ip_get_flag) { + + g_regulator_ip_test->vdec_ip = devm_regulator_get(g_regulator_ip_test->dev, "vdectest"); + if (IS_ERR(g_regulator_ip_test->vdec_ip)) { + pr_err("Couldn't get regulator ip [%s]! \n", __func__); + return; + } else { + pr_info("Get regulator ip [%s] succuse!\n", __func__); + } + ip_get_flag = 1; + } + /*-----------------control ip enable-----------------------*/ + ret = regulator_enable(g_regulator_ip_test->vdec_ip); + if (ret != 0) { + pr_err("Failed to enable %s: %d\n", __func__, ret); + return ; + } + + pr_info("<-----------------------[%s] test end------------------------>\n", __func__); +} +static void regulator_ip_vdec_disable_test(void) +{ + int ret; + pr_info("\n<-----------------------[%s] test begin------------------------>\n", __func__); + /*-----------------control ip disable-----------------------*/ + ret = regulator_disable(g_regulator_ip_test->vdec_ip); + if (ret != 0) { + pr_err("Failed to disable %s: %d\n", __func__, ret); + return ; + } + pr_info("<-----------------------[%s] test end------------------------>\n", __func__); +} + +static void regulator_ip_venc_enable_test(void) +{ + int ret; + static int ip_get_flag; + pr_info("\n<-----------------------[%s] test begin------------------------>\n", __func__); + if (0 == ip_get_flag) { + + g_regulator_ip_test->venc_ip = devm_regulator_get(g_regulator_ip_test->dev, "venctest"); + if (IS_ERR(g_regulator_ip_test->venc_ip)) { + pr_err("Couldn't get regulator ip [%s]! \n", __func__); + return; + } else { + pr_info("Get regulator ip [%s] succuse!\n", __func__); + } + ip_get_flag = 1; + } + /*-----------------control ip enable-----------------------*/ + ret = regulator_enable(g_regulator_ip_test->venc_ip); + if (ret != 0) { + pr_err("Failed to enable %s: %d\n", __func__, ret); + return ; + } + + pr_info("<-----------------------[%s] test end------------------------>\n", __func__); +} + +static void regulator_ip_venc_disable_test(void) +{ + int ret; + pr_info("\n<-----------------------[%s] test begin------------------------>\n", __func__); + /*-----------------control ip disable-----------------------*/ + ret = regulator_disable(g_regulator_ip_test->venc_ip); + if (ret != 0) { + pr_err("Failed to disable %s: %d\n", __func__, ret); + return ; + } + pr_info("<-----------------------[%s] test end------------------------>\n", __func__); +} + +static void regulator_ip_ispsubsys_enable_test(void) +{ + int ret; + static int ip_get_flag; + pr_info("\n<-----------------------[%s] test begin------------------------>\n", __func__); + if (0 == ip_get_flag) { + + g_regulator_ip_test->ispsubsys_ip = devm_regulator_get(g_regulator_ip_test->dev, "ispsubsystest"); + if (IS_ERR(g_regulator_ip_test->ispsubsys_ip)) { + pr_err("Couldn't get regulator ip [%s]! \n", __func__); + return; + } else { + pr_info("Get regulator ip [%s] succuse!\n", __func__); + } + ip_get_flag = 1; + } + /*-----------------control ip enable-----------------------*/ + ret = regulator_enable(g_regulator_ip_test->ispsubsys_ip); + if (ret != 0) { + pr_err("Failed to enable %s: %d\n", __func__, ret); + return ; + } + + pr_info("<-----------------------[%s] test end------------------------>\n", __func__); +} +static void regulator_ip_ispsubsys_disable_test(void) +{ + int ret; + pr_info("\n<-----------------------[%s] test begin------------------------>\n", __func__); + /*-----------------control ip disable-----------------------*/ + ret = regulator_disable(g_regulator_ip_test->ispsubsys_ip); + if (ret != 0) { + pr_err("Failed to disable %s: %d\n", __func__, ret); + return ; + } + pr_info("<-----------------------[%s] test end------------------------>\n", __func__); +} +static void regulator_ip_ivp_enable_test(void) +{ + int ret; + static int ip_get_flag; + pr_info("\n<-----------------------[%s] test begin------------------------>\n", __func__); + if (0 == ip_get_flag) { + + g_regulator_ip_test->ivp_ip = devm_regulator_get(g_regulator_ip_test->dev, "ivptest"); + if (IS_ERR(g_regulator_ip_test->ivp_ip)) { + pr_err("Couldn't get regulator ip [%s]! \n", __func__); + return; + } else { + pr_info("Get regulator ip [%s] succuse!\n", __func__); + } + ip_get_flag = 1; + } + /*-----------------control ip enable-----------------------*/ + ret = regulator_enable(g_regulator_ip_test->ivp_ip); + if (ret != 0) { + pr_err("Failed to enable %s: %d\n", __func__, ret); + return ; + } + pr_info("<-----------------------[%s] test end------------------------>\n", __func__); +} +static void regulator_ip_ivp_disable_test(void) +{ + int ret; + pr_info("\n<-----------------------[%s] test begin------------------------>\n", __func__); + /*-----------------control ip disable-----------------------*/ + ret = regulator_disable(g_regulator_ip_test->ivp_ip); + if (ret != 0) { + pr_err("Failed to disable %s: %d\n", __func__, ret); + return ; + } + pr_info("<-----------------------[%s] test end------------------------>\n", __func__); +} + +static void regulator_ip_debugsubsys_enable_test(void) +{ + int ret; + static int ip_get_flag; + pr_info("\n<-----------------------[%s] test begin------------------------>\n", __func__); + if (0 == ip_get_flag) { + + g_regulator_ip_test->debugsubsys_ip = devm_regulator_get(g_regulator_ip_test->dev, "debugsubsystest"); + if (IS_ERR(g_regulator_ip_test->debugsubsys_ip)) { + pr_err("Couldn't get regulator ip [%s]! \n", __func__); + return; + } else { + pr_info("Get regulator ip [%s] succuse!\n", __func__); + } + ip_get_flag = 1; + } + /*-----------------control ip enable-----------------------*/ + ret = regulator_enable(g_regulator_ip_test->debugsubsys_ip); + if (ret != 0) { + pr_err("Failed to enable %s: %d\n", __func__, ret); + return ; + } + + pr_info("<-----------------------[%s] test end------------------------>\n", __func__); +} + +static void regulator_ip_debugsubsys_disable_test(void) +{ + int ret; + + pr_info("\n<-----------------------[%s] test begin------------------------>\n", __func__); + /*-----------------control ip disable-----------------------*/ + ret = regulator_disable(g_regulator_ip_test->debugsubsys_ip); + if (ret != 0) { + pr_err("Failed to disable %s: %d\n", __func__, ret); + return ; + } + pr_info("<-----------------------[%s] test end------------------------>\n", __func__); +} + +static void regulator_ip_sec_p_enable_test(void) +{ + int ret; + static int ip_get_flag; + pr_info("\n<-----------------------[%s] test begin------------------------>\n", __func__); + if (0 == ip_get_flag) { + + g_regulator_ip_test->sec_p_ip = devm_regulator_get(g_regulator_ip_test->dev, "sec_ptest"); + if (IS_ERR(g_regulator_ip_test->sec_p_ip)) { + pr_err("Couldn't get regulator ip [%s]! \n", __func__); + return; + } else { + pr_info("Get regulator ip [%s] succuse!\n", __func__); + } + ip_get_flag = 1; + } + /*-----------------control ip enable-----------------------*/ + ret = regulator_enable(g_regulator_ip_test->sec_p_ip); + if (ret != 0) { + pr_err("Failed to enable %s: %d\n", __func__, ret); + return ; + } + pr_info("<-----------------------[%s] test end------------------------>\n", __func__); +} + +static void regulator_ip_sec_p_disable_test(void) +{ + int ret; + pr_info("\n<-----------------------[%s] test begin------------------------>\n", __func__); + /*-----------------control ip disable-----------------------*/ + ret = regulator_disable(g_regulator_ip_test->sec_p_ip); + if (ret != 0) { + pr_err("Failed to disable %s: %d\n", __func__, ret); + return ; + } + pr_info("<-----------------------[%s] test end------------------------>\n", __func__); +} + +static void regulator_ip_perf_enable_test(void) +{ + int ret; + static int ip_get_flag; + pr_info("\n<-----------------------[%s] test begin------------------------>\n", __func__); + if (0 == ip_get_flag) { + + g_regulator_ip_test->perf_ip = devm_regulator_get(g_regulator_ip_test->dev, "perftest"); + if (IS_ERR(g_regulator_ip_test->perf_ip)) { + pr_err("Couldn't get regulator ip [%s]! \n", __func__); + return; + } else { + pr_info("Get regulator ip [%s] succuse!\n", __func__); + } + ip_get_flag = 1; + } + /*-----------------control ip enable-----------------------*/ + ret = regulator_enable(g_regulator_ip_test->perf_ip); + if (ret != 0) { + pr_err("Failed to enable %s: %d\n", __func__, ret); + return ; + } + pr_info("<-----------------------[%s] test end------------------------>\n", __func__); +} + +static void regulator_ip_perf_disable_test(void) +{ + int ret; + + pr_info("\n<-----------------------[%s] test begin------------------------>\n", __func__); + /*-----------------control ip disable-----------------------*/ + ret = regulator_disable(g_regulator_ip_test->perf_ip); + if (ret != 0) { + pr_err("Failed to disable %s: %d\n", __func__, ret); + return ; + } + pr_info("<-----------------------[%s] test end------------------------>\n", __func__); +} + +static void regulator_ip_top_cssys_enable_test(void) +{ + int ret; + static int ip_get_flag; + pr_info("\n<-----------------------[%s] test begin------------------------>\n", __func__); + if (0 == ip_get_flag) { + + g_regulator_ip_test->top_cssys_ip = devm_regulator_get(g_regulator_ip_test->dev, "top_cssystest"); + if (IS_ERR(g_regulator_ip_test->top_cssys_ip)) { + pr_err("Couldn't get regulator ip [%s]! \n", __func__); + return; + } else { + pr_info("Get regulator ip [%s] succuse!\n", __func__); + } + ip_get_flag = 1; + } + /*-----------------control ip enable-----------------------*/ + ret = regulator_enable(g_regulator_ip_test->top_cssys_ip); + if (ret != 0) { + pr_err("Failed to enable %s: %d\n", __func__, ret); + return ; + } + pr_info("<-----------------------[%s] test end------------------------>\n", __func__); +} + +static void regulator_ip_top_cssys_disable_test(void) +{ + int ret; + + pr_info("\n<-----------------------[%s] test begin------------------------>\n", __func__); + /*-----------------control ip disable-----------------------*/ + ret = regulator_disable(g_regulator_ip_test->top_cssys_ip); + if (ret != 0) { + pr_err("Failed to disable %s: %d\n", __func__, ret); + return ; + } + pr_info("<-----------------------[%s] test end------------------------>\n", __func__); +} + +static void regulator_ip_usbotg_enable_test(void) +{ + int ret; + static int ip_get_flag; + pr_info("\n<-----------------------[%s] test begin------------------------>\n", __func__); + if (0 == ip_get_flag) { + + g_regulator_ip_test->usbotg_ip = devm_regulator_get(g_regulator_ip_test->dev, "usbotgtest"); + if (IS_ERR(g_regulator_ip_test->usbotg_ip)) { + pr_err("Couldn't get regulator ip [%s]! \n", __func__); + return; + } else { + pr_info("Get regulator ip [%s] succuse!\n", __func__); + } + ip_get_flag = 1; + } + /*-----------------control ip enable-----------------------*/ + ret = regulator_enable(g_regulator_ip_test->usbotg_ip); + if (ret != 0) { + pr_err("Failed to enable %s: %d\n", __func__, ret); + return ; + } + + pr_info("<-----------------------[%s] test end------------------------>\n", __func__); +} + +static void regulator_ip_usbotg_disable_test(void) +{ + int ret; + + pr_info("\n<-----------------------[%s] test begin------------------------>\n", __func__); + /*-----------------control ip disable-----------------------*/ + ret = regulator_disable(g_regulator_ip_test->usbotg_ip); + if (ret != 0) { + pr_err("Failed to disable %s: %d\n", __func__, ret); + return ; + } + pr_info("<-----------------------[%s] test end------------------------>\n", __func__); +} + +static void regulator_ip_sec_s_enable_test(void) +{ + int ret; + static int ip_get_flag; + pr_info("\n<-----------------------[%s] test begin------------------------>\n", __func__); + if (0 == ip_get_flag) { + + g_regulator_ip_test->sec_s_ip = devm_regulator_get(g_regulator_ip_test->dev, "sec_stest"); + if (IS_ERR(g_regulator_ip_test->sec_s_ip)) { + pr_err("Couldn't get regulator ip [%s]! \n", __func__); + return; + } else { + pr_info("Get regulator ip [%s] succuse!\n", __func__); + } + ip_get_flag = 1; + } + /*-----------------control ip enable-----------------------*/ + ret = regulator_enable(g_regulator_ip_test->sec_s_ip); + if (ret != 0) { + pr_err("Failed to enable %s: %d\n", __func__, ret); + return ; + } + pr_info("<-----------------------[%s] test end------------------------>\n", __func__); +} + +static void regulator_ip_sec_s_disable_test(void) +{ + int ret; + + pr_info("\n<-----------------------[%s] test begin------------------------>\n", __func__); + /*-----------------control ip disable-----------------------*/ + ret = regulator_disable(g_regulator_ip_test->sec_s_ip); + if (ret != 0) { + pr_err("Failed to disable %s: %d\n", __func__, ret); + return ; + } + pr_info("<-----------------------[%s] test end------------------------>\n", __func__); +} + +static void regulator_ip_socp_enable_test(void) +{ + int ret; + static int ip_get_flag; + pr_info("\n<-----------------------[%s] test begin------------------------>\n", __func__); + if (0 == ip_get_flag) { + + g_regulator_ip_test->socp_ip = devm_regulator_get(g_regulator_ip_test->dev, "socptest"); + if (IS_ERR(g_regulator_ip_test->socp_ip)) { + pr_err("Couldn't get regulator ip [%s]! \n", __func__); + return; + } else { + pr_info("Get regulator ip [%s] succuse!\n", __func__); + } + ip_get_flag = 1; + } + /*-----------------control ip enable-----------------------*/ + ret = regulator_enable(g_regulator_ip_test->socp_ip); + if (ret != 0) { + pr_err("Failed to enable %s: %d\n", __func__, ret); + return ; + } + pr_info("<-----------------------[%s] test end------------------------>\n", __func__); +} + +static void regulator_ip_socp_disable_test(void) +{ + int ret; + + pr_info("\n<-----------------------[%s] test begin------------------------>\n", __func__); + /*-----------------control ip disable-----------------------*/ + ret = regulator_disable(g_regulator_ip_test->socp_ip); + if (ret != 0) { + pr_err("Failed to disable %s: %d\n", __func__, ret); + return ; + } + pr_info("<-----------------------[%s] test end------------------------>\n", __func__); +} + +static void regulator_ip_g3d_enable_test(void) +{ + int ret; + static int ip_get_flag; + pr_info("\n<-----------------------[%s] test begin------------------------>\n", __func__); + if (0 == ip_get_flag) { + + g_regulator_ip_test->g3d_ip = devm_regulator_get(g_regulator_ip_test->dev, "g3dtest"); + if (IS_ERR(g_regulator_ip_test->g3d_ip)) { + pr_err("Couldn't get regulator ip [%s]! \n", __func__); + return; + } else { + pr_info("Get regulator ip [%s] succuse!\n", __func__); + } + ip_get_flag = 1; + } + /*-----------------control ip enable-----------------------*/ + ret = regulator_enable(g_regulator_ip_test->g3d_ip); + if (ret != 0) { + pr_err("Failed to enable %s: %d\n", __func__, ret); + return ; + } + pr_info("<-----------------------[%s] test end------------------------>\n", __func__); +} + +static void regulator_ip_g3d_disable_test(void) +{ + int ret; + + pr_info("\n<-----------------------[%s] test begin------------------------>\n", __func__); + /*-----------------control ip disable-----------------------*/ + ret = regulator_disable(g_regulator_ip_test->g3d_ip); + if (ret != 0) { + pr_err("Failed to disable %s: %d\n", __func__, ret); + return ; + } + pr_info("<-----------------------[%s] test end------------------------>\n", __func__); +} + +static void regulator_ip_asp_enable_test(void) +{ + int ret; + static int ip_get_flag; + pr_info("\n<-----------------------[%s] test begin------------------------>\n", __func__); + if (0 == ip_get_flag) { + + g_regulator_ip_test->asp_ip = devm_regulator_get(g_regulator_ip_test->dev, "asptest"); + if (IS_ERR(g_regulator_ip_test->asp_ip)) { + pr_err("Couldn't get regulator ip [%s]! \n", __func__); + return; + } else { + pr_info("Get regulator ip [%s] succuse!\n", __func__); + } + ip_get_flag = 1; + } + /*-----------------control ip enable-----------------------*/ + ret = regulator_enable(g_regulator_ip_test->asp_ip); + if (ret != 0) { + pr_err("Failed to enable %s: %d\n", __func__, ret); + return ; + } + pr_info("<-----------------------[%s] test end------------------------>\n", __func__); +} + +static void regulator_ip_asp_disable_test(void) +{ + int ret; + pr_info("\n<-----------------------[%s] test begin------------------------>\n", __func__); + /*-----------------control ip disable-----------------------*/ + ret = regulator_disable(g_regulator_ip_test->asp_ip); + if (ret != 0) { + pr_err("Failed to disable %s: %d\n", __func__, ret); + return ; + } + pr_info("<-----------------------[%s] test end------------------------>\n", __func__); +} +static void regulator_ip_hifi_enable_test(void) +{ + int ret; + static int ip_get_flag; + pr_info("\n<-----------------------[%s] test begin------------------------>\n", __func__); + if (0 == ip_get_flag) { + + g_regulator_ip_test->hifi_ip = devm_regulator_get(g_regulator_ip_test->dev, "hifitest"); + if (IS_ERR(g_regulator_ip_test->hifi_ip)) { + pr_err("Couldn't get regulator ip [%s]! \n", __func__); + return; + } else { + pr_info("Get regulator ip [%s] succuse!\n", __func__); + } + ip_get_flag = 1; + } + /*-----------------control ip enable-----------------------*/ + ret = regulator_enable(g_regulator_ip_test->hifi_ip); + if (ret != 0) { + pr_err("Failed to enable %s: %d\n", __func__, ret); + return ; + } + pr_info("<-----------------------[%s] test end------------------------>\n", __func__); +} + +static void regulator_ip_hifi_disable_test(void) +{ + int ret; + + pr_info("\n<-----------------------[%s] test begin------------------------>\n", __func__); + /*-----------------control ip disable-----------------------*/ + ret = regulator_disable(g_regulator_ip_test->hifi_ip); + if (ret != 0) { + pr_err("Failed to disable %s: %d\n", __func__, ret); + return ; + } + pr_info("<-----------------------[%s] test end------------------------>\n", __func__); +} + +static void regulator_ip_mmbuf_enable_test(void) +{ + int ret; + static int ip_get_flag; + pr_info("\n<-----------------------[%s] test begin------------------------>\n", __func__); + if (0 == ip_get_flag) { + + g_regulator_ip_test->mmbuf_ip = devm_regulator_get(g_regulator_ip_test->dev, "mmbuftest"); + if (IS_ERR(g_regulator_ip_test->mmbuf_ip)) { + pr_err("Couldn't get regulator ip [%s]! \n", __func__); + return; + } else { + pr_info("Get regulator ip [%s] succuse!\n", __func__); + } + ip_get_flag = 1; + } + /*-----------------control ip enable-----------------------*/ + ret = regulator_enable(g_regulator_ip_test->mmbuf_ip); + if (ret != 0) { + pr_err("Failed to enable %s: %d\n", __func__, ret); + return ; + } + pr_info("<-----------------------[%s] test end------------------------>\n", __func__); +} + +static void regulator_ip_mmbuf_disable_test(void) +{ + int ret; + + pr_info("\n<-----------------------[%s] test begin------------------------>\n", __func__); + /*-----------------control ip disable-----------------------*/ + ret = regulator_disable(g_regulator_ip_test->mmbuf_ip); + if (ret != 0) { + pr_err("Failed to disable %s: %d\n", __func__, ret); + return ; + } + pr_info("<-----------------------[%s] test end------------------------>\n", __func__); +} + +static void regulator_ip_ldo8_enable_test(void) +{ + int ret; + static int ip_get_flag; + pr_info("\n<-----------------------[%s] test begin------------------------>\n", __func__); + if (0 == ip_get_flag) { + + g_regulator_ip_test->ldo8_ip = devm_regulator_get(g_regulator_ip_test->dev, "ldo8test"); + if (IS_ERR(g_regulator_ip_test->ldo8_ip)) { + pr_err("Couldn't get regulator ip [%s]! \n", __func__); + return; + } else { + pr_info("Get regulator ip [%s] succuse!\n", __func__); + } + ip_get_flag = 1; + } + /*-----------------control ip enable-----------------------*/ + ret = regulator_enable(g_regulator_ip_test->ldo8_ip); + if (ret != 0) { + pr_err("Failed to enable %s: %d\n", __func__, ret); + return ; + } + pr_info("<-----------------------[%s] test end------------------------>\n", __func__); +} + +static void regulator_ip_ldo8_disable_test(void) +{ + int ret; + pr_info("\n<-----------------------[%s] test begin------------------------>\n", __func__); + /*-----------------control ip disable-----------------------*/ + ret = regulator_disable(g_regulator_ip_test->ldo8_ip); + if (ret != 0) { + pr_err("Failed to disable %s: %d\n", __func__, ret); + return ; + } + pr_info("<-----------------------[%s] test end------------------------>\n", __func__); +} + +static void regulator_ip_ldo26_enable_test(void) +{ + int ret; + static int ip_get_flag; + pr_info("\n<-----------------------[%s] test begin------------------------>\n", __func__); + if (0 == ip_get_flag) { + + g_regulator_ip_test->ldo26_ip = devm_regulator_get(g_regulator_ip_test->dev, "ldo26test"); + if (IS_ERR(g_regulator_ip_test->ldo26_ip)) { + pr_err("Couldn't get regulator ip [%s]! \n", __func__); + return; + } else { + pr_info("Get regulator ip [%s] succuse!\n", __func__); + } + ip_get_flag = 1; + } + /*-----------------control ip enable-----------------------*/ + ret = regulator_enable(g_regulator_ip_test->ldo26_ip); + if (ret != 0) { + pr_err("Failed to enable %s: %d\n", __func__, ret); + return ; + } + pr_info("<-----------------------[%s] test end------------------------>\n", __func__); +} + +static void regulator_ip_ldo26_disable_test(void) +{ + int ret; + pr_info("\n<-----------------------[%s] test begin------------------------>\n", __func__); + /*-----------------control ip disable-----------------------*/ + ret = regulator_disable(g_regulator_ip_test->ldo26_ip); + if (ret != 0) { + pr_err("Failed to disable %s: %d\n", __func__, ret); + return ; + } + pr_info("<-----------------------[%s] test end------------------------>\n", __func__); +} + +static void regulator_ip_ispsrt_enable_test(void) +{ + int ret; + static int ip_get_flag; + pr_info("\n<-----------------------[%s] test begin------------------------>\n", __func__); + if (0 == ip_get_flag) { + + g_regulator_ip_test->ispsrt_ip = devm_regulator_get(g_regulator_ip_test->dev, "ispsrttest"); + if (IS_ERR(g_regulator_ip_test->ispsrt_ip)) { + pr_err("Couldn't get regulator ip [%s]! \n", __func__); + return; + } else { + pr_info("Get regulator ip [%s] succuse!\n", __func__); + } + ip_get_flag = 1; + } + /*-----------------control ip enable-----------------------*/ + ret = regulator_enable(g_regulator_ip_test->ispsrt_ip); + if (ret != 0) { + pr_err("Failed to enable %s: %d\n", __func__, ret); + return ; + } + pr_info("<-----------------------[%s] test end------------------------>\n", __func__); +} + +static void regulator_ip_ispsrt_disable_test(void) +{ + int ret; + pr_info("\n<-----------------------[%s] test begin------------------------>\n", __func__); + /*-----------------control ip disable-----------------------*/ + ret = regulator_disable(g_regulator_ip_test->ispsrt_ip); + if (ret != 0) { + pr_err("Failed to disable %s: %d\n", __func__, ret); + return ; + } + pr_info("<-----------------------[%s] test end------------------------>\n", __func__); +} + +void regulator_ip_power_on(int regulator_id) +{ + if (regulator_id < 0) { + printk("Input regulator id[%d] is error!\n", regulator_id); + return ; + } + switch (regulator_id) { + case REGULATOR_VIVOBUS_ENA: + regulator_ip_vivobus_enable_test(); + break; + case REGULATOR_VIVOBUS_DIS: + regulator_ip_vivobus_disable_test(); + break; + case REGULATOR_DSSSUBSYS_ENA: + regulator_ip_dsssubsys_enable_test(); + break; + case REGULATOR_DSSSUBSYS_DIS: + regulator_ip_dsssubsys_disable_test(); + break; + case REGULATOR_VCODECSUBSYS_ENA: + regulator_ip_vcodecsubsys_enable_test(); + break; + case REGULATOR_VCODECSUBSYS_DIS: + regulator_ip_vcodecsubsys_disable_test(); + break; + case REGULATOR_VDEC_ENA: + regulator_ip_vdec_enable_test(); + break; + case REGULATOR_VDEC_DIS: + regulator_ip_vdec_disable_test(); + break; + case REGULATOR_VENC_ENA: + regulator_ip_venc_enable_test(); + break; + case REGULATOR_VENC_DIS: + regulator_ip_venc_disable_test(); + break; + case REGULATOR_ISPSUBSYS_ENA: + regulator_ip_ispsubsys_enable_test(); + break; + case REGULATOR_ISPSUBSYS_DIS: + regulator_ip_ispsubsys_disable_test(); + break; + case REGULATOR_IVP_ENA: + regulator_ip_ivp_enable_test(); + break; + case REGULATOR_IVP_DIS: + regulator_ip_ivp_disable_test(); + break; + case REGULATOR_DEBUG_ENA: + regulator_ip_debugsubsys_enable_test(); + break; + case REGULATOR_DEBUG_DIS: + regulator_ip_debugsubsys_disable_test(); + break; + case REGULATOR_SEC_P_ENA: + regulator_ip_sec_p_enable_test(); + break; + case REGULATOR_SEC_P_DIS: + regulator_ip_sec_p_disable_test(); + break; + case REGULATOR_PERF_ENA: + regulator_ip_perf_enable_test(); + break; + case REGULATOR_PERF_DIS: + regulator_ip_perf_disable_test(); + break; + case REGULATOR_CSSYS_ENA: + regulator_ip_top_cssys_enable_test(); + break; + case REGULATOR_CSSYS_DIS: + regulator_ip_top_cssys_disable_test(); + break; + case REGULATOR_USBOTG_ENA: + regulator_ip_usbotg_enable_test(); + break; + case REGULATOR_USBOTG_DIS: + regulator_ip_usbotg_disable_test(); + break; + case REGULATOR_SEC_S_ENA: + regulator_ip_sec_s_enable_test(); + break; + case REGULATOR_SEC_S_DIS: + regulator_ip_sec_s_disable_test(); + break; + case REGULATOR_SOCP_ENA: + regulator_ip_socp_enable_test(); + break; + case REGULATOR_SOCP_DIS: + regulator_ip_socp_disable_test(); + break; + case REGULATOR_G3D_ENA: + regulator_ip_g3d_enable_test(); + break; + case REGULATOR_G3D_DIS: + regulator_ip_g3d_disable_test(); + break; + case REGULATOR_ASP_ENA: + regulator_ip_asp_enable_test(); + break; + case REGULATOR_ASP_DIS: + regulator_ip_asp_disable_test(); + break; + case REGULATOR_HIFI_ENA: + regulator_ip_hifi_enable_test(); + break; + case REGULATOR_HIFI_DIS: + regulator_ip_hifi_disable_test(); + break; + case REGULATOR_MMBUF_ENA: + regulator_ip_mmbuf_enable_test(); + break; + case REGULATOR_MMBUF_DIS: + regulator_ip_mmbuf_disable_test(); + break; + case REGULATOR_LDO8_ENA: + regulator_ip_ldo8_enable_test(); + break; + case REGULATOR_LDO8_DIS: + regulator_ip_ldo8_disable_test(); + break; + case REGULATOR_LDO26_ENA: + regulator_ip_ldo26_enable_test(); + break; + case REGULATOR_LDO26_DIS: + regulator_ip_ldo26_disable_test(); + break; + default: + return; + } + return; +} + +/********************sys interface begin************************************/ +static ssize_t show_test_ip_enable(struct device *dev, struct device_attribute *da, char *buf) +{ + return snprintf(buf, (u64)2, "%d\n", 0); +} +static ssize_t set_test_ip_enable(struct device *dev, struct device_attribute *da, + const char *buf, size_t count) +{ + long new_value; + int result = kstrtol(buf, 10, &new_value); + printk("----------->set_test_enable<-------------\n"); + if (result < 0) + return -EINVAL; + + switch (new_value) { + case REGULATOR_VIVOBUS_ENA: + regulator_ip_vivobus_enable_test(); + break; + case REGULATOR_VIVOBUS_DIS: + regulator_ip_vivobus_disable_test(); + break; + case REGULATOR_DSSSUBSYS_ENA: + regulator_ip_dsssubsys_enable_test(); + break; + case REGULATOR_DSSSUBSYS_DIS: + regulator_ip_dsssubsys_disable_test(); + break; + case REGULATOR_VCODECSUBSYS_ENA: + regulator_ip_vcodecsubsys_enable_test(); + break; + case REGULATOR_VCODECSUBSYS_DIS: + regulator_ip_vcodecsubsys_disable_test(); + break; + case REGULATOR_VDEC_ENA: + regulator_ip_vdec_enable_test(); + break; + case REGULATOR_VDEC_DIS: + regulator_ip_vdec_disable_test(); + break; + case REGULATOR_VENC_ENA: + regulator_ip_venc_enable_test(); + break; + case REGULATOR_VENC_DIS: + regulator_ip_venc_disable_test(); + break; + case REGULATOR_ISPSUBSYS_ENA: + regulator_ip_ispsubsys_enable_test(); + break; + case REGULATOR_ISPSUBSYS_DIS: + regulator_ip_ispsubsys_disable_test(); + break; + case REGULATOR_IVP_ENA: + regulator_ip_ivp_enable_test(); + break; + case REGULATOR_IVP_DIS: + regulator_ip_ivp_disable_test(); + break; + case REGULATOR_DEBUG_ENA: + regulator_ip_debugsubsys_enable_test(); + break; + case REGULATOR_DEBUG_DIS: + regulator_ip_debugsubsys_disable_test(); + break; + case REGULATOR_SEC_P_ENA: + regulator_ip_sec_p_enable_test(); + break; + case REGULATOR_SEC_P_DIS: + regulator_ip_sec_p_disable_test(); + break; + case REGULATOR_PERF_ENA: + regulator_ip_perf_enable_test(); + break; + case REGULATOR_PERF_DIS: + regulator_ip_perf_disable_test(); + break; + case REGULATOR_CSSYS_ENA: + regulator_ip_top_cssys_enable_test(); + break; + case REGULATOR_CSSYS_DIS: + regulator_ip_top_cssys_disable_test(); + break; + case REGULATOR_USBOTG_ENA: + regulator_ip_usbotg_enable_test(); + break; + case REGULATOR_USBOTG_DIS: + regulator_ip_usbotg_disable_test(); + break; + case REGULATOR_SEC_S_ENA: + regulator_ip_sec_s_enable_test(); + break; + case REGULATOR_SEC_S_DIS: + regulator_ip_sec_s_disable_test(); + break; + case REGULATOR_SOCP_ENA: + regulator_ip_socp_enable_test(); + break; + case REGULATOR_SOCP_DIS: + regulator_ip_socp_disable_test(); + break; + case REGULATOR_G3D_ENA: + regulator_ip_g3d_enable_test(); + break; + case REGULATOR_G3D_DIS: + regulator_ip_g3d_disable_test(); + break; + case REGULATOR_ASP_ENA: + regulator_ip_asp_enable_test(); + break; + case REGULATOR_ASP_DIS: + regulator_ip_asp_disable_test(); + break; + case REGULATOR_HIFI_ENA: + regulator_ip_hifi_enable_test(); + break; + case REGULATOR_HIFI_DIS: + regulator_ip_hifi_disable_test(); + break; + case REGULATOR_MMBUF_ENA: + regulator_ip_mmbuf_enable_test(); + break; + case REGULATOR_MMBUF_DIS: + regulator_ip_mmbuf_disable_test(); + break; + case REGULATOR_LDO8_ENA: + regulator_ip_ldo8_enable_test(); + break; + case REGULATOR_LDO8_DIS: + regulator_ip_ldo8_disable_test(); + break; + case REGULATOR_ISPSRT_ENA: + regulator_ip_ispsrt_enable_test(); + break; + case REGULATOR_ISPSRT_DIS: + regulator_ip_ispsrt_disable_test(); + break; + default: + return -EINVAL; + } + + return count; +} +//lint -save -e665 +static DEVICE_ATTR(testip_enable, S_IRUGO | S_IWUSR, show_test_ip_enable, + set_test_ip_enable); +//lint -restore +/* sensors present on all models */ +static struct attribute *regulatoriptest_attributes[] = { + &dev_attr_testip_enable.attr, + NULL +}; + +static const struct attribute_group regulatoriptest_group = { + .attrs = regulatoriptest_attributes, +}; + + +static int regulator_ip_test_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct regulator_ip_test *iptest = NULL; + size_t reg_size = (64*1024); + size_t reg_size1 = (2*1024*1024); + int ret = 0; + + iptest = kzalloc(sizeof(*iptest), GFP_KERNEL); + if (!iptest) { + dev_err(dev, "cannot allocate regulator_ip_test device info\n"); + ret = -ENOMEM; + return ret; + } + /* get resources */ + iptest->res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!iptest->res) { + ret = -ENOMEM; + dev_err(dev, "platform_get_resource err, ret=%d\n", ret); + goto error_res; + } + + iptest->regs = ioremap(iptest->res->start, resource_size(iptest->res)); + if (!iptest->regs) { + ret = -ENOMEM; + dev_err(dev, "cannot map register memory\n"); + goto error_map; + } + + iptest->dev = &(pdev->dev); + + { + iptest->dsssubsys_reg = devm_ioremap(&pdev->dev, DSSSUBSYS_BASE_ADDR, reg_size); + if (iptest->dsssubsys_reg == NULL) { + pr_err("%s:failed to get addr %d.\n", __func__, __LINE__); + return -ENOMEM; + } + iptest->ispsubsys_reg = devm_ioremap(&pdev->dev, ISPSUBSYS_BASE_ADDR, reg_size1); + if (iptest->ispsubsys_reg == NULL) { + pr_err("%s:failed to get addr %d.\n", __func__, __LINE__); + return -ENOMEM; + } + iptest->venc_reg = devm_ioremap(&pdev->dev, VENC_BASE_ADDR, reg_size); + if (iptest->venc_reg == NULL) { + pr_err("%s:failed to get addr %d.\n", __func__, __LINE__); + return -ENOMEM; + } + iptest->vdec_reg = devm_ioremap(&pdev->dev, VDEC_BASE_ADDR, reg_size); + if (iptest->vdec_reg == NULL) { + pr_err("%s:failed to get addr %d.\n", __func__, __LINE__); + return -ENOMEM; + } + iptest->sec_p_reg = devm_ioremap(&pdev->dev, SEC_P_BASE_ADDR, reg_size); + if (iptest->sec_p_reg == NULL) { + pr_err("%s:failed to get addr %d.\n", __func__, __LINE__); + return -ENOMEM; + } + iptest->perf_reg = devm_ioremap(&pdev->dev, PERF_BASE_ADDR, reg_size); + if (iptest->perf_reg == NULL) { + pr_err("%s:failed to get addr %d.\n", __func__, __LINE__); + return -ENOMEM; + } + iptest->top_cssys_reg = devm_ioremap(&pdev->dev, TOP_CSSYS_BASE_ADDR, reg_size); + if (iptest->top_cssys_reg == NULL) { + pr_err("%s:failed to get addr %d.\n", __func__, __LINE__); + return -ENOMEM; + } + iptest->socp_reg = devm_ioremap(&pdev->dev, SOCP_BASE_ADDR, reg_size); + if (iptest->socp_reg == NULL) { + pr_err("%s:failed to get addr %d.\n", __func__, __LINE__); + return -ENOMEM; + } + iptest->g3d_reg = devm_ioremap(&pdev->dev, G3D_BASE_ADDR, reg_size); + if (iptest->g3d_reg == NULL) { + pr_err("%s:failed to get addr %d.\n", __func__, __LINE__); + return -ENOMEM; + } + iptest->sec_s_reg = devm_ioremap(&pdev->dev, SEC_S_BASE_ADDR, reg_size); + if (iptest->sec_s_reg == NULL) { + pr_err("%s:failed to get addr %d.\n", __func__, __LINE__); + return -ENOMEM; + } + iptest->asp_reg = devm_ioremap(&pdev->dev, ASP_BASE_ADDR, reg_size); + if (iptest->asp_reg == NULL) { + pr_err("%s:failed to get addr %d.\n", __func__, __LINE__); + return -ENOMEM; + } + iptest->mmbuf_reg = devm_ioremap(&pdev->dev, MMBUF_BASE_ADDR, reg_size); + if (iptest->mmbuf_reg == NULL) { + pr_err("%s:failed to get addr %d.\n", __func__, __LINE__); + return -ENOMEM; + } + iptest->ivp_reg = devm_ioremap(&pdev->dev, IVP32_BASE_ADDR, reg_size); + if (iptest->ivp_reg == NULL) { + pr_err("%s:failed to get addr %d.\n", __func__, __LINE__); + return -ENOMEM; + } + } + + g_regulator_ip_test = iptest; + platform_set_drvdata(pdev, iptest); + + regulatoriptestobj = kobject_create_and_add(MODULE_NAME, NULL); + if (!regulatoriptestobj) { + pr_err("%s:failed create and add regulatoriptest kobject %d.\n", __func__, __LINE__); + goto error_map; + } + ret = sysfs_create_group(regulatoriptestobj, ®ulatoriptest_group); + if (ret < 0) { + printk("test_probe, sysfs create group failed.\n"); + goto error_obj_create; + } + goto probe_end; +error_obj_create: + kobject_put(regulatoriptestobj); +error_map: + release_mem_region(iptest->res->start, resource_size(iptest->res)); +error_res: + kfree(iptest); +probe_end: + return ret; + +} + + +static int regulator_ip_test_remove(struct platform_device *pdev) + +{ + + struct regulator_ip_test *iptest = platform_get_drvdata(pdev); + + iounmap(iptest->regs); + release_mem_region(iptest->res->start, resource_size(iptest->res)); + + kfree(iptest); + + platform_set_drvdata(pdev, NULL); + + + return 0; + +} + + +static struct of_device_id of_regulator_ip_test_match_tbl[] = { + + { + + .compatible = "hisilicon,regulator-ip-test", + + }, + + { /* end */ } + +}; + + +static struct platform_driver regulator_ip_test_driver = { + + .driver = { + + .name = "regulator_ip_test", + + .owner = THIS_MODULE, + + .of_match_table = of_regulator_ip_test_match_tbl, + + }, + + .probe = regulator_ip_test_probe, + + .remove = regulator_ip_test_remove, + +}; + + +static int __init regulator_ip_test_init(void) + +{ + return platform_driver_register(®ulator_ip_test_driver); + +} + +late_initcall(regulator_ip_test_init); + + +void __exit regulator_ip_test_exit(void) + +{ + + platform_driver_unregister(®ulator_ip_test_driver); + +} + +module_exit(regulator_ip_test_exit); + + +MODULE_DESCRIPTION("Hisi ip regulator test driver"); + +MODULE_LICENSE("GPL v2"); diff --git a/include/linux/mfd/hisi_ip_core.h b/include/linux/mfd/hisi_ip_core.h new file mode 100644 index 000000000000..8ac9e1aae0ef --- /dev/null +++ b/include/linux/mfd/hisi_ip_core.h @@ -0,0 +1,42 @@ +/* + * Header file for device driver hi3xxx power manger + * + * Copyright (c) 2013 Linaro Ltd. + * Copyright (C) 2011 Hisilicon. + * + * 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 the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef __HISI_IP_CORE_H +#define __HISI_IP_CORE_H + +struct hisi_regulator_ip_core { + struct resource *res; + struct device *dev; + void __iomem *regs; + spinlock_t lock; +}; + +/* Register Access Helpers */ +static inline u32 hisi_regulator_ip_core_read(struct hisi_regulator_ip_core *pmic, int reg) +{ + return readl(pmic->regs + reg); +} + +static inline void hisi_regulator_ip_core_write(struct hisi_regulator_ip_core *pmic, int reg, u32 val) +{ + writel(val, pmic->regs + reg); +} + +#endif /* __HISI_IP_CORE_H */