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:
Gaurav Kashyap 2022-09-03 14:34:40 -07:00
parent 0e41a7e344
commit 72a344da59
6 changed files with 205 additions and 0 deletions

View file

@ -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
*

View file

@ -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

View file

@ -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
*/

View file

@ -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
*

View file

@ -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

View file

@ -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)
{