summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoranupam roy <anupam.roy@stericsson.com>2011-10-18 21:11:18 +0530
committerPhilippe Langlais <philippe.langlais@stericsson.com>2012-05-22 11:06:02 +0200
commit09e5ba4ee118f7019157062184aeeb6c83e2f8be (patch)
tree5c73b0bde145ce0c1da266480bb25bf685586f19
parent253a6fbf6c5a5a4b49600972b4f50e73e8c83b88 (diff)
CG2900 FM Radio: Improper RDS Thread handling.
This patch fixes the thread leak issue from CG2900 FM kernel driver by proper handling of RDS threads. ST-Ericsson Linux next: NA ST-Ericsson ID: 365795 ST-Ericsson FOSS-OUT ID: Trivial Change-Id: I277dae0e74f4115db2b0f734dd7f6361678b9502 Signed-off-by: anupam roy <anupam.roy@stericsson.com> Reviewed-on: http://gerrit.lud.stericsson.com/gerrit/34400 Reviewed-by: QATOOLS Reviewed-by: Anurag SRIVASTAVA <anurag.srivastava@stericsson.com> Reviewed-by: Johan PALMAEUS <johan.xj.palmaeus@stericsson.com> Reviewed-by: Hemant GUPTA <hemant.gupta@stericsson.com>
-rw-r--r--drivers/media/radio/CG2900/cg2900_fm_api.c62
-rw-r--r--drivers/media/radio/CG2900/cg2900_fm_driver.c5
2 files changed, 43 insertions, 24 deletions
diff --git a/drivers/media/radio/CG2900/cg2900_fm_api.c b/drivers/media/radio/CG2900/cg2900_fm_api.c
index ad9ab8de282..c18caffdaa7 100644
--- a/drivers/media/radio/CG2900/cg2900_fm_api.c
+++ b/drivers/media/radio/CG2900/cg2900_fm_api.c
@@ -585,6 +585,24 @@ error:
}
/**
+ * cg2900_fm_check_rds_status()- Checks whether RDS was On previously
+ *
+ * This method is called on receiving interrupt for Seek Completion,
+ * Scan completion and Block Scan completion. It will check whether RDS
+ * was forcefully disabled before the above operations started and if the
+ * previous RDS state was true, then RDS will be enabled back
+ */
+static void cg2900_fm_check_rds_status(void)
+{
+ FM_INFO_REPORT("cg2900_fm_check_rds_status");
+ if (fm_prev_rds_status) {
+ /* Restart RDS if it was active previously */
+ cg2900_fm_rds_on();
+ fm_prev_rds_status = false;
+ }
+}
+
+/**
* cg2900_fm_driver_callback()- Callback function indicating the event.
*
* This callback function is called on receiving irpt_CommandSucceeded,
@@ -631,6 +649,7 @@ static void cg2900_fm_driver_callback(
break;
case FMD_EVENT_SEEK_COMPLETED:
FM_DEBUG_REPORT("FMD_EVENT_SEEK_COMPLETED");
+ cg2900_fm_check_rds_status();
skb = alloc_skb(SKB_FM_INTERRUPT_DATA,
GFP_KERNEL);
if (!skb) {
@@ -645,6 +664,7 @@ static void cg2900_fm_driver_callback(
break;
case FMD_EVENT_SCAN_BAND_COMPLETED:
FM_DEBUG_REPORT("FMD_EVENT_SCAN_BAND_COMPLETED");
+ cg2900_fm_check_rds_status();
skb = alloc_skb(SKB_FM_INTERRUPT_DATA,
GFP_KERNEL);
if (!skb) {
@@ -659,6 +679,7 @@ static void cg2900_fm_driver_callback(
break;
case FMD_EVENT_BLOCK_SCAN_COMPLETED:
FM_DEBUG_REPORT("FMD_EVENT_BLOCK_SCAN_COMPLETED");
+ cg2900_fm_check_rds_status();
skb = alloc_skb(SKB_FM_INTERRUPT_DATA,
GFP_KERNEL);
if (!skb) {
@@ -830,6 +851,7 @@ int cg2900_fm_init(void)
fm_event = CG2900_EVENT_NO_EVENT;
fm_state = CG2900_FM_STATE_INITIALIZED;
fm_mode = CG2900_FM_IDLE_MODE;
+ fm_prev_rds_status = false;
error:
FM_DEBUG_REPORT("cg2900_fm_init: returning %d",
@@ -1473,6 +1495,7 @@ int cg2900_fm_search_up_freq(void)
if (0 != result) {
FM_ERR_REPORT("cg2900_fm_search_up_freq: "
"Error Code %d", (unsigned int)result);
+ cg2900_fm_check_rds_status();
result = -EINVAL;
goto error;
}
@@ -1513,6 +1536,7 @@ int cg2900_fm_search_down_freq(void)
if (0 != result) {
FM_ERR_REPORT("cg2900_fm_search_down_freq: "
"Error Code %d", (unsigned int)result);
+ cg2900_fm_check_rds_status();
result = -EINVAL;
goto error;
}
@@ -1553,6 +1577,7 @@ int cg2900_fm_start_band_scan(void)
if (0 != result) {
FM_ERR_REPORT("cg2900_fm_start_band_scan: "
"Error Code %d", (unsigned int)result);
+ cg2900_fm_check_rds_status();
result = -EINVAL;
goto error;
}
@@ -1685,11 +1710,6 @@ int cg2900_fm_get_scan_result(
}
}
}
- if (fm_prev_rds_status) {
- /* Restart RDS if it was active earlier */
- result = cg2900_fm_rds_on();
- fm_prev_rds_status = false;
- }
error:
FM_DEBUG_REPORT("cg2900_fm_get_scan_result: returning %d",
@@ -1739,6 +1759,7 @@ int cg2900_fm_start_block_scan(
if (0 != result) {
FM_ERR_REPORT("cg2900_fm_start_block_scan: "
"Error Code %d", (unsigned int)result);
+ cg2900_fm_check_rds_status();
result = -EINVAL;
goto error;
}
@@ -1791,13 +1812,7 @@ int cg2900_fm_get_block_scan_result(
= rssi[5];
}
}
- if (CG2900_FM_RX_MODE == fm_mode) {
- if (fm_prev_rds_status) {
- /* Restart RDS if it was active earlier*/
- result = cg2900_fm_rds_on();
- fm_prev_rds_status = false;
- }
- } else if (CG2900_FM_TX_MODE == fm_mode) {
+ if (CG2900_FM_TX_MODE == fm_mode) {
FM_DEBUG_REPORT("cg2900_fm_get_block_scan_result:"
" Sending Set fmd_tx_set_pa");
@@ -2441,7 +2456,12 @@ int cg2900_fm_rds_on(void)
int result;
FM_INFO_REPORT("cg2900_fm_rds_on");
-
+ if (fm_rds_status) {
+ result = 0;
+ FM_DEBUG_REPORT("cg2900_fm_rds_on: rds is on "
+ "return result = %d", result);
+ return result;
+ }
if (CG2900_FM_STATE_SWITCHED_ON != fm_state) {
FM_ERR_REPORT("cg2900_fm_rds_on: "
"Invalid state of FM Driver = %d", fm_state);
@@ -2635,11 +2655,6 @@ int cg2900_fm_get_frequency(
*freq = currentFreq * FREQUENCY_CONVERTOR_KHZ_HZ;
FM_DEBUG_REPORT("cg2900_fm_get_frequency: "
"Current Frequency = %d Hz", *freq);
- if (fm_prev_rds_status) {
- /* Restart RDS if it was active earlier */
- cg2900_fm_rds_on();
- fm_prev_rds_status = false;
- }
error:
FM_DEBUG_REPORT("cg2900_fm_get_frequency: returning %d",
@@ -2688,18 +2703,17 @@ int cg2900_fm_set_frequency(
result = fmd_tx_set_frequency(
new_freq / FREQUENCY_CONVERTOR_KHZ_HZ);
}
+ if (fm_prev_rds_status) {
+ /* Restart RDS if it was active earlier */
+ cg2900_fm_rds_on();
+ fm_prev_rds_status = false;
+ }
if (result != 0) {
FM_ERR_REPORT("cg2900_fm_set_frequency: "
"fmd_rx_set_frequency failed %x",
(unsigned int)result);
result = -EINVAL;
goto error;
- } else {
- if (fm_prev_rds_status) {
- /* Restart RDS if it was active earlier */
- cg2900_fm_rds_on();
- fm_prev_rds_status = false;
- }
}
if (CG2900_FM_TX_MODE == fm_mode) {
diff --git a/drivers/media/radio/CG2900/cg2900_fm_driver.c b/drivers/media/radio/CG2900/cg2900_fm_driver.c
index 1d3a2552da2..4b1d39839ae 100644
--- a/drivers/media/radio/CG2900/cg2900_fm_driver.c
+++ b/drivers/media/radio/CG2900/cg2900_fm_driver.c
@@ -1154,6 +1154,8 @@ static int fmd_rds_thread(
/* Give 100 ms for context switching */
schedule_timeout_interruptible(msecs_to_jiffies(100));
}
+ /* Always signal the rds_sem semaphore before exiting */
+ fmd_set_rds_sem();
FM_DEBUG_REPORT("fmd_rds_thread Exiting!!!");
return 0;
}
@@ -4667,6 +4669,9 @@ void fmd_stop_rds_thread(void)
sema_init(&rds_sem, 0);
cb_rds_func = NULL;
rds_thread_required = false;
+ /* Wait for RDS thread to exit gracefully */
+ fmd_get_rds_sem();
+
if (rds_thread_task)
rds_thread_task = NULL;
}