uboot/arch/blackfin/cpu/gpio.c
<<
>>
Prefs
   1/*
   2 * ADI GPIO1 Abstraction Layer
   3 * Support BF50x, BF51x, BF52x, BF53x and BF561 only.
   4 *
   5 * Copyright 2006-2010 Analog Devices Inc.
   6 *
   7 * Licensed under the GPL-2 or later
   8 */
   9
  10#include <common.h>
  11#include <asm/errno.h>
  12#include <asm/gpio.h>
  13#include <asm/portmux.h>
  14
  15#ifndef CONFIG_ADI_GPIO2
  16#if ANOMALY_05000311 || ANOMALY_05000323
  17enum {
  18        AWA_data = SYSCR,
  19        AWA_data_clear = SYSCR,
  20        AWA_data_set = SYSCR,
  21        AWA_toggle = SYSCR,
  22        AWA_maska = UART_SCR,
  23        AWA_maska_clear = UART_SCR,
  24        AWA_maska_set = UART_SCR,
  25        AWA_maska_toggle = UART_SCR,
  26        AWA_maskb = UART_GCTL,
  27        AWA_maskb_clear = UART_GCTL,
  28        AWA_maskb_set = UART_GCTL,
  29        AWA_maskb_toggle = UART_GCTL,
  30        AWA_dir = SPORT1_STAT,
  31        AWA_polar = SPORT1_STAT,
  32        AWA_edge = SPORT1_STAT,
  33        AWA_both = SPORT1_STAT,
  34#if ANOMALY_05000311
  35        AWA_inen = TIMER_ENABLE,
  36#elif ANOMALY_05000323
  37        AWA_inen = DMA1_1_CONFIG,
  38#endif
  39};
  40        /* Anomaly Workaround */
  41#define AWA_DUMMY_READ(name) bfin_read16(AWA_ ## name)
  42#else
  43#define AWA_DUMMY_READ(...)  do { } while (0)
  44#endif
  45
  46static struct gpio_port_t * const gpio_array[] = {
  47#if defined(BF533_FAMILY)
  48        (struct gpio_port_t *) FIO_FLAG_D,
  49#elif defined(CONFIG_BF52x) || defined(BF537_FAMILY) || defined(CONFIG_BF51x) \
  50        || defined(BF538_FAMILY) || defined(CONFIG_BF50x)
  51        (struct gpio_port_t *) PORTFIO,
  52# if !defined(BF538_FAMILY)
  53        (struct gpio_port_t *) PORTGIO,
  54        (struct gpio_port_t *) PORTHIO,
  55# endif
  56#elif defined(BF561_FAMILY)
  57        (struct gpio_port_t *) FIO0_FLAG_D,
  58        (struct gpio_port_t *) FIO1_FLAG_D,
  59        (struct gpio_port_t *) FIO2_FLAG_D,
  60#else
  61# error no gpio arrays defined
  62#endif
  63};
  64
  65#if defined(CONFIG_BF52x) || defined(BF537_FAMILY) || defined(CONFIG_BF51x) || \
  66    defined(CONFIG_BF50x)
  67static unsigned short * const port_fer[] = {
  68        (unsigned short *) PORTF_FER,
  69        (unsigned short *) PORTG_FER,
  70        (unsigned short *) PORTH_FER,
  71};
  72
  73# if !defined(BF537_FAMILY)
  74static unsigned short * const port_mux[] = {
  75        (unsigned short *) PORTF_MUX,
  76        (unsigned short *) PORTG_MUX,
  77        (unsigned short *) PORTH_MUX,
  78};
  79
  80static const
  81u8 pmux_offset[][16] = {
  82#  if defined(CONFIG_BF52x)
  83        { 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 4, 6, 8, 8, 10, 10 }, /* PORTF */
  84        { 0, 0, 0, 0, 0, 2, 2, 4, 4, 6, 8, 10, 10, 10, 12, 12 }, /* PORTG */
  85        { 0, 0, 0, 0, 0, 0, 0, 0, 2, 4, 4, 4, 4, 4, 4, 4 }, /* PORTH */
  86#  elif defined(CONFIG_BF51x)
  87        { 0, 2, 2, 2, 2, 2, 2, 4, 6, 6, 6, 8, 8, 8, 8, 10 }, /* PORTF */
  88        { 0, 0, 0, 2, 4, 6, 6, 6, 8, 10, 10, 12, 14, 14, 14, 14 }, /* PORTG */
  89        { 0, 0, 0, 0, 2, 2, 4, 6, 10, 10, 10, 10, 10, 10, 10, 10 }, /* PORTH */
  90#  endif
  91};
  92# endif
  93
  94#elif defined(BF538_FAMILY)
  95static unsigned short * const port_fer[] = {
  96        (unsigned short *) PORTCIO_FER,
  97        (unsigned short *) PORTDIO_FER,
  98        (unsigned short *) PORTEIO_FER,
  99};
 100#endif
 101
 102#ifdef CONFIG_BFIN_GPIO_TRACK
 103#define RESOURCE_LABEL_SIZE     16
 104
 105static struct str_ident {
 106        char name[RESOURCE_LABEL_SIZE];
 107} str_ident[MAX_RESOURCES];
 108
 109static void gpio_error(unsigned gpio)
 110{
 111        printf("bfin-gpio: GPIO %d wasn't requested!\n", gpio);
 112}
 113
 114static void set_label(unsigned short ident, const char *label)
 115{
 116        if (label) {
 117                strncpy(str_ident[ident].name, label,
 118                         RESOURCE_LABEL_SIZE);
 119                str_ident[ident].name[RESOURCE_LABEL_SIZE - 1] = 0;
 120        }
 121}
 122
 123static char *get_label(unsigned short ident)
 124{
 125        return (*str_ident[ident].name ? str_ident[ident].name : "UNKNOWN");
 126}
 127
 128static int cmp_label(unsigned short ident, const char *label)
 129{
 130        if (label == NULL)
 131                printf("bfin-gpio: please provide none-null label\n");
 132
 133        if (label)
 134                return strcmp(str_ident[ident].name, label);
 135        else
 136                return -EINVAL;
 137}
 138
 139#define map_entry(m, i)      reserved_##m##_map[gpio_bank(i)]
 140#define is_reserved(m, i, e) (map_entry(m, i) & gpio_bit(i))
 141#define reserve(m, i)        (map_entry(m, i) |= gpio_bit(i))
 142#define unreserve(m, i)      (map_entry(m, i) &= ~gpio_bit(i))
 143#define DECLARE_RESERVED_MAP(m, c) static unsigned short reserved_##m##_map[c]
 144#else
 145#define is_reserved(m, i, e) (!(e))
 146#define reserve(m, i)
 147#define unreserve(m, i)
 148#define DECLARE_RESERVED_MAP(m, c)
 149#define gpio_error(gpio)
 150#define set_label(...)
 151#define get_label(...) ""
 152#define cmp_label(...) 1
 153#endif
 154
 155DECLARE_RESERVED_MAP(gpio, GPIO_BANK_NUM);
 156DECLARE_RESERVED_MAP(peri, gpio_bank(MAX_RESOURCES));
 157
 158inline int check_gpio(unsigned gpio)
 159{
 160        if (gpio >= MAX_BLACKFIN_GPIOS)
 161                return -EINVAL;
 162        return 0;
 163}
 164
 165static void port_setup(unsigned gpio, unsigned short usage)
 166{
 167#if defined(BF538_FAMILY)
 168        /*
 169         * BF538/9 Port C,D and E are special.
 170         * Inverted PORT_FER polarity on CDE and no PORF_FER on F
 171         * Regular PORT F GPIOs are handled here, CDE are exclusively
 172         * managed by GPIOLIB
 173         */
 174
 175        if (gpio < MAX_BLACKFIN_GPIOS || gpio >= MAX_RESOURCES)
 176                return;
 177
 178        gpio -= MAX_BLACKFIN_GPIOS;
 179
 180        if (usage == GPIO_USAGE)
 181                *port_fer[gpio_bank(gpio)] |= gpio_bit(gpio);
 182        else
 183                *port_fer[gpio_bank(gpio)] &= ~gpio_bit(gpio);
 184        SSYNC();
 185        return;
 186#endif
 187
 188        if (check_gpio(gpio))
 189                return;
 190
 191#if defined(CONFIG_BF52x) || defined(BF537_FAMILY) || defined(CONFIG_BF51x) || \
 192    defined(CONFIG_BF50x)
 193        if (usage == GPIO_USAGE)
 194                *port_fer[gpio_bank(gpio)] &= ~gpio_bit(gpio);
 195        else
 196                *port_fer[gpio_bank(gpio)] |= gpio_bit(gpio);
 197        SSYNC();
 198#endif
 199}
 200
 201#ifdef BF537_FAMILY
 202static struct {
 203        unsigned short res;
 204        unsigned short offset;
 205} port_mux_lut[] = {
 206        {.res = P_PPI0_D13, .offset = 11},
 207        {.res = P_PPI0_D14, .offset = 11},
 208        {.res = P_PPI0_D15, .offset = 11},
 209        {.res = P_SPORT1_TFS, .offset = 11},
 210        {.res = P_SPORT1_TSCLK, .offset = 11},
 211        {.res = P_SPORT1_DTPRI, .offset = 11},
 212        {.res = P_PPI0_D10, .offset = 10},
 213        {.res = P_PPI0_D11, .offset = 10},
 214        {.res = P_PPI0_D12, .offset = 10},
 215        {.res = P_SPORT1_RSCLK, .offset = 10},
 216        {.res = P_SPORT1_RFS, .offset = 10},
 217        {.res = P_SPORT1_DRPRI, .offset = 10},
 218        {.res = P_PPI0_D8, .offset = 9},
 219        {.res = P_PPI0_D9, .offset = 9},
 220        {.res = P_SPORT1_DRSEC, .offset = 9},
 221        {.res = P_SPORT1_DTSEC, .offset = 9},
 222        {.res = P_TMR2, .offset = 8},
 223        {.res = P_PPI0_FS3, .offset = 8},
 224        {.res = P_TMR3, .offset = 7},
 225        {.res = P_SPI0_SSEL4, .offset = 7},
 226        {.res = P_TMR4, .offset = 6},
 227        {.res = P_SPI0_SSEL5, .offset = 6},
 228        {.res = P_TMR5, .offset = 5},
 229        {.res = P_SPI0_SSEL6, .offset = 5},
 230        {.res = P_UART1_RX, .offset = 4},
 231        {.res = P_UART1_TX, .offset = 4},
 232        {.res = P_TMR6, .offset = 4},
 233        {.res = P_TMR7, .offset = 4},
 234        {.res = P_UART0_RX, .offset = 3},
 235        {.res = P_UART0_TX, .offset = 3},
 236        {.res = P_DMAR0, .offset = 3},
 237        {.res = P_DMAR1, .offset = 3},
 238        {.res = P_SPORT0_DTSEC, .offset = 1},
 239        {.res = P_SPORT0_DRSEC, .offset = 1},
 240        {.res = P_CAN0_RX, .offset = 1},
 241        {.res = P_CAN0_TX, .offset = 1},
 242        {.res = P_SPI0_SSEL7, .offset = 1},
 243        {.res = P_SPORT0_TFS, .offset = 0},
 244        {.res = P_SPORT0_DTPRI, .offset = 0},
 245        {.res = P_SPI0_SSEL2, .offset = 0},
 246        {.res = P_SPI0_SSEL3, .offset = 0},
 247};
 248
 249static void portmux_setup(unsigned short per)
 250{
 251        u16 y, offset, muxreg, mask;
 252        u16 function = P_FUNCT2MUX(per);
 253
 254        for (y = 0; y < ARRAY_SIZE(port_mux_lut); y++) {
 255                if (port_mux_lut[y].res == per) {
 256
 257                        /* SET PORTMUX REG */
 258
 259                        offset = port_mux_lut[y].offset;
 260                        muxreg = bfin_read_PORT_MUX();
 261
 262                        if (offset == 1)
 263                                mask = 3;
 264                        else
 265                                mask = 1;
 266
 267                        muxreg &= ~(mask << offset);
 268                        muxreg |= ((function & mask) << offset);
 269                        bfin_write_PORT_MUX(muxreg);
 270                }
 271        }
 272}
 273#elif defined(CONFIG_BF52x) || defined(CONFIG_BF51x)
 274inline void portmux_setup(unsigned short per)
 275{
 276        u16 pmux, ident = P_IDENT(per), function = P_FUNCT2MUX(per);
 277        u8 offset = pmux_offset[gpio_bank(ident)][gpio_sub_n(ident)];
 278
 279        pmux = *port_mux[gpio_bank(ident)];
 280        pmux &= ~(3 << offset);
 281        pmux |= (function & 3) << offset;
 282        *port_mux[gpio_bank(ident)] = pmux;
 283        SSYNC();
 284}
 285#else
 286# define portmux_setup(...)  do { } while (0)
 287#endif
 288
 289/***********************************************************
 290*
 291* FUNCTIONS: Blackfin General Purpose Ports Access Functions
 292*
 293* INPUTS/OUTPUTS:
 294* gpio - GPIO Number between 0 and MAX_BLACKFIN_GPIOS
 295*
 296*
 297* DESCRIPTION: These functions abstract direct register access
 298*              to Blackfin processor General Purpose
 299*              Ports Regsiters
 300*
 301* CAUTION: These functions do not belong to the GPIO Driver API
 302*************************************************************
 303* MODIFICATION HISTORY :
 304**************************************************************/
 305
 306/* Set a specific bit */
 307
 308#define SET_GPIO(name) \
 309void set_gpio_ ## name(unsigned gpio, unsigned short arg) \
 310{ \
 311        unsigned long flags; \
 312        local_irq_save(flags); \
 313        if (arg) \
 314                gpio_array[gpio_bank(gpio)]->name |= gpio_bit(gpio); \
 315        else \
 316                gpio_array[gpio_bank(gpio)]->name &= ~gpio_bit(gpio); \
 317        AWA_DUMMY_READ(name); \
 318        local_irq_restore(flags); \
 319}
 320
 321SET_GPIO(dir)   /* set_gpio_dir() */
 322SET_GPIO(inen)  /* set_gpio_inen() */
 323SET_GPIO(polar) /* set_gpio_polar() */
 324SET_GPIO(edge)  /* set_gpio_edge() */
 325SET_GPIO(both)  /* set_gpio_both() */
 326
 327
 328#define SET_GPIO_SC(name) \
 329void set_gpio_ ## name(unsigned gpio, unsigned short arg) \
 330{ \
 331        unsigned long flags; \
 332        if (ANOMALY_05000311 || ANOMALY_05000323) \
 333                local_irq_save(flags); \
 334        if (arg) \
 335                gpio_array[gpio_bank(gpio)]->name ## _set = gpio_bit(gpio); \
 336        else \
 337                gpio_array[gpio_bank(gpio)]->name ## _clear = gpio_bit(gpio); \
 338        if (ANOMALY_05000311 || ANOMALY_05000323) { \
 339                AWA_DUMMY_READ(name); \
 340                local_irq_restore(flags); \
 341        } \
 342}
 343
 344SET_GPIO_SC(maska)
 345SET_GPIO_SC(maskb)
 346SET_GPIO_SC(data)
 347
 348void set_gpio_toggle(unsigned gpio)
 349{
 350        unsigned long flags;
 351        if (ANOMALY_05000311 || ANOMALY_05000323)
 352                local_irq_save(flags);
 353        gpio_array[gpio_bank(gpio)]->toggle = gpio_bit(gpio);
 354        if (ANOMALY_05000311 || ANOMALY_05000323) {
 355                AWA_DUMMY_READ(toggle);
 356                local_irq_restore(flags);
 357        }
 358}
 359
 360/* Set current PORT date (16-bit word) */
 361
 362#define SET_GPIO_P(name) \
 363void set_gpiop_ ## name(unsigned gpio, unsigned short arg) \
 364{ \
 365        unsigned long flags; \
 366        if (ANOMALY_05000311 || ANOMALY_05000323) \
 367                local_irq_save(flags); \
 368        gpio_array[gpio_bank(gpio)]->name = arg; \
 369        if (ANOMALY_05000311 || ANOMALY_05000323) { \
 370                AWA_DUMMY_READ(name); \
 371                local_irq_restore(flags); \
 372        } \
 373}
 374
 375SET_GPIO_P(data)
 376SET_GPIO_P(dir)
 377SET_GPIO_P(inen)
 378SET_GPIO_P(polar)
 379SET_GPIO_P(edge)
 380SET_GPIO_P(both)
 381SET_GPIO_P(maska)
 382SET_GPIO_P(maskb)
 383
 384/* Get a specific bit */
 385#define GET_GPIO(name) \
 386unsigned short get_gpio_ ## name(unsigned gpio) \
 387{ \
 388        unsigned long flags; \
 389        unsigned short ret; \
 390        if (ANOMALY_05000311 || ANOMALY_05000323) \
 391                local_irq_save(flags); \
 392        ret = 0x01 & (gpio_array[gpio_bank(gpio)]->name >> gpio_sub_n(gpio)); \
 393        if (ANOMALY_05000311 || ANOMALY_05000323) { \
 394                AWA_DUMMY_READ(name); \
 395                local_irq_restore(flags); \
 396        } \
 397        return ret; \
 398}
 399
 400GET_GPIO(data)
 401GET_GPIO(dir)
 402GET_GPIO(inen)
 403GET_GPIO(polar)
 404GET_GPIO(edge)
 405GET_GPIO(both)
 406GET_GPIO(maska)
 407GET_GPIO(maskb)
 408
 409/* Get current PORT date (16-bit word) */
 410
 411#define GET_GPIO_P(name) \
 412unsigned short get_gpiop_ ## name(unsigned gpio) \
 413{ \
 414        unsigned long flags; \
 415        unsigned short ret; \
 416        if (ANOMALY_05000311 || ANOMALY_05000323) \
 417                local_irq_save(flags); \
 418        ret = (gpio_array[gpio_bank(gpio)]->name); \
 419        if (ANOMALY_05000311 || ANOMALY_05000323) { \
 420                AWA_DUMMY_READ(name); \
 421                local_irq_restore(flags); \
 422        } \
 423        return ret; \
 424}
 425
 426GET_GPIO_P(data)
 427GET_GPIO_P(dir)
 428GET_GPIO_P(inen)
 429GET_GPIO_P(polar)
 430GET_GPIO_P(edge)
 431GET_GPIO_P(both)
 432GET_GPIO_P(maska)
 433GET_GPIO_P(maskb)
 434
 435/***********************************************************
 436*
 437* FUNCTIONS:    Blackfin Peripheral Resource Allocation
 438*               and PortMux Setup
 439*
 440* INPUTS/OUTPUTS:
 441* per   Peripheral Identifier
 442* label String
 443*
 444* DESCRIPTION: Blackfin Peripheral Resource Allocation and Setup API
 445*
 446* CAUTION:
 447*************************************************************
 448* MODIFICATION HISTORY :
 449**************************************************************/
 450
 451int peripheral_request(unsigned short per, const char *label)
 452{
 453        unsigned short ident = P_IDENT(per);
 454
 455        /*
 456         * Don't cares are pins with only one dedicated function
 457         */
 458
 459        if (per & P_DONTCARE)
 460                return 0;
 461
 462        if (!(per & P_DEFINED))
 463                return -ENODEV;
 464
 465        BUG_ON(ident >= MAX_RESOURCES);
 466
 467        /* If a pin can be muxed as either GPIO or peripheral, make
 468         * sure it is not already a GPIO pin when we request it.
 469         */
 470        if (unlikely(!check_gpio(ident) && is_reserved(gpio, ident, 1))) {
 471                printf("%s: Peripheral %d is already reserved as GPIO by %s !\n",
 472                       __func__, ident, get_label(ident));
 473                return -EBUSY;
 474        }
 475
 476        if (unlikely(is_reserved(peri, ident, 1))) {
 477
 478                /*
 479                 * Pin functions like AMC address strobes my
 480                 * be requested and used by several drivers
 481                 */
 482
 483                if (!(per & P_MAYSHARE)) {
 484                        /*
 485                         * Allow that the identical pin function can
 486                         * be requested from the same driver twice
 487                         */
 488
 489                        if (cmp_label(ident, label) == 0)
 490                                goto anyway;
 491
 492                        printf("%s: Peripheral %d function %d is already reserved by %s !\n",
 493                               __func__, ident, P_FUNCT2MUX(per), get_label(ident));
 494                        return -EBUSY;
 495                }
 496        }
 497
 498 anyway:
 499        reserve(peri, ident);
 500
 501        portmux_setup(per);
 502        port_setup(ident, PERIPHERAL_USAGE);
 503
 504        set_label(ident, label);
 505
 506        return 0;
 507}
 508
 509int peripheral_request_list(const unsigned short per[], const char *label)
 510{
 511        u16 cnt;
 512        int ret;
 513
 514        for (cnt = 0; per[cnt] != 0; cnt++) {
 515
 516                ret = peripheral_request(per[cnt], label);
 517
 518                if (ret < 0) {
 519                        for ( ; cnt > 0; cnt--)
 520                                peripheral_free(per[cnt - 1]);
 521
 522                        return ret;
 523                }
 524        }
 525
 526        return 0;
 527}
 528
 529void peripheral_free(unsigned short per)
 530{
 531        unsigned short ident = P_IDENT(per);
 532
 533        if (per & P_DONTCARE)
 534                return;
 535
 536        if (!(per & P_DEFINED))
 537                return;
 538
 539        if (unlikely(!is_reserved(peri, ident, 0)))
 540                return;
 541
 542        if (!(per & P_MAYSHARE))
 543                port_setup(ident, GPIO_USAGE);
 544
 545        unreserve(peri, ident);
 546
 547        set_label(ident, "free");
 548}
 549
 550void peripheral_free_list(const unsigned short per[])
 551{
 552        u16 cnt;
 553        for (cnt = 0; per[cnt] != 0; cnt++)
 554                peripheral_free(per[cnt]);
 555}
 556
 557/***********************************************************
 558*
 559* FUNCTIONS: Blackfin GPIO Driver
 560*
 561* INPUTS/OUTPUTS:
 562* gpio  PIO Number between 0 and MAX_BLACKFIN_GPIOS
 563* label String
 564*
 565* DESCRIPTION: Blackfin GPIO Driver API
 566*
 567* CAUTION:
 568*************************************************************
 569* MODIFICATION HISTORY :
 570**************************************************************/
 571
 572int gpio_request(unsigned gpio, const char *label)
 573{
 574        if (check_gpio(gpio) < 0)
 575                return -EINVAL;
 576
 577        /*
 578         * Allow that the identical GPIO can
 579         * be requested from the same driver twice
 580         * Do nothing and return -
 581         */
 582
 583        if (cmp_label(gpio, label) == 0)
 584                return 0;
 585
 586        if (unlikely(is_reserved(gpio, gpio, 1))) {
 587                printf("bfin-gpio: GPIO %d is already reserved by %s !\n",
 588                       gpio, get_label(gpio));
 589                return -EBUSY;
 590        }
 591        if (unlikely(is_reserved(peri, gpio, 1))) {
 592                printf("bfin-gpio: GPIO %d is already reserved as Peripheral by %s !\n",
 593                       gpio, get_label(gpio));
 594                return -EBUSY;
 595        }
 596        else {  /* Reset POLAR setting when acquiring a gpio for the first time */
 597                set_gpio_polar(gpio, 0);
 598        }
 599
 600        reserve(gpio, gpio);
 601        set_label(gpio, label);
 602
 603        port_setup(gpio, GPIO_USAGE);
 604
 605        return 0;
 606}
 607
 608int gpio_free(unsigned gpio)
 609{
 610        if (check_gpio(gpio) < 0)
 611                return -1;
 612
 613        if (unlikely(!is_reserved(gpio, gpio, 0))) {
 614                gpio_error(gpio);
 615                return -1;
 616        }
 617
 618        unreserve(gpio, gpio);
 619
 620        set_label(gpio, "free");
 621
 622        return 0;
 623}
 624
 625#ifdef ADI_SPECIAL_GPIO_BANKS
 626DECLARE_RESERVED_MAP(special_gpio, gpio_bank(MAX_RESOURCES));
 627
 628int special_gpio_request(unsigned gpio, const char *label)
 629{
 630        /*
 631         * Allow that the identical GPIO can
 632         * be requested from the same driver twice
 633         * Do nothing and return -
 634         */
 635
 636        if (cmp_label(gpio, label) == 0)
 637                return 0;
 638
 639        if (unlikely(is_reserved(special_gpio, gpio, 1))) {
 640                printf("bfin-gpio: GPIO %d is already reserved by %s !\n",
 641                       gpio, get_label(gpio));
 642                return -EBUSY;
 643        }
 644        if (unlikely(is_reserved(peri, gpio, 1))) {
 645                printf("bfin-gpio: GPIO %d is already reserved as Peripheral by %s !\n",
 646                       gpio, get_label(gpio));
 647
 648                return -EBUSY;
 649        }
 650
 651        reserve(special_gpio, gpio);
 652        reserve(peri, gpio);
 653
 654        set_label(gpio, label);
 655        port_setup(gpio, GPIO_USAGE);
 656
 657        return 0;
 658}
 659
 660void special_gpio_free(unsigned gpio)
 661{
 662        if (unlikely(!is_reserved(special_gpio, gpio, 0))) {
 663                gpio_error(gpio);
 664                return;
 665        }
 666
 667        unreserve(special_gpio, gpio);
 668        unreserve(peri, gpio);
 669        set_label(gpio, "free");
 670}
 671#endif
 672
 673static inline void __gpio_direction_input(unsigned gpio)
 674{
 675        gpio_array[gpio_bank(gpio)]->dir &= ~gpio_bit(gpio);
 676        gpio_array[gpio_bank(gpio)]->inen |= gpio_bit(gpio);
 677}
 678
 679int gpio_direction_input(unsigned gpio)
 680{
 681        unsigned long flags;
 682
 683        if (!is_reserved(gpio, gpio, 0)) {
 684                gpio_error(gpio);
 685                return -EINVAL;
 686        }
 687
 688        local_irq_save(flags);
 689        __gpio_direction_input(gpio);
 690        AWA_DUMMY_READ(inen);
 691        local_irq_restore(flags);
 692
 693        return 0;
 694}
 695
 696int gpio_set_value(unsigned gpio, int arg)
 697{
 698        if (arg)
 699                gpio_array[gpio_bank(gpio)]->data_set = gpio_bit(gpio);
 700        else
 701                gpio_array[gpio_bank(gpio)]->data_clear = gpio_bit(gpio);
 702
 703        return 0;
 704}
 705
 706int gpio_direction_output(unsigned gpio, int value)
 707{
 708        unsigned long flags;
 709
 710        if (!is_reserved(gpio, gpio, 0)) {
 711                gpio_error(gpio);
 712                return -EINVAL;
 713        }
 714
 715        local_irq_save(flags);
 716
 717        gpio_array[gpio_bank(gpio)]->inen &= ~gpio_bit(gpio);
 718        gpio_set_value(gpio, value);
 719        gpio_array[gpio_bank(gpio)]->dir |= gpio_bit(gpio);
 720
 721        AWA_DUMMY_READ(dir);
 722        local_irq_restore(flags);
 723
 724        return 0;
 725}
 726
 727int gpio_get_value(unsigned gpio)
 728{
 729        unsigned long flags;
 730
 731        if (unlikely(get_gpio_edge(gpio))) {
 732                int ret;
 733                local_irq_save(flags);
 734                set_gpio_edge(gpio, 0);
 735                ret = get_gpio_data(gpio);
 736                set_gpio_edge(gpio, 1);
 737                local_irq_restore(flags);
 738                return ret;
 739        } else
 740                return get_gpio_data(gpio);
 741}
 742
 743/* If we are booting from SPI and our board lacks a strong enough pull up,
 744 * the core can reset and execute the bootrom faster than the resistor can
 745 * pull the signal logically high.  To work around this (common) error in
 746 * board design, we explicitly set the pin back to GPIO mode, force /CS
 747 * high, and wait for the electrons to do their thing.
 748 *
 749 * This function only makes sense to be called from reset code, but it
 750 * lives here as we need to force all the GPIO states w/out going through
 751 * BUG() checks and such.
 752 */
 753void bfin_reset_boot_spi_cs(unsigned short pin)
 754{
 755        unsigned short gpio = P_IDENT(pin);
 756        port_setup(gpio, GPIO_USAGE);
 757        gpio_array[gpio_bank(gpio)]->data_set = gpio_bit(gpio);
 758        AWA_DUMMY_READ(data_set);
 759        udelay(1);
 760}
 761
 762int name_to_gpio(const char *name)
 763{
 764        int port_base;
 765
 766        if (tolower(*name) == 'p') {
 767                ++name;
 768
 769                switch (tolower(*name)) {
 770#ifdef GPIO_PA0
 771                case 'a': port_base = GPIO_PA0; break;
 772#endif
 773#ifdef GPIO_PB0
 774                case 'b': port_base = GPIO_PB0; break;
 775#endif
 776#ifdef GPIO_PC0
 777                case 'c': port_base = GPIO_PC0; break;
 778#endif
 779#ifdef GPIO_PD0
 780                case 'd': port_base = GPIO_PD0; break;
 781#endif
 782#ifdef GPIO_PE0
 783                case 'e': port_base = GPIO_PE0; break;
 784#endif
 785#ifdef GPIO_PF0
 786                case 'f': port_base = GPIO_PF0; break;
 787#endif
 788#ifdef GPIO_PG0
 789                case 'g': port_base = GPIO_PG0; break;
 790#endif
 791#ifdef GPIO_PH0
 792                case 'h': port_base = GPIO_PH0; break;
 793#endif
 794#ifdef GPIO_PI0
 795                case 'i': port_base = GPIO_PI0; break;
 796#endif
 797#ifdef GPIO_PJ
 798                case 'j': port_base = GPIO_PJ0; break;
 799#endif
 800                default:  return -1;
 801                }
 802
 803                ++name;
 804        } else
 805                port_base = 0;
 806
 807        return port_base + simple_strtoul(name, NULL, 10);
 808}
 809
 810void gpio_labels(void)
 811{
 812        int c, gpio;
 813
 814        for (c = 0; c < MAX_RESOURCES; c++) {
 815                gpio = is_reserved(gpio, c, 1);
 816                if (!check_gpio(c) && gpio)
 817                        printf("GPIO_%d:\t%s\tGPIO %s\n", c,
 818                                get_label(c),
 819                                get_gpio_dir(c) ? "OUTPUT" : "INPUT");
 820                else if (is_reserved(peri, c, 1))
 821                        printf("GPIO_%d:\t%s\tPeripheral\n", c, get_label(c));
 822                else
 823                        continue;
 824        }
 825}
 826#else
 827struct gpio_port_t * const gpio_array[] = {
 828        (struct gpio_port_t *)PORTA_FER,
 829        (struct gpio_port_t *)PORTB_FER,
 830        (struct gpio_port_t *)PORTC_FER,
 831        (struct gpio_port_t *)PORTD_FER,
 832        (struct gpio_port_t *)PORTE_FER,
 833        (struct gpio_port_t *)PORTF_FER,
 834        (struct gpio_port_t *)PORTG_FER,
 835#if defined(CONFIG_BF54x)
 836        (struct gpio_port_t *)PORTH_FER,
 837        (struct gpio_port_t *)PORTI_FER,
 838        (struct gpio_port_t *)PORTJ_FER,
 839#endif
 840};
 841#endif
 842