diff options
| author | Mauro Carvalho Chehab <mchehab@redhat.com> | 2009-09-07 01:22:01 -0400 |
|---|---|---|
| committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2009-09-12 11:20:17 -0400 |
| commit | 7aedd5ec87686c557d48584d69ad880c11a0984d (patch) | |
| tree | 4b700249f4c94e76fdf86c7f45bc287631d721d7 | |
| parent | 78f2e672b37ae8935ec0b97cedbc2d877ffa0c5f (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>
| -rw-r--r-- | drivers/media/video/saa7134/saa7134-input.c | 60 | ||||
| -rw-r--r-- | drivers/media/video/saa7134/saa7134.h | 4 |
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 | ||
| 692 | void saa7134_probe_i2c_ir(struct saa7134_dev *dev) | 692 | void 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 | ||
| 792 | static int saa7134_rc5_irq(struct saa7134_dev *dev) | 790 | static 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; |
