Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ac413c70 authored by Sarangdhar Joshi's avatar Sarangdhar Joshi
Browse files

soc: qcom: ddr-health: add a structure to pass info to rpm



Driver needs to send address and size info to RPM. Add a structure to send
this information to rpm with a single kvp resource.

Change-Id: Ic8f285374926f8f8a462fc7a7371771841888649
Signed-off-by: default avatarSarangdhar Joshi <spjoshi@codeaurora.org>
parent de6c83ce
Loading
Loading
Loading
Loading
+56 −25
Original line number Diff line number Diff line
@@ -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);