Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0+ */
0002 /*
0003  * Compaq Hot Plug Controller Driver
0004  *
0005  * Copyright (C) 1995,2001 Compaq Computer Corporation
0006  * Copyright (C) 2001 Greg Kroah-Hartman (greg@kroah.com)
0007  * Copyright (C) 2001 IBM
0008  *
0009  * All rights reserved.
0010  *
0011  * Send feedback to <greg@kroah.com>
0012  *
0013  */
0014 #ifndef _CPQPHP_H
0015 #define _CPQPHP_H
0016 
0017 #include <linux/interrupt.h>
0018 #include <linux/io.h>       /* for read? and write? functions */
0019 #include <linux/delay.h>    /* for delays */
0020 #include <linux/mutex.h>
0021 #include <linux/sched/signal.h> /* for signal_pending() */
0022 
0023 #define MY_NAME "cpqphp"
0024 
0025 #define dbg(fmt, arg...) do { if (cpqhp_debug) printk(KERN_DEBUG "%s: " fmt, MY_NAME, ## arg); } while (0)
0026 #define err(format, arg...) printk(KERN_ERR "%s: " format, MY_NAME, ## arg)
0027 #define info(format, arg...) printk(KERN_INFO "%s: " format, MY_NAME, ## arg)
0028 #define warn(format, arg...) printk(KERN_WARNING "%s: " format, MY_NAME, ## arg)
0029 
0030 
0031 
0032 struct smbios_system_slot {
0033     u8 type;
0034     u8 length;
0035     u16 handle;
0036     u8 name_string_num;
0037     u8 slot_type;
0038     u8 slot_width;
0039     u8 slot_current_usage;
0040     u8 slot_length;
0041     u16 slot_number;
0042     u8 properties1;
0043     u8 properties2;
0044 } __attribute__ ((packed));
0045 
0046 /* offsets to the smbios generic type based on the above structure layout */
0047 enum smbios_system_slot_offsets {
0048     SMBIOS_SLOT_GENERIC_TYPE =  offsetof(struct smbios_system_slot, type),
0049     SMBIOS_SLOT_GENERIC_LENGTH =    offsetof(struct smbios_system_slot, length),
0050     SMBIOS_SLOT_GENERIC_HANDLE =    offsetof(struct smbios_system_slot, handle),
0051     SMBIOS_SLOT_NAME_STRING_NUM =   offsetof(struct smbios_system_slot, name_string_num),
0052     SMBIOS_SLOT_TYPE =      offsetof(struct smbios_system_slot, slot_type),
0053     SMBIOS_SLOT_WIDTH =     offsetof(struct smbios_system_slot, slot_width),
0054     SMBIOS_SLOT_CURRENT_USAGE = offsetof(struct smbios_system_slot, slot_current_usage),
0055     SMBIOS_SLOT_LENGTH =        offsetof(struct smbios_system_slot, slot_length),
0056     SMBIOS_SLOT_NUMBER =        offsetof(struct smbios_system_slot, slot_number),
0057     SMBIOS_SLOT_PROPERTIES1 =   offsetof(struct smbios_system_slot, properties1),
0058     SMBIOS_SLOT_PROPERTIES2 =   offsetof(struct smbios_system_slot, properties2),
0059 };
0060 
0061 struct smbios_generic {
0062     u8 type;
0063     u8 length;
0064     u16 handle;
0065 } __attribute__ ((packed));
0066 
0067 /* offsets to the smbios generic type based on the above structure layout */
0068 enum smbios_generic_offsets {
0069     SMBIOS_GENERIC_TYPE =   offsetof(struct smbios_generic, type),
0070     SMBIOS_GENERIC_LENGTH = offsetof(struct smbios_generic, length),
0071     SMBIOS_GENERIC_HANDLE = offsetof(struct smbios_generic, handle),
0072 };
0073 
0074 struct smbios_entry_point {
0075     char anchor[4];
0076     u8 ep_checksum;
0077     u8 ep_length;
0078     u8 major_version;
0079     u8 minor_version;
0080     u16 max_size_entry;
0081     u8 ep_rev;
0082     u8 reserved[5];
0083     char int_anchor[5];
0084     u8 int_checksum;
0085     u16 st_length;
0086     u32 st_address;
0087     u16 number_of_entrys;
0088     u8 bcd_rev;
0089 } __attribute__ ((packed));
0090 
0091 /* offsets to the smbios entry point based on the above structure layout */
0092 enum smbios_entry_point_offsets {
0093     ANCHOR =        offsetof(struct smbios_entry_point, anchor[0]),
0094     EP_CHECKSUM =       offsetof(struct smbios_entry_point, ep_checksum),
0095     EP_LENGTH =     offsetof(struct smbios_entry_point, ep_length),
0096     MAJOR_VERSION =     offsetof(struct smbios_entry_point, major_version),
0097     MINOR_VERSION =     offsetof(struct smbios_entry_point, minor_version),
0098     MAX_SIZE_ENTRY =    offsetof(struct smbios_entry_point, max_size_entry),
0099     EP_REV =        offsetof(struct smbios_entry_point, ep_rev),
0100     INT_ANCHOR =        offsetof(struct smbios_entry_point, int_anchor[0]),
0101     INT_CHECKSUM =      offsetof(struct smbios_entry_point, int_checksum),
0102     ST_LENGTH =     offsetof(struct smbios_entry_point, st_length),
0103     ST_ADDRESS =        offsetof(struct smbios_entry_point, st_address),
0104     NUMBER_OF_ENTRYS =  offsetof(struct smbios_entry_point, number_of_entrys),
0105     BCD_REV =       offsetof(struct smbios_entry_point, bcd_rev),
0106 };
0107 
0108 struct ctrl_reg {           /* offset */
0109     u8  slot_RST;       /* 0x00 */
0110     u8  slot_enable;        /* 0x01 */
0111     u16 misc;           /* 0x02 */
0112     u32 led_control;        /* 0x04 */
0113     u32 int_input_clear;    /* 0x08 */
0114     u32 int_mask;       /* 0x0a */
0115     u8  reserved0;      /* 0x10 */
0116     u8  reserved1;      /* 0x11 */
0117     u8  reserved2;      /* 0x12 */
0118     u8  gen_output_AB;      /* 0x13 */
0119     u32 non_int_input;      /* 0x14 */
0120     u32 reserved3;      /* 0x18 */
0121     u32 reserved4;      /* 0x1a */
0122     u32 reserved5;      /* 0x20 */
0123     u8  reserved6;      /* 0x24 */
0124     u8  reserved7;      /* 0x25 */
0125     u16 reserved8;      /* 0x26 */
0126     u8  slot_mask;      /* 0x28 */
0127     u8  reserved9;      /* 0x29 */
0128     u8  reserved10;     /* 0x2a */
0129     u8  reserved11;     /* 0x2b */
0130     u8  slot_SERR;      /* 0x2c */
0131     u8  slot_power;     /* 0x2d */
0132     u8  reserved12;     /* 0x2e */
0133     u8  reserved13;     /* 0x2f */
0134     u8  next_curr_freq;     /* 0x30 */
0135     u8  reset_freq_mode;    /* 0x31 */
0136 } __attribute__ ((packed));
0137 
0138 /* offsets to the controller registers based on the above structure layout */
0139 enum ctrl_offsets {
0140     SLOT_RST =      offsetof(struct ctrl_reg, slot_RST),
0141     SLOT_ENABLE =       offsetof(struct ctrl_reg, slot_enable),
0142     MISC =          offsetof(struct ctrl_reg, misc),
0143     LED_CONTROL =       offsetof(struct ctrl_reg, led_control),
0144     INT_INPUT_CLEAR =   offsetof(struct ctrl_reg, int_input_clear),
0145     INT_MASK =      offsetof(struct ctrl_reg, int_mask),
0146     CTRL_RESERVED0 =    offsetof(struct ctrl_reg, reserved0),
0147     CTRL_RESERVED1 =    offsetof(struct ctrl_reg, reserved1),
0148     CTRL_RESERVED2 =    offsetof(struct ctrl_reg, reserved1),
0149     GEN_OUTPUT_AB =     offsetof(struct ctrl_reg, gen_output_AB),
0150     NON_INT_INPUT =     offsetof(struct ctrl_reg, non_int_input),
0151     CTRL_RESERVED3 =    offsetof(struct ctrl_reg, reserved3),
0152     CTRL_RESERVED4 =    offsetof(struct ctrl_reg, reserved4),
0153     CTRL_RESERVED5 =    offsetof(struct ctrl_reg, reserved5),
0154     CTRL_RESERVED6 =    offsetof(struct ctrl_reg, reserved6),
0155     CTRL_RESERVED7 =    offsetof(struct ctrl_reg, reserved7),
0156     CTRL_RESERVED8 =    offsetof(struct ctrl_reg, reserved8),
0157     SLOT_MASK =     offsetof(struct ctrl_reg, slot_mask),
0158     CTRL_RESERVED9 =    offsetof(struct ctrl_reg, reserved9),
0159     CTRL_RESERVED10 =   offsetof(struct ctrl_reg, reserved10),
0160     CTRL_RESERVED11 =   offsetof(struct ctrl_reg, reserved11),
0161     SLOT_SERR =     offsetof(struct ctrl_reg, slot_SERR),
0162     SLOT_POWER =        offsetof(struct ctrl_reg, slot_power),
0163     NEXT_CURR_FREQ =    offsetof(struct ctrl_reg, next_curr_freq),
0164     RESET_FREQ_MODE =   offsetof(struct ctrl_reg, reset_freq_mode),
0165 };
0166 
0167 struct hrt {
0168     char sig0;
0169     char sig1;
0170     char sig2;
0171     char sig3;
0172     u16 unused_IRQ;
0173     u16 PCIIRQ;
0174     u8 number_of_entries;
0175     u8 revision;
0176     u16 reserved1;
0177     u32 reserved2;
0178 } __attribute__ ((packed));
0179 
0180 /* offsets to the hotplug resource table registers based on the above
0181  * structure layout
0182  */
0183 enum hrt_offsets {
0184     SIG0 =          offsetof(struct hrt, sig0),
0185     SIG1 =          offsetof(struct hrt, sig1),
0186     SIG2 =          offsetof(struct hrt, sig2),
0187     SIG3 =          offsetof(struct hrt, sig3),
0188     UNUSED_IRQ =        offsetof(struct hrt, unused_IRQ),
0189     PCIIRQ =        offsetof(struct hrt, PCIIRQ),
0190     NUMBER_OF_ENTRIES = offsetof(struct hrt, number_of_entries),
0191     REVISION =      offsetof(struct hrt, revision),
0192     HRT_RESERVED1 =     offsetof(struct hrt, reserved1),
0193     HRT_RESERVED2 =     offsetof(struct hrt, reserved2),
0194 };
0195 
0196 struct slot_rt {
0197     u8 dev_func;
0198     u8 primary_bus;
0199     u8 secondary_bus;
0200     u8 max_bus;
0201     u16 io_base;
0202     u16 io_length;
0203     u16 mem_base;
0204     u16 mem_length;
0205     u16 pre_mem_base;
0206     u16 pre_mem_length;
0207 } __attribute__ ((packed));
0208 
0209 /* offsets to the hotplug slot resource table registers based on the above
0210  * structure layout
0211  */
0212 enum slot_rt_offsets {
0213     DEV_FUNC =      offsetof(struct slot_rt, dev_func),
0214     PRIMARY_BUS =       offsetof(struct slot_rt, primary_bus),
0215     SECONDARY_BUS =     offsetof(struct slot_rt, secondary_bus),
0216     MAX_BUS =       offsetof(struct slot_rt, max_bus),
0217     IO_BASE =       offsetof(struct slot_rt, io_base),
0218     IO_LENGTH =     offsetof(struct slot_rt, io_length),
0219     MEM_BASE =      offsetof(struct slot_rt, mem_base),
0220     MEM_LENGTH =        offsetof(struct slot_rt, mem_length),
0221     PRE_MEM_BASE =      offsetof(struct slot_rt, pre_mem_base),
0222     PRE_MEM_LENGTH =    offsetof(struct slot_rt, pre_mem_length),
0223 };
0224 
0225 struct pci_func {
0226     struct pci_func *next;
0227     u8 bus;
0228     u8 device;
0229     u8 function;
0230     u8 is_a_board;
0231     u16 status;
0232     u8 configured;
0233     u8 switch_save;
0234     u8 presence_save;
0235     u32 base_length[0x06];
0236     u8 base_type[0x06];
0237     u16 reserved2;
0238     u32 config_space[0x20];
0239     struct pci_resource *mem_head;
0240     struct pci_resource *p_mem_head;
0241     struct pci_resource *io_head;
0242     struct pci_resource *bus_head;
0243     struct timer_list *p_task_event;
0244     struct pci_dev *pci_dev;
0245 };
0246 
0247 struct slot {
0248     struct slot *next;
0249     u8 bus;
0250     u8 device;
0251     u8 number;
0252     u8 is_a_board;
0253     u8 configured;
0254     u8 state;
0255     u8 switch_save;
0256     u8 presence_save;
0257     u32 capabilities;
0258     u16 reserved2;
0259     struct timer_list task_event;
0260     u8 hp_slot;
0261     struct controller *ctrl;
0262     void __iomem *p_sm_slot;
0263     struct hotplug_slot hotplug_slot;
0264 };
0265 
0266 struct pci_resource {
0267     struct pci_resource *next;
0268     u32 base;
0269     u32 length;
0270 };
0271 
0272 struct event_info {
0273     u32 event_type;
0274     u8 hp_slot;
0275 };
0276 
0277 struct controller {
0278     struct controller *next;
0279     u32 ctrl_int_comp;
0280     struct mutex crit_sect; /* critical section mutex */
0281     void __iomem *hpc_reg;  /* cookie for our pci controller location */
0282     struct pci_resource *mem_head;
0283     struct pci_resource *p_mem_head;
0284     struct pci_resource *io_head;
0285     struct pci_resource *bus_head;
0286     struct pci_dev *pci_dev;
0287     struct pci_bus *pci_bus;
0288     struct event_info event_queue[10];
0289     struct slot *slot;
0290     u8 next_event;
0291     u8 interrupt;
0292     u8 cfgspc_irq;
0293     u8 bus;         /* bus number for the pci hotplug controller */
0294     u8 rev;
0295     u8 slot_device_offset;
0296     u8 first_slot;
0297     u8 add_support;
0298     u8 push_flag;
0299     u8 push_button;         /* 0 = no pushbutton, 1 = pushbutton present */
0300     u8 slot_switch_type;        /* 0 = no switch, 1 = switch present */
0301     u8 defeature_PHP;       /* 0 = PHP not supported, 1 = PHP supported */
0302     u8 alternate_base_address;  /* 0 = not supported, 1 = supported */
0303     u8 pci_config_space;        /* Index/data access to working registers 0 = not supported, 1 = supported */
0304     u8 pcix_speed_capability;   /* PCI-X */
0305     u8 pcix_support;        /* PCI-X */
0306     u16 vendor_id;
0307     struct work_struct int_task_event;
0308     wait_queue_head_t queue;    /* sleep & wake process */
0309     struct dentry *dentry;      /* debugfs dentry */
0310 };
0311 
0312 struct irq_mapping {
0313     u8 barber_pole;
0314     u8 valid_INT;
0315     u8 interrupt[4];
0316 };
0317 
0318 struct resource_lists {
0319     struct pci_resource *mem_head;
0320     struct pci_resource *p_mem_head;
0321     struct pci_resource *io_head;
0322     struct pci_resource *bus_head;
0323     struct irq_mapping *irqs;
0324 };
0325 
0326 #define ROM_PHY_ADDR            0x0F0000
0327 #define ROM_PHY_LEN         0x00ffff
0328 
0329 #define PCI_HPC_ID          0xA0F7
0330 #define PCI_SUB_HPC_ID          0xA2F7
0331 #define PCI_SUB_HPC_ID2         0xA2F8
0332 #define PCI_SUB_HPC_ID3         0xA2F9
0333 #define PCI_SUB_HPC_ID_INTC     0xA2FA
0334 #define PCI_SUB_HPC_ID4         0xA2FD
0335 
0336 #define INT_BUTTON_IGNORE       0
0337 #define INT_PRESENCE_ON         1
0338 #define INT_PRESENCE_OFF        2
0339 #define INT_SWITCH_CLOSE        3
0340 #define INT_SWITCH_OPEN         4
0341 #define INT_POWER_FAULT         5
0342 #define INT_POWER_FAULT_CLEAR       6
0343 #define INT_BUTTON_PRESS        7
0344 #define INT_BUTTON_RELEASE      8
0345 #define INT_BUTTON_CANCEL       9
0346 
0347 #define STATIC_STATE            0
0348 #define BLINKINGON_STATE        1
0349 #define BLINKINGOFF_STATE       2
0350 #define POWERON_STATE           3
0351 #define POWEROFF_STATE          4
0352 
0353 #define PCISLOT_INTERLOCK_CLOSED    0x00000001
0354 #define PCISLOT_ADAPTER_PRESENT     0x00000002
0355 #define PCISLOT_POWERED         0x00000004
0356 #define PCISLOT_66_MHZ_OPERATION    0x00000008
0357 #define PCISLOT_64_BIT_OPERATION    0x00000010
0358 #define PCISLOT_REPLACE_SUPPORTED   0x00000020
0359 #define PCISLOT_ADD_SUPPORTED       0x00000040
0360 #define PCISLOT_INTERLOCK_SUPPORTED 0x00000080
0361 #define PCISLOT_66_MHZ_SUPPORTED    0x00000100
0362 #define PCISLOT_64_BIT_SUPPORTED    0x00000200
0363 
0364 #define PCI_TO_PCI_BRIDGE_CLASS     0x00060400
0365 
0366 #define INTERLOCK_OPEN          0x00000002
0367 #define ADD_NOT_SUPPORTED       0x00000003
0368 #define CARD_FUNCTIONING        0x00000005
0369 #define ADAPTER_NOT_SAME        0x00000006
0370 #define NO_ADAPTER_PRESENT      0x00000009
0371 #define NOT_ENOUGH_RESOURCES        0x0000000B
0372 #define DEVICE_TYPE_NOT_SUPPORTED   0x0000000C
0373 #define POWER_FAILURE           0x0000000E
0374 
0375 #define REMOVE_NOT_SUPPORTED        0x00000003
0376 
0377 
0378 /*
0379  * error Messages
0380  */
0381 #define msg_initialization_err  "Initialization failure, error=%d\n"
0382 #define msg_HPC_rev_error   "Unsupported revision of the PCI hot plug controller found.\n"
0383 #define msg_HPC_non_compaq_or_intel "The PCI hot plug controller is not supported by this driver.\n"
0384 #define msg_HPC_not_supported   "this system is not supported by this version of cpqphpd. Upgrade to a newer version of cpqphpd\n"
0385 #define msg_unable_to_save  "unable to store PCI hot plug add resource information. This system must be rebooted before adding any PCI devices.\n"
0386 #define msg_button_on       "PCI slot #%d - powering on due to button press.\n"
0387 #define msg_button_off      "PCI slot #%d - powering off due to button press.\n"
0388 #define msg_button_cancel   "PCI slot #%d - action canceled due to button press.\n"
0389 #define msg_button_ignore   "PCI slot #%d - button press ignored.  (action in progress...)\n"
0390 
0391 
0392 /* debugfs functions for the hotplug controller info */
0393 void cpqhp_initialize_debugfs(void);
0394 void cpqhp_shutdown_debugfs(void);
0395 void cpqhp_create_debugfs_files(struct controller *ctrl);
0396 void cpqhp_remove_debugfs_files(struct controller *ctrl);
0397 
0398 /* controller functions */
0399 void cpqhp_pushbutton_thread(struct timer_list *t);
0400 irqreturn_t cpqhp_ctrl_intr(int IRQ, void *data);
0401 int cpqhp_find_available_resources(struct controller *ctrl,
0402                    void __iomem *rom_start);
0403 int cpqhp_event_start_thread(void);
0404 void cpqhp_event_stop_thread(void);
0405 struct pci_func *cpqhp_slot_create(unsigned char busnumber);
0406 struct pci_func *cpqhp_slot_find(unsigned char bus, unsigned char device,
0407                  unsigned char index);
0408 int cpqhp_process_SI(struct controller *ctrl, struct pci_func *func);
0409 int cpqhp_process_SS(struct controller *ctrl, struct pci_func *func);
0410 int cpqhp_hardware_test(struct controller *ctrl, int test_num);
0411 
0412 /* resource functions */
0413 int cpqhp_resource_sort_and_combine(struct pci_resource **head);
0414 
0415 /* pci functions */
0416 int cpqhp_set_irq(u8 bus_num, u8 dev_num, u8 int_pin, u8 irq_num);
0417 int cpqhp_get_bus_dev(struct controller *ctrl, u8 *bus_num, u8 *dev_num,
0418               u8 slot);
0419 int cpqhp_save_config(struct controller *ctrl, int busnumber, int is_hot_plug);
0420 int cpqhp_save_base_addr_length(struct controller *ctrl, struct pci_func *func);
0421 int cpqhp_save_used_resources(struct controller *ctrl, struct pci_func *func);
0422 int cpqhp_configure_board(struct controller *ctrl, struct pci_func *func);
0423 int cpqhp_save_slot_config(struct controller *ctrl, struct pci_func *new_slot);
0424 int cpqhp_valid_replace(struct controller *ctrl, struct pci_func *func);
0425 void cpqhp_destroy_board_resources(struct pci_func *func);
0426 int cpqhp_return_board_resources(struct pci_func *func,
0427                  struct resource_lists *resources);
0428 void cpqhp_destroy_resource_list(struct resource_lists *resources);
0429 int cpqhp_configure_device(struct controller *ctrl, struct pci_func *func);
0430 int cpqhp_unconfigure_device(struct pci_func *func);
0431 
0432 /* Global variables */
0433 extern int cpqhp_debug;
0434 extern int cpqhp_legacy_mode;
0435 extern struct controller *cpqhp_ctrl_list;
0436 extern struct pci_func *cpqhp_slot_list[256];
0437 extern struct irq_routing_table *cpqhp_routing_table;
0438 
0439 /* these can be gotten rid of, but for debugging they are purty */
0440 extern u8 cpqhp_nic_irq;
0441 extern u8 cpqhp_disk_irq;
0442 
0443 
0444 /* inline functions */
0445 
0446 static inline const char *slot_name(struct slot *slot)
0447 {
0448     return hotplug_slot_name(&slot->hotplug_slot);
0449 }
0450 
0451 static inline struct slot *to_slot(struct hotplug_slot *hotplug_slot)
0452 {
0453     return container_of(hotplug_slot, struct slot, hotplug_slot);
0454 }
0455 
0456 /*
0457  * return_resource
0458  *
0459  * Puts node back in the resource list pointed to by head
0460  */
0461 static inline void return_resource(struct pci_resource **head,
0462                    struct pci_resource *node)
0463 {
0464     if (!node || !head)
0465         return;
0466     node->next = *head;
0467     *head = node;
0468 }
0469 
0470 static inline void set_SOGO(struct controller *ctrl)
0471 {
0472     u16 misc;
0473 
0474     misc = readw(ctrl->hpc_reg + MISC);
0475     misc = (misc | 0x0001) & 0xFFFB;
0476     writew(misc, ctrl->hpc_reg + MISC);
0477 }
0478 
0479 
0480 static inline void amber_LED_on(struct controller *ctrl, u8 slot)
0481 {
0482     u32 led_control;
0483 
0484     led_control = readl(ctrl->hpc_reg + LED_CONTROL);
0485     led_control |= (0x01010000L << slot);
0486     writel(led_control, ctrl->hpc_reg + LED_CONTROL);
0487 }
0488 
0489 
0490 static inline void amber_LED_off(struct controller *ctrl, u8 slot)
0491 {
0492     u32 led_control;
0493 
0494     led_control = readl(ctrl->hpc_reg + LED_CONTROL);
0495     led_control &= ~(0x01010000L << slot);
0496     writel(led_control, ctrl->hpc_reg + LED_CONTROL);
0497 }
0498 
0499 
0500 static inline int read_amber_LED(struct controller *ctrl, u8 slot)
0501 {
0502     u32 led_control;
0503 
0504     led_control = readl(ctrl->hpc_reg + LED_CONTROL);
0505     led_control &= (0x01010000L << slot);
0506 
0507     return led_control ? 1 : 0;
0508 }
0509 
0510 
0511 static inline void green_LED_on(struct controller *ctrl, u8 slot)
0512 {
0513     u32 led_control;
0514 
0515     led_control = readl(ctrl->hpc_reg + LED_CONTROL);
0516     led_control |= 0x0101L << slot;
0517     writel(led_control, ctrl->hpc_reg + LED_CONTROL);
0518 }
0519 
0520 static inline void green_LED_off(struct controller *ctrl, u8 slot)
0521 {
0522     u32 led_control;
0523 
0524     led_control = readl(ctrl->hpc_reg + LED_CONTROL);
0525     led_control &= ~(0x0101L << slot);
0526     writel(led_control, ctrl->hpc_reg + LED_CONTROL);
0527 }
0528 
0529 
0530 static inline void green_LED_blink(struct controller *ctrl, u8 slot)
0531 {
0532     u32 led_control;
0533 
0534     led_control = readl(ctrl->hpc_reg + LED_CONTROL);
0535     led_control &= ~(0x0101L << slot);
0536     led_control |= (0x0001L << slot);
0537     writel(led_control, ctrl->hpc_reg + LED_CONTROL);
0538 }
0539 
0540 
0541 static inline void slot_disable(struct controller *ctrl, u8 slot)
0542 {
0543     u8 slot_enable;
0544 
0545     slot_enable = readb(ctrl->hpc_reg + SLOT_ENABLE);
0546     slot_enable &= ~(0x01 << slot);
0547     writeb(slot_enable, ctrl->hpc_reg + SLOT_ENABLE);
0548 }
0549 
0550 
0551 static inline void slot_enable(struct controller *ctrl, u8 slot)
0552 {
0553     u8 slot_enable;
0554 
0555     slot_enable = readb(ctrl->hpc_reg + SLOT_ENABLE);
0556     slot_enable |= (0x01 << slot);
0557     writeb(slot_enable, ctrl->hpc_reg + SLOT_ENABLE);
0558 }
0559 
0560 
0561 static inline u8 is_slot_enabled(struct controller *ctrl, u8 slot)
0562 {
0563     u8 slot_enable;
0564 
0565     slot_enable = readb(ctrl->hpc_reg + SLOT_ENABLE);
0566     slot_enable &= (0x01 << slot);
0567     return slot_enable ? 1 : 0;
0568 }
0569 
0570 
0571 static inline u8 read_slot_enable(struct controller *ctrl)
0572 {
0573     return readb(ctrl->hpc_reg + SLOT_ENABLE);
0574 }
0575 
0576 
0577 /**
0578  * get_controller_speed - find the current frequency/mode of controller.
0579  *
0580  * @ctrl: controller to get frequency/mode for.
0581  *
0582  * Returns controller speed.
0583  */
0584 static inline u8 get_controller_speed(struct controller *ctrl)
0585 {
0586     u8 curr_freq;
0587     u16 misc;
0588 
0589     if (ctrl->pcix_support) {
0590         curr_freq = readb(ctrl->hpc_reg + NEXT_CURR_FREQ);
0591         if ((curr_freq & 0xB0) == 0xB0)
0592             return PCI_SPEED_133MHz_PCIX;
0593         if ((curr_freq & 0xA0) == 0xA0)
0594             return PCI_SPEED_100MHz_PCIX;
0595         if ((curr_freq & 0x90) == 0x90)
0596             return PCI_SPEED_66MHz_PCIX;
0597         if (curr_freq & 0x10)
0598             return PCI_SPEED_66MHz;
0599 
0600         return PCI_SPEED_33MHz;
0601     }
0602 
0603     misc = readw(ctrl->hpc_reg + MISC);
0604     return (misc & 0x0800) ? PCI_SPEED_66MHz : PCI_SPEED_33MHz;
0605 }
0606 
0607 
0608 /**
0609  * get_adapter_speed - find the max supported frequency/mode of adapter.
0610  *
0611  * @ctrl: hotplug controller.
0612  * @hp_slot: hotplug slot where adapter is installed.
0613  *
0614  * Returns adapter speed.
0615  */
0616 static inline u8 get_adapter_speed(struct controller *ctrl, u8 hp_slot)
0617 {
0618     u32 temp_dword = readl(ctrl->hpc_reg + NON_INT_INPUT);
0619     dbg("slot: %d, PCIXCAP: %8x\n", hp_slot, temp_dword);
0620     if (ctrl->pcix_support) {
0621         if (temp_dword & (0x10000 << hp_slot))
0622             return PCI_SPEED_133MHz_PCIX;
0623         if (temp_dword & (0x100 << hp_slot))
0624             return PCI_SPEED_66MHz_PCIX;
0625     }
0626 
0627     if (temp_dword & (0x01 << hp_slot))
0628         return PCI_SPEED_66MHz;
0629 
0630     return PCI_SPEED_33MHz;
0631 }
0632 
0633 static inline void enable_slot_power(struct controller *ctrl, u8 slot)
0634 {
0635     u8 slot_power;
0636 
0637     slot_power = readb(ctrl->hpc_reg + SLOT_POWER);
0638     slot_power |= (0x01 << slot);
0639     writeb(slot_power, ctrl->hpc_reg + SLOT_POWER);
0640 }
0641 
0642 static inline void disable_slot_power(struct controller *ctrl, u8 slot)
0643 {
0644     u8 slot_power;
0645 
0646     slot_power = readb(ctrl->hpc_reg + SLOT_POWER);
0647     slot_power &= ~(0x01 << slot);
0648     writeb(slot_power, ctrl->hpc_reg + SLOT_POWER);
0649 }
0650 
0651 
0652 static inline int cpq_get_attention_status(struct controller *ctrl, struct slot *slot)
0653 {
0654     u8 hp_slot;
0655 
0656     hp_slot = slot->device - ctrl->slot_device_offset;
0657 
0658     return read_amber_LED(ctrl, hp_slot);
0659 }
0660 
0661 
0662 static inline int get_slot_enabled(struct controller *ctrl, struct slot *slot)
0663 {
0664     u8 hp_slot;
0665 
0666     hp_slot = slot->device - ctrl->slot_device_offset;
0667 
0668     return is_slot_enabled(ctrl, hp_slot);
0669 }
0670 
0671 
0672 static inline int cpq_get_latch_status(struct controller *ctrl,
0673                        struct slot *slot)
0674 {
0675     u32 status;
0676     u8 hp_slot;
0677 
0678     hp_slot = slot->device - ctrl->slot_device_offset;
0679     dbg("%s: slot->device = %d, ctrl->slot_device_offset = %d\n",
0680         __func__, slot->device, ctrl->slot_device_offset);
0681 
0682     status = (readl(ctrl->hpc_reg + INT_INPUT_CLEAR) & (0x01L << hp_slot));
0683 
0684     return (status == 0) ? 1 : 0;
0685 }
0686 
0687 
0688 static inline int get_presence_status(struct controller *ctrl,
0689                       struct slot *slot)
0690 {
0691     int presence_save = 0;
0692     u8 hp_slot;
0693     u32 tempdword;
0694 
0695     hp_slot = slot->device - ctrl->slot_device_offset;
0696 
0697     tempdword = readl(ctrl->hpc_reg + INT_INPUT_CLEAR);
0698     presence_save = (int) ((((~tempdword) >> 23) | ((~tempdword) >> 15))
0699                 >> hp_slot) & 0x02;
0700 
0701     return presence_save;
0702 }
0703 
0704 static inline int wait_for_ctrl_irq(struct controller *ctrl)
0705 {
0706     DECLARE_WAITQUEUE(wait, current);
0707     int retval = 0;
0708 
0709     dbg("%s - start\n", __func__);
0710     add_wait_queue(&ctrl->queue, &wait);
0711     /* Sleep for up to 1 second to wait for the LED to change. */
0712     msleep_interruptible(1000);
0713     remove_wait_queue(&ctrl->queue, &wait);
0714     if (signal_pending(current))
0715         retval =  -EINTR;
0716 
0717     dbg("%s - end\n", __func__);
0718     return retval;
0719 }
0720 
0721 #include <asm/pci_x86.h>
0722 static inline int cpqhp_routing_table_length(void)
0723 {
0724     BUG_ON(cpqhp_routing_table == NULL);
0725     return ((cpqhp_routing_table->size - sizeof(struct irq_routing_table)) /
0726         sizeof(struct irq_info));
0727 }
0728 
0729 #endif