aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-06-02 19:55:18 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2014-06-02 19:55:18 -0400
commitda579dd6a180693368ade74b3ac38701d35f686e (patch)
tree21d02a66dd18ee9d902a2e9ee38c928586cb0feb /drivers
parentfad01e866afdbe01a1f3ec06a39c3a8b9e197014 (diff)
parent9326c5ca0982f548cc08c0cffb14dcbd020f3d43 (diff)
Merge tag 'staging-3.15-rc8' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging
Pull staging driver fixes from Greg KH: "Here are some staging driver fixes for 3.15. Three are for the speakup drivers (one fixes a regression caused in 3.15-rc, and the other two resolve a tty issue found by Ben Hutchings) The comedi and r8192e_pci driver fixes also resolve reported issues" * tag 'staging-3.15-rc8' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging: staging: r8192e_pci: fix htons error Staging: speakup: Update __speakup_paste_selection() tty (ab)usage to match vt Staging: speakup: Move pasting into a work item staging: comedi: ni_daq_700: add mux settling delay speakup: fix incorrect perms on speakup_acntsa.c
Diffstat (limited to 'drivers')
-rw-r--r--drivers/staging/comedi/drivers/ni_daq_700.c2
-rw-r--r--drivers/staging/rtl8192e/rtllib_tx.c2
-rw-r--r--drivers/staging/speakup/main.c1
-rw-r--r--drivers/staging/speakup/selection.c52
-rw-r--r--drivers/staging/speakup/speakup.h1
-rw-r--r--drivers/staging/speakup/speakup_acntsa.c8
-rw-r--r--drivers/tty/tty_buffer.c2
7 files changed, 54 insertions, 14 deletions
diff --git a/drivers/staging/comedi/drivers/ni_daq_700.c b/drivers/staging/comedi/drivers/ni_daq_700.c
index 171a71d20c88..728bf7f14f7b 100644
--- a/drivers/staging/comedi/drivers/ni_daq_700.c
+++ b/drivers/staging/comedi/drivers/ni_daq_700.c
@@ -139,6 +139,8 @@ static int daq700_ai_rinsn(struct comedi_device *dev,
139 /* write channel to multiplexer */ 139 /* write channel to multiplexer */
140 /* set mask scan bit high to disable scanning */ 140 /* set mask scan bit high to disable scanning */
141 outb(chan | 0x80, dev->iobase + CMD_R1); 141 outb(chan | 0x80, dev->iobase + CMD_R1);
142 /* mux needs 2us to really settle [Fred Brooks]. */
143 udelay(2);
142 144
143 /* convert n samples */ 145 /* convert n samples */
144 for (n = 0; n < insn->n; n++) { 146 for (n = 0; n < insn->n; n++) {
diff --git a/drivers/staging/rtl8192e/rtllib_tx.c b/drivers/staging/rtl8192e/rtllib_tx.c
index 11d0a9d8ee59..b7dd1539bbc4 100644
--- a/drivers/staging/rtl8192e/rtllib_tx.c
+++ b/drivers/staging/rtl8192e/rtllib_tx.c
@@ -171,7 +171,7 @@ inline int rtllib_put_snap(u8 *data, u16 h_proto)
171 snap->oui[1] = oui[1]; 171 snap->oui[1] = oui[1];
172 snap->oui[2] = oui[2]; 172 snap->oui[2] = oui[2];
173 173
174 *(u16 *)(data + SNAP_SIZE) = h_proto; 174 *(__be16 *)(data + SNAP_SIZE) = htons(h_proto);
175 175
176 return SNAP_SIZE + sizeof(u16); 176 return SNAP_SIZE + sizeof(u16);
177} 177}
diff --git a/drivers/staging/speakup/main.c b/drivers/staging/speakup/main.c
index 3b6e5358c723..7de79d59a4cd 100644
--- a/drivers/staging/speakup/main.c
+++ b/drivers/staging/speakup/main.c
@@ -2218,6 +2218,7 @@ static void __exit speakup_exit(void)
2218 unregister_keyboard_notifier(&keyboard_notifier_block); 2218 unregister_keyboard_notifier(&keyboard_notifier_block);
2219 unregister_vt_notifier(&vt_notifier_block); 2219 unregister_vt_notifier(&vt_notifier_block);
2220 speakup_unregister_devsynth(); 2220 speakup_unregister_devsynth();
2221 speakup_cancel_paste();
2221 del_timer(&cursor_timer); 2222 del_timer(&cursor_timer);
2222 kthread_stop(speakup_task); 2223 kthread_stop(speakup_task);
2223 speakup_task = NULL; 2224 speakup_task = NULL;
diff --git a/drivers/staging/speakup/selection.c b/drivers/staging/speakup/selection.c
index f0fb00392d6b..ca04d3669acc 100644
--- a/drivers/staging/speakup/selection.c
+++ b/drivers/staging/speakup/selection.c
@@ -4,6 +4,10 @@
4#include <linux/sched.h> 4#include <linux/sched.h>
5#include <linux/device.h> /* for dev_warn */ 5#include <linux/device.h> /* for dev_warn */
6#include <linux/selection.h> 6#include <linux/selection.h>
7#include <linux/workqueue.h>
8#include <linux/tty.h>
9#include <linux/tty_flip.h>
10#include <asm/cmpxchg.h>
7 11
8#include "speakup.h" 12#include "speakup.h"
9 13
@@ -121,31 +125,61 @@ int speakup_set_selection(struct tty_struct *tty)
121 return 0; 125 return 0;
122} 126}
123 127
124/* TODO: move to some helper thread, probably. That'd fix having to check for 128struct speakup_paste_work {
125 * in_atomic(). */ 129 struct work_struct work;
126int speakup_paste_selection(struct tty_struct *tty) 130 struct tty_struct *tty;
131};
132
133static void __speakup_paste_selection(struct work_struct *work)
127{ 134{
135 struct speakup_paste_work *spw =
136 container_of(work, struct speakup_paste_work, work);
137 struct tty_struct *tty = xchg(&spw->tty, NULL);
128 struct vc_data *vc = (struct vc_data *) tty->driver_data; 138 struct vc_data *vc = (struct vc_data *) tty->driver_data;
129 int pasted = 0, count; 139 int pasted = 0, count;
140 struct tty_ldisc *ld;
130 DECLARE_WAITQUEUE(wait, current); 141 DECLARE_WAITQUEUE(wait, current);
142
143 ld = tty_ldisc_ref_wait(tty);
144 tty_buffer_lock_exclusive(&vc->port);
145
131 add_wait_queue(&vc->paste_wait, &wait); 146 add_wait_queue(&vc->paste_wait, &wait);
132 while (sel_buffer && sel_buffer_lth > pasted) { 147 while (sel_buffer && sel_buffer_lth > pasted) {
133 set_current_state(TASK_INTERRUPTIBLE); 148 set_current_state(TASK_INTERRUPTIBLE);
134 if (test_bit(TTY_THROTTLED, &tty->flags)) { 149 if (test_bit(TTY_THROTTLED, &tty->flags)) {
135 if (in_atomic())
136 /* if we are in an interrupt handler, abort */
137 break;
138 schedule(); 150 schedule();
139 continue; 151 continue;
140 } 152 }
141 count = sel_buffer_lth - pasted; 153 count = sel_buffer_lth - pasted;
142 count = min_t(int, count, tty->receive_room); 154 count = tty_ldisc_receive_buf(ld, sel_buffer + pasted, NULL,
143 tty->ldisc->ops->receive_buf(tty, sel_buffer + pasted, 155 count);
144 NULL, count);
145 pasted += count; 156 pasted += count;
146 } 157 }
147 remove_wait_queue(&vc->paste_wait, &wait); 158 remove_wait_queue(&vc->paste_wait, &wait);
148 current->state = TASK_RUNNING; 159 current->state = TASK_RUNNING;
160
161 tty_buffer_unlock_exclusive(&vc->port);
162 tty_ldisc_deref(ld);
163 tty_kref_put(tty);
164}
165
166static struct speakup_paste_work speakup_paste_work = {
167 .work = __WORK_INITIALIZER(speakup_paste_work.work,
168 __speakup_paste_selection)
169};
170
171int speakup_paste_selection(struct tty_struct *tty)
172{
173 if (cmpxchg(&speakup_paste_work.tty, NULL, tty) != NULL)
174 return -EBUSY;
175
176 tty_kref_get(tty);
177 schedule_work_on(WORK_CPU_UNBOUND, &speakup_paste_work.work);
149 return 0; 178 return 0;
150} 179}
151 180
181void speakup_cancel_paste(void)
182{
183 cancel_work_sync(&speakup_paste_work.work);
184 tty_kref_put(speakup_paste_work.tty);
185}
diff --git a/drivers/staging/speakup/speakup.h b/drivers/staging/speakup/speakup.h
index a7bcceec436a..898dce5e1243 100644
--- a/drivers/staging/speakup/speakup.h
+++ b/drivers/staging/speakup/speakup.h
@@ -75,6 +75,7 @@ extern void synth_buffer_clear(void);
75extern void speakup_clear_selection(void); 75extern void speakup_clear_selection(void);
76extern int speakup_set_selection(struct tty_struct *tty); 76extern int speakup_set_selection(struct tty_struct *tty);
77extern int speakup_paste_selection(struct tty_struct *tty); 77extern int speakup_paste_selection(struct tty_struct *tty);
78extern void speakup_cancel_paste(void);
78extern void speakup_register_devsynth(void); 79extern void speakup_register_devsynth(void);
79extern void speakup_unregister_devsynth(void); 80extern void speakup_unregister_devsynth(void);
80extern void synth_write(const char *buf, size_t count); 81extern void synth_write(const char *buf, size_t count);
diff --git a/drivers/staging/speakup/speakup_acntsa.c b/drivers/staging/speakup/speakup_acntsa.c
index c7f014ed9628..5079dbd5d7ad 100644
--- a/drivers/staging/speakup/speakup_acntsa.c
+++ b/drivers/staging/speakup/speakup_acntsa.c
@@ -60,15 +60,15 @@ static struct kobj_attribute vol_attribute =
60 __ATTR(vol, S_IWUGO|S_IRUGO, spk_var_show, spk_var_store); 60 __ATTR(vol, S_IWUGO|S_IRUGO, spk_var_show, spk_var_store);
61 61
62static struct kobj_attribute delay_time_attribute = 62static struct kobj_attribute delay_time_attribute =
63 __ATTR(delay_time, S_IRUSR|S_IRUGO, spk_var_show, spk_var_store); 63 __ATTR(delay_time, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store);
64static struct kobj_attribute direct_attribute = 64static struct kobj_attribute direct_attribute =
65 __ATTR(direct, S_IWUGO|S_IRUGO, spk_var_show, spk_var_store); 65 __ATTR(direct, S_IWUGO|S_IRUGO, spk_var_show, spk_var_store);
66static struct kobj_attribute full_time_attribute = 66static struct kobj_attribute full_time_attribute =
67 __ATTR(full_time, S_IRUSR|S_IRUGO, spk_var_show, spk_var_store); 67 __ATTR(full_time, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store);
68static struct kobj_attribute jiffy_delta_attribute = 68static struct kobj_attribute jiffy_delta_attribute =
69 __ATTR(jiffy_delta, S_IRUSR|S_IRUGO, spk_var_show, spk_var_store); 69 __ATTR(jiffy_delta, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store);
70static struct kobj_attribute trigger_time_attribute = 70static struct kobj_attribute trigger_time_attribute =
71 __ATTR(trigger_time, S_IRUSR|S_IRUGO, spk_var_show, spk_var_store); 71 __ATTR(trigger_time, S_IWUSR|S_IRUGO, spk_var_show, spk_var_store);
72 72
73/* 73/*
74 * Create a group of attributes so that we can create and destroy them all 74 * Create a group of attributes so that we can create and destroy them all
diff --git a/drivers/tty/tty_buffer.c b/drivers/tty/tty_buffer.c
index cf78d1985cd8..143deb62467d 100644
--- a/drivers/tty/tty_buffer.c
+++ b/drivers/tty/tty_buffer.c
@@ -60,6 +60,7 @@ void tty_buffer_lock_exclusive(struct tty_port *port)
60 atomic_inc(&buf->priority); 60 atomic_inc(&buf->priority);
61 mutex_lock(&buf->lock); 61 mutex_lock(&buf->lock);
62} 62}
63EXPORT_SYMBOL_GPL(tty_buffer_lock_exclusive);
63 64
64void tty_buffer_unlock_exclusive(struct tty_port *port) 65void tty_buffer_unlock_exclusive(struct tty_port *port)
65{ 66{
@@ -73,6 +74,7 @@ void tty_buffer_unlock_exclusive(struct tty_port *port)
73 if (restart) 74 if (restart)
74 queue_work(system_unbound_wq, &buf->work); 75 queue_work(system_unbound_wq, &buf->work);
75} 76}
77EXPORT_SYMBOL_GPL(tty_buffer_unlock_exclusive);
76 78
77/** 79/**
78 * tty_buffer_space_avail - return unused buffer space 80 * tty_buffer_space_avail - return unused buffer space