diff options
author | Antti Palosaari <crope@iki.fi> | 2012-06-19 21:21:34 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2012-08-04 06:56:37 -0400 |
commit | 41a0abf7100928b412be4d35d62fd77c83064a9b (patch) | |
tree | 8787aba8c9b6860c8315ebf49d596bb027e3cf92 /drivers/media/dvb | |
parent | 62a5f449cab52a458120ba5b046675ee2f81000f (diff) |
[media] dvb_usb_v2: merge files dvb_usb_init.c and dvb_usb_dvb.c
Merge files dvb_usb_init.c and dvb_usb_dvb.c to dvb_usb_core.c.
It is still under 1000 lines of code after all the optimization
so put it one file.
Signed-off-by: Antti Palosaari <crope@iki.fi>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/dvb')
-rw-r--r-- | drivers/media/dvb/dvb-usb/Makefile | 2 | ||||
-rw-r--r-- | drivers/media/dvb/dvb-usb/dvb_usb_common.h | 12 | ||||
-rw-r--r-- | drivers/media/dvb/dvb-usb/dvb_usb_core.c (renamed from drivers/media/dvb/dvb-usb/dvb_usb_init.c) | 442 |
3 files changed, 419 insertions, 37 deletions
diff --git a/drivers/media/dvb/dvb-usb/Makefile b/drivers/media/dvb/dvb-usb/Makefile index 490e2a295f3f..50f506e0632a 100644 --- a/drivers/media/dvb/dvb-usb/Makefile +++ b/drivers/media/dvb/dvb-usb/Makefile | |||
@@ -1,7 +1,7 @@ | |||
1 | dvb-usb-objs = dvb-usb-firmware.o dvb-usb-init.o dvb-usb-urb.o dvb-usb-i2c.o dvb-usb-dvb.o dvb-usb-remote.o usb-urb.o | 1 | dvb-usb-objs = dvb-usb-firmware.o dvb-usb-init.o dvb-usb-urb.o dvb-usb-i2c.o dvb-usb-dvb.o dvb-usb-remote.o usb-urb.o |
2 | obj-$(CONFIG_DVB_USB) += dvb-usb.o | 2 | obj-$(CONFIG_DVB_USB) += dvb-usb.o |
3 | 3 | ||
4 | dvb_usbv2-objs = dvb_usb_init.o dvb_usb_urb.o dvb_usb_dvb.o usb_urb.o | 4 | dvb_usbv2-objs = dvb_usb_core.o dvb_usb_urb.o usb_urb.o |
5 | obj-$(CONFIG_DVB_USB_V2) += dvb_usbv2.o | 5 | obj-$(CONFIG_DVB_USB_V2) += dvb_usbv2.o |
6 | 6 | ||
7 | obj-$(CONFIG_DVB_USB_FIRMWARE) += dvb_usb_firmware.o | 7 | obj-$(CONFIG_DVB_USB_FIRMWARE) += dvb_usb_firmware.o |
diff --git a/drivers/media/dvb/dvb-usb/dvb_usb_common.h b/drivers/media/dvb/dvb-usb/dvb_usb_common.h index c94a900c3264..80c8bd3079c5 100644 --- a/drivers/media/dvb/dvb-usb/dvb_usb_common.h +++ b/drivers/media/dvb/dvb-usb/dvb_usb_common.h | |||
@@ -11,11 +11,7 @@ | |||
11 | 11 | ||
12 | #include "dvb_usb.h" | 12 | #include "dvb_usb.h" |
13 | 13 | ||
14 | extern int dvb_usbv2_disable_rc_polling; | ||
15 | |||
16 | /* commonly used methods */ | 14 | /* commonly used methods */ |
17 | extern int dvb_usbv2_device_power_ctrl(struct dvb_usb_device *d, int onoff); | ||
18 | |||
19 | extern int usb_urb_initv2(struct usb_data_stream *stream, | 15 | extern int usb_urb_initv2(struct usb_data_stream *stream, |
20 | const struct usb_data_stream_properties *props); | 16 | const struct usb_data_stream_properties *props); |
21 | extern int usb_urb_exitv2(struct usb_data_stream *stream); | 17 | extern int usb_urb_exitv2(struct usb_data_stream *stream); |
@@ -23,12 +19,4 @@ extern int usb_urb_submitv2(struct usb_data_stream *stream, | |||
23 | struct usb_data_stream_properties *props); | 19 | struct usb_data_stream_properties *props); |
24 | extern int usb_urb_killv2(struct usb_data_stream *stream); | 20 | extern int usb_urb_killv2(struct usb_data_stream *stream); |
25 | 21 | ||
26 | extern int dvb_usbv2_adapter_stream_init(struct dvb_usb_adapter *adap); | ||
27 | extern int dvb_usbv2_adapter_stream_exit(struct dvb_usb_adapter *adap); | ||
28 | |||
29 | extern int dvb_usbv2_adapter_dvb_init(struct dvb_usb_adapter *adap); | ||
30 | extern int dvb_usbv2_adapter_dvb_exit(struct dvb_usb_adapter *adap); | ||
31 | extern int dvb_usbv2_adapter_frontend_init(struct dvb_usb_adapter *adap); | ||
32 | extern int dvb_usbv2_adapter_frontend_exit(struct dvb_usb_adapter *adap); | ||
33 | |||
34 | #endif | 22 | #endif |
diff --git a/drivers/media/dvb/dvb-usb/dvb_usb_init.c b/drivers/media/dvb/dvb-usb/dvb_usb_core.c index 1d92d831ab27..f3e1ec2c473e 100644 --- a/drivers/media/dvb/dvb-usb/dvb_usb_init.c +++ b/drivers/media/dvb/dvb-usb/dvb_usb_core.c | |||
@@ -200,6 +200,424 @@ static int dvb_usbv2_remote_exit(struct dvb_usb_device *d) | |||
200 | return 0; | 200 | return 0; |
201 | } | 201 | } |
202 | 202 | ||
203 | static void dvb_usb_data_complete(struct usb_data_stream *stream, u8 *buf, | ||
204 | size_t len) | ||
205 | { | ||
206 | struct dvb_usb_adapter *adap = stream->user_priv; | ||
207 | dvb_dmx_swfilter(&adap->demux, buf, len); | ||
208 | } | ||
209 | |||
210 | static void dvb_usb_data_complete_204(struct usb_data_stream *stream, u8 *buf, | ||
211 | size_t len) | ||
212 | { | ||
213 | struct dvb_usb_adapter *adap = stream->user_priv; | ||
214 | dvb_dmx_swfilter_204(&adap->demux, buf, len); | ||
215 | } | ||
216 | |||
217 | static void dvb_usb_data_complete_raw(struct usb_data_stream *stream, u8 *buf, | ||
218 | size_t len) | ||
219 | { | ||
220 | struct dvb_usb_adapter *adap = stream->user_priv; | ||
221 | dvb_dmx_swfilter_raw(&adap->demux, buf, len); | ||
222 | } | ||
223 | |||
224 | int dvb_usbv2_adapter_stream_init(struct dvb_usb_adapter *adap) | ||
225 | { | ||
226 | pr_debug("%s: adap=%d\n", __func__, adap->id); | ||
227 | |||
228 | adap->stream.udev = adap_to_d(adap)->udev; | ||
229 | adap->stream.user_priv = adap; | ||
230 | adap->stream.complete = dvb_usb_data_complete; | ||
231 | |||
232 | return usb_urb_initv2(&adap->stream, &adap->props->stream); | ||
233 | } | ||
234 | |||
235 | int dvb_usbv2_adapter_stream_exit(struct dvb_usb_adapter *adap) | ||
236 | { | ||
237 | pr_debug("%s: adap=%d\n", __func__, adap->id); | ||
238 | usb_urb_exitv2(&adap->stream); | ||
239 | |||
240 | return 0; | ||
241 | } | ||
242 | |||
243 | static inline int dvb_usb_ctrl_feed(struct dvb_demux_feed *dvbdmxfeed, | ||
244 | int count) | ||
245 | { | ||
246 | struct dvb_usb_adapter *adap = dvbdmxfeed->demux->priv; | ||
247 | struct dvb_usb_device *d = adap_to_d(adap); | ||
248 | int ret; | ||
249 | pr_debug("%s: adap=%d active_fe=%d feed_type=%d setting pid [%s]: " \ | ||
250 | "%04x (%04d) at index %d '%s'\n", __func__, adap->id, | ||
251 | adap->active_fe, dvbdmxfeed->type, | ||
252 | adap->pid_filtering ? "yes" : "no", dvbdmxfeed->pid, | ||
253 | dvbdmxfeed->pid, dvbdmxfeed->index, | ||
254 | (count == 1) ? "on" : "off"); | ||
255 | |||
256 | if (adap->active_fe == -1) | ||
257 | return -EINVAL; | ||
258 | |||
259 | adap->feed_count += count; | ||
260 | |||
261 | /* stop feeding if it is last pid */ | ||
262 | if (adap->feed_count == 0) { | ||
263 | pr_debug("%s: stop feeding\n", __func__); | ||
264 | usb_urb_killv2(&adap->stream); | ||
265 | |||
266 | if (d->props->streaming_ctrl) { | ||
267 | ret = d->props->streaming_ctrl(adap, 0); | ||
268 | if (ret < 0) { | ||
269 | pr_err("%s: streaming_ctrl() failed=%d\n", | ||
270 | KBUILD_MODNAME, ret); | ||
271 | goto err_mutex_unlock; | ||
272 | } | ||
273 | } | ||
274 | mutex_unlock(&adap->sync_mutex); | ||
275 | } | ||
276 | |||
277 | /* activate the pid on the device pid filter */ | ||
278 | if (adap->props->caps & DVB_USB_ADAP_HAS_PID_FILTER && | ||
279 | adap->pid_filtering && | ||
280 | adap->props->pid_filter) | ||
281 | ret = adap->props->pid_filter(adap, dvbdmxfeed->index, | ||
282 | dvbdmxfeed->pid, (count == 1) ? 1 : 0); | ||
283 | if (ret < 0) | ||
284 | pr_err("%s: pid_filter() failed=%d\n", | ||
285 | KBUILD_MODNAME, ret); | ||
286 | |||
287 | /* start feeding if it is first pid */ | ||
288 | if (adap->feed_count == 1 && count == 1) { | ||
289 | struct usb_data_stream_properties stream_props; | ||
290 | mutex_lock(&adap->sync_mutex); | ||
291 | pr_debug("%s: start feeding\n", __func__); | ||
292 | |||
293 | /* resolve input and output streaming paramters */ | ||
294 | if (d->props->get_stream_config) { | ||
295 | memcpy(&stream_props, &adap->props->stream, | ||
296 | sizeof(struct usb_data_stream_properties)); | ||
297 | ret = d->props->get_stream_config( | ||
298 | adap->fe[adap->active_fe], | ||
299 | &adap->ts_type, &stream_props); | ||
300 | if (ret < 0) | ||
301 | goto err_mutex_unlock; | ||
302 | } else { | ||
303 | stream_props = adap->props->stream; | ||
304 | } | ||
305 | |||
306 | switch (adap->ts_type) { | ||
307 | case DVB_USB_FE_TS_TYPE_204: | ||
308 | adap->stream.complete = dvb_usb_data_complete_204; | ||
309 | break; | ||
310 | case DVB_USB_FE_TS_TYPE_RAW: | ||
311 | adap->stream.complete = dvb_usb_data_complete_raw; | ||
312 | break; | ||
313 | case DVB_USB_FE_TS_TYPE_188: | ||
314 | default: | ||
315 | adap->stream.complete = dvb_usb_data_complete; | ||
316 | break; | ||
317 | } | ||
318 | |||
319 | usb_urb_submitv2(&adap->stream, &stream_props); | ||
320 | |||
321 | if (adap->props->caps & DVB_USB_ADAP_HAS_PID_FILTER && | ||
322 | adap->props->caps & | ||
323 | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF && | ||
324 | adap->props->pid_filter_ctrl) { | ||
325 | ret = adap->props->pid_filter_ctrl(adap, | ||
326 | adap->pid_filtering); | ||
327 | if (ret < 0) { | ||
328 | pr_err("%s: pid_filter_ctrl() failed=%d\n", | ||
329 | KBUILD_MODNAME, ret); | ||
330 | goto err_mutex_unlock; | ||
331 | } | ||
332 | } | ||
333 | |||
334 | if (d->props->streaming_ctrl) { | ||
335 | ret = d->props->streaming_ctrl(adap, 1); | ||
336 | if (ret < 0) { | ||
337 | pr_err("%s: streaming_ctrl() failed=%d\n", | ||
338 | KBUILD_MODNAME, ret); | ||
339 | goto err_mutex_unlock; | ||
340 | } | ||
341 | } | ||
342 | } | ||
343 | |||
344 | return 0; | ||
345 | err_mutex_unlock: | ||
346 | mutex_unlock(&adap->sync_mutex); | ||
347 | pr_debug("%s: failed=%d\n", __func__, ret); | ||
348 | return ret; | ||
349 | } | ||
350 | |||
351 | static int dvb_usb_start_feed(struct dvb_demux_feed *dvbdmxfeed) | ||
352 | { | ||
353 | return dvb_usb_ctrl_feed(dvbdmxfeed, 1); | ||
354 | } | ||
355 | |||
356 | static int dvb_usb_stop_feed(struct dvb_demux_feed *dvbdmxfeed) | ||
357 | { | ||
358 | return dvb_usb_ctrl_feed(dvbdmxfeed, -1); | ||
359 | } | ||
360 | |||
361 | int dvb_usbv2_adapter_dvb_init(struct dvb_usb_adapter *adap) | ||
362 | { | ||
363 | int ret; | ||
364 | struct dvb_usb_device *d = adap_to_d(adap); | ||
365 | pr_debug("%s: adap=%d\n", __func__, adap->id); | ||
366 | |||
367 | ret = dvb_register_adapter(&adap->dvb_adap, d->name, d->props->owner, | ||
368 | &d->udev->dev, d->props->adapter_nr); | ||
369 | if (ret < 0) { | ||
370 | pr_debug("%s: dvb_register_adapter() failed=%d\n", __func__, | ||
371 | ret); | ||
372 | goto err; | ||
373 | } | ||
374 | |||
375 | adap->dvb_adap.priv = adap; | ||
376 | |||
377 | if (d->props->read_mac_address) { | ||
378 | ret = d->props->read_mac_address(adap, | ||
379 | adap->dvb_adap.proposed_mac); | ||
380 | if (ret < 0) | ||
381 | goto err_dmx; | ||
382 | |||
383 | pr_info("%s: MAC address: %pM\n", KBUILD_MODNAME, | ||
384 | adap->dvb_adap.proposed_mac); | ||
385 | } | ||
386 | |||
387 | adap->demux.dmx.capabilities = DMX_TS_FILTERING | DMX_SECTION_FILTERING; | ||
388 | adap->demux.priv = adap; | ||
389 | adap->demux.filternum = 0; | ||
390 | if (adap->demux.filternum < adap->max_feed_count) | ||
391 | adap->demux.filternum = adap->max_feed_count; | ||
392 | adap->demux.feednum = adap->demux.filternum; | ||
393 | adap->demux.start_feed = dvb_usb_start_feed; | ||
394 | adap->demux.stop_feed = dvb_usb_stop_feed; | ||
395 | adap->demux.write_to_decoder = NULL; | ||
396 | ret = dvb_dmx_init(&adap->demux); | ||
397 | if (ret < 0) { | ||
398 | pr_err("%s: dvb_dmx_init() failed=%d\n", KBUILD_MODNAME, ret); | ||
399 | goto err_dmx; | ||
400 | } | ||
401 | |||
402 | adap->dmxdev.filternum = adap->demux.filternum; | ||
403 | adap->dmxdev.demux = &adap->demux.dmx; | ||
404 | adap->dmxdev.capabilities = 0; | ||
405 | ret = dvb_dmxdev_init(&adap->dmxdev, &adap->dvb_adap); | ||
406 | if (ret < 0) { | ||
407 | pr_err("%s: dvb_dmxdev_init() failed=%d\n", KBUILD_MODNAME, | ||
408 | ret); | ||
409 | goto err_dmx_dev; | ||
410 | } | ||
411 | |||
412 | ret = dvb_net_init(&adap->dvb_adap, &adap->dvb_net, &adap->demux.dmx); | ||
413 | if (ret < 0) { | ||
414 | pr_err("%s: dvb_net_init() failed=%d\n", KBUILD_MODNAME, ret); | ||
415 | goto err_net_init; | ||
416 | } | ||
417 | |||
418 | mutex_init(&adap->sync_mutex); | ||
419 | |||
420 | return 0; | ||
421 | err_net_init: | ||
422 | dvb_dmxdev_release(&adap->dmxdev); | ||
423 | err_dmx_dev: | ||
424 | dvb_dmx_release(&adap->demux); | ||
425 | err_dmx: | ||
426 | dvb_unregister_adapter(&adap->dvb_adap); | ||
427 | err: | ||
428 | adap->dvb_adap.priv = NULL; | ||
429 | return ret; | ||
430 | } | ||
431 | |||
432 | int dvb_usbv2_adapter_dvb_exit(struct dvb_usb_adapter *adap) | ||
433 | { | ||
434 | pr_debug("%s: adap=%d\n", __func__, adap->id); | ||
435 | |||
436 | if (adap->dvb_adap.priv) { | ||
437 | dvb_net_release(&adap->dvb_net); | ||
438 | adap->demux.dmx.close(&adap->demux.dmx); | ||
439 | dvb_dmxdev_release(&adap->dmxdev); | ||
440 | dvb_dmx_release(&adap->demux); | ||
441 | dvb_unregister_adapter(&adap->dvb_adap); | ||
442 | } | ||
443 | |||
444 | return 0; | ||
445 | } | ||
446 | |||
447 | int dvb_usbv2_device_power_ctrl(struct dvb_usb_device *d, int onoff) | ||
448 | { | ||
449 | int ret; | ||
450 | |||
451 | if (onoff) | ||
452 | d->powered++; | ||
453 | else | ||
454 | d->powered--; | ||
455 | |||
456 | if (d->powered == 0 || (onoff && d->powered == 1)) { | ||
457 | /* when switching from 1 to 0 or from 0 to 1 */ | ||
458 | pr_debug("%s: power control=%d\n", __func__, onoff); | ||
459 | if (d->props->power_ctrl) { | ||
460 | ret = d->props->power_ctrl(d, onoff); | ||
461 | goto err; | ||
462 | } | ||
463 | } | ||
464 | |||
465 | return 0; | ||
466 | err: | ||
467 | pr_debug("%s: failed=%d\n", __func__, ret); | ||
468 | return ret; | ||
469 | } | ||
470 | |||
471 | static int dvb_usb_fe_wakeup(struct dvb_frontend *fe) | ||
472 | { | ||
473 | int ret; | ||
474 | struct dvb_usb_adapter *adap = fe->dvb->priv; | ||
475 | struct dvb_usb_device *d = adap_to_d(adap); | ||
476 | mutex_lock(&adap->sync_mutex); | ||
477 | pr_debug("%s: adap=%d fe=%d\n", __func__, adap->id, fe->id); | ||
478 | |||
479 | ret = dvb_usbv2_device_power_ctrl(d, 1); | ||
480 | if (ret < 0) | ||
481 | goto err; | ||
482 | |||
483 | if (d->props->frontend_ctrl) { | ||
484 | ret = d->props->frontend_ctrl(fe, 1); | ||
485 | if (ret < 0) | ||
486 | goto err; | ||
487 | } | ||
488 | |||
489 | if (adap->fe_init[fe->id]) { | ||
490 | ret = adap->fe_init[fe->id](fe); | ||
491 | if (ret < 0) | ||
492 | goto err; | ||
493 | } | ||
494 | |||
495 | adap->active_fe = fe->id; | ||
496 | mutex_unlock(&adap->sync_mutex); | ||
497 | |||
498 | return 0; | ||
499 | err: | ||
500 | mutex_unlock(&adap->sync_mutex); | ||
501 | pr_debug("%s: failed=%d\n", __func__, ret); | ||
502 | return ret; | ||
503 | } | ||
504 | |||
505 | static int dvb_usb_fe_sleep(struct dvb_frontend *fe) | ||
506 | { | ||
507 | int ret; | ||
508 | struct dvb_usb_adapter *adap = fe->dvb->priv; | ||
509 | struct dvb_usb_device *d = adap_to_d(adap); | ||
510 | mutex_lock(&adap->sync_mutex); | ||
511 | pr_debug("%s: adap=%d fe=%d\n", __func__, adap->id, fe->id); | ||
512 | |||
513 | if (adap->fe_sleep[fe->id]) { | ||
514 | ret = adap->fe_sleep[fe->id](fe); | ||
515 | if (ret < 0) | ||
516 | goto err; | ||
517 | } | ||
518 | |||
519 | if (d->props->frontend_ctrl) { | ||
520 | ret = d->props->frontend_ctrl(fe, 0); | ||
521 | if (ret < 0) | ||
522 | goto err; | ||
523 | } | ||
524 | |||
525 | ret = dvb_usbv2_device_power_ctrl(d, 0); | ||
526 | if (ret < 0) | ||
527 | goto err; | ||
528 | |||
529 | adap->active_fe = -1; | ||
530 | mutex_unlock(&adap->sync_mutex); | ||
531 | |||
532 | return 0; | ||
533 | err: | ||
534 | mutex_unlock(&adap->sync_mutex); | ||
535 | pr_debug("%s: failed=%d\n", __func__, ret); | ||
536 | return ret; | ||
537 | } | ||
538 | |||
539 | int dvb_usbv2_adapter_frontend_init(struct dvb_usb_adapter *adap) | ||
540 | { | ||
541 | int ret, i, count_registered = 0; | ||
542 | struct dvb_usb_device *d = adap_to_d(adap); | ||
543 | pr_debug("%s: adap=%d\n", __func__, adap->id); | ||
544 | |||
545 | memset(adap->fe, 0, sizeof(adap->fe)); | ||
546 | adap->active_fe = -1; | ||
547 | |||
548 | if (d->props->frontend_attach) { | ||
549 | ret = d->props->frontend_attach(adap); | ||
550 | if (ret < 0) { | ||
551 | pr_debug("%s: frontend_attach() failed=%d\n", __func__, | ||
552 | ret); | ||
553 | goto err_dvb_frontend_detach; | ||
554 | } | ||
555 | } else { | ||
556 | pr_debug("%s: frontend_attach() do not exists\n", __func__); | ||
557 | ret = 0; | ||
558 | goto err; | ||
559 | } | ||
560 | |||
561 | for (i = 0; i < MAX_NO_OF_FE_PER_ADAP && adap->fe[i]; i++) { | ||
562 | adap->fe[i]->id = i; | ||
563 | |||
564 | /* re-assign sleep and wakeup functions */ | ||
565 | adap->fe_init[i] = adap->fe[i]->ops.init; | ||
566 | adap->fe[i]->ops.init = dvb_usb_fe_wakeup; | ||
567 | adap->fe_sleep[i] = adap->fe[i]->ops.sleep; | ||
568 | adap->fe[i]->ops.sleep = dvb_usb_fe_sleep; | ||
569 | |||
570 | ret = dvb_register_frontend(&adap->dvb_adap, adap->fe[i]); | ||
571 | if (ret < 0) { | ||
572 | pr_err("%s: frontend%d registration failed\n", | ||
573 | KBUILD_MODNAME, i); | ||
574 | goto err_dvb_unregister_frontend; | ||
575 | } | ||
576 | |||
577 | count_registered++; | ||
578 | } | ||
579 | |||
580 | if (d->props->tuner_attach) { | ||
581 | ret = d->props->tuner_attach(adap); | ||
582 | if (ret < 0) { | ||
583 | pr_debug("%s: tuner_attach() failed=%d\n", __func__, | ||
584 | ret); | ||
585 | goto err_dvb_unregister_frontend; | ||
586 | } | ||
587 | } | ||
588 | |||
589 | return 0; | ||
590 | |||
591 | err_dvb_unregister_frontend: | ||
592 | for (i = count_registered - 1; i >= 0; i--) | ||
593 | dvb_unregister_frontend(adap->fe[i]); | ||
594 | |||
595 | err_dvb_frontend_detach: | ||
596 | for (i = MAX_NO_OF_FE_PER_ADAP - 1; i >= 0; i--) { | ||
597 | if (adap->fe[i]) | ||
598 | dvb_frontend_detach(adap->fe[i]); | ||
599 | } | ||
600 | |||
601 | err: | ||
602 | pr_debug("%s: failed=%d\n", __func__, ret); | ||
603 | return ret; | ||
604 | } | ||
605 | |||
606 | int dvb_usbv2_adapter_frontend_exit(struct dvb_usb_adapter *adap) | ||
607 | { | ||
608 | int i; | ||
609 | pr_debug("%s: adap=%d\n", __func__, adap->id); | ||
610 | |||
611 | for (i = MAX_NO_OF_FE_PER_ADAP - 1; i >= 0; i--) { | ||
612 | if (adap->fe[i]) { | ||
613 | dvb_unregister_frontend(adap->fe[i]); | ||
614 | dvb_frontend_detach(adap->fe[i]); | ||
615 | } | ||
616 | } | ||
617 | |||
618 | return 0; | ||
619 | } | ||
620 | |||
203 | static int dvb_usbv2_adapter_init(struct dvb_usb_device *d) | 621 | static int dvb_usbv2_adapter_init(struct dvb_usb_device *d) |
204 | { | 622 | { |
205 | struct dvb_usb_adapter *adap; | 623 | struct dvb_usb_adapter *adap; |
@@ -346,30 +764,6 @@ err: | |||
346 | return ret; | 764 | return ret; |
347 | } | 765 | } |
348 | 766 | ||
349 | int dvb_usbv2_device_power_ctrl(struct dvb_usb_device *d, int onoff) | ||
350 | { | ||
351 | int ret; | ||
352 | |||
353 | if (onoff) | ||
354 | d->powered++; | ||
355 | else | ||
356 | d->powered--; | ||
357 | |||
358 | if (d->powered == 0 || (onoff && d->powered == 1)) { | ||
359 | /* when switching from 1 to 0 or from 0 to 1 */ | ||
360 | pr_debug("%s: power control=%d\n", __func__, onoff); | ||
361 | if (d->props->power_ctrl) { | ||
362 | ret = d->props->power_ctrl(d, onoff); | ||
363 | goto err; | ||
364 | } | ||
365 | } | ||
366 | |||
367 | return 0; | ||
368 | err: | ||
369 | pr_debug("%s: failed=%d\n", __func__, ret); | ||
370 | return ret; | ||
371 | } | ||
372 | |||
373 | /* | 767 | /* |
374 | * udev, which is used for the firmware downloading, requires we cannot | 768 | * udev, which is used for the firmware downloading, requires we cannot |
375 | * block during module_init(). module_init() calls USB probe() which | 769 | * block during module_init(). module_init() calls USB probe() which |