diff options
author | Ian Minett <ian_minett@creativelabs.com> | 2013-02-08 21:31:43 -0500 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2013-02-10 05:43:46 -0500 |
commit | 6d67530e2c73e375b9204eba10ee2d589ba353ae (patch) | |
tree | 2a222bcabc0da9817873c71ad28c234b20012c60 | |
parent | 884b088f61b64c22a9a34d4ef960ab9c807d8efd (diff) |
ALSA: CA0132: Improve the DSP transfer timeout calculations
Base the DSP firmware transfer and communication timeouts on jiffy values.
Signed-off-by: Ian Minett <ian_minett@creativelabs.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
-rw-r--r-- | sound/pci/hda/patch_ca0132.c | 41 |
1 files changed, 25 insertions, 16 deletions
diff --git a/sound/pci/hda/patch_ca0132.c b/sound/pci/hda/patch_ca0132.c index 639a2829112f..710dae81fc8e 100644 --- a/sound/pci/hda/patch_ca0132.c +++ b/sound/pci/hda/patch_ca0132.c | |||
@@ -783,7 +783,7 @@ static int chipio_send(struct hda_codec *codec, | |||
783 | unsigned int data) | 783 | unsigned int data) |
784 | { | 784 | { |
785 | unsigned int res; | 785 | unsigned int res; |
786 | int retry = 50; | 786 | unsigned long timeout = jiffies + msecs_to_jiffies(1000); |
787 | 787 | ||
788 | /* send bits of data specified by reg */ | 788 | /* send bits of data specified by reg */ |
789 | do { | 789 | do { |
@@ -791,7 +791,9 @@ static int chipio_send(struct hda_codec *codec, | |||
791 | reg, data); | 791 | reg, data); |
792 | if (res == VENDOR_STATUS_CHIPIO_OK) | 792 | if (res == VENDOR_STATUS_CHIPIO_OK) |
793 | return 0; | 793 | return 0; |
794 | } while (--retry); | 794 | msleep(20); |
795 | } while (time_before(jiffies, timeout)); | ||
796 | |||
795 | return -EIO; | 797 | return -EIO; |
796 | } | 798 | } |
797 | 799 | ||
@@ -1057,14 +1059,15 @@ static int dspio_send(struct hda_codec *codec, unsigned int reg, | |||
1057 | unsigned int data) | 1059 | unsigned int data) |
1058 | { | 1060 | { |
1059 | int res; | 1061 | int res; |
1060 | int retry = 50; | 1062 | unsigned long timeout = jiffies + msecs_to_jiffies(1000); |
1061 | 1063 | ||
1062 | /* send bits of data specified by reg to dsp */ | 1064 | /* send bits of data specified by reg to dsp */ |
1063 | do { | 1065 | do { |
1064 | res = snd_hda_codec_read(codec, WIDGET_DSP_CTRL, 0, reg, data); | 1066 | res = snd_hda_codec_read(codec, WIDGET_DSP_CTRL, 0, reg, data); |
1065 | if ((res >= 0) && (res != VENDOR_STATUS_DSPIO_BUSY)) | 1067 | if ((res >= 0) && (res != VENDOR_STATUS_DSPIO_BUSY)) |
1066 | return res; | 1068 | return res; |
1067 | } while (--retry); | 1069 | msleep(20); |
1070 | } while (time_before(jiffies, timeout)); | ||
1068 | 1071 | ||
1069 | return -EIO; | 1072 | return -EIO; |
1070 | } | 1073 | } |
@@ -1296,7 +1299,6 @@ static int dspio_send_scp_message(struct hda_codec *codec, | |||
1296 | unsigned int *bytes_returned) | 1299 | unsigned int *bytes_returned) |
1297 | { | 1300 | { |
1298 | struct ca0132_spec *spec = codec->spec; | 1301 | struct ca0132_spec *spec = codec->spec; |
1299 | int retry; | ||
1300 | int status = -1; | 1302 | int status = -1; |
1301 | unsigned int scp_send_size = 0; | 1303 | unsigned int scp_send_size = 0; |
1302 | unsigned int total_size; | 1304 | unsigned int total_size; |
@@ -1343,13 +1345,13 @@ static int dspio_send_scp_message(struct hda_codec *codec, | |||
1343 | } | 1345 | } |
1344 | 1346 | ||
1345 | if (waiting_for_resp) { | 1347 | if (waiting_for_resp) { |
1348 | unsigned long timeout = jiffies + msecs_to_jiffies(1000); | ||
1346 | memset(return_buf, 0, return_buf_size); | 1349 | memset(return_buf, 0, return_buf_size); |
1347 | retry = 50; | ||
1348 | do { | 1350 | do { |
1349 | msleep(20); | 1351 | msleep(20); |
1350 | } while (spec->wait_scp && (--retry != 0)); | 1352 | } while (spec->wait_scp && time_before(jiffies, timeout)); |
1351 | waiting_for_resp = false; | 1353 | waiting_for_resp = false; |
1352 | if (retry != 0) { | 1354 | if (!spec->wait_scp) { |
1353 | ret_msg = (struct scp_msg *)return_buf; | 1355 | ret_msg = (struct scp_msg *)return_buf; |
1354 | memcpy(&ret_msg->hdr, &spec->scp_resp_header, 4); | 1356 | memcpy(&ret_msg->hdr, &spec->scp_resp_header, 4); |
1355 | memcpy(&ret_msg->data, spec->scp_resp_data, | 1357 | memcpy(&ret_msg->data, spec->scp_resp_data, |
@@ -2242,7 +2244,8 @@ static int dspxfr_one_seg(struct hda_codec *codec, | |||
2242 | u32 chip_addx_remainder; | 2244 | u32 chip_addx_remainder; |
2243 | unsigned int run_size_words; | 2245 | unsigned int run_size_words; |
2244 | const struct dsp_image_seg *hci_write = NULL; | 2246 | const struct dsp_image_seg *hci_write = NULL; |
2245 | int retry; | 2247 | unsigned long timeout; |
2248 | bool dma_active; | ||
2246 | 2249 | ||
2247 | if (fls == NULL) | 2250 | if (fls == NULL) |
2248 | return -EINVAL; | 2251 | return -EINVAL; |
@@ -2360,11 +2363,17 @@ static int dspxfr_one_seg(struct hda_codec *codec, | |||
2360 | status = dspxfr_hci_write(codec, hci_write); | 2363 | status = dspxfr_hci_write(codec, hci_write); |
2361 | hci_write = NULL; | 2364 | hci_write = NULL; |
2362 | } | 2365 | } |
2363 | retry = 5000; | 2366 | |
2364 | while (dsp_is_dma_active(codec, dma_chan)) { | 2367 | timeout = jiffies + msecs_to_jiffies(2000); |
2365 | if (--retry <= 0) | 2368 | do { |
2369 | dma_active = dsp_is_dma_active(codec, dma_chan); | ||
2370 | if (!dma_active) | ||
2366 | break; | 2371 | break; |
2367 | } | 2372 | msleep(20); |
2373 | } while (time_before(jiffies, timeout)); | ||
2374 | if (dma_active) | ||
2375 | break; | ||
2376 | |||
2368 | snd_printdd(KERN_INFO "+++++ DMA complete"); | 2377 | snd_printdd(KERN_INFO "+++++ DMA complete"); |
2369 | dma_set_state(dma_engine, DMA_STATE_STOP); | 2378 | dma_set_state(dma_engine, DMA_STATE_STOP); |
2370 | dma_reset(dma_engine); | 2379 | dma_reset(dma_engine); |
@@ -2616,15 +2625,15 @@ static bool dspload_is_loaded(struct hda_codec *codec) | |||
2616 | 2625 | ||
2617 | static bool dspload_wait_loaded(struct hda_codec *codec) | 2626 | static bool dspload_wait_loaded(struct hda_codec *codec) |
2618 | { | 2627 | { |
2619 | int retry = 100; | 2628 | unsigned long timeout = jiffies + msecs_to_jiffies(2000); |
2620 | 2629 | ||
2621 | do { | 2630 | do { |
2622 | msleep(20); | ||
2623 | if (dspload_is_loaded(codec)) { | 2631 | if (dspload_is_loaded(codec)) { |
2624 | pr_info("ca0132 DOWNLOAD OK :-) DSP IS RUNNING.\n"); | 2632 | pr_info("ca0132 DOWNLOAD OK :-) DSP IS RUNNING.\n"); |
2625 | return true; | 2633 | return true; |
2626 | } | 2634 | } |
2627 | } while (--retry); | 2635 | msleep(20); |
2636 | } while (time_before(jiffies, timeout)); | ||
2628 | 2637 | ||
2629 | pr_err("ca0132 DOWNLOAD FAILED!!! DSP IS NOT RUNNING.\n"); | 2638 | pr_err("ca0132 DOWNLOAD FAILED!!! DSP IS NOT RUNNING.\n"); |
2630 | return false; | 2639 | return false; |