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-msc313.c (19952B)


      1// SPDX-License-Identifier: GPL-2.0
      2/* Copyright (C) 2020 Daniel Palmer<daniel@thingy.jp> */
      3
      4#include <linux/bitops.h>
      5#include <linux/kernel.h>
      6#include <linux/types.h>
      7#include <linux/io.h>
      8#include <linux/of.h>
      9#include <linux/of_device.h>
     10#include <linux/of_irq.h>
     11#include <linux/gpio/driver.h>
     12#include <linux/module.h>
     13#include <linux/platform_device.h>
     14
     15#include <dt-bindings/gpio/msc313-gpio.h>
     16#include <dt-bindings/interrupt-controller/arm-gic.h>
     17
     18#define DRIVER_NAME "gpio-msc313"
     19
     20#define MSC313_GPIO_IN  BIT(0)
     21#define MSC313_GPIO_OUT BIT(4)
     22#define MSC313_GPIO_OEN BIT(5)
     23
     24/*
     25 * These bits need to be saved to correctly restore the
     26 * gpio state when resuming from suspend to memory.
     27 */
     28#define MSC313_GPIO_BITSTOSAVE (MSC313_GPIO_OUT | MSC313_GPIO_OEN)
     29
     30/* pad names for fuart, same for all SoCs so far */
     31#define MSC313_PINNAME_FUART_RX		"fuart_rx"
     32#define MSC313_PINNAME_FUART_TX		"fuart_tx"
     33#define MSC313_PINNAME_FUART_CTS	"fuart_cts"
     34#define MSC313_PINNAME_FUART_RTS	"fuart_rts"
     35
     36/* pad names for sr, mercury5 is different */
     37#define MSC313_PINNAME_SR_IO2		"sr_io2"
     38#define MSC313_PINNAME_SR_IO3		"sr_io3"
     39#define MSC313_PINNAME_SR_IO4		"sr_io4"
     40#define MSC313_PINNAME_SR_IO5		"sr_io5"
     41#define MSC313_PINNAME_SR_IO6		"sr_io6"
     42#define MSC313_PINNAME_SR_IO7		"sr_io7"
     43#define MSC313_PINNAME_SR_IO8		"sr_io8"
     44#define MSC313_PINNAME_SR_IO9		"sr_io9"
     45#define MSC313_PINNAME_SR_IO10		"sr_io10"
     46#define MSC313_PINNAME_SR_IO11		"sr_io11"
     47#define MSC313_PINNAME_SR_IO12		"sr_io12"
     48#define MSC313_PINNAME_SR_IO13		"sr_io13"
     49#define MSC313_PINNAME_SR_IO14		"sr_io14"
     50#define MSC313_PINNAME_SR_IO15		"sr_io15"
     51#define MSC313_PINNAME_SR_IO16		"sr_io16"
     52#define MSC313_PINNAME_SR_IO17		"sr_io17"
     53
     54/* pad names for sd, same for all SoCs so far */
     55#define MSC313_PINNAME_SD_CLK		"sd_clk"
     56#define MSC313_PINNAME_SD_CMD		"sd_cmd"
     57#define MSC313_PINNAME_SD_D0		"sd_d0"
     58#define MSC313_PINNAME_SD_D1		"sd_d1"
     59#define MSC313_PINNAME_SD_D2		"sd_d2"
     60#define MSC313_PINNAME_SD_D3		"sd_d3"
     61
     62/* pad names for i2c1, same for all SoCs so for */
     63#define MSC313_PINNAME_I2C1_SCL		"i2c1_scl"
     64#define MSC313_PINNAME_I2C1_SCA		"i2c1_sda"
     65
     66/* pad names for spi0, same for all SoCs so far */
     67#define MSC313_PINNAME_SPI0_CZ		"spi0_cz"
     68#define MSC313_PINNAME_SPI0_CK		"spi0_ck"
     69#define MSC313_PINNAME_SPI0_DI		"spi0_di"
     70#define MSC313_PINNAME_SPI0_DO		"spi0_do"
     71
     72#define FUART_NAMES			\
     73	MSC313_PINNAME_FUART_RX,	\
     74	MSC313_PINNAME_FUART_TX,	\
     75	MSC313_PINNAME_FUART_CTS,	\
     76	MSC313_PINNAME_FUART_RTS
     77
     78#define OFF_FUART_RX	0x50
     79#define OFF_FUART_TX	0x54
     80#define OFF_FUART_CTS	0x58
     81#define OFF_FUART_RTS	0x5c
     82
     83#define FUART_OFFSETS	\
     84	OFF_FUART_RX,	\
     85	OFF_FUART_TX,	\
     86	OFF_FUART_CTS,	\
     87	OFF_FUART_RTS
     88
     89#define SR_NAMES		\
     90	MSC313_PINNAME_SR_IO2,	\
     91	MSC313_PINNAME_SR_IO3,	\
     92	MSC313_PINNAME_SR_IO4,	\
     93	MSC313_PINNAME_SR_IO5,	\
     94	MSC313_PINNAME_SR_IO6,	\
     95	MSC313_PINNAME_SR_IO7,	\
     96	MSC313_PINNAME_SR_IO8,	\
     97	MSC313_PINNAME_SR_IO9,	\
     98	MSC313_PINNAME_SR_IO10,	\
     99	MSC313_PINNAME_SR_IO11,	\
    100	MSC313_PINNAME_SR_IO12,	\
    101	MSC313_PINNAME_SR_IO13,	\
    102	MSC313_PINNAME_SR_IO14,	\
    103	MSC313_PINNAME_SR_IO15,	\
    104	MSC313_PINNAME_SR_IO16,	\
    105	MSC313_PINNAME_SR_IO17
    106
    107#define OFF_SR_IO2	0x88
    108#define OFF_SR_IO3	0x8c
    109#define OFF_SR_IO4	0x90
    110#define OFF_SR_IO5	0x94
    111#define OFF_SR_IO6	0x98
    112#define OFF_SR_IO7	0x9c
    113#define OFF_SR_IO8	0xa0
    114#define OFF_SR_IO9	0xa4
    115#define OFF_SR_IO10	0xa8
    116#define OFF_SR_IO11	0xac
    117#define OFF_SR_IO12	0xb0
    118#define OFF_SR_IO13	0xb4
    119#define OFF_SR_IO14	0xb8
    120#define OFF_SR_IO15	0xbc
    121#define OFF_SR_IO16	0xc0
    122#define OFF_SR_IO17	0xc4
    123
    124#define SR_OFFSETS	\
    125	OFF_SR_IO2,	\
    126	OFF_SR_IO3,	\
    127	OFF_SR_IO4,	\
    128	OFF_SR_IO5,	\
    129	OFF_SR_IO6,	\
    130	OFF_SR_IO7,	\
    131	OFF_SR_IO8,	\
    132	OFF_SR_IO9,	\
    133	OFF_SR_IO10,	\
    134	OFF_SR_IO11,	\
    135	OFF_SR_IO12,	\
    136	OFF_SR_IO13,	\
    137	OFF_SR_IO14,	\
    138	OFF_SR_IO15,	\
    139	OFF_SR_IO16,	\
    140	OFF_SR_IO17
    141
    142#define SD_NAMES		\
    143	MSC313_PINNAME_SD_CLK,	\
    144	MSC313_PINNAME_SD_CMD,	\
    145	MSC313_PINNAME_SD_D0,	\
    146	MSC313_PINNAME_SD_D1,	\
    147	MSC313_PINNAME_SD_D2,	\
    148	MSC313_PINNAME_SD_D3
    149
    150#define OFF_SD_CLK	0x140
    151#define OFF_SD_CMD	0x144
    152#define OFF_SD_D0	0x148
    153#define OFF_SD_D1	0x14c
    154#define OFF_SD_D2	0x150
    155#define OFF_SD_D3	0x154
    156
    157#define SD_OFFSETS	\
    158	OFF_SD_CLK,	\
    159	OFF_SD_CMD,	\
    160	OFF_SD_D0,	\
    161	OFF_SD_D1,	\
    162	OFF_SD_D2,	\
    163	OFF_SD_D3
    164
    165#define I2C1_NAMES			\
    166	MSC313_PINNAME_I2C1_SCL,	\
    167	MSC313_PINNAME_I2C1_SCA
    168
    169#define OFF_I2C1_SCL	0x188
    170#define OFF_I2C1_SCA	0x18c
    171
    172#define I2C1_OFFSETS	\
    173	OFF_I2C1_SCL,	\
    174	OFF_I2C1_SCA
    175
    176#define SPI0_NAMES		\
    177	MSC313_PINNAME_SPI0_CZ,	\
    178	MSC313_PINNAME_SPI0_CK,	\
    179	MSC313_PINNAME_SPI0_DI,	\
    180	MSC313_PINNAME_SPI0_DO
    181
    182#define OFF_SPI0_CZ	0x1c0
    183#define OFF_SPI0_CK	0x1c4
    184#define OFF_SPI0_DI	0x1c8
    185#define OFF_SPI0_DO	0x1cc
    186
    187#define SPI0_OFFSETS	\
    188	OFF_SPI0_CZ,	\
    189	OFF_SPI0_CK,	\
    190	OFF_SPI0_DI,	\
    191	OFF_SPI0_DO
    192
    193struct msc313_gpio_data {
    194	const char * const *names;
    195	const unsigned int *offsets;
    196	const unsigned int num;
    197};
    198
    199#define MSC313_GPIO_CHIPDATA(_chip) \
    200static const struct msc313_gpio_data _chip##_data = { \
    201	.names = _chip##_names, \
    202	.offsets = _chip##_offsets, \
    203	.num = ARRAY_SIZE(_chip##_offsets), \
    204}
    205
    206#ifdef CONFIG_MACH_INFINITY
    207static const char * const msc313_names[] = {
    208	FUART_NAMES,
    209	SR_NAMES,
    210	SD_NAMES,
    211	I2C1_NAMES,
    212	SPI0_NAMES,
    213};
    214
    215static const unsigned int msc313_offsets[] = {
    216	FUART_OFFSETS,
    217	SR_OFFSETS,
    218	SD_OFFSETS,
    219	I2C1_OFFSETS,
    220	SPI0_OFFSETS,
    221};
    222
    223MSC313_GPIO_CHIPDATA(msc313);
    224
    225/*
    226 * Unlike the msc313(e) the ssd20xd have a bunch of pins
    227 * that are actually called gpio probably because they
    228 * have no dedicated function.
    229 */
    230#define SSD20XD_PINNAME_GPIO0		"gpio0"
    231#define SSD20XD_PINNAME_GPIO1		"gpio1"
    232#define SSD20XD_PINNAME_GPIO2		"gpio2"
    233#define SSD20XD_PINNAME_GPIO3		"gpio3"
    234#define SSD20XD_PINNAME_GPIO4		"gpio4"
    235#define SSD20XD_PINNAME_GPIO5		"gpio5"
    236#define SSD20XD_PINNAME_GPIO6		"gpio6"
    237#define SSD20XD_PINNAME_GPIO7		"gpio7"
    238#define SSD20XD_PINNAME_GPIO10		"gpio10"
    239#define SSD20XD_PINNAME_GPIO11		"gpio11"
    240#define SSD20XD_PINNAME_GPIO12		"gpio12"
    241#define SSD20XD_PINNAME_GPIO13		"gpio13"
    242#define SSD20XD_PINNAME_GPIO14		"gpio14"
    243#define SSD20XD_PINNAME_GPIO85		"gpio85"
    244#define SSD20XD_PINNAME_GPIO86		"gpio86"
    245#define SSD20XD_PINNAME_GPIO90		"gpio90"
    246
    247#define SSD20XD_GPIO_NAMES SSD20XD_PINNAME_GPIO0,  \
    248			   SSD20XD_PINNAME_GPIO1,  \
    249			   SSD20XD_PINNAME_GPIO2,  \
    250			   SSD20XD_PINNAME_GPIO3,  \
    251			   SSD20XD_PINNAME_GPIO4,  \
    252			   SSD20XD_PINNAME_GPIO5,  \
    253			   SSD20XD_PINNAME_GPIO6,  \
    254			   SSD20XD_PINNAME_GPIO7,  \
    255			   SSD20XD_PINNAME_GPIO10, \
    256			   SSD20XD_PINNAME_GPIO11, \
    257			   SSD20XD_PINNAME_GPIO12, \
    258			   SSD20XD_PINNAME_GPIO13, \
    259			   SSD20XD_PINNAME_GPIO14, \
    260			   SSD20XD_PINNAME_GPIO85, \
    261			   SSD20XD_PINNAME_GPIO86, \
    262			   SSD20XD_PINNAME_GPIO90
    263
    264#define SSD20XD_GPIO_OFF_GPIO0 0x0
    265#define SSD20XD_GPIO_OFF_GPIO1 0x4
    266#define SSD20XD_GPIO_OFF_GPIO2 0x8
    267#define SSD20XD_GPIO_OFF_GPIO3 0xc
    268#define SSD20XD_GPIO_OFF_GPIO4 0x10
    269#define SSD20XD_GPIO_OFF_GPIO5 0x14
    270#define SSD20XD_GPIO_OFF_GPIO6 0x18
    271#define SSD20XD_GPIO_OFF_GPIO7 0x1c
    272#define SSD20XD_GPIO_OFF_GPIO10 0x28
    273#define SSD20XD_GPIO_OFF_GPIO11 0x2c
    274#define SSD20XD_GPIO_OFF_GPIO12 0x30
    275#define SSD20XD_GPIO_OFF_GPIO13 0x34
    276#define SSD20XD_GPIO_OFF_GPIO14 0x38
    277#define SSD20XD_GPIO_OFF_GPIO85 0x100
    278#define SSD20XD_GPIO_OFF_GPIO86 0x104
    279#define SSD20XD_GPIO_OFF_GPIO90 0x114
    280
    281#define SSD20XD_GPIO_OFFSETS SSD20XD_GPIO_OFF_GPIO0,  \
    282			     SSD20XD_GPIO_OFF_GPIO1,  \
    283			     SSD20XD_GPIO_OFF_GPIO2,  \
    284			     SSD20XD_GPIO_OFF_GPIO3,  \
    285			     SSD20XD_GPIO_OFF_GPIO4,  \
    286			     SSD20XD_GPIO_OFF_GPIO5,  \
    287			     SSD20XD_GPIO_OFF_GPIO6,  \
    288			     SSD20XD_GPIO_OFF_GPIO7,  \
    289			     SSD20XD_GPIO_OFF_GPIO10, \
    290			     SSD20XD_GPIO_OFF_GPIO11, \
    291			     SSD20XD_GPIO_OFF_GPIO12, \
    292			     SSD20XD_GPIO_OFF_GPIO13, \
    293			     SSD20XD_GPIO_OFF_GPIO14, \
    294			     SSD20XD_GPIO_OFF_GPIO85, \
    295			     SSD20XD_GPIO_OFF_GPIO86, \
    296			     SSD20XD_GPIO_OFF_GPIO90
    297
    298/* "ttl" pins lcd interface pins */
    299#define SSD20XD_PINNAME_TTL0	"ttl0"
    300#define SSD20XD_PINNAME_TTL1	"ttl1"
    301#define SSD20XD_PINNAME_TTL2	"ttl2"
    302#define SSD20XD_PINNAME_TTL3	"ttl3"
    303#define SSD20XD_PINNAME_TTL4	"ttl4"
    304#define SSD20XD_PINNAME_TTL5	"ttl5"
    305#define SSD20XD_PINNAME_TTL6	"ttl6"
    306#define SSD20XD_PINNAME_TTL7	"ttl7"
    307#define SSD20XD_PINNAME_TTL8	"ttl8"
    308#define SSD20XD_PINNAME_TTL9	"ttl9"
    309#define SSD20XD_PINNAME_TTL10	"ttl10"
    310#define SSD20XD_PINNAME_TTL11	"ttl11"
    311#define SSD20XD_PINNAME_TTL12	"ttl12"
    312#define SSD20XD_PINNAME_TTL13	"ttl13"
    313#define SSD20XD_PINNAME_TTL14	"ttl14"
    314#define SSD20XD_PINNAME_TTL15	"ttl15"
    315#define SSD20XD_PINNAME_TTL16	"ttl16"
    316#define SSD20XD_PINNAME_TTL17	"ttl17"
    317#define SSD20XD_PINNAME_TTL18	"ttl18"
    318#define SSD20XD_PINNAME_TTL19	"ttl19"
    319#define SSD20XD_PINNAME_TTL20	"ttl20"
    320#define SSD20XD_PINNAME_TTL21	"ttl21"
    321#define SSD20XD_PINNAME_TTL22	"ttl22"
    322#define SSD20XD_PINNAME_TTL23	"ttl23"
    323#define SSD20XD_PINNAME_TTL24	"ttl24"
    324#define SSD20XD_PINNAME_TTL25	"ttl25"
    325#define SSD20XD_PINNAME_TTL26	"ttl26"
    326#define SSD20XD_PINNAME_TTL27	"ttl27"
    327
    328#define SSD20XD_TTL_PINNAMES SSD20XD_PINNAME_TTL0,  \
    329			     SSD20XD_PINNAME_TTL1,  \
    330			     SSD20XD_PINNAME_TTL2,  \
    331			     SSD20XD_PINNAME_TTL3,  \
    332			     SSD20XD_PINNAME_TTL4,  \
    333			     SSD20XD_PINNAME_TTL5,  \
    334			     SSD20XD_PINNAME_TTL6,  \
    335			     SSD20XD_PINNAME_TTL7,  \
    336			     SSD20XD_PINNAME_TTL8,  \
    337			     SSD20XD_PINNAME_TTL9,  \
    338			     SSD20XD_PINNAME_TTL10, \
    339			     SSD20XD_PINNAME_TTL11, \
    340			     SSD20XD_PINNAME_TTL12, \
    341			     SSD20XD_PINNAME_TTL13, \
    342			     SSD20XD_PINNAME_TTL14, \
    343			     SSD20XD_PINNAME_TTL15, \
    344			     SSD20XD_PINNAME_TTL16, \
    345			     SSD20XD_PINNAME_TTL17, \
    346			     SSD20XD_PINNAME_TTL18, \
    347			     SSD20XD_PINNAME_TTL19, \
    348			     SSD20XD_PINNAME_TTL20, \
    349			     SSD20XD_PINNAME_TTL21, \
    350			     SSD20XD_PINNAME_TTL22, \
    351			     SSD20XD_PINNAME_TTL23, \
    352			     SSD20XD_PINNAME_TTL24, \
    353			     SSD20XD_PINNAME_TTL25, \
    354			     SSD20XD_PINNAME_TTL26, \
    355			     SSD20XD_PINNAME_TTL27
    356
    357#define SSD20XD_TTL_OFFSET_TTL0		0x80
    358#define SSD20XD_TTL_OFFSET_TTL1		0x84
    359#define SSD20XD_TTL_OFFSET_TTL2		0x88
    360#define SSD20XD_TTL_OFFSET_TTL3		0x8c
    361#define SSD20XD_TTL_OFFSET_TTL4		0x90
    362#define SSD20XD_TTL_OFFSET_TTL5		0x94
    363#define SSD20XD_TTL_OFFSET_TTL6		0x98
    364#define SSD20XD_TTL_OFFSET_TTL7		0x9c
    365#define SSD20XD_TTL_OFFSET_TTL8		0xa0
    366#define SSD20XD_TTL_OFFSET_TTL9		0xa4
    367#define SSD20XD_TTL_OFFSET_TTL10	0xa8
    368#define SSD20XD_TTL_OFFSET_TTL11	0xac
    369#define SSD20XD_TTL_OFFSET_TTL12	0xb0
    370#define SSD20XD_TTL_OFFSET_TTL13	0xb4
    371#define SSD20XD_TTL_OFFSET_TTL14	0xb8
    372#define SSD20XD_TTL_OFFSET_TTL15	0xbc
    373#define SSD20XD_TTL_OFFSET_TTL16	0xc0
    374#define SSD20XD_TTL_OFFSET_TTL17	0xc4
    375#define SSD20XD_TTL_OFFSET_TTL18	0xc8
    376#define SSD20XD_TTL_OFFSET_TTL19	0xcc
    377#define SSD20XD_TTL_OFFSET_TTL20	0xd0
    378#define SSD20XD_TTL_OFFSET_TTL21	0xd4
    379#define SSD20XD_TTL_OFFSET_TTL22	0xd8
    380#define SSD20XD_TTL_OFFSET_TTL23	0xdc
    381#define SSD20XD_TTL_OFFSET_TTL24	0xe0
    382#define SSD20XD_TTL_OFFSET_TTL25	0xe4
    383#define SSD20XD_TTL_OFFSET_TTL26	0xe8
    384#define SSD20XD_TTL_OFFSET_TTL27	0xec
    385
    386#define SSD20XD_TTL_OFFSETS SSD20XD_TTL_OFFSET_TTL0,  \
    387			    SSD20XD_TTL_OFFSET_TTL1,  \
    388			    SSD20XD_TTL_OFFSET_TTL2,  \
    389			    SSD20XD_TTL_OFFSET_TTL3,  \
    390			    SSD20XD_TTL_OFFSET_TTL4,  \
    391			    SSD20XD_TTL_OFFSET_TTL5,  \
    392			    SSD20XD_TTL_OFFSET_TTL6,  \
    393			    SSD20XD_TTL_OFFSET_TTL7,  \
    394			    SSD20XD_TTL_OFFSET_TTL8,  \
    395			    SSD20XD_TTL_OFFSET_TTL9,  \
    396			    SSD20XD_TTL_OFFSET_TTL10, \
    397			    SSD20XD_TTL_OFFSET_TTL11, \
    398			    SSD20XD_TTL_OFFSET_TTL12, \
    399			    SSD20XD_TTL_OFFSET_TTL13, \
    400			    SSD20XD_TTL_OFFSET_TTL14, \
    401			    SSD20XD_TTL_OFFSET_TTL15, \
    402			    SSD20XD_TTL_OFFSET_TTL16, \
    403			    SSD20XD_TTL_OFFSET_TTL17, \
    404			    SSD20XD_TTL_OFFSET_TTL18, \
    405			    SSD20XD_TTL_OFFSET_TTL19, \
    406			    SSD20XD_TTL_OFFSET_TTL20, \
    407			    SSD20XD_TTL_OFFSET_TTL21, \
    408			    SSD20XD_TTL_OFFSET_TTL22, \
    409			    SSD20XD_TTL_OFFSET_TTL23, \
    410			    SSD20XD_TTL_OFFSET_TTL24, \
    411			    SSD20XD_TTL_OFFSET_TTL25, \
    412			    SSD20XD_TTL_OFFSET_TTL26, \
    413			    SSD20XD_TTL_OFFSET_TTL27
    414
    415/* On the ssd20xd the two normal uarts have dedicated pins */
    416#define SSD20XD_PINNAME_UART0_RX	"uart0_rx"
    417#define SSD20XD_PINNAME_UART0_TX	"uart0_tx"
    418
    419#define SSD20XD_UART0_NAMES	  \
    420	SSD20XD_PINNAME_UART0_RX, \
    421	SSD20XD_PINNAME_UART0_TX
    422
    423#define SSD20XD_PINNAME_UART1_RX	"uart1_rx"
    424#define SSD20XD_PINNAME_UART1_TX	"uart1_tx"
    425
    426#define SSD20XD_UART1_NAMES	  \
    427	SSD20XD_PINNAME_UART1_RX, \
    428	SSD20XD_PINNAME_UART1_TX
    429
    430#define SSD20XD_OFF_UART0_RX	0x60
    431#define SSD20XD_OFF_UART0_TX	0x64
    432
    433#define SSD20XD_UART0_OFFSETS \
    434	SSD20XD_OFF_UART0_RX, \
    435	SSD20XD_OFF_UART0_TX
    436
    437#define SSD20XD_OFF_UART1_RX	0x68
    438#define SSD20XD_OFF_UART1_TX	0x6c
    439
    440#define SSD20XD_UART1_OFFSETS \
    441	SSD20XD_OFF_UART1_RX, \
    442	SSD20XD_OFF_UART1_TX
    443
    444/*
    445 * ssd20x has the same pin names but different ordering
    446 * of the registers that control the gpio.
    447 */
    448#define SSD20XD_OFF_SD_D0	0x140
    449#define SSD20XD_OFF_SD_D1	0x144
    450#define SSD20XD_OFF_SD_D2	0x148
    451#define SSD20XD_OFF_SD_D3	0x14c
    452#define SSD20XD_OFF_SD_CMD	0x150
    453#define SSD20XD_OFF_SD_CLK	0x154
    454
    455#define SSD20XD_SD_OFFSETS	SSD20XD_OFF_SD_CLK, \
    456				SSD20XD_OFF_SD_CMD, \
    457				SSD20XD_OFF_SD_D0,  \
    458				SSD20XD_OFF_SD_D1,  \
    459				SSD20XD_OFF_SD_D2,  \
    460				SSD20XD_OFF_SD_D3
    461
    462static const char * const ssd20xd_names[] = {
    463	FUART_NAMES,
    464	SD_NAMES,
    465	SSD20XD_UART0_NAMES,
    466	SSD20XD_UART1_NAMES,
    467	SSD20XD_TTL_PINNAMES,
    468	SSD20XD_GPIO_NAMES,
    469};
    470
    471static const unsigned int ssd20xd_offsets[] = {
    472	FUART_OFFSETS,
    473	SSD20XD_SD_OFFSETS,
    474	SSD20XD_UART0_OFFSETS,
    475	SSD20XD_UART1_OFFSETS,
    476	SSD20XD_TTL_OFFSETS,
    477	SSD20XD_GPIO_OFFSETS,
    478};
    479
    480MSC313_GPIO_CHIPDATA(ssd20xd);
    481#endif
    482
    483struct msc313_gpio {
    484	void __iomem *base;
    485	const struct msc313_gpio_data *gpio_data;
    486	u8 *saved;
    487};
    488
    489static void msc313_gpio_set(struct gpio_chip *chip, unsigned int offset, int value)
    490{
    491	struct msc313_gpio *gpio = gpiochip_get_data(chip);
    492	u8 gpioreg = readb_relaxed(gpio->base + gpio->gpio_data->offsets[offset]);
    493
    494	if (value)
    495		gpioreg |= MSC313_GPIO_OUT;
    496	else
    497		gpioreg &= ~MSC313_GPIO_OUT;
    498
    499	writeb_relaxed(gpioreg, gpio->base + gpio->gpio_data->offsets[offset]);
    500}
    501
    502static int msc313_gpio_get(struct gpio_chip *chip, unsigned int offset)
    503{
    504	struct msc313_gpio *gpio = gpiochip_get_data(chip);
    505
    506	return readb_relaxed(gpio->base + gpio->gpio_data->offsets[offset]) & MSC313_GPIO_IN;
    507}
    508
    509static int msc313_gpio_direction_input(struct gpio_chip *chip, unsigned int offset)
    510{
    511	struct msc313_gpio *gpio = gpiochip_get_data(chip);
    512	u8 gpioreg = readb_relaxed(gpio->base + gpio->gpio_data->offsets[offset]);
    513
    514	gpioreg |= MSC313_GPIO_OEN;
    515	writeb_relaxed(gpioreg, gpio->base + gpio->gpio_data->offsets[offset]);
    516
    517	return 0;
    518}
    519
    520static int msc313_gpio_direction_output(struct gpio_chip *chip, unsigned int offset, int value)
    521{
    522	struct msc313_gpio *gpio = gpiochip_get_data(chip);
    523	u8 gpioreg = readb_relaxed(gpio->base + gpio->gpio_data->offsets[offset]);
    524
    525	gpioreg &= ~MSC313_GPIO_OEN;
    526	if (value)
    527		gpioreg |= MSC313_GPIO_OUT;
    528	else
    529		gpioreg &= ~MSC313_GPIO_OUT;
    530	writeb_relaxed(gpioreg, gpio->base + gpio->gpio_data->offsets[offset]);
    531
    532	return 0;
    533}
    534
    535/*
    536 * The interrupt handling happens in the parent interrupt controller,
    537 * we don't do anything here.
    538 */
    539static struct irq_chip msc313_gpio_irqchip = {
    540	.name = "GPIO",
    541	.irq_eoi = irq_chip_eoi_parent,
    542	.irq_mask = irq_chip_mask_parent,
    543	.irq_unmask = irq_chip_unmask_parent,
    544	.irq_set_type = irq_chip_set_type_parent,
    545	.irq_set_affinity = irq_chip_set_affinity_parent,
    546};
    547
    548/*
    549 * The parent interrupt controller needs the GIC interrupt type set to GIC_SPI
    550 * so we need to provide the fwspec. Essentially gpiochip_populate_parent_fwspec_twocell
    551 * that puts GIC_SPI into the first cell.
    552 */
    553static void *msc313_gpio_populate_parent_fwspec(struct gpio_chip *gc,
    554					     unsigned int parent_hwirq,
    555					     unsigned int parent_type)
    556{
    557	struct irq_fwspec *fwspec;
    558
    559	fwspec = kmalloc(sizeof(*fwspec), GFP_KERNEL);
    560	if (!fwspec)
    561		return NULL;
    562
    563	fwspec->fwnode = gc->irq.parent_domain->fwnode;
    564	fwspec->param_count = 3;
    565	fwspec->param[0] = GIC_SPI;
    566	fwspec->param[1] = parent_hwirq;
    567	fwspec->param[2] = parent_type;
    568
    569	return fwspec;
    570}
    571
    572static int msc313e_gpio_child_to_parent_hwirq(struct gpio_chip *chip,
    573					     unsigned int child,
    574					     unsigned int child_type,
    575					     unsigned int *parent,
    576					     unsigned int *parent_type)
    577{
    578	struct msc313_gpio *priv = gpiochip_get_data(chip);
    579	unsigned int offset = priv->gpio_data->offsets[child];
    580
    581	/*
    582	 * only the spi0 pins have interrupts on the parent
    583	 * on all of the known chips and so far they are all
    584	 * mapped to the same place
    585	 */
    586	if (offset >= OFF_SPI0_CZ && offset <= OFF_SPI0_DO) {
    587		*parent_type = child_type;
    588		*parent = ((offset - OFF_SPI0_CZ) >> 2) + 28;
    589		return 0;
    590	}
    591
    592	return -EINVAL;
    593}
    594
    595static int msc313_gpio_probe(struct platform_device *pdev)
    596{
    597	const struct msc313_gpio_data *match_data;
    598	struct msc313_gpio *gpio;
    599	struct gpio_chip *gpiochip;
    600	struct gpio_irq_chip *gpioirqchip;
    601	struct irq_domain *parent_domain;
    602	struct device_node *parent_node;
    603	struct device *dev = &pdev->dev;
    604
    605	match_data = of_device_get_match_data(dev);
    606	if (!match_data)
    607		return -EINVAL;
    608
    609	parent_node = of_irq_find_parent(dev->of_node);
    610	if (!parent_node)
    611		return -ENODEV;
    612
    613	parent_domain = irq_find_host(parent_node);
    614	if (!parent_domain)
    615		return -ENODEV;
    616
    617	gpio = devm_kzalloc(dev, sizeof(*gpio), GFP_KERNEL);
    618	if (!gpio)
    619		return -ENOMEM;
    620
    621	gpio->gpio_data = match_data;
    622
    623	gpio->saved = devm_kcalloc(dev, gpio->gpio_data->num, sizeof(*gpio->saved), GFP_KERNEL);
    624	if (!gpio->saved)
    625		return -ENOMEM;
    626
    627	gpio->base = devm_platform_ioremap_resource(pdev, 0);
    628	if (IS_ERR(gpio->base))
    629		return PTR_ERR(gpio->base);
    630
    631	platform_set_drvdata(pdev, gpio);
    632
    633	gpiochip = devm_kzalloc(dev, sizeof(*gpiochip), GFP_KERNEL);
    634	if (!gpiochip)
    635		return -ENOMEM;
    636
    637	gpiochip->label = DRIVER_NAME;
    638	gpiochip->parent = dev;
    639	gpiochip->request = gpiochip_generic_request;
    640	gpiochip->free = gpiochip_generic_free;
    641	gpiochip->direction_input = msc313_gpio_direction_input;
    642	gpiochip->direction_output = msc313_gpio_direction_output;
    643	gpiochip->get = msc313_gpio_get;
    644	gpiochip->set = msc313_gpio_set;
    645	gpiochip->base = -1;
    646	gpiochip->ngpio = gpio->gpio_data->num;
    647	gpiochip->names = gpio->gpio_data->names;
    648
    649	gpioirqchip = &gpiochip->irq;
    650	gpioirqchip->chip = &msc313_gpio_irqchip;
    651	gpioirqchip->fwnode = of_node_to_fwnode(dev->of_node);
    652	gpioirqchip->parent_domain = parent_domain;
    653	gpioirqchip->child_to_parent_hwirq = msc313e_gpio_child_to_parent_hwirq;
    654	gpioirqchip->populate_parent_alloc_arg = msc313_gpio_populate_parent_fwspec;
    655	gpioirqchip->handler = handle_bad_irq;
    656	gpioirqchip->default_type = IRQ_TYPE_NONE;
    657
    658	return devm_gpiochip_add_data(dev, gpiochip, gpio);
    659}
    660
    661static int msc313_gpio_remove(struct platform_device *pdev)
    662{
    663	return 0;
    664}
    665
    666static const struct of_device_id msc313_gpio_of_match[] = {
    667#ifdef CONFIG_MACH_INFINITY
    668	{
    669		.compatible = "mstar,msc313-gpio",
    670		.data = &msc313_data,
    671	},
    672	{
    673		.compatible = "sstar,ssd20xd-gpio",
    674		.data = &ssd20xd_data,
    675	},
    676#endif
    677	{ }
    678};
    679
    680/*
    681 * The GPIO controller loses the state of the registers when the
    682 * SoC goes into suspend to memory mode so we need to save some
    683 * of the register bits before suspending and put it back when resuming
    684 */
    685static int __maybe_unused msc313_gpio_suspend(struct device *dev)
    686{
    687	struct msc313_gpio *gpio = dev_get_drvdata(dev);
    688	int i;
    689
    690	for (i = 0; i < gpio->gpio_data->num; i++)
    691		gpio->saved[i] = readb_relaxed(gpio->base + gpio->gpio_data->offsets[i]) & MSC313_GPIO_BITSTOSAVE;
    692
    693	return 0;
    694}
    695
    696static int __maybe_unused msc313_gpio_resume(struct device *dev)
    697{
    698	struct msc313_gpio *gpio = dev_get_drvdata(dev);
    699	int i;
    700
    701	for (i = 0; i < gpio->gpio_data->num; i++)
    702		writeb_relaxed(gpio->saved[i], gpio->base + gpio->gpio_data->offsets[i]);
    703
    704	return 0;
    705}
    706
    707static SIMPLE_DEV_PM_OPS(msc313_gpio_ops, msc313_gpio_suspend, msc313_gpio_resume);
    708
    709static struct platform_driver msc313_gpio_driver = {
    710	.driver = {
    711		.name = DRIVER_NAME,
    712		.of_match_table = msc313_gpio_of_match,
    713		.pm = &msc313_gpio_ops,
    714	},
    715	.probe = msc313_gpio_probe,
    716	.remove = msc313_gpio_remove,
    717};
    718builtin_platform_driver(msc313_gpio_driver);