diff options
author | Hans Verkuil <hverkuil@xs4all.nl> | 2007-07-22 11:52:40 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@infradead.org> | 2007-10-09 21:03:20 -0400 |
commit | c976bc82339437e840f7dbf0b8c89c09d3fcd75e (patch) | |
tree | a8e48cead1f061340fe19890fde43d880c26b92a | |
parent | fa8a7529ba8c3c2f87dec78ad32c388695f4c1b7 (diff) |
V4L/DVB (5922): ivtv, cx25840: postpone fw load until first use
The firmware is now loaded when the driver is actually used for the first
time. This allows the driver to be compiled in-kernel instead of as a module.
Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl>
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
-rw-r--r-- | drivers/media/video/Makefile | 3 | ||||
-rw-r--r-- | drivers/media/video/cx25840/cx25840-core.c | 21 | ||||
-rw-r--r-- | drivers/media/video/cx25840/cx25840-core.h | 1 | ||||
-rw-r--r-- | drivers/media/video/ivtv/ivtv-driver.c | 193 | ||||
-rw-r--r-- | drivers/media/video/ivtv/ivtv-driver.h | 5 | ||||
-rw-r--r-- | drivers/media/video/ivtv/ivtv-fileops.c | 9 |
6 files changed, 129 insertions, 103 deletions
diff --git a/drivers/media/video/Makefile b/drivers/media/video/Makefile index 8f7205b558f..c5286bfba44 100644 --- a/drivers/media/video/Makefile +++ b/drivers/media/video/Makefile | |||
@@ -64,7 +64,6 @@ obj-$(CONFIG_VIDEO_CPIA_USB) += cpia_usb.o | |||
64 | obj-$(CONFIG_VIDEO_MEYE) += meye.o | 64 | obj-$(CONFIG_VIDEO_MEYE) += meye.o |
65 | obj-$(CONFIG_VIDEO_SAA7134) += saa7134/ | 65 | obj-$(CONFIG_VIDEO_SAA7134) += saa7134/ |
66 | obj-$(CONFIG_VIDEO_CX88) += cx88/ | 66 | obj-$(CONFIG_VIDEO_CX88) += cx88/ |
67 | obj-$(CONFIG_VIDEO_IVTV) += ivtv/ | ||
68 | obj-$(CONFIG_VIDEO_EM28XX) += em28xx/ | 67 | obj-$(CONFIG_VIDEO_EM28XX) += em28xx/ |
69 | obj-$(CONFIG_VIDEO_USBVISION) += usbvision/ | 68 | obj-$(CONFIG_VIDEO_USBVISION) += usbvision/ |
70 | obj-$(CONFIG_VIDEO_TVP5150) += tvp5150.o | 69 | obj-$(CONFIG_VIDEO_TVP5150) += tvp5150.o |
@@ -117,6 +116,8 @@ obj-$(CONFIG_USB_KONICAWC) += usbvideo/ | |||
117 | obj-$(CONFIG_USB_VICAM) += usbvideo/ | 116 | obj-$(CONFIG_USB_VICAM) += usbvideo/ |
118 | obj-$(CONFIG_USB_QUICKCAM_MESSENGER) += usbvideo/ | 117 | obj-$(CONFIG_USB_QUICKCAM_MESSENGER) += usbvideo/ |
119 | 118 | ||
119 | obj-$(CONFIG_VIDEO_IVTV) += ivtv/ | ||
120 | |||
120 | obj-$(CONFIG_VIDEO_VIVI) += vivi.o | 121 | obj-$(CONFIG_VIDEO_VIVI) += vivi.o |
121 | 122 | ||
122 | EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core | 123 | EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core |
diff --git a/drivers/media/video/cx25840/cx25840-core.c b/drivers/media/video/cx25840/cx25840-core.c index 67bda9f9a44..9c12bd39cfb 100644 --- a/drivers/media/video/cx25840/cx25840-core.c +++ b/drivers/media/video/cx25840/cx25840-core.c | |||
@@ -625,6 +625,22 @@ static int cx25840_command(struct i2c_client *client, unsigned int cmd, | |||
625 | struct v4l2_tuner *vt = arg; | 625 | struct v4l2_tuner *vt = arg; |
626 | struct v4l2_routing *route = arg; | 626 | struct v4l2_routing *route = arg; |
627 | 627 | ||
628 | /* ignore these commands */ | ||
629 | switch (cmd) { | ||
630 | case TUNER_SET_TYPE_ADDR: | ||
631 | return 0; | ||
632 | } | ||
633 | |||
634 | if (!state->is_initialized) { | ||
635 | v4l_dbg(1, cx25840_debug, client, "cmd %08x triggered fw load\n", cmd); | ||
636 | /* initialize on first use */ | ||
637 | state->is_initialized = 1; | ||
638 | if (state->is_cx25836) | ||
639 | cx25836_initialize(client); | ||
640 | else | ||
641 | cx25840_initialize(client, 1); | ||
642 | } | ||
643 | |||
628 | switch (cmd) { | 644 | switch (cmd) { |
629 | #ifdef CONFIG_VIDEO_ADV_DEBUG | 645 | #ifdef CONFIG_VIDEO_ADV_DEBUG |
630 | /* ioctls to allow direct access to the | 646 | /* ioctls to allow direct access to the |
@@ -906,11 +922,6 @@ static int cx25840_detect_client(struct i2c_adapter *adapter, int address, | |||
906 | 922 | ||
907 | i2c_attach_client(client); | 923 | i2c_attach_client(client); |
908 | 924 | ||
909 | if (state->is_cx25836) | ||
910 | cx25836_initialize(client); | ||
911 | else | ||
912 | cx25840_initialize(client, 1); | ||
913 | |||
914 | return 0; | 925 | return 0; |
915 | } | 926 | } |
916 | 927 | ||
diff --git a/drivers/media/video/cx25840/cx25840-core.h b/drivers/media/video/cx25840/cx25840-core.h index f4b56d2fd6b..8c1fbd9b87c 100644 --- a/drivers/media/video/cx25840/cx25840-core.h +++ b/drivers/media/video/cx25840/cx25840-core.h | |||
@@ -46,6 +46,7 @@ struct cx25840_state { | |||
46 | u32 id; | 46 | u32 id; |
47 | u32 rev; | 47 | u32 rev; |
48 | int is_cx25836; | 48 | int is_cx25836; |
49 | int is_initialized; | ||
49 | }; | 50 | }; |
50 | 51 | ||
51 | /* ----------------------------------------------------------------------- */ | 52 | /* ----------------------------------------------------------------------- */ |
diff --git a/drivers/media/video/ivtv/ivtv-driver.c b/drivers/media/video/ivtv/ivtv-driver.c index 81cbaf7dd51..00bdcc2e8f5 100644 --- a/drivers/media/video/ivtv/ivtv-driver.c +++ b/drivers/media/video/ivtv/ivtv-driver.c | |||
@@ -814,7 +814,6 @@ static void ivtv_request_module(struct ivtv *itv, const char *name) | |||
814 | 814 | ||
815 | static void ivtv_load_and_init_modules(struct ivtv *itv) | 815 | static void ivtv_load_and_init_modules(struct ivtv *itv) |
816 | { | 816 | { |
817 | struct v4l2_control ctrl; | ||
818 | u32 hw = itv->card->hw_all; | 817 | u32 hw = itv->card->hw_all; |
819 | int i; | 818 | int i; |
820 | 819 | ||
@@ -896,11 +895,6 @@ static void ivtv_load_and_init_modules(struct ivtv *itv) | |||
896 | } | 895 | } |
897 | 896 | ||
898 | if (hw & IVTV_HW_CX25840) { | 897 | if (hw & IVTV_HW_CX25840) { |
899 | /* CX25840_CID_ENABLE_PVR150_WORKAROUND */ | ||
900 | ctrl.id = V4L2_CID_PRIVATE_BASE; | ||
901 | ctrl.value = itv->pvr150_workaround; | ||
902 | itv->video_dec_func(itv, VIDIOC_S_CTRL, &ctrl); | ||
903 | |||
904 | itv->vbi.raw_decoder_line_size = 1444; | 898 | itv->vbi.raw_decoder_line_size = 1444; |
905 | itv->vbi.raw_decoder_sav_odd_field = 0x20; | 899 | itv->vbi.raw_decoder_sav_odd_field = 0x20; |
906 | itv->vbi.raw_decoder_sav_even_field = 0x60; | 900 | itv->vbi.raw_decoder_sav_even_field = 0x60; |
@@ -946,12 +940,9 @@ static int __devinit ivtv_probe(struct pci_dev *dev, | |||
946 | const struct pci_device_id *pci_id) | 940 | const struct pci_device_id *pci_id) |
947 | { | 941 | { |
948 | int retval = 0; | 942 | int retval = 0; |
949 | int video_input; | ||
950 | int yuv_buf_size; | 943 | int yuv_buf_size; |
951 | int vbi_buf_size; | 944 | int vbi_buf_size; |
952 | int fw_retry_count = 3; | ||
953 | struct ivtv *itv; | 945 | struct ivtv *itv; |
954 | struct v4l2_frequency vf; | ||
955 | 946 | ||
956 | spin_lock(&ivtv_cards_lock); | 947 | spin_lock(&ivtv_cards_lock); |
957 | 948 | ||
@@ -1038,22 +1029,6 @@ static int __devinit ivtv_probe(struct pci_dev *dev, | |||
1038 | goto free_io; | 1029 | goto free_io; |
1039 | } | 1030 | } |
1040 | 1031 | ||
1041 | while (--fw_retry_count > 0) { | ||
1042 | /* load firmware */ | ||
1043 | if (ivtv_firmware_init(itv) == 0) | ||
1044 | break; | ||
1045 | if (fw_retry_count > 1) | ||
1046 | IVTV_WARN("Retry loading firmware\n"); | ||
1047 | } | ||
1048 | if (fw_retry_count == 0) { | ||
1049 | IVTV_ERR("Error initializing firmware\n"); | ||
1050 | goto free_i2c; | ||
1051 | } | ||
1052 | |||
1053 | /* Try and get firmware versions */ | ||
1054 | IVTV_DEBUG_INFO("Getting firmware version..\n"); | ||
1055 | ivtv_firmware_versions(itv); | ||
1056 | |||
1057 | /* Check yuv output filter table */ | 1032 | /* Check yuv output filter table */ |
1058 | if (itv->has_cx23415) ivtv_yuv_filter_check(itv); | 1033 | if (itv->has_cx23415) ivtv_yuv_filter_check(itv); |
1059 | 1034 | ||
@@ -1157,44 +1132,16 @@ static int __devinit ivtv_probe(struct pci_dev *dev, | |||
1157 | ivtv_call_i2c_clients(itv, TUNER_SET_TYPE_ADDR, &setup); | 1132 | ivtv_call_i2c_clients(itv, TUNER_SET_TYPE_ADDR, &setup); |
1158 | } | 1133 | } |
1159 | 1134 | ||
1160 | vf.tuner = 0; | ||
1161 | vf.type = V4L2_TUNER_ANALOG_TV; | ||
1162 | vf.frequency = 6400; /* the tuner 'baseline' frequency */ | ||
1163 | |||
1164 | /* Set initial frequency. For PAL/SECAM broadcasts no | ||
1165 | 'default' channel exists AFAIK. */ | ||
1166 | if (itv->std == V4L2_STD_NTSC_M_JP) { | ||
1167 | vf.frequency = 1460; /* ch. 1 91250*16/1000 */ | ||
1168 | } | ||
1169 | else if (itv->std & V4L2_STD_NTSC_M) { | ||
1170 | vf.frequency = 1076; /* ch. 4 67250*16/1000 */ | ||
1171 | } | ||
1172 | |||
1173 | /* The tuner is fixed to the standard. The other inputs (e.g. S-Video) | 1135 | /* The tuner is fixed to the standard. The other inputs (e.g. S-Video) |
1174 | are not. */ | 1136 | are not. */ |
1175 | itv->tuner_std = itv->std; | 1137 | itv->tuner_std = itv->std; |
1176 | 1138 | ||
1177 | video_input = itv->active_input; | ||
1178 | itv->active_input++; /* Force update of input */ | ||
1179 | ivtv_v4l2_ioctls(itv, NULL, VIDIOC_S_INPUT, &video_input); | ||
1180 | |||
1181 | /* Let the VIDIOC_S_STD ioctl do all the work, keeps the code | ||
1182 | in one place. */ | ||
1183 | itv->std++; /* Force full standard initialization */ | ||
1184 | itv->std_out = itv->std; | ||
1185 | ivtv_v4l2_ioctls(itv, NULL, VIDIOC_S_FREQUENCY, &vf); | ||
1186 | |||
1187 | retval = ivtv_streams_setup(itv); | 1139 | retval = ivtv_streams_setup(itv); |
1188 | if (retval) { | 1140 | if (retval) { |
1189 | IVTV_ERR("Error %d setting up streams\n", retval); | 1141 | IVTV_ERR("Error %d setting up streams\n", retval); |
1190 | goto free_i2c; | 1142 | goto free_i2c; |
1191 | } | 1143 | } |
1192 | 1144 | ||
1193 | if (itv->card->v4l2_capabilities & V4L2_CAP_VIDEO_OUTPUT) { | ||
1194 | ivtv_init_mpeg_decoder(itv); | ||
1195 | } | ||
1196 | ivtv_v4l2_ioctls(itv, NULL, VIDIOC_S_STD, &itv->tuner_std); | ||
1197 | |||
1198 | IVTV_DEBUG_IRQ("Masking interrupts\n"); | 1145 | IVTV_DEBUG_IRQ("Masking interrupts\n"); |
1199 | /* clear interrupt mask, effectively disabling interrupts */ | 1146 | /* clear interrupt mask, effectively disabling interrupts */ |
1200 | ivtv_set_irq_mask(itv, 0xffffffff); | 1147 | ivtv_set_irq_mask(itv, 0xffffffff); |
@@ -1206,26 +1153,7 @@ static int __devinit ivtv_probe(struct pci_dev *dev, | |||
1206 | IVTV_ERR("Failed to register irq %d\n", retval); | 1153 | IVTV_ERR("Failed to register irq %d\n", retval); |
1207 | goto free_streams; | 1154 | goto free_streams; |
1208 | } | 1155 | } |
1209 | |||
1210 | /* On a cx23416 this seems to be able to enable DMA to the chip? */ | ||
1211 | if (!itv->has_cx23415) | ||
1212 | write_reg_sync(0x03, IVTV_REG_DMACONTROL); | ||
1213 | |||
1214 | /* Default interrupts enabled. For the PVR350 this includes the | ||
1215 | decoder VSYNC interrupt, which is always on. It is not only used | ||
1216 | during decoding but also by the OSD. | ||
1217 | Some old PVR250 cards had a cx23415, so testing for that is too | ||
1218 | general. Instead test if the card has video output capability. */ | ||
1219 | if (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT) | ||
1220 | ivtv_clear_irq_mask(itv, IVTV_IRQ_MASK_INIT | IVTV_IRQ_DEC_VSYNC); | ||
1221 | else | ||
1222 | ivtv_clear_irq_mask(itv, IVTV_IRQ_MASK_INIT); | ||
1223 | |||
1224 | if (itv->has_cx23415) | ||
1225 | ivtv_set_osd_alpha(itv); | ||
1226 | |||
1227 | IVTV_INFO("Initialized card #%d: %s\n", itv->num, itv->card_name); | 1156 | IVTV_INFO("Initialized card #%d: %s\n", itv->num, itv->card_name); |
1228 | |||
1229 | return 0; | 1157 | return 0; |
1230 | 1158 | ||
1231 | free_irq: | 1159 | free_irq: |
@@ -1255,55 +1183,126 @@ static int __devinit ivtv_probe(struct pci_dev *dev, | |||
1255 | return retval; | 1183 | return retval; |
1256 | } | 1184 | } |
1257 | 1185 | ||
1186 | int ivtv_init_on_first_open(struct ivtv *itv) | ||
1187 | { | ||
1188 | struct v4l2_frequency vf; | ||
1189 | int fw_retry_count = 3; | ||
1190 | int video_input; | ||
1191 | |||
1192 | while (--fw_retry_count > 0) { | ||
1193 | /* load firmware */ | ||
1194 | if (ivtv_firmware_init(itv) == 0) | ||
1195 | break; | ||
1196 | if (fw_retry_count > 1) | ||
1197 | IVTV_WARN("Retry loading firmware\n"); | ||
1198 | } | ||
1199 | if (fw_retry_count == 0) { | ||
1200 | IVTV_ERR("Error initializing firmware\n"); | ||
1201 | return -1; | ||
1202 | } | ||
1203 | |||
1204 | /* Try and get firmware versions */ | ||
1205 | IVTV_DEBUG_INFO("Getting firmware version..\n"); | ||
1206 | ivtv_firmware_versions(itv); | ||
1207 | |||
1208 | if (itv->card->hw_all & IVTV_HW_CX25840) { | ||
1209 | struct v4l2_control ctrl; | ||
1210 | |||
1211 | /* CX25840_CID_ENABLE_PVR150_WORKAROUND */ | ||
1212 | ctrl.id = V4L2_CID_PRIVATE_BASE; | ||
1213 | ctrl.value = itv->pvr150_workaround; | ||
1214 | itv->video_dec_func(itv, VIDIOC_S_CTRL, &ctrl); | ||
1215 | } | ||
1216 | |||
1217 | vf.tuner = 0; | ||
1218 | vf.type = V4L2_TUNER_ANALOG_TV; | ||
1219 | vf.frequency = 6400; /* the tuner 'baseline' frequency */ | ||
1220 | |||
1221 | /* Set initial frequency. For PAL/SECAM broadcasts no | ||
1222 | 'default' channel exists AFAIK. */ | ||
1223 | if (itv->std == V4L2_STD_NTSC_M_JP) { | ||
1224 | vf.frequency = 1460; /* ch. 1 91250*16/1000 */ | ||
1225 | } | ||
1226 | else if (itv->std & V4L2_STD_NTSC_M) { | ||
1227 | vf.frequency = 1076; /* ch. 4 67250*16/1000 */ | ||
1228 | } | ||
1229 | |||
1230 | video_input = itv->active_input; | ||
1231 | itv->active_input++; /* Force update of input */ | ||
1232 | ivtv_v4l2_ioctls(itv, NULL, VIDIOC_S_INPUT, &video_input); | ||
1233 | |||
1234 | /* Let the VIDIOC_S_STD ioctl do all the work, keeps the code | ||
1235 | in one place. */ | ||
1236 | itv->std++; /* Force full standard initialization */ | ||
1237 | itv->std_out = itv->std; | ||
1238 | ivtv_v4l2_ioctls(itv, NULL, VIDIOC_S_FREQUENCY, &vf); | ||
1239 | |||
1240 | if (itv->card->v4l2_capabilities & V4L2_CAP_VIDEO_OUTPUT) { | ||
1241 | ivtv_init_mpeg_decoder(itv); | ||
1242 | } | ||
1243 | ivtv_v4l2_ioctls(itv, NULL, VIDIOC_S_STD, &itv->tuner_std); | ||
1244 | |||
1245 | /* On a cx23416 this seems to be able to enable DMA to the chip? */ | ||
1246 | if (!itv->has_cx23415) | ||
1247 | write_reg_sync(0x03, IVTV_REG_DMACONTROL); | ||
1248 | |||
1249 | /* Default interrupts enabled. For the PVR350 this includes the | ||
1250 | decoder VSYNC interrupt, which is always on. It is not only used | ||
1251 | during decoding but also by the OSD. | ||
1252 | Some old PVR250 cards had a cx23415, so testing for that is too | ||
1253 | general. Instead test if the card has video output capability. */ | ||
1254 | if (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT) { | ||
1255 | ivtv_clear_irq_mask(itv, IVTV_IRQ_MASK_INIT | IVTV_IRQ_DEC_VSYNC); | ||
1256 | ivtv_set_osd_alpha(itv); | ||
1257 | } | ||
1258 | else | ||
1259 | ivtv_clear_irq_mask(itv, IVTV_IRQ_MASK_INIT); | ||
1260 | return 0; | ||
1261 | } | ||
1262 | |||
1258 | static void ivtv_remove(struct pci_dev *pci_dev) | 1263 | static void ivtv_remove(struct pci_dev *pci_dev) |
1259 | { | 1264 | { |
1260 | struct ivtv *itv = pci_get_drvdata(pci_dev); | 1265 | struct ivtv *itv = pci_get_drvdata(pci_dev); |
1261 | 1266 | ||
1262 | IVTV_DEBUG_INFO("Removing Card #%d\n", itv->num); | 1267 | IVTV_DEBUG_INFO("Removing Card #%d\n", itv->num); |
1263 | 1268 | ||
1264 | /* Stop all captures */ | 1269 | if (test_bit(IVTV_F_I_INITED, &itv->i_flags)) { |
1265 | IVTV_DEBUG_INFO("Stopping all streams\n"); | 1270 | /* Stop all captures */ |
1266 | if (atomic_read(&itv->capturing) > 0) | 1271 | IVTV_DEBUG_INFO("Stopping all streams\n"); |
1267 | ivtv_stop_all_captures(itv); | 1272 | if (atomic_read(&itv->capturing) > 0) |
1268 | 1273 | ivtv_stop_all_captures(itv); | |
1269 | /* Stop all decoding */ | 1274 | |
1270 | IVTV_DEBUG_INFO("Stopping decoding\n"); | 1275 | /* Stop all decoding */ |
1271 | if (atomic_read(&itv->decoding) > 0) { | 1276 | IVTV_DEBUG_INFO("Stopping decoding\n"); |
1272 | int type; | 1277 | if (atomic_read(&itv->decoding) > 0) { |
1273 | 1278 | int type; | |
1274 | if (test_bit(IVTV_F_I_DEC_YUV, &itv->i_flags)) | 1279 | |
1275 | type = IVTV_DEC_STREAM_TYPE_YUV; | 1280 | if (test_bit(IVTV_F_I_DEC_YUV, &itv->i_flags)) |
1276 | else | 1281 | type = IVTV_DEC_STREAM_TYPE_YUV; |
1277 | type = IVTV_DEC_STREAM_TYPE_MPG; | 1282 | else |
1278 | ivtv_stop_v4l2_decode_stream(&itv->streams[type], | 1283 | type = IVTV_DEC_STREAM_TYPE_MPG; |
1279 | VIDEO_CMD_STOP_TO_BLACK | VIDEO_CMD_STOP_IMMEDIATELY, 0); | 1284 | ivtv_stop_v4l2_decode_stream(&itv->streams[type], |
1285 | VIDEO_CMD_STOP_TO_BLACK | VIDEO_CMD_STOP_IMMEDIATELY, 0); | ||
1286 | } | ||
1287 | ivtv_halt_firmware(itv); | ||
1280 | } | 1288 | } |
1281 | 1289 | ||
1282 | /* Interrupts */ | 1290 | /* Interrupts */ |
1283 | IVTV_DEBUG_INFO("Disabling interrupts\n"); | ||
1284 | ivtv_set_irq_mask(itv, 0xffffffff); | 1291 | ivtv_set_irq_mask(itv, 0xffffffff); |
1285 | del_timer_sync(&itv->dma_timer); | 1292 | del_timer_sync(&itv->dma_timer); |
1286 | 1293 | ||
1287 | /* Stop all Work Queues */ | 1294 | /* Stop all Work Queues */ |
1288 | IVTV_DEBUG_INFO("Stop Work Queues\n"); | ||
1289 | flush_workqueue(itv->irq_work_queues); | 1295 | flush_workqueue(itv->irq_work_queues); |
1290 | destroy_workqueue(itv->irq_work_queues); | 1296 | destroy_workqueue(itv->irq_work_queues); |
1291 | 1297 | ||
1292 | IVTV_DEBUG_INFO("Stopping Firmware\n"); | ||
1293 | ivtv_halt_firmware(itv); | ||
1294 | |||
1295 | IVTV_DEBUG_INFO("Unregistering v4l devices\n"); | ||
1296 | ivtv_streams_cleanup(itv); | 1298 | ivtv_streams_cleanup(itv); |
1297 | IVTV_DEBUG_INFO("Freeing dma resources\n"); | ||
1298 | ivtv_udma_free(itv); | 1299 | ivtv_udma_free(itv); |
1299 | 1300 | ||
1300 | exit_ivtv_i2c(itv); | 1301 | exit_ivtv_i2c(itv); |
1301 | 1302 | ||
1302 | IVTV_DEBUG_INFO(" Releasing irq\n"); | ||
1303 | free_irq(itv->dev->irq, (void *)itv); | 1303 | free_irq(itv->dev->irq, (void *)itv); |
1304 | ivtv_iounmap(itv); | 1304 | ivtv_iounmap(itv); |
1305 | 1305 | ||
1306 | IVTV_DEBUG_INFO(" Releasing mem\n"); | ||
1307 | release_mem_region(itv->base_addr, IVTV_ENCODER_SIZE); | 1306 | release_mem_region(itv->base_addr, IVTV_ENCODER_SIZE); |
1308 | release_mem_region(itv->base_addr + IVTV_REG_OFFSET, IVTV_REG_SIZE); | 1307 | release_mem_region(itv->base_addr + IVTV_REG_OFFSET, IVTV_REG_SIZE); |
1309 | if (itv->has_cx23415) | 1308 | if (itv->has_cx23415) |
diff --git a/drivers/media/video/ivtv/ivtv-driver.h b/drivers/media/video/ivtv/ivtv-driver.h index 8fe9d9c7a18..6e53a1f04f7 100644 --- a/drivers/media/video/ivtv/ivtv-driver.h +++ b/drivers/media/video/ivtv/ivtv-driver.h | |||
@@ -398,6 +398,8 @@ struct ivtv_mailbox_data { | |||
398 | #define IVTV_F_I_WORK_HANDLER_PIO 18 /* there is work to be done for PIO */ | 398 | #define IVTV_F_I_WORK_HANDLER_PIO 18 /* there is work to be done for PIO */ |
399 | #define IVTV_F_I_PIO 19 /* PIO in progress */ | 399 | #define IVTV_F_I_PIO 19 /* PIO in progress */ |
400 | #define IVTV_F_I_DEC_PAUSED 20 /* the decoder is paused */ | 400 | #define IVTV_F_I_DEC_PAUSED 20 /* the decoder is paused */ |
401 | #define IVTV_F_I_INITED 21 /* set after first open */ | ||
402 | #define IVTV_F_I_FAILED 22 /* set if first open failed */ | ||
401 | 403 | ||
402 | /* Event notifications */ | 404 | /* Event notifications */ |
403 | #define IVTV_F_I_EV_DEC_STOPPED 28 /* decoder stopped event */ | 405 | #define IVTV_F_I_EV_DEC_STOPPED 28 /* decoder stopped event */ |
@@ -838,6 +840,9 @@ int ivtv_waitq(wait_queue_head_t *waitq); | |||
838 | struct tveeprom; /* forward reference */ | 840 | struct tveeprom; /* forward reference */ |
839 | void ivtv_read_eeprom(struct ivtv *itv, struct tveeprom *tv); | 841 | void ivtv_read_eeprom(struct ivtv *itv, struct tveeprom *tv); |
840 | 842 | ||
843 | /* First-open initialization: load firmware, init cx25840, etc. */ | ||
844 | int ivtv_init_on_first_open(struct ivtv *itv); | ||
845 | |||
841 | /* This is a PCI post thing, where if the pci register is not read, then | 846 | /* This is a PCI post thing, where if the pci register is not read, then |
842 | the write doesn't always take effect right away. By reading back the | 847 | the write doesn't always take effect right away. By reading back the |
843 | register any pending PCI writes will be performed (in order), and so | 848 | register any pending PCI writes will be performed (in order), and so |
diff --git a/drivers/media/video/ivtv/ivtv-fileops.c b/drivers/media/video/ivtv/ivtv-fileops.c index 66ea3cbc369..49886084164 100644 --- a/drivers/media/video/ivtv/ivtv-fileops.c +++ b/drivers/media/video/ivtv/ivtv-fileops.c | |||
@@ -850,6 +850,15 @@ int ivtv_v4l2_open(struct inode *inode, struct file *filp) | |||
850 | return -ENXIO; | 850 | return -ENXIO; |
851 | } | 851 | } |
852 | 852 | ||
853 | if (!test_and_set_bit(IVTV_F_I_INITED, &itv->i_flags)) | ||
854 | if (ivtv_init_on_first_open(itv)) | ||
855 | set_bit(IVTV_F_I_FAILED, &itv->i_flags); | ||
856 | |||
857 | if (test_bit(IVTV_F_I_FAILED, &itv->i_flags)) { | ||
858 | printk(KERN_WARNING "ivtv: failed to initialize on minor %d\n", minor); | ||
859 | return -ENXIO; | ||
860 | } | ||
861 | |||
853 | if (y == IVTV_DEC_STREAM_TYPE_MPG && | 862 | if (y == IVTV_DEC_STREAM_TYPE_MPG && |
854 | test_bit(IVTV_F_S_CLAIMED, &itv->streams[IVTV_DEC_STREAM_TYPE_YUV].s_flags)) | 863 | test_bit(IVTV_F_S_CLAIMED, &itv->streams[IVTV_DEC_STREAM_TYPE_YUV].s_flags)) |
855 | return -EBUSY; | 864 | return -EBUSY; |