diff options
Diffstat (limited to 'sound/pci/cs46xx/dsp_spos_scb_lib.c')
-rw-r--r-- | sound/pci/cs46xx/dsp_spos_scb_lib.c | 33 |
1 files changed, 15 insertions, 18 deletions
diff --git a/sound/pci/cs46xx/dsp_spos_scb_lib.c b/sound/pci/cs46xx/dsp_spos_scb_lib.c index dd7c41b037b4..00b148a10239 100644 --- a/sound/pci/cs46xx/dsp_spos_scb_lib.c +++ b/sound/pci/cs46xx/dsp_spos_scb_lib.c | |||
@@ -115,7 +115,6 @@ static void cs46xx_dsp_proc_scb_info_read (struct snd_info_entry *entry, | |||
115 | static void _dsp_unlink_scb (struct snd_cs46xx *chip, struct dsp_scb_descriptor * scb) | 115 | static void _dsp_unlink_scb (struct snd_cs46xx *chip, struct dsp_scb_descriptor * scb) |
116 | { | 116 | { |
117 | struct dsp_spos_instance * ins = chip->dsp_spos_instance; | 117 | struct dsp_spos_instance * ins = chip->dsp_spos_instance; |
118 | unsigned long flags; | ||
119 | 118 | ||
120 | if ( scb->parent_scb_ptr ) { | 119 | if ( scb->parent_scb_ptr ) { |
121 | /* unlink parent SCB */ | 120 | /* unlink parent SCB */ |
@@ -153,8 +152,6 @@ static void _dsp_unlink_scb (struct snd_cs46xx *chip, struct dsp_scb_descriptor | |||
153 | scb->next_scb_ptr = ins->the_null_scb; | 152 | scb->next_scb_ptr = ins->the_null_scb; |
154 | } | 153 | } |
155 | 154 | ||
156 | spin_lock_irqsave(&chip->reg_lock, flags); | ||
157 | |||
158 | /* update parent first entry in DSP RAM */ | 155 | /* update parent first entry in DSP RAM */ |
159 | cs46xx_dsp_spos_update_scb(chip,scb->parent_scb_ptr); | 156 | cs46xx_dsp_spos_update_scb(chip,scb->parent_scb_ptr); |
160 | 157 | ||
@@ -162,7 +159,6 @@ static void _dsp_unlink_scb (struct snd_cs46xx *chip, struct dsp_scb_descriptor | |||
162 | cs46xx_dsp_spos_update_scb(chip,scb); | 159 | cs46xx_dsp_spos_update_scb(chip,scb); |
163 | 160 | ||
164 | scb->parent_scb_ptr = NULL; | 161 | scb->parent_scb_ptr = NULL; |
165 | spin_unlock_irqrestore(&chip->reg_lock, flags); | ||
166 | } | 162 | } |
167 | } | 163 | } |
168 | 164 | ||
@@ -197,9 +193,9 @@ void cs46xx_dsp_remove_scb (struct snd_cs46xx *chip, struct dsp_scb_descriptor * | |||
197 | goto _end; | 193 | goto _end; |
198 | #endif | 194 | #endif |
199 | 195 | ||
200 | spin_lock_irqsave(&scb->lock, flags); | 196 | spin_lock_irqsave(&chip->reg_lock, flags); |
201 | _dsp_unlink_scb (chip,scb); | 197 | _dsp_unlink_scb (chip,scb); |
202 | spin_unlock_irqrestore(&scb->lock, flags); | 198 | spin_unlock_irqrestore(&chip->reg_lock, flags); |
203 | 199 | ||
204 | cs46xx_dsp_proc_free_scb_desc(scb); | 200 | cs46xx_dsp_proc_free_scb_desc(scb); |
205 | if (snd_BUG_ON(!scb->scb_symbol)) | 201 | if (snd_BUG_ON(!scb->scb_symbol)) |
@@ -207,6 +203,10 @@ void cs46xx_dsp_remove_scb (struct snd_cs46xx *chip, struct dsp_scb_descriptor * | |||
207 | remove_symbol (chip,scb->scb_symbol); | 203 | remove_symbol (chip,scb->scb_symbol); |
208 | 204 | ||
209 | ins->scbs[scb->index].deleted = 1; | 205 | ins->scbs[scb->index].deleted = 1; |
206 | #ifdef CONFIG_PM | ||
207 | kfree(ins->scbs[scb->index].data); | ||
208 | ins->scbs[scb->index].data = NULL; | ||
209 | #endif | ||
210 | 210 | ||
211 | if (scb->index < ins->scb_highest_frag_index) | 211 | if (scb->index < ins->scb_highest_frag_index) |
212 | ins->scb_highest_frag_index = scb->index; | 212 | ins->scb_highest_frag_index = scb->index; |
@@ -1508,20 +1508,17 @@ int cs46xx_dsp_pcm_unlink (struct snd_cs46xx * chip, | |||
1508 | chip->dsp_spos_instance->npcm_channels <= 0)) | 1508 | chip->dsp_spos_instance->npcm_channels <= 0)) |
1509 | return -EIO; | 1509 | return -EIO; |
1510 | 1510 | ||
1511 | spin_lock(&pcm_channel->src_scb->lock); | 1511 | spin_lock_irqsave(&chip->reg_lock, flags); |
1512 | |||
1513 | if (pcm_channel->unlinked) { | 1512 | if (pcm_channel->unlinked) { |
1514 | spin_unlock(&pcm_channel->src_scb->lock); | 1513 | spin_unlock_irqrestore(&chip->reg_lock, flags); |
1515 | return -EIO; | 1514 | return -EIO; |
1516 | } | 1515 | } |
1517 | 1516 | ||
1518 | spin_lock_irqsave(&chip->reg_lock, flags); | ||
1519 | pcm_channel->unlinked = 1; | 1517 | pcm_channel->unlinked = 1; |
1520 | spin_unlock_irqrestore(&chip->reg_lock, flags); | ||
1521 | 1518 | ||
1522 | _dsp_unlink_scb (chip,pcm_channel->pcm_reader_scb); | 1519 | _dsp_unlink_scb (chip,pcm_channel->pcm_reader_scb); |
1520 | spin_unlock_irqrestore(&chip->reg_lock, flags); | ||
1523 | 1521 | ||
1524 | spin_unlock(&pcm_channel->src_scb->lock); | ||
1525 | return 0; | 1522 | return 0; |
1526 | } | 1523 | } |
1527 | 1524 | ||
@@ -1533,10 +1530,10 @@ int cs46xx_dsp_pcm_link (struct snd_cs46xx * chip, | |||
1533 | struct dsp_scb_descriptor * src_scb = pcm_channel->src_scb; | 1530 | struct dsp_scb_descriptor * src_scb = pcm_channel->src_scb; |
1534 | unsigned long flags; | 1531 | unsigned long flags; |
1535 | 1532 | ||
1536 | spin_lock(&pcm_channel->src_scb->lock); | 1533 | spin_lock_irqsave(&chip->reg_lock, flags); |
1537 | 1534 | ||
1538 | if (pcm_channel->unlinked == 0) { | 1535 | if (pcm_channel->unlinked == 0) { |
1539 | spin_unlock(&pcm_channel->src_scb->lock); | 1536 | spin_unlock_irqrestore(&chip->reg_lock, flags); |
1540 | return -EIO; | 1537 | return -EIO; |
1541 | } | 1538 | } |
1542 | 1539 | ||
@@ -1552,8 +1549,6 @@ int cs46xx_dsp_pcm_link (struct snd_cs46xx * chip, | |||
1552 | snd_BUG_ON(pcm_channel->pcm_reader_scb->parent_scb_ptr); | 1549 | snd_BUG_ON(pcm_channel->pcm_reader_scb->parent_scb_ptr); |
1553 | pcm_channel->pcm_reader_scb->parent_scb_ptr = parent_scb; | 1550 | pcm_channel->pcm_reader_scb->parent_scb_ptr = parent_scb; |
1554 | 1551 | ||
1555 | spin_lock_irqsave(&chip->reg_lock, flags); | ||
1556 | |||
1557 | /* update SCB entry in DSP RAM */ | 1552 | /* update SCB entry in DSP RAM */ |
1558 | cs46xx_dsp_spos_update_scb(chip,pcm_channel->pcm_reader_scb); | 1553 | cs46xx_dsp_spos_update_scb(chip,pcm_channel->pcm_reader_scb); |
1559 | 1554 | ||
@@ -1562,8 +1557,6 @@ int cs46xx_dsp_pcm_link (struct snd_cs46xx * chip, | |||
1562 | 1557 | ||
1563 | pcm_channel->unlinked = 0; | 1558 | pcm_channel->unlinked = 0; |
1564 | spin_unlock_irqrestore(&chip->reg_lock, flags); | 1559 | spin_unlock_irqrestore(&chip->reg_lock, flags); |
1565 | |||
1566 | spin_unlock(&pcm_channel->src_scb->lock); | ||
1567 | return 0; | 1560 | return 0; |
1568 | } | 1561 | } |
1569 | 1562 | ||
@@ -1596,13 +1589,17 @@ cs46xx_add_record_source (struct snd_cs46xx *chip, struct dsp_scb_descriptor * s | |||
1596 | 1589 | ||
1597 | int cs46xx_src_unlink(struct snd_cs46xx *chip, struct dsp_scb_descriptor * src) | 1590 | int cs46xx_src_unlink(struct snd_cs46xx *chip, struct dsp_scb_descriptor * src) |
1598 | { | 1591 | { |
1592 | unsigned long flags; | ||
1593 | |||
1599 | if (snd_BUG_ON(!src->parent_scb_ptr)) | 1594 | if (snd_BUG_ON(!src->parent_scb_ptr)) |
1600 | return -EINVAL; | 1595 | return -EINVAL; |
1601 | 1596 | ||
1602 | /* mute SCB */ | 1597 | /* mute SCB */ |
1603 | cs46xx_dsp_scb_set_volume (chip,src,0,0); | 1598 | cs46xx_dsp_scb_set_volume (chip,src,0,0); |
1604 | 1599 | ||
1600 | spin_lock_irqsave(&chip->reg_lock, flags); | ||
1605 | _dsp_unlink_scb (chip,src); | 1601 | _dsp_unlink_scb (chip,src); |
1602 | spin_unlock_irqrestore(&chip->reg_lock, flags); | ||
1606 | 1603 | ||
1607 | return 0; | 1604 | return 0; |
1608 | } | 1605 | } |