aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/pvrusb2
diff options
context:
space:
mode:
authorMike Isely <isely@pobox.com>2009-03-06 21:47:10 -0500
committerMauro Carvalho Chehab <mchehab@redhat.com>2009-03-30 11:43:33 -0400
commita932f507463d996b6ec1647ee7d4e2fa1e6aeda6 (patch)
tree00681f6ca29c2ddc052bc2f18c0503aba71d3f5f /drivers/media/video/pvrusb2
parente9c64a78dbd7c4f6c4a31c4040f340f732bf4ec5 (diff)
V4L/DVB (11159): pvrusb2: Providing means to stop tracking an old i2c module
This implements a temporary mechanism to "untrack" an i2c module from the old i2c layer. The v4l2-subdev related code in the driver will use this to remove a sub-device from the old i2c layer. In the end, once the old i2c layer is removed, this will also eventually go away. Signed-off-by: Mike Isely <isely@pobox.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/video/pvrusb2')
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-hdw.c6
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-i2c-track.c76
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-i2c-track.h5
3 files changed, 64 insertions, 23 deletions
diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw.c b/drivers/media/video/pvrusb2/pvrusb2-hdw.c
index faa94cef2c55..0e0d086bb278 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-hdw.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-hdw.c
@@ -2020,6 +2020,12 @@ static void pvr2_hdw_load_subdev(struct pvr2_hdw *hdw,
2020 i2caddr); 2020 i2caddr);
2021 } 2021 }
2022 2022
2023 /* If we have both old and new i2c layers enabled, make sure that
2024 old layer isn't also tracking this module. This is a debugging
2025 aid, in normal situations there's no reason for both mechanisms
2026 to be enabled. */
2027 pvr2_i2c_untrack_subdev(hdw, sd);
2028
2023 // ????? 2029 // ?????
2024 /* Based on module ID, we should remember subdev pointers 2030 /* Based on module ID, we should remember subdev pointers
2025 so that we can send certain custom commands where 2031 so that we can send certain custom commands where
diff --git a/drivers/media/video/pvrusb2/pvrusb2-i2c-track.c b/drivers/media/video/pvrusb2/pvrusb2-i2c-track.c
index 4bb6f9453e0d..3387897ed897 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-i2c-track.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-i2c-track.c
@@ -421,41 +421,71 @@ void pvr2_i2c_track_attach_inform(struct i2c_client *client)
421 if (fl) queue_work(hdw->workqueue,&hdw->worki2csync); 421 if (fl) queue_work(hdw->workqueue,&hdw->worki2csync);
422} 422}
423 423
424static void pvr2_i2c_client_disconnect(struct pvr2_i2c_client *cp)
425{
426 if (cp->handler && cp->handler->func_table->detach) {
427 cp->handler->func_table->detach(cp->handler->func_data);
428 }
429 list_del(&cp->list);
430 kfree(cp);
431}
432
424void pvr2_i2c_track_detach_inform(struct i2c_client *client) 433void pvr2_i2c_track_detach_inform(struct i2c_client *client)
425{ 434{
426 struct pvr2_hdw *hdw = (struct pvr2_hdw *)(client->adapter->algo_data); 435 struct pvr2_hdw *hdw = (struct pvr2_hdw *)(client->adapter->algo_data);
427 struct pvr2_i2c_client *cp, *ncp; 436 struct pvr2_i2c_client *cp, *ncp;
428 unsigned long amask = 0; 437 unsigned long amask = 0;
429 int foundfl = 0; 438 int foundfl = 0;
430 mutex_lock(&hdw->i2c_list_lock); do { 439 mutex_lock(&hdw->i2c_list_lock);
431 hdw->cropcap_stale = !0; 440 hdw->cropcap_stale = !0;
432 list_for_each_entry_safe(cp, ncp, &hdw->i2c_clients, list) { 441 list_for_each_entry_safe(cp, ncp, &hdw->i2c_clients, list) {
433 if (cp->client == client) { 442 if (cp->client == client) {
434 trace_i2c("pvr2_i2c_detach" 443 trace_i2c("pvr2_i2c_detach"
435 " [client=%s @ 0x%x ctxt=%p]", 444 " [client=%s @ 0x%x ctxt=%p]",
436 client->name, 445 client->name,
437 client->addr,cp); 446 client->addr, cp);
438 if (cp->handler && 447 pvr2_i2c_client_disconnect(cp);
439 cp->handler->func_table->detach) { 448 foundfl = !0;
440 cp->handler->func_table->detach( 449 continue;
441 cp->handler->func_data);
442 }
443 list_del(&cp->list);
444 kfree(cp);
445 foundfl = !0;
446 continue;
447 }
448 amask |= cp->ctl_mask;
449 } 450 }
450 hdw->i2c_active_mask = amask; 451 amask |= cp->ctl_mask;
451 } while (0); mutex_unlock(&hdw->i2c_list_lock); 452 }
453 hdw->i2c_active_mask = amask;
454 mutex_unlock(&hdw->i2c_list_lock);
452 if (!foundfl) { 455 if (!foundfl) {
453 trace_i2c("pvr2_i2c_detach [client=%s @ 0x%x ctxt=<unknown>]", 456 trace_i2c("pvr2_i2c_detach [client=%s @ 0x%x ctxt=<unknown>]",
454 client->name, 457 client->name, client->addr);
455 client->addr);
456 } 458 }
457} 459}
458 460
461/* This function is used to remove an i2c client from our tracking
462 structure if the client happens to be the specified v4l2 sub-device.
463 The idea here is to ensure that sub-devices are not also tracked with
464 the old tracking mechanism - it's one or the other not both. This is
465 only for debugging. In a "real" environment, only one of these two
466 mechanisms should even be compiled in. But by enabling both we can
467 incrementally test control of each sub-device. */
468void pvr2_i2c_untrack_subdev(struct pvr2_hdw *hdw, struct v4l2_subdev *sd)
469{
470 struct i2c_client *client;
471 struct pvr2_i2c_client *cp, *ncp;
472 unsigned long amask = 0;
473 mutex_lock(&hdw->i2c_list_lock);
474 list_for_each_entry_safe(cp, ncp, &hdw->i2c_clients, list) {
475 client = cp->client;
476 if (i2c_get_clientdata(client) == sd) {
477 trace_i2c("pvr2_i2c_detach (subdev active)"
478 " [client=%s @ 0x%x ctxt=%p]",
479 client->name, client->addr, cp);
480 pvr2_i2c_client_disconnect(cp);
481 continue;
482 }
483 amask |= cp->ctl_mask;
484 }
485 hdw->i2c_active_mask = amask;
486 mutex_unlock(&hdw->i2c_list_lock);
487}
488
459void pvr2_i2c_track_init(struct pvr2_hdw *hdw) 489void pvr2_i2c_track_init(struct pvr2_hdw *hdw)
460{ 490{
461 hdw->i2c_pend_mask = 0; 491 hdw->i2c_pend_mask = 0;
diff --git a/drivers/media/video/pvrusb2/pvrusb2-i2c-track.h b/drivers/media/video/pvrusb2/pvrusb2-i2c-track.h
index 7d0e4fb63785..eba48e4c9585 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-i2c-track.h
+++ b/drivers/media/video/pvrusb2/pvrusb2-i2c-track.h
@@ -22,6 +22,8 @@
22 22
23#include <linux/list.h> 23#include <linux/list.h>
24#include <linux/i2c.h> 24#include <linux/i2c.h>
25#include <media/v4l2-device.h>
26
25 27
26struct pvr2_hdw; 28struct pvr2_hdw;
27struct pvr2_i2c_client; 29struct pvr2_i2c_client;
@@ -83,6 +85,9 @@ unsigned int pvr2_i2c_report(struct pvr2_hdw *,char *buf,unsigned int maxlen);
83void pvr2_i2c_probe(struct pvr2_hdw *,struct pvr2_i2c_client *); 85void pvr2_i2c_probe(struct pvr2_hdw *,struct pvr2_i2c_client *);
84const struct pvr2_i2c_op *pvr2_i2c_get_op(unsigned int idx); 86const struct pvr2_i2c_op *pvr2_i2c_get_op(unsigned int idx);
85 87
88void pvr2_i2c_untrack_subdev(struct pvr2_hdw *, struct v4l2_subdev *sd);
89
90
86#endif /* __PVRUSB2_I2C_CORE_H */ 91#endif /* __PVRUSB2_I2C_CORE_H */
87 92
88 93