Loading drivers/platform/msm/sps/sps.c +26 −0 Original line number Diff line number Diff line Loading @@ -2340,6 +2340,32 @@ int sps_pipe_reset(unsigned long dev, u32 pipe) } EXPORT_SYMBOL(sps_pipe_reset); /* * Process any pending IRQ of a BAM */ int sps_bam_process_irq(unsigned long dev) { struct sps_bam *bam; SPS_DBG("sps:%s.", __func__); if (!dev) { SPS_ERR("sps:%s:BAM handle is NULL.\n", __func__); return SPS_ERROR; } bam = sps_h2bam(dev); if (bam == NULL) { SPS_ERR("sps:%s:BAM is not found by handle.\n", __func__); return SPS_ERROR; } sps_bam_check_irq(bam); return 0; } EXPORT_SYMBOL(sps_bam_process_irq); /** * Allocate client state context * Loading drivers/platform/msm/sps/sps_bam.c +72 −17 Original line number Diff line number Diff line Loading @@ -118,22 +118,17 @@ int sps_bam_driver_init(u32 options) return 0; } /** * BAM interrupt service routine * * This function is the BAM interrupt service routine. * * @ctxt - pointer to ISR's registered argument * * @return void /* * Check BAM interrupt */ static irqreturn_t bam_isr(int irq, void *ctxt) int sps_bam_check_irq(struct sps_bam *dev) { struct sps_bam *dev = ctxt; struct sps_pipe *pipe; u32 source; unsigned long flags = 0; int ret = 0; SPS_DBG1("sps:%s:bam=%pa.\n", __func__, BAM_ID(dev)); spin_lock_irqsave(&dev->isr_lock, flags); Loading @@ -144,11 +139,11 @@ static irqreturn_t bam_isr(int irq, void *ctxt) source = bam_check_irq_source(dev->base, dev->props.ee, mask, &cb_case); SPS_DBG1("sps:bam_isr:bam=%pa;source=0x%x;mask=0x%x.\n", SPS_DBG1("sps:bam=%pa;source=0x%x;mask=0x%x.\n", BAM_ID(dev), source, mask); if ((source & (1UL << 31)) && (dev->props.callback)) { SPS_DBG1("sps:bam_isr:bam=%pa;callback for case %d.\n", SPS_DBG1("sps:bam=%pa;callback for case %d.\n", BAM_ID(dev), cb_case); dev->props.callback(cb_case, dev->props.user); } Loading @@ -159,7 +154,7 @@ static irqreturn_t bam_isr(int irq, void *ctxt) /* If MTIs are used, must poll each active pipe */ source = dev->pipe_active_mask; SPS_DBG1("sps:bam_isr for MTI:bam=%pa;source=0x%x.\n", SPS_DBG1("sps:MTI:bam=%pa;source=0x%x.\n", BAM_ID(dev), source); } Loading Loading @@ -188,6 +183,50 @@ static irqreturn_t bam_isr(int irq, void *ctxt) spin_unlock_irqrestore(&dev->isr_lock, flags); return ret; } /** * BAM interrupt service routine * * This function is the BAM interrupt service routine. * * @ctxt - pointer to ISR's registered argument * * @return void */ static irqreturn_t bam_isr(int irq, void *ctxt) { struct sps_bam *dev = ctxt; SPS_DBG1("sps:bam_isr: bam:%pa; IRQ #:%d.\n", BAM_ID(dev), irq); if (dev->props.options & SPS_BAM_RES_CONFIRM) { if (dev->props.callback) { bool ready = false; dev->props.callback(SPS_CALLBACK_BAM_RES_REQ, &ready); if (ready) { SPS_DBG1( "sps:bam_isr: handle IRQ for bam:%pa IRQ #:%d.\n", BAM_ID(dev), irq); sps_bam_check_irq(dev); dev->props.callback(SPS_CALLBACK_BAM_RES_REL, &ready); } else { SPS_DBG1( "sps:bam_isr: BAM is not ready and thus skip IRQ for bam:%pa IRQ #:%d.\n", BAM_ID(dev), irq); } } else { SPS_ERR( "sps:Client of BAM %pa requires confirmation but does not register callback\n", BAM_ID(dev)); } } else { sps_bam_check_irq(dev); } return IRQ_HANDLED; } Loading Loading @@ -220,10 +259,26 @@ int sps_bam_enable(struct sps_bam *dev) dev->state &= ~BAM_STATE_IRQ; } else { /* Register BAM ISR */ if (dev->props.irq > 0) if (dev->props.irq > 0) { if (dev->props.options & SPS_BAM_RES_CONFIRM) { result = request_irq(dev->props.irq, (irq_handler_t) bam_isr, IRQF_TRIGGER_RISING, "sps", dev); SPS_DBG( "sps:BAM %pa uses edge for IRQ# %d\n", BAM_ID(dev), dev->props.irq); } else { result = request_irq(dev->props.irq, (irq_handler_t) bam_isr, IRQF_TRIGGER_HIGH, "sps", dev); SPS_DBG( "sps:BAM %pa uses level for IRQ# %d\n", BAM_ID(dev), dev->props.irq); } } else { SPS_DBG1("sps:BAM %pa does not have an vaild IRQ# %d\n", BAM_ID(dev), dev->props.irq); } if (result) { SPS_ERR("sps:Failed to enable BAM %pa IRQ %d\n", Loading drivers/platform/msm/sps/sps_bam.h +9 −0 Original line number Diff line number Diff line Loading @@ -569,4 +569,13 @@ int sps_bam_pipe_timer_ctrl(struct sps_bam *dev, u32 pipe_index, int sps_bam_pipe_get_unused_desc_num(struct sps_bam *dev, u32 pipe_index, u32 *desc_num); /* * sps_bam_check_irq - check IRQ of a BAM device. * @dev - pointer to BAM device descriptor * * This function checks any pending interrupt of a BAM device. * * Return: 0 on success, negative value on error */ int sps_bam_check_irq(struct sps_bam *dev); #endif /* _SPSBAM_H_ */ include/linux/msm-sps.h +19 −1 Original line number Diff line number Diff line Loading @@ -109,7 +109,8 @@ #define SPS_BAM_NO_LOCAL_CLK_GATING (1UL << 5) /* Don't enable writeback cancel*/ #define SPS_BAM_CANCEL_WB (1UL << 6) /* Confirm resource status before access BAM*/ #define SPS_BAM_RES_CONFIRM (1UL << 7) /* BAM device management flags */ Loading Loading @@ -296,6 +297,8 @@ enum sps_callback_case { SPS_CALLBACK_BAM_ERROR_IRQ = 1, /* BAM ERROR IRQ */ SPS_CALLBACK_BAM_HRESP_ERR_IRQ, /* Erroneous HResponse */ SPS_CALLBACK_BAM_TIMER_IRQ, /* Inactivity timer */ SPS_CALLBACK_BAM_RES_REQ, /* Request resource */ SPS_CALLBACK_BAM_RES_REL, /* Release resource */ }; /* Loading Loading @@ -1358,6 +1361,16 @@ int sps_ctrl_bam_dma_clk(bool clk_on); * Return: 0 on success, negative value on error */ int sps_pipe_reset(unsigned long dev, u32 pipe); /* * sps_bam_process_irq - process IRQ of a BAM. * @dev: BAM device handle * * This function processes any pending IRQ of a BAM. * * Return: 0 on success, negative value on error */ int sps_bam_process_irq(unsigned long dev); #else static inline int sps_register_bam_device(const struct sps_bam_props *bam_props, unsigned long *dev_handle) Loading Loading @@ -1530,6 +1543,11 @@ static inline int sps_pipe_reset(unsigned long dev, u32 pipe) { return -EPERM; } static inline int sps_bam_process_irq(unsigned long dev) { return -EPERM; } #endif #endif /* _SPS_H_ */ Loading
drivers/platform/msm/sps/sps.c +26 −0 Original line number Diff line number Diff line Loading @@ -2340,6 +2340,32 @@ int sps_pipe_reset(unsigned long dev, u32 pipe) } EXPORT_SYMBOL(sps_pipe_reset); /* * Process any pending IRQ of a BAM */ int sps_bam_process_irq(unsigned long dev) { struct sps_bam *bam; SPS_DBG("sps:%s.", __func__); if (!dev) { SPS_ERR("sps:%s:BAM handle is NULL.\n", __func__); return SPS_ERROR; } bam = sps_h2bam(dev); if (bam == NULL) { SPS_ERR("sps:%s:BAM is not found by handle.\n", __func__); return SPS_ERROR; } sps_bam_check_irq(bam); return 0; } EXPORT_SYMBOL(sps_bam_process_irq); /** * Allocate client state context * Loading
drivers/platform/msm/sps/sps_bam.c +72 −17 Original line number Diff line number Diff line Loading @@ -118,22 +118,17 @@ int sps_bam_driver_init(u32 options) return 0; } /** * BAM interrupt service routine * * This function is the BAM interrupt service routine. * * @ctxt - pointer to ISR's registered argument * * @return void /* * Check BAM interrupt */ static irqreturn_t bam_isr(int irq, void *ctxt) int sps_bam_check_irq(struct sps_bam *dev) { struct sps_bam *dev = ctxt; struct sps_pipe *pipe; u32 source; unsigned long flags = 0; int ret = 0; SPS_DBG1("sps:%s:bam=%pa.\n", __func__, BAM_ID(dev)); spin_lock_irqsave(&dev->isr_lock, flags); Loading @@ -144,11 +139,11 @@ static irqreturn_t bam_isr(int irq, void *ctxt) source = bam_check_irq_source(dev->base, dev->props.ee, mask, &cb_case); SPS_DBG1("sps:bam_isr:bam=%pa;source=0x%x;mask=0x%x.\n", SPS_DBG1("sps:bam=%pa;source=0x%x;mask=0x%x.\n", BAM_ID(dev), source, mask); if ((source & (1UL << 31)) && (dev->props.callback)) { SPS_DBG1("sps:bam_isr:bam=%pa;callback for case %d.\n", SPS_DBG1("sps:bam=%pa;callback for case %d.\n", BAM_ID(dev), cb_case); dev->props.callback(cb_case, dev->props.user); } Loading @@ -159,7 +154,7 @@ static irqreturn_t bam_isr(int irq, void *ctxt) /* If MTIs are used, must poll each active pipe */ source = dev->pipe_active_mask; SPS_DBG1("sps:bam_isr for MTI:bam=%pa;source=0x%x.\n", SPS_DBG1("sps:MTI:bam=%pa;source=0x%x.\n", BAM_ID(dev), source); } Loading Loading @@ -188,6 +183,50 @@ static irqreturn_t bam_isr(int irq, void *ctxt) spin_unlock_irqrestore(&dev->isr_lock, flags); return ret; } /** * BAM interrupt service routine * * This function is the BAM interrupt service routine. * * @ctxt - pointer to ISR's registered argument * * @return void */ static irqreturn_t bam_isr(int irq, void *ctxt) { struct sps_bam *dev = ctxt; SPS_DBG1("sps:bam_isr: bam:%pa; IRQ #:%d.\n", BAM_ID(dev), irq); if (dev->props.options & SPS_BAM_RES_CONFIRM) { if (dev->props.callback) { bool ready = false; dev->props.callback(SPS_CALLBACK_BAM_RES_REQ, &ready); if (ready) { SPS_DBG1( "sps:bam_isr: handle IRQ for bam:%pa IRQ #:%d.\n", BAM_ID(dev), irq); sps_bam_check_irq(dev); dev->props.callback(SPS_CALLBACK_BAM_RES_REL, &ready); } else { SPS_DBG1( "sps:bam_isr: BAM is not ready and thus skip IRQ for bam:%pa IRQ #:%d.\n", BAM_ID(dev), irq); } } else { SPS_ERR( "sps:Client of BAM %pa requires confirmation but does not register callback\n", BAM_ID(dev)); } } else { sps_bam_check_irq(dev); } return IRQ_HANDLED; } Loading Loading @@ -220,10 +259,26 @@ int sps_bam_enable(struct sps_bam *dev) dev->state &= ~BAM_STATE_IRQ; } else { /* Register BAM ISR */ if (dev->props.irq > 0) if (dev->props.irq > 0) { if (dev->props.options & SPS_BAM_RES_CONFIRM) { result = request_irq(dev->props.irq, (irq_handler_t) bam_isr, IRQF_TRIGGER_RISING, "sps", dev); SPS_DBG( "sps:BAM %pa uses edge for IRQ# %d\n", BAM_ID(dev), dev->props.irq); } else { result = request_irq(dev->props.irq, (irq_handler_t) bam_isr, IRQF_TRIGGER_HIGH, "sps", dev); SPS_DBG( "sps:BAM %pa uses level for IRQ# %d\n", BAM_ID(dev), dev->props.irq); } } else { SPS_DBG1("sps:BAM %pa does not have an vaild IRQ# %d\n", BAM_ID(dev), dev->props.irq); } if (result) { SPS_ERR("sps:Failed to enable BAM %pa IRQ %d\n", Loading
drivers/platform/msm/sps/sps_bam.h +9 −0 Original line number Diff line number Diff line Loading @@ -569,4 +569,13 @@ int sps_bam_pipe_timer_ctrl(struct sps_bam *dev, u32 pipe_index, int sps_bam_pipe_get_unused_desc_num(struct sps_bam *dev, u32 pipe_index, u32 *desc_num); /* * sps_bam_check_irq - check IRQ of a BAM device. * @dev - pointer to BAM device descriptor * * This function checks any pending interrupt of a BAM device. * * Return: 0 on success, negative value on error */ int sps_bam_check_irq(struct sps_bam *dev); #endif /* _SPSBAM_H_ */
include/linux/msm-sps.h +19 −1 Original line number Diff line number Diff line Loading @@ -109,7 +109,8 @@ #define SPS_BAM_NO_LOCAL_CLK_GATING (1UL << 5) /* Don't enable writeback cancel*/ #define SPS_BAM_CANCEL_WB (1UL << 6) /* Confirm resource status before access BAM*/ #define SPS_BAM_RES_CONFIRM (1UL << 7) /* BAM device management flags */ Loading Loading @@ -296,6 +297,8 @@ enum sps_callback_case { SPS_CALLBACK_BAM_ERROR_IRQ = 1, /* BAM ERROR IRQ */ SPS_CALLBACK_BAM_HRESP_ERR_IRQ, /* Erroneous HResponse */ SPS_CALLBACK_BAM_TIMER_IRQ, /* Inactivity timer */ SPS_CALLBACK_BAM_RES_REQ, /* Request resource */ SPS_CALLBACK_BAM_RES_REL, /* Release resource */ }; /* Loading Loading @@ -1358,6 +1361,16 @@ int sps_ctrl_bam_dma_clk(bool clk_on); * Return: 0 on success, negative value on error */ int sps_pipe_reset(unsigned long dev, u32 pipe); /* * sps_bam_process_irq - process IRQ of a BAM. * @dev: BAM device handle * * This function processes any pending IRQ of a BAM. * * Return: 0 on success, negative value on error */ int sps_bam_process_irq(unsigned long dev); #else static inline int sps_register_bam_device(const struct sps_bam_props *bam_props, unsigned long *dev_handle) Loading Loading @@ -1530,6 +1543,11 @@ static inline int sps_pipe_reset(unsigned long dev, u32 pipe) { return -EPERM; } static inline int sps_bam_process_irq(unsigned long dev) { return -EPERM; } #endif #endif /* _SPS_H_ */