Merge "[Feature][S300AI][task-view-1714]It is used for the initial verification of the function of switch rj11"
diff --git a/lynq/S300AI/ap/os/linux/linux-3.4.x/drivers/slic_tw/arch/slic_tw.c b/lynq/S300AI/ap/os/linux/linux-3.4.x/drivers/slic_tw/arch/slic_tw.c
index ba0449c..3ac2ad9 100644
--- a/lynq/S300AI/ap/os/linux/linux-3.4.x/drivers/slic_tw/arch/slic_tw.c
+++ b/lynq/S300AI/ap/os/linux/linux-3.4.x/drivers/slic_tw/arch/slic_tw.c
@@ -52,8 +52,7 @@
 
 
 static VpDeviceIdType deviceId = (0x0010 | 0x0100);
-
-static SLIC_TW_DATA *slic_tw;
+static SLIC_TW_DATA *slic_tw = NULL;
 static DEFINE_MUTEX(slic_tw_mutex);
 static SLIC_TW_MSG                   *msg_queue;
 static struct wake_lock slic_wakelock;
@@ -1520,31 +1519,30 @@
 static int slic_tw_probe(struct spi_device *spi)
 {
 	int ret;
+	bool slic_probe = false;
 #ifdef SLIC_USE_THREAD_POLLING
 	struct task_struct *th;
 	struct sched_param param;
 #endif
 	printk("slic_tw_probe\n");
-
-#if defined(CONFIG_ARCH_ZX297520V3_CPE_SWITCH)|| defined(CONFIG_ARCH_ZX297520V3_CPE)
-	ret = gpio_request_one(SLIC_PWR_CTRL, GPIOF_OUT_INIT_HIGH, "slic_pwr");
-	if (ret < 0) {
-		printk(KERN_ERR "slic_tw_probe: slic_pwr in use\n");
-		return ret;
-	}
-	ret = gpio_request_one(SLIC_PWR_CTRL_EN, GPIOF_OUT_INIT_HIGH, "slic_pwr_en");
-	if (ret < 0) {
-		printk(KERN_ERR "slic_tw_probe: slic_pwr_en in use\n");
-		return ret;
-	}
+#ifdef USE_RJ11_PLUG_IN_DETECT
+	msgFirstRun = 1;
 #endif
+#if defined(CONFIG_ARCH_ZX297520V3_CPE_SWITCH)|| defined(CONFIG_ARCH_ZX297520V3_CPE)
+	gpio_direction_output(SLIC_PWR_CTRL, 1);
+	gpio_direction_output(SLIC_PWR_CTRL_EN, 1);
+#endif
+	if(slic_tw != NULL)
+	{
+		slic_probe = true;
+		goto slic_fs;
+	}
 	slic_tw = kzalloc(sizeof(*slic_tw), GFP_KERNEL);
 	if (slic_tw == NULL) {
 		printk("slic_tw_probe slic_tw NULL\n");
 		ret = -ENOMEM;
 		goto out;
 	}
-	slic_tw->spi = spi;
 	ret = register_chrdev(SLIC_TW_MAJOR, SLIC_TW_NAME, &slic_tw_fops);
 	if (ret < 0) {
 		printk("slic_tw_probe:%s can't get major %d\n", SLIC_TW_NAME, SLIC_TW_MAJOR);
@@ -1565,6 +1563,9 @@
 		ret = -1;
 		goto out;
 	}
+	slic_tw->init_flg = 0;
+slic_fs:
+	slic_tw->spi = spi;
 	//dev_set_drvdata(&spi->dev, slic_tw);
     dev_set_drvdata(slic_tw->device, slic_tw);
 
@@ -1579,7 +1580,6 @@
 
 
 
-	slic_tw->init_flg = 0;
 
 	init_waitqueue_head(&msg_wait_queue);
 
@@ -1599,15 +1599,20 @@
 	slic_tw->polling_thread = th;
 	printk("slic create thread poll started\n");
 
-#else
-	hrtimer_init(&slic_tw->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
-	slic_tw->timer.function = handle_alarm;
-	INIT_WORK(&slic_tw->work, slic_get_event);
-#endif
-
+	#else
+	if(!slic_probe)
+	{
+		hrtimer_init(&slic_tw->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
+		slic_tw->timer.function = handle_alarm;
+		INIT_WORK(&slic_tw->work, slic_get_event);
+	}
+	#endif
 	CreatMsgQueue();
-
-	VpSysInit();
+	if(!slic_probe)
+	{
+		VpSysInit();
+	}
+	
 
 #ifdef USE_RJ11_PLUG_IN_DETECT
 	/* init delayed work */
@@ -1616,6 +1621,7 @@
 #endif
 
 	slic_tw->hookoff_flg = 0;
+	printk("slic_tw_probe end\n");
 	return 0;
 
 out:
@@ -1626,12 +1632,19 @@
 {
 	SLIC_TW_DATA *slic_data = container_of(spi, SLIC_TW_DATA, spi);
 	SLIC_DEBUG("slic_tw_remove\n");
-	device_destroy(slic_data->dev_class, MKDEV(SLIC_TW_MAJOR, 0));
-	class_destroy(slic_data->dev_class);
-	unregister_chrdev(SLIC_TW_MAJOR, SLIC_TW_NAME);
-	if (hrtimer_active(&slic_data->timer)) {
-		hrtimer_cancel(&slic_data->timer);
-	}
+	kfree(msg_queue);
+	msg_queue = NULL;
+	// device_destroy(slic_data->dev_class, MKDEV(SLIC_TW_MAJOR, 0));
+	// class_destroy(slic_data->dev_class);
+	// unregister_chrdev(SLIC_TW_MAJOR, SLIC_TW_NAME);
+#ifdef SLIC_USE_THREAD_POLLING
+	kthread_stop(slic_tw->polling_thread);
+	slic_tw->polling_thread = NULL;
+#else
+	// if (hrtimer_active(&slic_data->timer)) {
+	// 	hrtimer_cancel(&slic_data->timer);
+	// }
+#endif
 	//sysfs_remove_group(&(spi->dev.kobj), &slic_attr_grp);
     sysfs_remove_group(&(slic_tw->device->kobj), &slic_attr_grp);
 #ifdef USE_RJ11_PLUG_IN_DETECT
@@ -1639,7 +1652,10 @@
 #endif
     wake_lock_destroy(&slic_wakelock);
     zx_cpuidle_set_free(IDLE_FLAG_SLIC);
-
+#if defined(CONFIG_ARCH_ZX297520V3_CPE_SWITCH)|| defined(CONFIG_ARCH_ZX297520V3_CPE)
+	gpio_direction_output(SLIC_PWR_CTRL, 0);
+	gpio_direction_output(SLIC_PWR_CTRL_EN, 0);
+#endif
 	return 0;
 }
 
@@ -1762,7 +1778,7 @@
 	/* Wait  */
 	//wait_timeout(SLIC_POLLING_INTERVAL);
 
-	for (;;) {
+	while (!kthread_should_stop()) {
 		wait_timeout(SLIC_POLLING_INTERVAL);
 
 		/* lock the device pointers */
@@ -1785,6 +1801,22 @@
 
 	printk("slic_tw_spi_init\n");
 	zx29_i2s_tdm_pin_cfg();
+#if defined(CONFIG_ARCH_ZX297520V3_CPE_SWITCH)|| defined(CONFIG_ARCH_ZX297520V3_CPE)
+	ret = gpio_request(SLIC_PWR_CTRL, "slic_pwr");
+	if (ret < 0) {
+		printk(KERN_ERR "slic_tw_probe: slic_pwr in use\n");
+		gpio_free(SLIC_PWR_CTRL);
+		return ret;
+	}
+	ret = gpio_request(SLIC_PWR_CTRL_EN, "slic_pwr_en");
+	if (ret < 0) {
+		printk(KERN_ERR "slic_tw_probe: slic_pwr_en in use\n");
+		gpio_free(SLIC_PWR_CTRL_EN);
+		return ret;
+	}
+	gpio_direction_output(SLIC_PWR_CTRL, 0);
+	gpio_direction_output(SLIC_PWR_CTRL_EN, 0);
+#endif
 	ret = spi_register_driver(&slic_tw_spi_driver);
 	if (ret != 0) {
 		printk("slic_tw Failed to register slic_tw_spi_driver : %d\n", ret);