/*
 * Read the specified status registers and return their values.
 *
 * status: array of id-value pairs.  Each <id> specifies a status register,
 *         i.e, one of MSM_RPM_STATUS_ID_xxxx.  Upon return, each <value> will
 *         contain the value of the status register.
 * count: number of id-value pairs in the array
 *
 * Return value:
 *   0: success
 *   -EBUSY: RPM is updating the status page; values across different registers
 *           may not be consistent
 *   -EINVAL: invalid id in <status> array
 */
int msm_rpm_get_status(struct msm_rpm_iv_pair *status, int count)
{
	uint32_t seq_begin;
	uint32_t seq_end;
	int rc;
	int i;

	seq_begin = msm_rpm_read(MSM_RPM_PAGE_STATUS,
				MSM_RPM_STATUS_ID_SEQUENCE);

	for (i = 0; i < count; i++) {
		if (status[i].id > MSM_RPM_STATUS_ID_LAST) {
			rc = -EINVAL;
			goto get_status_exit;
		}

		status[i].value = msm_rpm_read(MSM_RPM_PAGE_STATUS,
						status[i].id);
	}

	seq_end = msm_rpm_read(MSM_RPM_PAGE_STATUS,
				MSM_RPM_STATUS_ID_SEQUENCE);

	rc = (seq_begin != seq_end || (seq_begin & 0x01)) ? -EBUSY : 0;

get_status_exit:
	return rc;
}
/*
 * Note: assumes caller has acquired <msm_rpm_irq_lock>.
 *
 * Return value:
 *   0: request acknowledgement
 *   1: notification
 *   2: spurious interrupt
 */
static int msm_rpm_process_ack_interrupt(void)
{
	uint32_t ctx_mask_ack;
	uint32_t sel_masks_ack[MSM_RPM_SEL_MASK_SIZE];

	ctx_mask_ack = msm_rpm_read(MSM_RPM_PAGE_CTRL, MSM_RPM_CTRL_ACK_CTX_0);
	msm_rpm_read_contiguous(MSM_RPM_PAGE_CTRL,
		MSM_RPM_CTRL_ACK_SEL_0, sel_masks_ack, MSM_RPM_SEL_MASK_SIZE);

	if (ctx_mask_ack & msm_rpm_get_ctx_mask(MSM_RPM_CTX_NOTIFICATION)) {
		struct msm_rpm_notification *n;
		int i;

		list_for_each_entry(n, &msm_rpm_notifications, list)
			for (i = 0; i < MSM_RPM_SEL_MASK_SIZE; i++)
				if (sel_masks_ack[i] & n->sel_masks[i]) {
					up(&n->sem);
					break;
				}

		msm_rpm_write_contiguous_zeros(MSM_RPM_PAGE_CTRL,
			MSM_RPM_CTRL_ACK_SEL_0, MSM_RPM_SEL_MASK_SIZE);
		msm_rpm_write(MSM_RPM_PAGE_CTRL, MSM_RPM_CTRL_ACK_CTX_0, 0);
		/* Ensure the write is complete before return */
		mb();

		return 1;
	}

	if (msm_rpm_request) {
		int i;

		*(msm_rpm_request->ctx_mask_ack) = ctx_mask_ack;
		memcpy(msm_rpm_request->sel_masks_ack, sel_masks_ack,
			sizeof(sel_masks_ack));

		for (i = 0; i < msm_rpm_request->count; i++)
			msm_rpm_request->req[i].value =
				msm_rpm_read(MSM_RPM_PAGE_ACK,
						msm_rpm_request->req[i].id);

		msm_rpm_write_contiguous_zeros(MSM_RPM_PAGE_CTRL,
			MSM_RPM_CTRL_ACK_SEL_0, MSM_RPM_SEL_MASK_SIZE);
		msm_rpm_write(MSM_RPM_PAGE_CTRL, MSM_RPM_CTRL_ACK_CTX_0, 0);
		/* Ensure the write is complete before return */
		mb();

		if (msm_rpm_request->done)
			complete_all(msm_rpm_request->done);

		msm_rpm_request = NULL;
		return 0;
	}

	return 2;
}
Exemplo n.º 3
0
int __init msm_rpm_init(struct msm_rpm_platform_data *data)
{
	unsigned int irq;
	int rc;

	if (cpu_is_apq8064())
		return 0;

	msm_rpm_platform = data;

	fw_major = msm_rpm_read(MSM_RPM_PAGE_STATUS,
					MSM_RPM_STATUS_ID_VERSION_MAJOR);
	fw_minor = msm_rpm_read(MSM_RPM_PAGE_STATUS,
					MSM_RPM_STATUS_ID_VERSION_MINOR);
	fw_build = msm_rpm_read(MSM_RPM_PAGE_STATUS,
					MSM_RPM_STATUS_ID_VERSION_BUILD);
	pr_info("%s: RPM firmware %u.%u.%u\n", __func__,
			fw_major, fw_minor, fw_build);

	if (fw_major != RPM_MAJOR_VER) {
		pr_err("%s: RPM version %u.%u.%u incompatible with "
				"this driver version %u.%u.%u\n", __func__,
				fw_major, fw_minor, fw_build,
				RPM_MAJOR_VER, RPM_MINOR_VER, RPM_BUILD_VER);
		return -EFAULT;
	}

	msm_rpm_write(MSM_RPM_PAGE_CTRL, MSM_RPM_CTRL_VERSION_MAJOR,
			RPM_MAJOR_VER);
	msm_rpm_write(MSM_RPM_PAGE_CTRL, MSM_RPM_CTRL_VERSION_MINOR,
			RPM_MINOR_VER);
	msm_rpm_write(MSM_RPM_PAGE_CTRL, MSM_RPM_CTRL_VERSION_BUILD,
			RPM_BUILD_VER);

	irq = msm_rpm_platform->irq_ack;

	rc = request_irq(irq, msm_rpm_ack_interrupt,
			IRQF_TRIGGER_RISING | IRQF_NO_SUSPEND,
			"rpm_drv", msm_rpm_ack_interrupt);
	if (rc) {
		pr_err("%s: failed to request irq %d: %d\n",
			__func__, irq, rc);
		return rc;
	}

	rc = irq_set_irq_wake(irq, 1);
	if (rc) {
		pr_err("%s: failed to set wakeup irq %u: %d\n",
			__func__, irq, rc);
		return rc;
	}

	msm_rpm_populate_map();

	return platform_driver_register(&msm_rpm_platform_driver);
}
Exemplo n.º 4
0
static inline void msm_rpm_read_contiguous(
	unsigned int page, unsigned int reg, uint32_t *values, int count)
{
	int i;

	for (i = 0; i < count; i++)
		values[i] = msm_rpm_read(page, reg + i);
}
Exemplo n.º 5
0
int __init msm_rpm_init(struct msm_rpm_platform_data *data)
{
	uint32_t major;
	uint32_t minor;
	uint32_t build;
	unsigned int irq;
	int rc;

	msm_rpm_platform = data;

	major = msm_rpm_read(MSM_RPM_PAGE_STATUS,
					MSM_RPM_STATUS_ID_VERSION_MAJOR);
	minor = msm_rpm_read(MSM_RPM_PAGE_STATUS,
					MSM_RPM_STATUS_ID_VERSION_MINOR);
	build = msm_rpm_read(MSM_RPM_PAGE_STATUS,
					MSM_RPM_STATUS_ID_VERSION_BUILD);
	pr_info("%s: RPM firmware %u.%u.%u\n", __func__, major, minor, build);

	msm_rpm_write(MSM_RPM_PAGE_CTRL, MSM_RPM_CTRL_VERSION_MAJOR, 2);
	msm_rpm_write(MSM_RPM_PAGE_CTRL, MSM_RPM_CTRL_VERSION_MINOR, 0);
	msm_rpm_write(MSM_RPM_PAGE_CTRL, MSM_RPM_CTRL_VERSION_BUILD, 0);

	irq = msm_rpm_platform->irq_ack;

	rc = request_irq(irq, msm_rpm_ack_interrupt,
			IRQF_TRIGGER_RISING | IRQF_NO_SUSPEND,
			"rpm_drv", msm_rpm_ack_interrupt);
	if (rc) {
		pr_err("%s: failed to request irq %d: %d\n",
			__func__, irq, rc);
		return rc;
	}

	rc = set_irq_wake(irq, 1);
	if (rc) {
		pr_err("%s: failed to set wakeup irq %u: %d\n",
			__func__, irq, rc);
		return rc;
	}

	msm_rpm_populate_map();
	return 0;
}
Exemplo n.º 6
0
/*
 * Read the specified status registers and return their values.
 *
 * status: array of id-value pairs.  Each <id> specifies a status register,
 *         i.e, one of MSM_RPM_STATUS_ID_xxxx.  Upon return, each <value> will
 *         contain the value of the status register.
 * count: number of id-value pairs in the array
 *
 * Return value:
 *   0: success
 *   -EBUSY: RPM is updating the status page; values across different registers
 *           may not be consistent
 *   -EINVAL: invalid id in <status> array
 *   -ENODEV: RPM driver not initialized
 */
int msm_rpm_get_status(struct msm_rpm_iv_pair *status, int count)
{
	uint32_t seq_begin;
	uint32_t seq_end;
	int rc;
	int i;

	seq_begin = msm_rpm_read(MSM_RPM_PAGE_STATUS,
				target_status(MSM_RPM_STATUS_ID_SEQUENCE));

	for (i = 0; i < count; i++) {
		int target_status_id;

		if (status[i].id >= MSM_RPM_STATUS_ID_LAST) {
			pr_err("%s(): Status ID beyond limits\n", __func__);
			rc = -EINVAL;
			goto get_status_exit;
		}

		target_status_id = target_status(status[i].id);
		if (target_status_id >= MSM_RPM_STATUS_ID_LAST) {
			pr_err("%s(): Status id %d not defined for target\n",
					__func__,
					target_status_id);
			rc = -EINVAL;
			goto get_status_exit;
		}

		status[i].value = msm_rpm_read(MSM_RPM_PAGE_STATUS,
				target_status_id);
	}

	seq_end = msm_rpm_read(MSM_RPM_PAGE_STATUS,
				target_status(MSM_RPM_STATUS_ID_SEQUENCE));

	rc = (seq_begin != seq_end || (seq_begin & 0x01)) ? -EBUSY : 0;

get_status_exit:
	return rc;
}
Exemplo n.º 7
0
int __init msm_rpm_init(struct msm_rpm_platform_data *data)
{
	int rc;

	memcpy(&msm_rpm_data, data, sizeof(struct msm_rpm_platform_data));
	msm_rpm_sel_mask_size = msm_rpm_data.sel_last / 32 + 1;
	BUG_ON(SEL_MASK_SIZE < msm_rpm_sel_mask_size);

	fw_major = msm_rpm_read(MSM_RPM_PAGE_STATUS,
				target_status(MSM_RPM_STATUS_ID_VERSION_MAJOR));
	fw_minor = msm_rpm_read(MSM_RPM_PAGE_STATUS,
				target_status(MSM_RPM_STATUS_ID_VERSION_MINOR));
	fw_build = msm_rpm_read(MSM_RPM_PAGE_STATUS,
				target_status(MSM_RPM_STATUS_ID_VERSION_BUILD));
	pr_info("%s: RPM firmware %u.%u.%u\n", __func__,
			fw_major, fw_minor, fw_build);

	if (fw_major != msm_rpm_data.ver[0]) {
		pr_err("%s: RPM version %u.%u.%u incompatible with "
				"this driver version %u.%u.%u\n", __func__,
				fw_major, fw_minor, fw_build,
				msm_rpm_data.ver[0],
				msm_rpm_data.ver[1],
				msm_rpm_data.ver[2]);
		return -EFAULT;
	}

	msm_rpm_write(MSM_RPM_PAGE_CTRL,
		target_ctrl(MSM_RPM_CTRL_VERSION_MAJOR), msm_rpm_data.ver[0]);
	msm_rpm_write(MSM_RPM_PAGE_CTRL,
		target_ctrl(MSM_RPM_CTRL_VERSION_MINOR), msm_rpm_data.ver[1]);
	msm_rpm_write(MSM_RPM_PAGE_CTRL,
		target_ctrl(MSM_RPM_CTRL_VERSION_BUILD), msm_rpm_data.ver[2]);

	rc = request_irq(data->irq_ack, msm_rpm_ack_interrupt,
			IRQF_TRIGGER_RISING | IRQF_NO_SUSPEND,
			"rpm_drv", msm_rpm_ack_interrupt);
	if (rc) {
		pr_err("%s: failed to request irq %d: %d\n",
			__func__, data->irq_ack, rc);
		return rc;
	}

	rc = irq_set_irq_wake(data->irq_ack, 1);
	if (rc) {
		pr_err("%s: failed to set wakeup irq %u: %d\n",
			__func__, data->irq_ack, rc);
		return rc;
	}

	rc = request_irq(data->irq_err, msm_rpm_err_interrupt,
			IRQF_TRIGGER_RISING, "rpm_err", NULL);
	if (rc) {
		pr_err("%s: failed to request error interrupt: %d\n",
			__func__, rc);
		return rc;
	}

	rc = request_irq(data->irq_wakeup,
			msm_pm_rpm_wakeup_interrupt, IRQF_TRIGGER_RISING,
			"pm_drv", msm_pm_rpm_wakeup_interrupt);
	if (rc) {
		pr_err("%s: failed to request irq %u: %d\n",
			__func__, data->irq_wakeup, rc);
		return rc;
	}

	rc = irq_set_irq_wake(data->irq_wakeup, 1);
	if (rc) {
		pr_err("%s: failed to set wakeup irq %u: %d\n",
			__func__, data->irq_wakeup, rc);
		return rc;
	}

	msm_rpm_populate_map(data);

	return platform_driver_register(&msm_rpm_platform_driver);
}
Exemplo n.º 8
0
/*
 * Note: assumes caller has acquired <msm_rpm_irq_lock>.
 *
 * Return value:
 *   0: request acknowledgement
 *   1: notification
 *   2: spurious interrupt
 */
static int msm_rpm_process_ack_interrupt(void)
{
	uint32_t ctx_mask_ack;
	uint32_t sel_masks_ack[SEL_MASK_SIZE] = {0};

	ctx_mask_ack = msm_rpm_read(MSM_RPM_PAGE_CTRL,
			target_ctrl(MSM_RPM_CTRL_ACK_CTX_0));
	msm_rpm_read_contiguous(MSM_RPM_PAGE_CTRL,
		target_ctrl(MSM_RPM_CTRL_ACK_SEL_0),
		sel_masks_ack, msm_rpm_sel_mask_size);

	if (ctx_mask_ack & msm_rpm_get_ctx_mask(MSM_RPM_CTX_NOTIFICATION)) {
		struct msm_rpm_notification *n;
		int i;

		list_for_each_entry(n, &msm_rpm_notifications, list)
			for (i = 0; i < msm_rpm_sel_mask_size; i++)
				if (sel_masks_ack[i] & n->sel_masks[i]) {
					up(&n->sem);
					break;
				}

		msm_rpm_write_contiguous_zeros(MSM_RPM_PAGE_CTRL,
			target_ctrl(MSM_RPM_CTRL_ACK_SEL_0),
			msm_rpm_sel_mask_size);
		msm_rpm_write(MSM_RPM_PAGE_CTRL,
			target_ctrl(MSM_RPM_CTRL_ACK_CTX_0), 0);
		/* Ensure the write is complete before return */
		mb();

		return 1;
	}

	if (msm_rpm_request) {
		int i;

		*(msm_rpm_request->ctx_mask_ack) = ctx_mask_ack;
		memcpy(msm_rpm_request->sel_masks_ack, sel_masks_ack,
			sizeof(sel_masks_ack));

		for (i = 0; i < msm_rpm_request->count; i++)
			msm_rpm_request->req[i].value =
				msm_rpm_read(MSM_RPM_PAGE_ACK,
				target_enum(msm_rpm_request->req[i].id));

		msm_rpm_write_contiguous_zeros(MSM_RPM_PAGE_CTRL,
			target_ctrl(MSM_RPM_CTRL_ACK_SEL_0),
			msm_rpm_sel_mask_size);
		msm_rpm_write(MSM_RPM_PAGE_CTRL,
			target_ctrl(MSM_RPM_CTRL_ACK_CTX_0), 0);
		/* Ensure the write is complete before return */
		mb();

		if (msm_rpm_request->done)
			complete_all(msm_rpm_request->done);
		
#if defined(CONFIG_PANTECH_DEBUG)
#if defined(CONFIG_PANTECH_DEBUG_RPM_LOG) //p14291_121102
		pantech_debug_rpm_log(0, msm_rpm_request->req->id, msm_rpm_request->req->value); 
#endif
#endif

		msm_rpm_request = NULL;
		return 0;
	}

	return 2;
}
int __init msm_rpm_init(struct msm_rpm_platform_data *data)
{
	unsigned int irq;
	int rc;
#ifdef CONFIG_ARCH_MSM8960
	int i;
#endif
	msm_rpm_platform = data;

	msm_rpm_stat_data = (stats_blob *)msm_rpm_platform->reg_base_addrs[MSM_RPM_PAGE_STAT];

#ifdef CONFIG_ARCH_MSM8960
	if (rpm_debug_enable != 0) {
		unsigned int *rpm_memtest;
		void *imem_loc = ioremap_nocache(IMEM_DEBUG_LOC, 4);
		rpm_memtest = kmalloc(1024*4, GFP_KERNEL);
		pa_memtest_rpm = __pa(rpm_memtest);
		pr_info("RPMTest address: %x\n", pa_memtest_rpm);

		for(i = 0; i < 1024; i++) {
			rpm_memtest[i] = 0xEFBEADDE;
		}

		writel(pa_memtest_rpm, imem_loc);
		iounmap(imem_loc);

		msm_rpm_stat_data->rpm_debug_mode |= RPM_DEBUG_RAM_DEBUG;
	}
	if ((get_radio_flag() & 0x8) && msm_rpm_stat_data)
		msm_rpm_stat_data->rpm_debug_mode |= RPM_DEBUG_RAM_DUMP;

	pr_info("%s : rpm_debug_mode : 0x%x\n", __func__, msm_rpm_stat_data->rpm_debug_mode);
#endif

	fw_major = msm_rpm_read(MSM_RPM_PAGE_STATUS,
					MSM_RPM_STATUS_ID_VERSION_MAJOR);
	fw_minor = msm_rpm_read(MSM_RPM_PAGE_STATUS,
					MSM_RPM_STATUS_ID_VERSION_MINOR);
	fw_build = msm_rpm_read(MSM_RPM_PAGE_STATUS,
					MSM_RPM_STATUS_ID_VERSION_BUILD);
	pr_info("%s: RPM firmware %u.%u.%u\n", __func__,
			fw_major, fw_minor, fw_build);

	if (fw_major != RPM_MAJOR_VER) {
		pr_err("%s: RPM version %u.%u.%u incompatible with "
				"this driver version %u.%u.%u\n", __func__,
				fw_major, fw_minor, fw_build,
				RPM_MAJOR_VER, RPM_MINOR_VER, RPM_BUILD_VER);
		return -EFAULT;
	}

	msm_rpm_write(MSM_RPM_PAGE_CTRL, MSM_RPM_CTRL_VERSION_MAJOR,
			RPM_MAJOR_VER);
	msm_rpm_write(MSM_RPM_PAGE_CTRL, MSM_RPM_CTRL_VERSION_MINOR,
			RPM_MINOR_VER);
	msm_rpm_write(MSM_RPM_PAGE_CTRL, MSM_RPM_CTRL_VERSION_BUILD,
			RPM_BUILD_VER);

	irq = msm_rpm_platform->irq_ack;

	rc = request_irq(irq, msm_rpm_ack_interrupt,
			IRQF_TRIGGER_RISING | IRQF_NO_SUSPEND,
			"rpm_drv", msm_rpm_ack_interrupt);
	if (rc) {
		pr_err("%s: failed to request irq %d: %d\n",
			__func__, irq, rc);
		return rc;
	}

	rc = irq_set_irq_wake(irq, 1);
	if (rc) {
		pr_err("%s: failed to set wakeup irq %u: %d\n",
			__func__, irq, rc);
		return rc;
	}

	msm_rpm_populate_map();
	msm_rpm_print_sleep_tick();
	return platform_driver_register(&msm_rpm_platform_driver);
}
Exemplo n.º 10
0
int __init msm_rpm_init(struct msm_rpm_platform_data *data)
{
	int rc;

	memcpy(&msm_rpm_data, data, sizeof(struct msm_rpm_platform_data));
	msm_rpm_stat_data = (stats_blob *)msm_rpm_data.reg_base_addrs[MSM_RPM_PAGE_STAT];
	msm_rpm_sel_mask_size = msm_rpm_data.sel_last / 32 + 1;
	BUG_ON(SEL_MASK_SIZE < msm_rpm_sel_mask_size);

#ifndef CONFIG_ARCH_MSM8X60
	if ((get_radio_flag() & KERNEL_FLAG_APPSBARK) && msm_rpm_stat_data)
		msm_rpm_stat_data->rpm_debug_mode |= RPM_DEBUG_RAM_DUMP;

	if ((get_kernel_flag() & KERNEL_FLAG_PM_MONITOR) && msm_rpm_stat_data)
		msm_rpm_stat_data->rpm_debug_mode |= RPM_DEBUG_POWER_MEASUREMENT;

	
	if ((get_kernel_flag() & KERNEL_FLAG_RPM_DISABLE_WATCHDOG) && msm_rpm_stat_data)
		msm_rpm_stat_data->rpm_debug_mode |= RPM_DEBUG_DISABLE_WATCHDOG;
#endif
	fw_major = msm_rpm_read(MSM_RPM_PAGE_STATUS,
				target_status(MSM_RPM_STATUS_ID_VERSION_MAJOR));
	fw_minor = msm_rpm_read(MSM_RPM_PAGE_STATUS,
				target_status(MSM_RPM_STATUS_ID_VERSION_MINOR));
	fw_build = msm_rpm_read(MSM_RPM_PAGE_STATUS,
				target_status(MSM_RPM_STATUS_ID_VERSION_BUILD));
	/*pr_info("%s: RPM firmware %u.%u.%u\n", __func__,
			fw_major, fw_minor, fw_build);*/

	if (fw_major != msm_rpm_data.ver[0]) {
		/*pr_err("%s: RPM version %u.%u.%u incompatible with "
				"this driver version %u.%u.%u\n", __func__,
				fw_major, fw_minor, fw_build,
				msm_rpm_data.ver[0],
				msm_rpm_data.ver[1],
				msm_rpm_data.ver[2]);*/
		return -EFAULT;
	}

	msm_rpm_write(MSM_RPM_PAGE_CTRL,
		target_ctrl(MSM_RPM_CTRL_VERSION_MAJOR), msm_rpm_data.ver[0]);
	msm_rpm_write(MSM_RPM_PAGE_CTRL,
		target_ctrl(MSM_RPM_CTRL_VERSION_MINOR), msm_rpm_data.ver[1]);
	msm_rpm_write(MSM_RPM_PAGE_CTRL,
		target_ctrl(MSM_RPM_CTRL_VERSION_BUILD), msm_rpm_data.ver[2]);

	rc = request_irq(data->irq_ack, msm_rpm_ack_interrupt,
			IRQF_TRIGGER_RISING | IRQF_NO_SUSPEND,
			"rpm_drv", msm_rpm_ack_interrupt);
	if (rc) {
		/*pr_err("%s: failed to request irq %d: %d\n",
			__func__, data->irq_ack, rc);*/
		return rc;
	}

	rc = irq_set_irq_wake(data->irq_ack, 1);
	if (rc) {
		/*pr_err("%s: failed to set wakeup irq %u: %d\n",
			__func__, data->irq_ack, rc);*/
		return rc;
	}

	rc = request_irq(data->irq_err, msm_rpm_err_interrupt,
			IRQF_TRIGGER_RISING, "rpm_err", NULL);
	if (rc) {
		/*pr_err("%s: failed to request error interrupt: %d\n",
			__func__, rc);*/
		return rc;
	}

	rc = request_irq(data->irq_wakeup,
			msm_pm_rpm_wakeup_interrupt, IRQF_TRIGGER_RISING,
			"pm_drv", msm_pm_rpm_wakeup_interrupt);
	if (rc) {
		/*pr_err("%s: failed to request irq %u: %d\n",
			__func__, data->irq_wakeup, rc);*/
		return rc;
	}

	rc = irq_set_irq_wake(data->irq_wakeup, 1);
	if (rc) {
		/*pr_err("%s: failed to set wakeup irq %u: %d\n",
			__func__, data->irq_wakeup, rc);*/
		return rc;
	}

	msm_rpm_populate_map(data);
	msm_rpm_print_sleep_tick();

	return platform_driver_register(&msm_rpm_platform_driver);
}