[svn-commits] sruffell: linux/trunk r9951 - in /linux/trunk/drivers/dahdi: voicebus/ wctdm2...

SVN commits to the Digium repositories svn-commits at lists.digium.com
Thu Jun 2 15:02:32 CDT 2011


Author: sruffell
Date: Thu Jun  2 15:02:28 2011
New Revision: 9951

URL: http://svnview.digium.com/svn/dahdi?view=rev&rev=9951
Log:
wcte12xp, wctdm24xxp: Separate test for VPMADT032 and initialization.

Part of increasing system startup speed.

Splitting these two operations facilitate checking if there is a module
present synchronously on driver load from the actual load of the firmware and
configuration of the channels.

This will allow the presence of the VPM module to be flagged on the span
before registration, but load and configuration can happen in the background.
When the modules are eventually loaded via udev, there will be enough time
from the time the drivers are loaded to when dahdi_cfg will run to complete
the firmware load, eliminating the need to block the driver here.

Signed-off-by: Shaun Ruffell <sruffell at digium.com>

Modified:
    linux/trunk/drivers/dahdi/voicebus/GpakCust.c
    linux/trunk/drivers/dahdi/voicebus/GpakCust.h
    linux/trunk/drivers/dahdi/wctdm24xxp/base.c
    linux/trunk/drivers/dahdi/wcte12xp/base.c

Modified: linux/trunk/drivers/dahdi/voicebus/GpakCust.c
URL: http://svnview.digium.com/svn/dahdi/linux/trunk/drivers/dahdi/voicebus/GpakCust.c?view=diff&rev=9951&r1=9950&r2=9951
==============================================================================
--- linux/trunk/drivers/dahdi/voicebus/GpakCust.c (original)
+++ linux/trunk/drivers/dahdi/voicebus/GpakCust.c Thu Jun  2 15:02:28 2011
@@ -513,6 +513,11 @@
 	sema_init(&vpm->sem, 1);
 	vpm->curpage = 0x80;
 	vpm->dspid = -1;
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 20)
+	INIT_WORK(&vpm->work, vpmadt032_bh, vpm);
+#else
+	INIT_WORK(&vpm->work, vpmadt032_bh);
+#endif
 
 	/* Do not use the global workqueue for processing these events.  Some of
 	 * the operations can take 100s of ms, most of that time spent sleeping.
@@ -605,36 +610,26 @@
 }
 EXPORT_SYMBOL(vpmadt032_reset);
 
-int
-vpmadt032_init(struct vpmadt032 *vpm, struct voicebus *vb)
-{
-	int i;
-	u16 reg;
-	int res = -EFAULT;
-	unsigned long stoptime;
-	struct device *dev;
-	gpakPingDspStat_t pingstatus;
-
-	BUG_ON(!vpm->setchanconfig_from_state);
-	BUG_ON(!vpm->wq);
-	BUG_ON(!vb);
+/**
+ * vpmadt032_test - Check if there is a VPMADT032 present on voicebus device.
+ * @vpm:	Allocated with vpmadt032_alloc previously.
+ * @vb:		Voicebus structure to test on.
+ *
+ * Returns 0 if there is a device, otherwise -ENODEV.
+ *
+ */
+int vpmadt032_test(struct vpmadt032 *vpm, struct voicebus *vb)
+{
+	u8 reg;
+	int i, x;
+	struct device *dev = &vb->pdev->dev;
 
 	vpm->vb = vb;
 
-	might_sleep();
-
-	dev = &vpm->vb->pdev->dev;
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 20)
-	INIT_WORK(&vpm->work, vpmadt032_bh, vpm);
-#else
-	INIT_WORK(&vpm->work, vpmadt032_bh);
-#endif
 	if (vpm->options.debug & DEBUG_VPMADT032_ECHOCAN)
 		dev_info(dev, "VPMADT032 Testing page access: ");
 
 	for (i = 0; i < 0xf; i++) {
-		int x;
 		for (x = 0; x < 3; x++) {
 			vpmadt032_setpage(vpm, i);
 			reg = vpmadt032_getpage(vpm);
@@ -645,14 +640,42 @@
 						"VPMADT032 Failed HI page " \
 						"test\n", i, reg);
 				}
-				res = -ENODEV;
-				goto failed_exit;
+				return -ENODEV;
 			}
 		}
 	}
 
 	if (vpm->options.debug & DEBUG_VPMADT032_ECHOCAN)
-		dev_info(&vpm->vb->pdev->dev, "Passed\n");
+		dev_info(dev, "Passed\n");
+
+	return 0;
+}
+EXPORT_SYMBOL(vpmadt032_test);
+
+/**
+ * vpmadt032_init - Initialize and load VPMADT032 firmware.
+ * @vpm:	Allocated with vpmadt032_alloc previously.
+ *
+ * Returns 0 on success.  This must be called after vpmadt032_test already
+ * checked if there appears to be a VPMADT032 installed on the board.
+ *
+ */
+int vpmadt032_init(struct vpmadt032 *vpm)
+{
+	int i;
+	u16 reg;
+	int res = -EFAULT;
+	unsigned long stoptime;
+	struct device *dev;
+	gpakPingDspStat_t pingstatus;
+
+	BUG_ON(!vpm->setchanconfig_from_state);
+	BUG_ON(!vpm->wq);
+	BUG_ON(!vpm->vb);
+
+	might_sleep();
+
+	dev = &vpm->vb->pdev->dev;
 
 	stoptime = jiffies + 3*HZ;
 	set_bit(VPM150M_HPIRESET, &vpm->control);
@@ -699,14 +722,14 @@
 		goto failed_exit;
 	}
 
-	res = vpmadtreg_loadfirmware(vb);
+	res = vpmadtreg_loadfirmware(vpm->vb);
 	if (res) {
-		dev_info(&vb->pdev->dev, "Failed to load the firmware.\n");
+		dev_info(&vpm->vb->pdev->dev, "Failed to load the firmware.\n");
 		return res;
 	}
 	vpm->curpage = -1;
 
-	dev_info(&vb->pdev->dev, "Booting VPMADT032\n");
+	dev_info(&vpm->vb->pdev->dev, "Booting VPMADT032\n");
 
 	stoptime = jiffies + 3*HZ;
 	set_bit(VPM150M_SWRESET, &vpm->control);
@@ -723,7 +746,7 @@
 	pingstatus = gpakPingDsp(vpm->dspid, &vpm->version);
 
 	if (!pingstatus) {
-		dev_info(&vb->pdev->dev, "VPM present and operational "
+		dev_info(&vpm->vb->pdev->dev, "VPM present and operational "
 			"(Firmware version %x)\n", vpm->version);
 	} else {
 		dev_notice(&vpm->vb->pdev->dev, "VPMADT032 Failed! Unable to ping the DSP (%d)!\n", pingstatus);

Modified: linux/trunk/drivers/dahdi/voicebus/GpakCust.h
URL: http://svnview.digium.com/svn/dahdi/linux/trunk/drivers/dahdi/voicebus/GpakCust.h?view=diff&rev=9951&r1=9950&r2=9951
==============================================================================
--- linux/trunk/drivers/dahdi/voicebus/GpakCust.h (original)
+++ linux/trunk/drivers/dahdi/voicebus/GpakCust.h Thu Jun  2 15:02:28 2011
@@ -137,7 +137,8 @@
 struct dahdi_echocan_state;
 
 char vpmadt032tone_to_zaptone(GpakToneCodes_t tone);
-int vpmadt032_init(struct vpmadt032 *vpm, struct voicebus *vb);
+int vpmadt032_test(struct vpmadt032 *vpm, struct voicebus *vb);
+int vpmadt032_init(struct vpmadt032 *vpm);
 int vpmadt032_reset(struct vpmadt032 *vpm);
 struct vpmadt032 *vpmadt032_alloc(struct vpmadt032_options *options);
 void vpmadt032_free(struct vpmadt032 *vpm);

Modified: linux/trunk/drivers/dahdi/wctdm24xxp/base.c
URL: http://svnview.digium.com/svn/dahdi/linux/trunk/drivers/dahdi/wctdm24xxp/base.c?view=diff&rev=9951&r1=9950&r2=9951
==============================================================================
--- linux/trunk/drivers/dahdi/wctdm24xxp/base.c (original)
+++ linux/trunk/drivers/dahdi/wctdm24xxp/base.c Thu Jun  2 15:02:28 2011
@@ -3841,7 +3841,9 @@
 	/* wc->vpmadt032->context = wc; */
 	/* Pull the configuration information from the span holding
 	 * the analog channels. */
-	res = vpmadt032_init(wc->vpmadt032, &wc->vb);
+	res = vpmadt032_test(wc->vpmadt032, &wc->vb);
+	if (!res)
+		res = vpmadt032_init(wc->vpmadt032);
 	if (res) {
 		vpmadt032_free(wc->vpmadt032);
 		wc->vpmadt032 = NULL;

Modified: linux/trunk/drivers/dahdi/wcte12xp/base.c
URL: http://svnview.digium.com/svn/dahdi/linux/trunk/drivers/dahdi/wcte12xp/base.c?view=diff&rev=9951&r1=9950&r2=9951
==============================================================================
--- linux/trunk/drivers/dahdi/wcte12xp/base.c (original)
+++ linux/trunk/drivers/dahdi/wcte12xp/base.c Thu Jun  2 15:02:28 2011
@@ -1385,6 +1385,64 @@
 	struct t1 *wc;
 };
 
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 20)
+static void vpm_load_func(void *data)
+{
+	struct maint_work_struct *w = data;
+#else
+static void vpm_load_func(struct work_struct *work)
+{
+	struct vpm_load_work *w = container_of(work,
+					struct vpm_load_work, work);
+#endif
+	struct t1 *wc = w->wc;
+	int res;
+
+	res = vpmadt032_init(wc->vpmadt032);
+	if (res) {
+		/* There was some problem during initialization, but it passed
+		 * the address test, let's try again in a bit. */
+		wc->vpm_check = jiffies + HZ/2;
+		return;
+	}
+
+	if (config_vpmadt032(wc->vpmadt032, wc)) {
+		clear_bit(VPM150M_ACTIVE, &wc->ctlreg);
+		wc->vpm_check = jiffies + HZ/2;
+		return;
+	}
+
+	/* turn on vpm (RX audio from vpm module) */
+	set_bit(VPM150M_ACTIVE, &wc->ctlreg);
+	wc->vpm_check = jiffies + HZ*5;
+	if (vpmtsisupport) {
+		debug_printk(wc, 1, "enabling VPM TSI pin\n");
+		/* turn on vpm timeslot interchange pin */
+		set_bit(0, &wc->ctlreg);
+	}
+
+	set_bit(READY, &wc->bit_flags);
+	kfree(w);
+}
+
+static int vpm_start_load(struct t1 *wc)
+{
+	struct vpm_load_work *work;
+
+	work = kzalloc(sizeof(*work), GFP_KERNEL);
+	if (!work)
+		return -ENOMEM;
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 20)
+	INIT_WORK(&work->work, vpm_load_func, work);
+#else
+	INIT_WORK(&work->work, vpm_load_func);
+#endif
+	work->wc = wc;
+
+	queue_work(wc->wq, &work->work);
+	return 0;
+}
+
 static int check_and_load_vpm(struct t1 *wc)
 {
 	int res;
@@ -1428,7 +1486,7 @@
 	wc->vpmadt032 = vpm;
 	spin_unlock_irqrestore(&wc->reglock, flags);
 
-	res = vpmadt032_init(vpm, &wc->vb);
+	res = vpmadt032_test(vpm, &wc->vb);
 	if (-ENODEV == res) {
 		struct vpmadt032 *vpm = wc->vpmadt032;
 
@@ -1439,30 +1497,19 @@
 		spin_unlock_irqrestore(&wc->reglock, flags);
 		vpmadt032_free(vpm);
 		return res;
-
-	} else if (res) {
-		/* There was some problem during initialization, but it passed
-		 * the address test, let's try again in a bit. */
-		wc->vpm_check = jiffies + HZ/2;
-		return -EAGAIN;
-	}
-
-	if (config_vpmadt032(vpm, wc)) {
+	}
+
+	res = vpm_start_load(wc);
+	if (res) {
+		/* There does not appear to be a VPMADT032 installed. */
 		clear_bit(VPM150M_ACTIVE, &wc->ctlreg);
-		wc->vpm_check = jiffies + HZ/2;
-		return -EAGAIN;
-	}
-
-	/* turn on vpm (RX audio from vpm module) */
-	set_bit(VPM150M_ACTIVE, &wc->ctlreg);
-	wc->vpm_check = jiffies + HZ*5;
-	if (vpmtsisupport) {
-		debug_printk(wc, 1, "enabling VPM TSI pin\n");
-		/* turn on vpm timeslot interchange pin */
-		set_bit(0, &wc->ctlreg);
-	}
-
-	return 0;
+		spin_lock_irqsave(&wc->reglock, flags);
+		wc->vpmadt032 = NULL;
+		spin_unlock_irqrestore(&wc->reglock, flags);
+		vpmadt032_free(vpm);
+		return res;
+	}
+	return res;
 }
 #else
 static inline int check_and_load_vpm(const struct t1 *wc)




More information about the svn-commits mailing list