Loading drivers/soc/qcom/ddr-health.c +56 −25 Original line number Diff line number Diff line Loading @@ -18,88 +18,119 @@ #define RPM_MISC_REQ_TYPE 0x6373696d #define RPM_MISC_REQ_DDR_HEALTH 0x31726464 static unsigned long mem_size; static uint32_t mem_size; static int ddr_health_set(const char *val, struct kernel_param *kp); module_param_call(mem_size, ddr_health_set, param_get_ulong, module_param_call(mem_size, ddr_health_set, param_get_uint, &mem_size, 0644); struct ddr_health { uint64_t addr; uint32_t size; uint32_t reserved; }; static struct mutex lock; static struct ddr_health *ddr_health; static struct msm_rpm_kvp rpm_kvp; static int ddr_health_set(const char *val, struct kernel_param *kp) { int ret; void *virt; phys_addr_t addr = 0; uint64_t old_addr = 0; uint32_t old_size = 0; mutex_lock(&lock); ret = param_set_ulong(val, kp); ret = param_set_uint(val, kp); if (ret) { pr_err("ddr-health: error setting value %d\n", ret); mutex_unlock(&lock); return ret; } if (rpm_kvp.data) addr = (phys_addr_t)rpm_kvp.data; if (rpm_kvp.data) { ddr_health = (struct ddr_health *)rpm_kvp.data; old_addr = ddr_health->addr; old_size = ddr_health->size; } rpm_kvp.key = RPM_MISC_REQ_DDR_HEALTH; if (mem_size) { virt = kzalloc(mem_size, GFP_KERNEL); if (!virt) { pr_err("ddr-health: failed to alloc mem %lx\n", pr_err("ddr-health: failed to alloc mem request %x\n", mem_size); mutex_unlock(&lock); return -ENOMEM; } rpm_kvp.length = (uint32_t)mem_size; rpm_kvp.data = (void *)virt_to_phys(virt); ddr_health->addr = (uint64_t)virt_to_phys(virt); ddr_health->size = mem_size; rpm_kvp.length = sizeof(struct ddr_health); rpm_kvp.data = (void *)ddr_health; ret = msm_rpm_send_message(MSM_RPM_CTX_ACTIVE_SET, RPM_MISC_REQ_TYPE, 0, &rpm_kvp, 1); if (ret) { kfree(phys_to_virt((phys_addr_t)rpm_kvp.data)); rpm_kvp.data = 0; pr_err("ddr-health: send buf to RPM failed %d, %lx\n", pr_err("ddr-health: send buf to RPM failed %d, %x\n", ret, mem_size); mutex_unlock(&lock); return ret; kfree(virt); goto err; } } else { rpm_kvp.length = 0; rpm_kvp.data = 0; ddr_health->addr = 0; ddr_health->size = 0; rpm_kvp.length = sizeof(struct ddr_health); rpm_kvp.data = (void *)ddr_health; ret = msm_rpm_send_message(MSM_RPM_CTX_ACTIVE_SET, RPM_MISC_REQ_TYPE, 0, &rpm_kvp, 1); if (ret) { pr_err("ddr-health: send nobuf to RPM failed %d,%lx\n", pr_err("ddr-health: send nobuf to RPM failed %d, %x\n", ret, mem_size); mutex_unlock(&lock); return ret; goto err; } } if (addr) kfree(phys_to_virt(addr)); if (old_addr) kfree(phys_to_virt((phys_addr_t)old_addr)); mutex_unlock(&lock); return 0; err: ddr_health->addr = old_addr; ddr_health->size = old_size; mutex_unlock(&lock); return ret; } static int __init ddr_health_init(void) { mutex_init(&lock); ddr_health = kzalloc(sizeof(*ddr_health), GFP_KERNEL); if (!ddr_health) { pr_err("ddr-health: failed to alloc mem\n"); return -ENOMEM; } return 0; } module_init(ddr_health_init); static void __exit ddr_health_exit(void) { if (rpm_kvp.data) kfree(phys_to_virt((phys_addr_t)rpm_kvp.data)); if (rpm_kvp.data) { ddr_health = (struct ddr_health *)rpm_kvp.data; if (ddr_health->addr) kfree(phys_to_virt((phys_addr_t)ddr_health->addr)); } kfree(ddr_health); mutex_destroy(&lock); } module_exit(ddr_health_exit); Loading Loading
drivers/soc/qcom/ddr-health.c +56 −25 Original line number Diff line number Diff line Loading @@ -18,88 +18,119 @@ #define RPM_MISC_REQ_TYPE 0x6373696d #define RPM_MISC_REQ_DDR_HEALTH 0x31726464 static unsigned long mem_size; static uint32_t mem_size; static int ddr_health_set(const char *val, struct kernel_param *kp); module_param_call(mem_size, ddr_health_set, param_get_ulong, module_param_call(mem_size, ddr_health_set, param_get_uint, &mem_size, 0644); struct ddr_health { uint64_t addr; uint32_t size; uint32_t reserved; }; static struct mutex lock; static struct ddr_health *ddr_health; static struct msm_rpm_kvp rpm_kvp; static int ddr_health_set(const char *val, struct kernel_param *kp) { int ret; void *virt; phys_addr_t addr = 0; uint64_t old_addr = 0; uint32_t old_size = 0; mutex_lock(&lock); ret = param_set_ulong(val, kp); ret = param_set_uint(val, kp); if (ret) { pr_err("ddr-health: error setting value %d\n", ret); mutex_unlock(&lock); return ret; } if (rpm_kvp.data) addr = (phys_addr_t)rpm_kvp.data; if (rpm_kvp.data) { ddr_health = (struct ddr_health *)rpm_kvp.data; old_addr = ddr_health->addr; old_size = ddr_health->size; } rpm_kvp.key = RPM_MISC_REQ_DDR_HEALTH; if (mem_size) { virt = kzalloc(mem_size, GFP_KERNEL); if (!virt) { pr_err("ddr-health: failed to alloc mem %lx\n", pr_err("ddr-health: failed to alloc mem request %x\n", mem_size); mutex_unlock(&lock); return -ENOMEM; } rpm_kvp.length = (uint32_t)mem_size; rpm_kvp.data = (void *)virt_to_phys(virt); ddr_health->addr = (uint64_t)virt_to_phys(virt); ddr_health->size = mem_size; rpm_kvp.length = sizeof(struct ddr_health); rpm_kvp.data = (void *)ddr_health; ret = msm_rpm_send_message(MSM_RPM_CTX_ACTIVE_SET, RPM_MISC_REQ_TYPE, 0, &rpm_kvp, 1); if (ret) { kfree(phys_to_virt((phys_addr_t)rpm_kvp.data)); rpm_kvp.data = 0; pr_err("ddr-health: send buf to RPM failed %d, %lx\n", pr_err("ddr-health: send buf to RPM failed %d, %x\n", ret, mem_size); mutex_unlock(&lock); return ret; kfree(virt); goto err; } } else { rpm_kvp.length = 0; rpm_kvp.data = 0; ddr_health->addr = 0; ddr_health->size = 0; rpm_kvp.length = sizeof(struct ddr_health); rpm_kvp.data = (void *)ddr_health; ret = msm_rpm_send_message(MSM_RPM_CTX_ACTIVE_SET, RPM_MISC_REQ_TYPE, 0, &rpm_kvp, 1); if (ret) { pr_err("ddr-health: send nobuf to RPM failed %d,%lx\n", pr_err("ddr-health: send nobuf to RPM failed %d, %x\n", ret, mem_size); mutex_unlock(&lock); return ret; goto err; } } if (addr) kfree(phys_to_virt(addr)); if (old_addr) kfree(phys_to_virt((phys_addr_t)old_addr)); mutex_unlock(&lock); return 0; err: ddr_health->addr = old_addr; ddr_health->size = old_size; mutex_unlock(&lock); return ret; } static int __init ddr_health_init(void) { mutex_init(&lock); ddr_health = kzalloc(sizeof(*ddr_health), GFP_KERNEL); if (!ddr_health) { pr_err("ddr-health: failed to alloc mem\n"); return -ENOMEM; } return 0; } module_init(ddr_health_init); static void __exit ddr_health_exit(void) { if (rpm_kvp.data) kfree(phys_to_virt((phys_addr_t)rpm_kvp.data)); if (rpm_kvp.data) { ddr_health = (struct ddr_health *)rpm_kvp.data; if (ddr_health->addr) kfree(phys_to_virt((phys_addr_t)ddr_health->addr)); } kfree(ddr_health); mutex_destroy(&lock); } module_exit(ddr_health_exit); Loading