Branch data Line data Source code
1 : : // SPDX-License-Identifier: GPL-2.0-only 2 : : /* 3 : : * cardbus.c -- 16-bit PCMCIA core support 4 : : * 5 : : * The initial developer of the original code is David A. Hinds 6 : : * <dahinds@users.sourceforge.net>. Portions created by David A. Hinds 7 : : * are Copyright (C) 1999 David A. Hinds. All Rights Reserved. 8 : : * 9 : : * (C) 1999 David A. Hinds 10 : : */ 11 : : 12 : : /* 13 : : * Cardbus handling has been re-written to be more of a PCI bridge thing, 14 : : * and the PCI code basically does all the resource handling. 15 : : * 16 : : * Linus, Jan 2000 17 : : */ 18 : : 19 : : 20 : : #include <linux/kernel.h> 21 : : #include <linux/module.h> 22 : : #include <linux/pci.h> 23 : : 24 : : #include <pcmcia/ss.h> 25 : : #include <pcmcia/cistpl.h> 26 : : 27 : : #include "cs_internal.h" 28 : : 29 : 0 : static void cardbus_config_irq_and_cls(struct pci_bus *bus, int irq) 30 : : { 31 : 0 : struct pci_dev *dev; 32 : : 33 [ # # ]: 0 : list_for_each_entry(dev, &bus->devices, bus_list) { 34 : 0 : u8 irq_pin; 35 : : 36 : : /* 37 : : * Since there is only one interrupt available to 38 : : * CardBus devices, all devices downstream of this 39 : : * device must be using this IRQ. 40 : : */ 41 : 0 : pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &irq_pin); 42 [ # # ]: 0 : if (irq_pin) { 43 : 0 : dev->irq = irq; 44 : 0 : pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq); 45 : : } 46 : : 47 : : /* 48 : : * Some controllers transfer very slowly with 0 CLS. 49 : : * Configure it. This may fail as CLS configuration 50 : : * is mandatory only for MWI. 51 : : */ 52 : 0 : pci_set_cacheline_size(dev); 53 : : 54 [ # # ]: 0 : if (dev->subordinate) 55 : 0 : cardbus_config_irq_and_cls(dev->subordinate, irq); 56 : : } 57 : 0 : } 58 : : 59 : : /** 60 : : * cb_alloc() - add CardBus device 61 : : * @s: the pcmcia_socket where the CardBus device is located 62 : : * 63 : : * cb_alloc() allocates the kernel data structures for a Cardbus device 64 : : * and handles the lowest level PCI device setup issues. 65 : : */ 66 : 0 : int __ref cb_alloc(struct pcmcia_socket *s) 67 : : { 68 : 0 : struct pci_bus *bus = s->cb_dev->subordinate; 69 : 0 : struct pci_dev *dev; 70 : 0 : unsigned int max, pass; 71 : : 72 : 0 : pci_lock_rescan_remove(); 73 : : 74 : 0 : s->functions = pci_scan_slot(bus, PCI_DEVFN(0, 0)); 75 : 0 : pci_fixup_cardbus(bus); 76 : : 77 : 0 : max = bus->busn_res.start; 78 [ # # ]: 0 : for (pass = 0; pass < 2; pass++) 79 [ # # # # ]: 0 : for_each_pci_bridge(dev, bus) 80 : 0 : max = pci_scan_bridge(bus, dev, max, pass); 81 : : 82 : : /* 83 : : * Size all resources below the CardBus controller. 84 : : */ 85 : 0 : pci_bus_size_bridges(bus); 86 : 0 : pci_bus_assign_resources(bus); 87 : 0 : cardbus_config_irq_and_cls(bus, s->pci_irq); 88 : : 89 : : /* socket specific tune function */ 90 [ # # ]: 0 : if (s->tune_bridge) 91 : 0 : s->tune_bridge(s, bus); 92 : : 93 : 0 : pci_bus_add_devices(bus); 94 : : 95 : 0 : pci_unlock_rescan_remove(); 96 : 0 : return 0; 97 : : } 98 : : 99 : : /** 100 : : * cb_free() - remove CardBus device 101 : : * @s: the pcmcia_socket where the CardBus device was located 102 : : * 103 : : * cb_free() handles the lowest level PCI device cleanup. 104 : : */ 105 : 0 : void cb_free(struct pcmcia_socket *s) 106 : : { 107 : 0 : struct pci_dev *bridge, *dev, *tmp; 108 : 0 : struct pci_bus *bus; 109 : : 110 : 0 : bridge = s->cb_dev; 111 [ # # ]: 0 : if (!bridge) 112 : : return; 113 : : 114 : 0 : bus = bridge->subordinate; 115 [ # # ]: 0 : if (!bus) 116 : : return; 117 : : 118 : 0 : pci_lock_rescan_remove(); 119 : : 120 [ # # ]: 0 : list_for_each_entry_safe(dev, tmp, &bus->devices, bus_list) 121 : 0 : pci_stop_and_remove_bus_device(dev); 122 : : 123 : 0 : pci_unlock_rescan_remove(); 124 : : }