aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/saa7134
diff options
context:
space:
mode:
authorMauro Carvalho Chehab <mchehab@redhat.com>2009-09-07 01:22:01 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2009-09-12 11:20:17 -0400
commit7aedd5ec87686c557d48584d69ad880c11a0984d (patch)
tree4b700249f4c94e76fdf86c7f45bc287631d721d7 /drivers/media/video/saa7134
parent78f2e672b37ae8935ec0b97cedbc2d877ffa0c5f (diff)
V4L/DVB (12701): saa7134: ir-kbd-i2c init data needs a persistent object
ir-kbd-i2c's ir_probe() function can be called much later (i.e. at ir-kbd-i2c module load), than the lifetime of a struct IR_i2c_init_data allocated off of the stack in cx18_i2c_new_ir() at registration time. Make sure we pass a pointer to a persistent IR_i2c_init_data object at i2c registration time. Thanks to Brian Rogers, Dustin Mitchell, Andy Walls and Jean Delvare to rise this question. Before this patch, if ir-kbd-i2c were probed after SAA7134, trash data were used. Compile tested only, but the patch is identical to em28xx one. So, it should work properly. Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/video/saa7134')
-rw-r--r--drivers/media/video/saa7134/saa7134-input.c60
-rw-r--r--drivers/media/video/saa7134/saa7134.h4
2 files changed, 33 insertions, 31 deletions
diff --git a/drivers/media/video/saa7134/saa7134-input.c b/drivers/media/video/saa7134/saa7134-input.c
index 9070e5fabb4e..e1e83c7b966e 100644
--- a/drivers/media/video/saa7134/saa7134-input.c
+++ b/drivers/media/video/saa7134/saa7134-input.c
@@ -691,8 +691,6 @@ void saa7134_input_fini(struct saa7134_dev *dev)
691 691
692void saa7134_probe_i2c_ir(struct saa7134_dev *dev) 692void saa7134_probe_i2c_ir(struct saa7134_dev *dev)
693{ 693{
694 struct i2c_board_info info;
695 struct IR_i2c_init_data init_data;
696 const unsigned short addr_list[] = { 694 const unsigned short addr_list[] = {
697 0x7a, 0x47, 0x71, 0x2d, 695 0x7a, 0x47, 0x71, 0x2d,
698 I2C_CLIENT_END 696 I2C_CLIENT_END
@@ -712,34 +710,34 @@ void saa7134_probe_i2c_ir(struct saa7134_dev *dev)
712 return; 710 return;
713 } 711 }
714 712
715 memset(&info, 0, sizeof(struct i2c_board_info)); 713 memset(&dev->info, 0, sizeof(dev->info));
716 memset(&init_data, 0, sizeof(struct IR_i2c_init_data)); 714 memset(&dev->init_data, 0, sizeof(dev->init_data));
717 strlcpy(info.type, "ir_video", I2C_NAME_SIZE); 715 strlcpy(dev->info.type, "ir_video", I2C_NAME_SIZE);
718 716
719 switch (dev->board) { 717 switch (dev->board) {
720 case SAA7134_BOARD_PINNACLE_PCTV_110i: 718 case SAA7134_BOARD_PINNACLE_PCTV_110i:
721 case SAA7134_BOARD_PINNACLE_PCTV_310i: 719 case SAA7134_BOARD_PINNACLE_PCTV_310i:
722 init_data.name = "Pinnacle PCTV"; 720 dev->init_data.name = "Pinnacle PCTV";
723 if (pinnacle_remote == 0) { 721 if (pinnacle_remote == 0) {
724 init_data.get_key = get_key_pinnacle_color; 722 dev->init_data.get_key = get_key_pinnacle_color;
725 init_data.ir_codes = &ir_codes_pinnacle_color_table; 723 dev->init_data.ir_codes = &ir_codes_pinnacle_color_table;
726 info.addr = 0x47; 724 dev->info.addr = 0x47;
727 } else { 725 } else {
728 init_data.get_key = get_key_pinnacle_grey; 726 dev->init_data.get_key = get_key_pinnacle_grey;
729 init_data.ir_codes = &ir_codes_pinnacle_grey_table; 727 dev->init_data.ir_codes = &ir_codes_pinnacle_grey_table;
730 info.addr = 0x47; 728 dev->info.addr = 0x47;
731 } 729 }
732 break; 730 break;
733 case SAA7134_BOARD_UPMOST_PURPLE_TV: 731 case SAA7134_BOARD_UPMOST_PURPLE_TV:
734 init_data.name = "Purple TV"; 732 dev->init_data.name = "Purple TV";
735 init_data.get_key = get_key_purpletv; 733 dev->init_data.get_key = get_key_purpletv;
736 init_data.ir_codes = &ir_codes_purpletv_table; 734 dev->init_data.ir_codes = &ir_codes_purpletv_table;
737 break; 735 break;
738 case SAA7134_BOARD_MSI_TVATANYWHERE_PLUS: 736 case SAA7134_BOARD_MSI_TVATANYWHERE_PLUS:
739 init_data.name = "MSI TV@nywhere Plus"; 737 dev->init_data.name = "MSI TV@nywhere Plus";
740 init_data.get_key = get_key_msi_tvanywhere_plus; 738 dev->init_data.get_key = get_key_msi_tvanywhere_plus;
741 init_data.ir_codes = &ir_codes_msi_tvanywhere_plus_table; 739 dev->init_data.ir_codes = &ir_codes_msi_tvanywhere_plus_table;
742 info.addr = 0x30; 740 dev->info.addr = 0x30;
743 /* MSI TV@nywhere Plus controller doesn't seem to 741 /* MSI TV@nywhere Plus controller doesn't seem to
744 respond to probes unless we read something from 742 respond to probes unless we read something from
745 an existing device. Weird... 743 an existing device. Weird...
@@ -750,9 +748,9 @@ void saa7134_probe_i2c_ir(struct saa7134_dev *dev)
750 (1 == rc) ? "yes" : "no"); 748 (1 == rc) ? "yes" : "no");
751 break; 749 break;
752 case SAA7134_BOARD_HAUPPAUGE_HVR1110: 750 case SAA7134_BOARD_HAUPPAUGE_HVR1110:
753 init_data.name = "HVR 1110"; 751 dev->init_data.name = "HVR 1110";
754 init_data.get_key = get_key_hvr1110; 752 dev->init_data.get_key = get_key_hvr1110;
755 init_data.ir_codes = &ir_codes_hauppauge_new_table; 753 dev->init_data.ir_codes = &ir_codes_hauppauge_new_table;
756 break; 754 break;
757 case SAA7134_BOARD_BEHOLD_607FM_MK3: 755 case SAA7134_BOARD_BEHOLD_607FM_MK3:
758 case SAA7134_BOARD_BEHOLD_607FM_MK5: 756 case SAA7134_BOARD_BEHOLD_607FM_MK5:
@@ -767,26 +765,26 @@ void saa7134_probe_i2c_ir(struct saa7134_dev *dev)
767 case SAA7134_BOARD_BEHOLD_M6_EXTRA: 765 case SAA7134_BOARD_BEHOLD_M6_EXTRA:
768 case SAA7134_BOARD_BEHOLD_H6: 766 case SAA7134_BOARD_BEHOLD_H6:
769 case SAA7134_BOARD_BEHOLD_X7: 767 case SAA7134_BOARD_BEHOLD_X7:
770 init_data.name = "BeholdTV"; 768 dev->init_data.name = "BeholdTV";
771 init_data.get_key = get_key_beholdm6xx; 769 dev->init_data.get_key = get_key_beholdm6xx;
772 init_data.ir_codes = &ir_codes_behold_table; 770 dev->init_data.ir_codes = &ir_codes_behold_table;
773 break; 771 break;
774 case SAA7134_BOARD_AVERMEDIA_CARDBUS_501: 772 case SAA7134_BOARD_AVERMEDIA_CARDBUS_501:
775 case SAA7134_BOARD_AVERMEDIA_CARDBUS_506: 773 case SAA7134_BOARD_AVERMEDIA_CARDBUS_506:
776 info.addr = 0x40; 774 dev->info.addr = 0x40;
777 break; 775 break;
778 } 776 }
779 777
780 if (init_data.name) 778 if (dev->init_data.name)
781 info.platform_data = &init_data; 779 dev->info.platform_data = &dev->init_data;
782 /* No need to probe if address is known */ 780 /* No need to probe if address is known */
783 if (info.addr) { 781 if (dev->info.addr) {
784 i2c_new_device(&dev->i2c_adap, &info); 782 i2c_new_device(&dev->i2c_adap, &dev->info);
785 return; 783 return;
786 } 784 }
787 785
788 /* Address not known, fallback to probing */ 786 /* Address not known, fallback to probing */
789 i2c_new_probed_device(&dev->i2c_adap, &info, addr_list); 787 i2c_new_probed_device(&dev->i2c_adap, &dev->info, addr_list);
790} 788}
791 789
792static int saa7134_rc5_irq(struct saa7134_dev *dev) 790static int saa7134_rc5_irq(struct saa7134_dev *dev)
diff --git a/drivers/media/video/saa7134/saa7134.h b/drivers/media/video/saa7134/saa7134.h
index ac74903a5bd4..d18bb9643856 100644
--- a/drivers/media/video/saa7134/saa7134.h
+++ b/drivers/media/video/saa7134/saa7134.h
@@ -589,6 +589,10 @@ struct saa7134_dev {
589 int nosignal; 589 int nosignal;
590 unsigned int insuspend; 590 unsigned int insuspend;
591 591
592 /* I2C keyboard data */
593 struct i2c_board_info info;
594 struct IR_i2c_init_data init_data;
595
592 /* SAA7134_MPEG_* */ 596 /* SAA7134_MPEG_* */
593 struct saa7134_ts ts; 597 struct saa7134_ts ts;
594 struct saa7134_dmaqueue ts_q; 598 struct saa7134_dmaqueue ts_q;