static uint64_t a7k8k_pmu_interrupt_handler(uint32_t id, uint32_t flags, void *handle, void *cookie) { unsigned int idx = plat_my_core_pos(); uint32_t irq; bakery_lock_get(&a7k8k_irq_lock); /* Acknowledge IRQ */ irq = plat_ic_acknowledge_interrupt(); plat_ic_end_of_interrupt(irq); if (irq != MARVELL_IRQ_PIC0) { bakery_lock_release(&a7k8k_irq_lock); return 0; } /* Acknowledge PMU overflow IRQ in PIC0 */ mmio_setbits_32(A7K8K_PIC_CAUSE_REG, A7K8K_PIC_PMUOF_IRQ_MASK); /* Trigger ODMI Frame IRQ */ mmio_write_32(A7K8K_ODMIN_SET_REG, A7K8K_ODMI_PMU_IRQ(idx)); bakery_lock_release(&a7k8k_irq_lock); return 0; }
void fvp_pwrc_clr_wen(unsigned long mpidr) { bakery_lock_get(&pwrc_lock); mmio_write_32(PWRC_BASE + PWKUPR_OFF, (unsigned int) mpidr); bakery_lock_release(&pwrc_lock); }
unsigned int fvp_pwrc_read_psysr(unsigned long mpidr) { unsigned int rc; bakery_lock_get(&pwrc_lock); mmio_write_32(PWRC_BASE + PSYSR_OFF, (unsigned int) mpidr); rc = mmio_read_32(PWRC_BASE + PSYSR_OFF); bakery_lock_release(&pwrc_lock); return rc; }
/** * pm_client_suspend() - Client-specific suspend actions * * This function should contain any PU-specific actions * required prior to sending suspend request to PMU * Actions taken depend on the state system is suspending to. */ void pm_client_suspend(const struct pm_proc *proc, unsigned int state) { bakery_lock_get(&pm_client_secure_lock); if (state == PM_STATE_SUSPEND_TO_RAM) pm_client_set_wakeup_sources(); /* Set powerdown request */ mmio_write_32(APU_PWRCTL, mmio_read_32(APU_PWRCTL) | proc->pwrdn_mask); bakery_lock_release(&pm_client_secure_lock); }
/** * pm_ipi_send() - Sends IPI request to the PMU * @proc Pointer to the processor who is initiating request * @payload API id and call arguments to be written in IPI buffer * * Send an IPI request to the power controller. * * @return Returns status, either success or error+reason */ enum pm_ret_status pm_ipi_send(const struct pm_proc *proc, uint32_t payload[PAYLOAD_ARG_CNT]) { enum pm_ret_status ret; bakery_lock_get(&pm_secure_lock); ret = pm_ipi_send_common(proc, payload); bakery_lock_release(&pm_secure_lock); return ret; }
/** * pm_client_abort_suspend() - Client-specific abort-suspend actions * * This function should contain any PU-specific actions * required for aborting a prior suspend request */ void pm_client_abort_suspend(void) { /* Enable interrupts at processor level (for current cpu) */ gicv2_cpuif_enable(); bakery_lock_get(&pm_client_secure_lock); /* Clear powerdown request */ mmio_write_32(APU_PWRCTL, mmio_read_32(APU_PWRCTL) & ~primary_proc->pwrdn_mask); bakery_lock_release(&pm_client_secure_lock); }
/** * pm_client_wakeup() - Client-specific wakeup actions * * This function should contain any PU-specific actions * required for waking up another APU core */ void pm_client_wakeup(const struct pm_proc *proc) { unsigned int cpuid = pm_get_cpuid(proc->node_id); if (cpuid == UNDEFINED_CPUID) return; bakery_lock_get(&pm_client_secure_lock); /* clear powerdown bit for affected cpu */ uint32_t val = mmio_read_32(APU_PWRCTL); val &= ~(proc->pwrdn_mask); mmio_write_32(APU_PWRCTL, val); bakery_lock_release(&pm_client_secure_lock); }
/** * pm_ipi_send_sync() - Sends IPI request to the PMU * @proc Pointer to the processor who is initiating request * @payload API id and call arguments to be written in IPI buffer * @value Used to return value from IPI buffer element (optional) * @count Number of values to return in @value * * Send an IPI request to the power controller and wait for it to be handled. * * @return Returns status, either success or error+reason and, optionally, * @value */ enum pm_ret_status pm_ipi_send_sync(const struct pm_proc *proc, uint32_t payload[PAYLOAD_ARG_CNT], unsigned int *value, size_t count) { enum pm_ret_status ret; bakery_lock_get(&pm_secure_lock); ret = pm_ipi_send_common(proc, payload); if (ret != PM_RET_SUCCESS) goto unlock; ret = pm_ipi_buff_read(proc, value, count); unlock: bakery_lock_release(&pm_secure_lock); return ret; }
void fvp_pwrc_write_pcoffr(unsigned long mpidr) { bakery_lock_get(&pwrc_lock); mmio_write_32(PWRC_BASE + PCOFFR_OFF, (unsigned int) mpidr); bakery_lock_release(&pwrc_lock); }
void spm_lock_get(void) { bakery_lock_get(&spm_lock); }