Commit 78149df6 authored by Linus Torvalds's avatar Linus Torvalds

Merge master.kernel.org:/pub/scm/linux/kernel/git/gregkh/pci-2.6

* master.kernel.org:/pub/scm/linux/kernel/git/gregkh/pci-2.6: (41 commits)
  Revert "PCI: remove duplicate device id from ata_piix"
  msi: Make MSI useable more architectures
  msi: Kill the msi_desc array.
  msi: Remove attach_msi_entry.
  msi: Fix msi_remove_pci_irq_vectors.
  msi: Remove msi_lock.
  msi: Kill msi_lookup_irq
  MSI: Combine pci_(save|restore)_msi/msix_state
  MSI: Remove pci_scan_msi_device()
  MSI: Replace pci_msi_quirk with calls to pci_no_msi()
  PCI: remove duplicate device id from ipr
  PCI: remove duplicate device id from ata_piix
  PCI: power management: remove noise on non-manageable hw
  PCI: cleanup MSI code
  PCI: make isa_bridge Alpha-only
  PCI: remove quirk_sis_96x_compatible()
  PCI: Speed up the Intel SMBus unhiding quirk
  PCI Quirk: 1k I/O space IOBL_ADR fix on P64H2
  shpchp: delete trailing whitespace
  shpchp: remove DBG_XXX_ROUTINE
  ...
parents c96e2c92 14719f32
...@@ -575,3 +575,7 @@ void pci_iounmap(struct pci_dev *dev, void __iomem * addr) ...@@ -575,3 +575,7 @@ void pci_iounmap(struct pci_dev *dev, void __iomem * addr)
EXPORT_SYMBOL(pci_iomap); EXPORT_SYMBOL(pci_iomap);
EXPORT_SYMBOL(pci_iounmap); EXPORT_SYMBOL(pci_iounmap);
/* FIXME: Some boxes have multiple ISA bridges! */
struct pci_dev *isa_bridge;
EXPORT_SYMBOL(isa_bridge);
...@@ -2606,25 +2606,32 @@ static struct irq_chip msi_chip = { ...@@ -2606,25 +2606,32 @@ static struct irq_chip msi_chip = {
.retrigger = ioapic_retrigger_irq, .retrigger = ioapic_retrigger_irq,
}; };
int arch_setup_msi_irq(unsigned int irq, struct pci_dev *dev) int arch_setup_msi_irq(struct pci_dev *dev, struct msi_desc *desc)
{ {
struct msi_msg msg; struct msi_msg msg;
int ret; int irq, ret;
irq = create_irq();
if (irq < 0)
return irq;
set_irq_msi(irq, desc);
ret = msi_compose_msg(dev, irq, &msg); ret = msi_compose_msg(dev, irq, &msg);
if (ret < 0) if (ret < 0) {
destroy_irq(irq);
return ret; return ret;
}
write_msi_msg(irq, &msg); write_msi_msg(irq, &msg);
set_irq_chip_and_handler_name(irq, &msi_chip, handle_edge_irq, set_irq_chip_and_handler_name(irq, &msi_chip, handle_edge_irq,
"edge"); "edge");
return 0; return irq;
} }
void arch_teardown_msi_irq(unsigned int irq) void arch_teardown_msi_irq(unsigned int irq)
{ {
return; destroy_irq(irq);
} }
#endif /* CONFIG_PCI_MSI */ #endif /* CONFIG_PCI_MSI */
......
...@@ -64,12 +64,17 @@ static void ia64_set_msi_irq_affinity(unsigned int irq, cpumask_t cpu_mask) ...@@ -64,12 +64,17 @@ static void ia64_set_msi_irq_affinity(unsigned int irq, cpumask_t cpu_mask)
} }
#endif /* CONFIG_SMP */ #endif /* CONFIG_SMP */
int ia64_setup_msi_irq(unsigned int irq, struct pci_dev *pdev) int ia64_setup_msi_irq(struct pci_dev *pdev, struct msi_desc *desc)
{ {
struct msi_msg msg; struct msi_msg msg;
unsigned long dest_phys_id; unsigned long dest_phys_id;
unsigned int vector; unsigned int irq, vector;
irq = create_irq();
if (irq < 0)
return irq;
set_irq_msi(irq, desc);
dest_phys_id = cpu_physical_id(first_cpu(cpu_online_map)); dest_phys_id = cpu_physical_id(first_cpu(cpu_online_map));
vector = irq; vector = irq;
...@@ -89,12 +94,12 @@ int ia64_setup_msi_irq(unsigned int irq, struct pci_dev *pdev) ...@@ -89,12 +94,12 @@ int ia64_setup_msi_irq(unsigned int irq, struct pci_dev *pdev)
write_msi_msg(irq, &msg); write_msi_msg(irq, &msg);
set_irq_chip_and_handler(irq, &ia64_msi_chip, handle_edge_irq); set_irq_chip_and_handler(irq, &ia64_msi_chip, handle_edge_irq);
return 0; return irq;
} }
void ia64_teardown_msi_irq(unsigned int irq) void ia64_teardown_msi_irq(unsigned int irq)
{ {
return; /* no-op */ destroy_irq(irq);
} }
static void ia64_ack_msi_irq(unsigned int irq) static void ia64_ack_msi_irq(unsigned int irq)
...@@ -126,12 +131,12 @@ static struct irq_chip ia64_msi_chip = { ...@@ -126,12 +131,12 @@ static struct irq_chip ia64_msi_chip = {
}; };
int arch_setup_msi_irq(unsigned int irq, struct pci_dev *pdev) int arch_setup_msi_irq(struct pci_dev *pdev, struct msi_desc *desc)
{ {
if (platform_setup_msi_irq) if (platform_setup_msi_irq)
return platform_setup_msi_irq(irq, pdev); return platform_setup_msi_irq(pdev, desc);
return ia64_setup_msi_irq(irq, pdev); return ia64_setup_msi_irq(pdev, desc);
} }
void arch_teardown_msi_irq(unsigned int irq) void arch_teardown_msi_irq(unsigned int irq)
......
...@@ -59,13 +59,12 @@ void sn_teardown_msi_irq(unsigned int irq) ...@@ -59,13 +59,12 @@ void sn_teardown_msi_irq(unsigned int irq)
sn_intr_free(nasid, widget, sn_irq_info); sn_intr_free(nasid, widget, sn_irq_info);
sn_msi_info[irq].sn_irq_info = NULL; sn_msi_info[irq].sn_irq_info = NULL;
return; destroy_irq(irq);
} }
int sn_setup_msi_irq(unsigned int irq, struct pci_dev *pdev) int sn_setup_msi_irq(struct pci_dev *pdev, struct msi_desc *entry)
{ {
struct msi_msg msg; struct msi_msg msg;
struct msi_desc *entry;
int widget; int widget;
int status; int status;
nasid_t nasid; nasid_t nasid;
...@@ -73,8 +72,8 @@ int sn_setup_msi_irq(unsigned int irq, struct pci_dev *pdev) ...@@ -73,8 +72,8 @@ int sn_setup_msi_irq(unsigned int irq, struct pci_dev *pdev)
struct sn_irq_info *sn_irq_info; struct sn_irq_info *sn_irq_info;
struct pcibus_bussoft *bussoft = SN_PCIDEV_BUSSOFT(pdev); struct pcibus_bussoft *bussoft = SN_PCIDEV_BUSSOFT(pdev);
struct sn_pcibus_provider *provider = SN_PCIDEV_BUSPROVIDER(pdev); struct sn_pcibus_provider *provider = SN_PCIDEV_BUSPROVIDER(pdev);
int irq;
entry = get_irq_data(irq);
if (!entry->msi_attrib.is_64) if (!entry->msi_attrib.is_64)
return -EINVAL; return -EINVAL;
...@@ -84,6 +83,11 @@ int sn_setup_msi_irq(unsigned int irq, struct pci_dev *pdev) ...@@ -84,6 +83,11 @@ int sn_setup_msi_irq(unsigned int irq, struct pci_dev *pdev)
if (provider == NULL || provider->dma_map_consistent == NULL) if (provider == NULL || provider->dma_map_consistent == NULL)
return -EINVAL; return -EINVAL;
irq = create_irq();
if (irq < 0)
return irq;
set_irq_msi(irq, entry);
/* /*
* Set up the vector plumbing. Let the prom (via sn_intr_alloc) * Set up the vector plumbing. Let the prom (via sn_intr_alloc)
* decide which cpu to direct this msi at by default. * decide which cpu to direct this msi at by default.
...@@ -95,12 +99,15 @@ int sn_setup_msi_irq(unsigned int irq, struct pci_dev *pdev) ...@@ -95,12 +99,15 @@ int sn_setup_msi_irq(unsigned int irq, struct pci_dev *pdev)
SWIN_WIDGETNUM(bussoft->bs_base); SWIN_WIDGETNUM(bussoft->bs_base);
sn_irq_info = kzalloc(sizeof(struct sn_irq_info), GFP_KERNEL); sn_irq_info = kzalloc(sizeof(struct sn_irq_info), GFP_KERNEL);
if (! sn_irq_info) if (! sn_irq_info) {
destroy_irq(irq);
return -ENOMEM; return -ENOMEM;
}
status = sn_intr_alloc(nasid, widget, sn_irq_info, irq, -1, -1); status = sn_intr_alloc(nasid, widget, sn_irq_info, irq, -1, -1);
if (status) { if (status) {
kfree(sn_irq_info); kfree(sn_irq_info);
destroy_irq(irq);
return -ENOMEM; return -ENOMEM;
} }
...@@ -121,6 +128,7 @@ int sn_setup_msi_irq(unsigned int irq, struct pci_dev *pdev) ...@@ -121,6 +128,7 @@ int sn_setup_msi_irq(unsigned int irq, struct pci_dev *pdev)
if (! bus_addr) { if (! bus_addr) {
sn_intr_free(nasid, widget, sn_irq_info); sn_intr_free(nasid, widget, sn_irq_info);
kfree(sn_irq_info); kfree(sn_irq_info);
destroy_irq(irq);
return -ENOMEM; return -ENOMEM;
} }
...@@ -139,7 +147,7 @@ int sn_setup_msi_irq(unsigned int irq, struct pci_dev *pdev) ...@@ -139,7 +147,7 @@ int sn_setup_msi_irq(unsigned int irq, struct pci_dev *pdev)
write_msi_msg(irq, &msg); write_msi_msg(irq, &msg);
set_irq_chip_and_handler(irq, &sn_msi_chip, handle_edge_irq); set_irq_chip_and_handler(irq, &sn_msi_chip, handle_edge_irq);
return 0; return irq;
} }
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
......
...@@ -381,8 +381,6 @@ struct pci_dev *of_create_pci_dev(struct device_node *node, ...@@ -381,8 +381,6 @@ struct pci_dev *of_create_pci_dev(struct device_node *node,
pci_device_add(dev, bus); pci_device_add(dev, bus);
/* XXX pci_scan_msi_device(dev); */
return dev; return dev;
} }
EXPORT_SYMBOL(of_create_pci_dev); EXPORT_SYMBOL(of_create_pci_dev);
......
...@@ -1956,24 +1956,31 @@ static struct irq_chip msi_chip = { ...@@ -1956,24 +1956,31 @@ static struct irq_chip msi_chip = {
.retrigger = ioapic_retrigger_irq, .retrigger = ioapic_retrigger_irq,
}; };
int arch_setup_msi_irq(unsigned int irq, struct pci_dev *dev) int arch_setup_msi_irq(struct pci_dev *dev, struct msi_desc *desc)
{ {
struct msi_msg msg; struct msi_msg msg;
int ret; int irq, ret;
irq = create_irq();
if (irq < 0)
return irq;
set_irq_msi(irq, desc);
ret = msi_compose_msg(dev, irq, &msg); ret = msi_compose_msg(dev, irq, &msg);
if (ret < 0) if (ret < 0) {
destroy_irq(irq);
return ret; return ret;
}
write_msi_msg(irq, &msg); write_msi_msg(irq, &msg);
set_irq_chip_and_handler_name(irq, &msi_chip, handle_edge_irq, "edge"); set_irq_chip_and_handler_name(irq, &msi_chip, handle_edge_irq, "edge");
return 0; return irq;
} }
void arch_teardown_msi_irq(unsigned int irq) void arch_teardown_msi_irq(unsigned int irq)
{ {
return; destroy_irq(irq);
} }
#endif /* CONFIG_PCI_MSI */ #endif /* CONFIG_PCI_MSI */
......
...@@ -5947,8 +5947,7 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev) ...@@ -5947,8 +5947,7 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev)
* responding after a while. * responding after a while.
* *
* AMD believes this incompatibility is unique to the 5706, and * AMD believes this incompatibility is unique to the 5706, and
* prefers to locally disable MSI rather than globally disabling it * prefers to locally disable MSI rather than globally disabling it.
* using pci_msi_quirk.
*/ */
if (CHIP_NUM(bp) == CHIP_NUM_5706 && disable_msi == 0) { if (CHIP_NUM(bp) == CHIP_NUM_5706 && disable_msi == 0) {
struct pci_dev *amd_8132 = NULL; struct pci_dev *amd_8132 = NULL;
......
...@@ -3584,7 +3584,7 @@ e1000_update_stats(struct e1000_adapter *adapter) ...@@ -3584,7 +3584,7 @@ e1000_update_stats(struct e1000_adapter *adapter)
*/ */
if (adapter->link_speed == 0) if (adapter->link_speed == 0)
return; return;
if (pdev->error_state && pdev->error_state != pci_channel_io_normal) if (pci_channel_offline(pdev))
return; return;
spin_lock_irqsave(&adapter->stats_lock, flags); spin_lock_irqsave(&adapter->stats_lock, flags);
......
...@@ -1605,7 +1605,7 @@ ixgb_update_stats(struct ixgb_adapter *adapter) ...@@ -1605,7 +1605,7 @@ ixgb_update_stats(struct ixgb_adapter *adapter)
struct pci_dev *pdev = adapter->pdev; struct pci_dev *pdev = adapter->pdev;
/* Prevent stats update while adapter is being reset */ /* Prevent stats update while adapter is being reset */
if (pdev->error_state && pdev->error_state != pci_channel_io_normal) if (pci_channel_offline(pdev))
return; return;
if((netdev->flags & IFF_PROMISC) || (netdev->flags & IFF_ALLMULTI) || if((netdev->flags & IFF_PROMISC) || (netdev->flags & IFF_ALLMULTI) ||
......
...@@ -145,15 +145,6 @@ config HOTPLUG_PCI_SHPC ...@@ -145,15 +145,6 @@ config HOTPLUG_PCI_SHPC
When in doubt, say N. When in doubt, say N.
config HOTPLUG_PCI_SHPC_POLL_EVENT_MODE
bool "Use polling mechanism for hot-plug events (for testing purpose)"
depends on HOTPLUG_PCI_SHPC
help
Say Y here if you want to use the polling mechanism for hot-plug
events for early platform testing.
When in doubt, say N.
config HOTPLUG_PCI_RPA config HOTPLUG_PCI_RPA
tristate "RPA PCI Hotplug driver" tristate "RPA PCI Hotplug driver"
depends on HOTPLUG_PCI && PPC_PSERIES && PPC64 && !HOTPLUG_PCI_FAKE depends on HOTPLUG_PCI && PPC_PSERIES && PPC64 && !HOTPLUG_PCI_FAKE
......
...@@ -44,15 +44,20 @@ extern int pciehp_poll_time; ...@@ -44,15 +44,20 @@ extern int pciehp_poll_time;
extern int pciehp_debug; extern int pciehp_debug;
extern int pciehp_force; extern int pciehp_force;
/*#define dbg(format, arg...) do { if (pciehp_debug) printk(KERN_DEBUG "%s: " format, MY_NAME , ## arg); } while (0)*/ #define dbg(format, arg...) \
#define dbg(format, arg...) do { if (pciehp_debug) printk("%s: " format, MY_NAME , ## arg); } while (0) do { \
#define err(format, arg...) printk(KERN_ERR "%s: " format, MY_NAME , ## arg) if (pciehp_debug) \
#define info(format, arg...) printk(KERN_INFO "%s: " format, MY_NAME , ## arg) printk("%s: " format, MY_NAME , ## arg); \
#define warn(format, arg...) printk(KERN_WARNING "%s: " format, MY_NAME , ## arg) } while (0)
#define err(format, arg...) \
printk(KERN_ERR "%s: " format, MY_NAME , ## arg)
#define info(format, arg...) \
printk(KERN_INFO "%s: " format, MY_NAME , ## arg)
#define warn(format, arg...) \
printk(KERN_WARNING "%s: " format, MY_NAME , ## arg)
#define SLOT_NAME_SIZE 10
struct slot { struct slot {
struct slot *next;
u8 bus; u8 bus;
u8 device; u8 device;
u32 number; u32 number;
...@@ -63,6 +68,8 @@ struct slot { ...@@ -63,6 +68,8 @@ struct slot {
struct hpc_ops *hpc_ops; struct hpc_ops *hpc_ops;
struct hotplug_slot *hotplug_slot; struct hotplug_slot *hotplug_slot;
struct list_head slot_list; struct list_head slot_list;
char name[SLOT_NAME_SIZE];
unsigned long last_emi_toggle;
}; };
struct event_info { struct event_info {
...@@ -70,34 +77,15 @@ struct event_info { ...@@ -70,34 +77,15 @@ struct event_info {
u8 hp_slot; u8 hp_slot;
}; };
typedef u8(*php_intr_callback_t) (u8 hp_slot, void *instance_id);
struct php_ctlr_state_s {
struct php_ctlr_state_s *pnext;
struct pci_dev *pci_dev;
unsigned int irq;
unsigned long flags; /* spinlock's */
u32 slot_device_offset;
u32 num_slots;
struct timer_list int_poll_timer; /* Added for poll event */
php_intr_callback_t attention_button_callback;
php_intr_callback_t switch_change_callback;
php_intr_callback_t presence_change_callback;
php_intr_callback_t power_fault_callback;
void *callback_instance_id;
struct ctrl_reg *creg; /* Ptr to controller register space */
};
#define MAX_EVENTS 10 #define MAX_EVENTS 10
struct controller { struct controller {
struct controller *next; struct controller *next;
struct mutex crit_sect; /* critical section mutex */ struct mutex crit_sect; /* critical section mutex */
struct mutex ctrl_lock; /* controller lock */ struct mutex ctrl_lock; /* controller lock */
struct php_ctlr_state_s *hpc_ctlr_handle; /* HPC controller handle */
int num_slots; /* Number of slots on ctlr */ int num_slots; /* Number of slots on ctlr */
int slot_num_inc; /* 1 or -1 */ int slot_num_inc; /* 1 or -1 */
struct pci_dev *pci_dev; struct pci_dev *pci_dev;
struct pci_bus *pci_bus; struct list_head slot_list;
struct event_info event_queue[MAX_EVENTS]; struct event_info event_queue[MAX_EVENTS];
struct slot *slot; struct slot *slot;
struct hpc_ops *hpc_ops; struct hpc_ops *hpc_ops;
...@@ -112,6 +100,8 @@ struct controller { ...@@ -112,6 +100,8 @@ struct controller {
u8 ctrlcap; u8 ctrlcap;
u16 vendor_id; u16 vendor_id;
u8 cap_base; u8 cap_base;
struct timer_list poll_timer;
volatile int cmd_busy;
}; };
#define INT_BUTTON_IGNORE 0 #define INT_BUTTON_IGNORE 0
...@@ -131,8 +121,6 @@ struct controller { ...@@ -131,8 +121,6 @@ struct controller {
#define POWERON_STATE 3 #define POWERON_STATE 3
#define POWEROFF_STATE 4 #define POWEROFF_STATE 4
#define PCI_TO_PCI_BRIDGE_CLASS 0x00060400
/* Error messages */ /* Error messages */
#define INTERLOCK_OPEN 0x00000002 #define INTERLOCK_OPEN 0x00000002
#define ADD_NOT_SUPPORTED 0x00000003 #define ADD_NOT_SUPPORTED 0x00000003
...@@ -144,10 +132,6 @@ struct controller { ...@@ -144,10 +132,6 @@ struct controller {
#define WRONG_BUS_FREQUENCY 0x0000000D #define WRONG_BUS_FREQUENCY 0x0000000D
#define POWER_FAILURE 0x0000000E #define POWER_FAILURE 0x0000000E
#define REMOVE_NOT_SUPPORTED 0x00000003
#define DISABLE_CARD 1
/* Field definitions in Slot Capabilities Register */ /* Field definitions in Slot Capabilities Register */
#define ATTN_BUTTN_PRSN 0x00000001 #define ATTN_BUTTN_PRSN 0x00000001
#define PWR_CTRL_PRSN 0x00000002 #define PWR_CTRL_PRSN 0x00000002
...@@ -155,6 +139,7 @@ struct controller { ...@@ -155,6 +139,7 @@ struct controller {
#define ATTN_LED_PRSN 0x00000008 #define ATTN_LED_PRSN 0x00000008
#define PWR_LED_PRSN 0x00000010 #define PWR_LED_PRSN 0x00000010
#define HP_SUPR_RM_SUP 0x00000020 #define HP_SUPR_RM_SUP 0x00000020
#define EMI_PRSN 0x00020000
#define ATTN_BUTTN(cap) (cap & ATTN_BUTTN_PRSN) #define ATTN_BUTTN(cap) (cap & ATTN_BUTTN_PRSN)
#define POWER_CTRL(cap) (cap & PWR_CTRL_PRSN) #define POWER_CTRL(cap) (cap & PWR_CTRL_PRSN)
...@@ -162,130 +147,65 @@ struct controller { ...@@ -162,130 +147,65 @@ struct controller {
#define ATTN_LED(cap) (cap & ATTN_LED_PRSN) #define ATTN_LED(cap) (cap & ATTN_LED_PRSN)
#define PWR_LED(cap) (cap & PWR_LED_PRSN) #define PWR_LED(cap) (cap & PWR_LED_PRSN)
#define HP_SUPR_RM(cap) (cap & HP_SUPR_RM_SUP) #define HP_SUPR_RM(cap) (cap & HP_SUPR_RM_SUP)
#define EMI(cap) (cap & EMI_PRSN)
/*
* error Messages extern int pciehp_event_start_thread(void);
*/ extern void pciehp_event_stop_thread(void);
#define msg_initialization_err "Initialization failure, error=%d\n" extern int pciehp_enable_slot(struct slot *slot);
#define msg_button_on "PCI slot #%s - powering on due to button press.\n" extern int pciehp_disable_slot(struct slot *slot);
#define msg_button_off "PCI slot #%s - powering off due to button press.\n" extern u8 pciehp_handle_attention_button(u8 hp_slot, struct controller *ctrl);
#define msg_button_cancel "PCI slot #%s - action canceled due to button press.\n" extern u8 pciehp_handle_switch_change(u8 hp_slot, struct controller *ctrl);
#define msg_button_ignore "PCI slot #%s - button press ignored. (action in progress...)\n" extern u8 pciehp_handle_presence_change(u8 hp_slot, struct controller *ctrl);
extern u8 pciehp_handle_power_fault(u8 hp_slot, struct controller *ctrl);
/* controller functions */ extern int pciehp_configure_device(struct slot *p_slot);
extern int pciehp_event_start_thread (void); extern int pciehp_unconfigure_device(struct slot *p_slot);
extern void pciehp_event_stop_thread (void); int pcie_init(struct controller *ctrl, struct pcie_device *dev);
extern int pciehp_enable_slot (struct slot *slot);
extern int pciehp_disable_slot (struct slot *slot);
extern u8 pciehp_handle_attention_button (u8 hp_slot, void *inst_id);
extern u8 pciehp_handle_switch_change (u8 hp_slot, void *inst_id);
extern u8 pciehp_handle_presence_change (u8 hp_slot, void *inst_id);
extern u8 pciehp_handle_power_fault (u8 hp_slot, void *inst_id);
/* extern void long_delay (int delay); */
/* pci functions */
extern int pciehp_configure_device (struct slot *p_slot);
extern int pciehp_unconfigure_device (struct slot *p_slot);
/* Global variables */ /* Global variables */
extern struct controller *pciehp_ctrl_list; extern struct controller *pciehp_ctrl_list;
/* Inline functions */
static inline struct slot *pciehp_find_slot(struct controller *ctrl, u8 device) static inline struct slot *pciehp_find_slot(struct controller *ctrl, u8 device)
{ {
struct slot *p_slot, *tmp_slot = NULL; struct slot *slot;
p_slot = ctrl->slot;
while (p_slot && (p_slot->device != device)) { list_for_each_entry(slot, &ctrl->slot_list, slot_list) {
tmp_slot = p_slot; if (slot->device == device)
p_slot = p_slot->next; return slot;
} }
if (p_slot == NULL) {
err("ERROR: pciehp_find_slot device=0x%x\n", device);
p_slot = tmp_slot;
}
return p_slot;
}
static inline int wait_for_ctrl_irq(struct controller *ctrl)
{
int retval = 0;
DECLARE_WAITQUEUE(wait, current);
add_wait_queue(&ctrl->queue, &wait);
if (!pciehp_poll_mode)
/* Sleep for up to 1 second */
msleep_interruptible(1000);
else
msleep_interruptible(2500);
remove_wait_queue(&ctrl->queue, &wait);
if (signal_pending(current))
retval = -EINTR;
return retval;
}
#define SLOT_NAME_SIZE 10
static inline void make_slot_name(char *buffer, int buffer_size, struct slot *slot) err("%s: slot (device=0x%x) not found\n", __FUNCTION__, device);
{ return NULL;
snprintf(buffer, buffer_size, "%04d_%04d", slot->bus, slot->number);
} }
enum php_ctlr_type {
PCI,
ISA,
ACPI
};
int pcie_init(struct controller *ctrl, struct pcie_device *dev);
/* This has no meaning for PCI Express, as there is only 1 slot per port */
int pcie_get_ctlr_slot_config(struct controller *ctrl,
int *num_ctlr_slots,
int *first_device_num,
int *physical_slot_num,
u8 *ctrlcap);
struct hpc_ops { struct hpc_ops {
int (*power_on_slot) (struct slot *slot); int (*power_on_slot)(struct slot *slot);
int (*power_off_slot) (struct slot *slot); int (*power_off_slot)(struct slot *slot);
int (*get_power_status) (struct slot *slot, u8 *status); int (*get_power_status)(struct slot *slot, u8 *status);
int (*get_attention_status) (struct slot *slot, u8 *status); int (*get_attention_status)(struct slot *slot, u8 *status);
int (*set_attention_status) (struct slot *slot, u8 status); int (*set_attention_status)(struct slot *slot, u8 status);
int (*get_latch_status) (struct slot *slot, u8 *status); int (*get_latch_status)(struct slot *slot, u8 *status);
int (*get_adapter_status) (struct slot *slot, u8 *status); int (*get_adapter_status)(struct slot *slot, u8 *status);
int (*get_emi_status)(struct slot *slot, u8 *status);
int (*get_max_bus_speed) (struct slot *slot, enum pci_bus_speed *speed); int (*toggle_emi)(struct slot *slot);
int (*get_cur_bus_speed) (struct slot *slot, enum pci_bus_speed *speed); int (*get_max_bus_speed)(struct slot *slot, enum pci_bus_speed *speed);
int (*get_cur_bus_speed)(struct slot *slot, enum pci_bus_speed *speed);
int (*get_max_lnk_width) (struct slot *slot, enum pcie_link_width *value); int (*get_max_lnk_width)(struct slot *slot, enum pcie_link_width *val);
int (*get_cur_lnk_width) (struct slot *slot, enum pcie_link_width *value); int (*get_cur_lnk_width)(struct slot *slot, enum pcie_link_width *val);
int (*query_power_fault)(struct slot *slot);
int (*query_power_fault) (struct slot *slot); void (*green_led_on)(struct slot *slot);
void (*green_led_on) (struct slot *slot); void (*green_led_off)(struct slot *slot);
void (*green_led_off) (struct slot *slot); void (*green_led_blink)(struct slot *slot);
void (*green_led_blink) (struct slot *slot); void (*release_ctlr)(struct controller *ctrl);
void (*release_ctlr) (struct controller *ctrl); int (*check_lnk_status)(struct controller *ctrl);
int (*check_lnk_status) (struct controller *ctrl);
}; };
#ifdef CONFIG_ACPI #ifdef CONFIG_ACPI
#include <acpi/acpi.h> #include <acpi/acpi.h>
#include <acpi/acpi_bus.h> #include <acpi/acpi_bus.h>
#include <acpi/actypes.h> #include <acpi/actypes.h>
#include <linux/pci-acpi.h> #include <linux/pci-acpi.h>
#define pciehp_get_hp_hw_control_from_firmware(dev) \ #define pciehp_get_hp_hw_control_from_firmware(dev) \
pciehp_acpi_get_hp_hw_control_from_firmware(dev) pciehp_acpi_get_hp_hw_control_from_firmware(dev)
static inline int pciehp_get_hp_params_from_firmware(struct pci_dev *dev, static inline int pciehp_get_hp_params_from_firmware(struct pci_dev *dev,
struct hotplug_params *hpp) struct hotplug_params *hpp)
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
...@@ -106,7 +106,7 @@ struct controller { ...@@ -106,7 +106,7 @@ struct controller {
}; };
/* Define AMD SHPC ID */ /* Define AMD SHPC ID */
#define PCI_DEVICE_ID_AMD_GOLAM_7450 0x7450 #define PCI_DEVICE_ID_AMD_GOLAM_7450 0x7450
#define PCI_DEVICE_ID_AMD_POGO_7458 0x7458 #define PCI_DEVICE_ID_AMD_POGO_7458 0x7458
/* AMD PCIX bridge registers */ /* AMD PCIX bridge registers */
...@@ -221,7 +221,7 @@ enum ctrl_offsets { ...@@ -221,7 +221,7 @@ enum ctrl_offsets {
}; };
static inline struct slot *get_slot(struct hotplug_slot *hotplug_slot) static inline struct slot *get_slot(struct hotplug_slot *hotplug_slot)
{ {
return hotplug_slot->private; return hotplug_slot->private;
} }
......
...@@ -401,10 +401,6 @@ static int __init shpcd_init(void) ...@@ -401,10 +401,6 @@ static int __init shpcd_init(void)
{ {
int retval = 0; int retval = 0;
#ifdef CONFIG_HOTPLUG_PCI_SHPC_POLL_EVENT_MODE
shpchp_poll_mode = 1;
#endif
retval = pci_register_driver(&shpc_driver); retval = pci_register_driver(&shpc_driver);
dbg("%s: pci_register_driver = %d\n", __FUNCTION__, retval); dbg("%s: pci_register_driver = %d\n", __FUNCTION__, retval);
info(DRIVER_DESC " version: " DRIVER_VERSION "\n"); info(DRIVER_DESC " version: " DRIVER_VERSION "\n");
......
...@@ -64,7 +64,7 @@ u8 shpchp_handle_attention_button(u8 hp_slot, struct controller *ctrl) ...@@ -64,7 +64,7 @@ u8 shpchp_handle_attention_button(u8 hp_slot, struct controller *ctrl)
/* Attention Button Change */ /* Attention Button Change */
dbg("shpchp: Attention button interrupt received.\n"); dbg("shpchp: Attention button interrupt received.\n");
p_slot = shpchp_find_slot(ctrl, hp_slot + ctrl->slot_device_offset); p_slot = shpchp_find_slot(ctrl, hp_slot + ctrl->slot_device_offset);
p_slot->hpc_ops->get_adapter_status(p_slot, &(p_slot->presence_save)); p_slot->hpc_ops->get_adapter_status(p_slot, &(p_slot->presence_save));
...@@ -128,7 +128,7 @@ u8 shpchp_handle_presence_change(u8 hp_slot, struct controller *ctrl) ...@@ -128,7 +128,7 @@ u8 shpchp_handle_presence_change(u8 hp_slot, struct controller *ctrl)
p_slot = shpchp_find_slot(ctrl, hp_slot + ctrl->slot_device_offset); p_slot = shpchp_find_slot(ctrl, hp_slot + ctrl->slot_device_offset);
/* /*
* Save the presence state * Save the presence state
*/ */
p_slot->hpc_ops->get_adapter_status(p_slot, &(p_slot->presence_save)); p_slot->hpc_ops->get_adapter_status(p_slot, &(p_slot->presence_save));
...@@ -184,12 +184,12 @@ u8 shpchp_handle_power_fault(u8 hp_slot, struct controller *ctrl) ...@@ -184,12 +184,12 @@ u8 shpchp_handle_power_fault(u8 hp_slot, struct controller *ctrl)
return 1; return 1;
} }
/* The following routines constitute the bulk of the /* The following routines constitute the bulk of the
hotplug controller logic hotplug controller logic
*/ */
static int change_bus_speed(struct controller *ctrl, struct slot *p_slot, static int change_bus_speed(struct controller *ctrl, struct slot *p_slot,
enum pci_bus_speed speed) enum pci_bus_speed speed)
{ {
int rc = 0; int rc = 0;
dbg("%s: change to speed %d\n", __FUNCTION__, speed); dbg("%s: change to speed %d\n", __FUNCTION__, speed);
...@@ -204,7 +204,7 @@ static int change_bus_speed(struct controller *ctrl, struct slot *p_slot, ...@@ -204,7 +204,7 @@ static int change_bus_speed(struct controller *ctrl, struct slot *p_slot,
static int fix_bus_speed(struct controller *ctrl, struct slot *pslot, static int fix_bus_speed(struct controller *ctrl, struct slot *pslot,
u8 flag, enum pci_bus_speed asp, enum pci_bus_speed bsp, u8 flag, enum pci_bus_speed asp, enum pci_bus_speed bsp,
enum pci_bus_speed msp) enum pci_bus_speed msp)
{ {
int rc = 0; int rc = 0;
/* /*
...@@ -257,23 +257,23 @@ static int board_added(struct slot *p_slot) ...@@ -257,23 +257,23 @@ static int board_added(struct slot *p_slot)
err("%s: Failed to power on slot\n", __FUNCTION__); err("%s: Failed to power on slot\n", __FUNCTION__);
return -1; return -1;
} }
if ((ctrl->pci_dev->vendor == 0x8086) && (ctrl->pci_dev->device == 0x0332)) { if ((ctrl->pci_dev->vendor == 0x8086) && (ctrl->pci_dev->device == 0x0332)) {
if (slots_not_empty) if (slots_not_empty)
return WRONG_BUS_FREQUENCY; return WRONG_BUS_FREQUENCY;
if ((rc = p_slot->hpc_ops->set_bus_speed_mode(p_slot, PCI_SPEED_33MHz))) { if ((rc = p_slot->hpc_ops->set_bus_speed_mode(p_slot, PCI_SPEED_33MHz))) {
err("%s: Issue of set bus speed mode command failed\n", __FUNCTION__); err("%s: Issue of set bus speed mode command failed\n", __FUNCTION__);
return WRONG_BUS_FREQUENCY; return WRONG_BUS_FREQUENCY;
} }
/* turn on board, blink green LED, turn off Amber LED */ /* turn on board, blink green LED, turn off Amber LED */
if ((rc = p_slot->hpc_ops->slot_enable(p_slot))) { if ((rc = p_slot->hpc_ops->slot_enable(p_slot))) {
err("%s: Issue of Slot Enable command failed\n", __FUNCTION__); err("%s: Issue of Slot Enable command failed\n", __FUNCTION__);
return rc; return rc;
} }
} }
rc = p_slot->hpc_ops->get_adapter_speed(p_slot, &asp); rc = p_slot->hpc_ops->get_adapter_speed(p_slot, &asp);
if (rc) { if (rc) {
err("%s: Can't get adapter speed or bus mode mismatch\n", err("%s: Can't get adapter speed or bus mode mismatch\n",
...@@ -378,7 +378,7 @@ static int remove_board(struct slot *p_slot) ...@@ -378,7 +378,7 @@ static int remove_board(struct slot *p_slot)
err("%s: Issue of Slot Disable command failed\n", __FUNCTION__); err("%s: Issue of Slot Disable command failed\n", __FUNCTION__);
return rc; return rc;
} }
rc = p_slot->hpc_ops->set_attention_status(p_slot, 0); rc = p_slot->hpc_ops->set_attention_status(p_slot, 0);
if (rc) { if (rc) {
err("%s: Issue of Set Attention command failed\n", __FUNCTION__); err("%s: Issue of Set Attention command failed\n", __FUNCTION__);
......
This diff is collapsed.
This diff is collapsed.
...@@ -324,8 +324,7 @@ static int pci_default_resume(struct pci_dev *pci_dev) ...@@ -324,8 +324,7 @@ static int pci_default_resume(struct pci_dev *pci_dev)
/* restore the PCI config space */ /* restore the PCI config space */
pci_restore_state(pci_dev); pci_restore_state(pci_dev);
/* if the device was enabled before suspend, reenable */ /* if the device was enabled before suspend, reenable */
if (atomic_read(&pci_dev->enable_cnt)) retval = __pci_reenable_device(pci_dev);
retval = __pci_enable_device(pci_dev);
/* if the device was busmaster before the suspend, make it busmaster again */ /* if the device was busmaster before the suspend, make it busmaster again */
if (pci_dev->is_busmaster) if (pci_dev->is_busmaster)
pci_set_master(pci_dev); pci_set_master(pci_dev);
......
...@@ -392,6 +392,14 @@ pci_set_power_state(struct pci_dev *dev, pci_power_t state) ...@@ -392,6 +392,14 @@ pci_set_power_state(struct pci_dev *dev, pci_power_t state)
if (state > PCI_D3hot) if (state > PCI_D3hot)
state = PCI_D3hot; state = PCI_D3hot;
/*
* If the device or the parent bridge can't support PCI PM, ignore
* the request if we're doing anything besides putting it into D0
* (which would only happen on boot).
*/
if ((state == PCI_D1 || state == PCI_D2) && pci_no_d1d2(dev))
return 0;
/* Validate current state: /* Validate current state:
* Can enter D0 from any state, but if we can only go deeper * Can enter D0 from any state, but if we can only go deeper
* to sleep if we're already in a low power state * to sleep if we're already in a low power state
...@@ -403,13 +411,6 @@ pci_set_power_state(struct pci_dev *dev, pci_power_t state) ...@@ -403,13 +411,6 @@ pci_set_power_state(struct pci_dev *dev, pci_power_t state)
} else if (dev->current_state == state) } else if (dev->current_state == state)
return 0; /* we're already there */ return 0; /* we're already there */
/*
* If the device or the parent bridge can't support PCI PM, ignore
* the request if we're doing anything besides putting it into D0
* (which would only happen on boot).
*/
if ((state == PCI_D1 || state == PCI_D2) && pci_no_d1d2(dev))
return 0;
/* find PCI PM capability in list */ /* find PCI PM capability in list */
pm = pci_find_capability(dev, PCI_CAP_ID_PM); pm = pci_find_capability(dev, PCI_CAP_ID_PM);
...@@ -633,8 +634,6 @@ pci_save_state(struct pci_dev *dev) ...@@ -633,8 +634,6 @@ pci_save_state(struct pci_dev *dev)
pci_read_config_dword(dev, i * 4,&dev->saved_config_space[i]); pci_read_config_dword(dev, i * 4,&dev->saved_config_space[i]);
if ((i = pci_save_msi_state(dev)) != 0) if ((i = pci_save_msi_state(dev)) != 0)
return i; return i;
if ((i = pci_save_msix_state(dev)) != 0)
return i;
if ((i = pci_save_pcie_state(dev)) != 0) if ((i = pci_save_pcie_state(dev)) != 0)
return i; return i;
if ((i = pci_save_pcix_state(dev)) != 0) if ((i = pci_save_pcix_state(dev)) != 0)
...@@ -672,22 +671,11 @@ pci_restore_state(struct pci_dev *dev) ...@@ -672,22 +671,11 @@ pci_restore_state(struct pci_dev *dev)
} }
pci_restore_pcix_state(dev); pci_restore_pcix_state(dev);
pci_restore_msi_state(dev); pci_restore_msi_state(dev);
pci_restore_msix_state(dev);
return 0; return 0;
} }
/** static int do_pci_enable_device(struct pci_dev *dev, int bars)
* pci_enable_device_bars - Initialize some of a device for use
* @dev: PCI device to be initialized
* @bars: bitmask of BAR's that must be configured
*
* Initialize device before it's used by a driver. Ask low-level code
* to enable selected I/O and memory resources. Wake up the device if it
* was suspended. Beware, this function can fail.
*/
int
pci_enable_device_bars(struct pci_dev *dev, int bars)
{ {
int err; int err;
...@@ -697,30 +685,47 @@ pci_enable_device_bars(struct pci_dev *dev, int bars) ...@@ -697,30 +685,47 @@ pci_enable_device_bars(struct pci_dev *dev, int bars)
err = pcibios_enable_device(dev, bars); err = pcibios_enable_device(dev, bars);
if (err < 0) if (err < 0)
return err; return err;
pci_fixup_device(pci_fixup_enable, dev);
return 0; return 0;
} }
/** /**
* __pci_enable_device - Initialize device before it's used by a driver. * __pci_reenable_device - Resume abandoned device
* @dev: PCI device to be resumed
*
* Note this function is a backend of pci_default_resume and is not supposed
* to be called by normal code, write proper resume handler and use it instead.
*/
int
__pci_reenable_device(struct pci_dev *dev)
{
if (atomic_read(&dev->enable_cnt))
return do_pci_enable_device(dev, (1 << PCI_NUM_RESOURCES) - 1);
return 0;
}
/**
* pci_enable_device_bars - Initialize some of a device for use
* @dev: PCI device to be initialized * @dev: PCI device to be initialized
* @bars: bitmask of BAR's that must be configured
* *
* Initialize device before it's used by a driver. Ask low-level code * Initialize device before it's used by a driver. Ask low-level code
* to enable I/O and memory. Wake up the device if it was suspended. * to enable selected I/O and memory resources. Wake up the device if it
* Beware, this function can fail. * was suspended. Beware, this function can fail.
*
* Note this function is a backend and is not supposed to be called by
* normal code, use pci_enable_device() instead.
*/ */
int int
__pci_enable_device(struct pci_dev *dev) pci_enable_device_bars(struct pci_dev *dev, int bars)
{ {
int err; int err;
err = pci_enable_device_bars(dev, (1 << PCI_NUM_RESOURCES) - 1); if (atomic_add_return(1, &dev->enable_cnt) > 1)
if (err) return 0; /* already enabled */
return err;
pci_fixup_device(pci_fixup_enable, dev); err = do_pci_enable_device(dev, bars);
return 0; if (err < 0)
atomic_dec(&dev->enable_cnt);
return err;
} }
/** /**
...@@ -736,13 +741,7 @@ __pci_enable_device(struct pci_dev *dev) ...@@ -736,13 +741,7 @@ __pci_enable_device(struct pci_dev *dev)
*/ */
int pci_enable_device(struct pci_dev *dev) int pci_enable_device(struct pci_dev *dev)
{ {
int result; return pci_enable_device_bars(dev, (1 << PCI_NUM_RESOURCES) - 1);
if (atomic_add_return(1, &dev->enable_cnt) > 1)
return 0; /* already enabled */
result = __pci_enable_device(dev);
if (result < 0)
atomic_dec(&dev->enable_cnt);
return result;
} }
/** /**
...@@ -921,6 +920,47 @@ int pci_request_region(struct pci_dev *pdev, int bar, const char *res_name) ...@@ -921,6 +920,47 @@ int pci_request_region(struct pci_dev *pdev, int bar, const char *res_name)
return -EBUSY; return -EBUSY;
} }
/**
* pci_release_selected_regions - Release selected PCI I/O and memory resources
* @pdev: PCI device whose resources were previously reserved
* @bars: Bitmask of BARs to be released
*
* Release selected PCI I/O and memory resources previously reserved.
* Call this function only after all use of the PCI regions has ceased.
*/
void pci_release_selected_regions(struct pci_dev *pdev, int bars)
{
int i;
for (i = 0; i < 6; i++)
if (bars & (1 << i))
pci_release_region(pdev, i);
}
/**
* pci_request_selected_regions - Reserve selected PCI I/O and memory resources
* @pdev: PCI device whose resources are to be reserved
* @bars: Bitmask of BARs to be requested
* @res_name: Name to be associated with resource
*/
int pci_request_selected_regions(struct pci_dev *pdev, int bars,
const char *res_name)
{
int i;
for (i = 0; i < 6; i++)
if (bars & (1 << i))
if(pci_request_region(pdev, i, res_name))
goto err_out;
return 0;
err_out:
while(--i >= 0)
if (bars & (1 << i))
pci_release_region(pdev, i);
return -EBUSY;
}
/** /**
* pci_release_regions - Release reserved PCI I/O and memory resources * pci_release_regions - Release reserved PCI I/O and memory resources
...@@ -933,10 +973,7 @@ int pci_request_region(struct pci_dev *pdev, int bar, const char *res_name) ...@@ -933,10 +973,7 @@ int pci_request_region(struct pci_dev *pdev, int bar, const char *res_name)
void pci_release_regions(struct pci_dev *pdev) void pci_release_regions(struct pci_dev *pdev)
{ {
int i; pci_release_selected_regions(pdev, (1 << 6) - 1);
for (i = 0; i < 6; i++)
pci_release_region(pdev, i);
} }
/** /**
...@@ -954,18 +991,7 @@ void pci_release_regions(struct pci_dev *pdev) ...@@ -954,18 +991,7 @@ void pci_release_regions(struct pci_dev *pdev)
*/ */
int pci_request_regions(struct pci_dev *pdev, const char *res_name) int pci_request_regions(struct pci_dev *pdev, const char *res_name)
{ {
int i; return pci_request_selected_regions(pdev, ((1 << 6) - 1), res_name);
for (i = 0; i < 6; i++)
if(pci_request_region(pdev, i, res_name))
goto err_out;
return 0;
err_out:
while(--i >= 0)
pci_release_region(pdev, i);
return -EBUSY;
} }
/** /**
...@@ -1148,7 +1174,23 @@ pci_set_consistent_dma_mask(struct pci_dev *dev, u64 mask) ...@@ -1148,7 +1174,23 @@ pci_set_consistent_dma_mask(struct pci_dev *dev, u64 mask)
return 0; return 0;
} }
#endif #endif
/**
* pci_select_bars - Make BAR mask from the type of resource
* @pdev: the PCI device for which BAR mask is made
* @flags: resource type mask to be selected
*
* This helper routine makes bar mask from the type of resource.
*/
int pci_select_bars(struct pci_dev *dev, unsigned long flags)
{
int i, bars = 0;
for (i = 0; i < PCI_NUM_RESOURCES; i++)
if (pci_resource_flags(dev, i) & flags)
bars |= (1 << i);
return bars;
}
static int __devinit pci_init(void) static int __devinit pci_init(void)
{ {
struct pci_dev *dev = NULL; struct pci_dev *dev = NULL;
...@@ -1181,12 +1223,6 @@ early_param("pci", pci_setup); ...@@ -1181,12 +1223,6 @@ early_param("pci", pci_setup);
device_initcall(pci_init); device_initcall(pci_init);
#if defined(CONFIG_ISA) || defined(CONFIG_EISA)
/* FIXME: Some boxes have multiple ISA bridges! */
struct pci_dev *isa_bridge;
EXPORT_SYMBOL(isa_bridge);
#endif
EXPORT_SYMBOL_GPL(pci_restore_bars); EXPORT_SYMBOL_GPL(pci_restore_bars);
EXPORT_SYMBOL(pci_enable_device_bars); EXPORT_SYMBOL(pci_enable_device_bars);
EXPORT_SYMBOL(pci_enable_device); EXPORT_SYMBOL(pci_enable_device);
...@@ -1197,6 +1233,8 @@ EXPORT_SYMBOL(pci_release_regions); ...@@ -1197,6 +1233,8 @@ 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);
EXPORT_SYMBOL(pci_request_region); EXPORT_SYMBOL(pci_request_region);
EXPORT_SYMBOL(pci_release_selected_regions);
EXPORT_SYMBOL(pci_request_selected_regions);
EXPORT_SYMBOL(pci_set_master); EXPORT_SYMBOL(pci_set_master);
EXPORT_SYMBOL(pci_set_mwi); EXPORT_SYMBOL(pci_set_mwi);
EXPORT_SYMBOL(pci_clear_mwi); EXPORT_SYMBOL(pci_clear_mwi);
...@@ -1205,13 +1243,10 @@ EXPORT_SYMBOL(pci_set_dma_mask); ...@@ -1205,13 +1243,10 @@ EXPORT_SYMBOL(pci_set_dma_mask);
EXPORT_SYMBOL(pci_set_consistent_dma_mask); EXPORT_SYMBOL(pci_set_consistent_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(pci_select_bars);
EXPORT_SYMBOL(pci_set_power_state); EXPORT_SYMBOL(pci_set_power_state);
EXPORT_SYMBOL(pci_save_state); EXPORT_SYMBOL(pci_save_state);
EXPORT_SYMBOL(pci_restore_state); EXPORT_SYMBOL(pci_restore_state);
EXPORT_SYMBOL(pci_enable_wake); EXPORT_SYMBOL(pci_enable_wake);
/* Quirk info */
EXPORT_SYMBOL(isa_dma_bridge_buggy);
EXPORT_SYMBOL(pci_pci_problems);
/* Functions internal to the PCI core code */ /* Functions internal to the PCI core code */
extern int __must_check __pci_enable_device(struct pci_dev *); extern int __must_check __pci_reenable_device(struct pci_dev *);
extern int pci_uevent(struct device *dev, char **envp, int num_envp, extern int pci_uevent(struct device *dev, char **envp, int num_envp,
char *buffer, int buffer_size); char *buffer, int buffer_size);
extern int pci_create_sysfs_dev_files(struct pci_dev *pdev); extern int pci_create_sysfs_dev_files(struct pci_dev *pdev);
...@@ -43,12 +43,8 @@ extern void pci_remove_legacy_files(struct pci_bus *bus); ...@@ -43,12 +43,8 @@ extern void pci_remove_legacy_files(struct pci_bus *bus);
/* Lock for read/write access to pci device and bus lists */ /* Lock for read/write access to pci device and bus lists */
extern struct rw_semaphore pci_bus_sem; extern struct rw_semaphore pci_bus_sem;
#ifdef CONFIG_PCI_MSI
extern int pci_msi_quirk;
#else
#define pci_msi_quirk 0
#endif
extern unsigned int pci_pm_d3_delay; extern unsigned int pci_pm_d3_delay;
#ifdef CONFIG_PCI_MSI #ifdef CONFIG_PCI_MSI
void disable_msi_mode(struct pci_dev *dev, int pos, int type); void disable_msi_mode(struct pci_dev *dev, int pos, int type);
void pci_no_msi(void); void pci_no_msi(void);
...@@ -56,17 +52,15 @@ void pci_no_msi(void); ...@@ -56,17 +52,15 @@ void pci_no_msi(void);
static inline void disable_msi_mode(struct pci_dev *dev, int pos, int type) { } static inline void disable_msi_mode(struct pci_dev *dev, int pos, int type) { }
static inline void pci_no_msi(void) { } static inline void pci_no_msi(void) { }
#endif #endif
#if defined(CONFIG_PCI_MSI) && defined(CONFIG_PM) #if defined(CONFIG_PCI_MSI) && defined(CONFIG_PM)
int pci_save_msi_state(struct pci_dev *dev); int pci_save_msi_state(struct pci_dev *dev);
int pci_save_msix_state(struct pci_dev *dev);
void pci_restore_msi_state(struct pci_dev *dev); void pci_restore_msi_state(struct pci_dev *dev);
void pci_restore_msix_state(struct pci_dev *dev);
#else #else
static inline int pci_save_msi_state(struct pci_dev *dev) { return 0; } static inline int pci_save_msi_state(struct pci_dev *dev) { return 0; }
static inline int pci_save_msix_state(struct pci_dev *dev) { return 0; }
static inline void pci_restore_msi_state(struct pci_dev *dev) {} static inline void pci_restore_msi_state(struct pci_dev *dev) {}
static inline void pci_restore_msix_state(struct pci_dev *dev) {}
#endif #endif
static inline int pci_no_d1d2(struct pci_dev *dev) static inline int pci_no_d1d2(struct pci_dev *dev)
{ {
unsigned int parent_dstates = 0; unsigned int parent_dstates = 0;
......
...@@ -144,6 +144,32 @@ static u32 pci_size(u32 base, u32 maxbase, u32 mask) ...@@ -144,6 +144,32 @@ static u32 pci_size(u32 base, u32 maxbase, u32 mask)
return size; return size;
} }
static u64 pci_size64(u64 base, u64 maxbase, u64 mask)
{
u64 size = mask & maxbase; /* Find the significant bits */
if (!size)
return 0;
/* Get the lowest of them to find the decode size, and
from that the extent. */
size = (size & ~(size-1)) - 1;
/* base == maxbase can be valid only if the BAR has
already been programmed with all 1s. */
if (base == maxbase && ((base | size) & mask) != mask)
return 0;
return size;
}
static inline int is_64bit_memory(u32 mask)
{
if ((mask & (PCI_BASE_ADDRESS_SPACE|PCI_BASE_ADDRESS_MEM_TYPE_MASK)) ==
(PCI_BASE_ADDRESS_SPACE_MEMORY|PCI_BASE_ADDRESS_MEM_TYPE_64))
return 1;
return 0;
}
static void pci_read_bases(struct pci_dev *dev, unsigned int howmany, int rom) static void pci_read_bases(struct pci_dev *dev, unsigned int howmany, int rom)
{ {
unsigned int pos, reg, next; unsigned int pos, reg, next;
...@@ -151,6 +177,10 @@ static void pci_read_bases(struct pci_dev *dev, unsigned int howmany, int rom) ...@@ -151,6 +177,10 @@ static void pci_read_bases(struct pci_dev *dev, unsigned int howmany, int rom)
struct resource *res; struct resource *res;
for(pos=0; pos<howmany; pos = next) { for(pos=0; pos<howmany; pos = next) {
u64 l64;
u64 sz64;
u32 raw_sz;
next = pos+1; next = pos+1;
res = &dev->resource[pos]; res = &dev->resource[pos];
res->name = pci_name(dev); res->name = pci_name(dev);
...@@ -163,9 +193,16 @@ static void pci_read_bases(struct pci_dev *dev, unsigned int howmany, int rom) ...@@ -163,9 +193,16 @@ static void pci_read_bases(struct pci_dev *dev, unsigned int howmany, int rom)
continue; continue;
if (l == 0xffffffff) if (l == 0xffffffff)
l = 0; l = 0;
if ((l & PCI_BASE_ADDRESS_SPACE) == PCI_BASE_ADDRESS_SPACE_MEMORY) { raw_sz = sz;
if ((l & PCI_BASE_ADDRESS_SPACE) ==
PCI_BASE_ADDRESS_SPACE_MEMORY) {
sz = pci_size(l, sz, (u32)PCI_BASE_ADDRESS_MEM_MASK); sz = pci_size(l, sz, (u32)PCI_BASE_ADDRESS_MEM_MASK);
if (!sz) /*
* For 64bit prefetchable memory sz could be 0, if the
* real size is bigger than 4G, so we need to check
* szhi for that.
*/
if (!is_64bit_memory(l) && !sz)
continue; continue;
res->start = l & PCI_BASE_ADDRESS_MEM_MASK; res->start = l & PCI_BASE_ADDRESS_MEM_MASK;
res->flags |= l & ~PCI_BASE_ADDRESS_MEM_MASK; res->flags |= l & ~PCI_BASE_ADDRESS_MEM_MASK;
...@@ -178,30 +215,36 @@ static void pci_read_bases(struct pci_dev *dev, unsigned int howmany, int rom) ...@@ -178,30 +215,36 @@ static void pci_read_bases(struct pci_dev *dev, unsigned int howmany, int rom)
} }
res->end = res->start + (unsigned long) sz; res->end = res->start + (unsigned long) sz;
res->flags |= pci_calc_resource_flags(l); res->flags |= pci_calc_resource_flags(l);
if ((l & (PCI_BASE_ADDRESS_SPACE | PCI_BASE_ADDRESS_MEM_TYPE_MASK)) if (is_64bit_memory(l)) {
== (PCI_BASE_ADDRESS_SPACE_MEMORY | PCI_BASE_ADDRESS_MEM_TYPE_64)) {
u32 szhi, lhi; u32 szhi, lhi;
pci_read_config_dword(dev, reg+4, &lhi); pci_read_config_dword(dev, reg+4, &lhi);
pci_write_config_dword(dev, reg+4, ~0); pci_write_config_dword(dev, reg+4, ~0);
pci_read_config_dword(dev, reg+4, &szhi); pci_read_config_dword(dev, reg+4, &szhi);
pci_write_config_dword(dev, reg+4, lhi); pci_write_config_dword(dev, reg+4, lhi);
szhi = pci_size(lhi, szhi, 0xffffffff); sz64 = ((u64)szhi << 32) | raw_sz;
l64 = ((u64)lhi << 32) | l;
sz64 = pci_size64(l64, sz64, PCI_BASE_ADDRESS_MEM_MASK);
next++; next++;
#if BITS_PER_LONG == 64 #if BITS_PER_LONG == 64
res->start |= ((unsigned long) lhi) << 32; if (!sz64) {
res->end = res->start + sz; res->start = 0;
if (szhi) { res->end = 0;
/* This BAR needs > 4GB? Wow. */ res->flags = 0;
res->end |= (unsigned long)szhi<<32; continue;
} }
res->start = l64 & PCI_BASE_ADDRESS_MEM_MASK;
res->end = res->start + sz64;
#else #else
if (szhi) { if (sz64 > 0x100000000ULL) {
printk(KERN_ERR "PCI: Unable to handle 64-bit BAR for device %s\n", pci_name(dev)); printk(KERN_ERR "PCI: Unable to handle 64-bit "
"BAR for device %s\n", pci_name(dev));
res->start = 0; res->start = 0;
res->flags = 0; res->flags = 0;
} else if (lhi) { } else if (lhi) {
/* 64-bit wide address, treat as disabled */ /* 64-bit wide address, treat as disabled */
pci_write_config_dword(dev, reg, l & ~(u32)PCI_BASE_ADDRESS_MEM_MASK); pci_write_config_dword(dev, reg,
l & ~(u32)PCI_BASE_ADDRESS_MEM_MASK);
pci_write_config_dword(dev, reg+4, 0); pci_write_config_dword(dev, reg+4, 0);
res->start = 0; res->start = 0;
res->end = sz; res->end = sz;
...@@ -902,7 +945,6 @@ pci_scan_single_device(struct pci_bus *bus, int devfn) ...@@ -902,7 +945,6 @@ pci_scan_single_device(struct pci_bus *bus, int devfn)
return NULL; return NULL;
pci_device_add(dev, bus); pci_device_add(dev, bus);
pci_scan_msi_device(dev);
return dev; return dev;
} }
......
This diff is collapsed.
...@@ -357,43 +357,6 @@ pci_get_device_reverse(unsigned int vendor, unsigned int device, struct pci_dev ...@@ -357,43 +357,6 @@ pci_get_device_reverse(unsigned int vendor, unsigned int device, struct pci_dev
return dev; return dev;
} }
/**
* pci_find_device_reverse - begin or continue searching for a PCI device by vendor/device id
* @vendor: PCI vendor id to match, or %PCI_ANY_ID to match all vendor ids
* @device: PCI device id to match, or %PCI_ANY_ID to match all device ids
* @from: Previous PCI device found in search, or %NULL for new search.
*
* Iterates through the list of known PCI devices in the reverse order of
* pci_find_device().
* If a PCI device is found with a matching @vendor and @device, a pointer to
* its device structure is returned. Otherwise, %NULL is returned.
* A new search is initiated by passing %NULL as the @from argument.
* Otherwise if @from is not %NULL, searches continue from previous device
* on the global list.
*/
struct pci_dev *
pci_find_device_reverse(unsigned int vendor, unsigned int device, const struct pci_dev *from)
{
struct list_head *n;
struct pci_dev *dev;
WARN_ON(in_interrupt());
down_read(&pci_bus_sem);
n = from ? from->global_list.prev : pci_devices.prev;
while (n && (n != &pci_devices)) {
dev = pci_dev_g(n);
if ((vendor == PCI_ANY_ID || dev->vendor == vendor) &&
(device == PCI_ANY_ID || dev->device == device))
goto exit;
n = n->prev;
}
dev = NULL;
exit:
up_read(&pci_bus_sem);
return dev;
}
/** /**
* pci_get_class - begin or continue searching for a PCI device by class * pci_get_class - begin or continue searching for a PCI device by class
* @class: search for a PCI device with this class designation * @class: search for a PCI device with this class designation
...@@ -469,7 +432,6 @@ EXPORT_SYMBOL(pci_dev_present); ...@@ -469,7 +432,6 @@ EXPORT_SYMBOL(pci_dev_present);
EXPORT_SYMBOL(pci_find_present); EXPORT_SYMBOL(pci_find_present);
EXPORT_SYMBOL(pci_find_device); EXPORT_SYMBOL(pci_find_device);
EXPORT_SYMBOL(pci_find_device_reverse);
EXPORT_SYMBOL(pci_find_slot); EXPORT_SYMBOL(pci_find_slot);
/* For boot time work */ /* For boot time work */
EXPORT_SYMBOL(pci_find_bus); EXPORT_SYMBOL(pci_find_bus);
......
...@@ -7558,9 +7558,6 @@ static struct pci_device_id ipr_pci_table[] __devinitdata = { ...@@ -7558,9 +7558,6 @@ static struct pci_device_id ipr_pci_table[] __devinitdata = {
{ PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_OBSIDIAN, { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_OBSIDIAN,
PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_575C, PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_575C,
0, 0, (kernel_ulong_t)&ipr_chip_cfg[0] }, 0, 0, (kernel_ulong_t)&ipr_chip_cfg[0] },
{ PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_OBSIDIAN,
PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_57B8,
0, 0, (kernel_ulong_t)&ipr_chip_cfg[0] },
{ PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_OBSIDIAN_E, { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_OBSIDIAN_E,
PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_57B7, PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_57B7,
0, 0, (kernel_ulong_t)&ipr_chip_cfg[0] }, 0, 0, (kernel_ulong_t)&ipr_chip_cfg[0] },
......
...@@ -293,4 +293,6 @@ struct pci_dev *alpha_gendev_to_pci(struct device *dev); ...@@ -293,4 +293,6 @@ struct pci_dev *alpha_gendev_to_pci(struct device *dev);
#define IOBASE_ROOT_BUS 5 #define IOBASE_ROOT_BUS 5
#define IOBASE_FROM_HOSE 0x10000 #define IOBASE_FROM_HOSE 0x10000
extern struct pci_dev *isa_bridge;
#endif /* __ALPHA_PCI_H */ #endif /* __ALPHA_PCI_H */
...@@ -21,6 +21,7 @@ struct mm_struct; ...@@ -21,6 +21,7 @@ struct mm_struct;
struct pci_bus; struct pci_bus;
struct task_struct; struct task_struct;
struct pci_dev; struct pci_dev;
struct msi_desc;
typedef void ia64_mv_setup_t (char **); typedef void ia64_mv_setup_t (char **);
typedef void ia64_mv_cpu_init_t (void); typedef void ia64_mv_cpu_init_t (void);
...@@ -79,7 +80,7 @@ typedef unsigned short ia64_mv_readw_relaxed_t (const volatile void __iomem *); ...@@ -79,7 +80,7 @@ typedef unsigned short ia64_mv_readw_relaxed_t (const volatile void __iomem *);
typedef unsigned int ia64_mv_readl_relaxed_t (const volatile void __iomem *); typedef unsigned int ia64_mv_readl_relaxed_t (const volatile void __iomem *);
typedef unsigned long ia64_mv_readq_relaxed_t (const volatile void __iomem *); typedef unsigned long ia64_mv_readq_relaxed_t (const volatile void __iomem *);
typedef int ia64_mv_setup_msi_irq_t (unsigned int irq, struct pci_dev *pdev); typedef int ia64_mv_setup_msi_irq_t (struct pci_dev *pdev, struct msi_desc *);
typedef void ia64_mv_teardown_msi_irq_t (unsigned int irq); typedef void ia64_mv_teardown_msi_irq_t (unsigned int irq);
static inline void static inline void
......
...@@ -68,6 +68,7 @@ typedef void fastcall (*irq_flow_handler_t)(unsigned int irq, ...@@ -68,6 +68,7 @@ typedef void fastcall (*irq_flow_handler_t)(unsigned int irq,
#define IRQ_MOVE_PENDING 0x40000000 /* need to re-target IRQ destination */ #define IRQ_MOVE_PENDING 0x40000000 /* need to re-target IRQ destination */
struct proc_dir_entry; struct proc_dir_entry;
struct msi_desc;
/** /**
* struct irq_chip - hardware interrupt chip descriptor * struct irq_chip - hardware interrupt chip descriptor
...@@ -148,6 +149,7 @@ struct irq_chip { ...@@ -148,6 +149,7 @@ struct irq_chip {
struct irq_desc { struct irq_desc {
irq_flow_handler_t handle_irq; irq_flow_handler_t handle_irq;
struct irq_chip *chip; struct irq_chip *chip;
struct msi_desc *msi_desc;
void *handler_data; void *handler_data;
void *chip_data; void *chip_data;
struct irqaction *action; /* IRQ action list */ struct irqaction *action; /* IRQ action list */
...@@ -373,10 +375,12 @@ extern int set_irq_chip(unsigned int irq, struct irq_chip *chip); ...@@ -373,10 +375,12 @@ extern int set_irq_chip(unsigned int irq, struct irq_chip *chip);
extern int set_irq_data(unsigned int irq, void *data); extern int set_irq_data(unsigned int irq, void *data);
extern int set_irq_chip_data(unsigned int irq, void *data); extern int set_irq_chip_data(unsigned int irq, void *data);
extern int set_irq_type(unsigned int irq, unsigned int type); extern int set_irq_type(unsigned int irq, unsigned int type);
extern int set_irq_msi(unsigned int irq, struct msi_desc *entry);
#define get_irq_chip(irq) (irq_desc[irq].chip) #define get_irq_chip(irq) (irq_desc[irq].chip)
#define get_irq_chip_data(irq) (irq_desc[irq].chip_data) #define get_irq_chip_data(irq) (irq_desc[irq].chip_data)
#define get_irq_data(irq) (irq_desc[irq].handler_data) #define get_irq_data(irq) (irq_desc[irq].handler_data)
#define get_irq_msi(irq) (irq_desc[irq].msi_desc)
#endif /* CONFIG_GENERIC_HARDIRQS */ #endif /* CONFIG_GENERIC_HARDIRQS */
......
...@@ -7,11 +7,10 @@ struct msi_msg { ...@@ -7,11 +7,10 @@ struct msi_msg {
u32 data; /* 16 bits of msi message data */ u32 data; /* 16 bits of msi message data */
}; };
/* Heper functions */ /* Helper functions */
extern void mask_msi_irq(unsigned int irq); extern void mask_msi_irq(unsigned int irq);
extern void unmask_msi_irq(unsigned int irq); extern void unmask_msi_irq(unsigned int irq);
extern void read_msi_msg(unsigned int irq, struct msi_msg *msg); extern void read_msi_msg(unsigned int irq, struct msi_msg *msg);
extern void write_msi_msg(unsigned int irq, struct msi_msg *msg); extern void write_msi_msg(unsigned int irq, struct msi_msg *msg);
struct msi_desc { struct msi_desc {
...@@ -42,7 +41,7 @@ struct msi_desc { ...@@ -42,7 +41,7 @@ struct msi_desc {
/* /*
* The arch hook for setup up msi irqs * The arch hook for setup up msi irqs
*/ */
int arch_setup_msi_irq(unsigned int irq, struct pci_dev *dev); int arch_setup_msi_irq(struct pci_dev *dev, struct msi_desc *desc);
void arch_teardown_msi_irq(unsigned int irq); void arch_teardown_msi_irq(unsigned int irq);
......
...@@ -174,6 +174,9 @@ struct pci_dev { ...@@ -174,6 +174,9 @@ struct pci_dev {
struct bin_attribute *rom_attr; /* attribute descriptor for sysfs ROM entry */ struct bin_attribute *rom_attr; /* attribute descriptor for sysfs ROM entry */
int rom_attr_enabled; /* has display of the rom attribute been enabled? */ int rom_attr_enabled; /* has display of the rom attribute been enabled? */
struct bin_attribute *res_attr[DEVICE_COUNT_RESOURCE]; /* sysfs file for resources */ struct bin_attribute *res_attr[DEVICE_COUNT_RESOURCE]; /* sysfs file for resources */
#ifdef CONFIG_PCI_MSI
unsigned int first_msi_irq;
#endif
}; };
#define pci_dev_g(n) list_entry(n, struct pci_dev, global_list) #define pci_dev_g(n) list_entry(n, struct pci_dev, global_list)
...@@ -181,6 +184,11 @@ struct pci_dev { ...@@ -181,6 +184,11 @@ struct pci_dev {
#define to_pci_dev(n) container_of(n, struct pci_dev, dev) #define to_pci_dev(n) container_of(n, struct pci_dev, dev)
#define for_each_pci_dev(d) while ((d = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, d)) != NULL) #define for_each_pci_dev(d) while ((d = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, d)) != NULL)
static inline int pci_channel_offline(struct pci_dev *pdev)
{
return (pdev->error_state != pci_channel_io_normal);
}
static inline struct pci_cap_saved_state *pci_find_saved_cap( static inline struct pci_cap_saved_state *pci_find_saved_cap(
struct pci_dev *pci_dev,char cap) struct pci_dev *pci_dev,char cap)
{ {
...@@ -463,8 +471,7 @@ extern void pci_sort_breadthfirst(void); ...@@ -463,8 +471,7 @@ extern void pci_sort_breadthfirst(void);
/* Generic PCI functions exported to card drivers */ /* Generic PCI functions exported to card drivers */
struct pci_dev *pci_find_device (unsigned int vendor, unsigned int device, const struct pci_dev *from); struct pci_dev __deprecated *pci_find_device (unsigned int vendor, unsigned int device, const struct pci_dev *from);
struct pci_dev *pci_find_device_reverse (unsigned int vendor, unsigned int device, const struct pci_dev *from);
struct pci_dev *pci_find_slot (unsigned int bus, unsigned int devfn); struct pci_dev *pci_find_slot (unsigned int bus, unsigned int devfn);
int pci_find_capability (struct pci_dev *dev, int cap); int pci_find_capability (struct pci_dev *dev, int cap);
int pci_find_next_capability (struct pci_dev *dev, u8 pos, int cap); int pci_find_next_capability (struct pci_dev *dev, u8 pos, int cap);
...@@ -533,6 +540,7 @@ void pci_update_resource(struct pci_dev *dev, struct resource *res, int resno); ...@@ -533,6 +540,7 @@ void pci_update_resource(struct pci_dev *dev, struct resource *res, int resno);
int __must_check pci_assign_resource(struct pci_dev *dev, int i); int __must_check pci_assign_resource(struct pci_dev *dev, int i);
int __must_check pci_assign_resource_fixed(struct pci_dev *dev, int i); int __must_check pci_assign_resource_fixed(struct pci_dev *dev, int i);
void pci_restore_bars(struct pci_dev *dev); void pci_restore_bars(struct pci_dev *dev);
int pci_select_bars(struct pci_dev *dev, unsigned long flags);
/* ROM control related routines */ /* ROM control related routines */
void __iomem __must_check *pci_map_rom(struct pci_dev *pdev, size_t *size); void __iomem __must_check *pci_map_rom(struct pci_dev *pdev, size_t *size);
...@@ -561,6 +569,8 @@ int __must_check pci_request_regions(struct pci_dev *, const char *); ...@@ -561,6 +569,8 @@ int __must_check pci_request_regions(struct pci_dev *, const char *);
void pci_release_regions(struct pci_dev *); void pci_release_regions(struct pci_dev *);
int __must_check pci_request_region(struct pci_dev *, int, const char *); int __must_check pci_request_region(struct pci_dev *, int, const char *);
void pci_release_region(struct pci_dev *, int); void pci_release_region(struct pci_dev *, int);
int pci_request_selected_regions(struct pci_dev *, int, const char *);
void pci_release_selected_regions(struct pci_dev *, int);
/* drivers/pci/bus.c */ /* drivers/pci/bus.c */
int __must_check pci_bus_alloc_resource(struct pci_bus *bus, int __must_check pci_bus_alloc_resource(struct pci_bus *bus,
...@@ -612,10 +622,6 @@ enum pci_dma_burst_strategy { ...@@ -612,10 +622,6 @@ enum pci_dma_burst_strategy {
strategy_parameter byte boundaries */ strategy_parameter byte boundaries */
}; };
#if defined(CONFIG_ISA) || defined(CONFIG_EISA)
extern struct pci_dev *isa_bridge;
#endif
struct msix_entry { struct msix_entry {
u16 vector; /* kernel uses to write allocated vector */ u16 vector; /* kernel uses to write allocated vector */
u16 entry; /* driver uses to specify entry, OS writes */ u16 entry; /* driver uses to specify entry, OS writes */
...@@ -623,7 +629,6 @@ struct msix_entry { ...@@ -623,7 +629,6 @@ struct msix_entry {
#ifndef CONFIG_PCI_MSI #ifndef CONFIG_PCI_MSI
static inline void pci_scan_msi_device(struct pci_dev *dev) {}
static inline int pci_enable_msi(struct pci_dev *dev) {return -1;} static inline int pci_enable_msi(struct pci_dev *dev) {return -1;}
static inline void pci_disable_msi(struct pci_dev *dev) {} static inline void pci_disable_msi(struct pci_dev *dev) {}
static inline int pci_enable_msix(struct pci_dev* dev, static inline int pci_enable_msix(struct pci_dev* dev,
...@@ -631,7 +636,6 @@ static inline int pci_enable_msix(struct pci_dev* dev, ...@@ -631,7 +636,6 @@ static inline int pci_enable_msix(struct pci_dev* dev,
static inline void pci_disable_msix(struct pci_dev *dev) {} static inline void pci_disable_msix(struct pci_dev *dev) {}
static inline void msi_remove_pci_irq_vectors(struct pci_dev *dev) {} static inline void msi_remove_pci_irq_vectors(struct pci_dev *dev) {}
#else #else
extern void pci_scan_msi_device(struct pci_dev *dev);
extern int pci_enable_msi(struct pci_dev *dev); extern int pci_enable_msi(struct pci_dev *dev);
extern void pci_disable_msi(struct pci_dev *dev); extern void pci_disable_msi(struct pci_dev *dev);
extern int pci_enable_msix(struct pci_dev* dev, extern int pci_enable_msix(struct pci_dev* dev,
...@@ -723,8 +727,6 @@ static inline int pci_set_power_state(struct pci_dev *dev, pci_power_t state) { ...@@ -723,8 +727,6 @@ static inline int pci_set_power_state(struct pci_dev *dev, pci_power_t state) {
static inline pci_power_t pci_choose_state(struct pci_dev *dev, pm_message_t state) { return PCI_D0; } static inline pci_power_t pci_choose_state(struct pci_dev *dev, pm_message_t state) { return PCI_D0; }
static inline int pci_enable_wake(struct pci_dev *dev, pci_power_t state, int enable) { return 0; } static inline int pci_enable_wake(struct pci_dev *dev, pci_power_t state, int enable) { return 0; }
#define isa_bridge ((struct pci_dev *)NULL)
#define pci_dma_burst_advice(pdev, strat, strategy_parameter) do { } while (0) #define pci_dma_burst_advice(pdev, strat, strategy_parameter) do { } while (0)
static inline void pci_block_user_cfg_access(struct pci_dev *dev) { } static inline void pci_block_user_cfg_access(struct pci_dev *dev) { }
......
...@@ -39,6 +39,7 @@ void dynamic_irq_init(unsigned int irq) ...@@ -39,6 +39,7 @@ void dynamic_irq_init(unsigned int irq)
desc->chip = &no_irq_chip; desc->chip = &no_irq_chip;
desc->handle_irq = handle_bad_irq; desc->handle_irq = handle_bad_irq;
desc->depth = 1; desc->depth = 1;
desc->msi_desc = NULL;
desc->handler_data = NULL; desc->handler_data = NULL;
desc->chip_data = NULL; desc->chip_data = NULL;
desc->action = NULL; desc->action = NULL;
...@@ -74,6 +75,9 @@ void dynamic_irq_cleanup(unsigned int irq) ...@@ -74,6 +75,9 @@ void dynamic_irq_cleanup(unsigned int irq)
WARN_ON(1); WARN_ON(1);
return; return;
} }
desc->msi_desc = NULL;
desc->handler_data = NULL;
desc->chip_data = NULL;
desc->handle_irq = handle_bad_irq; desc->handle_irq = handle_bad_irq;
desc->chip = &no_irq_chip; desc->chip = &no_irq_chip;
spin_unlock_irqrestore(&desc->lock, flags); spin_unlock_irqrestore(&desc->lock, flags);
...@@ -161,6 +165,30 @@ int set_irq_data(unsigned int irq, void *data) ...@@ -161,6 +165,30 @@ int set_irq_data(unsigned int irq, void *data)
} }
EXPORT_SYMBOL(set_irq_data); EXPORT_SYMBOL(set_irq_data);
/**
* set_irq_data - set irq type data for an irq
* @irq: Interrupt number
* @data: Pointer to interrupt specific data
*
* Set the hardware irq controller data for an irq
*/
int set_irq_msi(unsigned int irq, struct msi_desc *entry)
{
struct irq_desc *desc;
unsigned long flags;
if (irq >= NR_IRQS) {
printk(KERN_ERR
"Trying to install msi data for IRQ%d\n", irq);
return -EINVAL;
}
desc = irq_desc + irq;
spin_lock_irqsave(&desc->lock, flags);
desc->msi_desc = entry;
spin_unlock_irqrestore(&desc->lock, flags);
return 0;
}
/** /**
* set_irq_chip_data - set irq chip data for an irq * set_irq_chip_data - set irq chip data for an irq
* @irq: Interrupt number * @irq: Interrupt number
......
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