Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[media] cx23885-dvb: use a better approach to hook set_frontend

When the frontend drivers got converted to DVBv5 API, the original
hook that tracked when a frontend is set got removed, being replaced
by an approach that would use the gate control. That doesn't work
fine with some boards. Also, the code were called more times than
desired.
Replace it by a logic that will hook the dvb set_frontend ops,
with works with both DVBv3 and DVBv5 calls.
Tested on a Mygica X8502 OEM board.

Tested-by: Alfredo Delaiti <alfredodelaiti@netscape.net>
Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com>

+18 -8
+16 -8
drivers/media/pci/cx23885/cx23885-dvb.c
··· 119 119 cx23885_free_buffer(q, (struct cx23885_buffer *)vb); 120 120 } 121 121 122 - static int cx23885_dvb_set_frontend(struct dvb_frontend *fe); 123 - 124 122 static void cx23885_dvb_gate_ctrl(struct cx23885_tsport *port, int open) 125 123 { 126 124 struct videobuf_dvb_frontends *f; ··· 133 135 134 136 if (fe && fe->dvb.frontend && fe->dvb.frontend->ops.i2c_gate_ctrl) 135 137 fe->dvb.frontend->ops.i2c_gate_ctrl(fe->dvb.frontend, open); 136 - 137 - /* 138 - * FIXME: Improve this path to avoid calling the 139 - * cx23885_dvb_set_frontend() every time it passes here. 140 - */ 141 - cx23885_dvb_set_frontend(fe->dvb.frontend); 142 138 } 143 139 144 140 static struct videobuf_queue_ops dvb_qops = { ··· 553 561 cx23885_gpio_set(dev, GPIO_0); 554 562 break; 555 563 } 564 + 565 + /* Call the real set_frontend */ 566 + if (port->set_frontend) 567 + return port->set_frontend(fe); 568 + 556 569 return 0; 570 + } 571 + 572 + static void cx23885_set_frontend_hook(struct cx23885_tsport *port, 573 + struct dvb_frontend *fe) 574 + { 575 + port->set_frontend = fe->ops.set_frontend; 576 + fe->ops.set_frontend = cx23885_dvb_set_frontend; 557 577 } 558 578 559 579 static struct lgs8gxx_config magicpro_prohdtve2_lgs8g75_config = { ··· 775 771 0x60, &dev->i2c_bus[1].i2c_adap, 776 772 &hauppauge_hvr127x_config); 777 773 } 774 + if (dev->board == CX23885_BOARD_HAUPPAUGE_HVR1275) 775 + cx23885_set_frontend_hook(port, fe0->dvb.frontend); 778 776 break; 779 777 case CX23885_BOARD_HAUPPAUGE_HVR1255: 780 778 case CX23885_BOARD_HAUPPAUGE_HVR1255_22111: ··· 1112 1106 &i2c_bus2->i2c_adap, 1113 1107 &mygica_x8506_xc5000_config); 1114 1108 } 1109 + cx23885_set_frontend_hook(port, fe0->dvb.frontend); 1115 1110 break; 1116 1111 case CX23885_BOARD_MAGICPRO_PROHDTVE2: 1117 1112 i2c_bus = &dev->i2c_bus[0]; ··· 1126 1119 &i2c_bus2->i2c_adap, 1127 1120 &magicpro_prohdtve2_xc5000_config); 1128 1121 } 1122 + cx23885_set_frontend_hook(port, fe0->dvb.frontend); 1129 1123 break; 1130 1124 case CX23885_BOARD_HAUPPAUGE_HVR1850: 1131 1125 i2c_bus = &dev->i2c_bus[0];
+2
drivers/media/pci/cx23885/cx23885.h
··· 320 320 321 321 /* Workaround for a temp dvb_frontend that the tuner can attached to */ 322 322 struct dvb_frontend analog_fe; 323 + 324 + int (*set_frontend)(struct dvb_frontend *fe); 323 325 }; 324 326 325 327 struct cx23885_kernel_ir {