aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/serial/qcserial.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/serial/qcserial.c')
-rw-r--r--drivers/usb/serial/qcserial.c31
1 files changed, 24 insertions, 7 deletions
diff --git a/drivers/usb/serial/qcserial.c b/drivers/usb/serial/qcserial.c
index 8858201eb1d3..54a9dab1f33b 100644
--- a/drivers/usb/serial/qcserial.c
+++ b/drivers/usb/serial/qcserial.c
@@ -111,7 +111,7 @@ 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;
@@ -134,8 +134,10 @@ static int qcprobe(struct usb_serial *serial, const struct usb_device_id *id)
134 usb_endpoint_is_bulk_out(&intf->endpoint[1].desc)) { 134 usb_endpoint_is_bulk_out(&intf->endpoint[1].desc)) {
135 dbg("QDL port found"); 135 dbg("QDL port found");
136 136
137 if (serial->interface->num_altsetting == 1) 137 if (serial->interface->num_altsetting == 1) {
138 return 0; 138 retval = 0; /* Success */
139 break;
140 }
139 141
140 retval = usb_set_interface(serial->dev, ifnum, 1); 142 retval = usb_set_interface(serial->dev, ifnum, 1);
141 if (retval < 0) { 143 if (retval < 0) {
@@ -145,7 +147,6 @@ static int qcprobe(struct usb_serial *serial, const struct usb_device_id *id)
145 retval = -ENODEV; 147 retval = -ENODEV;
146 kfree(data); 148 kfree(data);
147 } 149 }
148 return retval;
149 } 150 }
150 break; 151 break;
151 152
@@ -166,6 +167,7 @@ static int qcprobe(struct usb_serial *serial, const struct usb_device_id *id)
166 "Could not set interface, error %d\n", 167 "Could not set interface, error %d\n",
167 retval); 168 retval);
168 retval = -ENODEV; 169 retval = -ENODEV;
170 kfree(data);
169 } 171 }
170 } else if (ifnum == 2) { 172 } else if (ifnum == 2) {
171 dbg("Modem port found"); 173 dbg("Modem port found");
@@ -177,7 +179,6 @@ static int qcprobe(struct usb_serial *serial, const struct usb_device_id *id)
177 retval = -ENODEV; 179 retval = -ENODEV;
178 kfree(data); 180 kfree(data);
179 } 181 }
180 return retval;
181 } else if (ifnum==3) { 182 } else if (ifnum==3) {
182 /* 183 /*
183 * NMEA (serial line 9600 8N1) 184 * NMEA (serial line 9600 8N1)
@@ -191,6 +192,7 @@ static int qcprobe(struct usb_serial *serial, const struct usb_device_id *id)
191 "Could not set interface, error %d\n", 192 "Could not set interface, error %d\n",
192 retval); 193 retval);
193 retval = -ENODEV; 194 retval = -ENODEV;
195 kfree(data);
194 } 196 }
195 } 197 }
196 break; 198 break;
@@ -199,12 +201,27 @@ static int qcprobe(struct usb_serial *serial, const struct usb_device_id *id)
199 dev_err(&serial->dev->dev, 201 dev_err(&serial->dev->dev,
200 "unknown number of interfaces: %d\n", nintf); 202 "unknown number of interfaces: %d\n", nintf);
201 kfree(data); 203 kfree(data);
202 return -ENODEV; 204 retval = -ENODEV;
203 } 205 }
204 206
207 /* Set serial->private if not returning -ENODEV */
208 if (retval != -ENODEV)
209 usb_set_serial_data(serial, data);
205 return retval; 210 return retval;
206} 211}
207 212
213static 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
208static struct usb_serial_driver qcdevice = { 225static struct usb_serial_driver qcdevice = {
209 .driver = { 226 .driver = {
210 .owner = THIS_MODULE, 227 .owner = THIS_MODULE,
@@ -222,7 +239,7 @@ static struct usb_serial_driver qcdevice = {
222 .chars_in_buffer = usb_wwan_chars_in_buffer, 239 .chars_in_buffer = usb_wwan_chars_in_buffer,
223 .attach = usb_wwan_startup, 240 .attach = usb_wwan_startup,
224 .disconnect = usb_wwan_disconnect, 241 .disconnect = usb_wwan_disconnect,
225 .release = usb_wwan_release, 242 .release = qc_release,
226#ifdef CONFIG_PM 243#ifdef CONFIG_PM
227 .suspend = usb_wwan_suspend, 244 .suspend = usb_wwan_suspend,
228 .resume = usb_wwan_resume, 245 .resume = usb_wwan_resume,