bfin_gpio.c 30.0 KB
Newer Older
B
Bryan Wu 已提交
1
/*
2
 * GPIO Abstraction Layer
B
Bryan Wu 已提交
3
 *
4
 * Copyright 2006-2010 Analog Devices Inc.
B
Bryan Wu 已提交
5
 *
6
 * Licensed under the GPL-2 or later
B
Bryan Wu 已提交
7 8
 */

9
#include <linux/delay.h>
B
Bryan Wu 已提交
10 11
#include <linux/module.h>
#include <linux/err.h>
12
#include <linux/proc_fs.h>
B
Bryan Wu 已提交
13 14
#include <asm/blackfin.h>
#include <asm/gpio.h>
15
#include <asm/portmux.h>
B
Bryan Wu 已提交
16 17
#include <linux/irq.h>

18 19 20 21 22 23
#if ANOMALY_05000311 || ANOMALY_05000323
enum {
	AWA_data = SYSCR,
	AWA_data_clear = SYSCR,
	AWA_data_set = SYSCR,
	AWA_toggle = SYSCR,
24 25 26 27 28 29 30 31
	AWA_maska = BFIN_UART_SCR,
	AWA_maska_clear = BFIN_UART_SCR,
	AWA_maska_set = BFIN_UART_SCR,
	AWA_maska_toggle = BFIN_UART_SCR,
	AWA_maskb = BFIN_UART_GCTL,
	AWA_maskb_clear = BFIN_UART_GCTL,
	AWA_maskb_set = BFIN_UART_GCTL,
	AWA_maskb_toggle = BFIN_UART_GCTL,
32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
	AWA_dir = SPORT1_STAT,
	AWA_polar = SPORT1_STAT,
	AWA_edge = SPORT1_STAT,
	AWA_both = SPORT1_STAT,
#if ANOMALY_05000311
	AWA_inen = TIMER_ENABLE,
#elif ANOMALY_05000323
	AWA_inen = DMA1_1_CONFIG,
#endif
};
	/* Anomaly Workaround */
#define AWA_DUMMY_READ(name) bfin_read16(AWA_ ## name)
#else
#define AWA_DUMMY_READ(...)  do { } while (0)
#endif

48
static struct gpio_port_t * const gpio_array[] = {
49
#if defined(BF533_FAMILY) || defined(BF538_FAMILY)
B
Bryan Wu 已提交
50
	(struct gpio_port_t *) FIO_FLAG_D,
51
#elif defined(CONFIG_BF52x) || defined(BF537_FAMILY) || defined(CONFIG_BF51x)
B
Bryan Wu 已提交
52 53 54
	(struct gpio_port_t *) PORTFIO,
	(struct gpio_port_t *) PORTGIO,
	(struct gpio_port_t *) PORTHIO,
55 56 57 58
#elif defined(BF561_FAMILY)
	(struct gpio_port_t *) FIO0_FLAG_D,
	(struct gpio_port_t *) FIO1_FLAG_D,
	(struct gpio_port_t *) FIO2_FLAG_D,
59
#elif defined(CONFIG_BF54x)
60 61 62 63 64 65 66 67 68 69 70 71 72
	(struct gpio_port_t *)PORTA_FER,
	(struct gpio_port_t *)PORTB_FER,
	(struct gpio_port_t *)PORTC_FER,
	(struct gpio_port_t *)PORTD_FER,
	(struct gpio_port_t *)PORTE_FER,
	(struct gpio_port_t *)PORTF_FER,
	(struct gpio_port_t *)PORTG_FER,
	(struct gpio_port_t *)PORTH_FER,
	(struct gpio_port_t *)PORTI_FER,
	(struct gpio_port_t *)PORTJ_FER,
#else
# error no gpio arrays defined
#endif
B
Bryan Wu 已提交
73 74
};

75
#if defined(CONFIG_BF52x) || defined(BF537_FAMILY) || defined(CONFIG_BF51x)
76
static unsigned short * const port_fer[] = {
B
Bryan Wu 已提交
77 78 79 80 81
	(unsigned short *) PORTF_FER,
	(unsigned short *) PORTG_FER,
	(unsigned short *) PORTH_FER,
};

82 83
# if !defined(BF537_FAMILY)
static unsigned short * const port_mux[] = {
84 85 86 87 88 89
	(unsigned short *) PORTF_MUX,
	(unsigned short *) PORTG_MUX,
	(unsigned short *) PORTH_MUX,
};

static const
90
u8 pmux_offset[][16] = {
91
#  if defined(CONFIG_BF52x)
92 93 94
	{ 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 4, 6, 8, 8, 10, 10 }, /* PORTF */
	{ 0, 0, 0, 0, 0, 2, 2, 4, 4, 6, 8, 10, 10, 10, 12, 12 }, /* PORTG */
	{ 0, 0, 0, 0, 0, 0, 0, 0, 2, 4, 4, 4, 4, 4, 4, 4 }, /* PORTH */
95
#  elif defined(CONFIG_BF51x)
96 97 98 99 100
	{ 0, 2, 2, 2, 2, 2, 2, 4, 6, 6, 6, 8, 8, 8, 8, 10 }, /* PORTF */
	{ 0, 0, 0, 2, 4, 6, 6, 6, 8, 10, 10, 12, 14, 14, 14, 14 }, /* PORTG */
	{ 0, 0, 0, 0, 2, 2, 4, 6, 10, 10, 10, 10, 10, 10, 10, 10 }, /* PORTH */
#  endif
};
101
# endif
102

103 104 105 106 107 108
#elif defined(BF538_FAMILY)
static unsigned short * const port_fer[] = {
	(unsigned short *) PORTCIO_FER,
	(unsigned short *) PORTDIO_FER,
	(unsigned short *) PORTEIO_FER,
};
109 110
#endif

111
#define RESOURCE_LABEL_SIZE	16
112

113
static struct str_ident {
114
	char name[RESOURCE_LABEL_SIZE];
115
} str_ident[MAX_RESOURCES];
B
Bryan Wu 已提交
116

117
#if defined(CONFIG_PM)
118
static struct gpio_port_s gpio_bank_saved[GPIO_BANK_NUM];
119 120
#endif

121
static void gpio_error(unsigned gpio)
122 123 124 125
{
	printk(KERN_ERR "bfin-gpio: GPIO %d wasn't requested!\n", gpio);
}

126 127
static void set_label(unsigned short ident, const char *label)
{
128
	if (label) {
129
		strncpy(str_ident[ident].name, label,
130
			 RESOURCE_LABEL_SIZE);
131
		str_ident[ident].name[RESOURCE_LABEL_SIZE - 1] = 0;
132 133 134 135 136
	}
}

static char *get_label(unsigned short ident)
{
137
	return (*str_ident[ident].name ? str_ident[ident].name : "UNKNOWN");
138 139 140 141
}

static int cmp_label(unsigned short ident, const char *label)
{
142 143 144 145 146
	if (label == NULL) {
		dump_stack();
		printk(KERN_ERR "Please provide none-null label\n");
	}

147
	if (label)
148
		return strcmp(str_ident[ident].name, label);
149 150 151 152
	else
		return -EINVAL;
}

153 154 155 156 157 158 159
#define map_entry(m, i)      reserved_##m##_map[gpio_bank(i)]
#define is_reserved(m, i, e) (map_entry(m, i) & gpio_bit(i))
#define reserve(m, i)        (map_entry(m, i) |= gpio_bit(i))
#define unreserve(m, i)      (map_entry(m, i) &= ~gpio_bit(i))
#define DECLARE_RESERVED_MAP(m, c) static unsigned short reserved_##m##_map[c]

DECLARE_RESERVED_MAP(gpio, GPIO_BANK_NUM);
160
DECLARE_RESERVED_MAP(peri, DIV_ROUND_UP(MAX_RESOURCES, GPIO_BANKSIZE));
161 162 163 164 165 166 167 168 169 170 171 172 173 174 175
DECLARE_RESERVED_MAP(gpio_irq, GPIO_BANK_NUM);

inline int check_gpio(unsigned gpio)
{
#if defined(CONFIG_BF54x)
	if (gpio == GPIO_PB15 || gpio == GPIO_PC14 || gpio == GPIO_PC15
	    || gpio == GPIO_PH14 || gpio == GPIO_PH15
	    || gpio == GPIO_PJ14 || gpio == GPIO_PJ15)
		return -EINVAL;
#endif
	if (gpio >= MAX_BLACKFIN_GPIOS)
		return -EINVAL;
	return 0;
}

176
static void port_setup(unsigned gpio, unsigned short usage)
B
Bryan Wu 已提交
177
{
178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198
#if defined(BF538_FAMILY)
	/*
	 * BF538/9 Port C,D and E are special.
	 * Inverted PORT_FER polarity on CDE and no PORF_FER on F
	 * Regular PORT F GPIOs are handled here, CDE are exclusively
	 * managed by GPIOLIB
	 */

	if (gpio < MAX_BLACKFIN_GPIOS || gpio >= MAX_RESOURCES)
		return;

	gpio -= MAX_BLACKFIN_GPIOS;

	if (usage == GPIO_USAGE)
		*port_fer[gpio_bank(gpio)] |= gpio_bit(gpio);
	else
		*port_fer[gpio_bank(gpio)] &= ~gpio_bit(gpio);
	SSYNC();
	return;
#endif

199 200 201
	if (check_gpio(gpio))
		return;

202
#if defined(CONFIG_BF52x) || defined(BF537_FAMILY) || defined(CONFIG_BF51x)
203 204 205 206 207
	if (usage == GPIO_USAGE)
		*port_fer[gpio_bank(gpio)] &= ~gpio_bit(gpio);
	else
		*port_fer[gpio_bank(gpio)] |= gpio_bit(gpio);
	SSYNC();
208
#elif defined(CONFIG_BF54x)
209 210 211 212 213
	if (usage == GPIO_USAGE)
		gpio_array[gpio_bank(gpio)]->port_fer &= ~gpio_bit(gpio);
	else
		gpio_array[gpio_bank(gpio)]->port_fer |= gpio_bit(gpio);
	SSYNC();
B
Bryan Wu 已提交
214
#endif
215
}
B
Bryan Wu 已提交
216

217
#ifdef BF537_FAMILY
218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243
static const s8 port_mux[] = {
	[GPIO_PF0] = 3,
	[GPIO_PF1] = 3,
	[GPIO_PF2] = 4,
	[GPIO_PF3] = 4,
	[GPIO_PF4] = 5,
	[GPIO_PF5] = 6,
	[GPIO_PF6] = 7,
	[GPIO_PF7] = 8,
	[GPIO_PF8 ... GPIO_PF15] = -1,
	[GPIO_PG0 ... GPIO_PG7] = -1,
	[GPIO_PG8] = 9,
	[GPIO_PG9] = 9,
	[GPIO_PG10] = 10,
	[GPIO_PG11] = 10,
	[GPIO_PG12] = 10,
	[GPIO_PG13] = 11,
	[GPIO_PG14] = 11,
	[GPIO_PG15] = 11,
	[GPIO_PH0 ... GPIO_PH15] = -1,
	[PORT_PJ0 ... PORT_PJ3] = -1,
	[PORT_PJ4] = 1,
	[PORT_PJ5] = 1,
	[PORT_PJ6 ... PORT_PJ9] = -1,
	[PORT_PJ10] = 0,
	[PORT_PJ11] = 0,
244 245
};

246
static int portmux_group_check(unsigned short per)
247
{
248
	u16 ident = P_IDENT(per);
249
	u16 function = P_FUNCT2MUX(per);
250 251
	s8 offset = port_mux[ident];
	u16 m, pmux, pfunc;
252

253 254
	if (offset < 0)
		return 0;
255

256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274
	pmux = bfin_read_PORT_MUX();
	for (m = 0; m < ARRAY_SIZE(port_mux); ++m) {
		if (m == ident)
			continue;
		if (port_mux[m] != offset)
			continue;
		if (!is_reserved(peri, m, 1))
			continue;

		if (offset == 1)
			pfunc = (pmux >> offset) & 3;
		else
			pfunc = (pmux >> offset) & 1;
		if (pfunc != function) {
			pr_err("pin group conflict! request pin %d func %d conflict with pin %d func %d\n",
				ident, function, m, pfunc);
			return -EINVAL;
		}
	}
275

276 277 278 279 280 281 282 283 284
	return 0;
}

static void portmux_setup(unsigned short per)
{
	u16 ident = P_IDENT(per);
	u16 function = P_FUNCT2MUX(per);
	s8 offset = port_mux[ident];
	u16 pmux;
285

286 287
	if (offset == -1)
		return;
288

289 290 291 292 293 294 295
	pmux = bfin_read_PORT_MUX();
	if (offset != 1)
		pmux &= ~(1 << offset);
	else
		pmux &= ~(3 << 1);
	pmux |= (function << offset);
	bfin_write_PORT_MUX(pmux);
296
}
297
#elif defined(CONFIG_BF54x)
298
inline void portmux_setup(unsigned short per)
299
{
300 301
	u16 ident = P_IDENT(per);
	u16 function = P_FUNCT2MUX(per);
302
	u32 pmux;
303

304
	pmux = gpio_array[gpio_bank(ident)]->port_mux;
305

306 307
	pmux &= ~(0x3 << (2 * gpio_sub_n(ident)));
	pmux |= (function & 0x3) << (2 * gpio_sub_n(ident));
308

309
	gpio_array[gpio_bank(ident)]->port_mux = pmux;
310 311
}

312
inline u16 get_portmux(unsigned short per)
313
{
314
	u16 ident = P_IDENT(per);
315
	u32 pmux = gpio_array[gpio_bank(ident)]->port_mux;
316
	return (pmux >> (2 * gpio_sub_n(ident)) & 0x3);
317
}
318 319 320 321
static int portmux_group_check(unsigned short per)
{
	return 0;
}
322
#elif defined(CONFIG_BF52x) || defined(CONFIG_BF51x)
323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351
static int portmux_group_check(unsigned short per)
{
	u16 ident = P_IDENT(per);
	u16 function = P_FUNCT2MUX(per);
	u8 offset = pmux_offset[gpio_bank(ident)][gpio_sub_n(ident)];
	u16 pin, gpiopin, pfunc;

	for (pin = 0; pin < GPIO_BANKSIZE; ++pin) {
		if (offset != pmux_offset[gpio_bank(ident)][pin])
			continue;

		gpiopin = gpio_bank(ident) * GPIO_BANKSIZE + pin;
		if (gpiopin == ident)
			continue;
		if (!is_reserved(peri, gpiopin, 1))
			continue;

		pfunc = *port_mux[gpio_bank(ident)];
		pfunc = (pfunc >> offset) & 3;
		if (pfunc != function) {
			pr_err("pin group conflict! request pin %d func %d conflict with pin %d func %d\n",
				ident, function, gpiopin, pfunc);
			return -EINVAL;
		}
	}

	return 0;
}

352
inline void portmux_setup(unsigned short per)
353
{
354 355
	u16 ident = P_IDENT(per);
	u16 function = P_FUNCT2MUX(per);
356
	u8 offset = pmux_offset[gpio_bank(ident)][gpio_sub_n(ident)];
357
	u16 pmux;
358 359

	pmux = *port_mux[gpio_bank(ident)];
360 361
	if  (((pmux >> offset) & 3) == function)
		return;
362 363 364 365 366
	pmux &= ~(3 << offset);
	pmux |= (function & 3) << offset;
	*port_mux[gpio_bank(ident)] = pmux;
	SSYNC();
}
367 368
#else
# define portmux_setup(...)  do { } while (0)
369 370 371 372
static int portmux_group_check(unsigned short per)
{
	return 0;
}
373
#endif
B
Bryan Wu 已提交
374

375
#ifndef CONFIG_BF54x
B
Bryan Wu 已提交
376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395
/***********************************************************
*
* FUNCTIONS: Blackfin General Purpose Ports Access Functions
*
* INPUTS/OUTPUTS:
* gpio - GPIO Number between 0 and MAX_BLACKFIN_GPIOS
*
*
* DESCRIPTION: These functions abstract direct register access
*              to Blackfin processor General Purpose
*              Ports Regsiters
*
* CAUTION: These functions do not belong to the GPIO Driver API
*************************************************************
* MODIFICATION HISTORY :
**************************************************************/

/* Set a specific bit */

#define SET_GPIO(name) \
396
void set_gpio_ ## name(unsigned gpio, unsigned short arg) \
B
Bryan Wu 已提交
397 398
{ \
	unsigned long flags; \
399
	flags = hard_local_irq_save(); \
B
Bryan Wu 已提交
400
	if (arg) \
401
		gpio_array[gpio_bank(gpio)]->name |= gpio_bit(gpio); \
B
Bryan Wu 已提交
402
	else \
403
		gpio_array[gpio_bank(gpio)]->name &= ~gpio_bit(gpio); \
404
	AWA_DUMMY_READ(name); \
405
	hard_local_irq_restore(flags); \
B
Bryan Wu 已提交
406 407 408
} \
EXPORT_SYMBOL(set_gpio_ ## name);

409 410 411 412 413
SET_GPIO(dir)   /* set_gpio_dir() */
SET_GPIO(inen)  /* set_gpio_inen() */
SET_GPIO(polar) /* set_gpio_polar() */
SET_GPIO(edge)  /* set_gpio_edge() */
SET_GPIO(both)  /* set_gpio_both() */
B
Bryan Wu 已提交
414 415


416
#define SET_GPIO_SC(name) \
417
void set_gpio_ ## name(unsigned gpio, unsigned short arg) \
418 419
{ \
	unsigned long flags; \
420
	if (ANOMALY_05000311 || ANOMALY_05000323) \
421
		flags = hard_local_irq_save(); \
B
Bryan Wu 已提交
422
	if (arg) \
423
		gpio_array[gpio_bank(gpio)]->name ## _set = gpio_bit(gpio); \
B
Bryan Wu 已提交
424
	else \
425 426 427
		gpio_array[gpio_bank(gpio)]->name ## _clear = gpio_bit(gpio); \
	if (ANOMALY_05000311 || ANOMALY_05000323) { \
		AWA_DUMMY_READ(name); \
428
		hard_local_irq_restore(flags); \
429
	} \
B
Bryan Wu 已提交
430 431 432 433 434 435 436
} \
EXPORT_SYMBOL(set_gpio_ ## name);

SET_GPIO_SC(maska)
SET_GPIO_SC(maskb)
SET_GPIO_SC(data)

437
void set_gpio_toggle(unsigned gpio)
B
Bryan Wu 已提交
438 439
{
	unsigned long flags;
440
	if (ANOMALY_05000311 || ANOMALY_05000323)
441
		flags = hard_local_irq_save();
442 443 444
	gpio_array[gpio_bank(gpio)]->toggle = gpio_bit(gpio);
	if (ANOMALY_05000311 || ANOMALY_05000323) {
		AWA_DUMMY_READ(toggle);
445
		hard_local_irq_restore(flags);
446
	}
B
Bryan Wu 已提交
447 448 449 450 451 452 453
}
EXPORT_SYMBOL(set_gpio_toggle);


/*Set current PORT date (16-bit word)*/

#define SET_GPIO_P(name) \
454
void set_gpiop_ ## name(unsigned gpio, unsigned short arg) \
B
Bryan Wu 已提交
455
{ \
456
	unsigned long flags; \
457
	if (ANOMALY_05000311 || ANOMALY_05000323) \
458
		flags = hard_local_irq_save(); \
459 460 461
	gpio_array[gpio_bank(gpio)]->name = arg; \
	if (ANOMALY_05000311 || ANOMALY_05000323) { \
		AWA_DUMMY_READ(name); \
462
		hard_local_irq_restore(flags); \
463
	} \
464 465
} \
EXPORT_SYMBOL(set_gpiop_ ## name);
B
Bryan Wu 已提交
466

467
SET_GPIO_P(data)
B
Bryan Wu 已提交
468 469 470 471 472 473 474 475 476
SET_GPIO_P(dir)
SET_GPIO_P(inen)
SET_GPIO_P(polar)
SET_GPIO_P(edge)
SET_GPIO_P(both)
SET_GPIO_P(maska)
SET_GPIO_P(maskb)

/* Get a specific bit */
477
#define GET_GPIO(name) \
478
unsigned short get_gpio_ ## name(unsigned gpio) \
479 480 481
{ \
	unsigned long flags; \
	unsigned short ret; \
482
	if (ANOMALY_05000311 || ANOMALY_05000323) \
483
		flags = hard_local_irq_save(); \
484 485 486
	ret = 0x01 & (gpio_array[gpio_bank(gpio)]->name >> gpio_sub_n(gpio)); \
	if (ANOMALY_05000311 || ANOMALY_05000323) { \
		AWA_DUMMY_READ(name); \
487
		hard_local_irq_restore(flags); \
488
	} \
489 490 491
	return ret; \
} \
EXPORT_SYMBOL(get_gpio_ ## name);
B
Bryan Wu 已提交
492

493
GET_GPIO(data)
B
Bryan Wu 已提交
494 495 496 497 498 499 500 501 502 503
GET_GPIO(dir)
GET_GPIO(inen)
GET_GPIO(polar)
GET_GPIO(edge)
GET_GPIO(both)
GET_GPIO(maska)
GET_GPIO(maskb)

/*Get current PORT date (16-bit word)*/

504
#define GET_GPIO_P(name) \
505
unsigned short get_gpiop_ ## name(unsigned gpio) \
506 507 508
{ \
	unsigned long flags; \
	unsigned short ret; \
509
	if (ANOMALY_05000311 || ANOMALY_05000323) \
510
		flags = hard_local_irq_save(); \
511 512 513
	ret = (gpio_array[gpio_bank(gpio)]->name); \
	if (ANOMALY_05000311 || ANOMALY_05000323) { \
		AWA_DUMMY_READ(name); \
514
		hard_local_irq_restore(flags); \
515
	} \
516 517 518
	return ret; \
} \
EXPORT_SYMBOL(get_gpiop_ ## name);
B
Bryan Wu 已提交
519

520
GET_GPIO_P(data)
B
Bryan Wu 已提交
521 522 523 524 525 526 527 528 529 530
GET_GPIO_P(dir)
GET_GPIO_P(inen)
GET_GPIO_P(polar)
GET_GPIO_P(edge)
GET_GPIO_P(both)
GET_GPIO_P(maska)
GET_GPIO_P(maskb)


#ifdef CONFIG_PM
531
DECLARE_RESERVED_MAP(wakeup, GPIO_BANK_NUM);
532 533 534 535 536 537 538 539

static const unsigned int sic_iwr_irqs[] = {
#if defined(BF533_FAMILY)
	IRQ_PROG_INTB
#elif defined(BF537_FAMILY)
	IRQ_PROG_INTB, IRQ_PORTG_INTB, IRQ_MAC_TX
#elif defined(BF538_FAMILY)
	IRQ_PORTF_INTB
540
#elif defined(CONFIG_BF52x) || defined(CONFIG_BF51x)
541 542 543 544 545 546 547 548
	IRQ_PORTF_INTB, IRQ_PORTG_INTB, IRQ_PORTH_INTB
#elif defined(BF561_FAMILY)
	IRQ_PROG0_INTB, IRQ_PROG1_INTB, IRQ_PROG2_INTB
#else
# error no SIC_IWR defined
#endif
};

B
Bryan Wu 已提交
549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567
/***********************************************************
*
* FUNCTIONS: Blackfin PM Setup API
*
* INPUTS/OUTPUTS:
* gpio - GPIO Number between 0 and MAX_BLACKFIN_GPIOS
* type -
*	PM_WAKE_RISING
*	PM_WAKE_FALLING
*	PM_WAKE_HIGH
*	PM_WAKE_LOW
*	PM_WAKE_BOTH_EDGES
*
* DESCRIPTION: Blackfin PM Driver API
*
* CAUTION:
*************************************************************
* MODIFICATION HISTORY :
**************************************************************/
568
int gpio_pm_wakeup_ctrl(unsigned gpio, unsigned ctrl)
B
Bryan Wu 已提交
569 570 571 572
{
	unsigned long flags;

	if (check_gpio(gpio) < 0)
573
		return -EINVAL;
B
Bryan Wu 已提交
574

575
	flags = hard_local_irq_save();
576
	if (ctrl)
577
		reserve(wakeup, gpio);
B
Bryan Wu 已提交
578
	else
579
		unreserve(wakeup, gpio);
B
Bryan Wu 已提交
580

581
	set_gpio_maskb(gpio, ctrl);
582
	hard_local_irq_restore(flags);
583

584
	return 0;
B
Bryan Wu 已提交
585 586
}

587
int bfin_pm_standby_ctrl(unsigned ctrl)
B
Bryan Wu 已提交
588 589 590
{
	u16 bank, mask, i;

591
	for (i = 0; i < MAX_BLACKFIN_GPIOS; i += GPIO_BANKSIZE) {
592
		mask = map_entry(wakeup, i);
B
Bryan Wu 已提交
593 594
		bank = gpio_bank(i);

595 596
		if (mask)
			bfin_internal_set_wake(sic_iwr_irqs[bank], ctrl);
B
Bryan Wu 已提交
597
	}
598
	return 0;
B
Bryan Wu 已提交
599 600
}

601 602 603 604 605 606 607
void bfin_gpio_pm_hibernate_suspend(void)
{
	int i, bank;

	for (i = 0; i < MAX_BLACKFIN_GPIOS; i += GPIO_BANKSIZE) {
		bank = gpio_bank(i);

608
#if defined(CONFIG_BF52x) || defined(BF537_FAMILY) || defined(CONFIG_BF51x)
609
		gpio_bank_saved[bank].fer = *port_fer[bank];
610
#if defined(CONFIG_BF52x) || defined(CONFIG_BF51x)
611
		gpio_bank_saved[bank].mux = *port_mux[bank];
612
#else
613 614
		if (bank == 0)
			gpio_bank_saved[bank].mux = bfin_read_PORT_MUX();
615 616
#endif
#endif
617 618 619 620 621 622 623
		gpio_bank_saved[bank].data  = gpio_array[bank]->data;
		gpio_bank_saved[bank].inen  = gpio_array[bank]->inen;
		gpio_bank_saved[bank].polar = gpio_array[bank]->polar;
		gpio_bank_saved[bank].dir   = gpio_array[bank]->dir;
		gpio_bank_saved[bank].edge  = gpio_array[bank]->edge;
		gpio_bank_saved[bank].both  = gpio_array[bank]->both;
		gpio_bank_saved[bank].maska = gpio_array[bank]->maska;
624 625 626 627 628 629 630 631 632 633
	}

	AWA_DUMMY_READ(maska);
}

void bfin_gpio_pm_hibernate_restore(void)
{
	int i, bank;

	for (i = 0; i < MAX_BLACKFIN_GPIOS; i += GPIO_BANKSIZE) {
634
		bank = gpio_bank(i);
635

636 637
#if defined(CONFIG_BF52x) || defined(BF537_FAMILY) || defined(CONFIG_BF51x)
#if defined(CONFIG_BF52x) || defined(CONFIG_BF51x)
638
		*port_mux[bank] = gpio_bank_saved[bank].mux;
639
#else
640 641
		if (bank == 0)
			bfin_write_PORT_MUX(gpio_bank_saved[bank].mux);
642
#endif
643
		*port_fer[bank] = gpio_bank_saved[bank].fer;
644
#endif
645
		gpio_array[bank]->inen  = gpio_bank_saved[bank].inen;
646 647
		gpio_array[bank]->data_set = gpio_bank_saved[bank].data
						& gpio_bank_saved[bank].dir;
648 649 650 651 652
		gpio_array[bank]->dir   = gpio_bank_saved[bank].dir;
		gpio_array[bank]->polar = gpio_bank_saved[bank].polar;
		gpio_array[bank]->edge  = gpio_bank_saved[bank].edge;
		gpio_array[bank]->both  = gpio_bank_saved[bank].both;
		gpio_array[bank]->maska = gpio_bank_saved[bank].maska;
653 654 655 656 657
	}
	AWA_DUMMY_READ(maska);
}


B
Bryan Wu 已提交
658
#endif
659
#else /* CONFIG_BF54x */
660 661
#ifdef CONFIG_PM

662
int bfin_pm_standby_ctrl(unsigned ctrl)
663 664 665 666 667 668 669 670 671 672 673
{
	return 0;
}

void bfin_gpio_pm_hibernate_suspend(void)
{
	int i, bank;

	for (i = 0; i < MAX_BLACKFIN_GPIOS; i += GPIO_BANKSIZE) {
		bank = gpio_bank(i);

674 675 676 677 678
		gpio_bank_saved[bank].fer = gpio_array[bank]->port_fer;
		gpio_bank_saved[bank].mux = gpio_array[bank]->port_mux;
		gpio_bank_saved[bank].data = gpio_array[bank]->data;
		gpio_bank_saved[bank].inen = gpio_array[bank]->inen;
		gpio_bank_saved[bank].dir = gpio_array[bank]->dir_set;
679 680 681 682 683 684 685 686
	}
}

void bfin_gpio_pm_hibernate_restore(void)
{
	int i, bank;

	for (i = 0; i < MAX_BLACKFIN_GPIOS; i += GPIO_BANKSIZE) {
687 688 689 690 691 692 693 694
		bank = gpio_bank(i);

		gpio_array[bank]->port_mux = gpio_bank_saved[bank].mux;
		gpio_array[bank]->port_fer = gpio_bank_saved[bank].fer;
		gpio_array[bank]->inen = gpio_bank_saved[bank].inen;
		gpio_array[bank]->dir_set = gpio_bank_saved[bank].dir;
		gpio_array[bank]->data_set = gpio_bank_saved[bank].data
						| gpio_bank_saved[bank].dir;
695 696 697
	}
}
#endif
698

699
unsigned short get_gpio_dir(unsigned gpio)
700
{
701
	return (0x01 & (gpio_array[gpio_bank(gpio)]->dir_clear >> gpio_sub_n(gpio)));
702 703 704
}
EXPORT_SYMBOL(get_gpio_dir);

705
#endif /* CONFIG_BF54x */
B
Bryan Wu 已提交
706

707 708
/***********************************************************
*
709
* FUNCTIONS:	Blackfin Peripheral Resource Allocation
710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730
*		and PortMux Setup
*
* INPUTS/OUTPUTS:
* per	Peripheral Identifier
* label	String
*
* DESCRIPTION: Blackfin Peripheral Resource Allocation and Setup API
*
* CAUTION:
*************************************************************
* MODIFICATION HISTORY :
**************************************************************/

int peripheral_request(unsigned short per, const char *label)
{
	unsigned long flags;
	unsigned short ident = P_IDENT(per);

	/*
	 * Don't cares are pins with only one dedicated function
	 */
731

732 733 734 735 736 737
	if (per & P_DONTCARE)
		return 0;

	if (!(per & P_DEFINED))
		return -ENODEV;

738 739
	BUG_ON(ident >= MAX_RESOURCES);

740
	flags = hard_local_irq_save();
741

742 743 744
	/* If a pin can be muxed as either GPIO or peripheral, make
	 * sure it is not already a GPIO pin when we request it.
	 */
745
	if (unlikely(!check_gpio(ident) && is_reserved(gpio, ident, 1))) {
746 747
		if (system_state == SYSTEM_BOOTING)
			dump_stack();
748
		printk(KERN_ERR
749
		       "%s: Peripheral %d is already reserved as GPIO by %s !\n",
750
		       __func__, ident, get_label(ident));
751
		hard_local_irq_restore(flags);
752 753 754
		return -EBUSY;
	}

755
	if (unlikely(is_reserved(peri, ident, 1))) {
756

757 758 759 760
		/*
		 * Pin functions like AMC address strobes my
		 * be requested and used by several drivers
		 */
761

762
#ifdef CONFIG_BF54x
763
		if (!((per & P_MAYSHARE) && get_portmux(per) == P_FUNCT2MUX(per))) {
764 765 766
#else
		if (!(per & P_MAYSHARE)) {
#endif
767 768 769 770
			/*
			 * Allow that the identical pin function can
			 * be requested from the same driver twice
			 */
771

772 773
			if (cmp_label(ident, label) == 0)
				goto anyway;
774

775 776
			if (system_state == SYSTEM_BOOTING)
				dump_stack();
777 778
			printk(KERN_ERR
			       "%s: Peripheral %d function %d is already reserved by %s !\n",
779
			       __func__, ident, P_FUNCT2MUX(per), get_label(ident));
780
			hard_local_irq_restore(flags);
781 782 783 784
			return -EBUSY;
		}
	}

785 786 787 788
	if (unlikely(portmux_group_check(per))) {
		hard_local_irq_restore(flags);
		return -EBUSY;
	}
789
 anyway:
790
	reserve(peri, ident);
791

792
	portmux_setup(per);
793 794
	port_setup(ident, PERIPHERAL_USAGE);

795
	hard_local_irq_restore(flags);
796 797 798 799 800 801
	set_label(ident, label);

	return 0;
}
EXPORT_SYMBOL(peripheral_request);

802
int peripheral_request_list(const unsigned short per[], const char *label)
803 804 805 806 807
{
	u16 cnt;
	int ret;

	for (cnt = 0; per[cnt] != 0; cnt++) {
808

809
		ret = peripheral_request(per[cnt], label);
810 811

		if (ret < 0) {
812
			for ( ; cnt > 0; cnt--)
813
				peripheral_free(per[cnt - 1]);
814 815

			return ret;
816
		}
817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833
	}

	return 0;
}
EXPORT_SYMBOL(peripheral_request_list);

void peripheral_free(unsigned short per)
{
	unsigned long flags;
	unsigned short ident = P_IDENT(per);

	if (per & P_DONTCARE)
		return;

	if (!(per & P_DEFINED))
		return;

834
	flags = hard_local_irq_save();
835

836
	if (unlikely(!is_reserved(peri, ident, 0))) {
837
		hard_local_irq_restore(flags);
838 839 840
		return;
	}

841
	if (!(per & P_MAYSHARE))
842 843
		port_setup(ident, GPIO_USAGE);

844
	unreserve(peri, ident);
845

846 847
	set_label(ident, "free");

848
	hard_local_irq_restore(flags);
849 850 851
}
EXPORT_SYMBOL(peripheral_free);

852
void peripheral_free_list(const unsigned short per[])
853 854
{
	u16 cnt;
855
	for (cnt = 0; per[cnt] != 0; cnt++)
856 857 858 859
		peripheral_free(per[cnt]);
}
EXPORT_SYMBOL(peripheral_free_list);

B
Bryan Wu 已提交
860 861 862 863 864
/***********************************************************
*
* FUNCTIONS: Blackfin GPIO Driver
*
* INPUTS/OUTPUTS:
865 866
* gpio	PIO Number between 0 and MAX_BLACKFIN_GPIOS
* label	String
B
Bryan Wu 已提交
867 868 869 870 871 872 873 874
*
* DESCRIPTION: Blackfin GPIO Driver API
*
* CAUTION:
*************************************************************
* MODIFICATION HISTORY :
**************************************************************/

875
int bfin_gpio_request(unsigned gpio, const char *label)
B
Bryan Wu 已提交
876 877 878 879 880 881
{
	unsigned long flags;

	if (check_gpio(gpio) < 0)
		return -EINVAL;

882
	flags = hard_local_irq_save();
B
Bryan Wu 已提交
883

884 885 886 887 888 889 890
	/*
	 * Allow that the identical GPIO can
	 * be requested from the same driver twice
	 * Do nothing and return -
	 */

	if (cmp_label(gpio, label) == 0) {
891
		hard_local_irq_restore(flags);
892 893 894
		return 0;
	}

895
	if (unlikely(is_reserved(gpio, gpio, 1))) {
896 897
		if (system_state == SYSTEM_BOOTING)
			dump_stack();
898
		printk(KERN_ERR "bfin-gpio: GPIO %d is already reserved by %s !\n",
899
		       gpio, get_label(gpio));
900
		hard_local_irq_restore(flags);
901 902
		return -EBUSY;
	}
903
	if (unlikely(is_reserved(peri, gpio, 1))) {
904 905
		if (system_state == SYSTEM_BOOTING)
			dump_stack();
906 907 908
		printk(KERN_ERR
		       "bfin-gpio: GPIO %d is already reserved as Peripheral by %s !\n",
		       gpio, get_label(gpio));
909
		hard_local_irq_restore(flags);
B
Bryan Wu 已提交
910 911
		return -EBUSY;
	}
912
	if (unlikely(is_reserved(gpio_irq, gpio, 1))) {
913 914
		printk(KERN_NOTICE "bfin-gpio: GPIO %d is already reserved as gpio-irq!"
		       " (Documentation/blackfin/bfin-gpio-notes.txt)\n", gpio);
915
	}
916
#ifndef CONFIG_BF54x
917 918 919 920
	else {	/* Reset POLAR setting when acquiring a gpio for the first time */
		set_gpio_polar(gpio, 0);
	}
#endif
921

922
	reserve(gpio, gpio);
923
	set_label(gpio, label);
B
Bryan Wu 已提交
924

925
	hard_local_irq_restore(flags);
B
Bryan Wu 已提交
926 927 928 929 930

	port_setup(gpio, GPIO_USAGE);

	return 0;
}
931
EXPORT_SYMBOL(bfin_gpio_request);
B
Bryan Wu 已提交
932

933
void bfin_gpio_free(unsigned gpio)
B
Bryan Wu 已提交
934 935 936 937 938 939
{
	unsigned long flags;

	if (check_gpio(gpio) < 0)
		return;

940 941
	might_sleep();

942
	flags = hard_local_irq_save();
B
Bryan Wu 已提交
943

944
	if (unlikely(!is_reserved(gpio, gpio, 0))) {
945 946
		if (system_state == SYSTEM_BOOTING)
			dump_stack();
947
		gpio_error(gpio);
948
		hard_local_irq_restore(flags);
B
Bryan Wu 已提交
949 950 951
		return;
	}

952
	unreserve(gpio, gpio);
B
Bryan Wu 已提交
953

954 955
	set_label(gpio, "free");

956
	hard_local_irq_restore(flags);
B
Bryan Wu 已提交
957
}
958
EXPORT_SYMBOL(bfin_gpio_free);
B
Bryan Wu 已提交
959

960
#ifdef BFIN_SPECIAL_GPIO_BANKS
961
DECLARE_RESERVED_MAP(special_gpio, gpio_bank(MAX_RESOURCES));
962 963 964 965 966

int bfin_special_gpio_request(unsigned gpio, const char *label)
{
	unsigned long flags;

967
	flags = hard_local_irq_save();
968 969 970 971 972 973 974 975

	/*
	 * Allow that the identical GPIO can
	 * be requested from the same driver twice
	 * Do nothing and return -
	 */

	if (cmp_label(gpio, label) == 0) {
976
		hard_local_irq_restore(flags);
977 978 979
		return 0;
	}

980
	if (unlikely(is_reserved(special_gpio, gpio, 1))) {
981
		hard_local_irq_restore(flags);
982 983 984 985 986
		printk(KERN_ERR "bfin-gpio: GPIO %d is already reserved by %s !\n",
		       gpio, get_label(gpio));

		return -EBUSY;
	}
987
	if (unlikely(is_reserved(peri, gpio, 1))) {
988
		hard_local_irq_restore(flags);
989 990 991 992 993 994 995
		printk(KERN_ERR
		       "bfin-gpio: GPIO %d is already reserved as Peripheral by %s !\n",
		       gpio, get_label(gpio));

		return -EBUSY;
	}

996 997
	reserve(special_gpio, gpio);
	reserve(peri, gpio);
998 999

	set_label(gpio, label);
1000
	hard_local_irq_restore(flags);
1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012
	port_setup(gpio, GPIO_USAGE);

	return 0;
}
EXPORT_SYMBOL(bfin_special_gpio_request);

void bfin_special_gpio_free(unsigned gpio)
{
	unsigned long flags;

	might_sleep();

1013
	flags = hard_local_irq_save();
1014

1015
	if (unlikely(!is_reserved(special_gpio, gpio, 0))) {
1016
		gpio_error(gpio);
1017
		hard_local_irq_restore(flags);
1018 1019 1020
		return;
	}

1021 1022
	unreserve(special_gpio, gpio);
	unreserve(peri, gpio);
1023
	set_label(gpio, "free");
1024
	hard_local_irq_restore(flags);
1025 1026 1027 1028 1029
}
EXPORT_SYMBOL(bfin_special_gpio_free);
#endif


1030 1031 1032 1033 1034 1035 1036
int bfin_gpio_irq_request(unsigned gpio, const char *label)
{
	unsigned long flags;

	if (check_gpio(gpio) < 0)
		return -EINVAL;

1037
	flags = hard_local_irq_save();
1038

1039
	if (unlikely(is_reserved(peri, gpio, 1))) {
1040 1041
		if (system_state == SYSTEM_BOOTING)
			dump_stack();
1042 1043 1044
		printk(KERN_ERR
		       "bfin-gpio: GPIO %d is already reserved as Peripheral by %s !\n",
		       gpio, get_label(gpio));
1045
		hard_local_irq_restore(flags);
1046 1047
		return -EBUSY;
	}
1048
	if (unlikely(is_reserved(gpio, gpio, 1)))
1049 1050 1051 1052
		printk(KERN_NOTICE "bfin-gpio: GPIO %d is already reserved by %s! "
		       "(Documentation/blackfin/bfin-gpio-notes.txt)\n",
		       gpio, get_label(gpio));

1053
	reserve(gpio_irq, gpio);
1054 1055
	set_label(gpio, label);

1056
	hard_local_irq_restore(flags);
1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069

	port_setup(gpio, GPIO_USAGE);

	return 0;
}

void bfin_gpio_irq_free(unsigned gpio)
{
	unsigned long flags;

	if (check_gpio(gpio) < 0)
		return;

1070
	flags = hard_local_irq_save();
1071

1072
	if (unlikely(!is_reserved(gpio_irq, gpio, 0))) {
1073 1074
		if (system_state == SYSTEM_BOOTING)
			dump_stack();
1075
		gpio_error(gpio);
1076
		hard_local_irq_restore(flags);
1077 1078 1079
		return;
	}

1080
	unreserve(gpio_irq, gpio);
1081 1082 1083

	set_label(gpio, "free");

1084
	hard_local_irq_restore(flags);
1085 1086
}

1087 1088
static inline void __bfin_gpio_direction_input(unsigned gpio)
{
1089
#ifdef CONFIG_BF54x
1090 1091 1092 1093 1094 1095 1096
	gpio_array[gpio_bank(gpio)]->dir_clear = gpio_bit(gpio);
#else
	gpio_array[gpio_bank(gpio)]->dir &= ~gpio_bit(gpio);
#endif
	gpio_array[gpio_bank(gpio)]->inen |= gpio_bit(gpio);
}

1097
int bfin_gpio_direction_input(unsigned gpio)
1098 1099 1100
{
	unsigned long flags;

1101
	if (unlikely(!is_reserved(gpio, gpio, 0))) {
1102 1103 1104 1105
		gpio_error(gpio);
		return -EINVAL;
	}

1106
	flags = hard_local_irq_save();
1107 1108
	__bfin_gpio_direction_input(gpio);
	AWA_DUMMY_READ(inen);
1109
	hard_local_irq_restore(flags);
1110 1111

	return 0;
1112
}
1113
EXPORT_SYMBOL(bfin_gpio_direction_input);
1114

1115
void bfin_gpio_irq_prepare(unsigned gpio)
1116
{
1117
#ifdef CONFIG_BF54x
1118
	unsigned long flags;
1119
#endif
1120

1121
	port_setup(gpio, GPIO_USAGE);
1122

1123
#ifdef CONFIG_BF54x
1124
	flags = hard_local_irq_save();
1125
	__bfin_gpio_direction_input(gpio);
1126
	hard_local_irq_restore(flags);
1127
#endif
1128 1129
}

1130
void bfin_gpio_set_value(unsigned gpio, int arg)
1131 1132
{
	if (arg)
1133
		gpio_array[gpio_bank(gpio)]->data_set = gpio_bit(gpio);
1134
	else
1135
		gpio_array[gpio_bank(gpio)]->data_clear = gpio_bit(gpio);
1136
}
1137
EXPORT_SYMBOL(bfin_gpio_set_value);
1138

1139
int bfin_gpio_direction_output(unsigned gpio, int value)
1140 1141 1142
{
	unsigned long flags;

1143
	if (unlikely(!is_reserved(gpio, gpio, 0))) {
1144 1145 1146
		gpio_error(gpio);
		return -EINVAL;
	}
1147

1148
	flags = hard_local_irq_save();
1149

1150 1151
	gpio_array[gpio_bank(gpio)]->inen &= ~gpio_bit(gpio);
	gpio_set_value(gpio, value);
1152
#ifdef CONFIG_BF54x
1153
	gpio_array[gpio_bank(gpio)]->dir_set = gpio_bit(gpio);
1154
#else
1155 1156 1157 1158
	gpio_array[gpio_bank(gpio)]->dir |= gpio_bit(gpio);
#endif

	AWA_DUMMY_READ(dir);
1159
	hard_local_irq_restore(flags);
1160 1161 1162 1163

	return 0;
}
EXPORT_SYMBOL(bfin_gpio_direction_output);
1164

1165
int bfin_gpio_get_value(unsigned gpio)
1166
{
1167
#ifdef CONFIG_BF54x
1168 1169
	return (1 & (gpio_array[gpio_bank(gpio)]->data >> gpio_sub_n(gpio)));
#else
1170 1171 1172
	unsigned long flags;

	if (unlikely(get_gpio_edge(gpio))) {
1173
		int ret;
1174
		flags = hard_local_irq_save();
1175 1176 1177
		set_gpio_edge(gpio, 0);
		ret = get_gpio_data(gpio);
		set_gpio_edge(gpio, 1);
1178
		hard_local_irq_restore(flags);
1179 1180 1181
		return ret;
	} else
		return get_gpio_data(gpio);
1182
#endif
1183
}
1184
EXPORT_SYMBOL(bfin_gpio_get_value);
1185

1186 1187 1188 1189 1190 1191 1192 1193 1194 1195
/* If we are booting from SPI and our board lacks a strong enough pull up,
 * the core can reset and execute the bootrom faster than the resistor can
 * pull the signal logically high.  To work around this (common) error in
 * board design, we explicitly set the pin back to GPIO mode, force /CS
 * high, and wait for the electrons to do their thing.
 *
 * This function only makes sense to be called from reset code, but it
 * lives here as we need to force all the GPIO states w/out going through
 * BUG() checks and such.
 */
1196
void bfin_reset_boot_spi_cs(unsigned short pin)
1197
{
1198
	unsigned short gpio = P_IDENT(pin);
1199
	port_setup(gpio, GPIO_USAGE);
1200
	gpio_array[gpio_bank(gpio)]->data_set = gpio_bit(gpio);
1201
	AWA_DUMMY_READ(data_set);
1202 1203
	udelay(1);
}
1204

1205 1206 1207 1208
#if defined(CONFIG_PROC_FS)
static int gpio_proc_read(char *buf, char **start, off_t offset,
			  int len, int *unused_i, void *unused_v)
{
1209
	int c, irq, gpio, outlen = 0;
1210 1211

	for (c = 0; c < MAX_RESOURCES; c++) {
1212 1213
		irq = is_reserved(gpio_irq, c, 1);
		gpio = is_reserved(gpio, c, 1);
1214 1215 1216 1217
		if (!check_gpio(c) && (gpio || irq))
			len = sprintf(buf, "GPIO_%d: \t%s%s \t\tGPIO %s\n", c,
				 get_label(c), (gpio && irq) ? " *" : "",
				 get_gpio_dir(c) ? "OUTPUT" : "INPUT");
1218
		else if (is_reserved(peri, c, 1))
1219
			len = sprintf(buf, "GPIO_%d: \t%s \t\tPeripheral\n", c, get_label(c));
1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238
		else
			continue;
		buf += len;
		outlen += len;
	}
	return outlen;
}

static __init int gpio_register_proc(void)
{
	struct proc_dir_entry *proc_gpio;

	proc_gpio = create_proc_entry("gpio", S_IRUGO, NULL);
	if (proc_gpio)
		proc_gpio->read_proc = gpio_proc_read;
	return proc_gpio != NULL;
}
__initcall(gpio_register_proc);
#endif
1239 1240

#ifdef CONFIG_GPIOLIB
1241
static int bfin_gpiolib_direction_input(struct gpio_chip *chip, unsigned gpio)
1242 1243 1244 1245
{
	return bfin_gpio_direction_input(gpio);
}

1246
static int bfin_gpiolib_direction_output(struct gpio_chip *chip, unsigned gpio, int level)
1247 1248 1249 1250
{
	return bfin_gpio_direction_output(gpio, level);
}

1251
static int bfin_gpiolib_get_value(struct gpio_chip *chip, unsigned gpio)
1252 1253 1254 1255
{
	return bfin_gpio_get_value(gpio);
}

1256
static void bfin_gpiolib_set_value(struct gpio_chip *chip, unsigned gpio, int value)
1257 1258 1259 1260
{
	return bfin_gpio_set_value(gpio, value);
}

1261
static int bfin_gpiolib_gpio_request(struct gpio_chip *chip, unsigned gpio)
1262 1263 1264 1265
{
	return bfin_gpio_request(gpio, chip->label);
}

1266
static void bfin_gpiolib_gpio_free(struct gpio_chip *chip, unsigned gpio)
1267 1268 1269 1270
{
	return bfin_gpio_free(gpio);
}

1271
static int bfin_gpiolib_gpio_to_irq(struct gpio_chip *chip, unsigned gpio)
1272 1273 1274 1275
{
	return gpio + GPIO_IRQ_BASE;
}

1276
static struct gpio_chip bfin_chip = {
1277
	.label			= "BFIN-GPIO",
1278 1279 1280 1281 1282 1283
	.direction_input	= bfin_gpiolib_direction_input,
	.get			= bfin_gpiolib_get_value,
	.direction_output	= bfin_gpiolib_direction_output,
	.set			= bfin_gpiolib_set_value,
	.request		= bfin_gpiolib_gpio_request,
	.free			= bfin_gpiolib_gpio_free,
1284
	.to_irq			= bfin_gpiolib_gpio_to_irq,
1285 1286 1287 1288 1289 1290 1291 1292 1293 1294
	.base			= 0,
	.ngpio			= MAX_BLACKFIN_GPIOS,
};

static int __init bfin_gpiolib_setup(void)
{
	return gpiochip_add(&bfin_chip);
}
arch_initcall(bfin_gpiolib_setup);
#endif