Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * cardbus.c -- 16-bit PCMCIA core support
0004  *
0005  * The initial developer of the original code is David A. Hinds
0006  * <dahinds@users.sourceforge.net>.  Portions created by David A. Hinds
0007  * are Copyright (C) 1999 David A. Hinds.  All Rights Reserved.
0008  *
0009  * (C) 1999     David A. Hinds
0010  */
0011 
0012 /*
0013  * Cardbus handling has been re-written to be more of a PCI bridge thing,
0014  * and the PCI code basically does all the resource handling.
0015  *
0016  *      Linus, Jan 2000
0017  */
0018 
0019 
0020 #include <linux/kernel.h>
0021 #include <linux/module.h>
0022 #include <linux/pci.h>
0023 
0024 #include <pcmcia/ss.h>
0025 #include <pcmcia/cistpl.h>
0026 
0027 #include "cs_internal.h"
0028 
0029 static void cardbus_config_irq_and_cls(struct pci_bus *bus, int irq)
0030 {
0031     struct pci_dev *dev;
0032 
0033     list_for_each_entry(dev, &bus->devices, bus_list) {
0034         u8 irq_pin;
0035 
0036         /*
0037          * Since there is only one interrupt available to
0038          * CardBus devices, all devices downstream of this
0039          * device must be using this IRQ.
0040          */
0041         pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &irq_pin);
0042         if (irq_pin) {
0043             dev->irq = irq;
0044             pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq);
0045         }
0046 
0047         /*
0048          * Some controllers transfer very slowly with 0 CLS.
0049          * Configure it.  This may fail as CLS configuration
0050          * is mandatory only for MWI.
0051          */
0052         pci_set_cacheline_size(dev);
0053 
0054         if (dev->subordinate)
0055             cardbus_config_irq_and_cls(dev->subordinate, irq);
0056     }
0057 }
0058 
0059 /**
0060  * cb_alloc() - add CardBus device
0061  * @s:      the pcmcia_socket where the CardBus device is located
0062  *
0063  * cb_alloc() allocates the kernel data structures for a Cardbus device
0064  * and handles the lowest level PCI device setup issues.
0065  */
0066 int __ref cb_alloc(struct pcmcia_socket *s)
0067 {
0068     struct pci_bus *bus = s->cb_dev->subordinate;
0069     struct pci_dev *dev;
0070     unsigned int max, pass;
0071 
0072     pci_lock_rescan_remove();
0073 
0074     s->functions = pci_scan_slot(bus, PCI_DEVFN(0, 0));
0075     pci_fixup_cardbus(bus);
0076 
0077     max = bus->busn_res.start;
0078     for (pass = 0; pass < 2; pass++)
0079         for_each_pci_bridge(dev, bus)
0080             max = pci_scan_bridge(bus, dev, max, pass);
0081 
0082     /*
0083      * Size all resources below the CardBus controller.
0084      */
0085     pci_bus_size_bridges(bus);
0086     pci_bus_assign_resources(bus);
0087     cardbus_config_irq_and_cls(bus, s->pci_irq);
0088 
0089     /* socket specific tune function */
0090     if (s->tune_bridge)
0091         s->tune_bridge(s, bus);
0092 
0093     pci_bus_add_devices(bus);
0094 
0095     pci_unlock_rescan_remove();
0096     return 0;
0097 }
0098 
0099 /**
0100  * cb_free() - remove CardBus device
0101  * @s:      the pcmcia_socket where the CardBus device was located
0102  *
0103  * cb_free() handles the lowest level PCI device cleanup.
0104  */
0105 void cb_free(struct pcmcia_socket *s)
0106 {
0107     struct pci_dev *bridge, *dev, *tmp;
0108     struct pci_bus *bus;
0109 
0110     bridge = s->cb_dev;
0111     if (!bridge)
0112         return;
0113 
0114     bus = bridge->subordinate;
0115     if (!bus)
0116         return;
0117 
0118     pci_lock_rescan_remove();
0119 
0120     list_for_each_entry_safe(dev, tmp, &bus->devices, bus_list)
0121         pci_stop_and_remove_bus_device(dev);
0122 
0123     pci_unlock_rescan_remove();
0124 }