msm: sdio: add SDIO test for modem reset feature
Signed-off-by: Maya Erez <merez@codeaurora.org>
diff --git a/arch/arm/mach-msm/sdio_al.c b/arch/arm/mach-msm/sdio_al.c
index e774508..5cbf013 100644
--- a/arch/arm/mach-msm/sdio_al.c
+++ b/arch/arm/mach-msm/sdio_al.c
@@ -3103,15 +3103,14 @@
pr_debug(MODULE_NAME ": %s: Notifying SDIO clients for card %d",
__func__, sdio_al_dev->card->host->index);
- if (!sdio_al->unittest_mode)
- for (j = 0; j < SDIO_AL_MAX_CHANNELS; j++) {
- if (sdio_al_dev->channel[j].state ==
- SDIO_CHANNEL_STATE_INVALID)
- continue;
- platform_device_unregister(
- sdio_al_dev->channel[j].pdev);
- sdio_al_dev->channel[i].signature = 0x0;
- }
+ for (j = 0; j < SDIO_AL_MAX_CHANNELS; j++) {
+ if (sdio_al_dev->channel[j].state ==
+ SDIO_CHANNEL_STATE_INVALID)
+ continue;
+ platform_device_unregister(
+ sdio_al_dev->channel[j].pdev);
+ sdio_al_dev->channel[i].signature = 0x0;
+ }
if (!sdio_al_verify_func1(sdio_al_dev, __func__))
sdio_release_host(sdio_al_dev->card->sdio_func[0]);
@@ -3160,7 +3159,6 @@
if (sdio_al_dev->channel[i].state == SDIO_CHANNEL_STATE_INVALID)
continue;
if (sdio_al->unittest_mode) {
- test_channel_init(sdio_al_dev->channel[i].name);
memset(sdio_al_dev->channel[i].ch_test_name, 0,
sizeof(sdio_al_dev->channel[i].ch_test_name));
ch_name_size = strnlen(sdio_al_dev->channel[i].name,
@@ -3436,18 +3434,16 @@
del_timer_sync(&sdio_al_dev->timer);
}
- if (!sdio_al->unittest_mode) {
- pr_info(MODULE_NAME ":%s: notifying clients for "
- "card %d\n",
- __func__, card->host->index);
- for (i = 0; i < SDIO_AL_MAX_CHANNELS; i++) {
- if (sdio_al_dev->channel[i].state ==
- SDIO_CHANNEL_STATE_INVALID)
- continue;
- platform_device_unregister(
- sdio_al_dev->channel[i].pdev);
- sdio_al_dev->channel[i].signature = 0x0;
- }
+ pr_info(MODULE_NAME ":%s: notifying clients for "
+ "card %d\n",
+ __func__, card->host->index);
+ for (i = 0; i < SDIO_AL_MAX_CHANNELS; i++) {
+ if (sdio_al_dev->channel[i].state ==
+ SDIO_CHANNEL_STATE_INVALID)
+ continue;
+ platform_device_unregister(
+ sdio_al_dev->channel[i].pdev);
+ sdio_al_dev->channel[i].signature = 0x0;
}
}
if (card->sdio_func[0])
diff --git a/arch/arm/mach-msm/sdio_al_private.h b/arch/arm/mach-msm/sdio_al_private.h
index 081ba0c..f352499 100644
--- a/arch/arm/mach-msm/sdio_al_private.h
+++ b/arch/arm/mach-msm/sdio_al_private.h
@@ -30,6 +30,7 @@
#define CHANNEL_NAME_SIZE (sizeof(SDIO_PREFIX) + PEER_CHANNEL_NAME_SIZE)
#define SDIO_TEST_POSTFIX_SIZE 5
#define MAX_NUM_OF_SDIO_DEVICES 2
+#define TEST_CH_NAME_SIZE (CHANNEL_NAME_SIZE + SDIO_TEST_POSTFIX_SIZE)
struct sdio_al_device; /* Forward Declaration */
@@ -164,7 +165,7 @@
struct sdio_channel {
/* Channel Configuration Parameters*/
char name[CHANNEL_NAME_SIZE];
- char ch_test_name[CHANNEL_NAME_SIZE+SDIO_TEST_POSTFIX_SIZE];
+ char ch_test_name[TEST_CH_NAME_SIZE];
int read_threshold;
int write_threshold;
int def_read_threshold;
diff --git a/arch/arm/mach-msm/sdio_al_test.c b/arch/arm/mach-msm/sdio_al_test.c
index 454d877..c27de7d 100644
--- a/arch/arm/mach-msm/sdio_al_test.c
+++ b/arch/arm/mach-msm/sdio_al_test.c
@@ -83,6 +83,7 @@
*/
SDIO_TEST_PERF,
SDIO_TEST_RTT,
+ SDIO_TEST_MODEM_RESET,
};
struct lpm_task {
@@ -185,6 +186,7 @@
atomic_t tx_notify_count;
atomic_t any_notify_count;
atomic_t wakeup_client;
+ atomic_t card_detected_event;
int wait_counter;
@@ -210,6 +212,7 @@
int modem_result_per_chan;
int notify_counter_per_chan;
int max_burst_size; /* number of writes before close/open */
+ int card_removed;
};
struct sdio_al_test_debug {
@@ -327,25 +330,26 @@
pr_info(TEST_MODULE_NAME "%s: channel name %s\n",
__func__, name);
- if (!strncmp(name, "SDIO_RPC", strnlen("SDIO_RPC", CHANNEL_NAME_SIZE)))
+ if (!strncmp(name, "SDIO_RPC_TEST",
+ strnlen("SDIO_RPC_TEST", CHANNEL_NAME_SIZE)))
return SDIO_RPC;
- else if (!strncmp(name, "SDIO_QMI",
- strnlen("SDIO_QMI", CHANNEL_NAME_SIZE)))
+ else if (!strncmp(name, "SDIO_QMI_TEST",
+ strnlen("SDIO_QMI_TEST", TEST_CH_NAME_SIZE)))
return SDIO_QMI;
- else if (!strncmp(name, "SDIO_RMNT",
- strnlen("SDIO_RMNT", CHANNEL_NAME_SIZE)))
+ else if (!strncmp(name, "SDIO_RMNT_TEST",
+ strnlen("SDIO_RMNT_TEST", TEST_CH_NAME_SIZE)))
return SDIO_RMNT;
- else if (!strncmp(name, "SDIO_DIAG",
- strnlen("SDIO_DIAG", CHANNEL_NAME_SIZE)))
+ else if (!strncmp(name, "SDIO_DIAG_TEST",
+ strnlen("SDIO_DIAG", TEST_CH_NAME_SIZE)))
return SDIO_DIAG;
- else if (!strncmp(name, "SDIO_DUN",
- strnlen("SDIO_DUN", CHANNEL_NAME_SIZE)))
+ else if (!strncmp(name, "SDIO_DUN_TEST",
+ strnlen("SDIO_DUN_TEST", TEST_CH_NAME_SIZE)))
return SDIO_DUN;
- else if (!strncmp(name, "SDIO_SMEM",
- strnlen("SDIO_SMEM", CHANNEL_NAME_SIZE)))
+ else if (!strncmp(name, "SDIO_SMEM_TEST",
+ strnlen("SDIO_SMEM_TEST", TEST_CH_NAME_SIZE)))
return SDIO_SMEM;
- else if (!strncmp(name, "SDIO_CIQ",
- strnlen("SDIO_CIQ", CHANNEL_NAME_SIZE)))
+ else if (!strncmp(name, "SDIO_CIQ_TEST",
+ strnlen("SDIO_CIQ_TEST", TEST_CH_NAME_SIZE)))
return SDIO_CIQ;
else
return SDIO_MAX_CHANNELS;
@@ -516,6 +520,11 @@
return;
}
+ if (!test_device->lpm_arr) {
+ pr_err(TEST_MODULE_NAME ": %s - NULL lpm_arr\n", __func__);
+ return;
+ }
+
if (test_device->next_avail_entry_in_array >=
test_device->array_size) {
pr_err(TEST_MODULE_NAME ": %s - lpm array is full",
@@ -1997,6 +2006,177 @@
return;
}
+
+/**
+ * Modem reset Test
+ * The test verifies that it finished sending all the packets
+ * while there might be modem reset in the middle
+ */
+static void modem_reset_test(struct test_channel *test_ch)
+{
+ int ret = 0 ;
+ u32 read_avail = 0;
+ u32 write_avail = 0;
+ int tx_packet_count = 0;
+ int rx_packet_count = 0;
+ int size = 0;
+ u16 *buf16 = (u16 *) test_ch->buf;
+ int i;
+ int max_packets = 10000;
+ u32 packet_size = test_ch->buf_size;
+ int is_err = 0;
+
+ max_packets = test_ch->config_msg.num_packets;
+ packet_size = test_ch->packet_length;
+
+ for (i = 0; i < packet_size / 2; i++)
+ buf16[i] = (u16) (i & 0xFFFF);
+
+ pr_info(TEST_MODULE_NAME ": Modem Reset TEST START for chan %s\n",
+ test_ch->name);
+
+ while (tx_packet_count < max_packets) {
+
+ if (test_ctx->exit_flag) {
+ pr_info(TEST_MODULE_NAME ":Exit Test.\n");
+ return;
+ }
+
+ if (test_ch->card_removed) {
+ pr_info(TEST_MODULE_NAME ": card removal was detected "
+ "for chan %s, tx_total=0x%x\n",
+ test_ch->name, test_ch->tx_bytes);
+ wait_event(test_ch->wait_q,
+ atomic_read(&test_ch->card_detected_event));
+ atomic_set(&test_ch->card_detected_event, 0);
+ pr_info(TEST_MODULE_NAME ": card_detected_event "
+ "for chan %s\n", test_ch->name);
+ if (test_ch->card_removed)
+ continue;
+ is_err = 0;
+ /* Need to wait for the modem to be ready */
+ msleep(5000);
+ pr_info(TEST_MODULE_NAME ": sending the config message "
+ "for chan %s\n", test_ch->name);
+ send_config_msg(test_ch);
+ }
+
+ /* wait for data ready event */
+ /* use a func to avoid compiler optimizations */
+ write_avail = sdio_write_avail(test_ch->ch);
+ read_avail = sdio_read_avail(test_ch->ch);
+ TEST_DBG(TEST_MODULE_NAME ":channel %s, write_avail=%d, "
+ "read_avail=%d for chan %s\n",
+ test_ch->name, write_avail, read_avail,
+ test_ch->name);
+ if ((write_avail == 0) && (read_avail == 0)) {
+ wait_event(test_ch->wait_q,
+ atomic_read(&test_ch->any_notify_count));
+ atomic_set(&test_ch->any_notify_count, 0);
+ }
+ if (atomic_read(&test_ch->card_detected_event)) {
+ atomic_set(&test_ch->card_detected_event, 0);
+ pr_info(TEST_MODULE_NAME ": card_detected_event "
+ "for chan %s, tx_total=0x%x\n",
+ test_ch->name, test_ch->tx_bytes);
+ if (test_ch->card_removed)
+ continue;
+ /* Need to wait for the modem to be ready */
+ msleep(5000);
+ is_err = 0;
+ pr_info(TEST_MODULE_NAME ": sending the config message "
+ "for chan %s\n", test_ch->name);
+ send_config_msg(test_ch);
+ }
+
+ write_avail = sdio_write_avail(test_ch->ch);
+ TEST_DBG(TEST_MODULE_NAME ":channel %s, write_avail=%d\n",
+ test_ch->name, write_avail);
+ if (write_avail > 0) {
+ size = min(packet_size, write_avail) ;
+ pr_debug(TEST_MODULE_NAME ":tx size = %d for chan %s\n",
+ size, test_ch->name);
+ test_ch->buf[0] = tx_packet_count;
+ test_ch->buf[(size/4)-1] = tx_packet_count;
+
+ TEST_DBG(TEST_MODULE_NAME ":channel %s, sdio_write, "
+ "size=%d\n", test_ch->name, size);
+ if (is_err) {
+ msleep(100);
+ continue;
+ }
+ ret = sdio_write(test_ch->ch, test_ch->buf, size);
+ if (ret) {
+ pr_info(TEST_MODULE_NAME ":sdio_write err=%d"
+ " for chan %s\n",
+ -ret, test_ch->name);
+ is_err = 1;
+ msleep(20);
+ continue;
+ }
+ tx_packet_count++;
+ test_ch->tx_bytes += size;
+ test_ch->config_msg.num_packets--;
+ }
+
+ read_avail = sdio_read_avail(test_ch->ch);
+ TEST_DBG(TEST_MODULE_NAME ":channel %s, read_avail=%d\n",
+ test_ch->name, read_avail);
+ if (read_avail > 0) {
+ size = min(packet_size, read_avail);
+ pr_debug(TEST_MODULE_NAME ":rx size = %d.\n", size);
+ TEST_DBG(TEST_MODULE_NAME ":channel %s, sdio_read, "
+ "size=%d\n", test_ch->name, size);
+ if (is_err) {
+ msleep(100);
+ continue;
+ }
+ ret = sdio_read(test_ch->ch, test_ch->buf, size);
+ if (ret) {
+ pr_info(TEST_MODULE_NAME ": sdio_read size %d "
+ " err=%d"
+ " for chan %s\n",
+ size, -ret, test_ch->name);
+ is_err = 1;
+ msleep(20);
+ continue;
+ }
+ rx_packet_count++;
+ test_ch->rx_bytes += size;
+ }
+
+ TEST_DBG(TEST_MODULE_NAME
+ ":total rx bytes = %d , rx_packet#=%d"
+ " for chan %s\n",
+ test_ch->rx_bytes, rx_packet_count, test_ch->name);
+ TEST_DBG(TEST_MODULE_NAME
+ ":total tx bytes = %d , tx_packet#=%d"
+ " for chan %s\n",
+ test_ch->tx_bytes, tx_packet_count, test_ch->name);
+
+ udelay(500);
+
+ } /* while (tx_packet_count < max_packets ) */
+
+ rx_cleanup(test_ch, &rx_packet_count);
+
+ pr_info(TEST_MODULE_NAME ":total rx bytes = 0x%x , rx_packet#=%d for"
+ " chan %s.\n",
+ test_ch->rx_bytes, rx_packet_count, test_ch->name);
+ pr_info(TEST_MODULE_NAME ":total tx bytes = 0x%x , tx_packet#=%d"
+ " for chan %s.\n",
+ test_ch->tx_bytes, tx_packet_count, test_ch->name);
+
+ pr_err(TEST_MODULE_NAME ": Modem Reset TEST END for chan %s.\n",
+ test_ch->name);
+
+ pr_err(TEST_MODULE_NAME ": TEST PASS for chan %s\n", test_ch->name);
+ test_ch->test_completed = 1;
+ test_ch->test_result = TEST_PASSED;
+ check_test_completion();
+ return;
+}
+
/**
* Worker thread to handle the tests types
*/
@@ -2045,6 +2225,9 @@
case SDIO_TEST_CLOSE_CHANNEL:
open_close_test(test_ch);
break;
+ case SDIO_TEST_MODEM_RESET:
+ modem_reset_test(test_ch);
+ break;
default:
pr_err(TEST_MODULE_NAME ":Bad Test type = %d.\n",
(int) test_type);
@@ -2169,7 +2352,7 @@
return ret;
}
-static struct platform_driver sdio_smem_drv = {
+static struct platform_driver sdio_smem_client_drv = {
.probe = sdio_smem_test_probe,
.driver = {
.name = "SDIO_SMEM_CLIENT",
@@ -2259,7 +2442,6 @@
lpm_array_lock,
tch->test_device->
lpm_array_lock_flags);
-
if (is_vote_for_sleep == 1)
lpm_test_update_entry(tch,
LPM_SLEEP,
@@ -2341,18 +2523,15 @@
spin_lock_init(&test_dev->
lpm_array_lock);
- pr_err(MODULE_NAME ": %s - "
- "Allocating Msg Array for "
- "Maximum open channels for device (%d) "
- "Channels. Array has %d entries",
- __func__,
- LPM_MAX_OPEN_CHAN_PER_DEV,
- test_dev->array_size);
-
if (tch->test_type == SDIO_TEST_LPM_RANDOM) {
- pr_err(TEST_MODULE_NAME ": %s - initializing the "
- "lpm_array", __func__);
+ pr_err(MODULE_NAME ": %s - "
+ "Allocating Msg Array for "
+ "Maximum open channels for device (%d) "
+ "Channels. Array has %d entries",
+ __func__,
+ LPM_MAX_OPEN_CHAN_PER_DEV,
+ test_dev->array_size);
test_dev->lpm_arr =
kzalloc(sizeof(
@@ -2495,6 +2674,7 @@
":openning channel %s failed\n",
tch->name);
tch->ch_ready = false;
+ continue;
}
}
}
@@ -2573,12 +2753,21 @@
wait_event(test_ctx->wait_q, test_ctx->test_completed);
check_test_result();
+ /*
+ * Close the channels and zero the is_used flag so that if the modem
+ * will be reset after the test completion we won't re-open
+ * the channels
+ */
for (i = 0; i < SDIO_MAX_CHANNELS; i++) {
struct test_channel *tch = test_ctx->test_ch_arr[i];
- if ((!tch) || (!tch->is_used) || (!tch->ch_ready) ||
- (tch->ch_id == SDIO_SMEM) || (!tch->ch->is_packet_mode))
+ if ((!tch) || (!tch->is_used))
continue;
+ if ((!tch->ch_ready) ||
+ (tch->ch_id == SDIO_SMEM) || (!tch->ch->is_packet_mode)) {
+ tch->is_used = 0;
+ continue;
+ }
ret = sdio_close(tch->ch);
if (ret) {
pr_err(TEST_MODULE_NAME":%s close channel %s"
@@ -2588,6 +2777,7 @@
" success\n", __func__, tch->name);
tch->ch_ready = false;
}
+ tch->is_used = 0;
}
return 0;
}
@@ -2708,6 +2898,30 @@
return 0;
}
+static int set_params_modem_reset(struct test_channel *tch)
+{
+ if (!tch) {
+ pr_err(TEST_MODULE_NAME ":NULL channel\n");
+ return -EINVAL;
+ }
+ tch->is_used = 1;
+ tch->test_type = SDIO_TEST_MODEM_RESET;
+ tch->config_msg.signature = TEST_CONFIG_SIGNATURE;
+ tch->config_msg.test_case = SDIO_TEST_LOOPBACK_CLIENT;
+ tch->packet_length = 512;
+ if (tch->ch_id == SDIO_RPC)
+ tch->packet_length = 128;
+ else if ((tch->ch_id == SDIO_RMNT) || (tch->ch_id == SDIO_DUN))
+ tch->packet_length = MAX_XFER_SIZE;
+
+ tch->config_msg.num_packets = 50000;
+ tch->config_msg.num_iterations = 1;
+
+ tch->timer_interval_ms = 0;
+
+ return 0;
+}
+
static int set_params_smem_test(struct test_channel *tch)
{
if (!tch) {
@@ -2886,13 +3100,6 @@
for (i = 0 ; i < MAX_NUM_OF_SDIO_DEVICES ; ++i)
test_ctx->test_dev_arr[i].sdio_al_device = NULL;
- for (i = 0; i < SDIO_MAX_CHANNELS; i++) {
- struct test_channel *tch = test_ctx->test_ch_arr[i];
- if (!tch)
- continue;
- tch->is_used = 0;
- }
-
ret = strict_strtol(buf, 10, &test_ctx->testcase);
switch (test_ctx->testcase) {
@@ -2979,6 +3186,40 @@
if (set_params_rtt(test_ctx->test_ch_arr[SDIO_RMNT]))
return size;
break;
+ case 22:
+ pr_info(TEST_MODULE_NAME " -- modem reset - RPC --");
+ if (set_params_modem_reset(test_ctx->test_ch_arr[SDIO_RPC]))
+ return size;
+ break;
+ case 23:
+ pr_info(TEST_MODULE_NAME " -- modem reset - RMNT --");
+ if (set_params_modem_reset(test_ctx->test_ch_arr[SDIO_RMNT]))
+ return size;
+ break;
+ case 24:
+ pr_info(TEST_MODULE_NAME " -- modem reset - all chs 4bit device --");
+ if (set_params_modem_reset(test_ctx->test_ch_arr[SDIO_RPC]) ||
+ set_params_modem_reset(test_ctx->test_ch_arr[SDIO_QMI]) ||
+ set_params_modem_reset(test_ctx->test_ch_arr[SDIO_DIAG]))
+ return size;
+ break;
+ case 25:
+ pr_info(TEST_MODULE_NAME " -- modem reset - all chs 8bit device--");
+ if (set_params_modem_reset(test_ctx->test_ch_arr[SDIO_RMNT]) ||
+ set_params_modem_reset(test_ctx->test_ch_arr[SDIO_DUN]) ||
+ set_params_modem_reset(test_ctx->test_ch_arr[SDIO_CIQ]))
+ return size;
+ break;
+ case 26:
+ pr_info(TEST_MODULE_NAME " -- modem reset - all chs --");
+ if (set_params_modem_reset(test_ctx->test_ch_arr[SDIO_RPC]) ||
+ set_params_modem_reset(test_ctx->test_ch_arr[SDIO_QMI]) ||
+ set_params_modem_reset(test_ctx->test_ch_arr[SDIO_DIAG]) ||
+ set_params_modem_reset(test_ctx->test_ch_arr[SDIO_RMNT]) ||
+ set_params_modem_reset(test_ctx->test_ch_arr[SDIO_DUN]) ||
+ set_params_modem_reset(test_ctx->test_ch_arr[SDIO_CIQ]))
+ return size;
+ break;
case 27:
pr_info(TEST_MODULE_NAME " -- host sender with open/close for "
"Diag, CIQ and RPC --");
@@ -3046,7 +3287,7 @@
default:
pr_info(TEST_MODULE_NAME ":Bad Test number = %d.\n",
(int)test_ctx->testcase);
- return 0;
+ return size;
}
ret = test_start();
if (ret) {
@@ -3084,9 +3325,7 @@
{
struct test_channel *test_ch;
int ch_id = 0;
-#ifdef CONFIG_MSM_SDIO_SMEM
int ret;
-#endif
pr_debug(TEST_MODULE_NAME ":%s.\n", __func__);
pr_info(TEST_MODULE_NAME ": init test cahnnel %s.\n", name);
@@ -3105,7 +3344,8 @@
test_ch->ch_id = ch_id;
- memcpy(test_ch->name, name, CHANNEL_NAME_SIZE);
+ strncpy(test_ch->name, name,
+ strnlen(name, TEST_CH_NAME_SIZE)-SDIO_TEST_POSTFIX_SIZE);
test_ch->buf_size = MAX_XFER_SIZE;
@@ -3129,7 +3369,7 @@
}
#ifdef CONFIG_MSM_SDIO_SMEM
- ret = platform_driver_register(&sdio_smem_drv);
+ ret = platform_driver_register(&sdio_smem_client_drv);
if (ret) {
pr_err(TEST_MODULE_NAME ":%s: Unable to "
"register sdio smem "
@@ -3147,14 +3387,138 @@
init_waitqueue_head(&test_ch->wait_q);
}
} else {
- pr_err(TEST_MODULE_NAME ":trying to call test_channel_init "
- "twice for chan %d\n",
- ch_id);
+ test_ch = test_ctx->test_ch_arr[ch_id];
+ pr_info(TEST_MODULE_NAME ":%s: ch %s was detected again\n",
+ __func__, test_ch->name);
+ test_ch->card_removed = 0;
+ if ((test_ch->is_used) &&
+ (test_ch->test_type == SDIO_TEST_MODEM_RESET)) {
+ if (test_ch->ch_id == SDIO_SMEM) {
+ test_ctx->smem_pdev.name = "SDIO_SMEM";
+ test_ctx->smem_pdev.dev.release =
+ default_sdio_al_test_release;
+ platform_device_register(&test_ctx->smem_pdev);
+ } else {
+ test_ch->ch_ready = true;
+ ret = sdio_open(test_ch->name , &test_ch->ch,
+ test_ch, notify);
+ if (ret) {
+ pr_info(TEST_MODULE_NAME
+ ":openning channel %s failed\n",
+ test_ch->name);
+ test_ch->ch_ready = false;
+ return 0;
+ }
+ ret = sdio_test_find_dev(test_ch);
+
+ if (ret) {
+ pr_err(TEST_MODULE_NAME ": %s - "
+ "sdio_test_find_dev() returned "
+ "with error", __func__);
+ return -ENODEV;
+ }
+
+ test_ch->sdio_al_device =
+ test_ch->ch->sdio_al_dev;
+ }
+ atomic_set(&test_ch->card_detected_event, 1);
+ wake_up(&test_ch->wait_q);
+ }
}
return 0;
}
+static int sdio_test_channel_probe(struct platform_device *pdev)
+{
+ if (!pdev)
+ return -EIO;
+ return test_channel_init((char *)pdev->name);
+}
+
+static int sdio_test_channel_remove(struct platform_device *pdev)
+{
+ int ch_id;
+
+ if (!pdev)
+ return -EIO;
+
+ ch_id = channel_name_to_id((char *)pdev->name);
+ if (test_ctx->test_ch_arr[ch_id] == NULL)
+ return 0;
+
+ pr_info(TEST_MODULE_NAME "%s: remove ch %s\n",
+ __func__, test_ctx->test_ch_arr[ch_id]->name);
+ test_ctx->test_ch_arr[ch_id]->ch_ready = 0;
+ test_ctx->test_ch_arr[ch_id]->card_removed = 1;
+
+ return 0;
+
+}
+
+static struct platform_driver sdio_rpc_drv = {
+ .probe = sdio_test_channel_probe,
+ .remove = sdio_test_channel_remove,
+ .driver = {
+ .name = "SDIO_RPC_TEST",
+ .owner = THIS_MODULE,
+ },
+};
+
+static struct platform_driver sdio_qmi_drv = {
+ .probe = sdio_test_channel_probe,
+ .remove = sdio_test_channel_remove,
+ .driver = {
+ .name = "SDIO_QMI_TEST",
+ .owner = THIS_MODULE,
+ },
+};
+
+static struct platform_driver sdio_diag_drv = {
+ .probe = sdio_test_channel_probe,
+ .remove = sdio_test_channel_remove,
+ .driver = {
+ .name = "SDIO_DIAG_TEST",
+ .owner = THIS_MODULE,
+ },
+};
+
+static struct platform_driver sdio_smem_drv = {
+ .probe = sdio_test_channel_probe,
+ .remove = sdio_test_channel_remove,
+ .driver = {
+ .name = "SDIO_SMEM_TEST",
+ .owner = THIS_MODULE,
+ },
+};
+
+static struct platform_driver sdio_rmnt_drv = {
+ .probe = sdio_test_channel_probe,
+ .remove = sdio_test_channel_remove,
+ .driver = {
+ .name = "SDIO_RMNT_TEST",
+ .owner = THIS_MODULE,
+ },
+};
+
+static struct platform_driver sdio_dun_drv = {
+ .probe = sdio_test_channel_probe,
+ .remove = sdio_test_channel_remove,
+ .driver = {
+ .name = "SDIO_DUN_TEST",
+ .owner = THIS_MODULE,
+ },
+};
+
+static struct platform_driver sdio_ciq_drv = {
+ .probe = sdio_test_channel_probe,
+ .remove = sdio_test_channel_remove,
+ .driver = {
+ .name = "SDIO_CIQ_TEST",
+ .owner = THIS_MODULE,
+ },
+};
+
static struct class *test_class;
const struct file_operations test_fops = {
@@ -3217,6 +3581,14 @@
else
pr_debug(TEST_MODULE_NAME ":SDIO-AL-Test init OK..\n");
+ platform_driver_register(&sdio_rpc_drv);
+ platform_driver_register(&sdio_qmi_drv);
+ platform_driver_register(&sdio_diag_drv);
+ platform_driver_register(&sdio_smem_drv);
+ platform_driver_register(&sdio_rmnt_drv);
+ platform_driver_register(&sdio_dun_drv);
+ platform_driver_register(&sdio_ciq_drv);
+
return ret;
}
@@ -3237,6 +3609,14 @@
device_destroy(test_class, test_ctx->dev_num);
unregister_chrdev_region(test_ctx->dev_num, 1);
+ platform_driver_unregister(&sdio_rpc_drv);
+ platform_driver_unregister(&sdio_qmi_drv);
+ platform_driver_unregister(&sdio_diag_drv);
+ platform_driver_unregister(&sdio_smem_drv);
+ platform_driver_unregister(&sdio_rmnt_drv);
+ platform_driver_unregister(&sdio_dun_drv);
+ platform_driver_unregister(&sdio_ciq_drv);
+
for (i = 0; i < SDIO_MAX_CHANNELS; i++) {
struct test_channel *tch = test_ctx->test_ch_arr[i];
if (!tch)