1095 lines · c
1// SPDX-License-Identifier: GPL-2.0+2/*3 * IBM Hot Plug Controller Driver4 *5 * Written By: Jyoti Shah, IBM Corporation6 *7 * Copyright (C) 2001-2003 IBM Corp.8 *9 * All rights reserved.10 *11 * Send feedback to <gregkh@us.ibm.com>12 * <jshah@us.ibm.com>13 *14 */15 16#include <linux/wait.h>17#include <linux/time.h>18#include <linux/completion.h>19#include <linux/delay.h>20#include <linux/module.h>21#include <linux/pci.h>22#include <linux/init.h>23#include <linux/mutex.h>24#include <linux/sched.h>25#include <linux/kthread.h>26#include "ibmphp.h"27 28static int to_debug = 0;29#define debug_polling(fmt, arg...) do { if (to_debug) debug(fmt, arg); } while (0)30 31//----------------------------------------------------------------------------32// timeout values33//----------------------------------------------------------------------------34#define CMD_COMPLETE_TOUT_SEC 60 // give HPC 60 sec to finish cmd35#define HPC_CTLR_WORKING_TOUT 60 // give HPC 60 sec to finish cmd36#define HPC_GETACCESS_TIMEOUT 60 // seconds37#define POLL_INTERVAL_SEC 2 // poll HPC every 2 seconds38#define POLL_LATCH_CNT 5 // poll latch 5 times, then poll slots39 40//----------------------------------------------------------------------------41// Winnipeg Architected Register Offsets42//----------------------------------------------------------------------------43#define WPG_I2CMBUFL_OFFSET 0x08 // I2C Message Buffer Low44#define WPG_I2CMOSUP_OFFSET 0x10 // I2C Master Operation Setup Reg45#define WPG_I2CMCNTL_OFFSET 0x20 // I2C Master Control Register46#define WPG_I2CPARM_OFFSET 0x40 // I2C Parameter Register47#define WPG_I2CSTAT_OFFSET 0x70 // I2C Status Register48 49//----------------------------------------------------------------------------50// Winnipeg Store Type commands (Add this commands to the register offset)51//----------------------------------------------------------------------------52#define WPG_I2C_AND 0x1000 // I2C AND operation53#define WPG_I2C_OR 0x2000 // I2C OR operation54 55//----------------------------------------------------------------------------56// Command set for I2C Master Operation Setup Register57//----------------------------------------------------------------------------58#define WPG_READATADDR_MASK 0x00010000 // read,bytes,I2C shifted,index59#define WPG_WRITEATADDR_MASK 0x40010000 // write,bytes,I2C shifted,index60#define WPG_READDIRECT_MASK 0x1001000061#define WPG_WRITEDIRECT_MASK 0x6001000062 63 64//----------------------------------------------------------------------------65// bit masks for I2C Master Control Register66//----------------------------------------------------------------------------67#define WPG_I2CMCNTL_STARTOP_MASK 0x00000002 // Start the Operation68 69//----------------------------------------------------------------------------70//71//----------------------------------------------------------------------------72#define WPG_I2C_IOREMAP_SIZE 0x2044 // size of linear address interval73 74//----------------------------------------------------------------------------75// command index76//----------------------------------------------------------------------------77#define WPG_1ST_SLOT_INDEX 0x01 // index - 1st slot for ctlr78#define WPG_CTLR_INDEX 0x0F // index - ctlr79#define WPG_1ST_EXTSLOT_INDEX 0x10 // index - 1st ext slot for ctlr80#define WPG_1ST_BUS_INDEX 0x1F // index - 1st bus for ctlr81 82//----------------------------------------------------------------------------83// macro utilities84//----------------------------------------------------------------------------85// if bits 20,22,25,26,27,29,30 are OFF return 186#define HPC_I2CSTATUS_CHECK(s) ((u8)((s & 0x00000A76) ? 0 : 1))87 88//----------------------------------------------------------------------------89// global variables90//----------------------------------------------------------------------------91static DEFINE_MUTEX(sem_hpcaccess); // lock access to HPC92static DEFINE_MUTEX(operations_mutex); // lock all operations and93 // access to data structures94static DECLARE_COMPLETION(exit_complete); // make sure polling thread goes away95static struct task_struct *ibmphp_poll_thread;96//----------------------------------------------------------------------------97// local function prototypes98//----------------------------------------------------------------------------99static u8 i2c_ctrl_read(struct controller *, void __iomem *, u8);100static u8 i2c_ctrl_write(struct controller *, void __iomem *, u8, u8);101static u8 hpc_writecmdtoindex(u8, u8);102static u8 hpc_readcmdtoindex(u8, u8);103static void get_hpc_access(void);104static void free_hpc_access(void);105static int poll_hpc(void *data);106static int process_changeinstatus(struct slot *, struct slot *);107static int process_changeinlatch(u8, u8, struct controller *);108static int hpc_wait_ctlr_notworking(int, struct controller *, void __iomem *, u8 *);109//----------------------------------------------------------------------------110 111 112/*----------------------------------------------------------------------113* Name: i2c_ctrl_read114*115* Action: read from HPC over I2C116*117*---------------------------------------------------------------------*/118static u8 i2c_ctrl_read(struct controller *ctlr_ptr, void __iomem *WPGBbar, u8 index)119{120 u8 status;121 int i;122 void __iomem *wpg_addr; // base addr + offset123 unsigned long wpg_data; // data to/from WPG LOHI format124 unsigned long ultemp;125 unsigned long data; // actual data HILO format126 127 debug_polling("%s - Entry WPGBbar[%p] index[%x] \n", __func__, WPGBbar, index);128 129 //--------------------------------------------------------------------130 // READ - step 1131 // read at address, byte length, I2C address (shifted), index132 // or read direct, byte length, index133 if (ctlr_ptr->ctlr_type == 0x02) {134 data = WPG_READATADDR_MASK;135 // fill in I2C address136 ultemp = (unsigned long)ctlr_ptr->u.wpeg_ctlr.i2c_addr;137 ultemp = ultemp >> 1;138 data |= (ultemp << 8);139 140 // fill in index141 data |= (unsigned long)index;142 } else if (ctlr_ptr->ctlr_type == 0x04) {143 data = WPG_READDIRECT_MASK;144 145 // fill in index146 ultemp = (unsigned long)index;147 ultemp = ultemp << 8;148 data |= ultemp;149 } else {150 err("this controller type is not supported \n");151 return HPC_ERROR;152 }153 154 wpg_data = swab32(data); // swap data before writing155 wpg_addr = WPGBbar + WPG_I2CMOSUP_OFFSET;156 writel(wpg_data, wpg_addr);157 158 //--------------------------------------------------------------------159 // READ - step 2 : clear the message buffer160 data = 0x00000000;161 wpg_data = swab32(data);162 wpg_addr = WPGBbar + WPG_I2CMBUFL_OFFSET;163 writel(wpg_data, wpg_addr);164 165 //--------------------------------------------------------------------166 // READ - step 3 : issue start operation, I2C master control bit 30:ON167 // 2020 : [20] OR operation at [20] offset 0x20168 data = WPG_I2CMCNTL_STARTOP_MASK;169 wpg_data = swab32(data);170 wpg_addr = WPGBbar + WPG_I2CMCNTL_OFFSET + WPG_I2C_OR;171 writel(wpg_data, wpg_addr);172 173 //--------------------------------------------------------------------174 // READ - step 4 : wait until start operation bit clears175 i = CMD_COMPLETE_TOUT_SEC;176 while (i) {177 msleep(10);178 wpg_addr = WPGBbar + WPG_I2CMCNTL_OFFSET;179 wpg_data = readl(wpg_addr);180 data = swab32(wpg_data);181 if (!(data & WPG_I2CMCNTL_STARTOP_MASK))182 break;183 i--;184 }185 if (i == 0) {186 debug("%s - Error : WPG timeout\n", __func__);187 return HPC_ERROR;188 }189 //--------------------------------------------------------------------190 // READ - step 5 : read I2C status register191 i = CMD_COMPLETE_TOUT_SEC;192 while (i) {193 msleep(10);194 wpg_addr = WPGBbar + WPG_I2CSTAT_OFFSET;195 wpg_data = readl(wpg_addr);196 data = swab32(wpg_data);197 if (HPC_I2CSTATUS_CHECK(data))198 break;199 i--;200 }201 if (i == 0) {202 debug("ctrl_read - Exit Error:I2C timeout\n");203 return HPC_ERROR;204 }205 206 //--------------------------------------------------------------------207 // READ - step 6 : get DATA208 wpg_addr = WPGBbar + WPG_I2CMBUFL_OFFSET;209 wpg_data = readl(wpg_addr);210 data = swab32(wpg_data);211 212 status = (u8) data;213 214 debug_polling("%s - Exit index[%x] status[%x]\n", __func__, index, status);215 216 return (status);217}218 219/*----------------------------------------------------------------------220* Name: i2c_ctrl_write221*222* Action: write to HPC over I2C223*224* Return 0 or error codes225*---------------------------------------------------------------------*/226static u8 i2c_ctrl_write(struct controller *ctlr_ptr, void __iomem *WPGBbar, u8 index, u8 cmd)227{228 u8 rc;229 void __iomem *wpg_addr; // base addr + offset230 unsigned long wpg_data; // data to/from WPG LOHI format231 unsigned long ultemp;232 unsigned long data; // actual data HILO format233 int i;234 235 debug_polling("%s - Entry WPGBbar[%p] index[%x] cmd[%x]\n", __func__, WPGBbar, index, cmd);236 237 rc = 0;238 //--------------------------------------------------------------------239 // WRITE - step 1240 // write at address, byte length, I2C address (shifted), index241 // or write direct, byte length, index242 data = 0x00000000;243 244 if (ctlr_ptr->ctlr_type == 0x02) {245 data = WPG_WRITEATADDR_MASK;246 // fill in I2C address247 ultemp = (unsigned long)ctlr_ptr->u.wpeg_ctlr.i2c_addr;248 ultemp = ultemp >> 1;249 data |= (ultemp << 8);250 251 // fill in index252 data |= (unsigned long)index;253 } else if (ctlr_ptr->ctlr_type == 0x04) {254 data = WPG_WRITEDIRECT_MASK;255 256 // fill in index257 ultemp = (unsigned long)index;258 ultemp = ultemp << 8;259 data |= ultemp;260 } else {261 err("this controller type is not supported \n");262 return HPC_ERROR;263 }264 265 wpg_data = swab32(data); // swap data before writing266 wpg_addr = WPGBbar + WPG_I2CMOSUP_OFFSET;267 writel(wpg_data, wpg_addr);268 269 //--------------------------------------------------------------------270 // WRITE - step 2 : clear the message buffer271 data = 0x00000000 | (unsigned long)cmd;272 wpg_data = swab32(data);273 wpg_addr = WPGBbar + WPG_I2CMBUFL_OFFSET;274 writel(wpg_data, wpg_addr);275 276 //--------------------------------------------------------------------277 // WRITE - step 3 : issue start operation,I2C master control bit 30:ON278 // 2020 : [20] OR operation at [20] offset 0x20279 data = WPG_I2CMCNTL_STARTOP_MASK;280 wpg_data = swab32(data);281 wpg_addr = WPGBbar + WPG_I2CMCNTL_OFFSET + WPG_I2C_OR;282 writel(wpg_data, wpg_addr);283 284 //--------------------------------------------------------------------285 // WRITE - step 4 : wait until start operation bit clears286 i = CMD_COMPLETE_TOUT_SEC;287 while (i) {288 msleep(10);289 wpg_addr = WPGBbar + WPG_I2CMCNTL_OFFSET;290 wpg_data = readl(wpg_addr);291 data = swab32(wpg_data);292 if (!(data & WPG_I2CMCNTL_STARTOP_MASK))293 break;294 i--;295 }296 if (i == 0) {297 debug("%s - Exit Error:WPG timeout\n", __func__);298 rc = HPC_ERROR;299 }300 301 //--------------------------------------------------------------------302 // WRITE - step 5 : read I2C status register303 i = CMD_COMPLETE_TOUT_SEC;304 while (i) {305 msleep(10);306 wpg_addr = WPGBbar + WPG_I2CSTAT_OFFSET;307 wpg_data = readl(wpg_addr);308 data = swab32(wpg_data);309 if (HPC_I2CSTATUS_CHECK(data))310 break;311 i--;312 }313 if (i == 0) {314 debug("ctrl_read - Error : I2C timeout\n");315 rc = HPC_ERROR;316 }317 318 debug_polling("%s Exit rc[%x]\n", __func__, rc);319 return (rc);320}321 322//------------------------------------------------------------323// Read from ISA type HPC324//------------------------------------------------------------325static u8 isa_ctrl_read(struct controller *ctlr_ptr, u8 offset)326{327 u16 start_address;328 u8 data;329 330 start_address = ctlr_ptr->u.isa_ctlr.io_start;331 data = inb(start_address + offset);332 return data;333}334 335//--------------------------------------------------------------336// Write to ISA type HPC337//--------------------------------------------------------------338static void isa_ctrl_write(struct controller *ctlr_ptr, u8 offset, u8 data)339{340 u16 start_address;341 u16 port_address;342 343 start_address = ctlr_ptr->u.isa_ctlr.io_start;344 port_address = start_address + (u16) offset;345 outb(data, port_address);346}347 348static u8 pci_ctrl_read(struct controller *ctrl, u8 offset)349{350 u8 data = 0x00;351 debug("inside pci_ctrl_read\n");352 if (ctrl->ctrl_dev)353 pci_read_config_byte(ctrl->ctrl_dev, HPC_PCI_OFFSET + offset, &data);354 return data;355}356 357static u8 pci_ctrl_write(struct controller *ctrl, u8 offset, u8 data)358{359 u8 rc = -ENODEV;360 debug("inside pci_ctrl_write\n");361 if (ctrl->ctrl_dev) {362 pci_write_config_byte(ctrl->ctrl_dev, HPC_PCI_OFFSET + offset, data);363 rc = 0;364 }365 return rc;366}367 368static u8 ctrl_read(struct controller *ctlr, void __iomem *base, u8 offset)369{370 u8 rc;371 switch (ctlr->ctlr_type) {372 case 0:373 rc = isa_ctrl_read(ctlr, offset);374 break;375 case 1:376 rc = pci_ctrl_read(ctlr, offset);377 break;378 case 2:379 case 4:380 rc = i2c_ctrl_read(ctlr, base, offset);381 break;382 default:383 return -ENODEV;384 }385 return rc;386}387 388static u8 ctrl_write(struct controller *ctlr, void __iomem *base, u8 offset, u8 data)389{390 u8 rc = 0;391 switch (ctlr->ctlr_type) {392 case 0:393 isa_ctrl_write(ctlr, offset, data);394 break;395 case 1:396 rc = pci_ctrl_write(ctlr, offset, data);397 break;398 case 2:399 case 4:400 rc = i2c_ctrl_write(ctlr, base, offset, data);401 break;402 default:403 return -ENODEV;404 }405 return rc;406}407/*----------------------------------------------------------------------408* Name: hpc_writecmdtoindex()409*410* Action: convert a write command to proper index within a controller411*412* Return index, HPC_ERROR413*---------------------------------------------------------------------*/414static u8 hpc_writecmdtoindex(u8 cmd, u8 index)415{416 u8 rc;417 418 switch (cmd) {419 case HPC_CTLR_ENABLEIRQ: // 0x00.N.15420 case HPC_CTLR_CLEARIRQ: // 0x06.N.15421 case HPC_CTLR_RESET: // 0x07.N.15422 case HPC_CTLR_IRQSTEER: // 0x08.N.15423 case HPC_CTLR_DISABLEIRQ: // 0x01.N.15424 case HPC_ALLSLOT_ON: // 0x11.N.15425 case HPC_ALLSLOT_OFF: // 0x12.N.15426 rc = 0x0F;427 break;428 429 case HPC_SLOT_OFF: // 0x02.Y.0-14430 case HPC_SLOT_ON: // 0x03.Y.0-14431 case HPC_SLOT_ATTNOFF: // 0x04.N.0-14432 case HPC_SLOT_ATTNON: // 0x05.N.0-14433 case HPC_SLOT_BLINKLED: // 0x13.N.0-14434 rc = index;435 break;436 437 case HPC_BUS_33CONVMODE:438 case HPC_BUS_66CONVMODE:439 case HPC_BUS_66PCIXMODE:440 case HPC_BUS_100PCIXMODE:441 case HPC_BUS_133PCIXMODE:442 rc = index + WPG_1ST_BUS_INDEX - 1;443 break;444 445 default:446 err("hpc_writecmdtoindex - Error invalid cmd[%x]\n", cmd);447 rc = HPC_ERROR;448 }449 450 return rc;451}452 453/*----------------------------------------------------------------------454* Name: hpc_readcmdtoindex()455*456* Action: convert a read command to proper index within a controller457*458* Return index, HPC_ERROR459*---------------------------------------------------------------------*/460static u8 hpc_readcmdtoindex(u8 cmd, u8 index)461{462 u8 rc;463 464 switch (cmd) {465 case READ_CTLRSTATUS:466 rc = 0x0F;467 break;468 case READ_SLOTSTATUS:469 case READ_ALLSTAT:470 rc = index;471 break;472 case READ_EXTSLOTSTATUS:473 rc = index + WPG_1ST_EXTSLOT_INDEX;474 break;475 case READ_BUSSTATUS:476 rc = index + WPG_1ST_BUS_INDEX - 1;477 break;478 case READ_SLOTLATCHLOWREG:479 rc = 0x28;480 break;481 case READ_REVLEVEL:482 rc = 0x25;483 break;484 case READ_HPCOPTIONS:485 rc = 0x27;486 break;487 default:488 rc = HPC_ERROR;489 }490 return rc;491}492 493/*----------------------------------------------------------------------494* Name: HPCreadslot()495*496* Action: issue a READ command to HPC497*498* Input: pslot - cannot be NULL for READ_ALLSTAT499* pstatus - can be NULL for READ_ALLSTAT500*501* Return 0 or error codes502*---------------------------------------------------------------------*/503int ibmphp_hpc_readslot(struct slot *pslot, u8 cmd, u8 *pstatus)504{505 void __iomem *wpg_bbar = NULL;506 struct controller *ctlr_ptr;507 u8 index, status;508 int rc = 0;509 int busindex;510 511 debug_polling("%s - Entry pslot[%p] cmd[%x] pstatus[%p]\n", __func__, pslot, cmd, pstatus);512 513 if ((pslot == NULL)514 || ((pstatus == NULL) && (cmd != READ_ALLSTAT) && (cmd != READ_BUSSTATUS))) {515 rc = -EINVAL;516 err("%s - Error invalid pointer, rc[%d]\n", __func__, rc);517 return rc;518 }519 520 if (cmd == READ_BUSSTATUS) {521 busindex = ibmphp_get_bus_index(pslot->bus);522 if (busindex < 0) {523 rc = -EINVAL;524 err("%s - Exit Error:invalid bus, rc[%d]\n", __func__, rc);525 return rc;526 } else527 index = (u8) busindex;528 } else529 index = pslot->ctlr_index;530 531 index = hpc_readcmdtoindex(cmd, index);532 533 if (index == HPC_ERROR) {534 rc = -EINVAL;535 err("%s - Exit Error:invalid index, rc[%d]\n", __func__, rc);536 return rc;537 }538 539 ctlr_ptr = pslot->ctrl;540 541 get_hpc_access();542 543 //--------------------------------------------------------------------544 // map physical address to logical address545 //--------------------------------------------------------------------546 if ((ctlr_ptr->ctlr_type == 2) || (ctlr_ptr->ctlr_type == 4))547 wpg_bbar = ioremap(ctlr_ptr->u.wpeg_ctlr.wpegbbar, WPG_I2C_IOREMAP_SIZE);548 549 //--------------------------------------------------------------------550 // check controller status before reading551 //--------------------------------------------------------------------552 rc = hpc_wait_ctlr_notworking(HPC_CTLR_WORKING_TOUT, ctlr_ptr, wpg_bbar, &status);553 if (!rc) {554 switch (cmd) {555 case READ_ALLSTAT:556 // update the slot structure557 pslot->ctrl->status = status;558 pslot->status = ctrl_read(ctlr_ptr, wpg_bbar, index);559 rc = hpc_wait_ctlr_notworking(HPC_CTLR_WORKING_TOUT, ctlr_ptr, wpg_bbar,560 &status);561 if (!rc)562 pslot->ext_status = ctrl_read(ctlr_ptr, wpg_bbar, index + WPG_1ST_EXTSLOT_INDEX);563 564 break;565 566 case READ_SLOTSTATUS:567 // DO NOT update the slot structure568 *pstatus = ctrl_read(ctlr_ptr, wpg_bbar, index);569 break;570 571 case READ_EXTSLOTSTATUS:572 // DO NOT update the slot structure573 *pstatus = ctrl_read(ctlr_ptr, wpg_bbar, index);574 break;575 576 case READ_CTLRSTATUS:577 // DO NOT update the slot structure578 *pstatus = status;579 break;580 581 case READ_BUSSTATUS:582 pslot->busstatus = ctrl_read(ctlr_ptr, wpg_bbar, index);583 break;584 case READ_REVLEVEL:585 *pstatus = ctrl_read(ctlr_ptr, wpg_bbar, index);586 break;587 case READ_HPCOPTIONS:588 *pstatus = ctrl_read(ctlr_ptr, wpg_bbar, index);589 break;590 case READ_SLOTLATCHLOWREG:591 // DO NOT update the slot structure592 *pstatus = ctrl_read(ctlr_ptr, wpg_bbar, index);593 break;594 595 // Not used596 case READ_ALLSLOT:597 list_for_each_entry(pslot, &ibmphp_slot_head,598 ibm_slot_list) {599 index = pslot->ctlr_index;600 rc = hpc_wait_ctlr_notworking(HPC_CTLR_WORKING_TOUT, ctlr_ptr,601 wpg_bbar, &status);602 if (!rc) {603 pslot->status = ctrl_read(ctlr_ptr, wpg_bbar, index);604 rc = hpc_wait_ctlr_notworking(HPC_CTLR_WORKING_TOUT,605 ctlr_ptr, wpg_bbar, &status);606 if (!rc)607 pslot->ext_status =608 ctrl_read(ctlr_ptr, wpg_bbar,609 index + WPG_1ST_EXTSLOT_INDEX);610 } else {611 err("%s - Error ctrl_read failed\n", __func__);612 rc = -EINVAL;613 break;614 }615 }616 break;617 default:618 rc = -EINVAL;619 break;620 }621 }622 //--------------------------------------------------------------------623 // cleanup624 //--------------------------------------------------------------------625 626 // remove physical to logical address mapping627 if ((ctlr_ptr->ctlr_type == 2) || (ctlr_ptr->ctlr_type == 4))628 iounmap(wpg_bbar);629 630 free_hpc_access();631 632 debug_polling("%s - Exit rc[%d]\n", __func__, rc);633 return rc;634}635 636/*----------------------------------------------------------------------637* Name: ibmphp_hpc_writeslot()638*639* Action: issue a WRITE command to HPC640*---------------------------------------------------------------------*/641int ibmphp_hpc_writeslot(struct slot *pslot, u8 cmd)642{643 void __iomem *wpg_bbar = NULL;644 struct controller *ctlr_ptr;645 u8 index, status;646 int busindex;647 u8 done;648 int rc = 0;649 int timeout;650 651 debug_polling("%s - Entry pslot[%p] cmd[%x]\n", __func__, pslot, cmd);652 if (pslot == NULL) {653 rc = -EINVAL;654 err("%s - Error Exit rc[%d]\n", __func__, rc);655 return rc;656 }657 658 if ((cmd == HPC_BUS_33CONVMODE) || (cmd == HPC_BUS_66CONVMODE) ||659 (cmd == HPC_BUS_66PCIXMODE) || (cmd == HPC_BUS_100PCIXMODE) ||660 (cmd == HPC_BUS_133PCIXMODE)) {661 busindex = ibmphp_get_bus_index(pslot->bus);662 if (busindex < 0) {663 rc = -EINVAL;664 err("%s - Exit Error:invalid bus, rc[%d]\n", __func__, rc);665 return rc;666 } else667 index = (u8) busindex;668 } else669 index = pslot->ctlr_index;670 671 index = hpc_writecmdtoindex(cmd, index);672 673 if (index == HPC_ERROR) {674 rc = -EINVAL;675 err("%s - Error Exit rc[%d]\n", __func__, rc);676 return rc;677 }678 679 ctlr_ptr = pslot->ctrl;680 681 get_hpc_access();682 683 //--------------------------------------------------------------------684 // map physical address to logical address685 //--------------------------------------------------------------------686 if ((ctlr_ptr->ctlr_type == 2) || (ctlr_ptr->ctlr_type == 4)) {687 wpg_bbar = ioremap(ctlr_ptr->u.wpeg_ctlr.wpegbbar, WPG_I2C_IOREMAP_SIZE);688 689 debug("%s - ctlr id[%x] physical[%lx] logical[%lx] i2c[%x]\n", __func__,690 ctlr_ptr->ctlr_id, (ulong) (ctlr_ptr->u.wpeg_ctlr.wpegbbar), (ulong) wpg_bbar,691 ctlr_ptr->u.wpeg_ctlr.i2c_addr);692 }693 //--------------------------------------------------------------------694 // check controller status before writing695 //--------------------------------------------------------------------696 rc = hpc_wait_ctlr_notworking(HPC_CTLR_WORKING_TOUT, ctlr_ptr, wpg_bbar, &status);697 if (!rc) {698 699 ctrl_write(ctlr_ptr, wpg_bbar, index, cmd);700 701 //--------------------------------------------------------------------702 // check controller is still not working on the command703 //--------------------------------------------------------------------704 timeout = CMD_COMPLETE_TOUT_SEC;705 done = 0;706 while (!done) {707 rc = hpc_wait_ctlr_notworking(HPC_CTLR_WORKING_TOUT, ctlr_ptr, wpg_bbar,708 &status);709 if (!rc) {710 if (NEEDTOCHECK_CMDSTATUS(cmd)) {711 if (CTLR_FINISHED(status) == HPC_CTLR_FINISHED_YES)712 done = 1;713 } else714 done = 1;715 }716 if (!done) {717 msleep(1000);718 if (timeout < 1) {719 done = 1;720 err("%s - Error command complete timeout\n", __func__);721 rc = -EFAULT;722 } else723 timeout--;724 }725 }726 ctlr_ptr->status = status;727 }728 // cleanup729 730 // remove physical to logical address mapping731 if ((ctlr_ptr->ctlr_type == 2) || (ctlr_ptr->ctlr_type == 4))732 iounmap(wpg_bbar);733 free_hpc_access();734 735 debug_polling("%s - Exit rc[%d]\n", __func__, rc);736 return rc;737}738 739/*----------------------------------------------------------------------740* Name: get_hpc_access()741*742* Action: make sure only one process can access HPC at one time743*---------------------------------------------------------------------*/744static void get_hpc_access(void)745{746 mutex_lock(&sem_hpcaccess);747}748 749/*----------------------------------------------------------------------750* Name: free_hpc_access()751*---------------------------------------------------------------------*/752void free_hpc_access(void)753{754 mutex_unlock(&sem_hpcaccess);755}756 757/*----------------------------------------------------------------------758* Name: ibmphp_lock_operations()759*760* Action: make sure only one process can change the data structure761*---------------------------------------------------------------------*/762void ibmphp_lock_operations(void)763{764 mutex_lock(&operations_mutex);765 to_debug = 1;766}767 768/*----------------------------------------------------------------------769* Name: ibmphp_unlock_operations()770*---------------------------------------------------------------------*/771void ibmphp_unlock_operations(void)772{773 debug("%s - Entry\n", __func__);774 mutex_unlock(&operations_mutex);775 to_debug = 0;776 debug("%s - Exit\n", __func__);777}778 779/*----------------------------------------------------------------------780* Name: poll_hpc()781*---------------------------------------------------------------------*/782#define POLL_LATCH_REGISTER 0783#define POLL_SLOTS 1784#define POLL_SLEEP 2785static int poll_hpc(void *data)786{787 struct slot myslot;788 struct slot *pslot = NULL;789 int rc;790 int poll_state = POLL_LATCH_REGISTER;791 u8 oldlatchlow = 0x00;792 u8 curlatchlow = 0x00;793 int poll_count = 0;794 u8 ctrl_count = 0x00;795 796 debug("%s - Entry\n", __func__);797 798 while (!kthread_should_stop()) {799 /* try to get the lock to do some kind of hardware access */800 mutex_lock(&operations_mutex);801 802 switch (poll_state) {803 case POLL_LATCH_REGISTER:804 oldlatchlow = curlatchlow;805 ctrl_count = 0x00;806 list_for_each_entry(pslot, &ibmphp_slot_head,807 ibm_slot_list) {808 if (ctrl_count >= ibmphp_get_total_controllers())809 break;810 if (pslot->ctrl->ctlr_relative_id == ctrl_count) {811 ctrl_count++;812 if (READ_SLOT_LATCH(pslot->ctrl)) {813 rc = ibmphp_hpc_readslot(pslot,814 READ_SLOTLATCHLOWREG,815 &curlatchlow);816 if (oldlatchlow != curlatchlow)817 process_changeinlatch(oldlatchlow,818 curlatchlow,819 pslot->ctrl);820 }821 }822 }823 ++poll_count;824 poll_state = POLL_SLEEP;825 break;826 case POLL_SLOTS:827 list_for_each_entry(pslot, &ibmphp_slot_head,828 ibm_slot_list) {829 // make a copy of the old status830 memcpy((void *) &myslot, (void *) pslot,831 sizeof(struct slot));832 rc = ibmphp_hpc_readslot(pslot, READ_ALLSTAT, NULL);833 if ((myslot.status != pslot->status)834 || (myslot.ext_status != pslot->ext_status))835 process_changeinstatus(pslot, &myslot);836 }837 ctrl_count = 0x00;838 list_for_each_entry(pslot, &ibmphp_slot_head,839 ibm_slot_list) {840 if (ctrl_count >= ibmphp_get_total_controllers())841 break;842 if (pslot->ctrl->ctlr_relative_id == ctrl_count) {843 ctrl_count++;844 if (READ_SLOT_LATCH(pslot->ctrl))845 rc = ibmphp_hpc_readslot(pslot,846 READ_SLOTLATCHLOWREG,847 &curlatchlow);848 }849 }850 ++poll_count;851 poll_state = POLL_SLEEP;852 break;853 case POLL_SLEEP:854 /* don't sleep with a lock on the hardware */855 mutex_unlock(&operations_mutex);856 msleep(POLL_INTERVAL_SEC * 1000);857 858 if (kthread_should_stop())859 goto out_sleep;860 861 mutex_lock(&operations_mutex);862 863 if (poll_count >= POLL_LATCH_CNT) {864 poll_count = 0;865 poll_state = POLL_SLOTS;866 } else867 poll_state = POLL_LATCH_REGISTER;868 break;869 }870 /* give up the hardware semaphore */871 mutex_unlock(&operations_mutex);872 /* sleep for a short time just for good measure */873out_sleep:874 msleep(100);875 }876 complete(&exit_complete);877 debug("%s - Exit\n", __func__);878 return 0;879}880 881 882/*----------------------------------------------------------------------883* Name: process_changeinstatus884*885* Action: compare old and new slot status, process the change in status886*887* Input: pointer to slot struct, old slot struct888*889* Return 0 or error codes890* Value:891*892* Side893* Effects: None.894*895* Notes:896*---------------------------------------------------------------------*/897static int process_changeinstatus(struct slot *pslot, struct slot *poldslot)898{899 u8 status;900 int rc = 0;901 u8 disable = 0;902 u8 update = 0;903 904 debug("process_changeinstatus - Entry pslot[%p], poldslot[%p]\n", pslot, poldslot);905 906 // bit 0 - HPC_SLOT_POWER907 if ((pslot->status & 0x01) != (poldslot->status & 0x01))908 update = 1;909 910 // bit 1 - HPC_SLOT_CONNECT911 // ignore912 913 // bit 2 - HPC_SLOT_ATTN914 if ((pslot->status & 0x04) != (poldslot->status & 0x04))915 update = 1;916 917 // bit 3 - HPC_SLOT_PRSNT2918 // bit 4 - HPC_SLOT_PRSNT1919 if (((pslot->status & 0x08) != (poldslot->status & 0x08))920 || ((pslot->status & 0x10) != (poldslot->status & 0x10)))921 update = 1;922 923 // bit 5 - HPC_SLOT_PWRGD924 if ((pslot->status & 0x20) != (poldslot->status & 0x20))925 // OFF -> ON: ignore, ON -> OFF: disable slot926 if ((poldslot->status & 0x20) && (SLOT_CONNECT(poldslot->status) == HPC_SLOT_CONNECTED) && (SLOT_PRESENT(poldslot->status)))927 disable = 1;928 929 // bit 6 - HPC_SLOT_BUS_SPEED930 // ignore931 932 // bit 7 - HPC_SLOT_LATCH933 if ((pslot->status & 0x80) != (poldslot->status & 0x80)) {934 update = 1;935 // OPEN -> CLOSE936 if (pslot->status & 0x80) {937 if (SLOT_PWRGD(pslot->status)) {938 // power goes on and off after closing latch939 // check again to make sure power is still ON940 msleep(1000);941 rc = ibmphp_hpc_readslot(pslot, READ_SLOTSTATUS, &status);942 if (SLOT_PWRGD(status))943 update = 1;944 else // overwrite power in pslot to OFF945 pslot->status &= ~HPC_SLOT_POWER;946 }947 }948 // CLOSE -> OPEN949 else if ((SLOT_PWRGD(poldslot->status) == HPC_SLOT_PWRGD_GOOD)950 && (SLOT_CONNECT(poldslot->status) == HPC_SLOT_CONNECTED) && (SLOT_PRESENT(poldslot->status))) {951 disable = 1;952 }953 // else - ignore954 }955 // bit 4 - HPC_SLOT_BLINK_ATTN956 if ((pslot->ext_status & 0x08) != (poldslot->ext_status & 0x08))957 update = 1;958 959 if (disable) {960 debug("process_changeinstatus - disable slot\n");961 pslot->flag = 0;962 rc = ibmphp_do_disable_slot(pslot);963 }964 965 if (update || disable)966 ibmphp_update_slot_info(pslot);967 968 debug("%s - Exit rc[%d] disable[%x] update[%x]\n", __func__, rc, disable, update);969 970 return rc;971}972 973/*----------------------------------------------------------------------974* Name: process_changeinlatch975*976* Action: compare old and new latch reg status, process the change977*978* Input: old and current latch register status979*980* Return 0 or error codes981* Value:982*---------------------------------------------------------------------*/983static int process_changeinlatch(u8 old, u8 new, struct controller *ctrl)984{985 struct slot myslot, *pslot;986 u8 i;987 u8 mask;988 int rc = 0;989 990 debug("%s - Entry old[%x], new[%x]\n", __func__, old, new);991 // bit 0 reserved, 0 is LSB, check bit 1-6 for 6 slots992 993 for (i = ctrl->starting_slot_num; i <= ctrl->ending_slot_num; i++) {994 mask = 0x01 << i;995 if ((mask & old) != (mask & new)) {996 pslot = ibmphp_get_slot_from_physical_num(i);997 if (pslot) {998 memcpy((void *) &myslot, (void *) pslot, sizeof(struct slot));999 rc = ibmphp_hpc_readslot(pslot, READ_ALLSTAT, NULL);1000 debug("%s - call process_changeinstatus for slot[%d]\n", __func__, i);1001 process_changeinstatus(pslot, &myslot);1002 } else {1003 rc = -EINVAL;1004 err("%s - Error bad pointer for slot[%d]\n", __func__, i);1005 }1006 }1007 }1008 debug("%s - Exit rc[%d]\n", __func__, rc);1009 return rc;1010}1011 1012/*----------------------------------------------------------------------1013* Name: ibmphp_hpc_start_poll_thread1014*1015* Action: start polling thread1016*---------------------------------------------------------------------*/1017int __init ibmphp_hpc_start_poll_thread(void)1018{1019 debug("%s - Entry\n", __func__);1020 1021 ibmphp_poll_thread = kthread_run(poll_hpc, NULL, "hpc_poll");1022 if (IS_ERR(ibmphp_poll_thread)) {1023 err("%s - Error, thread not started\n", __func__);1024 return PTR_ERR(ibmphp_poll_thread);1025 }1026 return 0;1027}1028 1029/*----------------------------------------------------------------------1030* Name: ibmphp_hpc_stop_poll_thread1031*1032* Action: stop polling thread and cleanup1033*---------------------------------------------------------------------*/1034void __exit ibmphp_hpc_stop_poll_thread(void)1035{1036 debug("%s - Entry\n", __func__);1037 1038 kthread_stop(ibmphp_poll_thread);1039 debug("before locking operations\n");1040 ibmphp_lock_operations();1041 debug("after locking operations\n");1042 1043 // wait for poll thread to exit1044 debug("before exit_complete down\n");1045 wait_for_completion(&exit_complete);1046 debug("after exit_completion down\n");1047 1048 // cleanup1049 debug("before free_hpc_access\n");1050 free_hpc_access();1051 debug("after free_hpc_access\n");1052 ibmphp_unlock_operations();1053 debug("after unlock operations\n");1054 1055 debug("%s - Exit\n", __func__);1056}1057 1058/*----------------------------------------------------------------------1059* Name: hpc_wait_ctlr_notworking1060*1061* Action: wait until the controller is in a not working state1062*1063* Return 0, HPC_ERROR1064* Value:1065*---------------------------------------------------------------------*/1066static int hpc_wait_ctlr_notworking(int timeout, struct controller *ctlr_ptr, void __iomem *wpg_bbar,1067 u8 *pstatus)1068{1069 int rc = 0;1070 u8 done = 0;1071 1072 debug_polling("hpc_wait_ctlr_notworking - Entry timeout[%d]\n", timeout);1073 1074 while (!done) {1075 *pstatus = ctrl_read(ctlr_ptr, wpg_bbar, WPG_CTLR_INDEX);1076 if (*pstatus == HPC_ERROR) {1077 rc = HPC_ERROR;1078 done = 1;1079 }1080 if (CTLR_WORKING(*pstatus) == HPC_CTLR_WORKING_NO)1081 done = 1;1082 if (!done) {1083 msleep(1000);1084 if (timeout < 1) {1085 done = 1;1086 err("HPCreadslot - Error ctlr timeout\n");1087 rc = HPC_ERROR;1088 } else1089 timeout--;1090 }1091 }1092 debug_polling("hpc_wait_ctlr_notworking - Exit rc[%x] status[%x]\n", rc, *pstatus);1093 return rc;1094}1095