diff options
Diffstat (limited to 'drivers/pci/hotplug')
-rw-r--r-- | drivers/pci/hotplug/acpiphp_glue.c | 2 | ||||
-rw-r--r-- | drivers/pci/hotplug/rpaphp_slot.c | 47 | ||||
-rw-r--r-- | drivers/pci/hotplug/shpchp.h | 238 | ||||
-rw-r--r-- | drivers/pci/hotplug/shpchp_core.c | 116 | ||||
-rw-r--r-- | drivers/pci/hotplug/shpchp_ctrl.c | 21 | ||||
-rw-r--r-- | drivers/pci/hotplug/shpchp_hpc.c | 223 |
6 files changed, 175 insertions, 472 deletions
diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c index 0b9d0db1590..bd1faebf61a 100644 --- a/drivers/pci/hotplug/acpiphp_glue.c +++ b/drivers/pci/hotplug/acpiphp_glue.c @@ -1682,7 +1682,7 @@ int __init acpiphp_glue_init(void) * * This function frees all data allocated in acpiphp_glue_init() */ -void __exit acpiphp_glue_exit(void) +void acpiphp_glue_exit(void) { acpi_pci_unregister_driver(&acpi_pci_hp_driver); } diff --git a/drivers/pci/hotplug/rpaphp_slot.c b/drivers/pci/hotplug/rpaphp_slot.c index b771196a654..3009193f005 100644 --- a/drivers/pci/hotplug/rpaphp_slot.c +++ b/drivers/pci/hotplug/rpaphp_slot.c @@ -47,21 +47,11 @@ static ssize_t location_read_file (struct hotplug_slot *php_slot, char *buf) return retval; } -static struct hotplug_slot_attribute hotplug_slot_attr_location = { +static struct hotplug_slot_attribute php_attr_location = { .attr = {.name = "phy_location", .mode = S_IFREG | S_IRUGO}, .show = location_read_file, }; -static void rpaphp_sysfs_add_attr_location (struct hotplug_slot *slot) -{ - sysfs_create_file(&slot->kobj, &hotplug_slot_attr_location.attr); -} - -static void rpaphp_sysfs_remove_attr_location (struct hotplug_slot *slot) -{ - sysfs_remove_file(&slot->kobj, &hotplug_slot_attr_location.attr); -} - /* free up the memory used by a slot */ static void rpaphp_release_slot(struct hotplug_slot *hotplug_slot) { @@ -145,7 +135,7 @@ int rpaphp_deregister_slot(struct slot *slot) list_del(&slot->rpaphp_slot_list); /* remove "phy_location" file */ - rpaphp_sysfs_remove_attr_location(php_slot); + sysfs_remove_file(&php_slot->kobj, &php_attr_location.attr); retval = pci_hp_deregister(php_slot); if (retval) @@ -160,36 +150,45 @@ EXPORT_SYMBOL_GPL(rpaphp_deregister_slot); int rpaphp_register_slot(struct slot *slot) { + struct hotplug_slot *php_slot = slot->hotplug_slot; int retval; dbg("%s registering slot:path[%s] index[%x], name[%s] pdomain[%x] type[%d]\n", __FUNCTION__, slot->dn->full_name, slot->index, slot->name, slot->power_domain, slot->type); + /* should not try to register the same slot twice */ - if (is_registered(slot)) { /* should't be here */ + if (is_registered(slot)) { err("rpaphp_register_slot: slot[%s] is already registered\n", slot->name); - rpaphp_release_slot(slot->hotplug_slot); - return -EAGAIN; + retval = -EAGAIN; + goto register_fail; } - retval = pci_hp_register(slot->hotplug_slot); + + retval = pci_hp_register(php_slot); if (retval) { err("pci_hp_register failed with error %d\n", retval); - rpaphp_release_slot(slot->hotplug_slot); - return retval; + goto register_fail; } - - /* create "phy_locatoin" file */ - rpaphp_sysfs_add_attr_location(slot->hotplug_slot); - /* add slot to our internal list */ - dbg("%s adding slot[%s] to rpaphp_slot_list\n", - __FUNCTION__, slot->name); + /* create "phy_location" file */ + retval = sysfs_create_file(&php_slot->kobj, &php_attr_location.attr); + if (retval) { + err("sysfs_create_file failed with error %d\n", retval); + goto sysfs_fail; + } + /* add slot to our internal list */ list_add(&slot->rpaphp_slot_list, &rpaphp_slot_head); info("Slot [%s](PCI location=%s) registered\n", slot->name, slot->location); num_slots++; return 0; + +sysfs_fail: + pci_hp_deregister(php_slot); +register_fail: + rpaphp_release_slot(php_slot); + return retval; } int rpaphp_get_power_status(struct slot *slot, u8 * value) diff --git a/drivers/pci/hotplug/shpchp.h b/drivers/pci/hotplug/shpchp.h index 50757695844..3ca6a4f574b 100644 --- a/drivers/pci/hotplug/shpchp.h +++ b/drivers/pci/hotplug/shpchp.h @@ -47,11 +47,17 @@ extern int shpchp_poll_time; extern int shpchp_debug; extern struct workqueue_struct *shpchp_wq; -/*#define dbg(format, arg...) do { if (shpchp_debug) printk(KERN_DEBUG "%s: " format, MY_NAME , ## arg); } while (0)*/ -#define dbg(format, arg...) do { if (shpchp_debug) printk("%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 dbg(format, arg...) \ + do { \ + if (shpchp_debug) \ + printk("%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 { @@ -83,34 +89,27 @@ struct event_info { struct controller { struct mutex crit_sect; /* critical section mutex */ struct mutex cmd_lock; /* command lock */ - struct php_ctlr_state_s *hpc_ctlr_handle; /* HPC controller handle */ int num_slots; /* Number of slots on ctlr */ int slot_num_inc; /* 1 or -1 */ struct pci_dev *pci_dev; struct list_head slot_list; struct hpc_ops *hpc_ops; wait_queue_head_t queue; /* sleep & wake process */ - u8 bus; - u8 device; - u8 function; u8 slot_device_offset; - u8 add_support; u32 pcix_misc2_reg; /* for amd pogo errata */ - enum pci_bus_speed speed; u32 first_slot; /* First physical slot number */ - u8 slot_bus; /* Bus where the slots handled by this controller sit */ u32 cap_offset; unsigned long mmio_base; unsigned long mmio_size; + void __iomem *creg; + struct timer_list poll_timer; }; - /* Define AMD SHPC ID */ #define PCI_DEVICE_ID_AMD_GOLAM_7450 0x7450 #define PCI_DEVICE_ID_AMD_POGO_7458 0x7458 /* AMD PCIX bridge registers */ - #define PCIX_MEM_BASE_LIMIT_OFFSET 0x1C #define PCIX_MISCII_OFFSET 0x48 #define PCIX_MISC_BRIDGE_ERRORS_OFFSET 0x80 @@ -145,8 +144,6 @@ struct controller { #define POWERON_STATE 3 #define POWEROFF_STATE 4 -#define PCI_TO_PCI_BRIDGE_CLASS 0x00060400 - /* Error messages */ #define INTERLOCK_OPEN 0x00000002 #define ADD_NOT_SUPPORTED 0x00000003 @@ -158,50 +155,32 @@ struct controller { #define WRONG_BUS_FREQUENCY 0x0000000D #define POWER_FAILURE 0x0000000E -#define REMOVE_NOT_SUPPORTED 0x00000003 - -#define DISABLE_CARD 1 - -/* - * error Messages - */ -#define msg_initialization_err "Initialization failure, error=%d\n" -#define msg_button_on "PCI slot #%s - powering on due to button press.\n" -#define msg_button_off "PCI slot #%s - powering off due to button press.\n" -#define msg_button_cancel "PCI slot #%s - action canceled due to button press.\n" - -/* sysfs functions for the hotplug controller info */ extern int __must_check shpchp_create_ctrl_files(struct controller *ctrl); - -extern int shpchp_sysfs_enable_slot(struct slot *slot); -extern int shpchp_sysfs_disable_slot(struct slot *slot); - -extern u8 shpchp_handle_attention_button(u8 hp_slot, void *inst_id); -extern u8 shpchp_handle_switch_change(u8 hp_slot, void *inst_id); -extern u8 shpchp_handle_presence_change(u8 hp_slot, void *inst_id); -extern u8 shpchp_handle_power_fault(u8 hp_slot, void *inst_id); - -/* pci functions */ -extern int shpchp_save_config(struct controller *ctrl, int busnumber, int num_ctlr_slots, int first_device_num); -extern int shpchp_configure_device(struct slot *p_slot); -extern int shpchp_unconfigure_device(struct slot *p_slot); -extern void shpchp_remove_ctrl_files(struct controller *ctrl); -extern void cleanup_slots(struct controller *ctrl); -extern void queue_pushbutton_work(struct work_struct *work); - +extern void shpchp_remove_ctrl_files(struct controller *ctrl); +extern int shpchp_sysfs_enable_slot(struct slot *slot); +extern int shpchp_sysfs_disable_slot(struct slot *slot); +extern u8 shpchp_handle_attention_button(u8 hp_slot, struct controller *ctrl); +extern u8 shpchp_handle_switch_change(u8 hp_slot, struct controller *ctrl); +extern u8 shpchp_handle_presence_change(u8 hp_slot, struct controller *ctrl); +extern u8 shpchp_handle_power_fault(u8 hp_slot, struct controller *ctrl); +extern int shpchp_configure_device(struct slot *p_slot); +extern int shpchp_unconfigure_device(struct slot *p_slot); +extern void cleanup_slots(struct controller *ctrl); +extern void queue_pushbutton_work(struct work_struct *work); +extern int shpc_init( struct controller *ctrl, struct pci_dev *pdev); #ifdef CONFIG_ACPI static inline int get_hp_params_from_firmware(struct pci_dev *dev, - struct hotplug_params *hpp) + struct hotplug_params *hpp) { if (ACPI_FAILURE(acpi_get_hp_params_from_firmware(dev->bus, hpp))) return -ENODEV; return 0; } -#define get_hp_hw_control_from_firmware(pdev) \ - do { \ - if (DEVICE_ACPI_HANDLE(&(pdev->dev))) \ - acpi_run_oshp(DEVICE_ACPI_HANDLE(&(pdev->dev))); \ +#define get_hp_hw_control_from_firmware(pdev) \ + do { \ + if (DEVICE_ACPI_HANDLE(&(pdev->dev))) \ + acpi_run_oshp(DEVICE_ACPI_HANDLE(&(pdev->dev)));\ } while (0) #else #define get_hp_params_from_firmware(dev, hpp) (-ENODEV) @@ -222,108 +201,40 @@ struct ctrl_reg { volatile u32 serr_loc; volatile u32 serr_intr_enable; volatile u32 slot1; - volatile u32 slot2; - volatile u32 slot3; - volatile u32 slot4; - volatile u32 slot5; - volatile u32 slot6; - volatile u32 slot7; - volatile u32 slot8; - volatile u32 slot9; - volatile u32 slot10; - volatile u32 slot11; - volatile u32 slot12; } __attribute__ ((packed)); /* offsets to the controller registers based on the above structure layout */ enum ctrl_offsets { - BASE_OFFSET = offsetof(struct ctrl_reg, base_offset), - SLOT_AVAIL1 = offsetof(struct ctrl_reg, slot_avail1), - SLOT_AVAIL2 = offsetof(struct ctrl_reg, slot_avail2), - SLOT_CONFIG = offsetof(struct ctrl_reg, slot_config), - SEC_BUS_CONFIG = offsetof(struct ctrl_reg, sec_bus_config), - MSI_CTRL = offsetof(struct ctrl_reg, msi_ctrl), - PROG_INTERFACE = offsetof(struct ctrl_reg, prog_interface), - CMD = offsetof(struct ctrl_reg, cmd), - CMD_STATUS = offsetof(struct ctrl_reg, cmd_status), - INTR_LOC = offsetof(struct ctrl_reg, intr_loc), - SERR_LOC = offsetof(struct ctrl_reg, serr_loc), - SERR_INTR_ENABLE = offsetof(struct ctrl_reg, serr_intr_enable), - SLOT1 = offsetof(struct ctrl_reg, slot1), - SLOT2 = offsetof(struct ctrl_reg, slot2), - SLOT3 = offsetof(struct ctrl_reg, slot3), - SLOT4 = offsetof(struct ctrl_reg, slot4), - SLOT5 = offsetof(struct ctrl_reg, slot5), - SLOT6 = offsetof(struct ctrl_reg, slot6), - SLOT7 = offsetof(struct ctrl_reg, slot7), - SLOT8 = offsetof(struct ctrl_reg, slot8), - SLOT9 = offsetof(struct ctrl_reg, slot9), - SLOT10 = offsetof(struct ctrl_reg, slot10), - SLOT11 = offsetof(struct ctrl_reg, slot11), - SLOT12 = offsetof(struct ctrl_reg, slot12), -}; -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; - void __iomem *creg; /* Ptr to controller register space */ + BASE_OFFSET = offsetof(struct ctrl_reg, base_offset), + SLOT_AVAIL1 = offsetof(struct ctrl_reg, slot_avail1), + SLOT_AVAIL2 = offsetof(struct ctrl_reg, slot_avail2), + SLOT_CONFIG = offsetof(struct ctrl_reg, slot_config), + SEC_BUS_CONFIG = offsetof(struct ctrl_reg, sec_bus_config), + MSI_CTRL = offsetof(struct ctrl_reg, msi_ctrl), + PROG_INTERFACE = offsetof(struct ctrl_reg, prog_interface), + CMD = offsetof(struct ctrl_reg, cmd), + CMD_STATUS = offsetof(struct ctrl_reg, cmd_status), + INTR_LOC = offsetof(struct ctrl_reg, intr_loc), + SERR_LOC = offsetof(struct ctrl_reg, serr_loc), + SERR_INTR_ENABLE = offsetof(struct ctrl_reg, serr_intr_enable), + SLOT1 = offsetof(struct ctrl_reg, slot1), }; -/* Inline functions */ - -/* Inline functions to check the sanity of a pointer that is passed to us */ -static inline int slot_paranoia_check (struct slot *slot, const char *function) -{ - if (!slot) { - dbg("%s - slot == NULL", function); - return -1; - } - if (!slot->hotplug_slot) { - dbg("%s - slot->hotplug_slot == NULL!", function); - return -1; - } - return 0; -} - -static inline struct slot *get_slot (struct hotplug_slot *hotplug_slot, const char *function) +static inline struct slot *get_slot(struct hotplug_slot *hotplug_slot) { - struct slot *slot; - - if (!hotplug_slot) { - dbg("%s - hotplug_slot == NULL\n", function); - return NULL; - } - - slot = (struct slot *)hotplug_slot->private; - if (slot_paranoia_check (slot, function)) - return NULL; - return slot; + return hotplug_slot->private; } -static inline struct slot *shpchp_find_slot (struct controller *ctrl, u8 device) +static inline struct slot *shpchp_find_slot(struct controller *ctrl, u8 device) { struct slot *slot; - if (!ctrl) - return NULL; - list_for_each_entry(slot, &ctrl->slot_list, slot_list) { if (slot->device == device) return slot; } err("%s: slot (device=0x%x) not found\n", __FUNCTION__, device); - return NULL; } @@ -400,44 +311,27 @@ static inline void amd_pogo_errata_restore_misc_reg(struct slot *p_slot) pci_write_config_dword(p_slot->ctrl->pci_dev, PCIX_MISCII_OFFSET, pcix_misc2_temp); } -enum php_ctlr_type { - PCI, - ISA, - ACPI -}; - -int shpc_init( struct controller *ctrl, struct pci_dev *pdev); - -int shpc_get_ctlr_slot_config( struct controller *ctrl, - int *num_ctlr_slots, - int *first_device_num, - int *physical_slot_num, - int *updown, - int *flags); - struct hpc_ops { - int (*power_on_slot ) (struct slot *slot); - int (*slot_enable ) (struct slot *slot); - int (*slot_disable ) (struct slot *slot); - int (*set_bus_speed_mode) (struct slot *slot, enum pci_bus_speed speed); - int (*get_power_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 (*get_latch_status) (struct slot *slot, u8 *status); - int (*get_adapter_status) (struct slot *slot, u8 *status); - - 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_adapter_speed) (struct slot *slot, enum pci_bus_speed *speed); - int (*get_mode1_ECC_cap) (struct slot *slot, u8 *mode); - int (*get_prog_int) (struct slot *slot, u8 *prog_int); - - int (*query_power_fault) (struct slot *slot); - void (*green_led_on) (struct slot *slot); - void (*green_led_off) (struct slot *slot); - void (*green_led_blink) (struct slot *slot); - void (*release_ctlr) (struct controller *ctrl); - int (*check_cmd_status) (struct controller *ctrl); + int (*power_on_slot)(struct slot *slot); + int (*slot_enable)(struct slot *slot); + int (*slot_disable)(struct slot *slot); + int (*set_bus_speed_mode)(struct slot *slot, enum pci_bus_speed speed); + int (*get_power_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 (*get_latch_status)(struct slot *slot, u8 *status); + int (*get_adapter_status)(struct slot *slot, u8 *status); + 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_adapter_speed)(struct slot *slot, enum pci_bus_speed *speed); + int (*get_mode1_ECC_cap)(struct slot *slot, u8 *mode); + int (*get_prog_int)(struct slot *slot, u8 *prog_int); + int (*query_power_fault)(struct slot *slot); + void (*green_led_on)(struct slot *slot); + void (*green_led_off)(struct slot *slot); + void (*green_led_blink)(struct slot *slot); + void (*release_ctlr)(struct controller *ctrl); + int (*check_cmd_status)(struct controller *ctrl); }; #endif /* _SHPCHP_H */ diff --git a/drivers/pci/hotplug/shpchp_core.c b/drivers/pci/hotplug/shpchp_core.c index 4eac85b3d90..590cd3cbe01 100644 --- a/drivers/pci/hotplug/shpchp_core.c +++ b/drivers/pci/hotplug/shpchp_core.c @@ -104,23 +104,6 @@ static void make_slot_name(struct slot *slot) slot->bus, slot->number); } - - - -static int -shpchprm_get_physical_slot_number(struct controller *ctrl, u32 *sun, - u8 busnum, u8 devnum) -{ - int offset = devnum - ctrl->slot_device_offset; - - dbg("%s: ctrl->slot_num_inc %d, offset %d\n", __FUNCTION__, - ctrl->slot_num_inc, offset); - *sun = (u8) (ctrl->first_slot + ctrl->slot_num_inc *offset); - return 0; -} - - - static int init_slots(struct controller *ctrl) { struct slot *slot; @@ -128,7 +111,6 @@ static int init_slots(struct controller *ctrl) struct hotplug_slot_info *info; int retval = -ENOMEM; int i; - u32 sun; for (i = 0; i < ctrl->num_slots; i++) { slot = kzalloc(sizeof(*slot), GFP_KERNEL); @@ -149,16 +131,11 @@ static int init_slots(struct controller *ctrl) slot->hp_slot = i; slot->ctrl = ctrl; - slot->bus = ctrl->slot_bus; + slot->bus = ctrl->pci_dev->subordinate->number; slot->device = ctrl->slot_device_offset + i; slot->hpc_ops = ctrl->hpc_ops; + slot->number = ctrl->first_slot + (ctrl->slot_num_inc * i); mutex_init(&slot->lock); - - if (shpchprm_get_physical_slot_number(ctrl, &sun, - slot->bus, slot->device)) - goto error_info; - - slot->number = sun; INIT_DELAYED_WORK(&slot->work, queue_pushbutton_work); /* register this slot with the hotplug pci core */ @@ -211,42 +188,12 @@ void cleanup_slots(struct controller *ctrl) } } -static int get_ctlr_slot_config(struct controller *ctrl) -{ - int num_ctlr_slots; - int first_device_num; - int physical_slot_num; - int updown; - int rc; - int flags; - - rc = shpc_get_ctlr_slot_config(ctrl, &num_ctlr_slots, - &first_device_num, &physical_slot_num, - &updown, &flags); - if (rc) { - err("%s: get_ctlr_slot_config fail for b:d (%x:%x)\n", - __FUNCTION__, ctrl->bus, ctrl->device); - return -1; - } - - ctrl->num_slots = num_ctlr_slots; - ctrl->slot_device_offset = first_device_num; - ctrl->first_slot = physical_slot_num; - ctrl->slot_num_inc = updown; /* either -1 or 1 */ - - dbg("%s: num_slot(0x%x) 1st_dev(0x%x) psn(0x%x) updown(%d) for b:d " - "(%x:%x)\n", __FUNCTION__, num_ctlr_slots, first_device_num, - physical_slot_num, updown, ctrl->bus, ctrl->device); - - return 0; -} - /* * set_attention_status - Turns the Amber LED for a slot on, off or blink */ static int set_attention_status (struct hotplug_slot *hotplug_slot, u8 status) { - struct slot *slot = get_slot(hotplug_slot, __FUNCTION__); + struct slot *slot = get_slot(hotplug_slot); dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name); @@ -258,7 +205,7 @@ static int set_attention_status (struct hotplug_slot *hotplug_slot, u8 status) static int enable_slot (struct hotplug_slot *hotplug_slot) { - struct slot *slot = get_slot(hotplug_slot, __FUNCTION__); + struct slot *slot = get_slot(hotplug_slot); dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name); @@ -267,7 +214,7 @@ static int enable_slot (struct hotplug_slot *hotplug_slot) static int disable_slot (struct hotplug_slot *hotplug_slot) { - struct slot *slot = get_slot(hotplug_slot, __FUNCTION__); + struct slot *slot = get_slot(hotplug_slot); dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name); @@ -276,7 +223,7 @@ static int disable_slot (struct hotplug_slot *hotplug_slot) static int get_power_status (struct hotplug_slot *hotplug_slot, u8 *value) { - struct slot *slot = get_slot(hotplug_slot, __FUNCTION__); + struct slot *slot = get_slot(hotplug_slot); int retval; dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name); @@ -290,7 +237,7 @@ static int get_power_status (struct hotplug_slot *hotplug_slot, u8 *value) static int get_attention_status (struct hotplug_slot *hotplug_slot, u8 *value) { - struct slot *slot = get_slot(hotplug_slot, __FUNCTION__); + struct slot *slot = get_slot(hotplug_slot); int retval; dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name); @@ -304,7 +251,7 @@ static int get_attention_status (struct hotplug_slot *hotplug_slot, u8 *value) static int get_latch_status (struct hotplug_slot *hotplug_slot, u8 *value) { - struct slot *slot = get_slot(hotplug_slot, __FUNCTION__); + struct slot *slot = get_slot(hotplug_slot); int retval; dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name); @@ -318,7 +265,7 @@ static int get_latch_status (struct hotplug_slot *hotplug_slot, u8 *value) static int get_adapter_status (struct hotplug_slot *hotplug_slot, u8 *value) { - struct slot *slot = get_slot(hotplug_slot, __FUNCTION__); + struct slot *slot = get_slot(hotplug_slot); int retval; dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name); @@ -332,7 +279,7 @@ static int get_adapter_status (struct hotplug_slot *hotplug_slot, u8 *value) static int get_address (struct hotplug_slot *hotplug_slot, u32 *value) { - struct slot *slot = get_slot(hotplug_slot, __FUNCTION__); + struct slot *slot = get_slot(hotplug_slot); struct pci_bus *bus = slot->ctrl->pci_dev->subordinate; dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name); @@ -344,7 +291,7 @@ static int get_address (struct hotplug_slot *hotplug_slot, u32 *value) static int get_max_bus_speed (struct hotplug_slot *hotplug_slot, enum pci_bus_speed *value) { - struct slot *slot = get_slot(hotplug_slot, __FUNCTION__); + struct slot *slot = get_slot(hotplug_slot); int retval; dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name); @@ -358,7 +305,7 @@ static int get_max_bus_speed (struct hotplug_slot *hotplug_slot, enum pci_bus_sp static int get_cur_bus_speed (struct hotplug_slot *hotplug_slot, enum pci_bus_speed *value) { - struct slot *slot = get_slot(hotplug_slot, __FUNCTION__); + struct slot *slot = get_slot(hotplug_slot); int retval; dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name); @@ -385,9 +332,6 @@ static int shpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent) { int rc; struct controller *ctrl; - struct slot *t_slot; - int first_device_num; /* first PCI device number */ - int num_ctlr_slots; /* number of slots implemented */ if (!is_shpc_capable(pdev)) return -ENODEV; @@ -408,47 +352,13 @@ static int shpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent) pci_set_drvdata(pdev, ctrl); - ctrl->bus = pdev->bus->number; - ctrl->slot_bus = pdev->subordinate->number; - ctrl->device = PCI_SLOT(pdev->devfn); - ctrl->function = PCI_FUNC(pdev->devfn); - - dbg("ctrl bus=0x%x, device=%x, function=%x, irq=%x\n", - ctrl->bus, ctrl->device, ctrl->function, pdev->irq); - - /* - * Save configuration headers for this and subordinate PCI buses - */ - rc = get_ctlr_slot_config(ctrl); - if (rc) { - err(msg_initialization_err, rc); - goto err_out_release_ctlr; - } - first_device_num = ctrl->slot_device_offset; - num_ctlr_slots = ctrl->num_slots; - - ctrl->add_support = 1; - /* Setup the slot information structures */ rc = init_slots(ctrl); if (rc) { - err(msg_initialization_err, 6); + err("%s: slot initialization failed\n", SHPC_MODULE_NAME); goto err_out_release_ctlr; } - /* Now hpc_functions (slot->hpc_ops->functions) are ready */ - t_slot = shpchp_find_slot(ctrl, first_device_num); - - /* Check for operation bus speed */ - rc = t_slot->hpc_ops->get_cur_bus_speed(t_slot, &ctrl->speed); - dbg("%s: t_slot->hp_slot %x\n", __FUNCTION__,t_slot->hp_slot); - - if (rc || ctrl->speed == PCI_SPEED_UNKNOWN) { - err(SHPC_MODULE_NAME ": Can't get current bus speed. " - "Set to 33MHz PCI.\n"); - ctrl->speed = PCI_SPEED_33MHz; - } - rc = shpchp_create_ctrl_files(ctrl); if (rc) goto err_cleanup_slots; diff --git a/drivers/pci/hotplug/shpchp_ctrl.c b/drivers/pci/hotplug/shpchp_ctrl.c index 158ac783609..6bb84734cd6 100644 --- a/drivers/pci/hotplug/shpchp_ctrl.c +++ b/drivers/pci/hotplug/shpchp_ctrl.c @@ -57,9 +57,8 @@ static int queue_interrupt_event(struct slot *p_slot, u32 event_type) return 0; } -u8 shpchp_handle_attention_button(u8 hp_slot, void *inst_id) +u8 shpchp_handle_attention_button(u8 hp_slot, struct controller *ctrl) { - struct controller *ctrl = (struct controller *) inst_id; struct slot *p_slot; u32 event_type; @@ -81,9 +80,8 @@ u8 shpchp_handle_attention_button(u8 hp_slot, void *inst_id) } -u8 shpchp_handle_switch_change(u8 hp_slot, void *inst_id) +u8 shpchp_handle_switch_change(u8 hp_slot, struct controller *ctrl) { - struct controller *ctrl = (struct controller *) inst_id; struct slot *p_slot; u8 getstatus; u32 event_type; @@ -120,9 +118,8 @@ u8 shpchp_handle_switch_change(u8 hp_slot, void *inst_id) return 1; } -u8 shpchp_handle_presence_change(u8 hp_slot, void *inst_id) +u8 shpchp_handle_presence_change(u8 hp_slot, struct controller *ctrl) { - struct controller *ctrl = (struct controller *) inst_id; struct slot *p_slot; u32 event_type; @@ -154,9 +151,8 @@ u8 shpchp_handle_presence_change(u8 hp_slot, void *inst_id) return 1; } -u8 shpchp_handle_power_fault(u8 hp_slot, void *inst_id) +u8 shpchp_handle_power_fault(u8 hp_slot, struct controller *ctrl) { - struct controller *ctrl = (struct controller *) inst_id; struct slot *p_slot; u32 event_type; @@ -497,10 +493,12 @@ static void handle_button_press_event(struct slot *p_slot) p_slot->hpc_ops->get_power_status(p_slot, &getstatus); if (getstatus) { p_slot->state = BLINKINGOFF_STATE; - info(msg_button_off, p_slot->name); + info("PCI slot #%s - powering off due to button " + "press.\n", p_slot->name); } else { p_slot->state = BLINKINGON_STATE; - info(msg_button_on, p_slot->name); + info("PCI slot #%s - powering on due to button " + "press.\n", p_slot->name); } /* blink green LED and turn off amber */ p_slot->hpc_ops->green_led_blink(p_slot); @@ -523,7 +521,8 @@ static void handle_button_press_event(struct slot *p_slot) else p_slot->hpc_ops->green_led_off(p_slot); p_slot->hpc_ops->set_attention_status(p_slot, 0); - info(msg_button_cancel, p_slot->name); + info("PCI slot #%s - action canceled due to button press\n", + p_slot->name); p_slot->state = STATIC_STATE; break; case POWEROFF_STATE: diff --git a/drivers/pci/hotplug/shpchp_hpc.c b/drivers/pci/hotplug/shpchp_hpc.c index 83a5226ba9e..b7bede4b7c2 100644 --- a/drivers/pci/hotplug/shpchp_hpc.c +++ b/drivers/pci/hotplug/shpchp_hpc.c @@ -212,44 +212,40 @@ #define SLOT_SERR_INT_MASK 0x3 DEFINE_DBG_BUFFER /* Debug string buffer for entire HPC defined here */ -static struct php_ctlr_state_s *php_ctlr_list_head; /* HPC state linked list */ -static int ctlr_seq_num = 0; /* Controller sequenc # */ -static spinlock_t list_lock; - static atomic_t shpchp_num_controllers = ATOMIC_INIT(0); static irqreturn_t shpc_isr(int irq, void *dev_id); -static void start_int_poll_timer(struct php_ctlr_state_s *php_ctlr, int sec); +static void start_int_poll_timer(struct controller *ctrl, int sec); static int hpc_check_cmd_status(struct controller *ctrl); static inline u8 shpc_readb(struct controller *ctrl, int reg) { - return readb(ctrl->hpc_ctlr_handle->creg + reg); + return readb(ctrl->creg + reg); } static inline void shpc_writeb(struct controller *ctrl, int reg, u8 val) { - writeb(val, ctrl->hpc_ctlr_handle->creg + reg); + writeb(val, ctrl->creg + reg); } static inline u16 shpc_readw(struct controller *ctrl, int reg) { - return readw(ctrl->hpc_ctlr_handle->creg + reg); + return readw(ctrl->creg + reg); } static inline void shpc_writew(struct controller *ctrl, int reg, u16 val) { - writew(val, ctrl->hpc_ctlr_handle->creg + reg); + writew(val, ctrl->creg + reg); } static inline u32 shpc_readl(struct controller *ctrl, int reg) { - return readl(ctrl->hpc_ctlr_handle->creg + reg); + return readl(ctrl->creg + reg); } static inline void shpc_writel(struct controller *ctrl, int reg, u32 val) { - writel(val, ctrl->hpc_ctlr_handle->creg + reg); + writel(val, ctrl->creg + reg); } static inline int shpc_indirect_read(struct controller *ctrl, int index, @@ -268,21 +264,20 @@ static inline int shpc_indirect_read(struct controller *ctrl, int index, /* * This is the interrupt polling timeout function. */ -static void int_poll_timeout(unsigned long lphp_ctlr) +static void int_poll_timeout(unsigned long data) { - struct php_ctlr_state_s *php_ctlr = - (struct php_ctlr_state_s *)lphp_ctlr; + struct controller *ctrl = (struct controller *)data; DBG_ENTER_ROUTINE /* Poll for interrupt events. regs == NULL => polling */ - shpc_isr(0, php_ctlr->callback_instance_id); + shpc_isr(0, ctrl); - init_timer(&php_ctlr->int_poll_timer); + init_timer(&ctrl->poll_timer); if (!shpchp_poll_time) shpchp_poll_time = 2; /* default polling interval is 2 sec */ - start_int_poll_timer(php_ctlr, shpchp_poll_time); + start_int_poll_timer(ctrl, shpchp_poll_time); DBG_LEAVE_ROUTINE } @@ -290,16 +285,16 @@ static void int_poll_timeout(unsigned long lphp_ctlr) /* * This function starts the interrupt polling timer. */ -static void start_int_poll_timer(struct php_ctlr_state_s *php_ctlr, int sec) +static void start_int_poll_timer(struct controller *ctrl, int sec) { /* Clamp to sane value */ if ((sec <= 0) || (sec > 60)) sec = 2; - php_ctlr->int_poll_timer.function = &int_poll_timeout; - php_ctlr->int_poll_timer.data = (unsigned long)php_ctlr; - php_ctlr->int_poll_timer.expires = jiffies + sec * HZ; - add_timer(&php_ctlr->int_poll_timer); + ctrl->poll_timer.function = &int_poll_timeout; + ctrl->poll_timer.data = (unsigned long)ctrl; + ctrl->poll_timer.expires = jiffies + sec * HZ; + add_timer(&ctrl->poll_timer); } static inline int is_ctrl_busy(struct controller *ctrl) @@ -666,33 +661,8 @@ static void hpc_set_green_led_blink(struct slot *slot) shpc_write_cmd(slot, slot->hp_slot, SET_PWR_BLINK); } -int shpc_get_ctlr_slot_config(struct controller *ctrl, - int *num_ctlr_slots, /* number of slots in this HPC */ - int *first_device_num, /* PCI dev num of the first slot in this SHPC */ - int *physical_slot_num, /* phy slot num of the first slot in this SHPC */ - int *updown, /* physical_slot_num increament: 1 or -1 */ - int *flags) -{ - u32 slot_config; - - DBG_ENTER_ROUTINE - - slot_config = shpc_readl(ctrl, SLOT_CONFIG); - *first_device_num = (slot_config & FIRST_DEV_NUM) >> 8; - *num_ctlr_slots = slot_config & SLOT_NUM; - *physical_slot_num = (slot_config & PSN) >> 16; - *updown = ((slot_config & UPDOWN) >> 29) ? 1 : -1; - - dbg("%s: physical_slot_num = %x\n", __FUNCTION__, *physical_slot_num); - - DBG_LEAVE_ROUTINE - return 0; -} - static void hpc_release_ctlr(struct controller *ctrl) { - struct php_ctlr_state_s *php_ctlr = ctrl->hpc_ctlr_handle; - struct php_ctlr_state_s *p, *p_prev; int i; u32 slot_reg, serr_int; @@ -722,40 +692,15 @@ static void hpc_release_ctlr(struct controller *ctrl) serr_int &= ~SERR_INTR_RSVDZ_MASK; shpc_writel(ctrl, SERR_INTR_ENABLE, serr_int); - if (shpchp_poll_mode) { - del_timer(&php_ctlr->int_poll_timer); - } else { - if (php_ctlr->irq) { - free_irq(php_ctlr->irq, ctrl); - php_ctlr->irq = 0; - pci_disable_msi(php_ctlr->pci_dev); - } - } - - if (php_ctlr->pci_dev) { - iounmap(php_ctlr->creg); - release_mem_region(ctrl->mmio_base, ctrl->mmio_size); - php_ctlr->pci_dev = NULL; - } - - spin_lock(&list_lock); - p = php_ctlr_list_head; - p_prev = NULL; - while (p) { - if (p == php_ctlr) { - if (p_prev) - p_prev->pnext = p->pnext; - else - php_ctlr_list_head = p->pnext; - break; - } else { - p_prev = p; - p = p->pnext; - } + if (shpchp_poll_mode) + del_timer(&ctrl->poll_timer); + else { + free_irq(ctrl->pci_dev->irq, ctrl); + pci_disable_msi(ctrl->pci_dev); } - spin_unlock(&list_lock); - kfree(php_ctlr); + iounmap(ctrl->creg); + release_mem_region(ctrl->mmio_base, ctrl->mmio_size); /* * If this is the last controller to be released, destroy the @@ -764,8 +709,7 @@ static void hpc_release_ctlr(struct controller *ctrl) if (atomic_dec_and_test(&shpchp_num_controllers)) destroy_workqueue(shpchp_wq); -DBG_LEAVE_ROUTINE - + DBG_LEAVE_ROUTINE } static int hpc_power_on_slot(struct slot * slot) @@ -891,7 +835,6 @@ static int hpc_set_bus_speed_mode(struct slot * slot, enum pci_bus_speed value) static irqreturn_t shpc_isr(int irq, void *dev_id) { struct controller *ctrl = (struct controller *)dev_id; - struct php_ctlr_state_s *php_ctlr = ctrl->hpc_ctlr_handle; u32 serr_int, slot_reg, intr_loc, intr_loc2; int hp_slot; @@ -942,20 +885,16 @@ static irqreturn_t shpc_isr(int irq, void *dev_id) __FUNCTION__, hp_slot, slot_reg); if (slot_reg & MRL_CHANGE_DETECTED) - php_ctlr->switch_change_callback( - hp_slot, php_ctlr->callback_instance_id); + shpchp_handle_switch_change(hp_slot, ctrl); if (slot_reg & BUTTON_PRESS_DETECTED) - php_ctlr->attention_button_callback( - hp_slot, php_ctlr->callback_instance_id); + shpchp_handle_attention_button(hp_slot, ctrl); if (slot_reg & PRSNT_CHANGE_DETECTED) - php_ctlr->presence_change_callback( - hp_slot , php_ctlr->callback_instance_id); + shpchp_handle_presence_change(hp_slot, ctrl); if (slot_reg & (ISO_PFAULT_DETECTED | CON_PFAULT_DETECTED)) - php_ctlr->power_fault_callback( - hp_slot, php_ctlr->callback_instance_id); + shpchp_handle_power_fault(hp_slot, ctrl); /* Clear all slot events */ slot_reg &= ~SLOT_REG_RSVDZ_MASK; @@ -1114,10 +1053,8 @@ static struct hpc_ops shpchp_hpc_ops = { .release_ctlr = hpc_release_ctlr, }; -int shpc_init(struct controller * ctrl, struct pci_dev * pdev) +int shpc_init(struct controller *ctrl, struct pci_dev *pdev) { - struct php_ctlr_state_s *php_ctlr, *p; - void *instance_id = ctrl; int rc = -1, num_slots = 0; u8 hp_slot; u32 shpc_base_offset; @@ -1128,16 +1065,6 @@ int shpc_init(struct controller * ctrl, struct pci_dev * pdev) ctrl->pci_dev = pdev; /* pci_dev of the P2P bridge */ - spin_lock_init(&list_lock); - php_ctlr = kzalloc(sizeof(*php_ctlr), GFP_KERNEL); - - if (!php_ctlr) { /* allocate controller state data */ - err("%s: HPC controller memory allocation error!\n", __FUNCTION__); - goto abort; - } - - php_ctlr->pci_dev = pdev; /* save pci_dev in context */ - if ((pdev->vendor == PCI_VENDOR_ID_AMD) || (pdev->device == PCI_DEVICE_ID_AMD_GOLAM_7450)) { /* amd shpc driver doesn't use Base Offset; assume 0 */ @@ -1147,20 +1074,20 @@ int shpc_init(struct controller * ctrl, struct pci_dev * pdev) ctrl->cap_offset = pci_find_capability(pdev, PCI_CAP_ID_SHPC); if (!ctrl->cap_offset) { err("%s : cap_offset == 0\n", __FUNCTION__); - goto abort_free_ctlr; + goto abort; } dbg("%s: cap_offset = %x\n", __FUNCTION__, ctrl->cap_offset); rc = shpc_indirect_read(ctrl, 0, &shpc_base_offset); if (rc) { err("%s: cannot read base_offset\n", __FUNCTION__); - goto abort_free_ctlr; + goto abort; } rc = shpc_indirect_read(ctrl, 3, &tempdword); if (rc) { err("%s: cannot read slot config\n", __FUNCTION__); - goto abort_free_ctlr; + goto abort; } num_slots = tempdword & SLOT_NUM; dbg("%s: num_slots (indirect) %x\n", __FUNCTION__, num_slots); @@ -1170,7 +1097,7 @@ int shpc_init(struct controller * ctrl, struct pci_dev * pdev) if (rc) { err("%s: cannot read creg (index = %d)\n", __FUNCTION__, i); - goto abort_free_ctlr; + goto abort; } dbg("%s: offset %d: value %x\n", __FUNCTION__,i, tempdword); @@ -1187,24 +1114,24 @@ int shpc_init(struct controller * ctrl, struct pci_dev * pdev) rc = pci_enable_device(pdev); if (rc) { err("%s: pci_enable_device failed\n", __FUNCTION__); - goto abort_free_ctlr; + goto abort; } if (!request_mem_region(ctrl->mmio_base, ctrl->mmio_size, MY_NAME)) { err("%s: cannot reserve MMIO region\n", __FUNCTION__); rc = -1; - goto abort_free_ctlr; + goto abort; } - php_ctlr->creg = ioremap(ctrl->mmio_base, ctrl->mmio_size); - if (!php_ctlr->creg) { + ctrl->creg = ioremap(ctrl->mmio_base, ctrl->mmio_size); + if (!ctrl->creg) { err("%s: cannot remap MMIO region %lx @ %lx\n", __FUNCTION__, ctrl->mmio_size, ctrl->mmio_base); release_mem_region(ctrl->mmio_base, ctrl->mmio_size); rc = -1; - goto abort_free_ctlr; + goto abort; } - dbg("%s: php_ctlr->creg %p\n", __FUNCTION__, php_ctlr->creg); + dbg("%s: ctrl->creg %p\n", __FUNCTION__, ctrl->creg); mutex_init(&ctrl->crit_sect); mutex_init(&ctrl->cmd_lock); @@ -1212,23 +1139,14 @@ int shpc_init(struct controller * ctrl, struct pci_dev * pdev) /* Setup wait queue */ init_waitqueue_head(&ctrl->queue); - /* Find the IRQ */ - php_ctlr->irq = pdev->irq; - php_ctlr->attention_button_callback = shpchp_handle_attention_button, - php_ctlr->switch_change_callback = shpchp_handle_switch_change; - php_ctlr->presence_change_callback = shpchp_handle_presence_change; - php_ctlr->power_fault_callback = shpchp_handle_power_fault; - php_ctlr->callback_instance_id = instance_id; - - ctrl->hpc_ctlr_handle = php_ctlr; ctrl->hpc_ops = &shpchp_hpc_ops; /* Return PCI Controller Info */ slot_config = shpc_readl(ctrl, SLOT_CONFIG); - php_ctlr->slot_device_offset = (slot_config & FIRST_DEV_NUM) >> 8; - php_ctlr->num_slots = slot_config & SLOT_NUM; - dbg("%s: slot_device_offset %x\n", __FUNCTION__, php_ctlr->slot_device_offset); - dbg("%s: num_slots %x\n", __FUNCTION__, php_ctlr->num_slots); + ctrl->slot_device_offset = (slot_config & FIRST_DEV_NUM) >> 8; + ctrl->num_slots = slot_config & SLOT_NUM; + ctrl->first_slot = (slot_config & PSN) >> 16; + ctrl->slot_num_inc = ((slot_config & UPDOWN) >> 29) ? 1 : -1; /* Mask Global Interrupt Mask & Command Complete Interrupt Mask */ tempdword = shpc_readl(ctrl, SERR_INTR_ENABLE); @@ -1243,7 +1161,7 @@ int shpc_init(struct controller * ctrl, struct pci_dev * pdev) /* Mask the MRL sensor SERR Mask of individual slot in * Slot SERR-INT Mask & clear all the existing event if any */ - for (hp_slot = 0; hp_slot < php_ctlr->num_slots; hp_slot++) { + for (hp_slot = 0; hp_slot < ctrl->num_slots; hp_slot++) { slot_reg = shpc_readl(ctrl, SLOT_REG(hp_slot)); dbg("%s: Default Logical Slot Register %d value %x\n", __FUNCTION__, hp_slot, slot_reg); @@ -1255,24 +1173,27 @@ int shpc_init(struct controller * ctrl, struct pci_dev * pdev) shpc_writel(ctrl, SLOT_REG(hp_slot), slot_reg); } - if (shpchp_poll_mode) {/* Install interrupt polling code */ - /* Install and start the interrupt polling timer */ - init_timer(&php_ctlr->int_poll_timer); - start_int_poll_timer( php_ctlr, 10 ); /* start with 10 second delay */ + if (shpchp_poll_mode) { + /* Install interrupt polling timer. Start with 10 sec delay */ + init_timer(&ctrl->poll_timer); + start_int_poll_timer(ctrl, 10); } else { /* Installs the interrupt handler */ rc = pci_enable_msi(pdev); if (rc) { info("Can't get msi for the hotplug controller\n"); info("Use INTx for the hotplug controller\n"); - } else - php_ctlr->irq = pdev->irq; + } - rc = request_irq(php_ctlr->irq, shpc_isr, IRQF_SHARED, MY_NAME, (void *) ctrl); - dbg("%s: request_irq %d for hpc%d (returns %d)\n", __FUNCTION__, php_ctlr->irq, ctlr_seq_num, rc); + rc = request_irq(ctrl->pci_dev->irq, shpc_isr, IRQF_SHARED, + MY_NAME, (void *)ctrl); + dbg("%s: request_irq %d for hpc%d (returns %d)\n", + __FUNCTION__, ctrl->pci_dev->irq, + atomic_read(&shpchp_num_controllers), rc); if (rc) { - err("Can't get irq %d for the hotplug controller\n", php_ctlr->irq); - goto abort_free_ctlr; + err("Can't get irq %d for the hotplug controller\n", + ctrl->pci_dev->irq); + goto abort_iounmap; } } dbg("%s: HPC at b:d:f:irq=0x%x:%x:%x:%x\n", __FUNCTION__, @@ -1280,24 +1201,6 @@ int shpc_init(struct controller * ctrl, struct pci_dev * pdev) PCI_FUNC(pdev->devfn), pdev->irq); get_hp_hw_control_from_firmware(pdev); - /* Add this HPC instance into the HPC list */ - spin_lock(&list_lock); - if (php_ctlr_list_head == 0) { - php_ctlr_list_head = php_ctlr; - p = php_ctlr_list_head; - p->pnext = NULL; - } else { - p = php_ctlr_list_head; - - while (p->pnext) - p = p->pnext; - - p->pnext = php_ctlr; - } - spin_unlock(&list_lock); - - ctlr_seq_num++; - /* * If this is the first controller to be initialized, * initialize the shpchpd work queue @@ -1306,14 +1209,14 @@ int shpc_init(struct controller * ctrl, struct pci_dev * pdev) shpchp_wq = create_singlethread_workqueue("shpchpd"); if (!shpchp_wq) { rc = -ENOMEM; - goto abort_free_ctlr; + goto abort_iounmap; } } /* * Unmask all event interrupts of all slots */ - for (hp_slot = 0; hp_slot < php_ctlr->num_slots; hp_slot++) { + for (hp_slot = 0; hp_slot < ctrl->num_slots; hp_slot++) { slot_reg = shpc_readl(ctrl, SLOT_REG(hp_slot)); dbg("%s: Default Logical Slot Register %d value %x\n", __FUNCTION__, hp_slot, slot_reg); @@ -1336,10 +1239,8 @@ int shpc_init(struct controller * ctrl, struct pci_dev * pdev) return 0; /* We end up here for the many possible ways to fail this API. */ -abort_free_ctlr: - if (php_ctlr->creg) - iounmap(php_ctlr->creg); - kfree(php_ctlr); +abort_iounmap: + iounmap(ctrl->creg); abort: DBG_LEAVE_ROUTINE return rc; |