Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

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