Commit 855c0673 authored by Greg Kroah-Hartman's avatar Greg Kroah-Hartman

Merge bk://linux-mtd.bkbits.net/quirks-2.6

into kroah.com:/home/greg/linux/BK/pci-2.6
parents a685d7b5 e46c313b
......@@ -1105,7 +1105,7 @@ config PCI_DIRECT
config PCI_MMCONFIG
bool
depends on PCI && (PCI_GOMMCONFIG || PCI_GOANY)
depends on PCI && (PCI_GOMMCONFIG || (PCI_GOANY && ACPI_BOOT))
select ACPI_BOOT
default y
......
......@@ -70,7 +70,7 @@ static void __devinit pcibios_fixup_ghosts(struct pci_bus *b)
int i;
DBG("PCI: Scanning for ghost devices on bus %d\n", b->number);
for (ln=b->devices.next; ln != &b->devices; ln=ln->next) {
list_for_each(ln, &b->devices) {
d = pci_dev_b(ln);
if ((d->class >> 8) == PCI_CLASS_BRIDGE_HOST)
seen_host_bridge++;
......
......@@ -365,7 +365,7 @@ void __devinit pcibios_sort(void)
idx = found = 0;
while (pci_bios_find_device(dev->vendor, dev->device, idx, &bus, &devfn) == PCIBIOS_SUCCESSFUL) {
idx++;
for (ln=pci_devices.next; ln != &pci_devices; ln=ln->next) {
list_for_each(ln, &pci_devices) {
d = pci_dev_g(ln);
if (d->bus->number == bus && d->devfn == devfn) {
list_del(&d->global_list);
......
......@@ -88,6 +88,18 @@ config HOTPLUG_PCI_ACPI
When in doubt, say N.
config HOTPLUG_PCI_ACPI_IBM
tristate "ACPI PCI Hotplug driver IBM extensions"
depends on HOTPLUG_PCI_ACPI
help
Say Y here if you have an IBM system that supports PCI Hotplug using
ACPI.
To compile this driver as a module, choose M here: the
module will be called acpiphp_ibm.
When in doubt, say N.
config HOTPLUG_PCI_CPCI
bool "CompactPCI Hotplug driver"
depends on HOTPLUG_PCI
......
......@@ -7,6 +7,7 @@ obj-$(CONFIG_HOTPLUG_PCI_FAKE) += fakephp.o
obj-$(CONFIG_HOTPLUG_PCI_COMPAQ) += cpqphp.o
obj-$(CONFIG_HOTPLUG_PCI_IBM) += ibmphp.o
obj-$(CONFIG_HOTPLUG_PCI_ACPI) += acpiphp.o
obj-$(CONFIG_HOTPLUG_PCI_ACPI_IBM) += acpiphp_ibm.o
obj-$(CONFIG_HOTPLUG_PCI_CPCI_ZT5550) += cpcihp_zt5550.o
obj-$(CONFIG_HOTPLUG_PCI_CPCI_GENERIC) += cpcihp_generic.o
obj-$(CONFIG_HOTPLUG_PCI_PCIE) += pciehp.o
......
......@@ -171,6 +171,18 @@ struct acpiphp_func {
struct pci_resource *bus_head;
};
/**
* struct acpiphp_attention_info - device specific attention registration
*
* ACPI has no generic method of setting/getting attention status
* this allows for device specific driver registration
*/
struct acpiphp_attention_info
{
int (*set_attn)(struct hotplug_slot *slot, u8 status);
int (*get_attn)(struct hotplug_slot *slot, u8 *status);
struct module *owner;
};
/* PCI bus bridge HID */
#define ACPI_PCI_HOST_HID "PNP0A03"
......@@ -212,6 +224,10 @@ struct acpiphp_func {
/* function prototypes */
/* acpiphp_core.c */
extern int acpiphp_register_attention(struct acpiphp_attention_info*info);
extern int acpiphp_unregister_attention(struct acpiphp_attention_info *info);
/* acpiphp_glue.c */
extern int acpiphp_glue_init (void);
extern void acpiphp_glue_exit (void);
......
......@@ -51,6 +51,7 @@ int acpiphp_debug;
/* local variables */
static int num_slots;
static struct acpiphp_attention_info *attention_info;
#define DRIVER_VERSION "0.4"
#define DRIVER_AUTHOR "Greg Kroah-Hartman <gregkh@us.ibm.com>, Takayoshi Kochi <t-kochi@bq.jp.nec.com>"
......@@ -62,10 +63,15 @@ MODULE_LICENSE("GPL");
MODULE_PARM_DESC(debug, "Debugging mode enabled or not");
module_param(debug, bool, 644);
/* export the attention callback registration methods */
EXPORT_SYMBOL_GPL(acpiphp_register_attention);
EXPORT_SYMBOL_GPL(acpiphp_unregister_attention);
static int enable_slot (struct hotplug_slot *slot);
static int disable_slot (struct hotplug_slot *slot);
static int set_attention_status (struct hotplug_slot *slot, u8 value);
static int get_power_status (struct hotplug_slot *slot, u8 *value);
static int get_attention_status (struct hotplug_slot *slot, u8 *value);
static int get_address (struct hotplug_slot *slot, u32 *value);
static int get_latch_status (struct hotplug_slot *slot, u8 *value);
static int get_adapter_status (struct hotplug_slot *slot, u8 *value);
......@@ -76,11 +82,54 @@ static struct hotplug_slot_ops acpi_hotplug_slot_ops = {
.disable_slot = disable_slot,
.set_attention_status = set_attention_status,
.get_power_status = get_power_status,
.get_attention_status = get_attention_status,
.get_latch_status = get_latch_status,
.get_adapter_status = get_adapter_status,
.get_address = get_address,
};
/**
* acpiphp_register_attention - set attention LED callback
* @info: must be completely filled with LED callbacks
*
* Description: this is used to register a hardware specific ACPI
* driver that manipulates the attention LED. All the fields in
* info must be set.
**/
int acpiphp_register_attention(struct acpiphp_attention_info *info)
{
int retval = -EINVAL;
if (info && info->owner && info->set_attn &&
info->get_attn && !attention_info) {
retval = 0;
attention_info = info;
}
return retval;
}
/**
* acpiphp_unregister_attention - unset attention LED callback
* @info: must match the pointer used to register
*
* Description: this is used to un-register a hardware specific acpi
* driver that manipulates the attention LED. The pointer to the
* info struct must be the same as the one used to set it.
**/
int acpiphp_unregister_attention(struct acpiphp_attention_info *info)
{
int retval = -EINVAL;
if (info && attention_info == info) {
attention_info = NULL;
retval = 0;
}
return retval;
}
/**
* enable_slot - power on and enable a slot
* @hotplug_slot: slot to enable
......@@ -117,33 +166,29 @@ static int disable_slot(struct hotplug_slot *hotplug_slot)
}
/**
* set_attention_status - set attention LED
/**
* set_attention_status - set attention LED
* @hotplug_slot: slot to set attention LED on
* @status: value to set attention LED to (0 or 1)
*
* TBD:
* ACPI doesn't have known method to manipulate
* attention status LED.
*
*/
static int set_attention_status(struct hotplug_slot *hotplug_slot, u8 status)
{
dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
switch (status) {
case 0:
/* FIXME turn light off */
hotplug_slot->info->attention_status = 0;
break;
case 1:
default:
/* FIXME turn light on */
hotplug_slot->info->attention_status = 1;
break;
}
return 0;
}
* attention status LED, so we use a callback that
* was registered with us. This allows hardware specific
* ACPI implementations to blink the light for us.
**/
static int set_attention_status(struct hotplug_slot *hotplug_slot, u8 status)
{
int retval = -ENODEV;
dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
if (attention_info && try_module_get(attention_info->owner)) {
retval = attention_info->set_attn(hotplug_slot, status);
module_put(attention_info->owner);
} else
attention_info = NULL;
return retval;
}
/**
* get_power_status - get power status of a slot
......@@ -165,6 +210,32 @@ static int get_power_status(struct hotplug_slot *hotplug_slot, u8 *value)
return 0;
}
/**
* get_attention_status - get attention LED status
* @hotplug_slot: slot to get status from
* @value: returns with value of attention LED
*
* ACPI doesn't have known method to determine the state
* of the attention status LED, so we use a callback that
* was registered with us. This allows hardware specific
* ACPI implementations to determine its state
**/
static int get_attention_status(struct hotplug_slot *hotplug_slot, u8 *value)
{
int retval = -EINVAL;
dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
if (attention_info && try_module_get(attention_info->owner)) {
retval = attention_info->get_attn(hotplug_slot, value);
module_put(attention_info->owner);
} else
attention_info = NULL;
return retval;
}
/**
* get_latch_status - get latch status of a slot
* @hotplug_slot: slot to get status
......@@ -307,7 +378,7 @@ static int __init init_slots(void)
slot->acpi_slot = get_slot_from_id(i);
slot->hotplug_slot->info->power_status = acpiphp_get_power_status(slot->acpi_slot);
slot->hotplug_slot->info->attention_status = acpiphp_get_attention_status(slot->acpi_slot);
slot->hotplug_slot->info->attention_status = 0;
slot->hotplug_slot->info->latch_status = acpiphp_get_latch_status(slot->acpi_slot);
slot->hotplug_slot->info->adapter_status = acpiphp_get_adapter_status(slot->acpi_slot);
slot->hotplug_slot->info->max_bus_speed = PCI_SPEED_UNKNOWN;
......
......@@ -1301,20 +1301,6 @@ u8 acpiphp_get_power_status(struct acpiphp_slot *slot)
}
/*
* attention LED ON: 1
* OFF: 0
*
* TBD
* no direct attention led status information via ACPI
*
*/
u8 acpiphp_get_attention_status(struct acpiphp_slot *slot)
{
return 0;
}
/*
* latch closed: 1
* latch open: 0
......
This diff is collapsed.
......@@ -33,6 +33,7 @@
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/smp_lock.h>
#include <linux/delay.h>
#include "pci_hotplug.h"
#include "cpci_hotplug.h"
......@@ -513,11 +514,10 @@ event_thread(void *data)
break;
while(controller->ops->query_enum()) {
rc = check_slots();
if(rc > 0) {
if (rc > 0)
/* Give userspace a chance to handle extraction */
set_current_state(TASK_INTERRUPTIBLE);
schedule_timeout(HZ / 2);
} else if(rc < 0) {
msleep(500);
else if (rc < 0) {
dbg("%s - error checking slots", __FUNCTION__);
thread_finished = 1;
break;
......@@ -568,11 +568,10 @@ poll_thread(void *data)
while(controller->ops->query_enum()) {
rc = check_slots();
if(rc > 0) {
if(rc > 0)
/* Give userspace a chance to handle extraction */
set_current_state(TASK_INTERRUPTIBLE);
schedule_timeout(HZ / 2);
} else if(rc < 0) {
msleep(500);
else if (rc < 0) {
dbg("%s - error checking slots", __FUNCTION__);
thread_finished = 1;
break;
......@@ -595,8 +594,7 @@ poll_thread(void *data)
}
}
set_current_state(TASK_INTERRUPTIBLE);
schedule_timeout(HZ / 10);
msleep(100);
}
dbg("poll thread signals exit");
up(&thread_exit);
......
......@@ -759,11 +759,5 @@ extern int ibmphp_configure_card (struct pci_func *, u8);
extern int ibmphp_unconfigure_card (struct slot **, int);
extern struct hotplug_slot_ops ibmphp_hotplug_slot_ops;
static inline void long_delay (int delay)
{
set_current_state (TASK_INTERRUPTIBLE);
schedule_timeout (delay);
}
#endif //__IBMPHP_H
......@@ -190,7 +190,7 @@ static inline int power_on (struct slot *slot_cur)
err ("command not completed successfully in power_on\n");
return -EIO;
}
long_delay (3 * HZ); /* For ServeRAID cards, and some 66 PCI */
msleep(3000); /* For ServeRAID cards, and some 66 PCI */
return 0;
}
......@@ -913,7 +913,7 @@ static int set_bus (struct slot * slot_cur)
}
/* This is for x440, once Brandon fixes the firmware,
will not need this delay */
long_delay (1 * HZ);
msleep(1000);
debug ("%s -Exit\n", __FUNCTION__);
return 0;
}
......
......@@ -29,6 +29,7 @@
#include <linux/wait.h>
#include <linux/time.h>
#include <linux/delay.h>
#include <linux/module.h>
#include <linux/pci.h>
#include <linux/smp_lock.h>
......@@ -205,7 +206,7 @@ static u8 i2c_ctrl_read (struct controller *ctlr_ptr, void *WPGBbar, u8 index)
// READ - step 4 : wait until start operation bit clears
i = CMD_COMPLETE_TOUT_SEC;
while (i) {
long_delay (1 * HZ / 100);
msleep(10);
wpg_addr = WPGBbar + WPG_I2CMCNTL_OFFSET;
wpg_data = readl (wpg_addr);
data = swab32 (wpg_data);
......@@ -221,7 +222,7 @@ static u8 i2c_ctrl_read (struct controller *ctlr_ptr, void *WPGBbar, u8 index)
// READ - step 5 : read I2C status register
i = CMD_COMPLETE_TOUT_SEC;
while (i) {
long_delay (1 * HZ / 100);
msleep(10);
wpg_addr = WPGBbar + WPG_I2CSTAT_OFFSET;
wpg_data = readl (wpg_addr);
data = swab32 (wpg_data);
......@@ -316,7 +317,7 @@ static u8 i2c_ctrl_write (struct controller *ctlr_ptr, void *WPGBbar, u8 index,
// WRITE - step 4 : wait until start operation bit clears
i = CMD_COMPLETE_TOUT_SEC;
while (i) {
long_delay (1 * HZ / 100);
msleep(10);
wpg_addr = WPGBbar + WPG_I2CMCNTL_OFFSET;
wpg_data = readl (wpg_addr);
data = swab32 (wpg_data);
......@@ -333,7 +334,7 @@ static u8 i2c_ctrl_write (struct controller *ctlr_ptr, void *WPGBbar, u8 index,
// WRITE - step 5 : read I2C status register
i = CMD_COMPLETE_TOUT_SEC;
while (i) {
long_delay (1 * HZ / 100);
msleep(10);
wpg_addr = WPGBbar + WPG_I2CSTAT_OFFSET;
wpg_data = readl (wpg_addr);
data = swab32 (wpg_data);
......@@ -748,7 +749,7 @@ int ibmphp_hpc_writeslot (struct slot * pslot, u8 cmd)
done = TRUE;
}
if (!done) {
long_delay (1 * HZ);
msleep(1000);
if (timeout < 1) {
done = TRUE;
err ("%s - Error command complete timeout\n", __FUNCTION__);
......@@ -891,7 +892,7 @@ static void poll_hpc (void)
case POLL_SLEEP:
/* don't sleep with a lock on the hardware */
up (&semOperations);
long_delay (POLL_INTERVAL_SEC * HZ);
msleep(POLL_INTERVAL_SEC * 1000);
if (ibmphp_shutdown)
break;
......@@ -908,8 +909,7 @@ static void poll_hpc (void)
/* give up the harware semaphore */
up (&semOperations);
/* sleep for a short time just for good measure */
set_current_state (TASK_INTERRUPTIBLE);
schedule_timeout (HZ/10);
msleep(100);
}
up (&sem_exit);
debug ("%s - Exit\n", __FUNCTION__);
......@@ -974,7 +974,7 @@ static int process_changeinstatus (struct slot *pslot, struct slot *poldslot)
if (SLOT_PWRGD (pslot->status)) {
// power goes on and off after closing latch
// check again to make sure power is still ON
long_delay (1 * HZ);
msleep(1000);
rc = ibmphp_hpc_readslot (pslot, READ_SLOTSTATUS, &status);
if (SLOT_PWRGD (status))
update = TRUE;
......@@ -1147,7 +1147,7 @@ static int hpc_wait_ctlr_notworking (int timeout, struct controller *ctlr_ptr, v
if (CTLR_WORKING (*pstatus) == HPC_CTLR_WORKING_NO)
done = TRUE;
if (!done) {
long_delay (1 * HZ);
msleep(1000);
if (timeout < 1) {
done = TRUE;
err ("HPCreadslot - Error ctlr timeout\n");
......
......@@ -341,7 +341,6 @@ static int rpaphp_config_pci_adapter(struct slot *slot)
return rc;
}
static void rpaphp_eeh_remove_bus_device(struct pci_dev *dev)
{
eeh_remove_device(dev);
......@@ -430,10 +429,26 @@ static int setup_pci_slot(struct slot *slot)
__FUNCTION__, slot->name);
goto exit_rc;
}
if (init_slot_pci_funcs(slot)) {
err("%s: init_slot_pci_funcs failed\n", __FUNCTION__);
if (slot->hotplug_slot->info->adapter_status == NOT_CONFIGURED) {
dbg("%s CONFIGURING pci adapter in slot[%s]\n",
__FUNCTION__, slot->name);
if (rpaphp_config_pci_adapter(slot)) {
err("%s: CONFIG pci adapter failed\n", __FUNCTION__);
goto exit_rc;
}
} else if (slot->hotplug_slot->info->adapter_status == CONFIGURED) {
if (init_slot_pci_funcs(slot)) {
err("%s: init_slot_pci_funcs failed\n", __FUNCTION__);
goto exit_rc;
}
} else {
err("%s: slot[%s]'s adapter_status is NOT_VALID.\n",
__FUNCTION__, slot->name);
goto exit_rc;
}
print_slot_pci_funcs(slot);
if (!list_empty(&slot->dev.pci_funcs)) {
slot->state = CONFIGURED;
......
......@@ -35,6 +35,7 @@
#include <linux/vmalloc.h>
#include <linux/interrupt.h>
#include <linux/spinlock.h>
#include <linux/delay.h>
#include <linux/pci.h>
#include <asm/system.h>
#include "shpchp.h"
......@@ -300,8 +301,7 @@ static int shpc_write_cmd(struct slot *slot, u8 t_slot, u8 cmd)
if (!(cmd_status & 0x1))
break;
/* Check every 0.1 sec for a total of 1 sec*/
set_current_state(TASK_INTERRUPTIBLE);
schedule_timeout(HZ/10);
msleep(100);
}
cmd_status = readw(php_ctlr->creg + CMD_STATUS);
......
......@@ -291,10 +291,7 @@ pci_set_power_state(struct pci_dev *dev, int state)
/* Mandatory power management transition delays */
/* see PCI PM 1.1 5.6.1 table 18 */
if(state == 3 || dev->current_state == 3)
{
set_current_state(TASK_UNINTERRUPTIBLE);
schedule_timeout(HZ/100);
}
msleep(10);
else if(state == 2 || dev->current_state == 2)
udelay(200);
dev->current_state = state;
......
This diff is collapsed.
......@@ -537,10 +537,11 @@ pci_assign_unassigned_resources(void)
/* Depth first, calculate sizes and alignments of all
subordinate buses. */
for(ln=pci_root_buses.next; ln != &pci_root_buses; ln=ln->next)
list_for_each(ln, &pci_root_buses) {
pci_bus_size_bridges(pci_bus_b(ln));
}
/* Depth last, allocate resources and update the hardware. */
for(ln=pci_root_buses.next; ln != &pci_root_buses; ln=ln->next) {
list_for_each(ln, &pci_root_buses) {
pci_bus_assign_resources(pci_bus_b(ln));
pci_enable_bridges(pci_bus_b(ln));
}
......
......@@ -2228,7 +2228,9 @@
#define PCI_DEVICE_ID_INTEL_82451NX 0x84ca
#define PCI_DEVICE_ID_INTEL_82454NX 0x84cb
#define PCI_DEVICE_ID_INTEL_84460GX 0x84ea
#define PCI_DEVICE_ID_INTEL_IXP4XX 0x8500
#define PCI_DEVICE_ID_INTEL_IXP4XX 0x8500
#define PCI_DEVICE_ID_INTEL_IXP2400 0x9001
#define PCI_DEVICE_ID_INTEL_IXP2800 0x9004
#define PCI_VENDOR_ID_COMPUTONE 0x8e0e
#define PCI_DEVICE_ID_COMPUTONE_IP2EX 0x0291
......
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