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