Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 117228
b: refs/heads/master
c: f18e962
h: refs/heads/master
v: v3
  • Loading branch information
Kenji Kaneshige authored and Jesse Barnes committed Oct 22, 2008
1 parent 3ca9ede commit 1a232c7
Show file tree
Hide file tree
Showing 4 changed files with 56 additions and 5 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: b84346ef74cf76793070762b933387729c5df1ed
refs/heads/master: f18e9625e02bb3e5ba9e81104f14e9d904ab28c4
1 change: 1 addition & 0 deletions trunk/drivers/pci/hotplug/pciehp.h
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ struct controller {
struct timer_list poll_timer;
int cmd_busy;
unsigned int no_cmd_complete:1;
unsigned int link_active_reporting:1;
};

#define INT_BUTTON_IGNORE 0
Expand Down
3 changes: 0 additions & 3 deletions trunk/drivers/pci/hotplug/pciehp_ctrl.c
Original file line number Diff line number Diff line change
Expand Up @@ -226,9 +226,6 @@ static int board_added(struct slot *p_slot)
if (PWR_LED(ctrl))
p_slot->hpc_ops->green_led_blink(p_slot);

/* Wait for ~1 second */
msleep(1000);

/* Check link training status */
retval = p_slot->hpc_ops->check_lnk_status(ctrl);
if (retval) {
Expand Down
55 changes: 54 additions & 1 deletion trunk/drivers/pci/hotplug/pciehp_hpc.c
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,7 @@ static inline int pciehp_writel(struct controller *ctrl, int reg, u32 value)
/* Field definitions in Link Capabilities Register */
#define MAX_LNK_SPEED 0x000F
#define MAX_LNK_WIDTH 0x03F0
#define LINK_ACTIVE_REPORTING 0x00100000

/* Link Width Encoding */
#define LNK_X1 0x01
Expand All @@ -141,6 +142,7 @@ static inline int pciehp_writel(struct controller *ctrl, int reg, u32 value)
#define LNK_TRN_ERR 0x0400
#define LNK_TRN 0x0800
#define SLOT_CLK_CONF 0x1000
#define LINK_ACTIVE 0x2000

/* Field definitions in Slot Capabilities Register */
#define ATTN_BUTTN_PRSN 0x00000001
Expand Down Expand Up @@ -368,11 +370,52 @@ static int pcie_write_cmd(struct controller *ctrl, u16 cmd, u16 mask)
return retval;
}

static inline int check_link_active(struct controller *ctrl)
{
u16 link_status;

if (pciehp_readw(ctrl, LNKSTATUS, &link_status))
return 0;
return !!(link_status & LINK_ACTIVE);
}

static void pcie_wait_link_active(struct controller *ctrl)
{
int timeout = 1000;

if (check_link_active(ctrl))
return;
while (timeout > 0) {
msleep(10);
timeout -= 10;
if (check_link_active(ctrl))
return;
}
ctrl_dbg(ctrl, "Data Link Layer Link Active not set in 1000 msec\n");
}

static int hpc_check_lnk_status(struct controller *ctrl)
{
u16 lnk_status;
int retval = 0;

/*
* Data Link Layer Link Active Reporting must be capable for
* hot-plug capable downstream port. But old controller might
* not implement it. In this case, we wait for 1000 ms.
*/
if (ctrl->link_active_reporting){
/* Wait for Data Link Layer Link Active bit to be set */
pcie_wait_link_active(ctrl);
/*
* We must wait for 100 ms after the Data Link Layer
* Link Active bit reads 1b before initiating a
* configuration access to the hot added device.
*/
msleep(100);
} else
msleep(1000);

retval = pciehp_readw(ctrl, LNKSTATUS, &lnk_status);
if (retval) {
ctrl_err(ctrl, "%s: Cannot read LNKSTATUS register\n",
Expand Down Expand Up @@ -1131,7 +1174,7 @@ static inline void dbg_ctrl(struct controller *ctrl)
struct controller *pcie_init(struct pcie_device *dev)
{
struct controller *ctrl;
u32 slot_cap;
u32 slot_cap, link_cap;
struct pci_dev *pdev = dev->port;

ctrl = kzalloc(sizeof(*ctrl), GFP_KERNEL);
Expand Down Expand Up @@ -1173,6 +1216,16 @@ struct controller *pcie_init(struct pcie_device *dev)
!(POWER_CTRL(ctrl) | ATTN_LED(ctrl) | PWR_LED(ctrl) | EMI(ctrl)))
ctrl->no_cmd_complete = 1;

/* Check if Data Link Layer Link Active Reporting is implemented */
if (pciehp_readl(ctrl, LNKCAP, &link_cap)) {
ctrl_err(ctrl, "%s: Cannot read LNKCAP register\n", __func__);
goto abort_ctrl;
}
if (link_cap & LINK_ACTIVE_REPORTING) {
ctrl_dbg(ctrl, "Link Active Reporting supported\n");
ctrl->link_active_reporting = 1;
}

/* Clear all remaining event bits in Slot Status register */
if (pciehp_writew(ctrl, SLOTSTATUS, 0x1f))
goto abort_ctrl;
Expand Down

0 comments on commit 1a232c7

Please sign in to comment.