diff options
author | Glenn Elliott <gelliott@cs.unc.edu> | 2012-03-04 19:47:13 -0500 |
---|---|---|
committer | Glenn Elliott <gelliott@cs.unc.edu> | 2012-03-04 19:47:13 -0500 |
commit | c71c03bda1e86c9d5198c5d83f712e695c4f2a1e (patch) | |
tree | ecb166cb3e2b7e2adb3b5e292245fefd23381ac8 /drivers/usb/serial/qcserial.c | |
parent | ea53c912f8a86a8567697115b6a0d8152beee5c8 (diff) | |
parent | 6a00f206debf8a5c8899055726ad127dbeeed098 (diff) |
Merge branch 'mpi-master' into wip-k-fmlpwip-k-fmlp
Conflicts:
litmus/sched_cedf.c
Diffstat (limited to 'drivers/usb/serial/qcserial.c')
-rw-r--r-- | drivers/usb/serial/qcserial.c | 64 |
1 files changed, 56 insertions, 8 deletions
diff --git a/drivers/usb/serial/qcserial.c b/drivers/usb/serial/qcserial.c index cde67cacb2c3..54a9dab1f33b 100644 --- a/drivers/usb/serial/qcserial.c +++ b/drivers/usb/serial/qcserial.c | |||
@@ -111,13 +111,15 @@ static int qcprobe(struct usb_serial *serial, const struct usb_device_id *id) | |||
111 | ifnum = intf->desc.bInterfaceNumber; | 111 | ifnum = intf->desc.bInterfaceNumber; |
112 | dbg("This Interface = %d", ifnum); | 112 | dbg("This Interface = %d", ifnum); |
113 | 113 | ||
114 | data = serial->private = kzalloc(sizeof(struct usb_wwan_intf_private), | 114 | data = kzalloc(sizeof(struct usb_wwan_intf_private), |
115 | GFP_KERNEL); | 115 | GFP_KERNEL); |
116 | if (!data) | 116 | if (!data) |
117 | return -ENOMEM; | 117 | return -ENOMEM; |
118 | 118 | ||
119 | spin_lock_init(&data->susp_lock); | 119 | spin_lock_init(&data->susp_lock); |
120 | 120 | ||
121 | usb_enable_autosuspend(serial->dev); | ||
122 | |||
121 | switch (nintf) { | 123 | switch (nintf) { |
122 | case 1: | 124 | case 1: |
123 | /* QDL mode */ | 125 | /* QDL mode */ |
@@ -132,8 +134,10 @@ static int qcprobe(struct usb_serial *serial, const struct usb_device_id *id) | |||
132 | usb_endpoint_is_bulk_out(&intf->endpoint[1].desc)) { | 134 | usb_endpoint_is_bulk_out(&intf->endpoint[1].desc)) { |
133 | dbg("QDL port found"); | 135 | dbg("QDL port found"); |
134 | 136 | ||
135 | if (serial->interface->num_altsetting == 1) | 137 | if (serial->interface->num_altsetting == 1) { |
136 | return 0; | 138 | retval = 0; /* Success */ |
139 | break; | ||
140 | } | ||
137 | 141 | ||
138 | retval = usb_set_interface(serial->dev, ifnum, 1); | 142 | retval = usb_set_interface(serial->dev, ifnum, 1); |
139 | if (retval < 0) { | 143 | if (retval < 0) { |
@@ -143,14 +147,29 @@ static int qcprobe(struct usb_serial *serial, const struct usb_device_id *id) | |||
143 | retval = -ENODEV; | 147 | retval = -ENODEV; |
144 | kfree(data); | 148 | kfree(data); |
145 | } | 149 | } |
146 | return retval; | ||
147 | } | 150 | } |
148 | break; | 151 | break; |
149 | 152 | ||
150 | case 3: | 153 | case 3: |
151 | case 4: | 154 | case 4: |
152 | /* Composite mode */ | 155 | /* Composite mode */ |
153 | if (ifnum == 2) { | 156 | /* ifnum == 0 is a broadband network adapter */ |
157 | if (ifnum == 1) { | ||
158 | /* | ||
159 | * Diagnostics Monitor (serial line 9600 8N1) | ||
160 | * Qualcomm DM protocol | ||
161 | * use "libqcdm" (ModemManager) for communication | ||
162 | */ | ||
163 | dbg("Diagnostics Monitor found"); | ||
164 | retval = usb_set_interface(serial->dev, ifnum, 0); | ||
165 | if (retval < 0) { | ||
166 | dev_err(&serial->dev->dev, | ||
167 | "Could not set interface, error %d\n", | ||
168 | retval); | ||
169 | retval = -ENODEV; | ||
170 | kfree(data); | ||
171 | } | ||
172 | } else if (ifnum == 2) { | ||
154 | dbg("Modem port found"); | 173 | dbg("Modem port found"); |
155 | retval = usb_set_interface(serial->dev, ifnum, 0); | 174 | retval = usb_set_interface(serial->dev, ifnum, 0); |
156 | if (retval < 0) { | 175 | if (retval < 0) { |
@@ -160,7 +179,21 @@ static int qcprobe(struct usb_serial *serial, const struct usb_device_id *id) | |||
160 | retval = -ENODEV; | 179 | retval = -ENODEV; |
161 | kfree(data); | 180 | kfree(data); |
162 | } | 181 | } |
163 | return retval; | 182 | } else if (ifnum==3) { |
183 | /* | ||
184 | * NMEA (serial line 9600 8N1) | ||
185 | * # echo "\$GPS_START" > /dev/ttyUSBx | ||
186 | * # echo "\$GPS_STOP" > /dev/ttyUSBx | ||
187 | */ | ||
188 | dbg("NMEA GPS interface found"); | ||
189 | retval = usb_set_interface(serial->dev, ifnum, 0); | ||
190 | if (retval < 0) { | ||
191 | dev_err(&serial->dev->dev, | ||
192 | "Could not set interface, error %d\n", | ||
193 | retval); | ||
194 | retval = -ENODEV; | ||
195 | kfree(data); | ||
196 | } | ||
164 | } | 197 | } |
165 | break; | 198 | break; |
166 | 199 | ||
@@ -168,12 +201,27 @@ static int qcprobe(struct usb_serial *serial, const struct usb_device_id *id) | |||
168 | dev_err(&serial->dev->dev, | 201 | dev_err(&serial->dev->dev, |
169 | "unknown number of interfaces: %d\n", nintf); | 202 | "unknown number of interfaces: %d\n", nintf); |
170 | kfree(data); | 203 | kfree(data); |
171 | return -ENODEV; | 204 | retval = -ENODEV; |
172 | } | 205 | } |
173 | 206 | ||
207 | /* Set serial->private if not returning -ENODEV */ | ||
208 | if (retval != -ENODEV) | ||
209 | usb_set_serial_data(serial, data); | ||
174 | return retval; | 210 | return retval; |
175 | } | 211 | } |
176 | 212 | ||
213 | static void qc_release(struct usb_serial *serial) | ||
214 | { | ||
215 | struct usb_wwan_intf_private *priv = usb_get_serial_data(serial); | ||
216 | |||
217 | dbg("%s", __func__); | ||
218 | |||
219 | /* Call usb_wwan release & free the private data allocated in qcprobe */ | ||
220 | usb_wwan_release(serial); | ||
221 | usb_set_serial_data(serial, NULL); | ||
222 | kfree(priv); | ||
223 | } | ||
224 | |||
177 | static struct usb_serial_driver qcdevice = { | 225 | static struct usb_serial_driver qcdevice = { |
178 | .driver = { | 226 | .driver = { |
179 | .owner = THIS_MODULE, | 227 | .owner = THIS_MODULE, |
@@ -191,7 +239,7 @@ static struct usb_serial_driver qcdevice = { | |||
191 | .chars_in_buffer = usb_wwan_chars_in_buffer, | 239 | .chars_in_buffer = usb_wwan_chars_in_buffer, |
192 | .attach = usb_wwan_startup, | 240 | .attach = usb_wwan_startup, |
193 | .disconnect = usb_wwan_disconnect, | 241 | .disconnect = usb_wwan_disconnect, |
194 | .release = usb_wwan_release, | 242 | .release = qc_release, |
195 | #ifdef CONFIG_PM | 243 | #ifdef CONFIG_PM |
196 | .suspend = usb_wwan_suspend, | 244 | .suspend = usb_wwan_suspend, |
197 | .resume = usb_wwan_resume, | 245 | .resume = usb_wwan_resume, |