Commit c54b1791 authored by Scott Murray's avatar Scott Murray Committed by Russell King

[PATCH] 2.5.45 CompactPCI driver patch 1/4

This is a patch 1 of 4 of my CompactPCI hotplug core and
drivers, consisting of the required core PCI changes.

The various arch file changes are to change pcibios_fixup_pbus_ranges to
from __init to __devinit, so that pci_setup_bridge can be safely exported
from drivers/pci/setup-bus.c.
parent 1aaa4de8
......@@ -326,7 +326,7 @@ common_swizzle(struct pci_dev *dev, u8 *pinp)
return PCI_SLOT(dev->devfn);
}
void __init
void __devinit
pcibios_fixup_pbus_ranges(struct pci_bus * bus,
struct pbus_set_ranges_data * ranges)
{
......
......@@ -90,6 +90,11 @@ static void __devinit pcibios_fixup_ghosts(struct pci_bus *b)
}
}
void __devinit
pcibios_fixup_pbus_ranges (struct pci_bus *bus, struct pbus_set_ranges_data *ranges)
{
}
/*
* Called after each bus is probed, but before its children
* are examined.
......
......@@ -297,8 +297,8 @@ void __init pcibios_update_irq(struct pci_dev *dev, int irq)
pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq);
}
void __init pcibios_fixup_pbus_ranges(struct pci_bus *bus,
struct pbus_set_ranges_data *ranges)
void __devinit pcibios_fixup_pbus_ranges(struct pci_bus *bus,
struct pbus_set_ranges_data *ranges)
{
}
......
......@@ -341,8 +341,8 @@ void __init pcibios_update_irq(struct pci_dev *dev, int irq)
pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq);
}
void __init pcibios_fixup_pbus_ranges(struct pci_bus *bus,
struct pbus_set_ranges_data *ranges)
void __devinit pcibios_fixup_pbus_ranges(struct pci_bus *bus,
struct pbus_set_ranges_data *ranges)
{
/*
* our caller figure out range by going through the dev structures.
......
......@@ -234,7 +234,7 @@ pcibios_fixup_bus(struct pci_bus *b)
pci_fixup_irqs(pci_swizzle, pci_map_irq);
}
void __init
void __devinit
pcibios_fixup_pbus_ranges(struct pci_bus * bus,
struct pbus_set_ranges_data * ranges)
{
......
......@@ -349,8 +349,8 @@ void __init pcibios_fixup_bus (struct pci_bus *b)
}
/* XXX anybody know what this is supposed to do? */
void __init pcibios_fixup_pbus_ranges(struct pci_bus * bus,
struct pbus_set_ranges_data * ranges)
void __devinit pcibios_fixup_pbus_ranges(struct pci_bus * bus,
struct pbus_set_ranges_data * ranges)
{
}
......
......@@ -345,7 +345,7 @@ pcibios_link_hba_resources( struct resource *hba_res, struct resource *r)
/*
** called by drivers/pci/setup-res.c:pci_setup_bridge().
*/
void pcibios_fixup_pbus_ranges(
void __devinit pcibios_fixup_pbus_ranges(
struct pci_bus *bus,
struct pbus_set_ranges_data *ranges
)
......
......@@ -1107,7 +1107,7 @@ common_swizzle(struct pci_dev *dev, unsigned char *pinp)
return PCI_SLOT(dev->devfn);
}
void __init
void __devinit
pcibios_fixup_pbus_ranges(struct pci_bus * bus, struct pbus_set_ranges_data * ranges)
{
}
......
......@@ -121,8 +121,8 @@ static void fixup_windbond_82c105(struct pci_dev* dev)
}
void pcibios_fixup_pbus_ranges(struct pci_bus *pbus,
struct pbus_set_ranges_data *pranges)
void __devinit pcibios_fixup_pbus_ranges(struct pci_bus *pbus,
struct pbus_set_ranges_data *pranges)
{
}
......
......@@ -113,7 +113,7 @@ void pci_free_consistent(struct pci_dev *hwdev, size_t size,
}
void __init pcibios_fixup_pbus_ranges(struct pci_bus *bus, struct pbus_set_ranges_data *ranges)
void __devinit pcibios_fixup_pbus_ranges(struct pci_bus *bus, struct pbus_set_ranges_data *ranges)
{
}
......
......@@ -250,8 +250,8 @@ struct pci_fixup pcibios_fixups[] = {
{ 0 }
};
void __init pcibios_fixup_pbus_ranges(struct pci_bus *b,
struct pbus_set_ranges_data *range)
void __devinit pcibios_fixup_pbus_ranges(struct pci_bus *b,
struct pbus_set_ranges_data *range)
{
/* No fixups needed */
}
......
......@@ -380,7 +380,7 @@ static int __init map_harp_irq(struct pci_dev *dev, u8 slot, u8 pin)
}
void __init
void __devinit
pcibios_fixup_pbus_ranges(struct pci_bus *bus,
struct pbus_set_ranges_data *ranges)
{
......
......@@ -479,8 +479,8 @@ void pcibios_update_irq(struct pci_dev *pdev, int irq)
{
}
void pcibios_fixup_pbus_ranges(struct pci_bus *pbus,
struct pbus_set_ranges_data *pranges)
void __devinit pcibios_fixup_pbus_ranges(struct pci_bus *pbus,
struct pbus_set_ranges_data *pranges)
{
}
......
......@@ -24,6 +24,49 @@
#define DBG(x...)
#endif
/**
* pci_bus_max_busnr - returns maximum PCI bus number of given bus' children
* @bus: pointer to PCI bus structure to search
*
* Given a PCI bus, returns the highest PCI bus number present in the set
* including the given PCI bus and its list of child PCI buses.
*/
unsigned char __devinit
pci_bus_max_busnr(struct pci_bus* bus)
{
struct list_head *tmp;
unsigned char max, n;
max = bus->number;
list_for_each(tmp, &bus->children) {
n = pci_bus_max_busnr(pci_bus_b(tmp));
if(n > max)
max = n;
}
return max;
}
/**
* pci_max_busnr - returns maximum PCI bus number
*
* Returns the highest PCI bus number present in the system global list of
* PCI buses.
*/
unsigned char __devinit
pci_max_busnr(void)
{
struct pci_bus* bus;
unsigned char max, n;
max = 0;
pci_for_each_bus(bus) {
n = pci_bus_max_busnr(bus);
if(n > max)
max = n;
}
return max;
}
/**
* pci_find_capability - query for devices' capabilities
* @dev: PCI device to query
......@@ -79,6 +122,49 @@ pci_find_capability(struct pci_dev *dev, int cap)
return 0;
}
/**
* pci_bus_find_capability - query for devices' capabilities
* @dev: PCI device to query
* @cap: capability code
*
* Like pci_find_capability() but works for pci devices that do not have a
* pci_dev structure set up yet.
* Returns the address of the requested capability structure within the
* device's PCI configuration space or 0 in case the device does not
* support it.
*/
int pci_bus_find_capability(struct pci_bus *bus, unsigned int devfn, int cap)
{
u16 status;
u8 pos, id;
int ttl = 48;
struct pci_dev *dev = bus->self;
pci_bus_read_config_word(bus, devfn, PCI_STATUS, &status);
if (!(status & PCI_STATUS_CAP_LIST))
return 0;
switch (dev->hdr_type) {
case PCI_HEADER_TYPE_NORMAL:
case PCI_HEADER_TYPE_BRIDGE:
pci_bus_read_config_byte(bus, devfn, PCI_CAPABILITY_LIST, &pos);
break;
case PCI_HEADER_TYPE_CARDBUS:
pci_bus_read_config_byte(bus, devfn, PCI_CB_CAPABILITY_LIST, &pos);
break;
default:
return 0;
}
while (ttl-- && pos >= 0x40) {
pos &= ~3;
pci_bus_read_config_byte(bus, devfn, pos + PCI_CAP_LIST_ID, &id);
if (id == 0xff)
break;
if (id == cap)
return pos;
pci_bus_read_config_byte(bus, devfn, pos + PCI_CAP_LIST_NEXT, &pos);
}
return 0;
}
/**
* pci_find_parent_resource - return resource region of parent bus of given region
......@@ -644,7 +730,10 @@ __setup("pci=", pci_setup);
EXPORT_SYMBOL(pci_enable_device);
EXPORT_SYMBOL(pci_disable_device);
EXPORT_SYMBOL(pci_max_busnr);
EXPORT_SYMBOL(pci_bus_max_busnr);
EXPORT_SYMBOL(pci_find_capability);
EXPORT_SYMBOL(pci_bus_find_capability);
EXPORT_SYMBOL(pci_release_regions);
EXPORT_SYMBOL(pci_request_regions);
EXPORT_SYMBOL(pci_release_region);
......@@ -656,6 +745,8 @@ EXPORT_SYMBOL(pci_set_dma_mask);
EXPORT_SYMBOL(pci_dac_set_dma_mask);
EXPORT_SYMBOL(pci_assign_resource);
EXPORT_SYMBOL(pci_find_parent_resource);
EXPORT_SYMBOL(pbus_size_bridges);
EXPORT_SYMBOL(pbus_assign_resources);
EXPORT_SYMBOL(pci_set_power_state);
EXPORT_SYMBOL(pci_save_state);
......
......@@ -254,7 +254,7 @@ struct pci_bus * __devinit pci_add_new_bus(struct pci_bus *parent, struct pci_de
* them, we proceed to assigning numbers to the remaining buses in
* order to avoid overlaps between old and new bus numbers.
*/
static int __devinit pci_scan_bridge(struct pci_bus *bus, struct pci_dev * dev, int max, int pass)
int __devinit pci_scan_bridge(struct pci_bus *bus, struct pci_dev * dev, int max, int pass)
{
unsigned int buses;
unsigned short cr;
......@@ -595,4 +595,5 @@ EXPORT_SYMBOL(pci_add_new_bus);
EXPORT_SYMBOL(pci_do_scan_bus);
EXPORT_SYMBOL(pci_scan_slot);
EXPORT_SYMBOL(pci_scan_bus);
EXPORT_SYMBOL(pci_scan_bridge);
#endif
#include <linux/pci.h>
#include <linux/module.h>
static struct pci_bus *
pci_do_find_bus(struct pci_bus* bus, unsigned char busnr)
{
struct pci_bus* child;
struct list_head *tmp;
if(bus->number == busnr)
return bus;
list_for_each(tmp, &bus->children) {
child = pci_do_find_bus(pci_bus_b(tmp), busnr);
if(child)
return child;
}
return NULL;
}
/**
* pci_find_bus - locate PCI bus from a given bus number
* @busnr: number of desired PCI bus
*
* Given a PCI bus number, the desired PCI bus is located in system
* global list of PCI buses. If the bus is found, a pointer to its
* data structure is returned. If no bus is found, %NULL is returned.
*/
struct pci_bus *
pci_find_bus(unsigned char busnr)
{
struct pci_bus* bus;
struct pci_bus* tmp_bus;
pci_for_each_bus(bus) {
tmp_bus = pci_do_find_bus(bus, busnr);
if(tmp_bus)
return tmp_bus;
}
return NULL;
}
/**
* pci_find_slot - locate PCI device from a given PCI slot
* @bus: number of PCI bus on which desired PCI device resides
......@@ -104,6 +143,7 @@ pci_find_class(unsigned int class, const struct pci_dev *from)
return NULL;
}
EXPORT_SYMBOL(pci_find_bus);
EXPORT_SYMBOL(pci_find_class);
EXPORT_SYMBOL(pci_find_device);
EXPORT_SYMBOL(pci_find_slot);
......
......@@ -35,7 +35,7 @@
#define ROUND_UP(x, a) (((x) + (a) - 1) & ~((a) - 1))
static int __init
static int __devinit
pbus_assign_resources_sorted(struct pci_bus *bus)
{
struct list_head *ln;
......@@ -85,7 +85,7 @@ pbus_assign_resources_sorted(struct pci_bus *bus)
requires that if there is no I/O ports or memory behind the
bridge, corresponding range must be turned off by writing base
value greater than limit to the bridge's base/limit registers. */
static void __init
static void __devinit
pci_setup_bridge(struct pci_bus *bus)
{
struct pbus_set_ranges_data ranges;
......@@ -168,7 +168,7 @@ pci_setup_bridge(struct pci_bus *bus)
/* Check whether the bridge supports optional I/O and
prefetchable memory ranges. If not, the respective
base/limit registers must be read-only and read as 0. */
static void __init
static void __devinit
pci_bridge_check_ranges(struct pci_bus *bus)
{
u16 io;
......@@ -210,7 +210,7 @@ pci_bridge_check_ranges(struct pci_bus *bus)
since these windows have 4K granularity and the IO ranges
of non-bridge PCI devices are limited to 256 bytes.
We must be careful with the ISA aliasing though. */
static void __init
static void __devinit
pbus_size_io(struct pci_bus *bus)
{
struct list_head *ln;
......@@ -259,7 +259,7 @@ pbus_size_io(struct pci_bus *bus)
/* Calculate the size of the bus and minimal alignment which
guarantees that all child resources fit in this size. */
static void __init
static void __devinit
pbus_size_mem(struct pci_bus *bus, unsigned long mask, unsigned long type)
{
struct list_head *ln;
......@@ -331,7 +331,7 @@ pbus_size_mem(struct pci_bus *bus, unsigned long mask, unsigned long type)
b_res->end = size + min_align - 1;
}
void __init
void __devinit
pbus_size_bridges(struct pci_bus *bus)
{
struct list_head *ln;
......@@ -358,7 +358,7 @@ pbus_size_bridges(struct pci_bus *bus)
pbus_size_mem(bus, mask, type);
}
void __init
void __devinit
pbus_assign_resources(struct pci_bus *bus)
{
struct list_head *ln;
......
......@@ -557,8 +557,12 @@ struct pci_dev *pci_find_subsys (unsigned int vendor, unsigned int device,
unsigned int ss_vendor, unsigned int ss_device,
const struct pci_dev *from);
struct pci_dev *pci_find_class (unsigned int class, const struct pci_dev *from);
struct pci_bus *pci_find_bus(unsigned char busnr);
struct pci_dev *pci_find_slot (unsigned int bus, unsigned int devfn);
unsigned char pci_bus_max_busnr(struct pci_bus* bus);
unsigned char pci_max_busnr(void);
int pci_find_capability (struct pci_dev *dev, int cap);
int pci_bus_find_capability (struct pci_bus *bus, unsigned int devfn, int cap);
int pci_bus_read_config_byte (struct pci_bus *bus, unsigned int devfn, int where, u8 *val);
int pci_bus_read_config_word (struct pci_bus *bus, unsigned int devfn, int where, u16 *val);
......@@ -613,6 +617,8 @@ int pci_enable_wake(struct pci_dev *dev, u32 state, int enable);
/* Helper functions for low-level code (drivers/pci/setup-[bus,res].c) */
void pbus_assign_resources(struct pci_bus *bus);
void pbus_size_bridges(struct pci_bus *bus);
int pci_claim_resource(struct pci_dev *, int);
void pci_assign_unassigned_resources(void);
void pdev_enable_device(struct pci_dev *);
......@@ -634,6 +640,7 @@ struct pci_driver *pci_dev_driver(const struct pci_dev *);
const struct pci_device_id *pci_match_device(const struct pci_device_id *ids, const struct pci_dev *dev);
unsigned int pci_do_scan_bus(struct pci_bus *bus);
struct pci_bus * pci_add_new_bus(struct pci_bus *parent, struct pci_dev *dev, int busnr);
int pci_scan_bridge(struct pci_bus *bus, struct pci_dev * dev, int max, int pass);
/* kmem_cache style wrapper around pci_alloc_consistent() */
struct pci_pool *pci_pool_create (const char *name, struct pci_dev *dev,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment