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) ...@@ -326,7 +326,7 @@ common_swizzle(struct pci_dev *dev, u8 *pinp)
return PCI_SLOT(dev->devfn); return PCI_SLOT(dev->devfn);
} }
void __init void __devinit
pcibios_fixup_pbus_ranges(struct pci_bus * bus, pcibios_fixup_pbus_ranges(struct pci_bus * bus,
struct pbus_set_ranges_data * ranges) struct pbus_set_ranges_data * ranges)
{ {
......
...@@ -90,6 +90,11 @@ static void __devinit pcibios_fixup_ghosts(struct pci_bus *b) ...@@ -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 * Called after each bus is probed, but before its children
* are examined. * are examined.
......
...@@ -297,7 +297,7 @@ void __init pcibios_update_irq(struct pci_dev *dev, int irq) ...@@ -297,7 +297,7 @@ void __init pcibios_update_irq(struct pci_dev *dev, int irq)
pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq); pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq);
} }
void __init pcibios_fixup_pbus_ranges(struct pci_bus *bus, void __devinit pcibios_fixup_pbus_ranges(struct pci_bus *bus,
struct pbus_set_ranges_data *ranges) struct pbus_set_ranges_data *ranges)
{ {
} }
......
...@@ -341,7 +341,7 @@ void __init pcibios_update_irq(struct pci_dev *dev, int irq) ...@@ -341,7 +341,7 @@ void __init pcibios_update_irq(struct pci_dev *dev, int irq)
pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq); pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq);
} }
void __init pcibios_fixup_pbus_ranges(struct pci_bus *bus, void __devinit pcibios_fixup_pbus_ranges(struct pci_bus *bus,
struct pbus_set_ranges_data *ranges) struct pbus_set_ranges_data *ranges)
{ {
/* /*
......
...@@ -234,7 +234,7 @@ pcibios_fixup_bus(struct pci_bus *b) ...@@ -234,7 +234,7 @@ pcibios_fixup_bus(struct pci_bus *b)
pci_fixup_irqs(pci_swizzle, pci_map_irq); pci_fixup_irqs(pci_swizzle, pci_map_irq);
} }
void __init void __devinit
pcibios_fixup_pbus_ranges(struct pci_bus * bus, pcibios_fixup_pbus_ranges(struct pci_bus * bus,
struct pbus_set_ranges_data * ranges) struct pbus_set_ranges_data * ranges)
{ {
......
...@@ -349,7 +349,7 @@ void __init pcibios_fixup_bus (struct pci_bus *b) ...@@ -349,7 +349,7 @@ void __init pcibios_fixup_bus (struct pci_bus *b)
} }
/* XXX anybody know what this is supposed to do? */ /* XXX anybody know what this is supposed to do? */
void __init pcibios_fixup_pbus_ranges(struct pci_bus * bus, void __devinit pcibios_fixup_pbus_ranges(struct pci_bus * bus,
struct pbus_set_ranges_data * ranges) struct pbus_set_ranges_data * ranges)
{ {
} }
......
...@@ -345,7 +345,7 @@ pcibios_link_hba_resources( struct resource *hba_res, struct resource *r) ...@@ -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(). ** 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 pci_bus *bus,
struct pbus_set_ranges_data *ranges struct pbus_set_ranges_data *ranges
) )
......
...@@ -1107,7 +1107,7 @@ common_swizzle(struct pci_dev *dev, unsigned char *pinp) ...@@ -1107,7 +1107,7 @@ common_swizzle(struct pci_dev *dev, unsigned char *pinp)
return PCI_SLOT(dev->devfn); return PCI_SLOT(dev->devfn);
} }
void __init void __devinit
pcibios_fixup_pbus_ranges(struct pci_bus * bus, struct pbus_set_ranges_data * ranges) pcibios_fixup_pbus_ranges(struct pci_bus * bus, struct pbus_set_ranges_data * ranges)
{ {
} }
......
...@@ -121,7 +121,7 @@ static void fixup_windbond_82c105(struct pci_dev* dev) ...@@ -121,7 +121,7 @@ static void fixup_windbond_82c105(struct pci_dev* dev)
} }
void pcibios_fixup_pbus_ranges(struct pci_bus *pbus, void __devinit pcibios_fixup_pbus_ranges(struct pci_bus *pbus,
struct pbus_set_ranges_data *pranges) struct pbus_set_ranges_data *pranges)
{ {
} }
......
...@@ -113,7 +113,7 @@ void pci_free_consistent(struct pci_dev *hwdev, size_t size, ...@@ -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,7 +250,7 @@ struct pci_fixup pcibios_fixups[] = { ...@@ -250,7 +250,7 @@ struct pci_fixup pcibios_fixups[] = {
{ 0 } { 0 }
}; };
void __init pcibios_fixup_pbus_ranges(struct pci_bus *b, void __devinit pcibios_fixup_pbus_ranges(struct pci_bus *b,
struct pbus_set_ranges_data *range) struct pbus_set_ranges_data *range)
{ {
/* No fixups needed */ /* No fixups needed */
......
...@@ -380,7 +380,7 @@ static int __init map_harp_irq(struct pci_dev *dev, u8 slot, u8 pin) ...@@ -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, pcibios_fixup_pbus_ranges(struct pci_bus *bus,
struct pbus_set_ranges_data *ranges) struct pbus_set_ranges_data *ranges)
{ {
......
...@@ -479,7 +479,7 @@ void pcibios_update_irq(struct pci_dev *pdev, int irq) ...@@ -479,7 +479,7 @@ void pcibios_update_irq(struct pci_dev *pdev, int irq)
{ {
} }
void pcibios_fixup_pbus_ranges(struct pci_bus *pbus, void __devinit pcibios_fixup_pbus_ranges(struct pci_bus *pbus,
struct pbus_set_ranges_data *pranges) struct pbus_set_ranges_data *pranges)
{ {
} }
......
...@@ -24,6 +24,49 @@ ...@@ -24,6 +24,49 @@
#define DBG(x...) #define DBG(x...)
#endif #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 * pci_find_capability - query for devices' capabilities
* @dev: PCI device to query * @dev: PCI device to query
...@@ -79,6 +122,49 @@ pci_find_capability(struct pci_dev *dev, int cap) ...@@ -79,6 +122,49 @@ pci_find_capability(struct pci_dev *dev, int cap)
return 0; 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 * pci_find_parent_resource - return resource region of parent bus of given region
...@@ -644,7 +730,10 @@ __setup("pci=", pci_setup); ...@@ -644,7 +730,10 @@ __setup("pci=", pci_setup);
EXPORT_SYMBOL(pci_enable_device); EXPORT_SYMBOL(pci_enable_device);
EXPORT_SYMBOL(pci_disable_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_find_capability);
EXPORT_SYMBOL(pci_bus_find_capability);
EXPORT_SYMBOL(pci_release_regions); EXPORT_SYMBOL(pci_release_regions);
EXPORT_SYMBOL(pci_request_regions); EXPORT_SYMBOL(pci_request_regions);
EXPORT_SYMBOL(pci_release_region); EXPORT_SYMBOL(pci_release_region);
...@@ -656,6 +745,8 @@ EXPORT_SYMBOL(pci_set_dma_mask); ...@@ -656,6 +745,8 @@ EXPORT_SYMBOL(pci_set_dma_mask);
EXPORT_SYMBOL(pci_dac_set_dma_mask); EXPORT_SYMBOL(pci_dac_set_dma_mask);
EXPORT_SYMBOL(pci_assign_resource); EXPORT_SYMBOL(pci_assign_resource);
EXPORT_SYMBOL(pci_find_parent_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_set_power_state);
EXPORT_SYMBOL(pci_save_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 ...@@ -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 * them, we proceed to assigning numbers to the remaining buses in
* order to avoid overlaps between old and new bus numbers. * 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 int buses;
unsigned short cr; unsigned short cr;
...@@ -595,4 +595,5 @@ EXPORT_SYMBOL(pci_add_new_bus); ...@@ -595,4 +595,5 @@ EXPORT_SYMBOL(pci_add_new_bus);
EXPORT_SYMBOL(pci_do_scan_bus); EXPORT_SYMBOL(pci_do_scan_bus);
EXPORT_SYMBOL(pci_scan_slot); EXPORT_SYMBOL(pci_scan_slot);
EXPORT_SYMBOL(pci_scan_bus); EXPORT_SYMBOL(pci_scan_bus);
EXPORT_SYMBOL(pci_scan_bridge);
#endif #endif
#include <linux/pci.h> #include <linux/pci.h>
#include <linux/module.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 * pci_find_slot - locate PCI device from a given PCI slot
* @bus: number of PCI bus on which desired PCI device resides * @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) ...@@ -104,6 +143,7 @@ pci_find_class(unsigned int class, const struct pci_dev *from)
return NULL; return NULL;
} }
EXPORT_SYMBOL(pci_find_bus);
EXPORT_SYMBOL(pci_find_class); EXPORT_SYMBOL(pci_find_class);
EXPORT_SYMBOL(pci_find_device); EXPORT_SYMBOL(pci_find_device);
EXPORT_SYMBOL(pci_find_slot); EXPORT_SYMBOL(pci_find_slot);
......
...@@ -35,7 +35,7 @@ ...@@ -35,7 +35,7 @@
#define ROUND_UP(x, a) (((x) + (a) - 1) & ~((a) - 1)) #define ROUND_UP(x, a) (((x) + (a) - 1) & ~((a) - 1))
static int __init static int __devinit
pbus_assign_resources_sorted(struct pci_bus *bus) pbus_assign_resources_sorted(struct pci_bus *bus)
{ {
struct list_head *ln; struct list_head *ln;
...@@ -85,7 +85,7 @@ pbus_assign_resources_sorted(struct pci_bus *bus) ...@@ -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 requires that if there is no I/O ports or memory behind the
bridge, corresponding range must be turned off by writing base bridge, corresponding range must be turned off by writing base
value greater than limit to the bridge's base/limit registers. */ value greater than limit to the bridge's base/limit registers. */
static void __init static void __devinit
pci_setup_bridge(struct pci_bus *bus) pci_setup_bridge(struct pci_bus *bus)
{ {
struct pbus_set_ranges_data ranges; struct pbus_set_ranges_data ranges;
...@@ -168,7 +168,7 @@ pci_setup_bridge(struct pci_bus *bus) ...@@ -168,7 +168,7 @@ pci_setup_bridge(struct pci_bus *bus)
/* Check whether the bridge supports optional I/O and /* Check whether the bridge supports optional I/O and
prefetchable memory ranges. If not, the respective prefetchable memory ranges. If not, the respective
base/limit registers must be read-only and read as 0. */ 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) pci_bridge_check_ranges(struct pci_bus *bus)
{ {
u16 io; u16 io;
...@@ -210,7 +210,7 @@ pci_bridge_check_ranges(struct pci_bus *bus) ...@@ -210,7 +210,7 @@ pci_bridge_check_ranges(struct pci_bus *bus)
since these windows have 4K granularity and the IO ranges since these windows have 4K granularity and the IO ranges
of non-bridge PCI devices are limited to 256 bytes. of non-bridge PCI devices are limited to 256 bytes.
We must be careful with the ISA aliasing though. */ We must be careful with the ISA aliasing though. */
static void __init static void __devinit
pbus_size_io(struct pci_bus *bus) pbus_size_io(struct pci_bus *bus)
{ {
struct list_head *ln; struct list_head *ln;
...@@ -259,7 +259,7 @@ pbus_size_io(struct pci_bus *bus) ...@@ -259,7 +259,7 @@ pbus_size_io(struct pci_bus *bus)
/* Calculate the size of the bus and minimal alignment which /* Calculate the size of the bus and minimal alignment which
guarantees that all child resources fit in this size. */ 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) pbus_size_mem(struct pci_bus *bus, unsigned long mask, unsigned long type)
{ {
struct list_head *ln; struct list_head *ln;
...@@ -331,7 +331,7 @@ pbus_size_mem(struct pci_bus *bus, unsigned long mask, unsigned long type) ...@@ -331,7 +331,7 @@ pbus_size_mem(struct pci_bus *bus, unsigned long mask, unsigned long type)
b_res->end = size + min_align - 1; b_res->end = size + min_align - 1;
} }
void __init void __devinit
pbus_size_bridges(struct pci_bus *bus) pbus_size_bridges(struct pci_bus *bus)
{ {
struct list_head *ln; struct list_head *ln;
...@@ -358,7 +358,7 @@ pbus_size_bridges(struct pci_bus *bus) ...@@ -358,7 +358,7 @@ pbus_size_bridges(struct pci_bus *bus)
pbus_size_mem(bus, mask, type); pbus_size_mem(bus, mask, type);
} }
void __init void __devinit
pbus_assign_resources(struct pci_bus *bus) pbus_assign_resources(struct pci_bus *bus)
{ {
struct list_head *ln; struct list_head *ln;
......
...@@ -557,8 +557,12 @@ struct pci_dev *pci_find_subsys (unsigned int vendor, unsigned int device, ...@@ -557,8 +557,12 @@ struct pci_dev *pci_find_subsys (unsigned int vendor, unsigned int device,
unsigned int ss_vendor, unsigned int ss_device, unsigned int ss_vendor, unsigned int ss_device,
const struct pci_dev *from); const struct pci_dev *from);
struct pci_dev *pci_find_class (unsigned int class, 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); 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_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_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); 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); ...@@ -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) */ /* 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); int pci_claim_resource(struct pci_dev *, int);
void pci_assign_unassigned_resources(void); void pci_assign_unassigned_resources(void);
void pdev_enable_device(struct pci_dev *); void pdev_enable_device(struct pci_dev *);
...@@ -634,6 +640,7 @@ struct pci_driver *pci_dev_driver(const 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); 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); 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); 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() */ /* kmem_cache style wrapper around pci_alloc_consistent() */
struct pci_pool *pci_pool_create (const char *name, struct pci_dev *dev, 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