aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pcmcia
diff options
context:
space:
mode:
authorDominik Brodowski <linux@dominikbrodowski.net>2010-03-07 06:21:16 -0500
committerDominik Brodowski <linux@dominikbrodowski.net>2010-05-10 04:23:13 -0400
commiteb14120f743d29744d9475bffec56ff4ad43a749 (patch)
tree56857094d2b0cfc0ecbd1685f18d6edbe78e140f /drivers/pcmcia
parenta7debe789dfcaee9c4d81e5738b0be8c5d93930b (diff)
pcmcia: re-work pcmcia_request_irq()
Instead of the old pcmcia_request_irq() interface, drivers may now choose between: - calling request_irq/free_irq directly. Use the IRQ from *p_dev->irq. - use pcmcia_request_irq(p_dev, handler_t); the PCMCIA core will clean up automatically on calls to pcmcia_disable_device() or device ejection. - drivers still not capable of IRQF_SHARED (or not telling us so) may use the deprecated pcmcia_request_exclusive_irq() for the time being; they might receive a shared IRQ nonetheless. CC: linux-bluetooth@vger.kernel.org CC: netdev@vger.kernel.org CC: linux-wireless@vger.kernel.org CC: linux-serial@vger.kernel.org CC: alsa-devel@alsa-project.org CC: linux-usb@vger.kernel.org CC: linux-ide@vger.kernel.org Signed-off-by: Dominik Brodowski <linux@dominikbrodowski.net>
Diffstat (limited to 'drivers/pcmcia')
-rw-r--r--drivers/pcmcia/ds.c3
-rw-r--r--drivers/pcmcia/pcmcia_resource.c137
2 files changed, 55 insertions, 85 deletions
diff --git a/drivers/pcmcia/ds.c b/drivers/pcmcia/ds.c
index 5fd2948c7ed9..a2649c7b05bd 100644
--- a/drivers/pcmcia/ds.c
+++ b/drivers/pcmcia/ds.c
@@ -546,7 +546,6 @@ struct pcmcia_device *pcmcia_device_add(struct pcmcia_socket *s, unsigned int fu
546 p_dev->function_config = tmp_dev->function_config; 546 p_dev->function_config = tmp_dev->function_config;
547 p_dev->io = tmp_dev->io; 547 p_dev->io = tmp_dev->io;
548 p_dev->irq = tmp_dev->irq; 548 p_dev->irq = tmp_dev->irq;
549 p_dev->irq_v = tmp_dev->irq_v;
550 kref_get(&p_dev->function_config->ref); 549 kref_get(&p_dev->function_config->ref);
551 } 550 }
552 551
@@ -571,7 +570,7 @@ struct pcmcia_device *pcmcia_device_add(struct pcmcia_socket *s, unsigned int fu
571 570
572 dev_printk(KERN_NOTICE, &p_dev->dev, 571 dev_printk(KERN_NOTICE, &p_dev->dev,
573 "pcmcia: registering new device %s (IRQ: %d)\n", 572 "pcmcia: registering new device %s (IRQ: %d)\n",
574 p_dev->devname, p_dev->irq_v); 573 p_dev->devname, p_dev->irq);
575 574
576 pcmcia_device_query(p_dev); 575 pcmcia_device_query(p_dev);
577 576
diff --git a/drivers/pcmcia/pcmcia_resource.c b/drivers/pcmcia/pcmcia_resource.c
index 8dce223f3f44..f355c5ac407b 100644
--- a/drivers/pcmcia/pcmcia_resource.c
+++ b/drivers/pcmcia/pcmcia_resource.c
@@ -408,41 +408,6 @@ out:
408} /* pcmcia_release_io */ 408} /* pcmcia_release_io */
409 409
410 410
411static int pcmcia_release_irq(struct pcmcia_device *p_dev, irq_req_t *req)
412{
413 struct pcmcia_socket *s = p_dev->socket;
414 config_t *c;
415 int ret = -EINVAL;
416
417 mutex_lock(&s->ops_mutex);
418
419 c = p_dev->function_config;
420
421 if (!p_dev->_irq)
422 goto out;
423
424 p_dev->_irq = 0;
425
426 if (c->state & CONFIG_LOCKED)
427 goto out;
428
429 if (s->pcmcia_irq != req->AssignedIRQ) {
430 dev_dbg(&s->dev, "IRQ must match assigned one\n");
431 goto out;
432 }
433
434 if (req->Handler)
435 free_irq(req->AssignedIRQ, p_dev->priv);
436
437 ret = 0;
438
439out:
440 mutex_unlock(&s->ops_mutex);
441
442 return ret;
443} /* pcmcia_release_irq */
444
445
446int pcmcia_release_window(struct pcmcia_device *p_dev, window_handle_t wh) 411int pcmcia_release_window(struct pcmcia_device *p_dev, window_handle_t wh)
447{ 412{
448 struct pcmcia_socket *s = p_dev->socket; 413 struct pcmcia_socket *s = p_dev->socket;
@@ -681,61 +646,66 @@ out:
681EXPORT_SYMBOL(pcmcia_request_io); 646EXPORT_SYMBOL(pcmcia_request_io);
682 647
683 648
684/** pcmcia_request_irq 649/**
650 * pcmcia_request_irq() - attempt to request a IRQ for a PCMCIA device
685 * 651 *
686 * Request_irq() reserves an irq for this client. 652 * pcmcia_request_irq() is a wrapper around request_irq which will allow
653 * the PCMCIA core to clean up the registration in pcmcia_disable_device().
654 * Drivers are free to use request_irq() directly, but then they need to
655 * call free_irq themselfves, too. Also, only IRQF_SHARED capable IRQ
656 * handlers are allowed.
687 */ 657 */
688 658int __must_check pcmcia_request_irq(struct pcmcia_device *p_dev,
689int pcmcia_request_irq(struct pcmcia_device *p_dev, irq_req_t *req) 659 irq_handler_t handler)
690{ 660{
691 struct pcmcia_socket *s = p_dev->socket; 661 int ret;
692 config_t *c;
693 int ret = -EINVAL, irq = p_dev->irq_v;
694 int type = IRQF_SHARED;
695 662
696 mutex_lock(&s->ops_mutex); 663 if (!p_dev->irq)
664 return -EINVAL;
697 665
698 if (!(s->state & SOCKET_PRESENT)) { 666 ret = request_irq(p_dev->irq, handler, IRQF_SHARED,
699 dev_dbg(&s->dev, "No card present\n"); 667 p_dev->devname, p_dev->priv);
700 goto out; 668 if (!ret)
701 } 669 p_dev->_irq = 1;
702 c = p_dev->function_config;
703 if (c->state & CONFIG_LOCKED) {
704 dev_dbg(&s->dev, "Configuration is locked\n");
705 goto out;
706 }
707 670
708 if (!irq) { 671 return ret;
709 dev_dbg(&s->dev, "no IRQ available\n"); 672}
710 goto out; 673EXPORT_SYMBOL(pcmcia_request_irq);
711 }
712 674
713 if (!(req->Attributes & IRQ_TYPE_DYNAMIC_SHARING)) {
714 req->Attributes |= IRQ_TYPE_DYNAMIC_SHARING;
715 dev_printk(KERN_WARNING, &p_dev->dev, "pcmcia: the driver "
716 "needs updating to supported shared IRQ lines.\n");
717 }
718 675
719 if (req->Handler) { 676/**
720 ret = request_irq(irq, req->Handler, type, 677 * pcmcia_request_exclusive_irq() - attempt to request an exclusive IRQ first
721 p_dev->devname, p_dev->priv); 678 *
722 if (ret) { 679 * pcmcia_request_exclusive_irq() is a wrapper around request_irq which
723 dev_printk(KERN_INFO, &s->dev, 680 * attempts first to request an exclusive IRQ. If it fails, it also accepts
724 "request_irq() failed\n"); 681 * a shared IRQ, but prints out a warning. PCMCIA drivers should allow for
725 goto out; 682 * IRQ sharing and either use request_irq directly (then they need to call
726 } 683 * free_irq themselves, too), or the pcmcia_request_irq() function.
727 } 684 */
685int __must_check
686pcmcia_request_exclusive_irq(struct pcmcia_device *p_dev, irq_handler_t handler)
687{
688 int ret;
728 689
729 req->AssignedIRQ = irq; 690 if (!p_dev->irq)
691 return -EINVAL;
730 692
731 p_dev->_irq = 1; 693 ret = request_irq(p_dev->irq, handler, 0, p_dev->devname, p_dev->priv);
694 if (ret) {
695 ret = pcmcia_request_irq(p_dev, handler);
696 dev_printk(KERN_WARNING, &p_dev->dev, "pcmcia: "
697 "request for exclusive IRQ could not be fulfilled.\n");
698 dev_printk(KERN_WARNING, &p_dev->dev, "pcmcia: the driver "
699 "needs updating to supported shared IRQ lines.\n");
700 }
701 if (ret)
702 dev_printk(KERN_INFO, &p_dev->dev, "request_irq() failed\n");
703 else
704 p_dev->_irq = 1;
732 705
733 ret = 0;
734out:
735 mutex_unlock(&s->ops_mutex);
736 return ret; 706 return ret;
737} /* pcmcia_request_irq */ 707} /* pcmcia_request_exclusive_irq */
738EXPORT_SYMBOL(pcmcia_request_irq); 708EXPORT_SYMBOL(pcmcia_request_exclusive_irq);
739 709
740 710
741#ifdef CONFIG_PCMCIA_PROBE 711#ifdef CONFIG_PCMCIA_PROBE
@@ -779,7 +749,7 @@ static int pcmcia_setup_isa_irq(struct pcmcia_device *p_dev, int type)
779 p_dev); 749 p_dev);
780 if (!ret) { 750 if (!ret) {
781 free_irq(irq, p_dev); 751 free_irq(irq, p_dev);
782 p_dev->irq_v = s->pcmcia_irq = irq; 752 p_dev->irq = s->pcmcia_irq = irq;
783 pcmcia_used_irq[irq]++; 753 pcmcia_used_irq[irq]++;
784 break; 754 break;
785 } 755 }
@@ -820,12 +790,12 @@ int pcmcia_setup_irq(struct pcmcia_device *p_dev)
820{ 790{
821 struct pcmcia_socket *s = p_dev->socket; 791 struct pcmcia_socket *s = p_dev->socket;
822 792
823 if (p_dev->irq_v) 793 if (p_dev->irq)
824 return 0; 794 return 0;
825 795
826 /* already assigned? */ 796 /* already assigned? */
827 if (s->pcmcia_irq) { 797 if (s->pcmcia_irq) {
828 p_dev->irq_v = s->pcmcia_irq; 798 p_dev->irq = s->pcmcia_irq;
829 return 0; 799 return 0;
830 } 800 }
831 801
@@ -839,7 +809,7 @@ int pcmcia_setup_irq(struct pcmcia_device *p_dev)
839 809
840 /* but use the PCI irq otherwise */ 810 /* but use the PCI irq otherwise */
841 if (s->pci_irq) { 811 if (s->pci_irq) {
842 p_dev->irq_v = s->pcmcia_irq = s->pci_irq; 812 p_dev->irq = s->pcmcia_irq = s->pci_irq;
843 return 0; 813 return 0;
844 } 814 }
845 815
@@ -947,7 +917,8 @@ void pcmcia_disable_device(struct pcmcia_device *p_dev)
947{ 917{
948 pcmcia_release_configuration(p_dev); 918 pcmcia_release_configuration(p_dev);
949 pcmcia_release_io(p_dev, &p_dev->io); 919 pcmcia_release_io(p_dev, &p_dev->io);
950 pcmcia_release_irq(p_dev, &p_dev->irq); 920 if (p_dev->_irq)
921 free_irq(p_dev->irq, p_dev->priv);
951 if (p_dev->win) 922 if (p_dev->win)
952 pcmcia_release_window(p_dev, p_dev->win); 923 pcmcia_release_window(p_dev, p_dev->win);
953} 924}