aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/dvb/ttpci/budget-ci.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/dvb/ttpci/budget-ci.c')
-rw-r--r--drivers/media/dvb/ttpci/budget-ci.c60
1 files changed, 37 insertions, 23 deletions
diff --git a/drivers/media/dvb/ttpci/budget-ci.c b/drivers/media/dvb/ttpci/budget-ci.c
index 0809fb90c264..b2869ab8b7b9 100644
--- a/drivers/media/dvb/ttpci/budget-ci.c
+++ b/drivers/media/dvb/ttpci/budget-ci.c
@@ -198,11 +198,13 @@ static int msp430_ir_init(struct budget_ci *budget_ci)
198 struct saa7146_dev *saa = budget_ci->budget.dev; 198 struct saa7146_dev *saa = budget_ci->budget.dev;
199 struct input_dev *input_dev = budget_ci->ir.dev; 199 struct input_dev *input_dev = budget_ci->ir.dev;
200 int i; 200 int i;
201 int err; 201 int error;
202 202
203 budget_ci->ir.dev = input_dev = input_allocate_device(); 203 budget_ci->ir.dev = input_dev = input_allocate_device();
204 if (!input_dev) 204 if (!input_dev) {
205 return -ENOMEM; 205 error = -ENOMEM;
206 goto out1;
207 }
206 208
207 snprintf(budget_ci->ir.name, sizeof(budget_ci->ir.name), 209 snprintf(budget_ci->ir.name, sizeof(budget_ci->ir.name),
208 "Budget-CI dvb ir receiver %s", saa->name); 210 "Budget-CI dvb ir receiver %s", saa->name);
@@ -232,20 +234,26 @@ static int msp430_ir_init(struct budget_ci *budget_ci)
232 if (key_map[i]) 234 if (key_map[i])
233 set_bit(key_map[i], input_dev->keybit); 235 set_bit(key_map[i], input_dev->keybit);
234 236
235 err = input_register_device(input_dev); 237 error = input_register_device(input_dev);
236 if (err) { 238 if (error) {
237 input_free_device(input_dev); 239 printk(KERN_ERR "budget_ci: could not init driver for IR device (code %d)\n", error);
238 return err; 240 goto out2;
239 } 241 }
240 242
241 input_register_device(budget_ci->ir.dev);
242
243 input_dev->timer.function = msp430_ir_debounce; 243 input_dev->timer.function = msp430_ir_debounce;
244 244
245 tasklet_init(&budget_ci->ir.msp430_irq_tasklet, msp430_ir_interrupt,
246 (unsigned long) budget_ci);
247
245 saa7146_write(saa, IER, saa7146_read(saa, IER) | MASK_06); 248 saa7146_write(saa, IER, saa7146_read(saa, IER) | MASK_06);
246 saa7146_setgpio(saa, 3, SAA7146_GPIO_IRQHI); 249 saa7146_setgpio(saa, 3, SAA7146_GPIO_IRQHI);
247 250
248 return 0; 251 return 0;
252
253out2:
254 input_free_device(input_dev);
255out1:
256 return error;
249} 257}
250 258
251static void msp430_ir_deinit(struct budget_ci *budget_ci) 259static void msp430_ir_deinit(struct budget_ci *budget_ci)
@@ -255,6 +263,7 @@ static void msp430_ir_deinit(struct budget_ci *budget_ci)
255 263
256 saa7146_write(saa, IER, saa7146_read(saa, IER) & ~MASK_06); 264 saa7146_write(saa, IER, saa7146_read(saa, IER) & ~MASK_06);
257 saa7146_setgpio(saa, 3, SAA7146_GPIO_INPUT); 265 saa7146_setgpio(saa, 3, SAA7146_GPIO_INPUT);
266 tasklet_kill(&budget_ci->ir.msp430_irq_tasklet);
258 267
259 if (del_timer(&dev->timer)) { 268 if (del_timer(&dev->timer)) {
260 input_event(dev, EV_KEY, key_map[dev->repeat_key], 0); 269 input_event(dev, EV_KEY, key_map[dev->repeat_key], 0);
@@ -1115,8 +1124,11 @@ static int budget_ci_attach(struct saa7146_dev *dev, struct saa7146_pci_extensio
1115 struct budget_ci *budget_ci; 1124 struct budget_ci *budget_ci;
1116 int err; 1125 int err;
1117 1126
1118 if (!(budget_ci = kmalloc(sizeof(struct budget_ci), GFP_KERNEL))) 1127 budget_ci = kmalloc(sizeof(struct budget_ci), GFP_KERNEL);
1119 return -ENOMEM; 1128 if (!budget_ci) {
1129 err = -ENOMEM;
1130 goto out1;
1131 }
1120 1132
1121 dprintk(2, "budget_ci: %p\n", budget_ci); 1133 dprintk(2, "budget_ci: %p\n", budget_ci);
1122 1134
@@ -1124,15 +1136,13 @@ static int budget_ci_attach(struct saa7146_dev *dev, struct saa7146_pci_extensio
1124 1136
1125 dev->ext_priv = budget_ci; 1137 dev->ext_priv = budget_ci;
1126 1138
1127 if ((err = ttpci_budget_init(&budget_ci->budget, dev, info, THIS_MODULE))) { 1139 err = ttpci_budget_init(&budget_ci->budget, dev, info, THIS_MODULE);
1128 kfree(budget_ci); 1140 if (err)
1129 return err; 1141 goto out2;
1130 }
1131 1142
1132 tasklet_init(&budget_ci->ir.msp430_irq_tasklet, msp430_ir_interrupt, 1143 err = msp430_ir_init(budget_ci);
1133 (unsigned long) budget_ci); 1144 if (err)
1134 1145 goto out3;
1135 msp430_ir_init(budget_ci);
1136 1146
1137 ciintf_init(budget_ci); 1147 ciintf_init(budget_ci);
1138 1148
@@ -1142,6 +1152,13 @@ static int budget_ci_attach(struct saa7146_dev *dev, struct saa7146_pci_extensio
1142 ttpci_budget_init_hooks(&budget_ci->budget); 1152 ttpci_budget_init_hooks(&budget_ci->budget);
1143 1153
1144 return 0; 1154 return 0;
1155
1156out3:
1157 ttpci_budget_deinit(&budget_ci->budget);
1158out2:
1159 kfree(budget_ci);
1160out1:
1161 return err;
1145} 1162}
1146 1163
1147static int budget_ci_detach(struct saa7146_dev *dev) 1164static int budget_ci_detach(struct saa7146_dev *dev)
@@ -1152,16 +1169,13 @@ static int budget_ci_detach(struct saa7146_dev *dev)
1152 1169
1153 if (budget_ci->budget.ci_present) 1170 if (budget_ci->budget.ci_present)
1154 ciintf_deinit(budget_ci); 1171 ciintf_deinit(budget_ci);
1172 msp430_ir_deinit(budget_ci);
1155 if (budget_ci->budget.dvb_frontend) { 1173 if (budget_ci->budget.dvb_frontend) {
1156 dvb_unregister_frontend(budget_ci->budget.dvb_frontend); 1174 dvb_unregister_frontend(budget_ci->budget.dvb_frontend);
1157 dvb_frontend_detach(budget_ci->budget.dvb_frontend); 1175 dvb_frontend_detach(budget_ci->budget.dvb_frontend);
1158 } 1176 }
1159 err = ttpci_budget_deinit(&budget_ci->budget); 1177 err = ttpci_budget_deinit(&budget_ci->budget);
1160 1178
1161 tasklet_kill(&budget_ci->ir.msp430_irq_tasklet);
1162
1163 msp430_ir_deinit(budget_ci);
1164
1165 // disable frontend and CI interface 1179 // disable frontend and CI interface
1166 saa7146_setgpio(saa, 2, SAA7146_GPIO_INPUT); 1180 saa7146_setgpio(saa, 2, SAA7146_GPIO_INPUT);
1167 1181