aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLuis Henriques <luis.henriques@canonical.com>2012-04-21 11:25:21 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2012-05-21 12:40:01 -0400
commit423b4f2750ebb8cb06c20396b66fb0144b92bbda (patch)
tree737ae2ca8eac42b98908c7a8248380c176896d23
parentdbda13fc2193061009cd20998f64dd01a97309a9 (diff)
media: rc: Postpone ISR registration
commit 9ef449c6b31bb6a8e6dedc24de475a3b8c79be20 upstream. An early registration of an ISR was causing a crash to several users (for example, with the ite-cir driver: http://bugs.launchpad.net/bugs/972723). The reason was that IRQs were being triggered before a driver initialisation was completed. This patch fixes this by moving the invocation to request_irq() and to request_region() to a later stage on the driver probe function. Signed-off-by: Luis Henriques <luis.henriques@canonical.com> Acked-by: Jarod Wilson <jarod@redhat.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--drivers/media/rc/ene_ir.c32
-rw-r--r--drivers/media/rc/fintek-cir.c20
-rw-r--r--drivers/media/rc/ite-cir.c20
-rw-r--r--drivers/media/rc/nuvoton-cir.c36
-rw-r--r--drivers/media/rc/winbond-cir.c78
5 files changed, 93 insertions, 93 deletions
diff --git a/drivers/media/rc/ene_ir.c b/drivers/media/rc/ene_ir.c
index a43ed6c41bf..12b91ae1b20 100644
--- a/drivers/media/rc/ene_ir.c
+++ b/drivers/media/rc/ene_ir.c
@@ -1017,22 +1017,6 @@ static int ene_probe(struct pnp_dev *pnp_dev, const struct pnp_device_id *id)
1017 1017
1018 spin_lock_init(&dev->hw_lock); 1018 spin_lock_init(&dev->hw_lock);
1019 1019
1020 /* claim the resources */
1021 error = -EBUSY;
1022 dev->hw_io = pnp_port_start(pnp_dev, 0);
1023 if (!request_region(dev->hw_io, ENE_IO_SIZE, ENE_DRIVER_NAME)) {
1024 dev->hw_io = -1;
1025 dev->irq = -1;
1026 goto error;
1027 }
1028
1029 dev->irq = pnp_irq(pnp_dev, 0);
1030 if (request_irq(dev->irq, ene_isr,
1031 IRQF_SHARED, ENE_DRIVER_NAME, (void *)dev)) {
1032 dev->irq = -1;
1033 goto error;
1034 }
1035
1036 pnp_set_drvdata(pnp_dev, dev); 1020 pnp_set_drvdata(pnp_dev, dev);
1037 dev->pnp_dev = pnp_dev; 1021 dev->pnp_dev = pnp_dev;
1038 1022
@@ -1085,6 +1069,22 @@ static int ene_probe(struct pnp_dev *pnp_dev, const struct pnp_device_id *id)
1085 device_set_wakeup_capable(&pnp_dev->dev, true); 1069 device_set_wakeup_capable(&pnp_dev->dev, true);
1086 device_set_wakeup_enable(&pnp_dev->dev, true); 1070 device_set_wakeup_enable(&pnp_dev->dev, true);
1087 1071
1072 /* claim the resources */
1073 error = -EBUSY;
1074 dev->hw_io = pnp_port_start(pnp_dev, 0);
1075 if (!request_region(dev->hw_io, ENE_IO_SIZE, ENE_DRIVER_NAME)) {
1076 dev->hw_io = -1;
1077 dev->irq = -1;
1078 goto error;
1079 }
1080
1081 dev->irq = pnp_irq(pnp_dev, 0);
1082 if (request_irq(dev->irq, ene_isr,
1083 IRQF_SHARED, ENE_DRIVER_NAME, (void *)dev)) {
1084 dev->irq = -1;
1085 goto error;
1086 }
1087
1088 error = rc_register_device(rdev); 1088 error = rc_register_device(rdev);
1089 if (error < 0) 1089 if (error < 0)
1090 goto error; 1090 goto error;
diff --git a/drivers/media/rc/fintek-cir.c b/drivers/media/rc/fintek-cir.c
index 7f7079b12f2..4218f7369c5 100644
--- a/drivers/media/rc/fintek-cir.c
+++ b/drivers/media/rc/fintek-cir.c
@@ -504,16 +504,6 @@ static int fintek_probe(struct pnp_dev *pdev, const struct pnp_device_id *dev_id
504 504
505 spin_lock_init(&fintek->fintek_lock); 505 spin_lock_init(&fintek->fintek_lock);
506 506
507 ret = -EBUSY;
508 /* now claim resources */
509 if (!request_region(fintek->cir_addr,
510 fintek->cir_port_len, FINTEK_DRIVER_NAME))
511 goto failure;
512
513 if (request_irq(fintek->cir_irq, fintek_cir_isr, IRQF_SHARED,
514 FINTEK_DRIVER_NAME, (void *)fintek))
515 goto failure;
516
517 pnp_set_drvdata(pdev, fintek); 507 pnp_set_drvdata(pdev, fintek);
518 fintek->pdev = pdev; 508 fintek->pdev = pdev;
519 509
@@ -548,6 +538,16 @@ static int fintek_probe(struct pnp_dev *pdev, const struct pnp_device_id *dev_id
548 /* rx resolution is hardwired to 50us atm, 1, 25, 100 also possible */ 538 /* rx resolution is hardwired to 50us atm, 1, 25, 100 also possible */
549 rdev->rx_resolution = US_TO_NS(CIR_SAMPLE_PERIOD); 539 rdev->rx_resolution = US_TO_NS(CIR_SAMPLE_PERIOD);
550 540
541 ret = -EBUSY;
542 /* now claim resources */
543 if (!request_region(fintek->cir_addr,
544 fintek->cir_port_len, FINTEK_DRIVER_NAME))
545 goto failure;
546
547 if (request_irq(fintek->cir_irq, fintek_cir_isr, IRQF_SHARED,
548 FINTEK_DRIVER_NAME, (void *)fintek))
549 goto failure;
550
551 ret = rc_register_device(rdev); 551 ret = rc_register_device(rdev);
552 if (ret) 552 if (ret)
553 goto failure; 553 goto failure;
diff --git a/drivers/media/rc/ite-cir.c b/drivers/media/rc/ite-cir.c
index ecd3d028076..c5ca0914087 100644
--- a/drivers/media/rc/ite-cir.c
+++ b/drivers/media/rc/ite-cir.c
@@ -1519,16 +1519,6 @@ static int ite_probe(struct pnp_dev *pdev, const struct pnp_device_id
1519 /* initialize raw event */ 1519 /* initialize raw event */
1520 init_ir_raw_event(&itdev->rawir); 1520 init_ir_raw_event(&itdev->rawir);
1521 1521
1522 ret = -EBUSY;
1523 /* now claim resources */
1524 if (!request_region(itdev->cir_addr,
1525 dev_desc->io_region_size, ITE_DRIVER_NAME))
1526 goto failure;
1527
1528 if (request_irq(itdev->cir_irq, ite_cir_isr, IRQF_SHARED,
1529 ITE_DRIVER_NAME, (void *)itdev))
1530 goto failure;
1531
1532 /* set driver data into the pnp device */ 1522 /* set driver data into the pnp device */
1533 pnp_set_drvdata(pdev, itdev); 1523 pnp_set_drvdata(pdev, itdev);
1534 itdev->pdev = pdev; 1524 itdev->pdev = pdev;
@@ -1604,6 +1594,16 @@ static int ite_probe(struct pnp_dev *pdev, const struct pnp_device_id
1604 rdev->driver_name = ITE_DRIVER_NAME; 1594 rdev->driver_name = ITE_DRIVER_NAME;
1605 rdev->map_name = RC_MAP_RC6_MCE; 1595 rdev->map_name = RC_MAP_RC6_MCE;
1606 1596
1597 ret = -EBUSY;
1598 /* now claim resources */
1599 if (!request_region(itdev->cir_addr,
1600 dev_desc->io_region_size, ITE_DRIVER_NAME))
1601 goto failure;
1602
1603 if (request_irq(itdev->cir_irq, ite_cir_isr, IRQF_SHARED,
1604 ITE_DRIVER_NAME, (void *)itdev))
1605 goto failure;
1606
1607 ret = rc_register_device(rdev); 1607 ret = rc_register_device(rdev);
1608 if (ret) 1608 if (ret)
1609 goto failure; 1609 goto failure;
diff --git a/drivers/media/rc/nuvoton-cir.c b/drivers/media/rc/nuvoton-cir.c
index 9fd019e6b9b..c212276202f 100644
--- a/drivers/media/rc/nuvoton-cir.c
+++ b/drivers/media/rc/nuvoton-cir.c
@@ -1027,24 +1027,6 @@ static int nvt_probe(struct pnp_dev *pdev, const struct pnp_device_id *dev_id)
1027 spin_lock_init(&nvt->nvt_lock); 1027 spin_lock_init(&nvt->nvt_lock);
1028 spin_lock_init(&nvt->tx.lock); 1028 spin_lock_init(&nvt->tx.lock);
1029 1029
1030 ret = -EBUSY;
1031 /* now claim resources */
1032 if (!request_region(nvt->cir_addr,
1033 CIR_IOREG_LENGTH, NVT_DRIVER_NAME))
1034 goto failure;
1035
1036 if (request_irq(nvt->cir_irq, nvt_cir_isr, IRQF_SHARED,
1037 NVT_DRIVER_NAME, (void *)nvt))
1038 goto failure;
1039
1040 if (!request_region(nvt->cir_wake_addr,
1041 CIR_IOREG_LENGTH, NVT_DRIVER_NAME))
1042 goto failure;
1043
1044 if (request_irq(nvt->cir_wake_irq, nvt_cir_wake_isr, IRQF_SHARED,
1045 NVT_DRIVER_NAME, (void *)nvt))
1046 goto failure;
1047
1048 pnp_set_drvdata(pdev, nvt); 1030 pnp_set_drvdata(pdev, nvt);
1049 nvt->pdev = pdev; 1031 nvt->pdev = pdev;
1050 1032
@@ -1091,6 +1073,24 @@ static int nvt_probe(struct pnp_dev *pdev, const struct pnp_device_id *dev_id)
1091 rdev->tx_resolution = XYZ; 1073 rdev->tx_resolution = XYZ;
1092#endif 1074#endif
1093 1075
1076 ret = -EBUSY;
1077 /* now claim resources */
1078 if (!request_region(nvt->cir_addr,
1079 CIR_IOREG_LENGTH, NVT_DRIVER_NAME))
1080 goto failure;
1081
1082 if (request_irq(nvt->cir_irq, nvt_cir_isr, IRQF_SHARED,
1083 NVT_DRIVER_NAME, (void *)nvt))
1084 goto failure;
1085
1086 if (!request_region(nvt->cir_wake_addr,
1087 CIR_IOREG_LENGTH, NVT_DRIVER_NAME))
1088 goto failure;
1089
1090 if (request_irq(nvt->cir_wake_irq, nvt_cir_wake_isr, IRQF_SHARED,
1091 NVT_DRIVER_NAME, (void *)nvt))
1092 goto failure;
1093
1094 ret = rc_register_device(rdev); 1094 ret = rc_register_device(rdev);
1095 if (ret) 1095 if (ret)
1096 goto failure; 1096 goto failure;
diff --git a/drivers/media/rc/winbond-cir.c b/drivers/media/rc/winbond-cir.c
index 6f03846ab1f..9e55a0c9ac5 100644
--- a/drivers/media/rc/winbond-cir.c
+++ b/drivers/media/rc/winbond-cir.c
@@ -1003,39 +1003,10 @@ wbcir_probe(struct pnp_dev *device, const struct pnp_device_id *dev_id)
1003 "(w: 0x%lX, e: 0x%lX, s: 0x%lX, i: %u)\n", 1003 "(w: 0x%lX, e: 0x%lX, s: 0x%lX, i: %u)\n",
1004 data->wbase, data->ebase, data->sbase, data->irq); 1004 data->wbase, data->ebase, data->sbase, data->irq);
1005 1005
1006 if (!request_region(data->wbase, WAKEUP_IOMEM_LEN, DRVNAME)) {
1007 dev_err(dev, "Region 0x%lx-0x%lx already in use!\n",
1008 data->wbase, data->wbase + WAKEUP_IOMEM_LEN - 1);
1009 err = -EBUSY;
1010 goto exit_free_data;
1011 }
1012
1013 if (!request_region(data->ebase, EHFUNC_IOMEM_LEN, DRVNAME)) {
1014 dev_err(dev, "Region 0x%lx-0x%lx already in use!\n",
1015 data->ebase, data->ebase + EHFUNC_IOMEM_LEN - 1);
1016 err = -EBUSY;
1017 goto exit_release_wbase;
1018 }
1019
1020 if (!request_region(data->sbase, SP_IOMEM_LEN, DRVNAME)) {
1021 dev_err(dev, "Region 0x%lx-0x%lx already in use!\n",
1022 data->sbase, data->sbase + SP_IOMEM_LEN - 1);
1023 err = -EBUSY;
1024 goto exit_release_ebase;
1025 }
1026
1027 err = request_irq(data->irq, wbcir_irq_handler,
1028 IRQF_DISABLED, DRVNAME, device);
1029 if (err) {
1030 dev_err(dev, "Failed to claim IRQ %u\n", data->irq);
1031 err = -EBUSY;
1032 goto exit_release_sbase;
1033 }
1034
1035 led_trigger_register_simple("cir-tx", &data->txtrigger); 1006 led_trigger_register_simple("cir-tx", &data->txtrigger);
1036 if (!data->txtrigger) { 1007 if (!data->txtrigger) {
1037 err = -ENOMEM; 1008 err = -ENOMEM;
1038 goto exit_free_irq; 1009 goto exit_free_data;
1039 } 1010 }
1040 1011
1041 led_trigger_register_simple("cir-rx", &data->rxtrigger); 1012 led_trigger_register_simple("cir-rx", &data->rxtrigger);
@@ -1074,9 +1045,38 @@ wbcir_probe(struct pnp_dev *device, const struct pnp_device_id *dev_id)
1074 data->dev->priv = data; 1045 data->dev->priv = data;
1075 data->dev->dev.parent = &device->dev; 1046 data->dev->dev.parent = &device->dev;
1076 1047
1048 if (!request_region(data->wbase, WAKEUP_IOMEM_LEN, DRVNAME)) {
1049 dev_err(dev, "Region 0x%lx-0x%lx already in use!\n",
1050 data->wbase, data->wbase + WAKEUP_IOMEM_LEN - 1);
1051 err = -EBUSY;
1052 goto exit_free_rc;
1053 }
1054
1055 if (!request_region(data->ebase, EHFUNC_IOMEM_LEN, DRVNAME)) {
1056 dev_err(dev, "Region 0x%lx-0x%lx already in use!\n",
1057 data->ebase, data->ebase + EHFUNC_IOMEM_LEN - 1);
1058 err = -EBUSY;
1059 goto exit_release_wbase;
1060 }
1061
1062 if (!request_region(data->sbase, SP_IOMEM_LEN, DRVNAME)) {
1063 dev_err(dev, "Region 0x%lx-0x%lx already in use!\n",
1064 data->sbase, data->sbase + SP_IOMEM_LEN - 1);
1065 err = -EBUSY;
1066 goto exit_release_ebase;
1067 }
1068
1069 err = request_irq(data->irq, wbcir_irq_handler,
1070 IRQF_DISABLED, DRVNAME, device);
1071 if (err) {
1072 dev_err(dev, "Failed to claim IRQ %u\n", data->irq);
1073 err = -EBUSY;
1074 goto exit_release_sbase;
1075 }
1076
1077 err = rc_register_device(data->dev); 1077 err = rc_register_device(data->dev);
1078 if (err) 1078 if (err)
1079 goto exit_free_rc; 1079 goto exit_free_irq;
1080 1080
1081 device_init_wakeup(&device->dev, 1); 1081 device_init_wakeup(&device->dev, 1);
1082 1082
@@ -1084,14 +1084,6 @@ wbcir_probe(struct pnp_dev *device, const struct pnp_device_id *dev_id)
1084 1084
1085 return 0; 1085 return 0;
1086 1086
1087exit_free_rc:
1088 rc_free_device(data->dev);
1089exit_unregister_led:
1090 led_classdev_unregister(&data->led);
1091exit_unregister_rxtrigger:
1092 led_trigger_unregister_simple(data->rxtrigger);
1093exit_unregister_txtrigger:
1094 led_trigger_unregister_simple(data->txtrigger);
1095exit_free_irq: 1087exit_free_irq:
1096 free_irq(data->irq, device); 1088 free_irq(data->irq, device);
1097exit_release_sbase: 1089exit_release_sbase:
@@ -1100,6 +1092,14 @@ exit_release_ebase:
1100 release_region(data->ebase, EHFUNC_IOMEM_LEN); 1092 release_region(data->ebase, EHFUNC_IOMEM_LEN);
1101exit_release_wbase: 1093exit_release_wbase:
1102 release_region(data->wbase, WAKEUP_IOMEM_LEN); 1094 release_region(data->wbase, WAKEUP_IOMEM_LEN);
1095exit_free_rc:
1096 rc_free_device(data->dev);
1097exit_unregister_led:
1098 led_classdev_unregister(&data->led);
1099exit_unregister_rxtrigger:
1100 led_trigger_unregister_simple(data->rxtrigger);
1101exit_unregister_txtrigger:
1102 led_trigger_unregister_simple(data->txtrigger);
1103exit_free_data: 1103exit_free_data:
1104 kfree(data); 1104 kfree(data);
1105 pnp_set_drvdata(device, NULL); 1105 pnp_set_drvdata(device, NULL);