/* * 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; }
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); }
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); }
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; }
/* * 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; }
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); }
/* * 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); }
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); }