linux/drivers/pci/hotplug/ibmphp_hpc.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * IBM Hot Plug Controller Driver
   4 *
   5 * Written By: Jyoti Shah, IBM Corporation
   6 *
   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/delay.h>
  19#include <linux/module.h>
  20#include <linux/pci.h>
  21#include <linux/init.h>
  22#include <linux/mutex.h>
  23#include <linux/sched.h>
  24#include <linux/semaphore.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 values
  33//----------------------------------------------------------------------------
  34#define CMD_COMPLETE_TOUT_SEC   60      // give HPC 60 sec to finish cmd
  35#define HPC_CTLR_WORKING_TOUT   60      // give HPC 60 sec to finish cmd
  36#define HPC_GETACCESS_TIMEOUT   60      // seconds
  37#define POLL_INTERVAL_SEC       2       // poll HPC every 2 seconds
  38#define POLL_LATCH_CNT          5       // poll latch 5 times, then poll slots
  39
  40//----------------------------------------------------------------------------
  41// Winnipeg Architected Register Offsets
  42//----------------------------------------------------------------------------
  43#define WPG_I2CMBUFL_OFFSET     0x08    // I2C Message Buffer Low
  44#define WPG_I2CMOSUP_OFFSET     0x10    // I2C Master Operation Setup Reg
  45#define WPG_I2CMCNTL_OFFSET     0x20    // I2C Master Control Register
  46#define WPG_I2CPARM_OFFSET      0x40    // I2C Parameter Register
  47#define WPG_I2CSTAT_OFFSET      0x70    // I2C Status Register
  48
  49//----------------------------------------------------------------------------
  50// Winnipeg Store Type commands (Add this commands to the register offset)
  51//----------------------------------------------------------------------------
  52#define WPG_I2C_AND             0x1000  // I2C AND operation
  53#define WPG_I2C_OR              0x2000  // I2C OR operation
  54
  55//----------------------------------------------------------------------------
  56// Command set for I2C Master Operation Setup Register
  57//----------------------------------------------------------------------------
  58#define WPG_READATADDR_MASK     0x00010000      // read,bytes,I2C shifted,index
  59#define WPG_WRITEATADDR_MASK    0x40010000      // write,bytes,I2C shifted,index
  60#define WPG_READDIRECT_MASK     0x10010000
  61#define WPG_WRITEDIRECT_MASK    0x60010000
  62
  63
  64//----------------------------------------------------------------------------
  65// bit masks for I2C Master Control Register
  66//----------------------------------------------------------------------------
  67#define WPG_I2CMCNTL_STARTOP_MASK       0x00000002      // Start the Operation
  68
  69//----------------------------------------------------------------------------
  70//
  71//----------------------------------------------------------------------------
  72#define WPG_I2C_IOREMAP_SIZE    0x2044  // size of linear address interval
  73
  74//----------------------------------------------------------------------------
  75// command index
  76//----------------------------------------------------------------------------
  77#define WPG_1ST_SLOT_INDEX      0x01    // index - 1st slot for ctlr
  78#define WPG_CTLR_INDEX          0x0F    // index - ctlr
  79#define WPG_1ST_EXTSLOT_INDEX   0x10    // index - 1st ext slot for ctlr
  80#define WPG_1ST_BUS_INDEX       0x1F    // index - 1st bus for ctlr
  81
  82//----------------------------------------------------------------------------
  83// macro utilities
  84//----------------------------------------------------------------------------
  85// if bits 20,22,25,26,27,29,30 are OFF return 1
  86#define HPC_I2CSTATUS_CHECK(s)  ((u8)((s & 0x00000A76) ? 0 : 1))
  87
  88//----------------------------------------------------------------------------
  89// global variables
  90//----------------------------------------------------------------------------
  91static struct mutex sem_hpcaccess;      // lock access to HPC
  92static struct semaphore semOperations;  // lock all operations and
  93                                        // access to data structures
  94static struct semaphore sem_exit;       // make sure polling thread goes away
  95static struct task_struct *ibmphp_poll_thread;
  96//----------------------------------------------------------------------------
  97// local function prototypes
  98//----------------------------------------------------------------------------
  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:    ibmphp_hpc_initvars
 114*
 115* Action:  initialize semaphores and variables
 116*---------------------------------------------------------------------*/
 117void __init ibmphp_hpc_initvars(void)
 118{
 119        debug("%s - Entry\n", __func__);
 120
 121        mutex_init(&sem_hpcaccess);
 122        sema_init(&semOperations, 1);
 123        sema_init(&sem_exit, 0);
 124        to_debug = 0;
 125
 126        debug("%s - Exit\n", __func__);
 127}
 128
 129/*----------------------------------------------------------------------
 130* Name:    i2c_ctrl_read
 131*
 132* Action:  read from HPC over I2C
 133*
 134*---------------------------------------------------------------------*/
 135static u8 i2c_ctrl_read(struct controller *ctlr_ptr, void __iomem *WPGBbar, u8 index)
 136{
 137        u8 status;
 138        int i;
 139        void __iomem *wpg_addr; // base addr + offset
 140        unsigned long wpg_data; // data to/from WPG LOHI format
 141        unsigned long ultemp;
 142        unsigned long data;     // actual data HILO format
 143
 144        debug_polling("%s - Entry WPGBbar[%p] index[%x] \n", __func__, WPGBbar, index);
 145
 146        //--------------------------------------------------------------------
 147        // READ - step 1
 148        // read at address, byte length, I2C address (shifted), index
 149        // or read direct, byte length, index
 150        if (ctlr_ptr->ctlr_type == 0x02) {
 151                data = WPG_READATADDR_MASK;
 152                // fill in I2C address
 153                ultemp = (unsigned long)ctlr_ptr->u.wpeg_ctlr.i2c_addr;
 154                ultemp = ultemp >> 1;
 155                data |= (ultemp << 8);
 156
 157                // fill in index
 158                data |= (unsigned long)index;
 159        } else if (ctlr_ptr->ctlr_type == 0x04) {
 160                data = WPG_READDIRECT_MASK;
 161
 162                // fill in index
 163                ultemp = (unsigned long)index;
 164                ultemp = ultemp << 8;
 165                data |= ultemp;
 166        } else {
 167                err("this controller type is not supported \n");
 168                return HPC_ERROR;
 169        }
 170
 171        wpg_data = swab32(data);        // swap data before writing
 172        wpg_addr = WPGBbar + WPG_I2CMOSUP_OFFSET;
 173        writel(wpg_data, wpg_addr);
 174
 175        //--------------------------------------------------------------------
 176        // READ - step 2 : clear the message buffer
 177        data = 0x00000000;
 178        wpg_data = swab32(data);
 179        wpg_addr = WPGBbar + WPG_I2CMBUFL_OFFSET;
 180        writel(wpg_data, wpg_addr);
 181
 182        //--------------------------------------------------------------------
 183        // READ - step 3 : issue start operation, I2C master control bit 30:ON
 184        //                 2020 : [20] OR operation at [20] offset 0x20
 185        data = WPG_I2CMCNTL_STARTOP_MASK;
 186        wpg_data = swab32(data);
 187        wpg_addr = WPGBbar + WPG_I2CMCNTL_OFFSET + WPG_I2C_OR;
 188        writel(wpg_data, wpg_addr);
 189
 190        //--------------------------------------------------------------------
 191        // READ - step 4 : wait until start operation bit clears
 192        i = CMD_COMPLETE_TOUT_SEC;
 193        while (i) {
 194                msleep(10);
 195                wpg_addr = WPGBbar + WPG_I2CMCNTL_OFFSET;
 196                wpg_data = readl(wpg_addr);
 197                data = swab32(wpg_data);
 198                if (!(data & WPG_I2CMCNTL_STARTOP_MASK))
 199                        break;
 200                i--;
 201        }
 202        if (i == 0) {
 203                debug("%s - Error : WPG timeout\n", __func__);
 204                return HPC_ERROR;
 205        }
 206        //--------------------------------------------------------------------
 207        // READ - step 5 : read I2C status register
 208        i = CMD_COMPLETE_TOUT_SEC;
 209        while (i) {
 210                msleep(10);
 211                wpg_addr = WPGBbar + WPG_I2CSTAT_OFFSET;
 212                wpg_data = readl(wpg_addr);
 213                data = swab32(wpg_data);
 214                if (HPC_I2CSTATUS_CHECK(data))
 215                        break;
 216                i--;
 217        }
 218        if (i == 0) {
 219                debug("ctrl_read - Exit Error:I2C timeout\n");
 220                return HPC_ERROR;
 221        }
 222
 223        //--------------------------------------------------------------------
 224        // READ - step 6 : get DATA
 225        wpg_addr = WPGBbar + WPG_I2CMBUFL_OFFSET;
 226        wpg_data = readl(wpg_addr);
 227        data = swab32(wpg_data);
 228
 229        status = (u8) data;
 230
 231        debug_polling("%s - Exit index[%x] status[%x]\n", __func__, index, status);
 232
 233        return (status);
 234}
 235
 236/*----------------------------------------------------------------------
 237* Name:    i2c_ctrl_write
 238*
 239* Action:  write to HPC over I2C
 240*
 241* Return   0 or error codes
 242*---------------------------------------------------------------------*/
 243static u8 i2c_ctrl_write(struct controller *ctlr_ptr, void __iomem *WPGBbar, u8 index, u8 cmd)
 244{
 245        u8 rc;
 246        void __iomem *wpg_addr; // base addr + offset
 247        unsigned long wpg_data; // data to/from WPG LOHI format
 248        unsigned long ultemp;
 249        unsigned long data;     // actual data HILO format
 250        int i;
 251
 252        debug_polling("%s - Entry WPGBbar[%p] index[%x] cmd[%x]\n", __func__, WPGBbar, index, cmd);
 253
 254        rc = 0;
 255        //--------------------------------------------------------------------
 256        // WRITE - step 1
 257        // write at address, byte length, I2C address (shifted), index
 258        // or write direct, byte length, index
 259        data = 0x00000000;
 260
 261        if (ctlr_ptr->ctlr_type == 0x02) {
 262                data = WPG_WRITEATADDR_MASK;
 263                // fill in I2C address
 264                ultemp = (unsigned long)ctlr_ptr->u.wpeg_ctlr.i2c_addr;
 265                ultemp = ultemp >> 1;
 266                data |= (ultemp << 8);
 267
 268                // fill in index
 269                data |= (unsigned long)index;
 270        } else if (ctlr_ptr->ctlr_type == 0x04) {
 271                data = WPG_WRITEDIRECT_MASK;
 272
 273                // fill in index
 274                ultemp = (unsigned long)index;
 275                ultemp = ultemp << 8;
 276                data |= ultemp;
 277        } else {
 278                err("this controller type is not supported \n");
 279                return HPC_ERROR;
 280        }
 281
 282        wpg_data = swab32(data);        // swap data before writing
 283        wpg_addr = WPGBbar + WPG_I2CMOSUP_OFFSET;
 284        writel(wpg_data, wpg_addr);
 285
 286        //--------------------------------------------------------------------
 287        // WRITE - step 2 : clear the message buffer
 288        data = 0x00000000 | (unsigned long)cmd;
 289        wpg_data = swab32(data);
 290        wpg_addr = WPGBbar + WPG_I2CMBUFL_OFFSET;
 291        writel(wpg_data, wpg_addr);
 292
 293        //--------------------------------------------------------------------
 294        // WRITE - step 3 : issue start operation,I2C master control bit 30:ON
 295        //                 2020 : [20] OR operation at [20] offset 0x20
 296        data = WPG_I2CMCNTL_STARTOP_MASK;
 297        wpg_data = swab32(data);
 298        wpg_addr = WPGBbar + WPG_I2CMCNTL_OFFSET + WPG_I2C_OR;
 299        writel(wpg_data, wpg_addr);
 300
 301        //--------------------------------------------------------------------
 302        // WRITE - step 4 : wait until start operation bit clears
 303        i = CMD_COMPLETE_TOUT_SEC;
 304        while (i) {
 305                msleep(10);
 306                wpg_addr = WPGBbar + WPG_I2CMCNTL_OFFSET;
 307                wpg_data = readl(wpg_addr);
 308                data = swab32(wpg_data);
 309                if (!(data & WPG_I2CMCNTL_STARTOP_MASK))
 310                        break;
 311                i--;
 312        }
 313        if (i == 0) {
 314                debug("%s - Exit Error:WPG timeout\n", __func__);
 315                rc = HPC_ERROR;
 316        }
 317
 318        //--------------------------------------------------------------------
 319        // WRITE - step 5 : read I2C status register
 320        i = CMD_COMPLETE_TOUT_SEC;
 321        while (i) {
 322                msleep(10);
 323                wpg_addr = WPGBbar + WPG_I2CSTAT_OFFSET;
 324                wpg_data = readl(wpg_addr);
 325                data = swab32(wpg_data);
 326                if (HPC_I2CSTATUS_CHECK(data))
 327                        break;
 328                i--;
 329        }
 330        if (i == 0) {
 331                debug("ctrl_read - Error : I2C timeout\n");
 332                rc = HPC_ERROR;
 333        }
 334
 335        debug_polling("%s Exit rc[%x]\n", __func__, rc);
 336        return (rc);
 337}
 338
 339//------------------------------------------------------------
 340//  Read from ISA type HPC
 341//------------------------------------------------------------
 342static u8 isa_ctrl_read(struct controller *ctlr_ptr, u8 offset)
 343{
 344        u16 start_address;
 345        u16 end_address;
 346        u8 data;
 347
 348        start_address = ctlr_ptr->u.isa_ctlr.io_start;
 349        end_address = ctlr_ptr->u.isa_ctlr.io_end;
 350        data = inb(start_address + offset);
 351        return data;
 352}
 353
 354//--------------------------------------------------------------
 355// Write to ISA type HPC
 356//--------------------------------------------------------------
 357static void isa_ctrl_write(struct controller *ctlr_ptr, u8 offset, u8 data)
 358{
 359        u16 start_address;
 360        u16 port_address;
 361
 362        start_address = ctlr_ptr->u.isa_ctlr.io_start;
 363        port_address = start_address + (u16) offset;
 364        outb(data, port_address);
 365}
 366
 367static u8 pci_ctrl_read(struct controller *ctrl, u8 offset)
 368{
 369        u8 data = 0x00;
 370        debug("inside pci_ctrl_read\n");
 371        if (ctrl->ctrl_dev)
 372                pci_read_config_byte(ctrl->ctrl_dev, HPC_PCI_OFFSET + offset, &data);
 373        return data;
 374}
 375
 376static u8 pci_ctrl_write(struct controller *ctrl, u8 offset, u8 data)
 377{
 378        u8 rc = -ENODEV;
 379        debug("inside pci_ctrl_write\n");
 380        if (ctrl->ctrl_dev) {
 381                pci_write_config_byte(ctrl->ctrl_dev, HPC_PCI_OFFSET + offset, data);
 382                rc = 0;
 383        }
 384        return rc;
 385}
 386
 387static u8 ctrl_read(struct controller *ctlr, void __iomem *base, u8 offset)
 388{
 389        u8 rc;
 390        switch (ctlr->ctlr_type) {
 391        case 0:
 392                rc = isa_ctrl_read(ctlr, offset);
 393                break;
 394        case 1:
 395                rc = pci_ctrl_read(ctlr, offset);
 396                break;
 397        case 2:
 398        case 4:
 399                rc = i2c_ctrl_read(ctlr, base, offset);
 400                break;
 401        default:
 402                return -ENODEV;
 403        }
 404        return rc;
 405}
 406
 407static u8 ctrl_write(struct controller *ctlr, void __iomem *base, u8 offset, u8 data)
 408{
 409        u8 rc = 0;
 410        switch (ctlr->ctlr_type) {
 411        case 0:
 412                isa_ctrl_write(ctlr, offset, data);
 413                break;
 414        case 1:
 415                rc = pci_ctrl_write(ctlr, offset, data);
 416                break;
 417        case 2:
 418        case 4:
 419                rc = i2c_ctrl_write(ctlr, base, offset, data);
 420                break;
 421        default:
 422                return -ENODEV;
 423        }
 424        return rc;
 425}
 426/*----------------------------------------------------------------------
 427* Name:    hpc_writecmdtoindex()
 428*
 429* Action:  convert a write command to proper index within a controller
 430*
 431* Return   index, HPC_ERROR
 432*---------------------------------------------------------------------*/
 433static u8 hpc_writecmdtoindex(u8 cmd, u8 index)
 434{
 435        u8 rc;
 436
 437        switch (cmd) {
 438        case HPC_CTLR_ENABLEIRQ:        // 0x00.N.15
 439        case HPC_CTLR_CLEARIRQ: // 0x06.N.15
 440        case HPC_CTLR_RESET:    // 0x07.N.15
 441        case HPC_CTLR_IRQSTEER: // 0x08.N.15
 442        case HPC_CTLR_DISABLEIRQ:       // 0x01.N.15
 443        case HPC_ALLSLOT_ON:    // 0x11.N.15
 444        case HPC_ALLSLOT_OFF:   // 0x12.N.15
 445                rc = 0x0F;
 446                break;
 447
 448        case HPC_SLOT_OFF:      // 0x02.Y.0-14
 449        case HPC_SLOT_ON:       // 0x03.Y.0-14
 450        case HPC_SLOT_ATTNOFF:  // 0x04.N.0-14
 451        case HPC_SLOT_ATTNON:   // 0x05.N.0-14
 452        case HPC_SLOT_BLINKLED: // 0x13.N.0-14
 453                rc = index;
 454                break;
 455
 456        case HPC_BUS_33CONVMODE:
 457        case HPC_BUS_66CONVMODE:
 458        case HPC_BUS_66PCIXMODE:
 459        case HPC_BUS_100PCIXMODE:
 460        case HPC_BUS_133PCIXMODE:
 461                rc = index + WPG_1ST_BUS_INDEX - 1;
 462                break;
 463
 464        default:
 465                err("hpc_writecmdtoindex - Error invalid cmd[%x]\n", cmd);
 466                rc = HPC_ERROR;
 467        }
 468
 469        return rc;
 470}
 471
 472/*----------------------------------------------------------------------
 473* Name:    hpc_readcmdtoindex()
 474*
 475* Action:  convert a read command to proper index within a controller
 476*
 477* Return   index, HPC_ERROR
 478*---------------------------------------------------------------------*/
 479static u8 hpc_readcmdtoindex(u8 cmd, u8 index)
 480{
 481        u8 rc;
 482
 483        switch (cmd) {
 484        case READ_CTLRSTATUS:
 485                rc = 0x0F;
 486                break;
 487        case READ_SLOTSTATUS:
 488        case READ_ALLSTAT:
 489                rc = index;
 490                break;
 491        case READ_EXTSLOTSTATUS:
 492                rc = index + WPG_1ST_EXTSLOT_INDEX;
 493                break;
 494        case READ_BUSSTATUS:
 495                rc = index + WPG_1ST_BUS_INDEX - 1;
 496                break;
 497        case READ_SLOTLATCHLOWREG:
 498                rc = 0x28;
 499                break;
 500        case READ_REVLEVEL:
 501                rc = 0x25;
 502                break;
 503        case READ_HPCOPTIONS:
 504                rc = 0x27;
 505                break;
 506        default:
 507                rc = HPC_ERROR;
 508        }
 509        return rc;
 510}
 511
 512/*----------------------------------------------------------------------
 513* Name:    HPCreadslot()
 514*
 515* Action:  issue a READ command to HPC
 516*
 517* Input:   pslot   - cannot be NULL for READ_ALLSTAT
 518*          pstatus - can be NULL for READ_ALLSTAT
 519*
 520* Return   0 or error codes
 521*---------------------------------------------------------------------*/
 522int ibmphp_hpc_readslot(struct slot *pslot, u8 cmd, u8 *pstatus)
 523{
 524        void __iomem *wpg_bbar = NULL;
 525        struct controller *ctlr_ptr;
 526        u8 index, status;
 527        int rc = 0;
 528        int busindex;
 529
 530        debug_polling("%s - Entry pslot[%p] cmd[%x] pstatus[%p]\n", __func__, pslot, cmd, pstatus);
 531
 532        if ((pslot == NULL)
 533            || ((pstatus == NULL) && (cmd != READ_ALLSTAT) && (cmd != READ_BUSSTATUS))) {
 534                rc = -EINVAL;
 535                err("%s - Error invalid pointer, rc[%d]\n", __func__, rc);
 536                return rc;
 537        }
 538
 539        if (cmd == READ_BUSSTATUS) {
 540                busindex = ibmphp_get_bus_index(pslot->bus);
 541                if (busindex < 0) {
 542                        rc = -EINVAL;
 543                        err("%s - Exit Error:invalid bus, rc[%d]\n", __func__, rc);
 544                        return rc;
 545                } else
 546                        index = (u8) busindex;
 547        } else
 548                index = pslot->ctlr_index;
 549
 550        index = hpc_readcmdtoindex(cmd, index);
 551
 552        if (index == HPC_ERROR) {
 553                rc = -EINVAL;
 554                err("%s - Exit Error:invalid index, rc[%d]\n", __func__, rc);
 555                return rc;
 556        }
 557
 558        ctlr_ptr = pslot->ctrl;
 559
 560        get_hpc_access();
 561
 562        //--------------------------------------------------------------------
 563        // map physical address to logical address
 564        //--------------------------------------------------------------------
 565        if ((ctlr_ptr->ctlr_type == 2) || (ctlr_ptr->ctlr_type == 4))
 566                wpg_bbar = ioremap(ctlr_ptr->u.wpeg_ctlr.wpegbbar, WPG_I2C_IOREMAP_SIZE);
 567
 568        //--------------------------------------------------------------------
 569        // check controller status before reading
 570        //--------------------------------------------------------------------
 571        rc = hpc_wait_ctlr_notworking(HPC_CTLR_WORKING_TOUT, ctlr_ptr, wpg_bbar, &status);
 572        if (!rc) {
 573                switch (cmd) {
 574                case READ_ALLSTAT:
 575                        // update the slot structure
 576                        pslot->ctrl->status = status;
 577                        pslot->status = ctrl_read(ctlr_ptr, wpg_bbar, index);
 578                        rc = hpc_wait_ctlr_notworking(HPC_CTLR_WORKING_TOUT, ctlr_ptr, wpg_bbar,
 579                                                       &status);
 580                        if (!rc)
 581                                pslot->ext_status = ctrl_read(ctlr_ptr, wpg_bbar, index + WPG_1ST_EXTSLOT_INDEX);
 582
 583                        break;
 584
 585                case READ_SLOTSTATUS:
 586                        // DO NOT update the slot structure
 587                        *pstatus = ctrl_read(ctlr_ptr, wpg_bbar, index);
 588                        break;
 589
 590                case READ_EXTSLOTSTATUS:
 591                        // DO NOT update the slot structure
 592                        *pstatus = ctrl_read(ctlr_ptr, wpg_bbar, index);
 593                        break;
 594
 595                case READ_CTLRSTATUS:
 596                        // DO NOT update the slot structure
 597                        *pstatus = status;
 598                        break;
 599
 600                case READ_BUSSTATUS:
 601                        pslot->busstatus = ctrl_read(ctlr_ptr, wpg_bbar, index);
 602                        break;
 603                case READ_REVLEVEL:
 604                        *pstatus = ctrl_read(ctlr_ptr, wpg_bbar, index);
 605                        break;
 606                case READ_HPCOPTIONS:
 607                        *pstatus = ctrl_read(ctlr_ptr, wpg_bbar, index);
 608                        break;
 609                case READ_SLOTLATCHLOWREG:
 610                        // DO NOT update the slot structure
 611                        *pstatus = ctrl_read(ctlr_ptr, wpg_bbar, index);
 612                        break;
 613
 614                        // Not used
 615                case READ_ALLSLOT:
 616                        list_for_each_entry(pslot, &ibmphp_slot_head,
 617                                            ibm_slot_list) {
 618                                index = pslot->ctlr_index;
 619                                rc = hpc_wait_ctlr_notworking(HPC_CTLR_WORKING_TOUT, ctlr_ptr,
 620                                                                wpg_bbar, &status);
 621                                if (!rc) {
 622                                        pslot->status = ctrl_read(ctlr_ptr, wpg_bbar, index);
 623                                        rc = hpc_wait_ctlr_notworking(HPC_CTLR_WORKING_TOUT,
 624                                                                        ctlr_ptr, wpg_bbar, &status);
 625                                        if (!rc)
 626                                                pslot->ext_status =
 627                                                    ctrl_read(ctlr_ptr, wpg_bbar,
 628                                                                index + WPG_1ST_EXTSLOT_INDEX);
 629                                } else {
 630                                        err("%s - Error ctrl_read failed\n", __func__);
 631                                        rc = -EINVAL;
 632                                        break;
 633                                }
 634                        }
 635                        break;
 636                default:
 637                        rc = -EINVAL;
 638                        break;
 639                }
 640        }
 641        //--------------------------------------------------------------------
 642        // cleanup
 643        //--------------------------------------------------------------------
 644
 645        // remove physical to logical address mapping
 646        if ((ctlr_ptr->ctlr_type == 2) || (ctlr_ptr->ctlr_type == 4))
 647                iounmap(wpg_bbar);
 648
 649        free_hpc_access();
 650
 651        debug_polling("%s - Exit rc[%d]\n", __func__, rc);
 652        return rc;
 653}
 654
 655/*----------------------------------------------------------------------
 656* Name:    ibmphp_hpc_writeslot()
 657*
 658* Action: issue a WRITE command to HPC
 659*---------------------------------------------------------------------*/
 660int ibmphp_hpc_writeslot(struct slot *pslot, u8 cmd)
 661{
 662        void __iomem *wpg_bbar = NULL;
 663        struct controller *ctlr_ptr;
 664        u8 index, status;
 665        int busindex;
 666        u8 done;
 667        int rc = 0;
 668        int timeout;
 669
 670        debug_polling("%s - Entry pslot[%p] cmd[%x]\n", __func__, pslot, cmd);
 671        if (pslot == NULL) {
 672                rc = -EINVAL;
 673                err("%s - Error Exit rc[%d]\n", __func__, rc);
 674                return rc;
 675        }
 676
 677        if ((cmd == HPC_BUS_33CONVMODE) || (cmd == HPC_BUS_66CONVMODE) ||
 678                (cmd == HPC_BUS_66PCIXMODE) || (cmd == HPC_BUS_100PCIXMODE) ||
 679                (cmd == HPC_BUS_133PCIXMODE)) {
 680                busindex = ibmphp_get_bus_index(pslot->bus);
 681                if (busindex < 0) {
 682                        rc = -EINVAL;
 683                        err("%s - Exit Error:invalid bus, rc[%d]\n", __func__, rc);
 684                        return rc;
 685                } else
 686                        index = (u8) busindex;
 687        } else
 688                index = pslot->ctlr_index;
 689
 690        index = hpc_writecmdtoindex(cmd, index);
 691
 692        if (index == HPC_ERROR) {
 693                rc = -EINVAL;
 694                err("%s - Error Exit rc[%d]\n", __func__, rc);
 695                return rc;
 696        }
 697
 698        ctlr_ptr = pslot->ctrl;
 699
 700        get_hpc_access();
 701
 702        //--------------------------------------------------------------------
 703        // map physical address to logical address
 704        //--------------------------------------------------------------------
 705        if ((ctlr_ptr->ctlr_type == 2) || (ctlr_ptr->ctlr_type == 4)) {
 706                wpg_bbar = ioremap(ctlr_ptr->u.wpeg_ctlr.wpegbbar, WPG_I2C_IOREMAP_SIZE);
 707
 708                debug("%s - ctlr id[%x] physical[%lx] logical[%lx] i2c[%x]\n", __func__,
 709                ctlr_ptr->ctlr_id, (ulong) (ctlr_ptr->u.wpeg_ctlr.wpegbbar), (ulong) wpg_bbar,
 710                ctlr_ptr->u.wpeg_ctlr.i2c_addr);
 711        }
 712        //--------------------------------------------------------------------
 713        // check controller status before writing
 714        //--------------------------------------------------------------------
 715        rc = hpc_wait_ctlr_notworking(HPC_CTLR_WORKING_TOUT, ctlr_ptr, wpg_bbar, &status);
 716        if (!rc) {
 717
 718                ctrl_write(ctlr_ptr, wpg_bbar, index, cmd);
 719
 720                //--------------------------------------------------------------------
 721                // check controller is still not working on the command
 722                //--------------------------------------------------------------------
 723                timeout = CMD_COMPLETE_TOUT_SEC;
 724                done = 0;
 725                while (!done) {
 726                        rc = hpc_wait_ctlr_notworking(HPC_CTLR_WORKING_TOUT, ctlr_ptr, wpg_bbar,
 727                                                        &status);
 728                        if (!rc) {
 729                                if (NEEDTOCHECK_CMDSTATUS(cmd)) {
 730                                        if (CTLR_FINISHED(status) == HPC_CTLR_FINISHED_YES)
 731                                                done = 1;
 732                                } else
 733                                        done = 1;
 734                        }
 735                        if (!done) {
 736                                msleep(1000);
 737                                if (timeout < 1) {
 738                                        done = 1;
 739                                        err("%s - Error command complete timeout\n", __func__);
 740                                        rc = -EFAULT;
 741                                } else
 742                                        timeout--;
 743                        }
 744                }
 745                ctlr_ptr->status = status;
 746        }
 747        // cleanup
 748
 749        // remove physical to logical address mapping
 750        if ((ctlr_ptr->ctlr_type == 2) || (ctlr_ptr->ctlr_type == 4))
 751                iounmap(wpg_bbar);
 752        free_hpc_access();
 753
 754        debug_polling("%s - Exit rc[%d]\n", __func__, rc);
 755        return rc;
 756}
 757
 758/*----------------------------------------------------------------------
 759* Name:    get_hpc_access()
 760*
 761* Action: make sure only one process can access HPC at one time
 762*---------------------------------------------------------------------*/
 763static void get_hpc_access(void)
 764{
 765        mutex_lock(&sem_hpcaccess);
 766}
 767
 768/*----------------------------------------------------------------------
 769* Name:    free_hpc_access()
 770*---------------------------------------------------------------------*/
 771void free_hpc_access(void)
 772{
 773        mutex_unlock(&sem_hpcaccess);
 774}
 775
 776/*----------------------------------------------------------------------
 777* Name:    ibmphp_lock_operations()
 778*
 779* Action: make sure only one process can change the data structure
 780*---------------------------------------------------------------------*/
 781void ibmphp_lock_operations(void)
 782{
 783        down(&semOperations);
 784        to_debug = 1;
 785}
 786
 787/*----------------------------------------------------------------------
 788* Name:    ibmphp_unlock_operations()
 789*---------------------------------------------------------------------*/
 790void ibmphp_unlock_operations(void)
 791{
 792        debug("%s - Entry\n", __func__);
 793        up(&semOperations);
 794        to_debug = 0;
 795        debug("%s - Exit\n", __func__);
 796}
 797
 798/*----------------------------------------------------------------------
 799* Name:    poll_hpc()
 800*---------------------------------------------------------------------*/
 801#define POLL_LATCH_REGISTER     0
 802#define POLL_SLOTS              1
 803#define POLL_SLEEP              2
 804static int poll_hpc(void *data)
 805{
 806        struct slot myslot;
 807        struct slot *pslot = NULL;
 808        int rc;
 809        int poll_state = POLL_LATCH_REGISTER;
 810        u8 oldlatchlow = 0x00;
 811        u8 curlatchlow = 0x00;
 812        int poll_count = 0;
 813        u8 ctrl_count = 0x00;
 814
 815        debug("%s - Entry\n", __func__);
 816
 817        while (!kthread_should_stop()) {
 818                /* try to get the lock to do some kind of hardware access */
 819                down(&semOperations);
 820
 821                switch (poll_state) {
 822                case POLL_LATCH_REGISTER:
 823                        oldlatchlow = curlatchlow;
 824                        ctrl_count = 0x00;
 825                        list_for_each_entry(pslot, &ibmphp_slot_head,
 826                                            ibm_slot_list) {
 827                                if (ctrl_count >= ibmphp_get_total_controllers())
 828                                        break;
 829                                if (pslot->ctrl->ctlr_relative_id == ctrl_count) {
 830                                        ctrl_count++;
 831                                        if (READ_SLOT_LATCH(pslot->ctrl)) {
 832                                                rc = ibmphp_hpc_readslot(pslot,
 833                                                                          READ_SLOTLATCHLOWREG,
 834                                                                          &curlatchlow);
 835                                                if (oldlatchlow != curlatchlow)
 836                                                        process_changeinlatch(oldlatchlow,
 837                                                                               curlatchlow,
 838                                                                               pslot->ctrl);
 839                                        }
 840                                }
 841                        }
 842                        ++poll_count;
 843                        poll_state = POLL_SLEEP;
 844                        break;
 845                case POLL_SLOTS:
 846                        list_for_each_entry(pslot, &ibmphp_slot_head,
 847                                            ibm_slot_list) {
 848                                // make a copy of the old status
 849                                memcpy((void *) &myslot, (void *) pslot,
 850                                        sizeof(struct slot));
 851                                rc = ibmphp_hpc_readslot(pslot, READ_ALLSTAT, NULL);
 852                                if ((myslot.status != pslot->status)
 853                                    || (myslot.ext_status != pslot->ext_status))
 854                                        process_changeinstatus(pslot, &myslot);
 855                        }
 856                        ctrl_count = 0x00;
 857                        list_for_each_entry(pslot, &ibmphp_slot_head,
 858                                            ibm_slot_list) {
 859                                if (ctrl_count >= ibmphp_get_total_controllers())
 860                                        break;
 861                                if (pslot->ctrl->ctlr_relative_id == ctrl_count) {
 862                                        ctrl_count++;
 863                                        if (READ_SLOT_LATCH(pslot->ctrl))
 864                                                rc = ibmphp_hpc_readslot(pslot,
 865                                                                          READ_SLOTLATCHLOWREG,
 866                                                                          &curlatchlow);
 867                                }
 868                        }
 869                        ++poll_count;
 870                        poll_state = POLL_SLEEP;
 871                        break;
 872                case POLL_SLEEP:
 873                        /* don't sleep with a lock on the hardware */
 874                        up(&semOperations);
 875                        msleep(POLL_INTERVAL_SEC * 1000);
 876
 877                        if (kthread_should_stop())
 878                                goto out_sleep;
 879
 880                        down(&semOperations);
 881
 882                        if (poll_count >= POLL_LATCH_CNT) {
 883                                poll_count = 0;
 884                                poll_state = POLL_SLOTS;
 885                        } else
 886                                poll_state = POLL_LATCH_REGISTER;
 887                        break;
 888                }
 889                /* give up the hardware semaphore */
 890                up(&semOperations);
 891                /* sleep for a short time just for good measure */
 892out_sleep:
 893                msleep(100);
 894        }
 895        up(&sem_exit);
 896        debug("%s - Exit\n", __func__);
 897        return 0;
 898}
 899
 900
 901/*----------------------------------------------------------------------
 902* Name:    process_changeinstatus
 903*
 904* Action:  compare old and new slot status, process the change in status
 905*
 906* Input:   pointer to slot struct, old slot struct
 907*
 908* Return   0 or error codes
 909* Value:
 910*
 911* Side
 912* Effects: None.
 913*
 914* Notes:
 915*---------------------------------------------------------------------*/
 916static int process_changeinstatus(struct slot *pslot, struct slot *poldslot)
 917{
 918        u8 status;
 919        int rc = 0;
 920        u8 disable = 0;
 921        u8 update = 0;
 922
 923        debug("process_changeinstatus - Entry pslot[%p], poldslot[%p]\n", pslot, poldslot);
 924
 925        // bit 0 - HPC_SLOT_POWER
 926        if ((pslot->status & 0x01) != (poldslot->status & 0x01))
 927                update = 1;
 928
 929        // bit 1 - HPC_SLOT_CONNECT
 930        // ignore
 931
 932        // bit 2 - HPC_SLOT_ATTN
 933        if ((pslot->status & 0x04) != (poldslot->status & 0x04))
 934                update = 1;
 935
 936        // bit 3 - HPC_SLOT_PRSNT2
 937        // bit 4 - HPC_SLOT_PRSNT1
 938        if (((pslot->status & 0x08) != (poldslot->status & 0x08))
 939                || ((pslot->status & 0x10) != (poldslot->status & 0x10)))
 940                update = 1;
 941
 942        // bit 5 - HPC_SLOT_PWRGD
 943        if ((pslot->status & 0x20) != (poldslot->status & 0x20))
 944                // OFF -> ON: ignore, ON -> OFF: disable slot
 945                if ((poldslot->status & 0x20) && (SLOT_CONNECT(poldslot->status) == HPC_SLOT_CONNECTED) && (SLOT_PRESENT(poldslot->status)))
 946                        disable = 1;
 947
 948        // bit 6 - HPC_SLOT_BUS_SPEED
 949        // ignore
 950
 951        // bit 7 - HPC_SLOT_LATCH
 952        if ((pslot->status & 0x80) != (poldslot->status & 0x80)) {
 953                update = 1;
 954                // OPEN -> CLOSE
 955                if (pslot->status & 0x80) {
 956                        if (SLOT_PWRGD(pslot->status)) {
 957                                // power goes on and off after closing latch
 958                                // check again to make sure power is still ON
 959                                msleep(1000);
 960                                rc = ibmphp_hpc_readslot(pslot, READ_SLOTSTATUS, &status);
 961                                if (SLOT_PWRGD(status))
 962                                        update = 1;
 963                                else    // overwrite power in pslot to OFF
 964                                        pslot->status &= ~HPC_SLOT_POWER;
 965                        }
 966                }
 967                // CLOSE -> OPEN
 968                else if ((SLOT_PWRGD(poldslot->status) == HPC_SLOT_PWRGD_GOOD)
 969                        && (SLOT_CONNECT(poldslot->status) == HPC_SLOT_CONNECTED) && (SLOT_PRESENT(poldslot->status))) {
 970                        disable = 1;
 971                }
 972                // else - ignore
 973        }
 974        // bit 4 - HPC_SLOT_BLINK_ATTN
 975        if ((pslot->ext_status & 0x08) != (poldslot->ext_status & 0x08))
 976                update = 1;
 977
 978        if (disable) {
 979                debug("process_changeinstatus - disable slot\n");
 980                pslot->flag = 0;
 981                rc = ibmphp_do_disable_slot(pslot);
 982        }
 983
 984        if (update || disable)
 985                ibmphp_update_slot_info(pslot);
 986
 987        debug("%s - Exit rc[%d] disable[%x] update[%x]\n", __func__, rc, disable, update);
 988
 989        return rc;
 990}
 991
 992/*----------------------------------------------------------------------
 993* Name:    process_changeinlatch
 994*
 995* Action:  compare old and new latch reg status, process the change
 996*
 997* Input:   old and current latch register status
 998*
 999* Return   0 or error codes
1000* Value:
1001*---------------------------------------------------------------------*/
1002static int process_changeinlatch(u8 old, u8 new, struct controller *ctrl)
1003{
1004        struct slot myslot, *pslot;
1005        u8 i;
1006        u8 mask;
1007        int rc = 0;
1008
1009        debug("%s - Entry old[%x], new[%x]\n", __func__, old, new);
1010        // bit 0 reserved, 0 is LSB, check bit 1-6 for 6 slots
1011
1012        for (i = ctrl->starting_slot_num; i <= ctrl->ending_slot_num; i++) {
1013                mask = 0x01 << i;
1014                if ((mask & old) != (mask & new)) {
1015                        pslot = ibmphp_get_slot_from_physical_num(i);
1016                        if (pslot) {
1017                                memcpy((void *) &myslot, (void *) pslot, sizeof(struct slot));
1018                                rc = ibmphp_hpc_readslot(pslot, READ_ALLSTAT, NULL);
1019                                debug("%s - call process_changeinstatus for slot[%d]\n", __func__, i);
1020                                process_changeinstatus(pslot, &myslot);
1021                        } else {
1022                                rc = -EINVAL;
1023                                err("%s - Error bad pointer for slot[%d]\n", __func__, i);
1024                        }
1025                }
1026        }
1027        debug("%s - Exit rc[%d]\n", __func__, rc);
1028        return rc;
1029}
1030
1031/*----------------------------------------------------------------------
1032* Name:    ibmphp_hpc_start_poll_thread
1033*
1034* Action:  start polling thread
1035*---------------------------------------------------------------------*/
1036int __init ibmphp_hpc_start_poll_thread(void)
1037{
1038        debug("%s - Entry\n", __func__);
1039
1040        ibmphp_poll_thread = kthread_run(poll_hpc, NULL, "hpc_poll");
1041        if (IS_ERR(ibmphp_poll_thread)) {
1042                err("%s - Error, thread not started\n", __func__);
1043                return PTR_ERR(ibmphp_poll_thread);
1044        }
1045        return 0;
1046}
1047
1048/*----------------------------------------------------------------------
1049* Name:    ibmphp_hpc_stop_poll_thread
1050*
1051* Action:  stop polling thread and cleanup
1052*---------------------------------------------------------------------*/
1053void __exit ibmphp_hpc_stop_poll_thread(void)
1054{
1055        debug("%s - Entry\n", __func__);
1056
1057        kthread_stop(ibmphp_poll_thread);
1058        debug("before locking operations\n");
1059        ibmphp_lock_operations();
1060        debug("after locking operations\n");
1061
1062        // wait for poll thread to exit
1063        debug("before sem_exit down\n");
1064        down(&sem_exit);
1065        debug("after sem_exit down\n");
1066
1067        // cleanup
1068        debug("before free_hpc_access\n");
1069        free_hpc_access();
1070        debug("after free_hpc_access\n");
1071        ibmphp_unlock_operations();
1072        debug("after unlock operations\n");
1073        up(&sem_exit);
1074        debug("after sem exit up\n");
1075
1076        debug("%s - Exit\n", __func__);
1077}
1078
1079/*----------------------------------------------------------------------
1080* Name:    hpc_wait_ctlr_notworking
1081*
1082* Action:  wait until the controller is in a not working state
1083*
1084* Return   0, HPC_ERROR
1085* Value:
1086*---------------------------------------------------------------------*/
1087static int hpc_wait_ctlr_notworking(int timeout, struct controller *ctlr_ptr, void __iomem *wpg_bbar,
1088                                    u8 *pstatus)
1089{
1090        int rc = 0;
1091        u8 done = 0;
1092
1093        debug_polling("hpc_wait_ctlr_notworking - Entry timeout[%d]\n", timeout);
1094
1095        while (!done) {
1096                *pstatus = ctrl_read(ctlr_ptr, wpg_bbar, WPG_CTLR_INDEX);
1097                if (*pstatus == HPC_ERROR) {
1098                        rc = HPC_ERROR;
1099                        done = 1;
1100                }
1101                if (CTLR_WORKING(*pstatus) == HPC_CTLR_WORKING_NO)
1102                        done = 1;
1103                if (!done) {
1104                        msleep(1000);
1105                        if (timeout < 1) {
1106                                done = 1;
1107                                err("HPCreadslot - Error ctlr timeout\n");
1108                                rc = HPC_ERROR;
1109                        } else
1110                                timeout--;
1111                }
1112        }
1113        debug_polling("hpc_wait_ctlr_notworking - Exit rc[%x] status[%x]\n", rc, *pstatus);
1114        return rc;
1115}
1116