Loading Documentation/devicetree/bindings/arm/msm/rpm_stats.txt +6 −0 Original line number Diff line number Diff line Loading @@ -24,10 +24,16 @@ PROPERTIES Value type: <prop-encoded-array> Definition: Provides labels for the reg property. - qcom,num-records: Usage: optional Value type: <u32> Definition: Specifies number of records to read from RPM RAM. EXAMPLE: qcom,rpm-stats@c000000 { compatible = "qcom,rpm-stats"; reg = <0xC000000 0x1000>, <0x3F0000 0x4>; reg-names = "phys_addr_base", "offset_addr"; qcom,num-records = <3>; }; arch/arm64/boot/dts/qcom/sdmmagpie-pm.dtsi +1 −0 Original line number Diff line number Diff line Loading @@ -163,6 +163,7 @@ compatible = "qcom,rpm-stats"; reg = <0xc300000 0x1000>, <0xc3f0004 0x4>; reg-names = "phys_addr_base", "offset_addr"; qcom,num-records = <3>; }; qcom,rpmh-master-stats@b221200 { Loading arch/arm64/boot/dts/qcom/sm6150-pm.dtsi +1 −0 Original line number Diff line number Diff line Loading @@ -165,6 +165,7 @@ compatible = "qcom,rpm-stats"; reg = <0xc300000 0x1000>, <0xc3f0004 0x4>; reg-names = "phys_addr_base", "offset_addr"; qcom,num-records = <3>; }; qcom,rpmh-master-stats@b221200 { Loading arch/arm64/boot/dts/qcom/sm8150-pm.dtsi +1 −0 Original line number Diff line number Diff line Loading @@ -142,6 +142,7 @@ compatible = "qcom,rpm-stats"; reg = <0xc300000 0x1000>, <0xc3f0004 0x4>; reg-names = "phys_addr_base", "offset_addr"; qcom,num-records = <3>; }; qcom,rpmh-master-stats@b221200 { Loading drivers/soc/qcom/rpm_stats.c +47 −18 Original line number Diff line number Diff line Loading @@ -11,6 +11,8 @@ * */ #define pr_fmt(fmt) "%s: " fmt, __func__ #include <linux/init.h> #include <linux/io.h> #include <linux/kernel.h> Loading @@ -36,6 +38,7 @@ struct msm_rpmstats_record { struct msm_rpmstats_platform_data { phys_addr_t phys_addr_base; u32 phys_size; u32 num_records; }; struct msm_rpmstats_private_data { Loading @@ -43,7 +46,7 @@ struct msm_rpmstats_private_data { u32 num_records; u32 read_idx; u32 len; char buf[320]; char buf[480]; struct msm_rpmstats_platform_data *platform_data; }; Loading @@ -61,6 +64,7 @@ struct msm_rpm_stats_data { }; struct msm_rpmstats_kobj_attr { struct kobject *kobj; struct kobj_attribute ka; struct msm_rpmstats_platform_data *pd; }; Loading Loading @@ -175,29 +179,32 @@ static ssize_t rpmstats_show(struct kobject *kobj, { struct msm_rpmstats_private_data prvdata; struct msm_rpmstats_platform_data *pdata = NULL; ssize_t length; pdata = GET_PDATA_OF_ATTR(attr); prvdata.reg_base = ioremap_nocache(pdata->phys_addr_base, pdata->phys_size); if (!prvdata.reg_base) { pr_err("%s: ERROR could not ioremap start=%pa, len=%u\n", __func__, &pdata->phys_addr_base, pdata->phys_size); pr_err("ERROR could not ioremap start=%pa, len=%u\n", &pdata->phys_addr_base, pdata->phys_size); return -EBUSY; } prvdata.read_idx = prvdata.len = 0; prvdata.platform_data = pdata; prvdata.num_records = RPM_STATS_NUM_REC; prvdata.num_records = pdata->num_records; if (prvdata.read_idx < prvdata.num_records) prvdata.len = msm_rpmstats_copy_stats(&prvdata); return snprintf(buf, prvdata.len, "%s", prvdata.buf); length = scnprintf(buf, prvdata.len, "%s", prvdata.buf); iounmap(prvdata.reg_base); return length; } static int msm_rpmstats_create_sysfs(struct msm_rpmstats_platform_data *pd) static int msm_rpmstats_create_sysfs(struct platform_device *pdev, struct msm_rpmstats_platform_data *pd) { struct kobject *rpmstats_kobj = NULL; struct msm_rpmstats_kobj_attr *rpms_ka = NULL; Loading @@ -205,7 +212,7 @@ static int msm_rpmstats_create_sysfs(struct msm_rpmstats_platform_data *pd) rpmstats_kobj = kobject_create_and_add("system_sleep", power_kobj); if (!rpmstats_kobj) { pr_err("%s: Cannot create rpmstats kobject\n", __func__); pr_err("Cannot create rpmstats kobject\n"); ret = -ENOMEM; goto fail; } Loading @@ -217,6 +224,8 @@ static int msm_rpmstats_create_sysfs(struct msm_rpmstats_platform_data *pd) goto fail; } rpms_ka->kobj = rpmstats_kobj; sysfs_attr_init(&rpms_ka->ka.attr); rpms_ka->pd = pd; rpms_ka->ka.attr.mode = 0444; Loading @@ -225,6 +234,7 @@ static int msm_rpmstats_create_sysfs(struct msm_rpmstats_platform_data *pd) rpms_ka->ka.store = NULL; ret = sysfs_create_file(rpmstats_kobj, &rpms_ka->ka.attr); platform_set_drvdata(pdev, rpms_ka); fail: return ret; Loading @@ -233,28 +243,27 @@ static int msm_rpmstats_create_sysfs(struct msm_rpmstats_platform_data *pd) static int msm_rpmstats_probe(struct platform_device *pdev) { struct msm_rpmstats_platform_data *pdata; struct msm_rpmstats_platform_data *pd; struct resource *res = NULL, *offset = NULL; u32 offset_addr = 0; void __iomem *phys_ptr = NULL; char *key; pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL); if (!pdata) return -ENOMEM; res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "phys_addr_base"); key = "phys_addr_base"; res = platform_get_resource_byname(pdev, IORESOURCE_MEM, key); if (!res) return -EINVAL; offset = platform_get_resource_byname(pdev, IORESOURCE_MEM, "offset_addr"); key = "offset_addr"; offset = platform_get_resource_byname(pdev, IORESOURCE_MEM, key); if (offset) { /* Remap the rpm-stats pointer */ phys_ptr = ioremap_nocache(offset->start, SZ_4); if (!phys_ptr) { pr_err("%s: Failed to ioremap address: %x\n", __func__, offset_addr); pr_err("Failed to ioremap offset address\n"); return -ENODEV; } offset_addr = readl_relaxed(phys_ptr); Loading @@ -264,14 +273,33 @@ static int msm_rpmstats_probe(struct platform_device *pdev) pdata->phys_addr_base = res->start + offset_addr; pdata->phys_size = resource_size(res); if (pdev->dev.platform_data) pd = pdev->dev.platform_data; key = "qcom,num-records"; if (of_property_read_u32(pdev->dev.of_node, key, &pdata->num_records)) pdata->num_records = RPM_STATS_NUM_REC; msm_rpmstats_create_sysfs(pdev, pdata); return 0; } static int msm_rpmstats_remove(struct platform_device *pdev) { struct msm_rpmstats_kobj_attr *rpms_ka; msm_rpmstats_create_sysfs(pdata); if (!pdev) return -EINVAL; rpms_ka = (struct msm_rpmstats_kobj_attr *) platform_get_drvdata(pdev); sysfs_remove_file(rpms_ka->kobj, &rpms_ka->ka.attr); kobject_put(rpms_ka->kobj); platform_set_drvdata(pdev, NULL); return 0; } static const struct of_device_id rpm_stats_table[] = { { .compatible = "qcom,rpm-stats" }, { }, Loading @@ -279,6 +307,7 @@ static const struct of_device_id rpm_stats_table[] = { static struct platform_driver msm_rpmstats_driver = { .probe = msm_rpmstats_probe, .remove = msm_rpmstats_remove, .driver = { .name = "msm_rpm_stat", .owner = THIS_MODULE, Loading Loading
Documentation/devicetree/bindings/arm/msm/rpm_stats.txt +6 −0 Original line number Diff line number Diff line Loading @@ -24,10 +24,16 @@ PROPERTIES Value type: <prop-encoded-array> Definition: Provides labels for the reg property. - qcom,num-records: Usage: optional Value type: <u32> Definition: Specifies number of records to read from RPM RAM. EXAMPLE: qcom,rpm-stats@c000000 { compatible = "qcom,rpm-stats"; reg = <0xC000000 0x1000>, <0x3F0000 0x4>; reg-names = "phys_addr_base", "offset_addr"; qcom,num-records = <3>; };
arch/arm64/boot/dts/qcom/sdmmagpie-pm.dtsi +1 −0 Original line number Diff line number Diff line Loading @@ -163,6 +163,7 @@ compatible = "qcom,rpm-stats"; reg = <0xc300000 0x1000>, <0xc3f0004 0x4>; reg-names = "phys_addr_base", "offset_addr"; qcom,num-records = <3>; }; qcom,rpmh-master-stats@b221200 { Loading
arch/arm64/boot/dts/qcom/sm6150-pm.dtsi +1 −0 Original line number Diff line number Diff line Loading @@ -165,6 +165,7 @@ compatible = "qcom,rpm-stats"; reg = <0xc300000 0x1000>, <0xc3f0004 0x4>; reg-names = "phys_addr_base", "offset_addr"; qcom,num-records = <3>; }; qcom,rpmh-master-stats@b221200 { Loading
arch/arm64/boot/dts/qcom/sm8150-pm.dtsi +1 −0 Original line number Diff line number Diff line Loading @@ -142,6 +142,7 @@ compatible = "qcom,rpm-stats"; reg = <0xc300000 0x1000>, <0xc3f0004 0x4>; reg-names = "phys_addr_base", "offset_addr"; qcom,num-records = <3>; }; qcom,rpmh-master-stats@b221200 { Loading
drivers/soc/qcom/rpm_stats.c +47 −18 Original line number Diff line number Diff line Loading @@ -11,6 +11,8 @@ * */ #define pr_fmt(fmt) "%s: " fmt, __func__ #include <linux/init.h> #include <linux/io.h> #include <linux/kernel.h> Loading @@ -36,6 +38,7 @@ struct msm_rpmstats_record { struct msm_rpmstats_platform_data { phys_addr_t phys_addr_base; u32 phys_size; u32 num_records; }; struct msm_rpmstats_private_data { Loading @@ -43,7 +46,7 @@ struct msm_rpmstats_private_data { u32 num_records; u32 read_idx; u32 len; char buf[320]; char buf[480]; struct msm_rpmstats_platform_data *platform_data; }; Loading @@ -61,6 +64,7 @@ struct msm_rpm_stats_data { }; struct msm_rpmstats_kobj_attr { struct kobject *kobj; struct kobj_attribute ka; struct msm_rpmstats_platform_data *pd; }; Loading Loading @@ -175,29 +179,32 @@ static ssize_t rpmstats_show(struct kobject *kobj, { struct msm_rpmstats_private_data prvdata; struct msm_rpmstats_platform_data *pdata = NULL; ssize_t length; pdata = GET_PDATA_OF_ATTR(attr); prvdata.reg_base = ioremap_nocache(pdata->phys_addr_base, pdata->phys_size); if (!prvdata.reg_base) { pr_err("%s: ERROR could not ioremap start=%pa, len=%u\n", __func__, &pdata->phys_addr_base, pdata->phys_size); pr_err("ERROR could not ioremap start=%pa, len=%u\n", &pdata->phys_addr_base, pdata->phys_size); return -EBUSY; } prvdata.read_idx = prvdata.len = 0; prvdata.platform_data = pdata; prvdata.num_records = RPM_STATS_NUM_REC; prvdata.num_records = pdata->num_records; if (prvdata.read_idx < prvdata.num_records) prvdata.len = msm_rpmstats_copy_stats(&prvdata); return snprintf(buf, prvdata.len, "%s", prvdata.buf); length = scnprintf(buf, prvdata.len, "%s", prvdata.buf); iounmap(prvdata.reg_base); return length; } static int msm_rpmstats_create_sysfs(struct msm_rpmstats_platform_data *pd) static int msm_rpmstats_create_sysfs(struct platform_device *pdev, struct msm_rpmstats_platform_data *pd) { struct kobject *rpmstats_kobj = NULL; struct msm_rpmstats_kobj_attr *rpms_ka = NULL; Loading @@ -205,7 +212,7 @@ static int msm_rpmstats_create_sysfs(struct msm_rpmstats_platform_data *pd) rpmstats_kobj = kobject_create_and_add("system_sleep", power_kobj); if (!rpmstats_kobj) { pr_err("%s: Cannot create rpmstats kobject\n", __func__); pr_err("Cannot create rpmstats kobject\n"); ret = -ENOMEM; goto fail; } Loading @@ -217,6 +224,8 @@ static int msm_rpmstats_create_sysfs(struct msm_rpmstats_platform_data *pd) goto fail; } rpms_ka->kobj = rpmstats_kobj; sysfs_attr_init(&rpms_ka->ka.attr); rpms_ka->pd = pd; rpms_ka->ka.attr.mode = 0444; Loading @@ -225,6 +234,7 @@ static int msm_rpmstats_create_sysfs(struct msm_rpmstats_platform_data *pd) rpms_ka->ka.store = NULL; ret = sysfs_create_file(rpmstats_kobj, &rpms_ka->ka.attr); platform_set_drvdata(pdev, rpms_ka); fail: return ret; Loading @@ -233,28 +243,27 @@ static int msm_rpmstats_create_sysfs(struct msm_rpmstats_platform_data *pd) static int msm_rpmstats_probe(struct platform_device *pdev) { struct msm_rpmstats_platform_data *pdata; struct msm_rpmstats_platform_data *pd; struct resource *res = NULL, *offset = NULL; u32 offset_addr = 0; void __iomem *phys_ptr = NULL; char *key; pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL); if (!pdata) return -ENOMEM; res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "phys_addr_base"); key = "phys_addr_base"; res = platform_get_resource_byname(pdev, IORESOURCE_MEM, key); if (!res) return -EINVAL; offset = platform_get_resource_byname(pdev, IORESOURCE_MEM, "offset_addr"); key = "offset_addr"; offset = platform_get_resource_byname(pdev, IORESOURCE_MEM, key); if (offset) { /* Remap the rpm-stats pointer */ phys_ptr = ioremap_nocache(offset->start, SZ_4); if (!phys_ptr) { pr_err("%s: Failed to ioremap address: %x\n", __func__, offset_addr); pr_err("Failed to ioremap offset address\n"); return -ENODEV; } offset_addr = readl_relaxed(phys_ptr); Loading @@ -264,14 +273,33 @@ static int msm_rpmstats_probe(struct platform_device *pdev) pdata->phys_addr_base = res->start + offset_addr; pdata->phys_size = resource_size(res); if (pdev->dev.platform_data) pd = pdev->dev.platform_data; key = "qcom,num-records"; if (of_property_read_u32(pdev->dev.of_node, key, &pdata->num_records)) pdata->num_records = RPM_STATS_NUM_REC; msm_rpmstats_create_sysfs(pdev, pdata); return 0; } static int msm_rpmstats_remove(struct platform_device *pdev) { struct msm_rpmstats_kobj_attr *rpms_ka; msm_rpmstats_create_sysfs(pdata); if (!pdev) return -EINVAL; rpms_ka = (struct msm_rpmstats_kobj_attr *) platform_get_drvdata(pdev); sysfs_remove_file(rpms_ka->kobj, &rpms_ka->ka.attr); kobject_put(rpms_ka->kobj); platform_set_drvdata(pdev, NULL); return 0; } static const struct of_device_id rpm_stats_table[] = { { .compatible = "qcom,rpm-stats" }, { }, Loading @@ -279,6 +307,7 @@ static const struct of_device_id rpm_stats_table[] = { static struct platform_driver msm_rpmstats_driver = { .probe = msm_rpmstats_probe, .remove = msm_rpmstats_remove, .driver = { .name = "msm_rpm_stat", .owner = THIS_MODULE, Loading