// SPDX-License-Identifier: GPL-2.0-only /* * Regular cardbus driver ("yenta_socket") * * (C) Copyright 1999, 2000 Linus Torvalds * * Changelog: * Aug 2002: Manfred Spraul <manfred@colorfullife.com> * Dynamically adjust the size of the bridge resource * * May 2003: Dominik Brodowski <linux@brodo.de> * Merge pci_socket.c and yenta.c into one file
*/ #include <linux/init.h> #include <linux/pci.h> #include <linux/workqueue.h> #include <linux/interrupt.h> #include <linux/delay.h> #include <linux/module.h> #include <linux/io.h> #include <linux/slab.h>
#include <pcmcia/ss.h>
#include"yenta_socket.h" #include"i82365.h"
staticbool disable_clkrun;
module_param(disable_clkrun, bool, 0444);
MODULE_PARM_DESC(disable_clkrun, "If PC card doesn't function properly, please try this option (TI and Ricoh bridges only)");
staticbool isa_probe = 1;
module_param(isa_probe, bool, 0444);
MODULE_PARM_DESC(isa_probe, "If set ISA interrupts are probed (default). Set to N to disable probing");
staticbool pwr_irqs_off;
module_param(pwr_irqs_off, bool, 0644);
MODULE_PARM_DESC(pwr_irqs_off, "Force IRQs off during power-on of slot. Use only when seeing IRQ storms!");
staticchar o2_speedup[] = "default";
module_param_string(o2_speedup, o2_speedup, sizeof(o2_speedup), 0444);
MODULE_PARM_DESC(o2_speedup, "Use prefetch/burst for O2-bridges: 'on', 'off' " "or 'default' (uses recommended behaviour for the detected bridge)");
/* * Only probe "regular" interrupts, don't * touch dangerous spots like the mouse irq, * because there are mice that apparently * get really confused if they get fondled * too intimately. * * Default to 11, 10, 9, 7, 6, 5, 4, 3.
*/ static u32 isa_interrupts = 0x0ef8;
/* * Use an adaptive allocation for the memory resource, * sometimes the memory behind pci bridges is limited: * 1/8 of the size of the io window of the parent. * max 4 MB, min 16 kB. We try very hard to not get below * the "ACC" values, though.
*/ #define BRIDGE_MEM_MAX (4*1024*1024) #define BRIDGE_MEM_ACC (128*1024) #define BRIDGE_MEM_MIN (16*1024)
res = &dev->resource[nr]; if (res->start != 0 && res->end != 0)
release_resource(res);
res->start = res->end = res->flags = 0;
}
/* * Allocate the bridge mappings for the device..
*/ staticvoid yenta_allocate_resources(struct yenta_socket *socket)
{ int program = 0;
program += yenta_allocate_res(socket, PCI_CB_BRIDGE_IO_0_WINDOW,
IORESOURCE_IO,
PCI_CB_IO_BASE_0, PCI_CB_IO_LIMIT_0);
program += yenta_allocate_res(socket, PCI_CB_BRIDGE_IO_1_WINDOW,
IORESOURCE_IO,
PCI_CB_IO_BASE_1, PCI_CB_IO_LIMIT_1);
program += yenta_allocate_res(socket, PCI_CB_BRIDGE_MEM_0_WINDOW,
IORESOURCE_MEM | IORESOURCE_PREFETCH,
PCI_CB_MEMORY_BASE_0, PCI_CB_MEMORY_LIMIT_0);
program += yenta_allocate_res(socket, PCI_CB_BRIDGE_MEM_1_WINDOW,
IORESOURCE_MEM,
PCI_CB_MEMORY_BASE_1, PCI_CB_MEMORY_LIMIT_1); if (program)
pci_setup_cardbus(socket->dev->subordinate);
}
/* * Free the bridge mappings for the device..
*/ staticvoid yenta_free_resources(struct yenta_socket *socket)
{
yenta_free_res(socket, PCI_CB_BRIDGE_IO_0_WINDOW);
yenta_free_res(socket, PCI_CB_BRIDGE_IO_1_WINDOW);
yenta_free_res(socket, PCI_CB_BRIDGE_MEM_0_WINDOW);
yenta_free_res(socket, PCI_CB_BRIDGE_MEM_1_WINDOW);
}
/* * Close it down - release our resources and go home..
*/ staticvoid yenta_close(struct pci_dev *dev)
{ struct yenta_socket *sock = pci_get_drvdata(dev);
/* Remove the register attributes */
device_remove_file(&dev->dev, &dev_attr_yenta_registers);
/* we don't want a dying socket registered */
pcmcia_unregister_socket(&sock->socket);
/* Disable all events so we don't die in an IRQ storm */
cb_writel(sock, CB_SOCKET_MASK, 0x0);
exca_writeb(sock, I365_CSCINT, 0);
if (sock->cb_irq)
free_irq(sock->cb_irq, sock); else
timer_shutdown_sync(&sock->poll_timer);
/** * yenta_fixup_parent_bridge - Fix subordinate bus# of the parent bridge * @cardbus_bridge: The PCI bus which the CardBus bridge bridges to * * Checks if devices on the bus which the CardBus bridge bridges to would be * invisible during PCI scans because of a misconfigured subordinate number * of the parent brige - some BIOSes seem to be too lazy to set it right. * Does the fixup carefully by checking how far it can go without conflicts. * See http://bugzilla.kernel.org/show_bug.cgi?id=2944 for more information.
*/ staticvoid yenta_fixup_parent_bridge(struct pci_bus *cardbus_bridge)
{ struct pci_bus *sibling; unsignedchar upper_limit; /* * We only check and fix the parent bridge: All systems which need * this fixup that have been reviewed are laptops and the only bridge * which needed fixing was the parent bridge of the CardBus bridge:
*/ struct pci_bus *bridge_to_fix = cardbus_bridge->parent;
/* Check bus numbers are already set up correctly: */ if (bridge_to_fix->busn_res.end >= cardbus_bridge->busn_res.end) return; /* The subordinate number is ok, nothing to do */
if (!bridge_to_fix->parent) return; /* Root bridges are ok */
/* stay within the limits of the bus range of the parent: */
upper_limit = bridge_to_fix->parent->busn_res.end;
/* check the bus ranges of all sibling bridges to prevent overlap */
list_for_each_entry(sibling, &bridge_to_fix->parent->children,
node) { /* * If the sibling has a higher secondary bus number * and it's secondary is equal or smaller than our * current upper limit, set the new upper limit to * the bus number below the sibling's range:
*/ if (sibling->busn_res.start > bridge_to_fix->busn_res.end
&& sibling->busn_res.start <= upper_limit)
upper_limit = sibling->busn_res.start - 1;
}
/* Show that the wanted subordinate number is not possible: */ if (cardbus_bridge->busn_res.end > upper_limit)
dev_warn(&cardbus_bridge->dev, "Upper limit for fixing this bridge's parent bridge: #%02x\n",
upper_limit);
/* If we have room to increase the bridge's subordinate number, */ if (bridge_to_fix->busn_res.end < upper_limit) {
/* use the highest number of the hidden bus, within limits */ unsignedchar subordinate_to_assign =
min_t(int, cardbus_bridge->busn_res.end, upper_limit);
dev_info(&bridge_to_fix->dev, "Raising subordinate bus# of parent bus (#%02x) from #%02x to #%02x\n",
bridge_to_fix->number,
(int)bridge_to_fix->busn_res.end,
subordinate_to_assign);
/* Save the new subordinate in the bus struct of the bridge */
bridge_to_fix->busn_res.end = subordinate_to_assign;
/* and update the PCI config space with the new subordinate */
pci_write_config_byte(bridge_to_fix->self,
PCI_SUBORDINATE_BUS, bridge_to_fix->busn_res.end);
}
}
/* * Initialize a cardbus controller. Make sure we have a usable * interrupt, and that we can map the cardbus area. Fill in the * socket information structure..
*/ staticint yenta_probe(struct pci_dev *dev, conststruct pci_device_id *id)
{ struct yenta_socket *socket; int ret;
/* * If we failed to assign proper bus numbers for this cardbus * controller during PCI probe, its subordinate pci_bus is NULL. * Bail out if so.
*/ if (!dev->subordinate) {
dev_err(&dev->dev, "no bus associated! (try 'pci=assign-busses')\n"); return -ENODEV;
}
socket = kzalloc(sizeof(struct yenta_socket), GFP_KERNEL); if (!socket) return -ENOMEM;
/* * Do some basic sanity checking..
*/ if (pci_enable_device(dev)) {
ret = -EBUSY; goto free;
}
ret = pci_request_regions(dev, "yenta_socket"); if (ret) goto disable;
if (!pci_resource_start(dev, 0)) {
dev_err(&dev->dev, "No cardbus resource!\n");
ret = -ENODEV; goto release;
}
/* * Ok, start setup.. Map the cardbus registers, * and request the IRQ.
*/
socket->base = ioremap(pci_resource_start(dev, 0), 0x1000); if (!socket->base) {
ret = -ENOMEM; goto release;
}
/* * report the subsystem vendor and device for help debugging * the irq stuff...
*/
dev_info(&dev->dev, "CardBus bridge found [%04x:%04x]\n",
dev->subsystem_vendor, dev->subsystem_device);
yenta_config_init(socket);
/* Disable all events */
cb_writel(socket, CB_SOCKET_MASK, 0x0);
/* Set up the bridge regions.. */
yenta_allocate_resources(socket);
socket->cb_irq = dev->irq;
/* Do we have special options for the device? */ if (id->driver_data != CARDBUS_TYPE_DEFAULT &&
id->driver_data < ARRAY_SIZE(cardbus_type)) {
socket->type = &cardbus_type[id->driver_data];
ret = socket->type->override(socket); if (ret < 0) goto unmap;
}
/* We must finish initialization here */
if (!socket->cb_irq || request_irq(socket->cb_irq, yenta_interrupt, IRQF_SHARED, "yenta", socket)) { /* No IRQ or request_irq failed. Poll */
socket->cb_irq = 0; /* But zero is a valid IRQ number. */
timer_setup(&socket->poll_timer, yenta_interrupt_wrapper, 0);
mod_timer(&socket->poll_timer, jiffies + HZ);
dev_info(&dev->dev, "no PCI IRQ, CardBus support disabled for this socket.\n");
dev_info(&dev->dev, "check your BIOS CardBus, BIOS IRQ or ACPI settings.\n");
} else {
socket->socket.features |= SS_CAP_CARDBUS;
}
/* Figure out what the dang thing can do for the PCMCIA layer... */
yenta_interrogate(socket);
yenta_get_socket_capabilities(socket, isa_interrupts);
dev_info(&dev->dev, "Socket status: %08x\n",
cb_readl(socket, CB_SOCKET_STATE));
yenta_fixup_parent_bridge(dev->subordinate);
/* Register it with the pcmcia layer.. */
ret = pcmcia_register_socket(&socket->socket); if (ret) goto free_irq;
/* Add the yenta register attributes */
ret = device_create_file(&dev->dev, &dev_attr_yenta_registers); if (ret) goto unregister_socket;
/* * TBD: Check if these TI variants can use more * advanced overrides instead. (I can't get the * data sheets for these devices. --rmk)
*/ #ifdef CONFIG_YENTA_TI
CB_ID(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_1210, TI),
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.