cardbus.c (2867B)
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 29static void cardbus_config_irq_and_cls(struct pci_bus *bus, int irq) 30{ 31 struct pci_dev *dev; 32 33 list_for_each_entry(dev, &bus->devices, bus_list) { 34 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 pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &irq_pin); 42 if (irq_pin) { 43 dev->irq = irq; 44 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 pci_set_cacheline_size(dev); 53 54 if (dev->subordinate) 55 cardbus_config_irq_and_cls(dev->subordinate, irq); 56 } 57} 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 */ 66int __ref cb_alloc(struct pcmcia_socket *s) 67{ 68 struct pci_bus *bus = s->cb_dev->subordinate; 69 struct pci_dev *dev; 70 unsigned int max, pass; 71 72 pci_lock_rescan_remove(); 73 74 s->functions = pci_scan_slot(bus, PCI_DEVFN(0, 0)); 75 pci_fixup_cardbus(bus); 76 77 max = bus->busn_res.start; 78 for (pass = 0; pass < 2; pass++) 79 for_each_pci_bridge(dev, bus) 80 max = pci_scan_bridge(bus, dev, max, pass); 81 82 /* 83 * Size all resources below the CardBus controller. 84 */ 85 pci_bus_size_bridges(bus); 86 pci_bus_assign_resources(bus); 87 cardbus_config_irq_and_cls(bus, s->pci_irq); 88 89 /* socket specific tune function */ 90 if (s->tune_bridge) 91 s->tune_bridge(s, bus); 92 93 pci_bus_add_devices(bus); 94 95 pci_unlock_rescan_remove(); 96 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 */ 105void cb_free(struct pcmcia_socket *s) 106{ 107 struct pci_dev *bridge, *dev, *tmp; 108 struct pci_bus *bus; 109 110 bridge = s->cb_dev; 111 if (!bridge) 112 return; 113 114 bus = bridge->subordinate; 115 if (!bus) 116 return; 117 118 pci_lock_rescan_remove(); 119 120 list_for_each_entry_safe(dev, tmp, &bus->devices, bus_list) 121 pci_stop_and_remove_bus_device(dev); 122 123 pci_unlock_rescan_remove(); 124}