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

pinctrl-s3c64xx.c (19941B)


      1// SPDX-License-Identifier: GPL-2.0+
      2//
      3// S3C64xx specific support for pinctrl-samsung driver.
      4//
      5// Copyright (c) 2013 Tomasz Figa <tomasz.figa@gmail.com>
      6//
      7// Based on pinctrl-exynos.c, please see the file for original copyrights.
      8//
      9// This file contains the Samsung S3C64xx specific information required by the
     10// the Samsung pinctrl/gpiolib driver. It also includes the implementation of
     11// external gpio and wakeup interrupt support.
     12
     13#include <linux/init.h>
     14#include <linux/device.h>
     15#include <linux/interrupt.h>
     16#include <linux/irqdomain.h>
     17#include <linux/irq.h>
     18#include <linux/of_irq.h>
     19#include <linux/io.h>
     20#include <linux/irqchip/chained_irq.h>
     21#include <linux/slab.h>
     22#include <linux/err.h>
     23
     24#include "pinctrl-samsung.h"
     25
     26#define NUM_EINT0		28
     27#define NUM_EINT0_IRQ		4
     28#define EINT_MAX_PER_REG	16
     29#define EINT_MAX_PER_GROUP	16
     30
     31/* External GPIO and wakeup interrupt related definitions */
     32#define SVC_GROUP_SHIFT		4
     33#define SVC_GROUP_MASK		0xf
     34#define SVC_NUM_MASK		0xf
     35#define SVC_GROUP(x)		((x >> SVC_GROUP_SHIFT) & \
     36						SVC_GROUP_MASK)
     37
     38#define EINT12CON_REG		0x200
     39#define EINT12MASK_REG		0x240
     40#define EINT12PEND_REG		0x260
     41
     42#define EINT_OFFS(i)		((i) % (2 * EINT_MAX_PER_GROUP))
     43#define EINT_GROUP(i)		((i) / EINT_MAX_PER_GROUP)
     44#define EINT_REG(g)		(4 * ((g) / 2))
     45
     46#define EINTCON_REG(i)		(EINT12CON_REG + EINT_REG(EINT_GROUP(i)))
     47#define EINTMASK_REG(i)		(EINT12MASK_REG + EINT_REG(EINT_GROUP(i)))
     48#define EINTPEND_REG(i)		(EINT12PEND_REG + EINT_REG(EINT_GROUP(i)))
     49
     50#define SERVICE_REG		0x284
     51#define SERVICEPEND_REG		0x288
     52
     53#define EINT0CON0_REG		0x900
     54#define EINT0MASK_REG		0x920
     55#define EINT0PEND_REG		0x924
     56
     57/* S3C64xx specific external interrupt trigger types */
     58#define EINT_LEVEL_LOW		0
     59#define EINT_LEVEL_HIGH		1
     60#define EINT_EDGE_FALLING	2
     61#define EINT_EDGE_RISING	4
     62#define EINT_EDGE_BOTH		6
     63#define EINT_CON_MASK		0xF
     64#define EINT_CON_LEN		4
     65
     66static const struct samsung_pin_bank_type bank_type_4bit_off = {
     67	.fld_width = { 4, 1, 2, 0, 2, 2, },
     68	.reg_offset = { 0x00, 0x04, 0x08, 0, 0x0c, 0x10, },
     69};
     70
     71static const struct samsung_pin_bank_type bank_type_4bit_alive = {
     72	.fld_width = { 4, 1, 2, },
     73	.reg_offset = { 0x00, 0x04, 0x08, },
     74};
     75
     76static const struct samsung_pin_bank_type bank_type_4bit2_off = {
     77	.fld_width = { 4, 1, 2, 0, 2, 2, },
     78	.reg_offset = { 0x00, 0x08, 0x0c, 0, 0x10, 0x14, },
     79};
     80
     81static const struct samsung_pin_bank_type bank_type_4bit2_alive = {
     82	.fld_width = { 4, 1, 2, },
     83	.reg_offset = { 0x00, 0x08, 0x0c, },
     84};
     85
     86static const struct samsung_pin_bank_type bank_type_2bit_off = {
     87	.fld_width = { 2, 1, 2, 0, 2, 2, },
     88	.reg_offset = { 0x00, 0x04, 0x08, 0, 0x0c, 0x10, },
     89};
     90
     91static const struct samsung_pin_bank_type bank_type_2bit_alive = {
     92	.fld_width = { 2, 1, 2, },
     93	.reg_offset = { 0x00, 0x04, 0x08, },
     94};
     95
     96#define PIN_BANK_4BIT(pins, reg, id)			\
     97	{						\
     98		.type		= &bank_type_4bit_off,	\
     99		.pctl_offset	= reg,			\
    100		.nr_pins	= pins,			\
    101		.eint_type	= EINT_TYPE_NONE,	\
    102		.name		= id			\
    103	}
    104
    105#define PIN_BANK_4BIT_EINTG(pins, reg, id, eoffs)	\
    106	{						\
    107		.type		= &bank_type_4bit_off,	\
    108		.pctl_offset	= reg,			\
    109		.nr_pins	= pins,			\
    110		.eint_type	= EINT_TYPE_GPIO,	\
    111		.eint_func	= 7,			\
    112		.eint_mask	= (1 << (pins)) - 1,	\
    113		.eint_offset	= eoffs,		\
    114		.name		= id			\
    115	}
    116
    117#define PIN_BANK_4BIT_EINTW(pins, reg, id, eoffs, emask) \
    118	{						\
    119		.type		= &bank_type_4bit_alive,\
    120		.pctl_offset	= reg,			\
    121		.nr_pins	= pins,			\
    122		.eint_type	= EINT_TYPE_WKUP,	\
    123		.eint_func	= 3,			\
    124		.eint_mask	= emask,		\
    125		.eint_offset	= eoffs,		\
    126		.name		= id			\
    127	}
    128
    129#define PIN_BANK_4BIT2_EINTG(pins, reg, id, eoffs)	\
    130	{						\
    131		.type		= &bank_type_4bit2_off,	\
    132		.pctl_offset	= reg,			\
    133		.nr_pins	= pins,			\
    134		.eint_type	= EINT_TYPE_GPIO,	\
    135		.eint_func	= 7,			\
    136		.eint_mask	= (1 << (pins)) - 1,	\
    137		.eint_offset	= eoffs,		\
    138		.name		= id			\
    139	}
    140
    141#define PIN_BANK_4BIT2_EINTW(pins, reg, id, eoffs, emask) \
    142	{						\
    143		.type		= &bank_type_4bit2_alive,\
    144		.pctl_offset	= reg,			\
    145		.nr_pins	= pins,			\
    146		.eint_type	= EINT_TYPE_WKUP,	\
    147		.eint_func	= 3,			\
    148		.eint_mask	= emask,		\
    149		.eint_offset	= eoffs,		\
    150		.name		= id			\
    151	}
    152
    153#define PIN_BANK_4BIT2_ALIVE(pins, reg, id)		\
    154	{						\
    155		.type		= &bank_type_4bit2_alive,\
    156		.pctl_offset	= reg,			\
    157		.nr_pins	= pins,			\
    158		.eint_type	= EINT_TYPE_NONE,	\
    159		.name		= id			\
    160	}
    161
    162#define PIN_BANK_2BIT(pins, reg, id)			\
    163	{						\
    164		.type		= &bank_type_2bit_off,	\
    165		.pctl_offset	= reg,			\
    166		.nr_pins	= pins,			\
    167		.eint_type	= EINT_TYPE_NONE,	\
    168		.name		= id			\
    169	}
    170
    171#define PIN_BANK_2BIT_EINTG(pins, reg, id, eoffs, emask) \
    172	{						\
    173		.type		= &bank_type_2bit_off,	\
    174		.pctl_offset	= reg,			\
    175		.nr_pins	= pins,			\
    176		.eint_type	= EINT_TYPE_GPIO,	\
    177		.eint_func	= 3,			\
    178		.eint_mask	= emask,		\
    179		.eint_offset	= eoffs,		\
    180		.name		= id			\
    181	}
    182
    183#define PIN_BANK_2BIT_EINTW(pins, reg, id, eoffs)	\
    184	{						\
    185		.type		= &bank_type_2bit_alive,\
    186		.pctl_offset	= reg,			\
    187		.nr_pins	= pins,			\
    188		.eint_type	= EINT_TYPE_WKUP,	\
    189		.eint_func	= 2,			\
    190		.eint_mask	= (1 << (pins)) - 1,	\
    191		.eint_offset	= eoffs,		\
    192		.name		= id			\
    193	}
    194
    195/**
    196 * struct s3c64xx_eint0_data - EINT0 common data
    197 * @drvdata: pin controller driver data
    198 * @domains: IRQ domains of particular EINT0 interrupts
    199 * @pins: pin offsets inside of banks of particular EINT0 interrupts
    200 */
    201struct s3c64xx_eint0_data {
    202	struct samsung_pinctrl_drv_data *drvdata;
    203	struct irq_domain *domains[NUM_EINT0];
    204	u8 pins[NUM_EINT0];
    205};
    206
    207/**
    208 * struct s3c64xx_eint0_domain_data - EINT0 per-domain data
    209 * @bank: pin bank related to the domain
    210 * @eints: EINT0 interrupts related to the domain
    211 */
    212struct s3c64xx_eint0_domain_data {
    213	struct samsung_pin_bank *bank;
    214	u8 eints[];
    215};
    216
    217/**
    218 * struct s3c64xx_eint_gpio_data - GPIO EINT data
    219 * @drvdata: pin controller driver data
    220 * @domains: array of domains related to EINT interrupt groups
    221 */
    222struct s3c64xx_eint_gpio_data {
    223	struct samsung_pinctrl_drv_data *drvdata;
    224	struct irq_domain *domains[];
    225};
    226
    227/*
    228 * Common functions for S3C64xx EINT configuration
    229 */
    230
    231static int s3c64xx_irq_get_trigger(unsigned int type)
    232{
    233	int trigger;
    234
    235	switch (type) {
    236	case IRQ_TYPE_EDGE_RISING:
    237		trigger = EINT_EDGE_RISING;
    238		break;
    239	case IRQ_TYPE_EDGE_FALLING:
    240		trigger = EINT_EDGE_FALLING;
    241		break;
    242	case IRQ_TYPE_EDGE_BOTH:
    243		trigger = EINT_EDGE_BOTH;
    244		break;
    245	case IRQ_TYPE_LEVEL_HIGH:
    246		trigger = EINT_LEVEL_HIGH;
    247		break;
    248	case IRQ_TYPE_LEVEL_LOW:
    249		trigger = EINT_LEVEL_LOW;
    250		break;
    251	default:
    252		return -EINVAL;
    253	}
    254
    255	return trigger;
    256}
    257
    258static void s3c64xx_irq_set_handler(struct irq_data *d, unsigned int type)
    259{
    260	/* Edge- and level-triggered interrupts need different handlers */
    261	if (type & IRQ_TYPE_EDGE_BOTH)
    262		irq_set_handler_locked(d, handle_edge_irq);
    263	else
    264		irq_set_handler_locked(d, handle_level_irq);
    265}
    266
    267static void s3c64xx_irq_set_function(struct samsung_pinctrl_drv_data *d,
    268					struct samsung_pin_bank *bank, int pin)
    269{
    270	const struct samsung_pin_bank_type *bank_type = bank->type;
    271	unsigned long flags;
    272	void __iomem *reg;
    273	u8 shift;
    274	u32 mask;
    275	u32 val;
    276
    277	/* Make sure that pin is configured as interrupt */
    278	reg = d->virt_base + bank->pctl_offset;
    279	shift = pin;
    280	if (bank_type->fld_width[PINCFG_TYPE_FUNC] * shift >= 32) {
    281		/* 4-bit bank type with 2 con regs */
    282		reg += 4;
    283		shift -= 8;
    284	}
    285
    286	shift = shift * bank_type->fld_width[PINCFG_TYPE_FUNC];
    287	mask = (1 << bank_type->fld_width[PINCFG_TYPE_FUNC]) - 1;
    288
    289	raw_spin_lock_irqsave(&bank->slock, flags);
    290
    291	val = readl(reg);
    292	val &= ~(mask << shift);
    293	val |= bank->eint_func << shift;
    294	writel(val, reg);
    295
    296	raw_spin_unlock_irqrestore(&bank->slock, flags);
    297}
    298
    299/*
    300 * Functions for EINT GPIO configuration (EINT groups 1-9)
    301 */
    302
    303static inline void s3c64xx_gpio_irq_set_mask(struct irq_data *irqd, bool mask)
    304{
    305	struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd);
    306	struct samsung_pinctrl_drv_data *d = bank->drvdata;
    307	unsigned char index = EINT_OFFS(bank->eint_offset) + irqd->hwirq;
    308	void __iomem *reg = d->virt_base + EINTMASK_REG(bank->eint_offset);
    309	u32 val;
    310
    311	val = readl(reg);
    312	if (mask)
    313		val |= 1 << index;
    314	else
    315		val &= ~(1 << index);
    316	writel(val, reg);
    317}
    318
    319static void s3c64xx_gpio_irq_unmask(struct irq_data *irqd)
    320{
    321	s3c64xx_gpio_irq_set_mask(irqd, false);
    322}
    323
    324static void s3c64xx_gpio_irq_mask(struct irq_data *irqd)
    325{
    326	s3c64xx_gpio_irq_set_mask(irqd, true);
    327}
    328
    329static void s3c64xx_gpio_irq_ack(struct irq_data *irqd)
    330{
    331	struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd);
    332	struct samsung_pinctrl_drv_data *d = bank->drvdata;
    333	unsigned char index = EINT_OFFS(bank->eint_offset) + irqd->hwirq;
    334	void __iomem *reg = d->virt_base + EINTPEND_REG(bank->eint_offset);
    335
    336	writel(1 << index, reg);
    337}
    338
    339static int s3c64xx_gpio_irq_set_type(struct irq_data *irqd, unsigned int type)
    340{
    341	struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd);
    342	struct samsung_pinctrl_drv_data *d = bank->drvdata;
    343	void __iomem *reg;
    344	int trigger;
    345	u8 shift;
    346	u32 val;
    347
    348	trigger = s3c64xx_irq_get_trigger(type);
    349	if (trigger < 0) {
    350		pr_err("unsupported external interrupt type\n");
    351		return -EINVAL;
    352	}
    353
    354	s3c64xx_irq_set_handler(irqd, type);
    355
    356	/* Set up interrupt trigger */
    357	reg = d->virt_base + EINTCON_REG(bank->eint_offset);
    358	shift = EINT_OFFS(bank->eint_offset) + irqd->hwirq;
    359	shift = 4 * (shift / 4); /* 4 EINTs per trigger selector */
    360
    361	val = readl(reg);
    362	val &= ~(EINT_CON_MASK << shift);
    363	val |= trigger << shift;
    364	writel(val, reg);
    365
    366	s3c64xx_irq_set_function(d, bank, irqd->hwirq);
    367
    368	return 0;
    369}
    370
    371/*
    372 * irq_chip for gpio interrupts.
    373 */
    374static struct irq_chip s3c64xx_gpio_irq_chip = {
    375	.name		= "GPIO",
    376	.irq_unmask	= s3c64xx_gpio_irq_unmask,
    377	.irq_mask	= s3c64xx_gpio_irq_mask,
    378	.irq_ack	= s3c64xx_gpio_irq_ack,
    379	.irq_set_type	= s3c64xx_gpio_irq_set_type,
    380};
    381
    382static int s3c64xx_gpio_irq_map(struct irq_domain *h, unsigned int virq,
    383					irq_hw_number_t hw)
    384{
    385	struct samsung_pin_bank *bank = h->host_data;
    386
    387	if (!(bank->eint_mask & (1 << hw)))
    388		return -EINVAL;
    389
    390	irq_set_chip_and_handler(virq,
    391				&s3c64xx_gpio_irq_chip, handle_level_irq);
    392	irq_set_chip_data(virq, bank);
    393
    394	return 0;
    395}
    396
    397/*
    398 * irq domain callbacks for external gpio interrupt controller.
    399 */
    400static const struct irq_domain_ops s3c64xx_gpio_irqd_ops = {
    401	.map	= s3c64xx_gpio_irq_map,
    402	.xlate	= irq_domain_xlate_twocell,
    403};
    404
    405static void s3c64xx_eint_gpio_irq(struct irq_desc *desc)
    406{
    407	struct irq_chip *chip = irq_desc_get_chip(desc);
    408	struct s3c64xx_eint_gpio_data *data = irq_desc_get_handler_data(desc);
    409	struct samsung_pinctrl_drv_data *drvdata = data->drvdata;
    410
    411	chained_irq_enter(chip, desc);
    412
    413	do {
    414		unsigned int svc;
    415		unsigned int group;
    416		unsigned int pin;
    417		int ret;
    418
    419		svc = readl(drvdata->virt_base + SERVICE_REG);
    420		group = SVC_GROUP(svc);
    421		pin = svc & SVC_NUM_MASK;
    422
    423		if (!group)
    424			break;
    425
    426		/* Group 1 is used for two pin banks */
    427		if (group == 1) {
    428			if (pin < 8)
    429				group = 0;
    430			else
    431				pin -= 8;
    432		}
    433
    434		ret = generic_handle_domain_irq(data->domains[group], pin);
    435		/*
    436		 * Something must be really wrong if an unmapped EINT
    437		 * was unmasked...
    438		 */
    439		BUG_ON(ret);
    440	} while (1);
    441
    442	chained_irq_exit(chip, desc);
    443}
    444
    445/**
    446 * s3c64xx_eint_gpio_init() - setup handling of external gpio interrupts.
    447 * @d: driver data of samsung pinctrl driver.
    448 */
    449static int s3c64xx_eint_gpio_init(struct samsung_pinctrl_drv_data *d)
    450{
    451	struct s3c64xx_eint_gpio_data *data;
    452	struct samsung_pin_bank *bank;
    453	struct device *dev = d->dev;
    454	unsigned int nr_domains;
    455	unsigned int i;
    456
    457	if (!d->irq) {
    458		dev_err(dev, "irq number not available\n");
    459		return -EINVAL;
    460	}
    461
    462	nr_domains = 0;
    463	bank = d->pin_banks;
    464	for (i = 0; i < d->nr_banks; ++i, ++bank) {
    465		unsigned int nr_eints;
    466		unsigned int mask;
    467
    468		if (bank->eint_type != EINT_TYPE_GPIO)
    469			continue;
    470
    471		mask = bank->eint_mask;
    472		nr_eints = fls(mask);
    473
    474		bank->irq_domain = irq_domain_create_linear(bank->fwnode,
    475					nr_eints, &s3c64xx_gpio_irqd_ops, bank);
    476		if (!bank->irq_domain) {
    477			dev_err(dev, "gpio irq domain add failed\n");
    478			return -ENXIO;
    479		}
    480
    481		++nr_domains;
    482	}
    483
    484	data = devm_kzalloc(dev, struct_size(data, domains, nr_domains),
    485			    GFP_KERNEL);
    486	if (!data)
    487		return -ENOMEM;
    488	data->drvdata = d;
    489
    490	bank = d->pin_banks;
    491	nr_domains = 0;
    492	for (i = 0; i < d->nr_banks; ++i, ++bank) {
    493		if (bank->eint_type != EINT_TYPE_GPIO)
    494			continue;
    495
    496		data->domains[nr_domains++] = bank->irq_domain;
    497	}
    498
    499	irq_set_chained_handler_and_data(d->irq, s3c64xx_eint_gpio_irq, data);
    500
    501	return 0;
    502}
    503
    504/*
    505 * Functions for configuration of EINT0 wake-up interrupts
    506 */
    507
    508static inline void s3c64xx_eint0_irq_set_mask(struct irq_data *irqd, bool mask)
    509{
    510	struct s3c64xx_eint0_domain_data *ddata =
    511					irq_data_get_irq_chip_data(irqd);
    512	struct samsung_pinctrl_drv_data *d = ddata->bank->drvdata;
    513	u32 val;
    514
    515	val = readl(d->virt_base + EINT0MASK_REG);
    516	if (mask)
    517		val |= 1 << ddata->eints[irqd->hwirq];
    518	else
    519		val &= ~(1 << ddata->eints[irqd->hwirq]);
    520	writel(val, d->virt_base + EINT0MASK_REG);
    521}
    522
    523static void s3c64xx_eint0_irq_unmask(struct irq_data *irqd)
    524{
    525	s3c64xx_eint0_irq_set_mask(irqd, false);
    526}
    527
    528static void s3c64xx_eint0_irq_mask(struct irq_data *irqd)
    529{
    530	s3c64xx_eint0_irq_set_mask(irqd, true);
    531}
    532
    533static void s3c64xx_eint0_irq_ack(struct irq_data *irqd)
    534{
    535	struct s3c64xx_eint0_domain_data *ddata =
    536					irq_data_get_irq_chip_data(irqd);
    537	struct samsung_pinctrl_drv_data *d = ddata->bank->drvdata;
    538
    539	writel(1 << ddata->eints[irqd->hwirq],
    540					d->virt_base + EINT0PEND_REG);
    541}
    542
    543static int s3c64xx_eint0_irq_set_type(struct irq_data *irqd, unsigned int type)
    544{
    545	struct s3c64xx_eint0_domain_data *ddata =
    546					irq_data_get_irq_chip_data(irqd);
    547	struct samsung_pin_bank *bank = ddata->bank;
    548	struct samsung_pinctrl_drv_data *d = bank->drvdata;
    549	void __iomem *reg;
    550	int trigger;
    551	u8 shift;
    552	u32 val;
    553
    554	trigger = s3c64xx_irq_get_trigger(type);
    555	if (trigger < 0) {
    556		pr_err("unsupported external interrupt type\n");
    557		return -EINVAL;
    558	}
    559
    560	s3c64xx_irq_set_handler(irqd, type);
    561
    562	/* Set up interrupt trigger */
    563	reg = d->virt_base + EINT0CON0_REG;
    564	shift = ddata->eints[irqd->hwirq];
    565	if (shift >= EINT_MAX_PER_REG) {
    566		reg += 4;
    567		shift -= EINT_MAX_PER_REG;
    568	}
    569	shift = EINT_CON_LEN * (shift / 2);
    570
    571	val = readl(reg);
    572	val &= ~(EINT_CON_MASK << shift);
    573	val |= trigger << shift;
    574	writel(val, reg);
    575
    576	s3c64xx_irq_set_function(d, bank, irqd->hwirq);
    577
    578	return 0;
    579}
    580
    581/*
    582 * irq_chip for wakeup interrupts
    583 */
    584static struct irq_chip s3c64xx_eint0_irq_chip = {
    585	.name		= "EINT0",
    586	.irq_unmask	= s3c64xx_eint0_irq_unmask,
    587	.irq_mask	= s3c64xx_eint0_irq_mask,
    588	.irq_ack	= s3c64xx_eint0_irq_ack,
    589	.irq_set_type	= s3c64xx_eint0_irq_set_type,
    590};
    591
    592static inline void s3c64xx_irq_demux_eint(struct irq_desc *desc, u32 range)
    593{
    594	struct irq_chip *chip = irq_desc_get_chip(desc);
    595	struct s3c64xx_eint0_data *data = irq_desc_get_handler_data(desc);
    596	struct samsung_pinctrl_drv_data *drvdata = data->drvdata;
    597	unsigned int pend, mask;
    598
    599	chained_irq_enter(chip, desc);
    600
    601	pend = readl(drvdata->virt_base + EINT0PEND_REG);
    602	mask = readl(drvdata->virt_base + EINT0MASK_REG);
    603
    604	pend = pend & range & ~mask;
    605	pend &= range;
    606
    607	while (pend) {
    608		unsigned int irq;
    609		int ret;
    610
    611		irq = fls(pend) - 1;
    612		pend &= ~(1 << irq);
    613		ret = generic_handle_domain_irq(data->domains[irq], data->pins[irq]);
    614		/*
    615		 * Something must be really wrong if an unmapped EINT
    616		 * was unmasked...
    617		 */
    618		BUG_ON(ret);
    619	}
    620
    621	chained_irq_exit(chip, desc);
    622}
    623
    624static void s3c64xx_demux_eint0_3(struct irq_desc *desc)
    625{
    626	s3c64xx_irq_demux_eint(desc, 0xf);
    627}
    628
    629static void s3c64xx_demux_eint4_11(struct irq_desc *desc)
    630{
    631	s3c64xx_irq_demux_eint(desc, 0xff0);
    632}
    633
    634static void s3c64xx_demux_eint12_19(struct irq_desc *desc)
    635{
    636	s3c64xx_irq_demux_eint(desc, 0xff000);
    637}
    638
    639static void s3c64xx_demux_eint20_27(struct irq_desc *desc)
    640{
    641	s3c64xx_irq_demux_eint(desc, 0xff00000);
    642}
    643
    644static irq_flow_handler_t s3c64xx_eint0_handlers[NUM_EINT0_IRQ] = {
    645	s3c64xx_demux_eint0_3,
    646	s3c64xx_demux_eint4_11,
    647	s3c64xx_demux_eint12_19,
    648	s3c64xx_demux_eint20_27,
    649};
    650
    651static int s3c64xx_eint0_irq_map(struct irq_domain *h, unsigned int virq,
    652					irq_hw_number_t hw)
    653{
    654	struct s3c64xx_eint0_domain_data *ddata = h->host_data;
    655	struct samsung_pin_bank *bank = ddata->bank;
    656
    657	if (!(bank->eint_mask & (1 << hw)))
    658		return -EINVAL;
    659
    660	irq_set_chip_and_handler(virq,
    661				&s3c64xx_eint0_irq_chip, handle_level_irq);
    662	irq_set_chip_data(virq, ddata);
    663
    664	return 0;
    665}
    666
    667/*
    668 * irq domain callbacks for external wakeup interrupt controller.
    669 */
    670static const struct irq_domain_ops s3c64xx_eint0_irqd_ops = {
    671	.map	= s3c64xx_eint0_irq_map,
    672	.xlate	= irq_domain_xlate_twocell,
    673};
    674
    675/* list of external wakeup controllers supported */
    676static const struct of_device_id s3c64xx_eint0_irq_ids[] = {
    677	{ .compatible = "samsung,s3c64xx-wakeup-eint", },
    678	{ }
    679};
    680
    681/**
    682 * s3c64xx_eint_eint0_init() - setup handling of external wakeup interrupts.
    683 * @d: driver data of samsung pinctrl driver.
    684 */
    685static int s3c64xx_eint_eint0_init(struct samsung_pinctrl_drv_data *d)
    686{
    687	struct device *dev = d->dev;
    688	struct device_node *eint0_np = NULL;
    689	struct device_node *np;
    690	struct samsung_pin_bank *bank;
    691	struct s3c64xx_eint0_data *data;
    692	unsigned int i;
    693
    694	for_each_child_of_node(dev->of_node, np) {
    695		if (of_match_node(s3c64xx_eint0_irq_ids, np)) {
    696			eint0_np = np;
    697			break;
    698		}
    699	}
    700	if (!eint0_np)
    701		return -ENODEV;
    702
    703	data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
    704	if (!data) {
    705		of_node_put(eint0_np);
    706		return -ENOMEM;
    707	}
    708	data->drvdata = d;
    709
    710	for (i = 0; i < NUM_EINT0_IRQ; ++i) {
    711		unsigned int irq;
    712
    713		irq = irq_of_parse_and_map(eint0_np, i);
    714		if (!irq) {
    715			dev_err(dev, "failed to get wakeup EINT IRQ %d\n", i);
    716			of_node_put(eint0_np);
    717			return -ENXIO;
    718		}
    719
    720		irq_set_chained_handler_and_data(irq,
    721						 s3c64xx_eint0_handlers[i],
    722						 data);
    723	}
    724	of_node_put(eint0_np);
    725
    726	bank = d->pin_banks;
    727	for (i = 0; i < d->nr_banks; ++i, ++bank) {
    728		struct s3c64xx_eint0_domain_data *ddata;
    729		unsigned int nr_eints;
    730		unsigned int mask;
    731		unsigned int irq;
    732		unsigned int pin;
    733
    734		if (bank->eint_type != EINT_TYPE_WKUP)
    735			continue;
    736
    737		mask = bank->eint_mask;
    738		nr_eints = fls(mask);
    739
    740		ddata = devm_kzalloc(dev,
    741				sizeof(*ddata) + nr_eints, GFP_KERNEL);
    742		if (!ddata)
    743			return -ENOMEM;
    744		ddata->bank = bank;
    745
    746		bank->irq_domain = irq_domain_create_linear(bank->fwnode,
    747				nr_eints, &s3c64xx_eint0_irqd_ops, ddata);
    748		if (!bank->irq_domain) {
    749			dev_err(dev, "wkup irq domain add failed\n");
    750			return -ENXIO;
    751		}
    752
    753		irq = bank->eint_offset;
    754		mask = bank->eint_mask;
    755		for (pin = 0; mask; ++pin, mask >>= 1) {
    756			if (!(mask & 1))
    757				continue;
    758			data->domains[irq] = bank->irq_domain;
    759			data->pins[irq] = pin;
    760			ddata->eints[pin] = irq;
    761			++irq;
    762		}
    763	}
    764
    765	return 0;
    766}
    767
    768/* pin banks of s3c64xx pin-controller 0 */
    769static const struct samsung_pin_bank_data s3c64xx_pin_banks0[] __initconst = {
    770	PIN_BANK_4BIT_EINTG(8, 0x000, "gpa", 0),
    771	PIN_BANK_4BIT_EINTG(7, 0x020, "gpb", 8),
    772	PIN_BANK_4BIT_EINTG(8, 0x040, "gpc", 16),
    773	PIN_BANK_4BIT_EINTG(5, 0x060, "gpd", 32),
    774	PIN_BANK_4BIT(5, 0x080, "gpe"),
    775	PIN_BANK_2BIT_EINTG(16, 0x0a0, "gpf", 48, 0x3fff),
    776	PIN_BANK_4BIT_EINTG(7, 0x0c0, "gpg", 64),
    777	PIN_BANK_4BIT2_EINTG(10, 0x0e0, "gph", 80),
    778	PIN_BANK_2BIT(16, 0x100, "gpi"),
    779	PIN_BANK_2BIT(12, 0x120, "gpj"),
    780	PIN_BANK_4BIT2_ALIVE(16, 0x800, "gpk"),
    781	PIN_BANK_4BIT2_EINTW(15, 0x810, "gpl", 16, 0x7f00),
    782	PIN_BANK_4BIT_EINTW(6, 0x820, "gpm", 23, 0x1f),
    783	PIN_BANK_2BIT_EINTW(16, 0x830, "gpn", 0),
    784	PIN_BANK_2BIT_EINTG(16, 0x140, "gpo", 96, 0xffff),
    785	PIN_BANK_2BIT_EINTG(15, 0x160, "gpp", 112, 0x7fff),
    786	PIN_BANK_2BIT_EINTG(9, 0x180, "gpq", 128, 0x1ff),
    787};
    788
    789/*
    790 * Samsung pinctrl driver data for S3C64xx SoC. S3C64xx SoC includes
    791 * one gpio/pin-mux/pinconfig controller.
    792 */
    793static const struct samsung_pin_ctrl s3c64xx_pin_ctrl[] __initconst = {
    794	{
    795		/* pin-controller instance 1 data */
    796		.pin_banks	= s3c64xx_pin_banks0,
    797		.nr_banks	= ARRAY_SIZE(s3c64xx_pin_banks0),
    798		.eint_gpio_init = s3c64xx_eint_gpio_init,
    799		.eint_wkup_init = s3c64xx_eint_eint0_init,
    800	},
    801};
    802
    803const struct samsung_pinctrl_of_match_data s3c64xx_of_data __initconst = {
    804	.ctrl		= s3c64xx_pin_ctrl,
    805	.num_ctrl	= ARRAY_SIZE(s3c64xx_pin_ctrl),
    806};