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