summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShaun Ruffell <sruffell@digium.com>2010-07-26 00:30:37 +0000
committerShaun Ruffell <sruffell@digium.com>2010-07-26 00:30:37 +0000
commit89d606a5f043893b31cd7f8b8a44ae7a95fa13ab (patch)
tree7a0469fd8773f56c86b0ee6485ee0635ad5d76f3
parent703ffcb43df24020a99b61e107f06bd76f1fcecf (diff)
wcte12xp, wctdm24xxp: spin_lock_bh -> spin_lock_irqsave
Will add an option to allow calling the deferred processing callback directly in the interrupt handler. It appears there are some systems which still are unable to process their tasklets in a timely fashion, especially if they get pushed out to the ksoftirqd daemon. git-svn-id: http://svn.asterisk.org/svn/dahdi/linux/trunk@8981 a0bf4364-ded3-4de4-8d8a-66a801d63aff
-rw-r--r--drivers/dahdi/voicebus/voicebus.c45
-rw-r--r--drivers/dahdi/voicebus/voicebus.h5
-rw-r--r--drivers/dahdi/wctdm24xxp/base.c4
-rw-r--r--drivers/dahdi/wcte12xp/base.c41
4 files changed, 56 insertions, 39 deletions
diff --git a/drivers/dahdi/voicebus/voicebus.c b/drivers/dahdi/voicebus/voicebus.c
index 6f38e1d..3874fbb 100644
--- a/drivers/dahdi/voicebus/voicebus.c
+++ b/drivers/dahdi/voicebus/voicebus.c
@@ -243,6 +243,7 @@ vb_initialize_rx_descriptors(struct voicebus *vb)
int
voicebus_set_minlatency(struct voicebus *vb, unsigned int ms)
{
+ unsigned long flags;
/*
* One millisecond of latency means that we have 3 buffers pending,
* since two are always going to be waiting in the TX fifo on the
@@ -257,9 +258,9 @@ voicebus_set_minlatency(struct voicebus *vb, unsigned int ms)
dev_warn(&vb->pdev->dev, MESSAGE, ms, VOICEBUS_DEFAULT_LATENCY);
return -EINVAL;
}
- spin_lock_bh(&vb->lock);
+ spin_lock_irqsave(&vb->lock, flags);
vb->min_tx_buffer_count = ms;
- spin_unlock_bh(&vb->lock);
+ spin_unlock_irqrestore(&vb->lock, flags);
return 0;
}
EXPORT_SYMBOL(voicebus_set_minlatency);
@@ -269,9 +270,10 @@ int
voicebus_current_latency(struct voicebus *vb)
{
int latency;
- spin_lock_bh(&vb->lock);
+ unsigned long flags;
+ spin_lock_irqsave(&vb->lock, flags);
latency = vb->min_tx_buffer_count;
- spin_unlock_bh(&vb->lock);
+ spin_unlock_irqrestore(&vb->lock, flags);
return latency;
}
EXPORT_SYMBOL(voicebus_current_latency);
@@ -295,10 +297,11 @@ __vb_getctl(struct voicebus *vb, u32 addr)
static inline u32
vb_getctl(struct voicebus *vb, u32 addr)
{
+ unsigned long flags;
u32 val;
- spin_lock_bh(&vb->lock);
+ spin_lock_irqsave(&vb->lock, flags);
val = __vb_getctl(vb, addr);
- spin_unlock_bh(&vb->lock);
+ spin_unlock_irqrestore(&vb->lock, flags);
return val;
}
@@ -322,9 +325,10 @@ static int
vb_is_stopped(struct voicebus *vb)
{
int ret;
- spin_lock_bh(&vb->lock);
+ unsigned long flags;
+ spin_lock_irqsave(&vb->lock, flags);
ret = __vb_is_stopped(vb);
- spin_unlock_bh(&vb->lock);
+ spin_unlock_irqrestore(&vb->lock, flags);
return ret;
}
@@ -442,9 +446,10 @@ __vb_setctl(struct voicebus *vb, u32 addr, u32 val)
static inline void
vb_setctl(struct voicebus *vb, u32 addr, u32 val)
{
- spin_lock_bh(&vb->lock);
+ unsigned long flags;
+ spin_lock_irqsave(&vb->lock, flags);
__vb_setctl(vb, addr, val);
- spin_unlock_bh(&vb->lock);
+ spin_unlock_irqrestore(&vb->lock, flags);
}
static int
@@ -480,26 +485,28 @@ vb_setsdi(struct voicebus *vb, int addr, u16 val)
{
u32 bits;
u32 sdi = 0;
+ unsigned long flags;
/* Send preamble */
bits = 0xffffffff;
- spin_lock_bh(&vb->lock);
+ spin_lock_irqsave(&vb->lock, flags);
__vb_sdi_sendbits(vb, bits, 32, &sdi);
bits = (0x5 << 12) | (1 << 7) | (addr << 2) | 0x2;
__vb_sdi_sendbits(vb, bits, 16, &sdi);
__vb_sdi_sendbits(vb, val, 16, &sdi);
- spin_unlock_bh(&vb->lock);
+ spin_unlock_irqrestore(&vb->lock, flags);
}
static void
vb_enable_io_access(struct voicebus *vb)
{
u32 reg;
+ unsigned long flags;
BUG_ON(!vb->pdev);
- spin_lock_bh(&vb->lock);
+ spin_lock_irqsave(&vb->lock, flags);
pci_read_config_dword(vb->pdev, 0x0004, &reg);
reg |= 0x00000007;
pci_write_config_dword(vb->pdev, 0x0004, reg);
- spin_unlock_bh(&vb->lock);
+ spin_unlock_irqrestore(&vb->lock, flags);
}
/*! \brief Resets the voicebus hardware interface. */
@@ -864,16 +871,18 @@ __vb_disable_interrupts(struct voicebus *vb)
static void
vb_disable_interrupts(struct voicebus *vb)
{
- spin_lock_bh(&vb->lock);
+ unsigned long flags;
+ spin_lock_irqsave(&vb->lock, flags);
__vb_disable_interrupts(vb);
- spin_unlock_bh(&vb->lock);
+ spin_unlock_irqrestore(&vb->lock, flags);
}
static void start_packet_processing(struct voicebus *vb)
{
u32 reg;
+ unsigned long flags;
- spin_lock_bh(&vb->lock);
+ spin_lock_irqsave(&vb->lock, flags);
clear_bit(VOICEBUS_STOP, &vb->flags);
clear_bit(VOICEBUS_STOPPED, &vb->flags);
#if defined(CONFIG_VOICEBUS_TIMER)
@@ -891,7 +900,7 @@ static void start_packet_processing(struct voicebus *vb)
__vb_rx_demand_poll(vb);
__vb_tx_demand_poll(vb);
__vb_getctl(vb, 0x0030);
- spin_unlock_bh(&vb->lock);
+ spin_unlock_irqrestore(&vb->lock, flags);
}
static void vb_tasklet_boot(unsigned long data);
diff --git a/drivers/dahdi/voicebus/voicebus.h b/drivers/dahdi/voicebus/voicebus.h
index e563604..37b9271 100644
--- a/drivers/dahdi/voicebus/voicebus.h
+++ b/drivers/dahdi/voicebus/voicebus.h
@@ -216,10 +216,11 @@ static inline void voicebus_set_hx8_mode(struct voicebus *vb)
static inline void
voicebus_set_maxlatency(struct voicebus *vb, unsigned int max_latency)
{
- spin_lock_bh(&vb->lock);
+ unsigned long flags;
+ spin_lock_irqsave(&vb->lock, flags);
vb->max_latency = clamp(max_latency,
vb->min_tx_buffer_count,
VOICEBUS_DEFAULT_MAXLATENCY);
- spin_unlock_bh(&vb->lock);
+ spin_unlock_irqrestore(&vb->lock, flags);
}
#endif /* __VOICEBUS_H__ */
diff --git a/drivers/dahdi/wctdm24xxp/base.c b/drivers/dahdi/wctdm24xxp/base.c
index 3973640..92b5b50 100644
--- a/drivers/dahdi/wctdm24xxp/base.c
+++ b/drivers/dahdi/wctdm24xxp/base.c
@@ -4214,9 +4214,9 @@ static int hx8_send_command(struct wctdm *wc, const u8 *command,
if (bootloader)
vbb->data[EFRAME_SIZE + 3] = 0xAA;
- spin_lock_bh(&wc->vb.lock);
+ spin_lock_irqsave(&wc->vb.lock, flags);
voicebus_transmit(&wc->vb, vbb);
- spin_unlock_bh(&wc->vb.lock);
+ spin_unlock_irqrestore(&wc->vb.lock, flags);
/* Do not wait for the response if the caller doesn't care about the
* results. */
diff --git a/drivers/dahdi/wcte12xp/base.c b/drivers/dahdi/wcte12xp/base.c
index 0981749..9f93954 100644
--- a/drivers/dahdi/wcte12xp/base.c
+++ b/drivers/dahdi/wcte12xp/base.c
@@ -152,10 +152,10 @@ static void resend_cmds(struct t1 *wc)
list_splice_init(&wc->active_cmds, &wc->pending_cmds);
spin_unlock_irqrestore(&wc->cmd_list_lock, flags);
- spin_lock(&wc->reglock);
+ spin_lock_irqsave(&wc->reglock, flags);
if (wc->vpmadt032)
vpmadt032_resend(wc->vpmadt032);
- spin_unlock(&wc->reglock);
+ spin_unlock_irqrestore(&wc->reglock, flags);
}
static void cmd_dequeue(struct t1 *wc, unsigned char *writechunk, int eframe, int slot)
@@ -572,6 +572,7 @@ static int t1_getreg(struct t1 *wc, int addr)
{
struct command *cmd = NULL;
unsigned long ret;
+ unsigned long flags;
might_sleep();
@@ -584,12 +585,12 @@ static int t1_getreg(struct t1 *wc, int addr)
submit_cmd(wc, cmd);
ret = wait_for_completion_timeout(&cmd->complete, HZ*10);
if (unlikely(!ret)) {
- spin_lock_bh(&wc->cmd_list_lock);
+ spin_lock_irqsave(&wc->cmd_list_lock, flags);
if (!list_empty(&cmd->node)) {
/* Since we've removed this command from the list, we
* can go ahead and free it right away. */
list_del_init(&cmd->node);
- spin_unlock_bh(&wc->cmd_list_lock);
+ spin_unlock_irqrestore(&wc->cmd_list_lock, flags);
if (printk_ratelimit()) {
dev_warn(&wc->vb.pdev->dev,
"Timeout in %s\n", __func__);
@@ -600,7 +601,7 @@ static int t1_getreg(struct t1 *wc, int addr)
/* Looks like this command was removed from the list by
* someone else already. Let's wait for them to complete
* it so that we don't free up the memory. */
- spin_unlock_bh(&wc->cmd_list_lock);
+ spin_unlock_irqrestore(&wc->cmd_list_lock, flags);
ret = wait_for_completion_timeout(&cmd->complete, HZ*2);
WARN_ON(!ret);
ret = cmd->data;
@@ -630,6 +631,7 @@ static void t1_setleds(struct t1 *wc, int leds)
static inline int t1_getpins(struct t1 *wc, int inisr)
{
struct command *cmd;
+ unsigned long flags;
unsigned long ret;
cmd = get_free_cmd(wc);
@@ -641,9 +643,9 @@ static inline int t1_getpins(struct t1 *wc, int inisr)
submit_cmd(wc, cmd);
ret = wait_for_completion_timeout(&cmd->complete, HZ*2);
if (unlikely(!ret)) {
- spin_lock_bh(&wc->cmd_list_lock);
+ spin_lock_irqsave(&wc->cmd_list_lock, flags);
list_del_init(&cmd->node);
- spin_unlock_bh(&wc->cmd_list_lock);
+ spin_unlock_irqrestore(&wc->cmd_list_lock, flags);
if (printk_ratelimit()) {
dev_warn(&wc->vb.pdev->dev,
"Timeout in %s\n", __func__);
@@ -1407,6 +1409,7 @@ setchanconfig_from_state(struct vpmadt032 *vpm, int channel,
static int check_and_load_vpm(struct t1 *wc)
{
int res;
+ unsigned long flags;
struct vpmadt032_options options;
if (!vpmsupport) {
@@ -1445,9 +1448,9 @@ static int check_and_load_vpm(struct t1 *wc)
if (-ENODEV == res) {
/* There does not appear to be a VPMADT032 installed. */
clear_bit(4, &wc->ctlreg);
- spin_lock_bh(&wc->reglock);
+ spin_lock_irqsave(&wc->reglock, flags);
wc->vpmadt032 = NULL;
- spin_unlock_bh(&wc->reglock);
+ spin_unlock_irqrestore(&wc->reglock, flags);
vpmadt032_free(wc->vpmadt032);
return res;
@@ -1856,6 +1859,7 @@ static inline void t1_transmitprep(struct t1 *wc, u8 *writechunk)
int x;
int y;
int chan;
+ unsigned long flags;
/* Calculate Transmission */
if (likely(test_bit(INITIALIZED, &wc->bit_flags))) {
@@ -1873,10 +1877,10 @@ static inline void t1_transmitprep(struct t1 *wc, u8 *writechunk)
cmd_dequeue(wc, writechunk, x, y);
#ifdef VPM_SUPPORT
- spin_lock(&wc->reglock);
+ spin_lock_irqsave(&wc->reglock, flags);
if (wc->vpmadt032)
cmd_dequeue_vpmadt032(wc, writechunk, x);
- spin_unlock(&wc->reglock);
+ spin_unlock_irqrestore(&wc->reglock, flags);
#endif
if (x < DAHDI_CHUNKSIZE - 1) {
@@ -1901,6 +1905,7 @@ static inline bool is_good_frame(const u8 *sframe)
static inline void t1_receiveprep(struct t1 *wc, const u8* readchunk)
{
int x,chan;
+ unsigned long flags;
unsigned char expected;
if (!is_good_frame(readchunk))
@@ -1928,10 +1933,10 @@ static inline void t1_receiveprep(struct t1 *wc, const u8* readchunk)
}
cmd_decipher(wc, readchunk);
#ifdef VPM_SUPPORT
- spin_lock(&wc->reglock);
+ spin_lock_irqsave(&wc->reglock, flags);
if (wc->vpmadt032)
cmd_decipher_vpmadt032(wc, readchunk);
- spin_unlock(&wc->reglock);
+ spin_unlock_irqrestore(&wc->reglock, flags);
#endif
readchunk += (EFRAME_SIZE + EFRAME_GAP);
}
@@ -2049,6 +2054,7 @@ static void vpm_check_func(struct work_struct *work)
static void te12xp_timer(unsigned long data)
{
+ unsigned long flags;
struct t1 *wc = (struct t1 *)data;
if (unlikely(!test_bit(INITIALIZED, &wc->bit_flags)))
@@ -2056,7 +2062,7 @@ static void te12xp_timer(unsigned long data)
queue_work(wc->wq, &wc->timer_work);
- spin_lock(&wc->reglock);
+ spin_lock_irqsave(&wc->reglock, flags);
if (!wc->vpmadt032)
goto unlock_exit;
@@ -2066,22 +2072,23 @@ static void te12xp_timer(unsigned long data)
queue_work(wc->vpmadt032->wq, &wc->vpm_check_work);
unlock_exit:
- spin_unlock(&wc->reglock);
+ spin_unlock_irqrestore(&wc->reglock, flags);
return;
}
static void t1_handle_error(struct voicebus *vb)
{
+ unsigned long flags;
struct t1 *wc = container_of(vb, struct t1, vb);
- spin_lock_bh(&wc->reglock);
+ spin_lock_irqsave(&wc->reglock, flags);
if (!wc->vpmadt032)
goto unlock_exit;
clear_bit(4, &wc->ctlreg);
queue_work(wc->vpmadt032->wq, &wc->vpm_check_work);
unlock_exit:
- spin_unlock_bh(&wc->reglock);
+ spin_unlock_irqrestore(&wc->reglock, flags);
}
static const struct voicebus_operations voicebus_operations = {