soc: qcom: sps: support to enable/disable irqs
Adding support to enable/disable BAM IRQs from client drivers/modules. this allows clients to disable IRQs when clocks are off. Tests: Bootup and qcedev tests. Change-Id: I30f5ffb2f4a9a48ff76e7e3adb7a6eb90f8dcc62 Signed-off-by: Gaurav Kashyap <quic_gaurkash@quicinc.com>
This commit is contained in:
parent
0e41a7e344
commit
72a344da59
6 changed files with 205 additions and 0 deletions
|
|
@ -948,6 +948,17 @@ int bam_init(void *base, u32 ee,
|
|||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set BAM global interrupt
|
||||
*/
|
||||
void bam_set_global_irq(void *base, u32 ee, u32 irq_mask, bool en)
|
||||
{
|
||||
if (en)
|
||||
bam_write_reg_field(base, IRQ_SRCS_MSK_EE, ee, BAM_IRQ, 1);
|
||||
else
|
||||
bam_write_reg_field(base, IRQ_SRCS_MSK_EE, ee, BAM_IRQ, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set BAM global execution environment
|
||||
*
|
||||
|
|
|
|||
|
|
@ -185,6 +185,21 @@ void bam_output_register_content(void *base, u32 ee);
|
|||
u32 bam_check_irq_source(void *base, u32 ee, u32 mask,
|
||||
enum sps_callback_case *cb_case);
|
||||
|
||||
/**
|
||||
* Set BAM global interrupts
|
||||
*
|
||||
* This function initializes a BAM device.
|
||||
*
|
||||
* @base - BAM virtual base address.
|
||||
*
|
||||
* @ee - BAM execution environment index
|
||||
*
|
||||
* @mask - error interrupts mask
|
||||
*
|
||||
* @en - Enable or Disable interrupt
|
||||
*
|
||||
*/
|
||||
void bam_set_global_irq(void *base, u32 ee, u32 mask, bool en);
|
||||
|
||||
/**
|
||||
* Initialize a BAM pipe
|
||||
|
|
|
|||
|
|
@ -2427,6 +2427,58 @@ int sps_bam_process_irq(unsigned long dev)
|
|||
}
|
||||
EXPORT_SYMBOL(sps_bam_process_irq);
|
||||
|
||||
/*
|
||||
* Enable all IRQs of a BAM
|
||||
*/
|
||||
int sps_bam_enable_irqs(unsigned long dev)
|
||||
{
|
||||
struct sps_bam *bam;
|
||||
|
||||
if (!dev) {
|
||||
SPS_ERR(sps, "sps: BAM handle is NULL\n");
|
||||
return SPS_ERROR;
|
||||
}
|
||||
|
||||
bam = sps_h2bam(dev);
|
||||
if (bam == NULL) {
|
||||
SPS_ERR(sps, "sps: BAM is not found by handle\n");
|
||||
return SPS_ERROR;
|
||||
}
|
||||
|
||||
SPS_DBG1(bam, "sps: BAM: %pa\n", BAM_ID(bam));
|
||||
|
||||
sps_bam_enable_all_irqs(bam);
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(sps_bam_enable_irqs);
|
||||
|
||||
/*
|
||||
* Disable all IRQs of a BAM
|
||||
*/
|
||||
int sps_bam_disable_irqs(unsigned long dev)
|
||||
{
|
||||
struct sps_bam *bam;
|
||||
|
||||
if (!dev) {
|
||||
SPS_ERR(sps, "sps: BAM handle is NULL\n");
|
||||
return SPS_ERROR;
|
||||
}
|
||||
|
||||
bam = sps_h2bam(dev);
|
||||
if (bam == NULL) {
|
||||
SPS_ERR(sps, "sps: BAM is not found by handle\n");
|
||||
return SPS_ERROR;
|
||||
}
|
||||
|
||||
SPS_DBG1(bam, "sps: BAM: %pa\n", BAM_ID(bam));
|
||||
|
||||
sps_bam_disable_all_irqs(bam);
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(sps_bam_disable_irqs);
|
||||
|
||||
/*
|
||||
* Get address info of a BAM
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -125,6 +125,13 @@ int sps_bam_check_irq(struct sps_bam *dev)
|
|||
|
||||
spin_lock_irqsave(&dev->isr_lock, flags);
|
||||
|
||||
if (dev->no_serve_irq) {
|
||||
SPS_ERR(dev, "sps:IRQ from BAM %pa can't be currently served\n",
|
||||
BAM_ID(dev));
|
||||
spin_unlock_irqrestore(&dev->isr_lock, flags);
|
||||
return ret;
|
||||
}
|
||||
|
||||
polling:
|
||||
/* Get BAM interrupt source(s) */
|
||||
if ((dev->state & BAM_STATE_MTI) == 0) {
|
||||
|
|
@ -581,6 +588,7 @@ int sps_bam_device_init(struct sps_bam *dev)
|
|||
dev->state = 0;
|
||||
dev->pipe_active_mask = 0;
|
||||
dev->pipe_remote_mask = 0;
|
||||
dev->no_serve_irq = false;
|
||||
INIT_LIST_HEAD(&dev->pipes_q);
|
||||
|
||||
spin_lock_init(&dev->isr_lock);
|
||||
|
|
@ -1324,6 +1332,73 @@ int sps_bam_pipe_set_params(struct sps_bam *dev, u32 pipe_index, u32 options)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable all IRQs of a BAM and its pipes.
|
||||
*
|
||||
*/
|
||||
void sps_bam_enable_all_irqs(struct sps_bam *dev)
|
||||
{
|
||||
struct sps_pipe *pipe;
|
||||
u32 irq_mask;
|
||||
unsigned long flags = 0;
|
||||
|
||||
spin_lock_irqsave(&dev->isr_lock, flags);
|
||||
/* Enable global interrupt */
|
||||
irq_mask = BAM_IRQ_ALL;
|
||||
bam_set_global_irq(&dev->base, dev->props.ee, irq_mask, true);
|
||||
|
||||
/* Enable all pipe interrupts */
|
||||
pipe = list_first_entry(&dev->pipes_q, struct sps_pipe, list);
|
||||
|
||||
list_for_each_entry(pipe, &dev->pipes_q, list) {
|
||||
/* Check this pipe's bit in the source mask */
|
||||
if (BAM_PIPE_IS_ASSIGNED(pipe)
|
||||
&& (!pipe->disconnecting)) {
|
||||
bam_pipe_set_irq(&dev->base, pipe->pipe_index, BAM_ENABLE,
|
||||
pipe->irq_mask, dev->props.ee);
|
||||
}
|
||||
}
|
||||
|
||||
// Write memory barrier
|
||||
wmb();
|
||||
dev->no_serve_irq = false;
|
||||
|
||||
spin_unlock_irqrestore(&dev->isr_lock, flags);
|
||||
}
|
||||
|
||||
/**
|
||||
* Disable all IRQs of a BAM and its pipes.
|
||||
*
|
||||
*/
|
||||
void sps_bam_disable_all_irqs(struct sps_bam *dev)
|
||||
{
|
||||
struct sps_pipe *pipe;
|
||||
unsigned long flags = 0;
|
||||
|
||||
spin_lock_irqsave(&dev->isr_lock, flags);
|
||||
|
||||
/* Disable global interrupt */
|
||||
bam_set_global_irq(&dev->base, dev->props.ee, 0, false);
|
||||
|
||||
/* Disable all pipe interrupts */
|
||||
pipe = list_first_entry(&dev->pipes_q, struct sps_pipe, list);
|
||||
|
||||
list_for_each_entry(pipe, &dev->pipes_q, list) {
|
||||
/* Check this pipe's bit in the source mask */
|
||||
if (BAM_PIPE_IS_ASSIGNED(pipe)
|
||||
&& (!pipe->disconnecting)) {
|
||||
bam_pipe_set_irq(&dev->base, pipe->pipe_index, BAM_DISABLE,
|
||||
0, dev->props.ee);
|
||||
}
|
||||
}
|
||||
|
||||
// Write memory barrier
|
||||
wmb();
|
||||
dev->no_serve_irq = true;
|
||||
|
||||
spin_unlock_irqrestore(&dev->isr_lock, flags);
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable a BAM pipe
|
||||
*
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2011-2019, 2021, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*/
|
||||
/*
|
||||
* Function and data structure declarations for SPS BAM handling.
|
||||
|
|
@ -220,6 +221,9 @@ struct sps_bam {
|
|||
|
||||
/* Desc cache pointers */
|
||||
u8 *desc_cache_pointers[BAM_MAX_PIPES];
|
||||
|
||||
/* ISR behavior */
|
||||
bool no_serve_irq;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -584,6 +588,24 @@ int sps_bam_pipe_get_unused_desc_num(struct sps_bam *dev, u32 pipe_index,
|
|||
*/
|
||||
int sps_bam_check_irq(struct sps_bam *dev);
|
||||
|
||||
/*
|
||||
* sps_bam_enable_all_irqs - Enable all IRQs of a BAM
|
||||
* @dev - pointer to BAM device descriptor
|
||||
*
|
||||
* This function enables all irqs of a BAM and its pipes.
|
||||
*
|
||||
*/
|
||||
void sps_bam_enable_all_irqs(struct sps_bam *dev);
|
||||
|
||||
/*
|
||||
* sps_bam_disable_all_irqs - Disable all IRQs of a BAM
|
||||
* @dev - pointer to BAM device descriptor
|
||||
*
|
||||
* This function disables all irqs of a BAM and its pipes.
|
||||
*
|
||||
*/
|
||||
void sps_bam_disable_all_irqs(struct sps_bam *dev);
|
||||
|
||||
/*
|
||||
* sps_bam_pipe_pending_desc - checking pending descriptor.
|
||||
* @dev: BAM device handle
|
||||
|
|
|
|||
|
|
@ -1408,6 +1408,26 @@ int sps_pipe_pending_desc(unsigned long dev, u32 pipe, bool *pending);
|
|||
*/
|
||||
int sps_bam_process_irq(unsigned long dev);
|
||||
|
||||
/*
|
||||
* sps_bam_enable_irqs - enable IRQs of a BAM.
|
||||
* @dev: BAM device handle
|
||||
*
|
||||
* This function enables all IRQs of a BAM.
|
||||
*
|
||||
* Return: 0 on success, negative value on error
|
||||
*/
|
||||
int sps_bam_enable_irqs(unsigned long dev);
|
||||
|
||||
/*
|
||||
* sps_bam_disable_irqs - disable IRQs of a BAM.
|
||||
* @dev: BAM device handle
|
||||
*
|
||||
* This function disables all IRQs of a BAM.
|
||||
*
|
||||
* Return: 0 on success, negative value on error
|
||||
*/
|
||||
int sps_bam_disable_irqs(unsigned long dev);
|
||||
|
||||
/*
|
||||
* sps_get_bam_addr - get address info of a BAM.
|
||||
* @dev: BAM device handle
|
||||
|
|
@ -1620,6 +1640,16 @@ static inline int sps_bam_process_irq(unsigned long dev)
|
|||
return -EPERM;
|
||||
}
|
||||
|
||||
static inline int sps_bam_enable_irqs(unsigned long dev)
|
||||
{
|
||||
return -EPERM;
|
||||
}
|
||||
|
||||
static inline int sps_bam_disable_irqs(unsigned long dev)
|
||||
{
|
||||
return -EPERM;
|
||||
}
|
||||
|
||||
static inline int sps_get_bam_addr(unsigned long dev, phys_addr_t *base,
|
||||
u32 *size)
|
||||
{
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue