cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

gpio-samsung.c (31106B)


      1// SPDX-License-Identifier: GPL-2.0
      2//
      3// Copyright (c) 2009-2011 Samsung Electronics Co., Ltd.
      4//		http://www.samsung.com/
      5//
      6// Copyright 2008 Openmoko, Inc.
      7// Copyright 2008 Simtec Electronics
      8//      Ben Dooks <ben@simtec.co.uk>
      9//      http://armlinux.simtec.co.uk/
     10//
     11// Samsung - GPIOlib support
     12
     13#include <linux/kernel.h>
     14#include <linux/irq.h>
     15#include <linux/io.h>
     16#include <linux/gpio.h>
     17#include <linux/init.h>
     18#include <linux/spinlock.h>
     19#include <linux/module.h>
     20#include <linux/interrupt.h>
     21#include <linux/device.h>
     22#include <linux/ioport.h>
     23#include <linux/of.h>
     24#include <linux/slab.h>
     25#include <linux/of_address.h>
     26
     27#include <asm/irq.h>
     28
     29#include "irqs.h"
     30#include "map.h"
     31#include "regs-gpio.h"
     32#include "gpio-samsung.h"
     33
     34#include "cpu.h"
     35#include "gpio-core.h"
     36#include "gpio-cfg.h"
     37#include "gpio-cfg-helpers.h"
     38#include "hardware-s3c24xx.h"
     39#include "pm.h"
     40
     41int samsung_gpio_setpull_updown(struct samsung_gpio_chip *chip,
     42				unsigned int off, samsung_gpio_pull_t pull)
     43{
     44	void __iomem *reg = chip->base + 0x08;
     45	int shift = off * 2;
     46	u32 pup;
     47
     48	pup = __raw_readl(reg);
     49	pup &= ~(3 << shift);
     50	pup |= pull << shift;
     51	__raw_writel(pup, reg);
     52
     53	return 0;
     54}
     55
     56samsung_gpio_pull_t samsung_gpio_getpull_updown(struct samsung_gpio_chip *chip,
     57						unsigned int off)
     58{
     59	void __iomem *reg = chip->base + 0x08;
     60	int shift = off * 2;
     61	u32 pup = __raw_readl(reg);
     62
     63	pup >>= shift;
     64	pup &= 0x3;
     65
     66	return (__force samsung_gpio_pull_t)pup;
     67}
     68
     69int s3c2443_gpio_setpull(struct samsung_gpio_chip *chip,
     70			 unsigned int off, samsung_gpio_pull_t pull)
     71{
     72	switch (pull) {
     73	case S3C_GPIO_PULL_NONE:
     74		pull = 0x01;
     75		break;
     76	case S3C_GPIO_PULL_UP:
     77		pull = 0x00;
     78		break;
     79	case S3C_GPIO_PULL_DOWN:
     80		pull = 0x02;
     81		break;
     82	}
     83	return samsung_gpio_setpull_updown(chip, off, pull);
     84}
     85
     86samsung_gpio_pull_t s3c2443_gpio_getpull(struct samsung_gpio_chip *chip,
     87					 unsigned int off)
     88{
     89	samsung_gpio_pull_t pull;
     90
     91	pull = samsung_gpio_getpull_updown(chip, off);
     92
     93	switch (pull) {
     94	case 0x00:
     95		pull = S3C_GPIO_PULL_UP;
     96		break;
     97	case 0x01:
     98	case 0x03:
     99		pull = S3C_GPIO_PULL_NONE;
    100		break;
    101	case 0x02:
    102		pull = S3C_GPIO_PULL_DOWN;
    103		break;
    104	}
    105
    106	return pull;
    107}
    108
    109static int s3c24xx_gpio_setpull_1(struct samsung_gpio_chip *chip,
    110				  unsigned int off, samsung_gpio_pull_t pull,
    111				  samsung_gpio_pull_t updown)
    112{
    113	void __iomem *reg = chip->base + 0x08;
    114	u32 pup = __raw_readl(reg);
    115
    116	if (pull == updown)
    117		pup &= ~(1 << off);
    118	else if (pull == S3C_GPIO_PULL_NONE)
    119		pup |= (1 << off);
    120	else
    121		return -EINVAL;
    122
    123	__raw_writel(pup, reg);
    124	return 0;
    125}
    126
    127static samsung_gpio_pull_t s3c24xx_gpio_getpull_1(struct samsung_gpio_chip *chip,
    128						  unsigned int off,
    129						  samsung_gpio_pull_t updown)
    130{
    131	void __iomem *reg = chip->base + 0x08;
    132	u32 pup = __raw_readl(reg);
    133
    134	pup &= (1 << off);
    135	return pup ? S3C_GPIO_PULL_NONE : updown;
    136}
    137
    138samsung_gpio_pull_t s3c24xx_gpio_getpull_1up(struct samsung_gpio_chip *chip,
    139					     unsigned int off)
    140{
    141	return s3c24xx_gpio_getpull_1(chip, off, S3C_GPIO_PULL_UP);
    142}
    143
    144int s3c24xx_gpio_setpull_1up(struct samsung_gpio_chip *chip,
    145			     unsigned int off, samsung_gpio_pull_t pull)
    146{
    147	return s3c24xx_gpio_setpull_1(chip, off, pull, S3C_GPIO_PULL_UP);
    148}
    149
    150samsung_gpio_pull_t s3c24xx_gpio_getpull_1down(struct samsung_gpio_chip *chip,
    151					       unsigned int off)
    152{
    153	return s3c24xx_gpio_getpull_1(chip, off, S3C_GPIO_PULL_DOWN);
    154}
    155
    156int s3c24xx_gpio_setpull_1down(struct samsung_gpio_chip *chip,
    157			       unsigned int off, samsung_gpio_pull_t pull)
    158{
    159	return s3c24xx_gpio_setpull_1(chip, off, pull, S3C_GPIO_PULL_DOWN);
    160}
    161
    162/*
    163 * samsung_gpio_setcfg_2bit - Samsung 2bit style GPIO configuration.
    164 * @chip: The gpio chip that is being configured.
    165 * @off: The offset for the GPIO being configured.
    166 * @cfg: The configuration value to set.
    167 *
    168 * This helper deal with the GPIO cases where the control register
    169 * has two bits of configuration per gpio, which have the following
    170 * functions:
    171 *	00 = input
    172 *	01 = output
    173 *	1x = special function
    174 */
    175
    176static int samsung_gpio_setcfg_2bit(struct samsung_gpio_chip *chip,
    177				    unsigned int off, unsigned int cfg)
    178{
    179	void __iomem *reg = chip->base;
    180	unsigned int shift = off * 2;
    181	u32 con;
    182
    183	if (samsung_gpio_is_cfg_special(cfg)) {
    184		cfg &= 0xf;
    185		if (cfg > 3)
    186			return -EINVAL;
    187
    188		cfg <<= shift;
    189	}
    190
    191	con = __raw_readl(reg);
    192	con &= ~(0x3 << shift);
    193	con |= cfg;
    194	__raw_writel(con, reg);
    195
    196	return 0;
    197}
    198
    199/*
    200 * samsung_gpio_getcfg_2bit - Samsung 2bit style GPIO configuration read.
    201 * @chip: The gpio chip that is being configured.
    202 * @off: The offset for the GPIO being configured.
    203 *
    204 * The reverse of samsung_gpio_setcfg_2bit(). Will return a value which
    205 * could be directly passed back to samsung_gpio_setcfg_2bit(), from the
    206 * S3C_GPIO_SPECIAL() macro.
    207 */
    208
    209static unsigned int samsung_gpio_getcfg_2bit(struct samsung_gpio_chip *chip,
    210					     unsigned int off)
    211{
    212	u32 con;
    213
    214	con = __raw_readl(chip->base);
    215	con >>= off * 2;
    216	con &= 3;
    217
    218	/* this conversion works for IN and OUT as well as special mode */
    219	return S3C_GPIO_SPECIAL(con);
    220}
    221
    222/*
    223 * samsung_gpio_setcfg_4bit - Samsung 4bit single register GPIO config.
    224 * @chip: The gpio chip that is being configured.
    225 * @off: The offset for the GPIO being configured.
    226 * @cfg: The configuration value to set.
    227 *
    228 * This helper deal with the GPIO cases where the control register has 4 bits
    229 * of control per GPIO, generally in the form of:
    230 *	0000 = Input
    231 *	0001 = Output
    232 *	others = Special functions (dependent on bank)
    233 *
    234 * Note, since the code to deal with the case where there are two control
    235 * registers instead of one, we do not have a separate set of functions for
    236 * each case.
    237 */
    238
    239static int samsung_gpio_setcfg_4bit(struct samsung_gpio_chip *chip,
    240				    unsigned int off, unsigned int cfg)
    241{
    242	void __iomem *reg = chip->base;
    243	unsigned int shift = (off & 7) * 4;
    244	u32 con;
    245
    246	if (off < 8 && chip->chip.ngpio > 8)
    247		reg -= 4;
    248
    249	if (samsung_gpio_is_cfg_special(cfg)) {
    250		cfg &= 0xf;
    251		cfg <<= shift;
    252	}
    253
    254	con = __raw_readl(reg);
    255	con &= ~(0xf << shift);
    256	con |= cfg;
    257	__raw_writel(con, reg);
    258
    259	return 0;
    260}
    261
    262/*
    263 * samsung_gpio_getcfg_4bit - Samsung 4bit single register GPIO config read.
    264 * @chip: The gpio chip that is being configured.
    265 * @off: The offset for the GPIO being configured.
    266 *
    267 * The reverse of samsung_gpio_setcfg_4bit(), turning a gpio configuration
    268 * register setting into a value the software can use, such as could be passed
    269 * to samsung_gpio_setcfg_4bit().
    270 *
    271 * @sa samsung_gpio_getcfg_2bit
    272 */
    273
    274static unsigned samsung_gpio_getcfg_4bit(struct samsung_gpio_chip *chip,
    275					 unsigned int off)
    276{
    277	void __iomem *reg = chip->base;
    278	unsigned int shift = (off & 7) * 4;
    279	u32 con;
    280
    281	if (off < 8 && chip->chip.ngpio > 8)
    282		reg -= 4;
    283
    284	con = __raw_readl(reg);
    285	con >>= shift;
    286	con &= 0xf;
    287
    288	/* this conversion works for IN and OUT as well as special mode */
    289	return S3C_GPIO_SPECIAL(con);
    290}
    291
    292#ifdef CONFIG_PLAT_S3C24XX
    293/*
    294 * s3c24xx_gpio_setcfg_abank - S3C24XX style GPIO configuration (Bank A)
    295 * @chip: The gpio chip that is being configured.
    296 * @off: The offset for the GPIO being configured.
    297 * @cfg: The configuration value to set.
    298 *
    299 * This helper deal with the GPIO cases where the control register
    300 * has one bit of configuration for the gpio, where setting the bit
    301 * means the pin is in special function mode and unset means output.
    302 */
    303
    304static int s3c24xx_gpio_setcfg_abank(struct samsung_gpio_chip *chip,
    305				     unsigned int off, unsigned int cfg)
    306{
    307	void __iomem *reg = chip->base;
    308	unsigned int shift = off;
    309	u32 con;
    310
    311	if (samsung_gpio_is_cfg_special(cfg)) {
    312		cfg &= 0xf;
    313
    314		/* Map output to 0, and SFN2 to 1 */
    315		cfg -= 1;
    316		if (cfg > 1)
    317			return -EINVAL;
    318
    319		cfg <<= shift;
    320	}
    321
    322	con = __raw_readl(reg);
    323	con &= ~(0x1 << shift);
    324	con |= cfg;
    325	__raw_writel(con, reg);
    326
    327	return 0;
    328}
    329
    330/*
    331 * s3c24xx_gpio_getcfg_abank - S3C24XX style GPIO configuration read (Bank A)
    332 * @chip: The gpio chip that is being configured.
    333 * @off: The offset for the GPIO being configured.
    334 *
    335 * The reverse of s3c24xx_gpio_setcfg_abank() turning an GPIO into a usable
    336 * GPIO configuration value.
    337 *
    338 * @sa samsung_gpio_getcfg_2bit
    339 * @sa samsung_gpio_getcfg_4bit
    340 */
    341
    342static unsigned s3c24xx_gpio_getcfg_abank(struct samsung_gpio_chip *chip,
    343					  unsigned int off)
    344{
    345	u32 con;
    346
    347	con = __raw_readl(chip->base);
    348	con >>= off;
    349	con &= 1;
    350	con++;
    351
    352	return S3C_GPIO_SFN(con);
    353}
    354#endif
    355
    356static void __init samsung_gpiolib_set_cfg(struct samsung_gpio_cfg *chipcfg,
    357					   int nr_chips)
    358{
    359	for (; nr_chips > 0; nr_chips--, chipcfg++) {
    360		if (!chipcfg->set_config)
    361			chipcfg->set_config = samsung_gpio_setcfg_4bit;
    362		if (!chipcfg->get_config)
    363			chipcfg->get_config = samsung_gpio_getcfg_4bit;
    364		if (!chipcfg->set_pull)
    365			chipcfg->set_pull = samsung_gpio_setpull_updown;
    366		if (!chipcfg->get_pull)
    367			chipcfg->get_pull = samsung_gpio_getpull_updown;
    368	}
    369}
    370
    371struct samsung_gpio_cfg s3c24xx_gpiocfg_default = {
    372	.set_config	= samsung_gpio_setcfg_2bit,
    373	.get_config	= samsung_gpio_getcfg_2bit,
    374};
    375
    376#ifdef CONFIG_PLAT_S3C24XX
    377static struct samsung_gpio_cfg s3c24xx_gpiocfg_banka = {
    378	.set_config	= s3c24xx_gpio_setcfg_abank,
    379	.get_config	= s3c24xx_gpio_getcfg_abank,
    380};
    381#endif
    382
    383static struct samsung_gpio_cfg samsung_gpio_cfgs[] = {
    384	[0] = {
    385		.cfg_eint	= 0x0,
    386	},
    387	[1] = {
    388		.cfg_eint	= 0x3,
    389	},
    390	[2] = {
    391		.cfg_eint	= 0x7,
    392	},
    393	[3] = {
    394		.cfg_eint	= 0xF,
    395	},
    396	[4] = {
    397		.cfg_eint	= 0x0,
    398		.set_config	= samsung_gpio_setcfg_2bit,
    399		.get_config	= samsung_gpio_getcfg_2bit,
    400	},
    401	[5] = {
    402		.cfg_eint	= 0x2,
    403		.set_config	= samsung_gpio_setcfg_2bit,
    404		.get_config	= samsung_gpio_getcfg_2bit,
    405	},
    406	[6] = {
    407		.cfg_eint	= 0x3,
    408		.set_config	= samsung_gpio_setcfg_2bit,
    409		.get_config	= samsung_gpio_getcfg_2bit,
    410	},
    411	[7] = {
    412		.set_config	= samsung_gpio_setcfg_2bit,
    413		.get_config	= samsung_gpio_getcfg_2bit,
    414	},
    415};
    416
    417/*
    418 * Default routines for controlling GPIO, based on the original S3C24XX
    419 * GPIO functions which deal with the case where each gpio bank of the
    420 * chip is as following:
    421 *
    422 * base + 0x00: Control register, 2 bits per gpio
    423 *	        gpio n: 2 bits starting at (2*n)
    424 *		00 = input, 01 = output, others mean special-function
    425 * base + 0x04: Data register, 1 bit per gpio
    426 *		bit n: data bit n
    427*/
    428
    429static int samsung_gpiolib_2bit_input(struct gpio_chip *chip, unsigned offset)
    430{
    431	struct samsung_gpio_chip *ourchip = to_samsung_gpio(chip);
    432	void __iomem *base = ourchip->base;
    433	unsigned long flags;
    434	unsigned long con;
    435
    436	samsung_gpio_lock(ourchip, flags);
    437
    438	con = __raw_readl(base + 0x00);
    439	con &= ~(3 << (offset * 2));
    440
    441	__raw_writel(con, base + 0x00);
    442
    443	samsung_gpio_unlock(ourchip, flags);
    444	return 0;
    445}
    446
    447static int samsung_gpiolib_2bit_output(struct gpio_chip *chip,
    448				       unsigned offset, int value)
    449{
    450	struct samsung_gpio_chip *ourchip = to_samsung_gpio(chip);
    451	void __iomem *base = ourchip->base;
    452	unsigned long flags;
    453	unsigned long dat;
    454	unsigned long con;
    455
    456	samsung_gpio_lock(ourchip, flags);
    457
    458	dat = __raw_readl(base + 0x04);
    459	dat &= ~(1 << offset);
    460	if (value)
    461		dat |= 1 << offset;
    462	__raw_writel(dat, base + 0x04);
    463
    464	con = __raw_readl(base + 0x00);
    465	con &= ~(3 << (offset * 2));
    466	con |= 1 << (offset * 2);
    467
    468	__raw_writel(con, base + 0x00);
    469	__raw_writel(dat, base + 0x04);
    470
    471	samsung_gpio_unlock(ourchip, flags);
    472	return 0;
    473}
    474
    475/*
    476 * The samsung_gpiolib_4bit routines are to control the gpio banks where
    477 * the gpio configuration register (GPxCON) has 4 bits per GPIO, as the
    478 * following example:
    479 *
    480 * base + 0x00: Control register, 4 bits per gpio
    481 *		gpio n: 4 bits starting at (4*n)
    482 *		0000 = input, 0001 = output, others mean special-function
    483 * base + 0x04: Data register, 1 bit per gpio
    484 *		bit n: data bit n
    485 *
    486 * Note, since the data register is one bit per gpio and is at base + 0x4
    487 * we can use samsung_gpiolib_get and samsung_gpiolib_set to change the
    488 * state of the output.
    489 */
    490
    491static int samsung_gpiolib_4bit_input(struct gpio_chip *chip,
    492				      unsigned int offset)
    493{
    494	struct samsung_gpio_chip *ourchip = to_samsung_gpio(chip);
    495	void __iomem *base = ourchip->base;
    496	unsigned long con;
    497
    498	con = __raw_readl(base + GPIOCON_OFF);
    499	if (ourchip->bitmap_gpio_int & BIT(offset))
    500		con |= 0xf << con_4bit_shift(offset);
    501	else
    502		con &= ~(0xf << con_4bit_shift(offset));
    503	__raw_writel(con, base + GPIOCON_OFF);
    504
    505	pr_debug("%s: %p: CON now %08lx\n", __func__, base, con);
    506
    507	return 0;
    508}
    509
    510static int samsung_gpiolib_4bit_output(struct gpio_chip *chip,
    511				       unsigned int offset, int value)
    512{
    513	struct samsung_gpio_chip *ourchip = to_samsung_gpio(chip);
    514	void __iomem *base = ourchip->base;
    515	unsigned long con;
    516	unsigned long dat;
    517
    518	con = __raw_readl(base + GPIOCON_OFF);
    519	con &= ~(0xf << con_4bit_shift(offset));
    520	con |= 0x1 << con_4bit_shift(offset);
    521
    522	dat = __raw_readl(base + GPIODAT_OFF);
    523
    524	if (value)
    525		dat |= 1 << offset;
    526	else
    527		dat &= ~(1 << offset);
    528
    529	__raw_writel(dat, base + GPIODAT_OFF);
    530	__raw_writel(con, base + GPIOCON_OFF);
    531	__raw_writel(dat, base + GPIODAT_OFF);
    532
    533	pr_debug("%s: %p: CON %08lx, DAT %08lx\n", __func__, base, con, dat);
    534
    535	return 0;
    536}
    537
    538/*
    539 * The next set of routines are for the case where the GPIO configuration
    540 * registers are 4 bits per GPIO but there is more than one register (the
    541 * bank has more than 8 GPIOs.
    542 *
    543 * This case is the similar to the 4 bit case, but the registers are as
    544 * follows:
    545 *
    546 * base + 0x00: Control register, 4 bits per gpio (lower 8 GPIOs)
    547 *		gpio n: 4 bits starting at (4*n)
    548 *		0000 = input, 0001 = output, others mean special-function
    549 * base + 0x04: Control register, 4 bits per gpio (up to 8 additions GPIOs)
    550 *		gpio n: 4 bits starting at (4*n)
    551 *		0000 = input, 0001 = output, others mean special-function
    552 * base + 0x08: Data register, 1 bit per gpio
    553 *		bit n: data bit n
    554 *
    555 * To allow us to use the samsung_gpiolib_get and samsung_gpiolib_set
    556 * routines we store the 'base + 0x4' address so that these routines see
    557 * the data register at ourchip->base + 0x04.
    558 */
    559
    560static int samsung_gpiolib_4bit2_input(struct gpio_chip *chip,
    561				       unsigned int offset)
    562{
    563	struct samsung_gpio_chip *ourchip = to_samsung_gpio(chip);
    564	void __iomem *base = ourchip->base;
    565	void __iomem *regcon = base;
    566	unsigned long con;
    567
    568	if (offset > 7)
    569		offset -= 8;
    570	else
    571		regcon -= 4;
    572
    573	con = __raw_readl(regcon);
    574	con &= ~(0xf << con_4bit_shift(offset));
    575	__raw_writel(con, regcon);
    576
    577	pr_debug("%s: %p: CON %08lx\n", __func__, base, con);
    578
    579	return 0;
    580}
    581
    582static int samsung_gpiolib_4bit2_output(struct gpio_chip *chip,
    583					unsigned int offset, int value)
    584{
    585	struct samsung_gpio_chip *ourchip = to_samsung_gpio(chip);
    586	void __iomem *base = ourchip->base;
    587	void __iomem *regcon = base;
    588	unsigned long con;
    589	unsigned long dat;
    590	unsigned con_offset = offset;
    591
    592	if (con_offset > 7)
    593		con_offset -= 8;
    594	else
    595		regcon -= 4;
    596
    597	con = __raw_readl(regcon);
    598	con &= ~(0xf << con_4bit_shift(con_offset));
    599	con |= 0x1 << con_4bit_shift(con_offset);
    600
    601	dat = __raw_readl(base + GPIODAT_OFF);
    602
    603	if (value)
    604		dat |= 1 << offset;
    605	else
    606		dat &= ~(1 << offset);
    607
    608	__raw_writel(dat, base + GPIODAT_OFF);
    609	__raw_writel(con, regcon);
    610	__raw_writel(dat, base + GPIODAT_OFF);
    611
    612	pr_debug("%s: %p: CON %08lx, DAT %08lx\n", __func__, base, con, dat);
    613
    614	return 0;
    615}
    616
    617#ifdef CONFIG_PLAT_S3C24XX
    618/* The next set of routines are for the case of s3c24xx bank a */
    619
    620static int s3c24xx_gpiolib_banka_input(struct gpio_chip *chip, unsigned offset)
    621{
    622	return -EINVAL;
    623}
    624
    625static int s3c24xx_gpiolib_banka_output(struct gpio_chip *chip,
    626					unsigned offset, int value)
    627{
    628	struct samsung_gpio_chip *ourchip = to_samsung_gpio(chip);
    629	void __iomem *base = ourchip->base;
    630	unsigned long flags;
    631	unsigned long dat;
    632	unsigned long con;
    633
    634	local_irq_save(flags);
    635
    636	con = __raw_readl(base + 0x00);
    637	dat = __raw_readl(base + 0x04);
    638
    639	dat &= ~(1 << offset);
    640	if (value)
    641		dat |= 1 << offset;
    642
    643	__raw_writel(dat, base + 0x04);
    644
    645	con &= ~(1 << offset);
    646
    647	__raw_writel(con, base + 0x00);
    648	__raw_writel(dat, base + 0x04);
    649
    650	local_irq_restore(flags);
    651	return 0;
    652}
    653#endif
    654
    655static void samsung_gpiolib_set(struct gpio_chip *chip,
    656				unsigned offset, int value)
    657{
    658	struct samsung_gpio_chip *ourchip = to_samsung_gpio(chip);
    659	void __iomem *base = ourchip->base;
    660	unsigned long flags;
    661	unsigned long dat;
    662
    663	samsung_gpio_lock(ourchip, flags);
    664
    665	dat = __raw_readl(base + 0x04);
    666	dat &= ~(1 << offset);
    667	if (value)
    668		dat |= 1 << offset;
    669	__raw_writel(dat, base + 0x04);
    670
    671	samsung_gpio_unlock(ourchip, flags);
    672}
    673
    674static int samsung_gpiolib_get(struct gpio_chip *chip, unsigned offset)
    675{
    676	struct samsung_gpio_chip *ourchip = to_samsung_gpio(chip);
    677	unsigned long val;
    678
    679	val = __raw_readl(ourchip->base + 0x04);
    680	val >>= offset;
    681	val &= 1;
    682
    683	return val;
    684}
    685
    686/*
    687 * CONFIG_S3C_GPIO_TRACK enables the tracking of the s3c specific gpios
    688 * for use with the configuration calls, and other parts of the s3c gpiolib
    689 * support code.
    690 *
    691 * Not all s3c support code will need this, as some configurations of cpu
    692 * may only support one or two different configuration options and have an
    693 * easy gpio to samsung_gpio_chip mapping function. If this is the case, then
    694 * the machine support file should provide its own samsung_gpiolib_getchip()
    695 * and any other necessary functions.
    696 */
    697
    698#ifdef CONFIG_S3C_GPIO_TRACK
    699struct samsung_gpio_chip *s3c_gpios[S3C_GPIO_END];
    700
    701static __init void s3c_gpiolib_track(struct samsung_gpio_chip *chip)
    702{
    703	unsigned int gpn;
    704	int i;
    705
    706	gpn = chip->chip.base;
    707	for (i = 0; i < chip->chip.ngpio; i++, gpn++) {
    708		BUG_ON(gpn >= ARRAY_SIZE(s3c_gpios));
    709		s3c_gpios[gpn] = chip;
    710	}
    711}
    712#endif /* CONFIG_S3C_GPIO_TRACK */
    713
    714/*
    715 * samsung_gpiolib_add() - add the Samsung gpio_chip.
    716 * @chip: The chip to register
    717 *
    718 * This is a wrapper to gpiochip_add() that takes our specific gpio chip
    719 * information and makes the necessary alterations for the platform and
    720 * notes the information for use with the configuration systems and any
    721 * other parts of the system.
    722 */
    723
    724static void __init samsung_gpiolib_add(struct samsung_gpio_chip *chip)
    725{
    726	struct gpio_chip *gc = &chip->chip;
    727	int ret;
    728
    729	BUG_ON(!chip->base);
    730	BUG_ON(!gc->label);
    731	BUG_ON(!gc->ngpio);
    732
    733	spin_lock_init(&chip->lock);
    734
    735	if (!gc->direction_input)
    736		gc->direction_input = samsung_gpiolib_2bit_input;
    737	if (!gc->direction_output)
    738		gc->direction_output = samsung_gpiolib_2bit_output;
    739	if (!gc->set)
    740		gc->set = samsung_gpiolib_set;
    741	if (!gc->get)
    742		gc->get = samsung_gpiolib_get;
    743
    744#ifdef CONFIG_PM
    745	if (chip->pm != NULL) {
    746		if (!chip->pm->save || !chip->pm->resume)
    747			pr_err("gpio: %s has missing PM functions\n",
    748			       gc->label);
    749	} else
    750		pr_err("gpio: %s has no PM function\n", gc->label);
    751#endif
    752
    753	/* gpiochip_add() prints own failure message on error. */
    754	ret = gpiochip_add_data(gc, chip);
    755	if (ret >= 0)
    756		s3c_gpiolib_track(chip);
    757}
    758
    759static void __init s3c24xx_gpiolib_add_chips(struct samsung_gpio_chip *chip,
    760					     int nr_chips, void __iomem *base)
    761{
    762	int i;
    763	struct gpio_chip *gc = &chip->chip;
    764
    765	for (i = 0 ; i < nr_chips; i++, chip++) {
    766		/* skip banks not present on SoC */
    767		if (chip->chip.base >= S3C_GPIO_END)
    768			continue;
    769
    770		if (!chip->config)
    771			chip->config = &s3c24xx_gpiocfg_default;
    772		if (!chip->pm)
    773			chip->pm = __gpio_pm(&samsung_gpio_pm_2bit);
    774		if ((base != NULL) && (chip->base == NULL))
    775			chip->base = base + ((i) * 0x10);
    776
    777		if (!gc->direction_input)
    778			gc->direction_input = samsung_gpiolib_2bit_input;
    779		if (!gc->direction_output)
    780			gc->direction_output = samsung_gpiolib_2bit_output;
    781
    782		samsung_gpiolib_add(chip);
    783	}
    784}
    785
    786static void __init samsung_gpiolib_add_2bit_chips(struct samsung_gpio_chip *chip,
    787						  int nr_chips, void __iomem *base,
    788						  unsigned int offset)
    789{
    790	int i;
    791
    792	for (i = 0 ; i < nr_chips; i++, chip++) {
    793		chip->chip.direction_input = samsung_gpiolib_2bit_input;
    794		chip->chip.direction_output = samsung_gpiolib_2bit_output;
    795
    796		if (!chip->config)
    797			chip->config = &samsung_gpio_cfgs[7];
    798		if (!chip->pm)
    799			chip->pm = __gpio_pm(&samsung_gpio_pm_2bit);
    800		if ((base != NULL) && (chip->base == NULL))
    801			chip->base = base + ((i) * offset);
    802
    803		samsung_gpiolib_add(chip);
    804	}
    805}
    806
    807/*
    808 * samsung_gpiolib_add_4bit_chips - 4bit single register GPIO config.
    809 * @chip: The gpio chip that is being configured.
    810 * @nr_chips: The no of chips (gpio ports) for the GPIO being configured.
    811 *
    812 * This helper deal with the GPIO cases where the control register has 4 bits
    813 * of control per GPIO, generally in the form of:
    814 * 0000 = Input
    815 * 0001 = Output
    816 * others = Special functions (dependent on bank)
    817 *
    818 * Note, since the code to deal with the case where there are two control
    819 * registers instead of one, we do not have a separate set of function
    820 * (samsung_gpiolib_add_4bit2_chips)for each case.
    821 */
    822
    823static void __init samsung_gpiolib_add_4bit_chips(struct samsung_gpio_chip *chip,
    824						  int nr_chips, void __iomem *base)
    825{
    826	int i;
    827
    828	for (i = 0 ; i < nr_chips; i++, chip++) {
    829		chip->chip.direction_input = samsung_gpiolib_4bit_input;
    830		chip->chip.direction_output = samsung_gpiolib_4bit_output;
    831
    832		if (!chip->config)
    833			chip->config = &samsung_gpio_cfgs[2];
    834		if (!chip->pm)
    835			chip->pm = __gpio_pm(&samsung_gpio_pm_4bit);
    836		if ((base != NULL) && (chip->base == NULL))
    837			chip->base = base + ((i) * 0x20);
    838
    839		chip->bitmap_gpio_int = 0;
    840
    841		samsung_gpiolib_add(chip);
    842	}
    843}
    844
    845static void __init samsung_gpiolib_add_4bit2_chips(struct samsung_gpio_chip *chip,
    846						   int nr_chips)
    847{
    848	for (; nr_chips > 0; nr_chips--, chip++) {
    849		chip->chip.direction_input = samsung_gpiolib_4bit2_input;
    850		chip->chip.direction_output = samsung_gpiolib_4bit2_output;
    851
    852		if (!chip->config)
    853			chip->config = &samsung_gpio_cfgs[2];
    854		if (!chip->pm)
    855			chip->pm = __gpio_pm(&samsung_gpio_pm_4bit);
    856
    857		samsung_gpiolib_add(chip);
    858	}
    859}
    860
    861int samsung_gpiolib_to_irq(struct gpio_chip *chip, unsigned int offset)
    862{
    863	struct samsung_gpio_chip *samsung_chip = gpiochip_get_data(chip);
    864
    865	return samsung_chip->irq_base + offset;
    866}
    867
    868#ifdef CONFIG_PLAT_S3C24XX
    869static int s3c24xx_gpiolib_fbank_to_irq(struct gpio_chip *chip, unsigned offset)
    870{
    871	if (offset < 4) {
    872		if (soc_is_s3c2412())
    873			return IRQ_EINT0_2412 + offset;
    874		else
    875			return IRQ_EINT0 + offset;
    876	}
    877
    878	if (offset < 8)
    879		return IRQ_EINT4 + offset - 4;
    880
    881	return -EINVAL;
    882}
    883#endif
    884
    885#ifdef CONFIG_ARCH_S3C64XX
    886static int s3c64xx_gpiolib_mbank_to_irq(struct gpio_chip *chip, unsigned pin)
    887{
    888	return pin < 5 ? IRQ_EINT(23) + pin : -ENXIO;
    889}
    890
    891static int s3c64xx_gpiolib_lbank_to_irq(struct gpio_chip *chip, unsigned pin)
    892{
    893	return pin >= 8 ? IRQ_EINT(16) + pin - 8 : -ENXIO;
    894}
    895#endif
    896
    897struct samsung_gpio_chip s3c24xx_gpios[] = {
    898#ifdef CONFIG_PLAT_S3C24XX
    899	{
    900		.config	= &s3c24xx_gpiocfg_banka,
    901		.chip	= {
    902			.base			= S3C2410_GPA(0),
    903			.owner			= THIS_MODULE,
    904			.label			= "GPIOA",
    905			.ngpio			= 27,
    906			.direction_input	= s3c24xx_gpiolib_banka_input,
    907			.direction_output	= s3c24xx_gpiolib_banka_output,
    908		},
    909	}, {
    910		.chip	= {
    911			.base	= S3C2410_GPB(0),
    912			.owner	= THIS_MODULE,
    913			.label	= "GPIOB",
    914			.ngpio	= 11,
    915		},
    916	}, {
    917		.chip	= {
    918			.base	= S3C2410_GPC(0),
    919			.owner	= THIS_MODULE,
    920			.label	= "GPIOC",
    921			.ngpio	= 16,
    922		},
    923	}, {
    924		.chip	= {
    925			.base	= S3C2410_GPD(0),
    926			.owner	= THIS_MODULE,
    927			.label	= "GPIOD",
    928			.ngpio	= 16,
    929		},
    930	}, {
    931		.chip	= {
    932			.base	= S3C2410_GPE(0),
    933			.label	= "GPIOE",
    934			.owner	= THIS_MODULE,
    935			.ngpio	= 16,
    936		},
    937	}, {
    938		.chip	= {
    939			.base	= S3C2410_GPF(0),
    940			.owner	= THIS_MODULE,
    941			.label	= "GPIOF",
    942			.ngpio	= 8,
    943			.to_irq	= s3c24xx_gpiolib_fbank_to_irq,
    944		},
    945	}, {
    946		.irq_base = IRQ_EINT8,
    947		.chip	= {
    948			.base	= S3C2410_GPG(0),
    949			.owner	= THIS_MODULE,
    950			.label	= "GPIOG",
    951			.ngpio	= 16,
    952			.to_irq	= samsung_gpiolib_to_irq,
    953		},
    954	}, {
    955		.chip	= {
    956			.base	= S3C2410_GPH(0),
    957			.owner	= THIS_MODULE,
    958			.label	= "GPIOH",
    959			.ngpio	= 15,
    960		},
    961	},
    962		/* GPIOS for the S3C2443 and later devices. */
    963	{
    964		.base	= S3C2440_GPJCON,
    965		.chip	= {
    966			.base	= S3C2410_GPJ(0),
    967			.owner	= THIS_MODULE,
    968			.label	= "GPIOJ",
    969			.ngpio	= 16,
    970		},
    971	}, {
    972		.base	= S3C2443_GPKCON,
    973		.chip	= {
    974			.base	= S3C2410_GPK(0),
    975			.owner	= THIS_MODULE,
    976			.label	= "GPIOK",
    977			.ngpio	= 16,
    978		},
    979	}, {
    980		.base	= S3C2443_GPLCON,
    981		.chip	= {
    982			.base	= S3C2410_GPL(0),
    983			.owner	= THIS_MODULE,
    984			.label	= "GPIOL",
    985			.ngpio	= 15,
    986		},
    987	}, {
    988		.base	= S3C2443_GPMCON,
    989		.chip	= {
    990			.base	= S3C2410_GPM(0),
    991			.owner	= THIS_MODULE,
    992			.label	= "GPIOM",
    993			.ngpio	= 2,
    994		},
    995	},
    996#endif
    997};
    998
    999/*
   1000 * GPIO bank summary:
   1001 *
   1002 * Bank	GPIOs	Style	SlpCon	ExtInt Group
   1003 * A	8	4Bit	Yes	1
   1004 * B	7	4Bit	Yes	1
   1005 * C	8	4Bit	Yes	2
   1006 * D	5	4Bit	Yes	3
   1007 * E	5	4Bit	Yes	None
   1008 * F	16	2Bit	Yes	4 [1]
   1009 * G	7	4Bit	Yes	5
   1010 * H	10	4Bit[2]	Yes	6
   1011 * I	16	2Bit	Yes	None
   1012 * J	12	2Bit	Yes	None
   1013 * K	16	4Bit[2]	No	None
   1014 * L	15	4Bit[2] No	None
   1015 * M	6	4Bit	No	IRQ_EINT
   1016 * N	16	2Bit	No	IRQ_EINT
   1017 * O	16	2Bit	Yes	7
   1018 * P	15	2Bit	Yes	8
   1019 * Q	9	2Bit	Yes	9
   1020 *
   1021 * [1] BANKF pins 14,15 do not form part of the external interrupt sources
   1022 * [2] BANK has two control registers, GPxCON0 and GPxCON1
   1023 */
   1024
   1025static struct samsung_gpio_chip s3c64xx_gpios_4bit[] = {
   1026#ifdef CONFIG_ARCH_S3C64XX
   1027	{
   1028		.chip	= {
   1029			.base	= S3C64XX_GPA(0),
   1030			.ngpio	= S3C64XX_GPIO_A_NR,
   1031			.label	= "GPA",
   1032		},
   1033	}, {
   1034		.chip	= {
   1035			.base	= S3C64XX_GPB(0),
   1036			.ngpio	= S3C64XX_GPIO_B_NR,
   1037			.label	= "GPB",
   1038		},
   1039	}, {
   1040		.chip	= {
   1041			.base	= S3C64XX_GPC(0),
   1042			.ngpio	= S3C64XX_GPIO_C_NR,
   1043			.label	= "GPC",
   1044		},
   1045	}, {
   1046		.chip	= {
   1047			.base	= S3C64XX_GPD(0),
   1048			.ngpio	= S3C64XX_GPIO_D_NR,
   1049			.label	= "GPD",
   1050		},
   1051	}, {
   1052		.config	= &samsung_gpio_cfgs[0],
   1053		.chip	= {
   1054			.base	= S3C64XX_GPE(0),
   1055			.ngpio	= S3C64XX_GPIO_E_NR,
   1056			.label	= "GPE",
   1057		},
   1058	}, {
   1059		.base	= S3C64XX_GPG_BASE,
   1060		.chip	= {
   1061			.base	= S3C64XX_GPG(0),
   1062			.ngpio	= S3C64XX_GPIO_G_NR,
   1063			.label	= "GPG",
   1064		},
   1065	}, {
   1066		.base	= S3C64XX_GPM_BASE,
   1067		.config	= &samsung_gpio_cfgs[1],
   1068		.chip	= {
   1069			.base	= S3C64XX_GPM(0),
   1070			.ngpio	= S3C64XX_GPIO_M_NR,
   1071			.label	= "GPM",
   1072			.to_irq = s3c64xx_gpiolib_mbank_to_irq,
   1073		},
   1074	},
   1075#endif
   1076};
   1077
   1078static struct samsung_gpio_chip s3c64xx_gpios_4bit2[] = {
   1079#ifdef CONFIG_ARCH_S3C64XX
   1080	{
   1081		.base	= S3C64XX_GPH_BASE + 0x4,
   1082		.chip	= {
   1083			.base	= S3C64XX_GPH(0),
   1084			.ngpio	= S3C64XX_GPIO_H_NR,
   1085			.label	= "GPH",
   1086		},
   1087	}, {
   1088		.base	= S3C64XX_GPK_BASE + 0x4,
   1089		.config	= &samsung_gpio_cfgs[0],
   1090		.chip	= {
   1091			.base	= S3C64XX_GPK(0),
   1092			.ngpio	= S3C64XX_GPIO_K_NR,
   1093			.label	= "GPK",
   1094		},
   1095	}, {
   1096		.base	= S3C64XX_GPL_BASE + 0x4,
   1097		.config	= &samsung_gpio_cfgs[1],
   1098		.chip	= {
   1099			.base	= S3C64XX_GPL(0),
   1100			.ngpio	= S3C64XX_GPIO_L_NR,
   1101			.label	= "GPL",
   1102			.to_irq = s3c64xx_gpiolib_lbank_to_irq,
   1103		},
   1104	},
   1105#endif
   1106};
   1107
   1108static struct samsung_gpio_chip s3c64xx_gpios_2bit[] = {
   1109#ifdef CONFIG_ARCH_S3C64XX
   1110	{
   1111		.base	= S3C64XX_GPF_BASE,
   1112		.config	= &samsung_gpio_cfgs[6],
   1113		.chip	= {
   1114			.base	= S3C64XX_GPF(0),
   1115			.ngpio	= S3C64XX_GPIO_F_NR,
   1116			.label	= "GPF",
   1117		},
   1118	}, {
   1119		.config	= &samsung_gpio_cfgs[7],
   1120		.chip	= {
   1121			.base	= S3C64XX_GPI(0),
   1122			.ngpio	= S3C64XX_GPIO_I_NR,
   1123			.label	= "GPI",
   1124		},
   1125	}, {
   1126		.config	= &samsung_gpio_cfgs[7],
   1127		.chip	= {
   1128			.base	= S3C64XX_GPJ(0),
   1129			.ngpio	= S3C64XX_GPIO_J_NR,
   1130			.label	= "GPJ",
   1131		},
   1132	}, {
   1133		.config	= &samsung_gpio_cfgs[6],
   1134		.chip	= {
   1135			.base	= S3C64XX_GPO(0),
   1136			.ngpio	= S3C64XX_GPIO_O_NR,
   1137			.label	= "GPO",
   1138		},
   1139	}, {
   1140		.config	= &samsung_gpio_cfgs[6],
   1141		.chip	= {
   1142			.base	= S3C64XX_GPP(0),
   1143			.ngpio	= S3C64XX_GPIO_P_NR,
   1144			.label	= "GPP",
   1145		},
   1146	}, {
   1147		.config	= &samsung_gpio_cfgs[6],
   1148		.chip	= {
   1149			.base	= S3C64XX_GPQ(0),
   1150			.ngpio	= S3C64XX_GPIO_Q_NR,
   1151			.label	= "GPQ",
   1152		},
   1153	}, {
   1154		.base	= S3C64XX_GPN_BASE,
   1155		.irq_base = IRQ_EINT(0),
   1156		.config	= &samsung_gpio_cfgs[5],
   1157		.chip	= {
   1158			.base	= S3C64XX_GPN(0),
   1159			.ngpio	= S3C64XX_GPIO_N_NR,
   1160			.label	= "GPN",
   1161			.to_irq = samsung_gpiolib_to_irq,
   1162		},
   1163	},
   1164#endif
   1165};
   1166
   1167/* TODO: cleanup soc_is_* */
   1168static __init int samsung_gpiolib_init(void)
   1169{
   1170	/*
   1171	 * Currently there are two drivers that can provide GPIO support for
   1172	 * Samsung SoCs. For device tree enabled platforms, the new
   1173	 * pinctrl-samsung driver is used, providing both GPIO and pin control
   1174	 * interfaces. For legacy (non-DT) platforms this driver is used.
   1175	 */
   1176	if (of_have_populated_dt())
   1177		return 0;
   1178
   1179	if (soc_is_s3c24xx()) {
   1180		samsung_gpiolib_set_cfg(samsung_gpio_cfgs,
   1181				ARRAY_SIZE(samsung_gpio_cfgs));
   1182		s3c24xx_gpiolib_add_chips(s3c24xx_gpios,
   1183				ARRAY_SIZE(s3c24xx_gpios), S3C24XX_VA_GPIO);
   1184	} else if (soc_is_s3c64xx()) {
   1185		samsung_gpiolib_set_cfg(samsung_gpio_cfgs,
   1186				ARRAY_SIZE(samsung_gpio_cfgs));
   1187		samsung_gpiolib_add_2bit_chips(s3c64xx_gpios_2bit,
   1188				ARRAY_SIZE(s3c64xx_gpios_2bit),
   1189				S3C64XX_VA_GPIO + 0xE0, 0x20);
   1190		samsung_gpiolib_add_4bit_chips(s3c64xx_gpios_4bit,
   1191				ARRAY_SIZE(s3c64xx_gpios_4bit),
   1192				S3C64XX_VA_GPIO);
   1193		samsung_gpiolib_add_4bit2_chips(s3c64xx_gpios_4bit2,
   1194				ARRAY_SIZE(s3c64xx_gpios_4bit2));
   1195	}
   1196
   1197	return 0;
   1198}
   1199core_initcall(samsung_gpiolib_init);
   1200
   1201int s3c_gpio_cfgpin(unsigned int pin, unsigned int config)
   1202{
   1203	struct samsung_gpio_chip *chip = samsung_gpiolib_getchip(pin);
   1204	unsigned long flags;
   1205	int offset;
   1206	int ret;
   1207
   1208	if (!chip)
   1209		return -EINVAL;
   1210
   1211	offset = pin - chip->chip.base;
   1212
   1213	samsung_gpio_lock(chip, flags);
   1214	ret = samsung_gpio_do_setcfg(chip, offset, config);
   1215	samsung_gpio_unlock(chip, flags);
   1216
   1217	return ret;
   1218}
   1219EXPORT_SYMBOL(s3c_gpio_cfgpin);
   1220
   1221int s3c_gpio_cfgpin_range(unsigned int start, unsigned int nr,
   1222			  unsigned int cfg)
   1223{
   1224	int ret;
   1225
   1226	for (; nr > 0; nr--, start++) {
   1227		ret = s3c_gpio_cfgpin(start, cfg);
   1228		if (ret != 0)
   1229			return ret;
   1230	}
   1231
   1232	return 0;
   1233}
   1234EXPORT_SYMBOL_GPL(s3c_gpio_cfgpin_range);
   1235
   1236int s3c_gpio_cfgall_range(unsigned int start, unsigned int nr,
   1237			  unsigned int cfg, samsung_gpio_pull_t pull)
   1238{
   1239	int ret;
   1240
   1241	for (; nr > 0; nr--, start++) {
   1242		s3c_gpio_setpull(start, pull);
   1243		ret = s3c_gpio_cfgpin(start, cfg);
   1244		if (ret != 0)
   1245			return ret;
   1246	}
   1247
   1248	return 0;
   1249}
   1250EXPORT_SYMBOL_GPL(s3c_gpio_cfgall_range);
   1251
   1252unsigned s3c_gpio_getcfg(unsigned int pin)
   1253{
   1254	struct samsung_gpio_chip *chip = samsung_gpiolib_getchip(pin);
   1255	unsigned long flags;
   1256	unsigned ret = 0;
   1257	int offset;
   1258
   1259	if (chip) {
   1260		offset = pin - chip->chip.base;
   1261
   1262		samsung_gpio_lock(chip, flags);
   1263		ret = samsung_gpio_do_getcfg(chip, offset);
   1264		samsung_gpio_unlock(chip, flags);
   1265	}
   1266
   1267	return ret;
   1268}
   1269EXPORT_SYMBOL(s3c_gpio_getcfg);
   1270
   1271int s3c_gpio_setpull(unsigned int pin, samsung_gpio_pull_t pull)
   1272{
   1273	struct samsung_gpio_chip *chip = samsung_gpiolib_getchip(pin);
   1274	unsigned long flags;
   1275	int offset, ret;
   1276
   1277	if (!chip)
   1278		return -EINVAL;
   1279
   1280	offset = pin - chip->chip.base;
   1281
   1282	samsung_gpio_lock(chip, flags);
   1283	ret = samsung_gpio_do_setpull(chip, offset, pull);
   1284	samsung_gpio_unlock(chip, flags);
   1285
   1286	return ret;
   1287}
   1288EXPORT_SYMBOL(s3c_gpio_setpull);
   1289
   1290samsung_gpio_pull_t s3c_gpio_getpull(unsigned int pin)
   1291{
   1292	struct samsung_gpio_chip *chip = samsung_gpiolib_getchip(pin);
   1293	unsigned long flags;
   1294	int offset;
   1295	u32 pup = 0;
   1296
   1297	if (chip) {
   1298		offset = pin - chip->chip.base;
   1299
   1300		samsung_gpio_lock(chip, flags);
   1301		pup = samsung_gpio_do_getpull(chip, offset);
   1302		samsung_gpio_unlock(chip, flags);
   1303	}
   1304
   1305	return (__force samsung_gpio_pull_t)pup;
   1306}
   1307EXPORT_SYMBOL(s3c_gpio_getpull);
   1308
   1309#ifdef CONFIG_PLAT_S3C24XX
   1310unsigned int s3c2410_modify_misccr(unsigned int clear, unsigned int change)
   1311{
   1312	unsigned long flags;
   1313	unsigned long misccr;
   1314
   1315	local_irq_save(flags);
   1316	misccr = __raw_readl(S3C24XX_MISCCR);
   1317	misccr &= ~clear;
   1318	misccr ^= change;
   1319	__raw_writel(misccr, S3C24XX_MISCCR);
   1320	local_irq_restore(flags);
   1321
   1322	return misccr;
   1323}
   1324EXPORT_SYMBOL(s3c2410_modify_misccr);
   1325#endif