linux/arch/ppc/syslib/ipic.c
<<
>>
Prefs
   1/*
   2 * arch/ppc/syslib/ipic.c
   3 *
   4 * IPIC routines implementations.
   5 *
   6 * Copyright 2005 Freescale Semiconductor, Inc.
   7 *
   8 * This program is free software; you can redistribute  it and/or modify it
   9 * under  the terms of  the GNU General  Public License as published by the
  10 * Free Software Foundation;  either version 2 of the  License, or (at your
  11 * option) any later version.
  12 */
  13#include <linux/kernel.h>
  14#include <linux/init.h>
  15#include <linux/errno.h>
  16#include <linux/reboot.h>
  17#include <linux/slab.h>
  18#include <linux/stddef.h>
  19#include <linux/sched.h>
  20#include <linux/signal.h>
  21#include <linux/sysdev.h>
  22#include <asm/irq.h>
  23#include <asm/io.h>
  24#include <asm/ipic.h>
  25#include <asm/mpc83xx.h>
  26
  27#include "ipic.h"
  28
  29static struct ipic p_ipic;
  30static struct ipic * primary_ipic;
  31
  32static struct ipic_info ipic_info[] = {
  33        [9] = {
  34                .pend   = IPIC_SIPNR_H,
  35                .mask   = IPIC_SIMSR_H,
  36                .prio   = IPIC_SIPRR_D,
  37                .force  = IPIC_SIFCR_H,
  38                .bit    = 24,
  39                .prio_mask = 0,
  40        },
  41        [10] = {
  42                .pend   = IPIC_SIPNR_H,
  43                .mask   = IPIC_SIMSR_H,
  44                .prio   = IPIC_SIPRR_D,
  45                .force  = IPIC_SIFCR_H,
  46                .bit    = 25,
  47                .prio_mask = 1,
  48        },
  49        [11] = {
  50                .pend   = IPIC_SIPNR_H,
  51                .mask   = IPIC_SIMSR_H,
  52                .prio   = IPIC_SIPRR_D,
  53                .force  = IPIC_SIFCR_H,
  54                .bit    = 26,
  55                .prio_mask = 2,
  56        },
  57        [14] = {
  58                .pend   = IPIC_SIPNR_H,
  59                .mask   = IPIC_SIMSR_H,
  60                .prio   = IPIC_SIPRR_D,
  61                .force  = IPIC_SIFCR_H,
  62                .bit    = 29,
  63                .prio_mask = 5,
  64        },
  65        [15] = {
  66                .pend   = IPIC_SIPNR_H,
  67                .mask   = IPIC_SIMSR_H,
  68                .prio   = IPIC_SIPRR_D,
  69                .force  = IPIC_SIFCR_H,
  70                .bit    = 30,
  71                .prio_mask = 6,
  72        },
  73        [16] = {
  74                .pend   = IPIC_SIPNR_H,
  75                .mask   = IPIC_SIMSR_H,
  76                .prio   = IPIC_SIPRR_D,
  77                .force  = IPIC_SIFCR_H,
  78                .bit    = 31,
  79                .prio_mask = 7,
  80        },
  81        [17] = {
  82                .pend   = IPIC_SEPNR,
  83                .mask   = IPIC_SEMSR,
  84                .prio   = IPIC_SMPRR_A,
  85                .force  = IPIC_SEFCR,
  86                .bit    = 1,
  87                .prio_mask = 5,
  88        },
  89        [18] = {
  90                .pend   = IPIC_SEPNR,
  91                .mask   = IPIC_SEMSR,
  92                .prio   = IPIC_SMPRR_A,
  93                .force  = IPIC_SEFCR,
  94                .bit    = 2,
  95                .prio_mask = 6,
  96        },
  97        [19] = {
  98                .pend   = IPIC_SEPNR,
  99                .mask   = IPIC_SEMSR,
 100                .prio   = IPIC_SMPRR_A,
 101                .force  = IPIC_SEFCR,
 102                .bit    = 3,
 103                .prio_mask = 7,
 104        },
 105        [20] = {
 106                .pend   = IPIC_SEPNR,
 107                .mask   = IPIC_SEMSR,
 108                .prio   = IPIC_SMPRR_B,
 109                .force  = IPIC_SEFCR,
 110                .bit    = 4,
 111                .prio_mask = 4,
 112        },
 113        [21] = {
 114                .pend   = IPIC_SEPNR,
 115                .mask   = IPIC_SEMSR,
 116                .prio   = IPIC_SMPRR_B,
 117                .force  = IPIC_SEFCR,
 118                .bit    = 5,
 119                .prio_mask = 5,
 120        },
 121        [22] = {
 122                .pend   = IPIC_SEPNR,
 123                .mask   = IPIC_SEMSR,
 124                .prio   = IPIC_SMPRR_B,
 125                .force  = IPIC_SEFCR,
 126                .bit    = 6,
 127                .prio_mask = 6,
 128        },
 129        [23] = {
 130                .pend   = IPIC_SEPNR,
 131                .mask   = IPIC_SEMSR,
 132                .prio   = IPIC_SMPRR_B,
 133                .force  = IPIC_SEFCR,
 134                .bit    = 7,
 135                .prio_mask = 7,
 136        },
 137        [32] = {
 138                .pend   = IPIC_SIPNR_H,
 139                .mask   = IPIC_SIMSR_H,
 140                .prio   = IPIC_SIPRR_A,
 141                .force  = IPIC_SIFCR_H,
 142                .bit    = 0,
 143                .prio_mask = 0,
 144        },
 145        [33] = {
 146                .pend   = IPIC_SIPNR_H,
 147                .mask   = IPIC_SIMSR_H,
 148                .prio   = IPIC_SIPRR_A,
 149                .force  = IPIC_SIFCR_H,
 150                .bit    = 1,
 151                .prio_mask = 1,
 152        },
 153        [34] = {
 154                .pend   = IPIC_SIPNR_H,
 155                .mask   = IPIC_SIMSR_H,
 156                .prio   = IPIC_SIPRR_A,
 157                .force  = IPIC_SIFCR_H,
 158                .bit    = 2,
 159                .prio_mask = 2,
 160        },
 161        [35] = {
 162                .pend   = IPIC_SIPNR_H,
 163                .mask   = IPIC_SIMSR_H,
 164                .prio   = IPIC_SIPRR_A,
 165                .force  = IPIC_SIFCR_H,
 166                .bit    = 3,
 167                .prio_mask = 3,
 168        },
 169        [36] = {
 170                .pend   = IPIC_SIPNR_H,
 171                .mask   = IPIC_SIMSR_H,
 172                .prio   = IPIC_SIPRR_A,
 173                .force  = IPIC_SIFCR_H,
 174                .bit    = 4,
 175                .prio_mask = 4,
 176        },
 177        [37] = {
 178                .pend   = IPIC_SIPNR_H,
 179                .mask   = IPIC_SIMSR_H,
 180                .prio   = IPIC_SIPRR_A,
 181                .force  = IPIC_SIFCR_H,
 182                .bit    = 5,
 183                .prio_mask = 5,
 184        },
 185        [38] = {
 186                .pend   = IPIC_SIPNR_H,
 187                .mask   = IPIC_SIMSR_H,
 188                .prio   = IPIC_SIPRR_A,
 189                .force  = IPIC_SIFCR_H,
 190                .bit    = 6,
 191                .prio_mask = 6,
 192        },
 193        [39] = {
 194                .pend   = IPIC_SIPNR_H,
 195                .mask   = IPIC_SIMSR_H,
 196                .prio   = IPIC_SIPRR_A,
 197                .force  = IPIC_SIFCR_H,
 198                .bit    = 7,
 199                .prio_mask = 7,
 200        },
 201        [48] = {
 202                .pend   = IPIC_SEPNR,
 203                .mask   = IPIC_SEMSR,
 204                .prio   = IPIC_SMPRR_A,
 205                .force  = IPIC_SEFCR,
 206                .bit    = 0,
 207                .prio_mask = 4,
 208        },
 209        [64] = {
 210                .pend   = IPIC_SIPNR_H,
 211                .mask   = IPIC_SIMSR_L,
 212                .prio   = IPIC_SMPRR_A,
 213                .force  = IPIC_SIFCR_L,
 214                .bit    = 0,
 215                .prio_mask = 0,
 216        },
 217        [65] = {
 218                .pend   = IPIC_SIPNR_H,
 219                .mask   = IPIC_SIMSR_L,
 220                .prio   = IPIC_SMPRR_A,
 221                .force  = IPIC_SIFCR_L,
 222                .bit    = 1,
 223                .prio_mask = 1,
 224        },
 225        [66] = {
 226                .pend   = IPIC_SIPNR_H,
 227                .mask   = IPIC_SIMSR_L,
 228                .prio   = IPIC_SMPRR_A,
 229                .force  = IPIC_SIFCR_L,
 230                .bit    = 2,
 231                .prio_mask = 2,
 232        },
 233        [67] = {
 234                .pend   = IPIC_SIPNR_H,
 235                .mask   = IPIC_SIMSR_L,
 236                .prio   = IPIC_SMPRR_A,
 237                .force  = IPIC_SIFCR_L,
 238                .bit    = 3,
 239                .prio_mask = 3,
 240        },
 241        [68] = {
 242                .pend   = IPIC_SIPNR_H,
 243                .mask   = IPIC_SIMSR_L,
 244                .prio   = IPIC_SMPRR_B,
 245                .force  = IPIC_SIFCR_L,
 246                .bit    = 4,
 247                .prio_mask = 0,
 248        },
 249        [69] = {
 250                .pend   = IPIC_SIPNR_H,
 251                .mask   = IPIC_SIMSR_L,
 252                .prio   = IPIC_SMPRR_B,
 253                .force  = IPIC_SIFCR_L,
 254                .bit    = 5,
 255                .prio_mask = 1,
 256        },
 257        [70] = {
 258                .pend   = IPIC_SIPNR_H,
 259                .mask   = IPIC_SIMSR_L,
 260                .prio   = IPIC_SMPRR_B,
 261                .force  = IPIC_SIFCR_L,
 262                .bit    = 6,
 263                .prio_mask = 2,
 264        },
 265        [71] = {
 266                .pend   = IPIC_SIPNR_H,
 267                .mask   = IPIC_SIMSR_L,
 268                .prio   = IPIC_SMPRR_B,
 269                .force  = IPIC_SIFCR_L,
 270                .bit    = 7,
 271                .prio_mask = 3,
 272        },
 273        [72] = {
 274                .pend   = IPIC_SIPNR_H,
 275                .mask   = IPIC_SIMSR_L,
 276                .prio   = 0,
 277                .force  = IPIC_SIFCR_L,
 278                .bit    = 8,
 279        },
 280        [73] = {
 281                .pend   = IPIC_SIPNR_H,
 282                .mask   = IPIC_SIMSR_L,
 283                .prio   = 0,
 284                .force  = IPIC_SIFCR_L,
 285                .bit    = 9,
 286        },
 287        [74] = {
 288                .pend   = IPIC_SIPNR_H,
 289                .mask   = IPIC_SIMSR_L,
 290                .prio   = 0,
 291                .force  = IPIC_SIFCR_L,
 292                .bit    = 10,
 293        },
 294        [75] = {
 295                .pend   = IPIC_SIPNR_H,
 296                .mask   = IPIC_SIMSR_L,
 297                .prio   = 0,
 298                .force  = IPIC_SIFCR_L,
 299                .bit    = 11,
 300        },
 301        [76] = {
 302                .pend   = IPIC_SIPNR_H,
 303                .mask   = IPIC_SIMSR_L,
 304                .prio   = 0,
 305                .force  = IPIC_SIFCR_L,
 306                .bit    = 12,
 307        },
 308        [77] = {
 309                .pend   = IPIC_SIPNR_H,
 310                .mask   = IPIC_SIMSR_L,
 311                .prio   = 0,
 312                .force  = IPIC_SIFCR_L,
 313                .bit    = 13,
 314        },
 315        [78] = {
 316                .pend   = IPIC_SIPNR_H,
 317                .mask   = IPIC_SIMSR_L,
 318                .prio   = 0,
 319                .force  = IPIC_SIFCR_L,
 320                .bit    = 14,
 321        },
 322        [79] = {
 323                .pend   = IPIC_SIPNR_H,
 324                .mask   = IPIC_SIMSR_L,
 325                .prio   = 0,
 326                .force  = IPIC_SIFCR_L,
 327                .bit    = 15,
 328        },
 329        [80] = {
 330                .pend   = IPIC_SIPNR_H,
 331                .mask   = IPIC_SIMSR_L,
 332                .prio   = 0,
 333                .force  = IPIC_SIFCR_L,
 334                .bit    = 16,
 335        },
 336        [84] = {
 337                .pend   = IPIC_SIPNR_H,
 338                .mask   = IPIC_SIMSR_L,
 339                .prio   = 0,
 340                .force  = IPIC_SIFCR_L,
 341                .bit    = 20,
 342        },
 343        [85] = {
 344                .pend   = IPIC_SIPNR_H,
 345                .mask   = IPIC_SIMSR_L,
 346                .prio   = 0,
 347                .force  = IPIC_SIFCR_L,
 348                .bit    = 21,
 349        },
 350        [90] = {
 351                .pend   = IPIC_SIPNR_H,
 352                .mask   = IPIC_SIMSR_L,
 353                .prio   = 0,
 354                .force  = IPIC_SIFCR_L,
 355                .bit    = 26,
 356        },
 357        [91] = {
 358                .pend   = IPIC_SIPNR_H,
 359                .mask   = IPIC_SIMSR_L,
 360                .prio   = 0,
 361                .force  = IPIC_SIFCR_L,
 362                .bit    = 27,
 363        },
 364};
 365
 366static inline u32 ipic_read(volatile u32 __iomem *base, unsigned int reg)
 367{
 368        return in_be32(base + (reg >> 2));
 369}
 370
 371static inline void ipic_write(volatile u32 __iomem *base, unsigned int reg, u32 value)
 372{
 373        out_be32(base + (reg >> 2), value);
 374}
 375
 376static inline struct ipic * ipic_from_irq(unsigned int irq)
 377{
 378        return primary_ipic;
 379}
 380
 381static void ipic_enable_irq(unsigned int irq)
 382{
 383        struct ipic *ipic = ipic_from_irq(irq);
 384        unsigned int src = irq - ipic->irq_offset;
 385        u32 temp;
 386
 387        temp = ipic_read(ipic->regs, ipic_info[src].mask);
 388        temp |= (1 << (31 - ipic_info[src].bit));
 389        ipic_write(ipic->regs, ipic_info[src].mask, temp);
 390}
 391
 392static void ipic_disable_irq(unsigned int irq)
 393{
 394        struct ipic *ipic = ipic_from_irq(irq);
 395        unsigned int src = irq - ipic->irq_offset;
 396        u32 temp;
 397
 398        temp = ipic_read(ipic->regs, ipic_info[src].mask);
 399        temp &= ~(1 << (31 - ipic_info[src].bit));
 400        ipic_write(ipic->regs, ipic_info[src].mask, temp);
 401}
 402
 403static void ipic_disable_irq_and_ack(unsigned int irq)
 404{
 405        struct ipic *ipic = ipic_from_irq(irq);
 406        unsigned int src = irq - ipic->irq_offset;
 407        u32 temp;
 408
 409        ipic_disable_irq(irq);
 410
 411        temp = ipic_read(ipic->regs, ipic_info[src].pend);
 412        temp |= (1 << (31 - ipic_info[src].bit));
 413        ipic_write(ipic->regs, ipic_info[src].pend, temp);
 414}
 415
 416static void ipic_end_irq(unsigned int irq)
 417{
 418        if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
 419                ipic_enable_irq(irq);
 420}
 421
 422struct hw_interrupt_type ipic = {
 423        .typename = " IPIC  ",
 424        .enable = ipic_enable_irq,
 425        .disable = ipic_disable_irq,
 426        .ack = ipic_disable_irq_and_ack,
 427        .end = ipic_end_irq,
 428};
 429
 430void __init ipic_init(phys_addr_t phys_addr,
 431                unsigned int flags,
 432                unsigned int irq_offset,
 433                unsigned char *senses,
 434                unsigned int senses_count)
 435{
 436        u32 i, temp = 0;
 437
 438        primary_ipic = &p_ipic;
 439        primary_ipic->regs = ioremap(phys_addr, MPC83xx_IPIC_SIZE);
 440
 441        primary_ipic->irq_offset = irq_offset;
 442
 443        ipic_write(primary_ipic->regs, IPIC_SICNR, 0x0);
 444
 445        /* default priority scheme is grouped. If spread mode is required
 446         * configure SICFR accordingly */
 447        if (flags & IPIC_SPREADMODE_GRP_A)
 448                temp |= SICFR_IPSA;
 449        if (flags & IPIC_SPREADMODE_GRP_D)
 450                temp |= SICFR_IPSD;
 451        if (flags & IPIC_SPREADMODE_MIX_A)
 452                temp |= SICFR_MPSA;
 453        if (flags & IPIC_SPREADMODE_MIX_B)
 454                temp |= SICFR_MPSB;
 455
 456        ipic_write(primary_ipic->regs, IPIC_SICNR, temp);
 457
 458        /* handle MCP route */
 459        temp = 0;
 460        if (flags & IPIC_DISABLE_MCP_OUT)
 461                temp = SERCR_MCPR;
 462        ipic_write(primary_ipic->regs, IPIC_SERCR, temp);
 463
 464        /* handle routing of IRQ0 to MCP */
 465        temp = ipic_read(primary_ipic->regs, IPIC_SEMSR);
 466
 467        if (flags & IPIC_IRQ0_MCP)
 468                temp |= SEMSR_SIRQ0;
 469        else
 470                temp &= ~SEMSR_SIRQ0;
 471
 472        ipic_write(primary_ipic->regs, IPIC_SEMSR, temp);
 473
 474        for (i = 0 ; i < NR_IPIC_INTS ; i++) {
 475                irq_desc[i+irq_offset].chip = &ipic;
 476                irq_desc[i+irq_offset].status = IRQ_LEVEL;
 477        }
 478
 479        temp = 0;
 480        for (i = 0 ; i < senses_count ; i++) {
 481                if ((senses[i] & IRQ_SENSE_MASK) == IRQ_SENSE_EDGE) {
 482                        temp |= 1 << (15 - i);
 483                        if (i != 0)
 484                                irq_desc[i + irq_offset + MPC83xx_IRQ_EXT1 - 1].status = 0;
 485                        else
 486                                irq_desc[irq_offset + MPC83xx_IRQ_EXT0].status = 0;
 487                }
 488        }
 489        ipic_write(primary_ipic->regs, IPIC_SECNR, temp);
 490
 491        printk ("IPIC (%d IRQ sources, %d External IRQs) at %p\n", NR_IPIC_INTS,
 492                        senses_count, primary_ipic->regs);
 493}
 494
 495int ipic_set_priority(unsigned int irq, unsigned int priority)
 496{
 497        struct ipic *ipic = ipic_from_irq(irq);
 498        unsigned int src = irq - ipic->irq_offset;
 499        u32 temp;
 500
 501        if (priority > 7)
 502                return -EINVAL;
 503        if (src > 127)
 504                return -EINVAL;
 505        if (ipic_info[src].prio == 0)
 506                return -EINVAL;
 507
 508        temp = ipic_read(ipic->regs, ipic_info[src].prio);
 509
 510        if (priority < 4) {
 511                temp &= ~(0x7 << (20 + (3 - priority) * 3));
 512                temp |= ipic_info[src].prio_mask << (20 + (3 - priority) * 3);
 513        } else {
 514                temp &= ~(0x7 << (4 + (7 - priority) * 3));
 515                temp |= ipic_info[src].prio_mask << (4 + (7 - priority) * 3);
 516        }
 517
 518        ipic_write(ipic->regs, ipic_info[src].prio, temp);
 519
 520        return 0;
 521}
 522
 523void ipic_set_highest_priority(unsigned int irq)
 524{
 525        struct ipic *ipic = ipic_from_irq(irq);
 526        unsigned int src = irq - ipic->irq_offset;
 527        u32 temp;
 528
 529        temp = ipic_read(ipic->regs, IPIC_SICFR);
 530
 531        /* clear and set HPI */
 532        temp &= 0x7f000000;
 533        temp |= (src & 0x7f) << 24;
 534
 535        ipic_write(ipic->regs, IPIC_SICFR, temp);
 536}
 537
 538void ipic_set_default_priority(void)
 539{
 540        ipic_set_priority(MPC83xx_IRQ_TSEC1_TX, 0);
 541        ipic_set_priority(MPC83xx_IRQ_TSEC1_RX, 1);
 542        ipic_set_priority(MPC83xx_IRQ_TSEC1_ERROR, 2);
 543        ipic_set_priority(MPC83xx_IRQ_TSEC2_TX, 3);
 544        ipic_set_priority(MPC83xx_IRQ_TSEC2_RX, 4);
 545        ipic_set_priority(MPC83xx_IRQ_TSEC2_ERROR, 5);
 546        ipic_set_priority(MPC83xx_IRQ_USB2_DR, 6);
 547        ipic_set_priority(MPC83xx_IRQ_USB2_MPH, 7);
 548
 549        ipic_set_priority(MPC83xx_IRQ_UART1, 0);
 550        ipic_set_priority(MPC83xx_IRQ_UART2, 1);
 551        ipic_set_priority(MPC83xx_IRQ_SEC2, 2);
 552        ipic_set_priority(MPC83xx_IRQ_IIC1, 5);
 553        ipic_set_priority(MPC83xx_IRQ_IIC2, 6);
 554        ipic_set_priority(MPC83xx_IRQ_SPI, 7);
 555        ipic_set_priority(MPC83xx_IRQ_RTC_SEC, 0);
 556        ipic_set_priority(MPC83xx_IRQ_PIT, 1);
 557        ipic_set_priority(MPC83xx_IRQ_PCI1, 2);
 558        ipic_set_priority(MPC83xx_IRQ_PCI2, 3);
 559        ipic_set_priority(MPC83xx_IRQ_EXT0, 4);
 560        ipic_set_priority(MPC83xx_IRQ_EXT1, 5);
 561        ipic_set_priority(MPC83xx_IRQ_EXT2, 6);
 562        ipic_set_priority(MPC83xx_IRQ_EXT3, 7);
 563        ipic_set_priority(MPC83xx_IRQ_RTC_ALR, 0);
 564        ipic_set_priority(MPC83xx_IRQ_MU, 1);
 565        ipic_set_priority(MPC83xx_IRQ_SBA, 2);
 566        ipic_set_priority(MPC83xx_IRQ_DMA, 3);
 567        ipic_set_priority(MPC83xx_IRQ_EXT4, 4);
 568        ipic_set_priority(MPC83xx_IRQ_EXT5, 5);
 569        ipic_set_priority(MPC83xx_IRQ_EXT6, 6);
 570        ipic_set_priority(MPC83xx_IRQ_EXT7, 7);
 571}
 572
 573void ipic_enable_mcp(enum ipic_mcp_irq mcp_irq)
 574{
 575        struct ipic *ipic = primary_ipic;
 576        u32 temp;
 577
 578        temp = ipic_read(ipic->regs, IPIC_SERMR);
 579        temp |= (1 << (31 - mcp_irq));
 580        ipic_write(ipic->regs, IPIC_SERMR, temp);
 581}
 582
 583void ipic_disable_mcp(enum ipic_mcp_irq mcp_irq)
 584{
 585        struct ipic *ipic = primary_ipic;
 586        u32 temp;
 587
 588        temp = ipic_read(ipic->regs, IPIC_SERMR);
 589        temp &= (1 << (31 - mcp_irq));
 590        ipic_write(ipic->regs, IPIC_SERMR, temp);
 591}
 592
 593u32 ipic_get_mcp_status(void)
 594{
 595        return ipic_read(primary_ipic->regs, IPIC_SERMR);
 596}
 597
 598void ipic_clear_mcp_status(u32 mask)
 599{
 600        ipic_write(primary_ipic->regs, IPIC_SERMR, mask);
 601}
 602
 603/* Return an interrupt vector or -1 if no interrupt is pending. */
 604int ipic_get_irq(void)
 605{
 606        int irq;
 607
 608        irq = ipic_read(primary_ipic->regs, IPIC_SIVCR) & 0x7f;
 609
 610        if (irq == 0)    /* 0 --> no irq is pending */
 611                irq = -1;
 612
 613        return irq;
 614}
 615
 616static struct sysdev_class ipic_sysclass = {
 617        set_kset_name("ipic"),
 618};
 619
 620static struct sys_device device_ipic = {
 621        .id             = 0,
 622        .cls            = &ipic_sysclass,
 623};
 624
 625static int __init init_ipic_sysfs(void)
 626{
 627        int rc;
 628
 629        if (!primary_ipic->regs)
 630                return -ENODEV;
 631        printk(KERN_DEBUG "Registering ipic with sysfs...\n");
 632
 633        rc = sysdev_class_register(&ipic_sysclass);
 634        if (rc) {
 635                printk(KERN_ERR "Failed registering ipic sys class\n");
 636                return -ENODEV;
 637        }
 638        rc = sysdev_register(&device_ipic);
 639        if (rc) {
 640                printk(KERN_ERR "Failed registering ipic sys device\n");
 641                return -ENODEV;
 642        }
 643        return 0;
 644}
 645
 646subsys_initcall(init_ipic_sysfs);
 647