mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-09 13:49:24 -04:00
Merge "haven: irq_lend: Use Linux IRQ numbers"
This commit is contained in:
commit
d6503522e1
3 changed files with 42 additions and 12 deletions
|
|
@ -4,11 +4,15 @@
|
|||
*
|
||||
*/
|
||||
|
||||
#include <linux/irq.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/notifier.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||
#include <linux/haven/hh_irq_lend.h>
|
||||
#include <linux/haven/hh_rm_drv.h>
|
||||
#include <linux/spinlock.h>
|
||||
|
||||
#include "hh_rm_drv_private.h"
|
||||
|
||||
struct hh_irq_entry {
|
||||
hh_vmid_t vmid;
|
||||
|
|
@ -116,23 +120,29 @@ static struct notifier_block hh_irq_lent_nb = {
|
|||
* hh_irq_lend: Lend a hardware interrupt to another VM
|
||||
* @label: vIRQ high-level label
|
||||
* @name: VM name to send interrupt to
|
||||
* @hw_irq: Hardware IRQ number to lend
|
||||
* @irq: Linux IRQ number to lend
|
||||
* @on_release: callback to invoke when other VM returns the
|
||||
* interrupt
|
||||
* @data: Argument to pass to on_release
|
||||
*/
|
||||
int hh_irq_lend(enum hh_irq_label label, enum hh_vm_names name,
|
||||
int hw_irq, hh_irq_handle_fn on_release, void *data)
|
||||
int irq, hh_irq_handle_fn on_release, void *data)
|
||||
{
|
||||
int ret;
|
||||
int ret, virq;
|
||||
unsigned long flags;
|
||||
struct hh_irq_entry *entry;
|
||||
struct irq_data *irq_data;
|
||||
|
||||
if (label >= HH_IRQ_LABEL_MAX || !on_release)
|
||||
return -EINVAL;
|
||||
|
||||
entry = &hh_irq_entries[label];
|
||||
|
||||
irq_data = irq_get_irq_data(irq);
|
||||
if (!irq_data)
|
||||
return -EINVAL;
|
||||
virq = irq_data->hwirq;
|
||||
|
||||
spin_lock_irqsave(&hh_irq_lend_lock, flags);
|
||||
if (entry->state != HH_IRQ_STATE_NONE) {
|
||||
spin_unlock_irqrestore(&hh_irq_lend_lock, flags);
|
||||
|
|
@ -151,7 +161,7 @@ int hh_irq_lend(enum hh_irq_label label, enum hh_vm_names name,
|
|||
entry->state = HH_IRQ_STATE_WAIT_RELEASE;
|
||||
spin_unlock_irqrestore(&hh_irq_lend_lock, flags);
|
||||
|
||||
return hh_rm_vm_irq_lend_notify(entry->vmid, hw_irq, label,
|
||||
return hh_rm_vm_irq_lend_notify(entry->vmid, virq, label,
|
||||
&entry->virq_handle);
|
||||
}
|
||||
EXPORT_SYMBOL(hh_irq_lend);
|
||||
|
|
@ -231,17 +241,18 @@ EXPORT_SYMBOL(hh_irq_wait_for_lend);
|
|||
/**
|
||||
* hh_irq_accept: Register to receive interrupts with a lent vIRQ
|
||||
* @label: vIRQ high-level label
|
||||
* @hw_irq: HWIRQ# to associate vIRQ with. If don't care, use -1
|
||||
* @irq: Linux IRQ# to associate vIRQ with. If don't care, use -1
|
||||
*
|
||||
* If hw_irq is not -1, then returns 0 on success, <0 otherwise
|
||||
* If hw_irq is -1, then returns the HWIRQ# that vIRQ was registered
|
||||
* to or <0 for error.
|
||||
* Returns the Linux IRQ# that vIRQ was registered to on success.
|
||||
* Returns <0 on error
|
||||
* This function is not thread-safe w.r.t. IRQ lend state. Do not race with
|
||||
* with hh_irq_release or another hh_irq_accept with same label.
|
||||
*/
|
||||
int hh_irq_accept(enum hh_irq_label label, int hw_irq)
|
||||
int hh_irq_accept(enum hh_irq_label label, int irq)
|
||||
{
|
||||
struct hh_irq_entry *entry;
|
||||
const struct irq_data *irq_data;
|
||||
int virq;
|
||||
|
||||
if (label >= HH_IRQ_LABEL_MAX)
|
||||
return -EINVAL;
|
||||
|
|
@ -251,7 +262,23 @@ int hh_irq_accept(enum hh_irq_label label, int hw_irq)
|
|||
if (entry->state != HH_IRQ_STATE_LENT)
|
||||
return -EINVAL;
|
||||
|
||||
return hh_rm_vm_irq_accept(entry->virq_handle, hw_irq);
|
||||
if (irq != -1) {
|
||||
irq_data = irq_get_irq_data(irq);
|
||||
if (!irq_data)
|
||||
return -EINVAL;
|
||||
virq = irq_data->hwirq;
|
||||
} else
|
||||
virq = -1;
|
||||
|
||||
virq = hh_rm_vm_irq_accept(entry->virq_handle, virq);
|
||||
if (virq < 0)
|
||||
return virq;
|
||||
|
||||
if (irq == -1)
|
||||
irq = hh_rm_virq_to_linux_irq(virq - 32, GIC_SPI,
|
||||
IRQ_TYPE_LEVEL_HIGH);
|
||||
|
||||
return irq;
|
||||
}
|
||||
EXPORT_SYMBOL(hh_irq_accept);
|
||||
|
||||
|
|
|
|||
|
|
@ -642,7 +642,7 @@ out:
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int hh_rm_virq_to_linux_irq(u32 virq, u32 type, u32 trigger)
|
||||
int hh_rm_virq_to_linux_irq(u32 virq, u32 type, u32 trigger)
|
||||
{
|
||||
struct irq_fwspec fwspec = {};
|
||||
|
||||
|
|
@ -654,6 +654,7 @@ static int hh_rm_virq_to_linux_irq(u32 virq, u32 type, u32 trigger)
|
|||
|
||||
return irq_create_fwspec_mapping(&fwspec);
|
||||
}
|
||||
EXPORT_SYMBOL(hh_rm_virq_to_linux_irq);
|
||||
|
||||
static int hh_rm_get_irq(struct hh_vm_get_hyp_res_resp_entry *res_entry)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@
|
|||
|
||||
#include <linux/types.h>
|
||||
|
||||
#include <linux/haven/hh_msgq.h>
|
||||
#include <linux/haven/hh_rm_drv.h>
|
||||
#include <linux/haven/hh_common.h>
|
||||
|
||||
|
|
@ -280,6 +281,7 @@ struct hh_mem_notify_req_payload {
|
|||
/* End Message ID headers */
|
||||
|
||||
/* Common function declerations */
|
||||
int hh_rm_virq_to_linux_irq(u32 virq, u32 type, u32 trigger);
|
||||
int hh_update_vm_prop_table(enum hh_vm_names vm_name,
|
||||
struct hh_vm_property *vm_prop);
|
||||
void *hh_rm_call(hh_rm_msgid_t message_id,
|
||||
|
|
|
|||
Loading…
Reference in a new issue