linux/arch/cris/arch-v10/kernel/io_interface_mux.c
<<
>>
Prefs
   1/* IO interface mux allocator for ETRAX100LX.
   2 * Copyright 2004-2007, Axis Communications AB
   3 */
   4
   5
   6/* C.f. ETRAX100LX Designer's Reference chapter 19.9 */
   7
   8#include <linux/kernel.h>
   9#include <linux/slab.h>
  10#include <linux/errno.h>
  11#include <linux/module.h>
  12#include <linux/init.h>
  13
  14#include <arch/svinto.h>
  15#include <asm/io.h>
  16#include <arch/io_interface_mux.h>
  17
  18
  19#define DBG(s)
  20
  21/* Macro to access ETRAX 100 registers */
  22#define SETS(var, reg, field, val) var = (var & ~IO_MASK_(reg##_, field##_)) | \
  23                                          IO_STATE_(reg##_, field##_, _##val)
  24
  25enum io_if_group {
  26        group_a = (1<<0),
  27        group_b = (1<<1),
  28        group_c = (1<<2),
  29        group_d = (1<<3),
  30        group_e = (1<<4),
  31        group_f = (1<<5)
  32};
  33
  34struct watcher
  35{
  36        void (*notify)(const unsigned int gpio_in_available,
  37                       const unsigned int gpio_out_available,
  38                       const unsigned char pa_available,
  39                       const unsigned char pb_available);
  40        struct watcher *next;
  41};
  42
  43
  44struct if_group
  45{
  46        enum io_if_group        group;
  47        /* name - the name of the group 'A' to 'F' */
  48        char                   *name;
  49        /* used - a bit mask of all pins in the group in the order listed
  50         * in the tables in 19.9.1 to 19.9.6.  Note that no
  51         * distinction is made between in, out and in/out pins. */
  52        unsigned int            used;
  53};
  54
  55
  56struct interface
  57{
  58        enum cris_io_interface   ioif;
  59        /* name - the name of the interface */
  60        char                    *name;
  61        /* groups - OR'ed together io_if_group flags describing what pin groups
  62         * the interface uses pins in. */
  63        unsigned char            groups;
  64        /* used - set when the interface is allocated. */
  65        unsigned char            used;
  66        char                    *owner;
  67        /* group_a through group_f - bit masks describing what pins in the
  68         * pin groups the interface uses. */
  69        unsigned int             group_a;
  70        unsigned int             group_b;
  71        unsigned int             group_c;
  72        unsigned int             group_d;
  73        unsigned int             group_e;
  74        unsigned int             group_f;
  75
  76        /* gpio_g_in, gpio_g_out, gpio_b - bit masks telling what pins in the
  77         * GPIO ports the interface uses.  This could be reconstucted using
  78         * the group_X masks and a table of what pins the GPIO ports use,
  79         * but that would be messy. */
  80        unsigned int             gpio_g_in;
  81        unsigned int             gpio_g_out;
  82        unsigned char            gpio_b;
  83};
  84
  85static struct if_group if_groups[6] = {
  86        {
  87                .group = group_a,
  88                .name = "A",
  89                .used = 0,
  90        },
  91        {
  92                .group = group_b,
  93                .name = "B",
  94                .used = 0,
  95        },
  96        {
  97                .group = group_c,
  98                .name = "C",
  99                .used = 0,
 100        },
 101        {
 102                .group = group_d,
 103                .name = "D",
 104                .used = 0,
 105        },
 106        {
 107                .group = group_e,
 108                .name = "E",
 109                .used = 0,
 110        },
 111        {
 112                .group = group_f,
 113                .name = "F",
 114                .used = 0,
 115        }
 116};
 117
 118/* The order in the array must match the order of enum
 119 * cris_io_interface in io_interface_mux.h */
 120static struct interface interfaces[] = {
 121        /* Begin Non-multiplexed interfaces */
 122        {
 123                .ioif = if_eth,
 124                .name = "ethernet",
 125                .groups = 0,
 126
 127                .group_a = 0,
 128                .group_b = 0,
 129                .group_c = 0,
 130                .group_d = 0,
 131                .group_e = 0,
 132                .group_f = 0,
 133
 134                .gpio_g_in = 0,
 135                .gpio_g_out = 0,
 136                .gpio_b = 0
 137        },
 138        {
 139                .ioif = if_serial_0,
 140                .name = "serial_0",
 141                .groups = 0,
 142
 143                .group_a = 0,
 144                .group_b = 0,
 145                .group_c = 0,
 146                .group_d = 0,
 147                .group_e = 0,
 148                .group_f = 0,
 149
 150                .gpio_g_in = 0,
 151                .gpio_g_out = 0,
 152                .gpio_b = 0
 153        },
 154        /* End Non-multiplexed interfaces */
 155        {
 156                .ioif = if_serial_1,
 157                .name = "serial_1",
 158                .groups = group_e,
 159
 160                .group_a = 0,
 161                .group_b = 0,
 162                .group_c = 0,
 163                .group_d = 0,
 164                .group_e = 0x0f,
 165                .group_f = 0,
 166
 167                .gpio_g_in =  0x00000000,
 168                .gpio_g_out = 0x00000000,
 169                .gpio_b = 0x00
 170        },
 171        {
 172                .ioif = if_serial_2,
 173                .name = "serial_2",
 174                .groups = group_b,
 175
 176                .group_a = 0,
 177                .group_b = 0x0f,
 178                .group_c = 0,
 179                .group_d = 0,
 180                .group_e = 0,
 181                .group_f = 0,
 182
 183                .gpio_g_in =  0x000000c0,
 184                .gpio_g_out = 0x000000c0,
 185                .gpio_b = 0x00
 186        },
 187        {
 188                .ioif = if_serial_3,
 189                .name = "serial_3",
 190                .groups = group_c,
 191
 192                .group_a = 0,
 193                .group_b = 0,
 194                .group_c = 0x0f,
 195                .group_d = 0,
 196                .group_e = 0,
 197                .group_f = 0,
 198
 199                .gpio_g_in =  0xc0000000,
 200                .gpio_g_out = 0xc0000000,
 201                .gpio_b = 0x00
 202        },
 203        {
 204                .ioif = if_sync_serial_1,
 205                .name = "sync_serial_1",
 206                .groups = group_e | group_f,
 207
 208                .group_a = 0,
 209                .group_b = 0,
 210                .group_c = 0,
 211                .group_d = 0,
 212                .group_e = 0x0f,
 213                .group_f = 0x10,
 214
 215                .gpio_g_in =  0x00000000,
 216                .gpio_g_out = 0x00000000,
 217                .gpio_b = 0x10
 218        },
 219        {
 220                .ioif = if_sync_serial_3,
 221                .name = "sync_serial_3",
 222                .groups = group_c | group_f,
 223
 224                .group_a = 0,
 225                .group_b = 0,
 226                .group_c = 0x0f,
 227                .group_d = 0,
 228                .group_e = 0,
 229                .group_f = 0x80,
 230
 231                .gpio_g_in =  0xc0000000,
 232                .gpio_g_out = 0xc0000000,
 233                .gpio_b = 0x80
 234        },
 235        {
 236                .ioif = if_shared_ram,
 237                .name = "shared_ram",
 238                .groups = group_a,
 239
 240                .group_a = 0x7f8ff,
 241                .group_b = 0,
 242                .group_c = 0,
 243                .group_d = 0,
 244                .group_e = 0,
 245                .group_f = 0,
 246
 247                .gpio_g_in =  0x0000ff3e,
 248                .gpio_g_out = 0x0000ff38,
 249                .gpio_b = 0x00
 250        },
 251        {
 252                .ioif = if_shared_ram_w,
 253                .name = "shared_ram_w",
 254                .groups = group_a | group_d,
 255
 256                .group_a = 0x7f8ff,
 257                .group_b = 0,
 258                .group_c = 0,
 259                .group_d = 0xff,
 260                .group_e = 0,
 261                .group_f = 0,
 262
 263                .gpio_g_in =  0x00ffff3e,
 264                .gpio_g_out = 0x00ffff38,
 265                .gpio_b = 0x00
 266        },
 267        {
 268                .ioif = if_par_0,
 269                .name = "par_0",
 270                .groups = group_a,
 271
 272                .group_a = 0x7fbff,
 273                .group_b = 0,
 274                .group_c = 0,
 275                .group_d = 0,
 276                .group_e = 0,
 277                .group_f = 0,
 278
 279                .gpio_g_in =  0x0000ff3e,
 280                .gpio_g_out = 0x0000ff3e,
 281                .gpio_b = 0x00
 282        },
 283        {
 284                .ioif = if_par_1,
 285                .name = "par_1",
 286                .groups = group_d,
 287
 288                .group_a = 0,
 289                .group_b = 0,
 290                .group_c = 0,
 291                .group_d = 0x7feff,
 292                .group_e = 0,
 293                .group_f = 0,
 294
 295                .gpio_g_in =  0x3eff0000,
 296                .gpio_g_out = 0x3eff0000,
 297                .gpio_b = 0x00
 298        },
 299        {
 300                .ioif = if_par_w,
 301                .name = "par_w",
 302                .groups = group_a | group_d,
 303
 304                .group_a = 0x7fbff,
 305                .group_b = 0,
 306                .group_c = 0,
 307                .group_d = 0xff,
 308                .group_e = 0,
 309                .group_f = 0,
 310
 311                .gpio_g_in =  0x00ffff3e,
 312                .gpio_g_out = 0x00ffff3e,
 313                .gpio_b = 0x00
 314        },
 315        {
 316                .ioif = if_scsi8_0,
 317                .name = "scsi8_0",
 318                .groups = group_a | group_b | group_f,
 319
 320                .group_a = 0x7ffff,
 321                .group_b = 0x0f,
 322                .group_c = 0,
 323                .group_d = 0,
 324                .group_e = 0,
 325                .group_f = 0x10,
 326
 327                .gpio_g_in =  0x0000ffff,
 328                .gpio_g_out = 0x0000ffff,
 329                .gpio_b = 0x10
 330        },
 331        {
 332                .ioif = if_scsi8_1,
 333                .name = "scsi8_1",
 334                .groups = group_c | group_d | group_f,
 335
 336                .group_a = 0,
 337                .group_b = 0,
 338                .group_c = 0x0f,
 339                .group_d = 0x7ffff,
 340                .group_e = 0,
 341                .group_f = 0x80,
 342
 343                .gpio_g_in =  0xffff0000,
 344                .gpio_g_out = 0xffff0000,
 345                .gpio_b = 0x80
 346        },
 347        {
 348                .ioif = if_scsi_w,
 349                .name = "scsi_w",
 350                .groups = group_a | group_b | group_d | group_f,
 351
 352                .group_a = 0x7ffff,
 353                .group_b = 0x0f,
 354                .group_c = 0,
 355                .group_d = 0x601ff,
 356                .group_e = 0,
 357                .group_f = 0x90,
 358
 359                .gpio_g_in =  0x01ffffff,
 360                .gpio_g_out = 0x07ffffff,
 361                .gpio_b = 0x80
 362        },
 363        {
 364                .ioif = if_ata,
 365                .name = "ata",
 366                .groups = group_a | group_b | group_c | group_d,
 367
 368                .group_a = 0x7ffff,
 369                .group_b = 0x0f,
 370                .group_c = 0x0f,
 371                .group_d = 0x7cfff,
 372                .group_e = 0,
 373                .group_f = 0,
 374
 375                .gpio_g_in =  0xf9ffffff,
 376                .gpio_g_out = 0xffffffff,
 377                .gpio_b = 0x80
 378        },
 379        {
 380                .ioif = if_csp,
 381                .name = "csp",
 382                .groups = group_f,
 383
 384                .group_a = 0,
 385                .group_b = 0,
 386                .group_c = 0,
 387                .group_d = 0,
 388                .group_e = 0,
 389                .group_f = 0xfc,
 390
 391                .gpio_g_in =  0x00000000,
 392                .gpio_g_out = 0x00000000,
 393                .gpio_b = 0xfc
 394        },
 395        {
 396                .ioif = if_i2c,
 397                .name = "i2c",
 398                .groups = group_f,
 399
 400                .group_a = 0,
 401                .group_b = 0,
 402                .group_c = 0,
 403                .group_d = 0,
 404                .group_e = 0,
 405                .group_f = 0x03,
 406
 407                .gpio_g_in =  0x00000000,
 408                .gpio_g_out = 0x00000000,
 409                .gpio_b = 0x03
 410        },
 411        {
 412                .ioif = if_usb_1,
 413                .name = "usb_1",
 414                .groups = group_e | group_f,
 415
 416                .group_a = 0,
 417                .group_b = 0,
 418                .group_c = 0,
 419                .group_d = 0,
 420                .group_e = 0x0f,
 421                .group_f = 0x2c,
 422
 423                .gpio_g_in =  0x00000000,
 424                .gpio_g_out = 0x00000000,
 425                .gpio_b = 0x2c
 426        },
 427        {
 428                .ioif = if_usb_2,
 429                .name = "usb_2",
 430                .groups = group_d,
 431
 432                .group_a = 0,
 433                .group_b = 0,
 434                .group_c = 0,
 435                .group_d = 0,
 436                .group_e = 0x33e00,
 437                .group_f = 0,
 438
 439                .gpio_g_in =  0x3e000000,
 440                .gpio_g_out = 0x0c000000,
 441                .gpio_b = 0x00
 442        },
 443        /* GPIO pins */
 444        {
 445                .ioif = if_gpio_grp_a,
 446                .name = "gpio_a",
 447                .groups = group_a,
 448
 449                .group_a = 0,
 450                .group_b = 0,
 451                .group_c = 0,
 452                .group_d = 0,
 453                .group_e = 0,
 454                .group_f = 0,
 455
 456                .gpio_g_in =  0x0000ff3f,
 457                .gpio_g_out = 0x0000ff3f,
 458                .gpio_b = 0x00
 459        },
 460        {
 461                .ioif = if_gpio_grp_b,
 462                .name = "gpio_b",
 463                .groups = group_b,
 464
 465                .group_a = 0,
 466                .group_b = 0,
 467                .group_c = 0,
 468                .group_d = 0,
 469                .group_e = 0,
 470                .group_f = 0,
 471
 472                .gpio_g_in =  0x000000c0,
 473                .gpio_g_out = 0x000000c0,
 474                .gpio_b = 0x00
 475        },
 476        {
 477                .ioif = if_gpio_grp_c,
 478                .name = "gpio_c",
 479                .groups = group_c,
 480
 481                .group_a = 0,
 482                .group_b = 0,
 483                .group_c = 0,
 484                .group_d = 0,
 485                .group_e = 0,
 486                .group_f = 0,
 487
 488                .gpio_g_in =  0xc0000000,
 489                .gpio_g_out = 0xc0000000,
 490                .gpio_b = 0x00
 491        },
 492        {
 493                .ioif = if_gpio_grp_d,
 494                .name = "gpio_d",
 495                .groups = group_d,
 496
 497                .group_a = 0,
 498                .group_b = 0,
 499                .group_c = 0,
 500                .group_d = 0,
 501                .group_e = 0,
 502                .group_f = 0,
 503
 504                .gpio_g_in =  0x3fff0000,
 505                .gpio_g_out = 0x3fff0000,
 506                .gpio_b = 0x00
 507        },
 508        {
 509                .ioif = if_gpio_grp_e,
 510                .name = "gpio_e",
 511                .groups = group_e,
 512
 513                .group_a = 0,
 514                .group_b = 0,
 515                .group_c = 0,
 516                .group_d = 0,
 517                .group_e = 0,
 518                .group_f = 0,
 519
 520                .gpio_g_in =  0x00000000,
 521                .gpio_g_out = 0x00000000,
 522                .gpio_b = 0x00
 523        },
 524        {
 525                .ioif = if_gpio_grp_f,
 526                .name = "gpio_f",
 527                .groups = group_f,
 528
 529                .group_a = 0,
 530                .group_b = 0,
 531                .group_c = 0,
 532                .group_d = 0,
 533                .group_e = 0,
 534                .group_f = 0,
 535
 536                .gpio_g_in =  0x00000000,
 537                .gpio_g_out = 0x00000000,
 538                .gpio_b = 0xff
 539        }
 540        /* Array end */
 541};
 542
 543static struct watcher *watchers = NULL;
 544
 545/* The pins that are free to use in the GPIO ports. */
 546static unsigned int gpio_in_pins =  0xffffffff;
 547static unsigned int gpio_out_pins = 0xffffffff;
 548static unsigned char gpio_pb_pins = 0xff;
 549static unsigned char gpio_pa_pins = 0xff;
 550
 551/* Identifiers for the owners of the GPIO pins. */
 552static enum cris_io_interface gpio_pa_owners[8];
 553static enum cris_io_interface gpio_pb_owners[8];
 554static enum cris_io_interface gpio_pg_owners[32];
 555
 556static int cris_io_interface_init(void);
 557
 558static unsigned char clear_group_from_set(const unsigned char groups, struct if_group *group)
 559{
 560        return (groups & ~group->group);
 561}
 562
 563
 564static struct if_group *get_group(const unsigned char groups)
 565{
 566        int i;
 567        for (i = 0; i < ARRAY_SIZE(if_groups); i++) {
 568                if (groups & if_groups[i].group) {
 569                        return &if_groups[i];
 570                }
 571        }
 572        return NULL;
 573}
 574
 575
 576static void notify_watchers(void)
 577{
 578        struct watcher *w = watchers;
 579
 580        DBG(printk("io_interface_mux: notifying watchers\n"));
 581
 582        while (NULL != w) {
 583                w->notify((const unsigned int)gpio_in_pins,
 584                          (const unsigned int)gpio_out_pins,
 585                          (const unsigned char)gpio_pa_pins,
 586                          (const unsigned char)gpio_pb_pins);
 587                w = w->next;
 588        }
 589}
 590
 591
 592int cris_request_io_interface(enum cris_io_interface ioif, const char *device_id)
 593{
 594        int set_gen_config = 0;
 595        int set_gen_config_ii = 0;
 596        unsigned long int gens;
 597        unsigned long int gens_ii;
 598        struct if_group *grp;
 599        unsigned char group_set;
 600        unsigned long flags;
 601        int res = 0;
 602
 603        (void)cris_io_interface_init();
 604
 605        DBG(printk("cris_request_io_interface(%d, \"%s\")\n", ioif, device_id));
 606
 607        if ((ioif >= if_max_interfaces) || (ioif < 0)) {
 608                printk(KERN_CRIT "cris_request_io_interface: Bad interface "
 609                        "%u submitted for %s\n",
 610                       ioif,
 611                       device_id);
 612                return -EINVAL;
 613        }
 614
 615        local_irq_save(flags);
 616
 617        if (interfaces[ioif].used) {
 618                printk(KERN_CRIT "cris_io_interface: Cannot allocate interface "
 619                        "%s for %s, in use by %s\n",
 620                       interfaces[ioif].name,
 621                       device_id,
 622                       interfaces[ioif].owner);
 623                res = -EBUSY;
 624                goto exit;
 625        }
 626
 627        /* Check that all required pins in the used groups are free
 628         * before allocating. */
 629        group_set = interfaces[ioif].groups;
 630        while (NULL != (grp = get_group(group_set))) {
 631                unsigned int if_group_use = 0;
 632
 633                switch (grp->group) {
 634                case group_a:
 635                        if_group_use = interfaces[ioif].group_a;
 636                        break;
 637                case group_b:
 638                        if_group_use = interfaces[ioif].group_b;
 639                        break;
 640                case group_c:
 641                        if_group_use = interfaces[ioif].group_c;
 642                        break;
 643                case group_d:
 644                        if_group_use = interfaces[ioif].group_d;
 645                        break;
 646                case group_e:
 647                        if_group_use = interfaces[ioif].group_e;
 648                        break;
 649                case group_f:
 650                        if_group_use = interfaces[ioif].group_f;
 651                        break;
 652                default:
 653                        BUG_ON(1);
 654                }
 655
 656                if (if_group_use & grp->used) {
 657                        printk(KERN_INFO "cris_request_io_interface: group "
 658                                "%s needed by %s not available\n",
 659                                grp->name, interfaces[ioif].name);
 660                        res = -EBUSY;
 661                        goto exit;
 662                }
 663
 664                group_set = clear_group_from_set(group_set, grp);
 665        }
 666
 667        /* Are the required GPIO pins available too? */
 668        if (((interfaces[ioif].gpio_g_in & gpio_in_pins) !=
 669                        interfaces[ioif].gpio_g_in) ||
 670                ((interfaces[ioif].gpio_g_out & gpio_out_pins) !=
 671                        interfaces[ioif].gpio_g_out) ||
 672                ((interfaces[ioif].gpio_b & gpio_pb_pins) !=
 673                        interfaces[ioif].gpio_b)) {
 674                printk(KERN_CRIT "cris_request_io_interface: Could not get "
 675                        "required pins for interface %u\n", ioif);
 676                res = -EBUSY;
 677                goto exit;
 678        }
 679
 680        /* Check which registers need to be reconfigured. */
 681        gens = genconfig_shadow;
 682        gens_ii = gen_config_ii_shadow;
 683
 684        set_gen_config = 1;
 685        switch (ioif)
 686        {
 687        /* Begin Non-multiplexed interfaces */
 688        case if_eth:
 689                /* fall through */
 690        case if_serial_0:
 691                set_gen_config = 0;
 692                break;
 693        /* End Non-multiplexed interfaces */
 694        case if_serial_1:
 695                set_gen_config_ii = 1;
 696                SETS(gens_ii, R_GEN_CONFIG_II, sermode1, async);
 697                break;
 698        case if_serial_2:
 699                SETS(gens, R_GEN_CONFIG, ser2, select);
 700                break;
 701        case if_serial_3:
 702                SETS(gens, R_GEN_CONFIG, ser3, select);
 703                set_gen_config_ii = 1;
 704                SETS(gens_ii, R_GEN_CONFIG_II, sermode3, async);
 705                break;
 706        case if_sync_serial_1:
 707                set_gen_config_ii = 1;
 708                SETS(gens_ii, R_GEN_CONFIG_II, sermode1, sync);
 709                break;
 710        case if_sync_serial_3:
 711                SETS(gens, R_GEN_CONFIG, ser3, select);
 712                set_gen_config_ii = 1;
 713                SETS(gens_ii, R_GEN_CONFIG_II, sermode3, sync);
 714                break;
 715        case if_shared_ram:
 716                SETS(gens, R_GEN_CONFIG, mio, select);
 717                break;
 718        case if_shared_ram_w:
 719                SETS(gens, R_GEN_CONFIG, mio_w, select);
 720                break;
 721        case if_par_0:
 722                SETS(gens, R_GEN_CONFIG, par0, select);
 723                break;
 724        case if_par_1:
 725                SETS(gens, R_GEN_CONFIG, par1, select);
 726                break;
 727        case if_par_w:
 728                SETS(gens, R_GEN_CONFIG, par0, select);
 729                SETS(gens, R_GEN_CONFIG, par_w, select);
 730                break;
 731        case if_scsi8_0:
 732                SETS(gens, R_GEN_CONFIG, scsi0, select);
 733                break;
 734        case if_scsi8_1:
 735                SETS(gens, R_GEN_CONFIG, scsi1, select);
 736                break;
 737        case if_scsi_w:
 738                SETS(gens, R_GEN_CONFIG, scsi0, select);
 739                SETS(gens, R_GEN_CONFIG, scsi0w, select);
 740                break;
 741        case if_ata:
 742                SETS(gens, R_GEN_CONFIG, ata, select);
 743                break;
 744        case if_csp:
 745                /* fall through */
 746        case if_i2c:
 747                set_gen_config = 0;
 748                break;
 749        case if_usb_1:
 750                SETS(gens, R_GEN_CONFIG, usb1, select);
 751                break;
 752        case if_usb_2:
 753                SETS(gens, R_GEN_CONFIG, usb2, select);
 754                break;
 755        case if_gpio_grp_a:
 756                /* GPIO groups are only accounted, don't do configuration changes. */
 757                /* fall through */
 758        case if_gpio_grp_b:
 759                /* fall through */
 760        case if_gpio_grp_c:
 761                /* fall through */
 762        case if_gpio_grp_d:
 763                /* fall through */
 764        case if_gpio_grp_e:
 765                /* fall through */
 766        case if_gpio_grp_f:
 767                set_gen_config = 0;
 768                break;
 769        default:
 770                printk(KERN_INFO "cris_request_io_interface: Bad interface "
 771                        "%u submitted for %s\n",
 772                        ioif, device_id);
 773                res = -EBUSY;
 774                goto exit;
 775        }
 776
 777        /* All needed I/O pins and pin groups are free, allocate. */
 778        group_set = interfaces[ioif].groups;
 779        while (NULL != (grp = get_group(group_set))) {
 780                unsigned int if_group_use = 0;
 781
 782                switch (grp->group) {
 783                case group_a:
 784                        if_group_use = interfaces[ioif].group_a;
 785                        break;
 786                case group_b:
 787                        if_group_use = interfaces[ioif].group_b;
 788                        break;
 789                case group_c:
 790                        if_group_use = interfaces[ioif].group_c;
 791                        break;
 792                case group_d:
 793                        if_group_use = interfaces[ioif].group_d;
 794                        break;
 795                case group_e:
 796                        if_group_use = interfaces[ioif].group_e;
 797                        break;
 798                case group_f:
 799                        if_group_use = interfaces[ioif].group_f;
 800                        break;
 801                default:
 802                        BUG_ON(1);
 803                }
 804                grp->used |= if_group_use;
 805
 806                group_set = clear_group_from_set(group_set, grp);
 807        }
 808
 809        interfaces[ioif].used = 1;
 810        interfaces[ioif].owner = (char*)device_id;
 811
 812        if (set_gen_config) {
 813                volatile int i;
 814                genconfig_shadow = gens;
 815                *R_GEN_CONFIG = genconfig_shadow;
 816                /* Wait 12 cycles before doing any DMA command */
 817                for(i = 6; i > 0; i--)
 818                        nop();
 819        }
 820        if (set_gen_config_ii) {
 821                gen_config_ii_shadow = gens_ii;
 822                *R_GEN_CONFIG_II = gen_config_ii_shadow;
 823        }
 824
 825        DBG(printk(KERN_DEBUG "GPIO pins: available before: "
 826                "g_in=0x%08x g_out=0x%08x pb=0x%02x\n",
 827                gpio_in_pins, gpio_out_pins, gpio_pb_pins));
 828        DBG(printk(KERN_DEBUG
 829                "grabbing pins: g_in=0x%08x g_out=0x%08x pb=0x%02x\n",
 830                interfaces[ioif].gpio_g_in,
 831                interfaces[ioif].gpio_g_out,
 832                interfaces[ioif].gpio_b));
 833
 834        gpio_in_pins &= ~interfaces[ioif].gpio_g_in;
 835        gpio_out_pins &= ~interfaces[ioif].gpio_g_out;
 836        gpio_pb_pins &= ~interfaces[ioif].gpio_b;
 837
 838        DBG(printk(KERN_DEBUG "GPIO pins: available after: "
 839                "g_in=0x%08x g_out=0x%08x pb=0x%02x\n",
 840                gpio_in_pins, gpio_out_pins, gpio_pb_pins));
 841
 842exit:
 843        local_irq_restore(flags);
 844        if (res == 0)
 845                notify_watchers();
 846        return res;
 847}
 848
 849
 850void cris_free_io_interface(enum cris_io_interface ioif)
 851{
 852        struct if_group *grp;
 853        unsigned char group_set;
 854        unsigned long flags;
 855
 856        (void)cris_io_interface_init();
 857
 858        if ((ioif >= if_max_interfaces) || (ioif < 0)) {
 859                printk(KERN_CRIT "cris_free_io_interface: Bad interface %u\n",
 860                       ioif);
 861                return;
 862        }
 863        local_irq_save(flags);
 864        if (!interfaces[ioif].used) {
 865                printk(KERN_CRIT "cris_free_io_interface: Freeing free interface %u\n",
 866                       ioif);
 867                local_irq_restore(flags);
 868                return;
 869        }
 870        group_set = interfaces[ioif].groups;
 871        while (NULL != (grp = get_group(group_set))) {
 872                unsigned int if_group_use = 0;
 873
 874                switch (grp->group) {
 875                case group_a:
 876                        if_group_use = interfaces[ioif].group_a;
 877                        break;
 878                case group_b:
 879                        if_group_use = interfaces[ioif].group_b;
 880                        break;
 881                case group_c:
 882                        if_group_use = interfaces[ioif].group_c;
 883                        break;
 884                case group_d:
 885                        if_group_use = interfaces[ioif].group_d;
 886                        break;
 887                case group_e:
 888                        if_group_use = interfaces[ioif].group_e;
 889                        break;
 890                case group_f:
 891                        if_group_use = interfaces[ioif].group_f;
 892                        break;
 893                default:
 894                        BUG_ON(1);
 895                }
 896
 897                if ((grp->used & if_group_use) != if_group_use)
 898                        BUG_ON(1);
 899                grp->used = grp->used & ~if_group_use;
 900
 901                group_set = clear_group_from_set(group_set, grp);
 902        }
 903        interfaces[ioif].used = 0;
 904        interfaces[ioif].owner = NULL;
 905
 906        DBG(printk("GPIO pins: available before: g_in=0x%08x g_out=0x%08x pb=0x%02x\n",
 907                   gpio_in_pins, gpio_out_pins, gpio_pb_pins));
 908        DBG(printk("freeing pins: g_in=0x%08x g_out=0x%08x pb=0x%02x\n",
 909                   interfaces[ioif].gpio_g_in,
 910                   interfaces[ioif].gpio_g_out,
 911                   interfaces[ioif].gpio_b));
 912
 913        gpio_in_pins |= interfaces[ioif].gpio_g_in;
 914        gpio_out_pins |= interfaces[ioif].gpio_g_out;
 915        gpio_pb_pins |= interfaces[ioif].gpio_b;
 916
 917        DBG(printk("GPIO pins: available after: g_in=0x%08x g_out=0x%08x pb=0x%02x\n",
 918                   gpio_in_pins, gpio_out_pins, gpio_pb_pins));
 919
 920        local_irq_restore(flags);
 921
 922        notify_watchers();
 923}
 924
 925/* Create a bitmask from bit 0 (inclusive) to bit stop_bit
 926   (non-inclusive).  stop_bit == 0 returns 0x0 */
 927static inline unsigned int create_mask(const unsigned stop_bit)
 928{
 929        /* Avoid overflow */
 930        if (stop_bit >= 32) {
 931                return 0xffffffff;
 932        }
 933        return (1<<stop_bit)-1;
 934}
 935
 936
 937/* port can be 'a', 'b' or 'g' */
 938int cris_io_interface_allocate_pins(const enum cris_io_interface ioif,
 939                                    const char port,
 940                                    const unsigned start_bit,
 941                                    const unsigned stop_bit)
 942{
 943        unsigned int i;
 944        unsigned int mask = 0;
 945        unsigned int tmp_mask;
 946        unsigned long int flags;
 947        enum cris_io_interface *owners;
 948
 949        (void)cris_io_interface_init();
 950
 951        DBG(printk("cris_io_interface_allocate_pins: if=%d port=%c start=%u stop=%u\n",
 952                   ioif, port, start_bit, stop_bit));
 953
 954        if (!((start_bit <= stop_bit) &&
 955              ((((port == 'a') || (port == 'b')) && (stop_bit < 8)) ||
 956               ((port == 'g') && (stop_bit < 32))))) {
 957                return -EINVAL;
 958        }
 959
 960        mask = create_mask(stop_bit + 1);
 961        tmp_mask = create_mask(start_bit);
 962        mask &= ~tmp_mask;
 963
 964        DBG(printk("cris_io_interface_allocate_pins: port=%c start=%u stop=%u mask=0x%08x\n",
 965                   port, start_bit, stop_bit, mask));
 966
 967        local_irq_save(flags);
 968
 969        switch (port) {
 970        case 'a':
 971                if ((gpio_pa_pins & mask) != mask) {
 972                        local_irq_restore(flags);
 973                        return -EBUSY;
 974                }
 975                owners = gpio_pa_owners;
 976                gpio_pa_pins &= ~mask;
 977                break;
 978        case 'b':
 979                if ((gpio_pb_pins & mask) != mask) {
 980                        local_irq_restore(flags);
 981                        return -EBUSY;
 982                }
 983                owners = gpio_pb_owners;
 984                gpio_pb_pins &= ~mask;
 985                break;
 986        case 'g':
 987                if (((gpio_in_pins & mask) != mask) ||
 988                    ((gpio_out_pins & mask) != mask)) {
 989                        local_irq_restore(flags);
 990                        return -EBUSY;
 991                }
 992                owners = gpio_pg_owners;
 993                gpio_in_pins &= ~mask;
 994                gpio_out_pins &= ~mask;
 995                break;
 996        default:
 997                local_irq_restore(flags);
 998                return -EINVAL;
 999        }
1000
1001        for (i = start_bit; i <= stop_bit; i++) {
1002                owners[i] = ioif;
1003        }
1004        local_irq_restore(flags);
1005
1006        notify_watchers();
1007        return 0;
1008}
1009
1010
1011/* port can be 'a', 'b' or 'g' */
1012int cris_io_interface_free_pins(const enum cris_io_interface ioif,
1013                                const char port,
1014                                const unsigned start_bit,
1015                                const unsigned stop_bit)
1016{
1017        unsigned int i;
1018        unsigned int mask = 0;
1019        unsigned int tmp_mask;
1020        unsigned long int flags;
1021        enum cris_io_interface *owners;
1022
1023        (void)cris_io_interface_init();
1024
1025        if (!((start_bit <= stop_bit) &&
1026              ((((port == 'a') || (port == 'b')) && (stop_bit < 8)) ||
1027               ((port == 'g') && (stop_bit < 32))))) {
1028                return -EINVAL;
1029        }
1030
1031        mask = create_mask(stop_bit + 1);
1032        tmp_mask = create_mask(start_bit);
1033        mask &= ~tmp_mask;
1034
1035        DBG(printk("cris_io_interface_free_pins: port=%c start=%u stop=%u mask=0x%08x\n",
1036                   port, start_bit, stop_bit, mask));
1037
1038        local_irq_save(flags);
1039
1040        switch (port) {
1041        case 'a':
1042                if ((~gpio_pa_pins & mask) != mask) {
1043                        local_irq_restore(flags);
1044                        printk(KERN_CRIT "cris_io_interface_free_pins: Freeing free pins");
1045                }
1046                owners = gpio_pa_owners;
1047                break;
1048        case 'b':
1049                if ((~gpio_pb_pins & mask) != mask) {
1050                        local_irq_restore(flags);
1051                        printk(KERN_CRIT "cris_io_interface_free_pins: Freeing free pins");
1052                }
1053                owners = gpio_pb_owners;
1054                break;
1055        case 'g':
1056                if (((~gpio_in_pins & mask) != mask) ||
1057                    ((~gpio_out_pins & mask) != mask)) {
1058                        local_irq_restore(flags);
1059                        printk(KERN_CRIT "cris_io_interface_free_pins: Freeing free pins");
1060                }
1061                owners = gpio_pg_owners;
1062                break;
1063        default:
1064                owners = NULL; /* Cannot happen. Shut up, gcc! */
1065        }
1066
1067        for (i = start_bit; i <= stop_bit; i++) {
1068                if (owners[i] != ioif) {
1069                        printk(KERN_CRIT "cris_io_interface_free_pins: Freeing unowned pins");
1070                }
1071        }
1072
1073        /* All was ok, change data. */
1074        switch (port) {
1075        case 'a':
1076                gpio_pa_pins |= mask;
1077                break;
1078        case 'b':
1079                gpio_pb_pins |= mask;
1080                break;
1081        case 'g':
1082                gpio_in_pins |= mask;
1083                gpio_out_pins |= mask;
1084                break;
1085        }
1086
1087        for (i = start_bit; i <= stop_bit; i++) {
1088                owners[i] = if_unclaimed;
1089        }
1090        local_irq_restore(flags);
1091        notify_watchers();
1092
1093        return 0;
1094}
1095
1096
1097int cris_io_interface_register_watcher(void (*notify)(const unsigned int gpio_in_available,
1098                                                      const unsigned int gpio_out_available,
1099                                                      const unsigned char pa_available,
1100                                                      const unsigned char pb_available))
1101{
1102        struct watcher *w;
1103
1104        (void)cris_io_interface_init();
1105
1106        if (NULL == notify) {
1107                return -EINVAL;
1108        }
1109        w = kmalloc(sizeof(*w), GFP_KERNEL);
1110        if (!w) {
1111                return -ENOMEM;
1112        }
1113        w->notify = notify;
1114        w->next = watchers;
1115        watchers = w;
1116
1117        w->notify((const unsigned int)gpio_in_pins,
1118                  (const unsigned int)gpio_out_pins,
1119                  (const unsigned char)gpio_pa_pins,
1120                  (const unsigned char)gpio_pb_pins);
1121
1122        return 0;
1123}
1124
1125void cris_io_interface_delete_watcher(void (*notify)(const unsigned int gpio_in_available,
1126                                                     const unsigned int gpio_out_available,
1127                                                     const unsigned char pa_available,
1128                                                     const unsigned char pb_available))
1129{
1130        struct watcher *w = watchers, *prev = NULL;
1131
1132        (void)cris_io_interface_init();
1133
1134        while ((NULL != w) && (w->notify != notify)){
1135                prev = w;
1136                w = w->next;
1137        }
1138        if (NULL != w) {
1139                if (NULL != prev) {
1140                        prev->next = w->next;
1141                } else {
1142                        watchers = w->next;
1143                }
1144                kfree(w);
1145                return;
1146        }
1147        printk(KERN_WARNING "cris_io_interface_delete_watcher: Deleting unknown watcher 0x%p\n", notify);
1148}
1149
1150
1151static int cris_io_interface_init(void)
1152{
1153        static int first = 1;
1154        int i;
1155
1156        if (!first) {
1157                return 0;
1158        }
1159        first = 0;
1160
1161        for (i = 0; i<8; i++) {
1162                gpio_pa_owners[i] = if_unclaimed;
1163                gpio_pb_owners[i] = if_unclaimed;
1164                gpio_pg_owners[i] = if_unclaimed;
1165        }
1166        for (; i<32; i++) {
1167                gpio_pg_owners[i] = if_unclaimed;
1168        }
1169        return 0;
1170}
1171
1172
1173module_init(cris_io_interface_init);
1174
1175
1176EXPORT_SYMBOL(cris_request_io_interface);
1177EXPORT_SYMBOL(cris_free_io_interface);
1178EXPORT_SYMBOL(cris_io_interface_allocate_pins);
1179EXPORT_SYMBOL(cris_io_interface_free_pins);
1180EXPORT_SYMBOL(cris_io_interface_register_watcher);
1181EXPORT_SYMBOL(cris_io_interface_delete_watcher);
1182