summaryrefslogtreecommitdiff
path: root/drivers/dahdi/wcte12xp/base.c
diff options
context:
space:
mode:
authorShaun Ruffell <sruffell@digium.com>2011-06-02 20:02:28 +0000
committerShaun Ruffell <sruffell@digium.com>2011-06-02 20:02:28 +0000
commitb7fc6dac6f4931514221a5ee75e5db28851d08fe (patch)
treea94bcbcda3abb709659fe9a75b6d8600978f0d33 /drivers/dahdi/wcte12xp/base.c
parent87c911c8248a41c5e57bd7c19dad106a1b30d531 (diff)
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@digium.com> git-svn-id: http://svn.asterisk.org/svn/dahdi/linux/trunk@9951 a0bf4364-ded3-4de4-8d8a-66a801d63aff
Diffstat (limited to 'drivers/dahdi/wcte12xp/base.c')
-rw-r--r--drivers/dahdi/wcte12xp/base.c89
1 files changed, 68 insertions, 21 deletions
diff --git a/drivers/dahdi/wcte12xp/base.c b/drivers/dahdi/wcte12xp/base.c
index 8698461..6ffb8ba 100644
--- a/drivers/dahdi/wcte12xp/base.c
+++ b/drivers/dahdi/wcte12xp/base.c
@@ -1385,6 +1385,64 @@ struct vpm_load_work {
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 @@ static int check_and_load_vpm(struct t1 *wc)
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 @@ static int check_and_load_vpm(struct t1 *wc)
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);
+ spin_lock_irqsave(&wc->reglock, flags);
+ wc->vpmadt032 = NULL;
+ spin_unlock_irqrestore(&wc->reglock, flags);
+ vpmadt032_free(vpm);
+ return res;
}
-
- return 0;
+ return res;
}
#else
static inline int check_and_load_vpm(const struct t1 *wc)