1875a92b3SAndy Shevchenko // SPDX-License-Identifier: GPL-2.0 26e08d6bbSMika Westerberg /* 36e08d6bbSMika Westerberg * Cherryview/Braswell pinctrl driver 46e08d6bbSMika Westerberg * 5293428f9SAndy Shevchenko * Copyright (C) 2014, 2020 Intel Corporation 66e08d6bbSMika Westerberg * Author: Mika Westerberg <mika.westerberg@linux.intel.com> 76e08d6bbSMika Westerberg * 86e08d6bbSMika Westerberg * This driver is based on the original Cherryview GPIO driver by 96e08d6bbSMika Westerberg * Ning Li <ning.li@intel.com> 106e08d6bbSMika Westerberg * Alan Cox <alan@linux.intel.com> 116e08d6bbSMika Westerberg */ 126e08d6bbSMika Westerberg 13994f8865SAndy Shevchenko #include <linux/acpi.h> 1470365027SMika Westerberg #include <linux/dmi.h> 15994f8865SAndy Shevchenko #include <linux/gpio/driver.h> 166e08d6bbSMika Westerberg #include <linux/kernel.h> 176e08d6bbSMika Westerberg #include <linux/module.h> 18994f8865SAndy Shevchenko #include <linux/platform_device.h> 19*414fb9f2SAndy Shevchenko #include <linux/seq_file.h> 206e08d6bbSMika Westerberg #include <linux/types.h> 21994f8865SAndy Shevchenko 22*414fb9f2SAndy Shevchenko #include <linux/pinctrl/consumer.h> 23*414fb9f2SAndy Shevchenko #include <linux/pinctrl/pinconf-generic.h> 24*414fb9f2SAndy Shevchenko #include <linux/pinctrl/pinconf.h> 256e08d6bbSMika Westerberg #include <linux/pinctrl/pinctrl.h> 266e08d6bbSMika Westerberg #include <linux/pinctrl/pinmux.h> 276e08d6bbSMika Westerberg 285458b7ceSAndy Shevchenko #include "pinctrl-intel.h" 295458b7ceSAndy Shevchenko 306e08d6bbSMika Westerberg #define CHV_INTSTAT 0x300 316e08d6bbSMika Westerberg #define CHV_INTMASK 0x380 326e08d6bbSMika Westerberg 336e08d6bbSMika Westerberg #define FAMILY_PAD_REGS_OFF 0x4400 346e08d6bbSMika Westerberg #define FAMILY_PAD_REGS_SIZE 0x400 356e08d6bbSMika Westerberg #define MAX_FAMILY_PAD_GPIO_NO 15 366e08d6bbSMika Westerberg #define GPIO_REGS_SIZE 8 376e08d6bbSMika Westerberg 386e08d6bbSMika Westerberg #define CHV_PADCTRL0 0x000 396e08d6bbSMika Westerberg #define CHV_PADCTRL0_INTSEL_SHIFT 28 405707dd73SAndy Shevchenko #define CHV_PADCTRL0_INTSEL_MASK GENMASK(31, 28) 416e08d6bbSMika Westerberg #define CHV_PADCTRL0_TERM_UP BIT(23) 426e08d6bbSMika Westerberg #define CHV_PADCTRL0_TERM_SHIFT 20 435707dd73SAndy Shevchenko #define CHV_PADCTRL0_TERM_MASK GENMASK(22, 20) 446e08d6bbSMika Westerberg #define CHV_PADCTRL0_TERM_20K 1 456e08d6bbSMika Westerberg #define CHV_PADCTRL0_TERM_5K 2 466e08d6bbSMika Westerberg #define CHV_PADCTRL0_TERM_1K 4 476e08d6bbSMika Westerberg #define CHV_PADCTRL0_PMODE_SHIFT 16 485707dd73SAndy Shevchenko #define CHV_PADCTRL0_PMODE_MASK GENMASK(19, 16) 496e08d6bbSMika Westerberg #define CHV_PADCTRL0_GPIOEN BIT(15) 506e08d6bbSMika Westerberg #define CHV_PADCTRL0_GPIOCFG_SHIFT 8 515707dd73SAndy Shevchenko #define CHV_PADCTRL0_GPIOCFG_MASK GENMASK(10, 8) 526e08d6bbSMika Westerberg #define CHV_PADCTRL0_GPIOCFG_GPIO 0 536e08d6bbSMika Westerberg #define CHV_PADCTRL0_GPIOCFG_GPO 1 546e08d6bbSMika Westerberg #define CHV_PADCTRL0_GPIOCFG_GPI 2 556e08d6bbSMika Westerberg #define CHV_PADCTRL0_GPIOCFG_HIZ 3 566e08d6bbSMika Westerberg #define CHV_PADCTRL0_GPIOTXSTATE BIT(1) 576e08d6bbSMika Westerberg #define CHV_PADCTRL0_GPIORXSTATE BIT(0) 586e08d6bbSMika Westerberg 596e08d6bbSMika Westerberg #define CHV_PADCTRL1 0x004 606e08d6bbSMika Westerberg #define CHV_PADCTRL1_CFGLOCK BIT(31) 616e08d6bbSMika Westerberg #define CHV_PADCTRL1_INVRXTX_SHIFT 4 625707dd73SAndy Shevchenko #define CHV_PADCTRL1_INVRXTX_MASK GENMASK(7, 4) 63a0bf06dcSHans de Goede #define CHV_PADCTRL1_INVRXTX_TXDATA BIT(7) 645707dd73SAndy Shevchenko #define CHV_PADCTRL1_INVRXTX_RXDATA BIT(6) 655707dd73SAndy Shevchenko #define CHV_PADCTRL1_INVRXTX_TXENABLE BIT(5) 666e08d6bbSMika Westerberg #define CHV_PADCTRL1_ODEN BIT(3) 675707dd73SAndy Shevchenko #define CHV_PADCTRL1_INTWAKECFG_MASK GENMASK(2, 0) 686e08d6bbSMika Westerberg #define CHV_PADCTRL1_INTWAKECFG_FALLING 1 696e08d6bbSMika Westerberg #define CHV_PADCTRL1_INTWAKECFG_RISING 2 706e08d6bbSMika Westerberg #define CHV_PADCTRL1_INTWAKECFG_BOTH 3 716e08d6bbSMika Westerberg #define CHV_PADCTRL1_INTWAKECFG_LEVEL 4 726e08d6bbSMika Westerberg 73293428f9SAndy Shevchenko struct intel_pad_context { 749eb457b5SMika Westerberg u32 padctrl0; 759eb457b5SMika Westerberg u32 padctrl1; 769eb457b5SMika Westerberg }; 779eb457b5SMika Westerberg 78bdfbef2dSHans de Goede #define CHV_INVALID_HWIRQ ((unsigned int)INVALID_HWIRQ) 79bdfbef2dSHans de Goede 806e08d6bbSMika Westerberg /** 818a828570SAndy Shevchenko * struct intel_community_context - community context for Cherryview 828a828570SAndy Shevchenko * @intr_lines: Mapping between 16 HW interrupt wires and GPIO offset (in GPIO number space) 838a828570SAndy Shevchenko * @saved_intmask: Interrupt mask saved for system sleep 848a828570SAndy Shevchenko */ 858a828570SAndy Shevchenko struct intel_community_context { 868a828570SAndy Shevchenko unsigned int intr_lines[16]; 878a828570SAndy Shevchenko u32 saved_intmask; 888a828570SAndy Shevchenko }; 898a828570SAndy Shevchenko 9036ad7b24SAndy Shevchenko #define PINMODE_INVERT_OE BIT(15) 916e08d6bbSMika Westerberg 9236ad7b24SAndy Shevchenko #define PINMODE(m, i) ((m) | ((i) * PINMODE_INVERT_OE)) 936e08d6bbSMika Westerberg 9436ad7b24SAndy Shevchenko #define CHV_GPP(start, end) \ 956e08d6bbSMika Westerberg { \ 966e08d6bbSMika Westerberg .base = (start), \ 9736ad7b24SAndy Shevchenko .size = (end) - (start) + 1, \ 986e08d6bbSMika Westerberg } 996e08d6bbSMika Westerberg 100293428f9SAndy Shevchenko #define CHV_COMMUNITY(g, i, a) \ 101293428f9SAndy Shevchenko { \ 102293428f9SAndy Shevchenko .gpps = (g), \ 103293428f9SAndy Shevchenko .ngpps = ARRAY_SIZE(g), \ 104293428f9SAndy Shevchenko .nirqs = (i), \ 105293428f9SAndy Shevchenko .acpi_space_id = (a), \ 106293428f9SAndy Shevchenko } 107293428f9SAndy Shevchenko 1086e08d6bbSMika Westerberg static const struct pinctrl_pin_desc southwest_pins[] = { 1096e08d6bbSMika Westerberg PINCTRL_PIN(0, "FST_SPI_D2"), 1106e08d6bbSMika Westerberg PINCTRL_PIN(1, "FST_SPI_D0"), 1116e08d6bbSMika Westerberg PINCTRL_PIN(2, "FST_SPI_CLK"), 1126e08d6bbSMika Westerberg PINCTRL_PIN(3, "FST_SPI_D3"), 1136e08d6bbSMika Westerberg PINCTRL_PIN(4, "FST_SPI_CS1_B"), 1146e08d6bbSMika Westerberg PINCTRL_PIN(5, "FST_SPI_D1"), 1156e08d6bbSMika Westerberg PINCTRL_PIN(6, "FST_SPI_CS0_B"), 1166e08d6bbSMika Westerberg PINCTRL_PIN(7, "FST_SPI_CS2_B"), 1176e08d6bbSMika Westerberg 1186e08d6bbSMika Westerberg PINCTRL_PIN(15, "UART1_RTS_B"), 1196e08d6bbSMika Westerberg PINCTRL_PIN(16, "UART1_RXD"), 1206e08d6bbSMika Westerberg PINCTRL_PIN(17, "UART2_RXD"), 1216e08d6bbSMika Westerberg PINCTRL_PIN(18, "UART1_CTS_B"), 1226e08d6bbSMika Westerberg PINCTRL_PIN(19, "UART2_RTS_B"), 1236e08d6bbSMika Westerberg PINCTRL_PIN(20, "UART1_TXD"), 1246e08d6bbSMika Westerberg PINCTRL_PIN(21, "UART2_TXD"), 1256e08d6bbSMika Westerberg PINCTRL_PIN(22, "UART2_CTS_B"), 1266e08d6bbSMika Westerberg 1276e08d6bbSMika Westerberg PINCTRL_PIN(30, "MF_HDA_CLK"), 1286e08d6bbSMika Westerberg PINCTRL_PIN(31, "MF_HDA_RSTB"), 1296e08d6bbSMika Westerberg PINCTRL_PIN(32, "MF_HDA_SDIO"), 1306e08d6bbSMika Westerberg PINCTRL_PIN(33, "MF_HDA_SDO"), 1316e08d6bbSMika Westerberg PINCTRL_PIN(34, "MF_HDA_DOCKRSTB"), 1326e08d6bbSMika Westerberg PINCTRL_PIN(35, "MF_HDA_SYNC"), 1336e08d6bbSMika Westerberg PINCTRL_PIN(36, "MF_HDA_SDI1"), 1346e08d6bbSMika Westerberg PINCTRL_PIN(37, "MF_HDA_DOCKENB"), 1356e08d6bbSMika Westerberg 1366e08d6bbSMika Westerberg PINCTRL_PIN(45, "I2C5_SDA"), 1376e08d6bbSMika Westerberg PINCTRL_PIN(46, "I2C4_SDA"), 1386e08d6bbSMika Westerberg PINCTRL_PIN(47, "I2C6_SDA"), 1396e08d6bbSMika Westerberg PINCTRL_PIN(48, "I2C5_SCL"), 1406e08d6bbSMika Westerberg PINCTRL_PIN(49, "I2C_NFC_SDA"), 1416e08d6bbSMika Westerberg PINCTRL_PIN(50, "I2C4_SCL"), 1426e08d6bbSMika Westerberg PINCTRL_PIN(51, "I2C6_SCL"), 1436e08d6bbSMika Westerberg PINCTRL_PIN(52, "I2C_NFC_SCL"), 1446e08d6bbSMika Westerberg 1456e08d6bbSMika Westerberg PINCTRL_PIN(60, "I2C1_SDA"), 1466e08d6bbSMika Westerberg PINCTRL_PIN(61, "I2C0_SDA"), 1476e08d6bbSMika Westerberg PINCTRL_PIN(62, "I2C2_SDA"), 1486e08d6bbSMika Westerberg PINCTRL_PIN(63, "I2C1_SCL"), 1496e08d6bbSMika Westerberg PINCTRL_PIN(64, "I2C3_SDA"), 1506e08d6bbSMika Westerberg PINCTRL_PIN(65, "I2C0_SCL"), 1516e08d6bbSMika Westerberg PINCTRL_PIN(66, "I2C2_SCL"), 1526e08d6bbSMika Westerberg PINCTRL_PIN(67, "I2C3_SCL"), 1536e08d6bbSMika Westerberg 1546e08d6bbSMika Westerberg PINCTRL_PIN(75, "SATA_GP0"), 1556e08d6bbSMika Westerberg PINCTRL_PIN(76, "SATA_GP1"), 1566e08d6bbSMika Westerberg PINCTRL_PIN(77, "SATA_LEDN"), 1576e08d6bbSMika Westerberg PINCTRL_PIN(78, "SATA_GP2"), 1586e08d6bbSMika Westerberg PINCTRL_PIN(79, "MF_SMB_ALERTB"), 1596e08d6bbSMika Westerberg PINCTRL_PIN(80, "SATA_GP3"), 1606e08d6bbSMika Westerberg PINCTRL_PIN(81, "MF_SMB_CLK"), 1616e08d6bbSMika Westerberg PINCTRL_PIN(82, "MF_SMB_DATA"), 1626e08d6bbSMika Westerberg 1636e08d6bbSMika Westerberg PINCTRL_PIN(90, "PCIE_CLKREQ0B"), 1646e08d6bbSMika Westerberg PINCTRL_PIN(91, "PCIE_CLKREQ1B"), 1656e08d6bbSMika Westerberg PINCTRL_PIN(92, "GP_SSP_2_CLK"), 1666e08d6bbSMika Westerberg PINCTRL_PIN(93, "PCIE_CLKREQ2B"), 1676e08d6bbSMika Westerberg PINCTRL_PIN(94, "GP_SSP_2_RXD"), 1686e08d6bbSMika Westerberg PINCTRL_PIN(95, "PCIE_CLKREQ3B"), 1696e08d6bbSMika Westerberg PINCTRL_PIN(96, "GP_SSP_2_FS"), 1706e08d6bbSMika Westerberg PINCTRL_PIN(97, "GP_SSP_2_TXD"), 1716e08d6bbSMika Westerberg }; 1726e08d6bbSMika Westerberg 1736e08d6bbSMika Westerberg static const unsigned southwest_uart0_pins[] = { 16, 20 }; 1746e08d6bbSMika Westerberg static const unsigned southwest_uart1_pins[] = { 15, 16, 18, 20 }; 1756e08d6bbSMika Westerberg static const unsigned southwest_uart2_pins[] = { 17, 19, 21, 22 }; 1766e08d6bbSMika Westerberg static const unsigned southwest_i2c0_pins[] = { 61, 65 }; 1776e08d6bbSMika Westerberg static const unsigned southwest_hda_pins[] = { 30, 31, 32, 33, 34, 35, 36, 37 }; 1786e08d6bbSMika Westerberg static const unsigned southwest_lpe_pins[] = { 1796e08d6bbSMika Westerberg 30, 31, 32, 33, 34, 35, 36, 37, 92, 94, 96, 97, 1806e08d6bbSMika Westerberg }; 1816e08d6bbSMika Westerberg static const unsigned southwest_i2c1_pins[] = { 60, 63 }; 1826e08d6bbSMika Westerberg static const unsigned southwest_i2c2_pins[] = { 62, 66 }; 1836e08d6bbSMika Westerberg static const unsigned southwest_i2c3_pins[] = { 64, 67 }; 1846e08d6bbSMika Westerberg static const unsigned southwest_i2c4_pins[] = { 46, 50 }; 1856e08d6bbSMika Westerberg static const unsigned southwest_i2c5_pins[] = { 45, 48 }; 1866e08d6bbSMika Westerberg static const unsigned southwest_i2c6_pins[] = { 47, 51 }; 1876e08d6bbSMika Westerberg static const unsigned southwest_i2c_nfc_pins[] = { 49, 52 }; 1886e08d6bbSMika Westerberg static const unsigned southwest_spi3_pins[] = { 76, 79, 80, 81, 82 }; 1896e08d6bbSMika Westerberg 19036ad7b24SAndy Shevchenko /* Some of LPE I2S TXD pins need to have OE inversion set */ 19136ad7b24SAndy Shevchenko static const unsigned int southwest_lpe_altfuncs[] = { 19236ad7b24SAndy Shevchenko PINMODE(1, 1), PINMODE(1, 0), PINMODE(1, 0), PINMODE(1, 0), /* 30, 31, 32, 33 */ 19336ad7b24SAndy Shevchenko PINMODE(1, 1), PINMODE(1, 0), PINMODE(1, 0), PINMODE(1, 0), /* 34, 35, 36, 37 */ 19436ad7b24SAndy Shevchenko PINMODE(1, 0), PINMODE(1, 0), PINMODE(1, 0), PINMODE(1, 1), /* 92, 94, 96, 97 */ 1956e08d6bbSMika Westerberg }; 1966e08d6bbSMika Westerberg 1976e08d6bbSMika Westerberg /* 1986e08d6bbSMika Westerberg * Two spi3 chipselects are available in different mode than the main spi3 19936ad7b24SAndy Shevchenko * functionality, which is using mode 2. 2006e08d6bbSMika Westerberg */ 20136ad7b24SAndy Shevchenko static const unsigned int southwest_spi3_altfuncs[] = { 20236ad7b24SAndy Shevchenko PINMODE(3, 0), PINMODE(2, 0), PINMODE(3, 0), PINMODE(2, 0), /* 76, 79, 80, 81 */ 20336ad7b24SAndy Shevchenko PINMODE(2, 0), /* 82 */ 2046e08d6bbSMika Westerberg }; 2056e08d6bbSMika Westerberg 20636ad7b24SAndy Shevchenko static const struct intel_pingroup southwest_groups[] = { 20736ad7b24SAndy Shevchenko PIN_GROUP("uart0_grp", southwest_uart0_pins, PINMODE(2, 0)), 20836ad7b24SAndy Shevchenko PIN_GROUP("uart1_grp", southwest_uart1_pins, PINMODE(1, 0)), 20936ad7b24SAndy Shevchenko PIN_GROUP("uart2_grp", southwest_uart2_pins, PINMODE(1, 0)), 21036ad7b24SAndy Shevchenko PIN_GROUP("hda_grp", southwest_hda_pins, PINMODE(2, 0)), 21136ad7b24SAndy Shevchenko PIN_GROUP("i2c0_grp", southwest_i2c0_pins, PINMODE(1, 1)), 21236ad7b24SAndy Shevchenko PIN_GROUP("i2c1_grp", southwest_i2c1_pins, PINMODE(1, 1)), 21336ad7b24SAndy Shevchenko PIN_GROUP("i2c2_grp", southwest_i2c2_pins, PINMODE(1, 1)), 21436ad7b24SAndy Shevchenko PIN_GROUP("i2c3_grp", southwest_i2c3_pins, PINMODE(1, 1)), 21536ad7b24SAndy Shevchenko PIN_GROUP("i2c4_grp", southwest_i2c4_pins, PINMODE(1, 1)), 21636ad7b24SAndy Shevchenko PIN_GROUP("i2c5_grp", southwest_i2c5_pins, PINMODE(1, 1)), 21736ad7b24SAndy Shevchenko PIN_GROUP("i2c6_grp", southwest_i2c6_pins, PINMODE(1, 1)), 21836ad7b24SAndy Shevchenko PIN_GROUP("i2c_nfc_grp", southwest_i2c_nfc_pins, PINMODE(2, 1)), 21936ad7b24SAndy Shevchenko PIN_GROUP("lpe_grp", southwest_lpe_pins, southwest_lpe_altfuncs), 22036ad7b24SAndy Shevchenko PIN_GROUP("spi3_grp", southwest_spi3_pins, southwest_spi3_altfuncs), 2216e08d6bbSMika Westerberg }; 2226e08d6bbSMika Westerberg 2236e08d6bbSMika Westerberg static const char * const southwest_uart0_groups[] = { "uart0_grp" }; 2246e08d6bbSMika Westerberg static const char * const southwest_uart1_groups[] = { "uart1_grp" }; 2256e08d6bbSMika Westerberg static const char * const southwest_uart2_groups[] = { "uart2_grp" }; 2266e08d6bbSMika Westerberg static const char * const southwest_hda_groups[] = { "hda_grp" }; 2276e08d6bbSMika Westerberg static const char * const southwest_lpe_groups[] = { "lpe_grp" }; 2286e08d6bbSMika Westerberg static const char * const southwest_i2c0_groups[] = { "i2c0_grp" }; 2296e08d6bbSMika Westerberg static const char * const southwest_i2c1_groups[] = { "i2c1_grp" }; 2306e08d6bbSMika Westerberg static const char * const southwest_i2c2_groups[] = { "i2c2_grp" }; 2316e08d6bbSMika Westerberg static const char * const southwest_i2c3_groups[] = { "i2c3_grp" }; 2326e08d6bbSMika Westerberg static const char * const southwest_i2c4_groups[] = { "i2c4_grp" }; 2336e08d6bbSMika Westerberg static const char * const southwest_i2c5_groups[] = { "i2c5_grp" }; 2346e08d6bbSMika Westerberg static const char * const southwest_i2c6_groups[] = { "i2c6_grp" }; 2356e08d6bbSMika Westerberg static const char * const southwest_i2c_nfc_groups[] = { "i2c_nfc_grp" }; 2366e08d6bbSMika Westerberg static const char * const southwest_spi3_groups[] = { "spi3_grp" }; 2376e08d6bbSMika Westerberg 2386e08d6bbSMika Westerberg /* 2396e08d6bbSMika Westerberg * Only do pinmuxing for certain LPSS devices for now. Rest of the pins are 2406e08d6bbSMika Westerberg * enabled only as GPIOs. 2416e08d6bbSMika Westerberg */ 2425458b7ceSAndy Shevchenko static const struct intel_function southwest_functions[] = { 2436e08d6bbSMika Westerberg FUNCTION("uart0", southwest_uart0_groups), 2446e08d6bbSMika Westerberg FUNCTION("uart1", southwest_uart1_groups), 2456e08d6bbSMika Westerberg FUNCTION("uart2", southwest_uart2_groups), 2466e08d6bbSMika Westerberg FUNCTION("hda", southwest_hda_groups), 2476e08d6bbSMika Westerberg FUNCTION("lpe", southwest_lpe_groups), 2486e08d6bbSMika Westerberg FUNCTION("i2c0", southwest_i2c0_groups), 2496e08d6bbSMika Westerberg FUNCTION("i2c1", southwest_i2c1_groups), 2506e08d6bbSMika Westerberg FUNCTION("i2c2", southwest_i2c2_groups), 2516e08d6bbSMika Westerberg FUNCTION("i2c3", southwest_i2c3_groups), 2526e08d6bbSMika Westerberg FUNCTION("i2c4", southwest_i2c4_groups), 2536e08d6bbSMika Westerberg FUNCTION("i2c5", southwest_i2c5_groups), 2546e08d6bbSMika Westerberg FUNCTION("i2c6", southwest_i2c6_groups), 2556e08d6bbSMika Westerberg FUNCTION("i2c_nfc", southwest_i2c_nfc_groups), 2566e08d6bbSMika Westerberg FUNCTION("spi3", southwest_spi3_groups), 2576e08d6bbSMika Westerberg }; 2586e08d6bbSMika Westerberg 25936ad7b24SAndy Shevchenko static const struct intel_padgroup southwest_gpps[] = { 26036ad7b24SAndy Shevchenko CHV_GPP(0, 7), 26136ad7b24SAndy Shevchenko CHV_GPP(15, 22), 26236ad7b24SAndy Shevchenko CHV_GPP(30, 37), 26336ad7b24SAndy Shevchenko CHV_GPP(45, 52), 26436ad7b24SAndy Shevchenko CHV_GPP(60, 67), 26536ad7b24SAndy Shevchenko CHV_GPP(75, 82), 26636ad7b24SAndy Shevchenko CHV_GPP(90, 97), 2676e08d6bbSMika Westerberg }; 2686e08d6bbSMika Westerberg 269293428f9SAndy Shevchenko /* 270293428f9SAndy Shevchenko * Southwest community can generate GPIO interrupts only for the first 8 271293428f9SAndy Shevchenko * interrupts. The upper half (8-15) can only be used to trigger GPEs. 272293428f9SAndy Shevchenko */ 273293428f9SAndy Shevchenko static const struct intel_community southwest_communities[] = { 274293428f9SAndy Shevchenko CHV_COMMUNITY(southwest_gpps, 8, 0x91), 275293428f9SAndy Shevchenko }; 276293428f9SAndy Shevchenko 277293428f9SAndy Shevchenko static const struct intel_pinctrl_soc_data southwest_soc_data = { 2786e08d6bbSMika Westerberg .uid = "1", 2796e08d6bbSMika Westerberg .pins = southwest_pins, 2806e08d6bbSMika Westerberg .npins = ARRAY_SIZE(southwest_pins), 2816e08d6bbSMika Westerberg .groups = southwest_groups, 2826e08d6bbSMika Westerberg .ngroups = ARRAY_SIZE(southwest_groups), 2836e08d6bbSMika Westerberg .functions = southwest_functions, 2846e08d6bbSMika Westerberg .nfunctions = ARRAY_SIZE(southwest_functions), 285293428f9SAndy Shevchenko .communities = southwest_communities, 286293428f9SAndy Shevchenko .ncommunities = ARRAY_SIZE(southwest_communities), 2876e08d6bbSMika Westerberg }; 2886e08d6bbSMika Westerberg 2896e08d6bbSMika Westerberg static const struct pinctrl_pin_desc north_pins[] = { 2906e08d6bbSMika Westerberg PINCTRL_PIN(0, "GPIO_DFX_0"), 2916e08d6bbSMika Westerberg PINCTRL_PIN(1, "GPIO_DFX_3"), 2926e08d6bbSMika Westerberg PINCTRL_PIN(2, "GPIO_DFX_7"), 2936e08d6bbSMika Westerberg PINCTRL_PIN(3, "GPIO_DFX_1"), 2946e08d6bbSMika Westerberg PINCTRL_PIN(4, "GPIO_DFX_5"), 2956e08d6bbSMika Westerberg PINCTRL_PIN(5, "GPIO_DFX_4"), 2966e08d6bbSMika Westerberg PINCTRL_PIN(6, "GPIO_DFX_8"), 2976e08d6bbSMika Westerberg PINCTRL_PIN(7, "GPIO_DFX_2"), 2986e08d6bbSMika Westerberg PINCTRL_PIN(8, "GPIO_DFX_6"), 2996e08d6bbSMika Westerberg 3006e08d6bbSMika Westerberg PINCTRL_PIN(15, "GPIO_SUS0"), 3016e08d6bbSMika Westerberg PINCTRL_PIN(16, "SEC_GPIO_SUS10"), 3026e08d6bbSMika Westerberg PINCTRL_PIN(17, "GPIO_SUS3"), 3036e08d6bbSMika Westerberg PINCTRL_PIN(18, "GPIO_SUS7"), 3046e08d6bbSMika Westerberg PINCTRL_PIN(19, "GPIO_SUS1"), 3056e08d6bbSMika Westerberg PINCTRL_PIN(20, "GPIO_SUS5"), 3066e08d6bbSMika Westerberg PINCTRL_PIN(21, "SEC_GPIO_SUS11"), 3076e08d6bbSMika Westerberg PINCTRL_PIN(22, "GPIO_SUS4"), 3086e08d6bbSMika Westerberg PINCTRL_PIN(23, "SEC_GPIO_SUS8"), 3096e08d6bbSMika Westerberg PINCTRL_PIN(24, "GPIO_SUS2"), 3106e08d6bbSMika Westerberg PINCTRL_PIN(25, "GPIO_SUS6"), 3116e08d6bbSMika Westerberg PINCTRL_PIN(26, "CX_PREQ_B"), 3126e08d6bbSMika Westerberg PINCTRL_PIN(27, "SEC_GPIO_SUS9"), 3136e08d6bbSMika Westerberg 3146e08d6bbSMika Westerberg PINCTRL_PIN(30, "TRST_B"), 3156e08d6bbSMika Westerberg PINCTRL_PIN(31, "TCK"), 3166e08d6bbSMika Westerberg PINCTRL_PIN(32, "PROCHOT_B"), 3176e08d6bbSMika Westerberg PINCTRL_PIN(33, "SVIDO_DATA"), 3186e08d6bbSMika Westerberg PINCTRL_PIN(34, "TMS"), 3196e08d6bbSMika Westerberg PINCTRL_PIN(35, "CX_PRDY_B_2"), 3206e08d6bbSMika Westerberg PINCTRL_PIN(36, "TDO_2"), 3216e08d6bbSMika Westerberg PINCTRL_PIN(37, "CX_PRDY_B"), 3226e08d6bbSMika Westerberg PINCTRL_PIN(38, "SVIDO_ALERT_B"), 3236e08d6bbSMika Westerberg PINCTRL_PIN(39, "TDO"), 3246e08d6bbSMika Westerberg PINCTRL_PIN(40, "SVIDO_CLK"), 3256e08d6bbSMika Westerberg PINCTRL_PIN(41, "TDI"), 3266e08d6bbSMika Westerberg 3276e08d6bbSMika Westerberg PINCTRL_PIN(45, "GP_CAMERASB_05"), 3286e08d6bbSMika Westerberg PINCTRL_PIN(46, "GP_CAMERASB_02"), 3296e08d6bbSMika Westerberg PINCTRL_PIN(47, "GP_CAMERASB_08"), 3306e08d6bbSMika Westerberg PINCTRL_PIN(48, "GP_CAMERASB_00"), 3316e08d6bbSMika Westerberg PINCTRL_PIN(49, "GP_CAMERASB_06"), 3326e08d6bbSMika Westerberg PINCTRL_PIN(50, "GP_CAMERASB_10"), 3336e08d6bbSMika Westerberg PINCTRL_PIN(51, "GP_CAMERASB_03"), 3346e08d6bbSMika Westerberg PINCTRL_PIN(52, "GP_CAMERASB_09"), 3356e08d6bbSMika Westerberg PINCTRL_PIN(53, "GP_CAMERASB_01"), 3366e08d6bbSMika Westerberg PINCTRL_PIN(54, "GP_CAMERASB_07"), 3376e08d6bbSMika Westerberg PINCTRL_PIN(55, "GP_CAMERASB_11"), 3386e08d6bbSMika Westerberg PINCTRL_PIN(56, "GP_CAMERASB_04"), 3396e08d6bbSMika Westerberg 3406e08d6bbSMika Westerberg PINCTRL_PIN(60, "PANEL0_BKLTEN"), 3416e08d6bbSMika Westerberg PINCTRL_PIN(61, "HV_DDI0_HPD"), 3426e08d6bbSMika Westerberg PINCTRL_PIN(62, "HV_DDI2_DDC_SDA"), 3436e08d6bbSMika Westerberg PINCTRL_PIN(63, "PANEL1_BKLTCTL"), 3446e08d6bbSMika Westerberg PINCTRL_PIN(64, "HV_DDI1_HPD"), 3456e08d6bbSMika Westerberg PINCTRL_PIN(65, "PANEL0_BKLTCTL"), 3466e08d6bbSMika Westerberg PINCTRL_PIN(66, "HV_DDI0_DDC_SDA"), 3476e08d6bbSMika Westerberg PINCTRL_PIN(67, "HV_DDI2_DDC_SCL"), 3486e08d6bbSMika Westerberg PINCTRL_PIN(68, "HV_DDI2_HPD"), 3496e08d6bbSMika Westerberg PINCTRL_PIN(69, "PANEL1_VDDEN"), 3506e08d6bbSMika Westerberg PINCTRL_PIN(70, "PANEL1_BKLTEN"), 3516e08d6bbSMika Westerberg PINCTRL_PIN(71, "HV_DDI0_DDC_SCL"), 3526e08d6bbSMika Westerberg PINCTRL_PIN(72, "PANEL0_VDDEN"), 3536e08d6bbSMika Westerberg }; 3546e08d6bbSMika Westerberg 35536ad7b24SAndy Shevchenko static const struct intel_padgroup north_gpps[] = { 35636ad7b24SAndy Shevchenko CHV_GPP(0, 8), 35736ad7b24SAndy Shevchenko CHV_GPP(15, 27), 35836ad7b24SAndy Shevchenko CHV_GPP(30, 41), 35936ad7b24SAndy Shevchenko CHV_GPP(45, 56), 36036ad7b24SAndy Shevchenko CHV_GPP(60, 72), 3616e08d6bbSMika Westerberg }; 3626e08d6bbSMika Westerberg 363293428f9SAndy Shevchenko /* 364293428f9SAndy Shevchenko * North community can generate GPIO interrupts only for the first 8 365293428f9SAndy Shevchenko * interrupts. The upper half (8-15) can only be used to trigger GPEs. 366293428f9SAndy Shevchenko */ 367293428f9SAndy Shevchenko static const struct intel_community north_communities[] = { 368293428f9SAndy Shevchenko CHV_COMMUNITY(north_gpps, 8, 0x92), 369293428f9SAndy Shevchenko }; 370293428f9SAndy Shevchenko 371293428f9SAndy Shevchenko static const struct intel_pinctrl_soc_data north_soc_data = { 3726e08d6bbSMika Westerberg .uid = "2", 3736e08d6bbSMika Westerberg .pins = north_pins, 3746e08d6bbSMika Westerberg .npins = ARRAY_SIZE(north_pins), 375293428f9SAndy Shevchenko .communities = north_communities, 376293428f9SAndy Shevchenko .ncommunities = ARRAY_SIZE(north_communities), 3776e08d6bbSMika Westerberg }; 3786e08d6bbSMika Westerberg 3796e08d6bbSMika Westerberg static const struct pinctrl_pin_desc east_pins[] = { 3806e08d6bbSMika Westerberg PINCTRL_PIN(0, "PMU_SLP_S3_B"), 3816e08d6bbSMika Westerberg PINCTRL_PIN(1, "PMU_BATLOW_B"), 3826e08d6bbSMika Westerberg PINCTRL_PIN(2, "SUS_STAT_B"), 3836e08d6bbSMika Westerberg PINCTRL_PIN(3, "PMU_SLP_S0IX_B"), 3846e08d6bbSMika Westerberg PINCTRL_PIN(4, "PMU_AC_PRESENT"), 3856e08d6bbSMika Westerberg PINCTRL_PIN(5, "PMU_PLTRST_B"), 3866e08d6bbSMika Westerberg PINCTRL_PIN(6, "PMU_SUSCLK"), 3876e08d6bbSMika Westerberg PINCTRL_PIN(7, "PMU_SLP_LAN_B"), 3886e08d6bbSMika Westerberg PINCTRL_PIN(8, "PMU_PWRBTN_B"), 3896e08d6bbSMika Westerberg PINCTRL_PIN(9, "PMU_SLP_S4_B"), 3906e08d6bbSMika Westerberg PINCTRL_PIN(10, "PMU_WAKE_B"), 3916e08d6bbSMika Westerberg PINCTRL_PIN(11, "PMU_WAKE_LAN_B"), 3926e08d6bbSMika Westerberg 3936e08d6bbSMika Westerberg PINCTRL_PIN(15, "MF_ISH_GPIO_3"), 3946e08d6bbSMika Westerberg PINCTRL_PIN(16, "MF_ISH_GPIO_7"), 3956e08d6bbSMika Westerberg PINCTRL_PIN(17, "MF_ISH_I2C1_SCL"), 3966e08d6bbSMika Westerberg PINCTRL_PIN(18, "MF_ISH_GPIO_1"), 3976e08d6bbSMika Westerberg PINCTRL_PIN(19, "MF_ISH_GPIO_5"), 3986e08d6bbSMika Westerberg PINCTRL_PIN(20, "MF_ISH_GPIO_9"), 3996e08d6bbSMika Westerberg PINCTRL_PIN(21, "MF_ISH_GPIO_0"), 4006e08d6bbSMika Westerberg PINCTRL_PIN(22, "MF_ISH_GPIO_4"), 4016e08d6bbSMika Westerberg PINCTRL_PIN(23, "MF_ISH_GPIO_8"), 4026e08d6bbSMika Westerberg PINCTRL_PIN(24, "MF_ISH_GPIO_2"), 4036e08d6bbSMika Westerberg PINCTRL_PIN(25, "MF_ISH_GPIO_6"), 4046e08d6bbSMika Westerberg PINCTRL_PIN(26, "MF_ISH_I2C1_SDA"), 4056e08d6bbSMika Westerberg }; 4066e08d6bbSMika Westerberg 40736ad7b24SAndy Shevchenko static const struct intel_padgroup east_gpps[] = { 40836ad7b24SAndy Shevchenko CHV_GPP(0, 11), 40936ad7b24SAndy Shevchenko CHV_GPP(15, 26), 4106e08d6bbSMika Westerberg }; 4116e08d6bbSMika Westerberg 412293428f9SAndy Shevchenko static const struct intel_community east_communities[] = { 413293428f9SAndy Shevchenko CHV_COMMUNITY(east_gpps, 16, 0x93), 414293428f9SAndy Shevchenko }; 415293428f9SAndy Shevchenko 416293428f9SAndy Shevchenko static const struct intel_pinctrl_soc_data east_soc_data = { 4176e08d6bbSMika Westerberg .uid = "3", 4186e08d6bbSMika Westerberg .pins = east_pins, 4196e08d6bbSMika Westerberg .npins = ARRAY_SIZE(east_pins), 420293428f9SAndy Shevchenko .communities = east_communities, 421293428f9SAndy Shevchenko .ncommunities = ARRAY_SIZE(east_communities), 4226e08d6bbSMika Westerberg }; 4236e08d6bbSMika Westerberg 4246e08d6bbSMika Westerberg static const struct pinctrl_pin_desc southeast_pins[] = { 4256e08d6bbSMika Westerberg PINCTRL_PIN(0, "MF_PLT_CLK0"), 4266e08d6bbSMika Westerberg PINCTRL_PIN(1, "PWM1"), 4276e08d6bbSMika Westerberg PINCTRL_PIN(2, "MF_PLT_CLK1"), 4286e08d6bbSMika Westerberg PINCTRL_PIN(3, "MF_PLT_CLK4"), 4296e08d6bbSMika Westerberg PINCTRL_PIN(4, "MF_PLT_CLK3"), 4306e08d6bbSMika Westerberg PINCTRL_PIN(5, "PWM0"), 4316e08d6bbSMika Westerberg PINCTRL_PIN(6, "MF_PLT_CLK5"), 4326e08d6bbSMika Westerberg PINCTRL_PIN(7, "MF_PLT_CLK2"), 4336e08d6bbSMika Westerberg 4346e08d6bbSMika Westerberg PINCTRL_PIN(15, "SDMMC2_D3_CD_B"), 4356e08d6bbSMika Westerberg PINCTRL_PIN(16, "SDMMC1_CLK"), 4366e08d6bbSMika Westerberg PINCTRL_PIN(17, "SDMMC1_D0"), 4376e08d6bbSMika Westerberg PINCTRL_PIN(18, "SDMMC2_D1"), 4386e08d6bbSMika Westerberg PINCTRL_PIN(19, "SDMMC2_CLK"), 4396e08d6bbSMika Westerberg PINCTRL_PIN(20, "SDMMC1_D2"), 4406e08d6bbSMika Westerberg PINCTRL_PIN(21, "SDMMC2_D2"), 4416e08d6bbSMika Westerberg PINCTRL_PIN(22, "SDMMC2_CMD"), 4426e08d6bbSMika Westerberg PINCTRL_PIN(23, "SDMMC1_CMD"), 4436e08d6bbSMika Westerberg PINCTRL_PIN(24, "SDMMC1_D1"), 4446e08d6bbSMika Westerberg PINCTRL_PIN(25, "SDMMC2_D0"), 4456e08d6bbSMika Westerberg PINCTRL_PIN(26, "SDMMC1_D3_CD_B"), 4466e08d6bbSMika Westerberg 4476e08d6bbSMika Westerberg PINCTRL_PIN(30, "SDMMC3_D1"), 4486e08d6bbSMika Westerberg PINCTRL_PIN(31, "SDMMC3_CLK"), 4496e08d6bbSMika Westerberg PINCTRL_PIN(32, "SDMMC3_D3"), 4506e08d6bbSMika Westerberg PINCTRL_PIN(33, "SDMMC3_D2"), 4516e08d6bbSMika Westerberg PINCTRL_PIN(34, "SDMMC3_CMD"), 4526e08d6bbSMika Westerberg PINCTRL_PIN(35, "SDMMC3_D0"), 4536e08d6bbSMika Westerberg 4546e08d6bbSMika Westerberg PINCTRL_PIN(45, "MF_LPC_AD2"), 4556e08d6bbSMika Westerberg PINCTRL_PIN(46, "LPC_CLKRUNB"), 4566e08d6bbSMika Westerberg PINCTRL_PIN(47, "MF_LPC_AD0"), 4576e08d6bbSMika Westerberg PINCTRL_PIN(48, "LPC_FRAMEB"), 4586e08d6bbSMika Westerberg PINCTRL_PIN(49, "MF_LPC_CLKOUT1"), 4596e08d6bbSMika Westerberg PINCTRL_PIN(50, "MF_LPC_AD3"), 4606e08d6bbSMika Westerberg PINCTRL_PIN(51, "MF_LPC_CLKOUT0"), 4616e08d6bbSMika Westerberg PINCTRL_PIN(52, "MF_LPC_AD1"), 4626e08d6bbSMika Westerberg 4636e08d6bbSMika Westerberg PINCTRL_PIN(60, "SPI1_MISO"), 4646e08d6bbSMika Westerberg PINCTRL_PIN(61, "SPI1_CSO_B"), 4656e08d6bbSMika Westerberg PINCTRL_PIN(62, "SPI1_CLK"), 4666e08d6bbSMika Westerberg PINCTRL_PIN(63, "MMC1_D6"), 4676e08d6bbSMika Westerberg PINCTRL_PIN(64, "SPI1_MOSI"), 4686e08d6bbSMika Westerberg PINCTRL_PIN(65, "MMC1_D5"), 4696e08d6bbSMika Westerberg PINCTRL_PIN(66, "SPI1_CS1_B"), 4706e08d6bbSMika Westerberg PINCTRL_PIN(67, "MMC1_D4_SD_WE"), 4716e08d6bbSMika Westerberg PINCTRL_PIN(68, "MMC1_D7"), 4726e08d6bbSMika Westerberg PINCTRL_PIN(69, "MMC1_RCLK"), 4736e08d6bbSMika Westerberg 4746e08d6bbSMika Westerberg PINCTRL_PIN(75, "USB_OC1_B"), 4756e08d6bbSMika Westerberg PINCTRL_PIN(76, "PMU_RESETBUTTON_B"), 4766e08d6bbSMika Westerberg PINCTRL_PIN(77, "GPIO_ALERT"), 4776e08d6bbSMika Westerberg PINCTRL_PIN(78, "SDMMC3_PWR_EN_B"), 4786e08d6bbSMika Westerberg PINCTRL_PIN(79, "ILB_SERIRQ"), 4796e08d6bbSMika Westerberg PINCTRL_PIN(80, "USB_OC0_B"), 4806e08d6bbSMika Westerberg PINCTRL_PIN(81, "SDMMC3_CD_B"), 4816e08d6bbSMika Westerberg PINCTRL_PIN(82, "SPKR"), 4826e08d6bbSMika Westerberg PINCTRL_PIN(83, "SUSPWRDNACK"), 4836e08d6bbSMika Westerberg PINCTRL_PIN(84, "SPARE_PIN"), 4846e08d6bbSMika Westerberg PINCTRL_PIN(85, "SDMMC3_1P8_EN"), 4856e08d6bbSMika Westerberg }; 4866e08d6bbSMika Westerberg 4876e08d6bbSMika Westerberg static const unsigned southeast_pwm0_pins[] = { 5 }; 4886e08d6bbSMika Westerberg static const unsigned southeast_pwm1_pins[] = { 1 }; 4896e08d6bbSMika Westerberg static const unsigned southeast_sdmmc1_pins[] = { 4906e08d6bbSMika Westerberg 16, 17, 20, 23, 24, 26, 63, 65, 67, 68, 69, 4916e08d6bbSMika Westerberg }; 4926e08d6bbSMika Westerberg static const unsigned southeast_sdmmc2_pins[] = { 15, 18, 19, 21, 22, 25 }; 4936e08d6bbSMika Westerberg static const unsigned southeast_sdmmc3_pins[] = { 4946e08d6bbSMika Westerberg 30, 31, 32, 33, 34, 35, 78, 81, 85, 4956e08d6bbSMika Westerberg }; 4966e08d6bbSMika Westerberg static const unsigned southeast_spi1_pins[] = { 60, 61, 62, 64, 66 }; 4976e08d6bbSMika Westerberg static const unsigned southeast_spi2_pins[] = { 2, 3, 4, 6, 7 }; 4986e08d6bbSMika Westerberg 49936ad7b24SAndy Shevchenko static const struct intel_pingroup southeast_groups[] = { 50036ad7b24SAndy Shevchenko PIN_GROUP("pwm0_grp", southeast_pwm0_pins, PINMODE(1, 0)), 50136ad7b24SAndy Shevchenko PIN_GROUP("pwm1_grp", southeast_pwm1_pins, PINMODE(1, 0)), 50236ad7b24SAndy Shevchenko PIN_GROUP("sdmmc1_grp", southeast_sdmmc1_pins, PINMODE(1, 0)), 50336ad7b24SAndy Shevchenko PIN_GROUP("sdmmc2_grp", southeast_sdmmc2_pins, PINMODE(1, 0)), 50436ad7b24SAndy Shevchenko PIN_GROUP("sdmmc3_grp", southeast_sdmmc3_pins, PINMODE(1, 0)), 50536ad7b24SAndy Shevchenko PIN_GROUP("spi1_grp", southeast_spi1_pins, PINMODE(1, 0)), 50636ad7b24SAndy Shevchenko PIN_GROUP("spi2_grp", southeast_spi2_pins, PINMODE(4, 0)), 5076e08d6bbSMika Westerberg }; 5086e08d6bbSMika Westerberg 5096e08d6bbSMika Westerberg static const char * const southeast_pwm0_groups[] = { "pwm0_grp" }; 5106e08d6bbSMika Westerberg static const char * const southeast_pwm1_groups[] = { "pwm1_grp" }; 5116e08d6bbSMika Westerberg static const char * const southeast_sdmmc1_groups[] = { "sdmmc1_grp" }; 5126e08d6bbSMika Westerberg static const char * const southeast_sdmmc2_groups[] = { "sdmmc2_grp" }; 5136e08d6bbSMika Westerberg static const char * const southeast_sdmmc3_groups[] = { "sdmmc3_grp" }; 5146e08d6bbSMika Westerberg static const char * const southeast_spi1_groups[] = { "spi1_grp" }; 5156e08d6bbSMika Westerberg static const char * const southeast_spi2_groups[] = { "spi2_grp" }; 5166e08d6bbSMika Westerberg 5175458b7ceSAndy Shevchenko static const struct intel_function southeast_functions[] = { 5186e08d6bbSMika Westerberg FUNCTION("pwm0", southeast_pwm0_groups), 5196e08d6bbSMika Westerberg FUNCTION("pwm1", southeast_pwm1_groups), 5206e08d6bbSMika Westerberg FUNCTION("sdmmc1", southeast_sdmmc1_groups), 5216e08d6bbSMika Westerberg FUNCTION("sdmmc2", southeast_sdmmc2_groups), 5226e08d6bbSMika Westerberg FUNCTION("sdmmc3", southeast_sdmmc3_groups), 5236e08d6bbSMika Westerberg FUNCTION("spi1", southeast_spi1_groups), 5246e08d6bbSMika Westerberg FUNCTION("spi2", southeast_spi2_groups), 5256e08d6bbSMika Westerberg }; 5266e08d6bbSMika Westerberg 52736ad7b24SAndy Shevchenko static const struct intel_padgroup southeast_gpps[] = { 52836ad7b24SAndy Shevchenko CHV_GPP(0, 7), 52936ad7b24SAndy Shevchenko CHV_GPP(15, 26), 53036ad7b24SAndy Shevchenko CHV_GPP(30, 35), 53136ad7b24SAndy Shevchenko CHV_GPP(45, 52), 53236ad7b24SAndy Shevchenko CHV_GPP(60, 69), 53336ad7b24SAndy Shevchenko CHV_GPP(75, 85), 5346e08d6bbSMika Westerberg }; 5356e08d6bbSMika Westerberg 536293428f9SAndy Shevchenko static const struct intel_community southeast_communities[] = { 537293428f9SAndy Shevchenko CHV_COMMUNITY(southeast_gpps, 16, 0x94), 538293428f9SAndy Shevchenko }; 539293428f9SAndy Shevchenko 540293428f9SAndy Shevchenko static const struct intel_pinctrl_soc_data southeast_soc_data = { 5416e08d6bbSMika Westerberg .uid = "4", 5426e08d6bbSMika Westerberg .pins = southeast_pins, 5436e08d6bbSMika Westerberg .npins = ARRAY_SIZE(southeast_pins), 5446e08d6bbSMika Westerberg .groups = southeast_groups, 5456e08d6bbSMika Westerberg .ngroups = ARRAY_SIZE(southeast_groups), 5466e08d6bbSMika Westerberg .functions = southeast_functions, 5476e08d6bbSMika Westerberg .nfunctions = ARRAY_SIZE(southeast_functions), 548293428f9SAndy Shevchenko .communities = southeast_communities, 549293428f9SAndy Shevchenko .ncommunities = ARRAY_SIZE(southeast_communities), 5506e08d6bbSMika Westerberg }; 5516e08d6bbSMika Westerberg 552293428f9SAndy Shevchenko static const struct intel_pinctrl_soc_data *chv_soc_data[] = { 553293428f9SAndy Shevchenko &southwest_soc_data, 554293428f9SAndy Shevchenko &north_soc_data, 555293428f9SAndy Shevchenko &east_soc_data, 556293428f9SAndy Shevchenko &southeast_soc_data, 557293428f9SAndy Shevchenko NULL 5586e08d6bbSMika Westerberg }; 5596e08d6bbSMika Westerberg 5600bd50d71SDan O'Donovan /* 5610bd50d71SDan O'Donovan * Lock to serialize register accesses 5620bd50d71SDan O'Donovan * 5630bd50d71SDan O'Donovan * Due to a silicon issue, a shared lock must be used to prevent 5640bd50d71SDan O'Donovan * concurrent accesses across the 4 GPIO controllers. 5650bd50d71SDan O'Donovan * 5660bd50d71SDan O'Donovan * See Intel Atom Z8000 Processor Series Specification Update (Rev. 005), 5670bd50d71SDan O'Donovan * errata #CHT34, for further information. 5680bd50d71SDan O'Donovan */ 5690bd50d71SDan O'Donovan static DEFINE_RAW_SPINLOCK(chv_lock); 5700bd50d71SDan O'Donovan 5713ea2e2caSAndy Shevchenko static u32 chv_pctrl_readl(struct intel_pinctrl *pctrl, unsigned int offset) 57299fd6512SAndy Shevchenko { 573293428f9SAndy Shevchenko const struct intel_community *community = &pctrl->communities[0]; 574293428f9SAndy Shevchenko 575293428f9SAndy Shevchenko return readl(community->regs + offset); 57699fd6512SAndy Shevchenko } 57799fd6512SAndy Shevchenko 5783ea2e2caSAndy Shevchenko static void chv_pctrl_writel(struct intel_pinctrl *pctrl, unsigned int offset, u32 value) 57999fd6512SAndy Shevchenko { 580293428f9SAndy Shevchenko const struct intel_community *community = &pctrl->communities[0]; 581293428f9SAndy Shevchenko void __iomem *reg = community->regs + offset; 58299fd6512SAndy Shevchenko 58399fd6512SAndy Shevchenko /* Write and simple read back to confirm the bus transferring done */ 58499fd6512SAndy Shevchenko writel(value, reg); 58599fd6512SAndy Shevchenko readl(reg); 58699fd6512SAndy Shevchenko } 58799fd6512SAndy Shevchenko 5883ea2e2caSAndy Shevchenko static void __iomem *chv_padreg(struct intel_pinctrl *pctrl, unsigned int offset, 5894e737af8SAndy Shevchenko unsigned int reg) 5906e08d6bbSMika Westerberg { 591293428f9SAndy Shevchenko const struct intel_community *community = &pctrl->communities[0]; 5924e737af8SAndy Shevchenko unsigned int family_no = offset / MAX_FAMILY_PAD_GPIO_NO; 5934e737af8SAndy Shevchenko unsigned int pad_no = offset % MAX_FAMILY_PAD_GPIO_NO; 5946e08d6bbSMika Westerberg 595293428f9SAndy Shevchenko offset = FAMILY_PAD_REGS_SIZE * family_no + GPIO_REGS_SIZE * pad_no; 5966e08d6bbSMika Westerberg 597293428f9SAndy Shevchenko return community->pad_regs + offset + reg; 5986e08d6bbSMika Westerberg } 5996e08d6bbSMika Westerberg 6003ea2e2caSAndy Shevchenko static u32 chv_readl(struct intel_pinctrl *pctrl, unsigned int pin, unsigned int offset) 6014e7293e3SAndy Shevchenko { 6024e7293e3SAndy Shevchenko return readl(chv_padreg(pctrl, pin, offset)); 6034e7293e3SAndy Shevchenko } 6044e7293e3SAndy Shevchenko 6053ea2e2caSAndy Shevchenko static void chv_writel(struct intel_pinctrl *pctrl, unsigned int pin, unsigned int offset, u32 value) 6066e08d6bbSMika Westerberg { 607bfc8a4baSAndy Shevchenko void __iomem *reg = chv_padreg(pctrl, pin, offset); 608bfc8a4baSAndy Shevchenko 609bfc8a4baSAndy Shevchenko /* Write and simple read back to confirm the bus transferring done */ 6106e08d6bbSMika Westerberg writel(value, reg); 6116e08d6bbSMika Westerberg readl(reg); 6126e08d6bbSMika Westerberg } 6136e08d6bbSMika Westerberg 6146e08d6bbSMika Westerberg /* When Pad Cfg is locked, driver can only change GPIOTXState or GPIORXState */ 6153ea2e2caSAndy Shevchenko static bool chv_pad_locked(struct intel_pinctrl *pctrl, unsigned int offset) 6166e08d6bbSMika Westerberg { 6174e7293e3SAndy Shevchenko return chv_readl(pctrl, offset, CHV_PADCTRL1) & CHV_PADCTRL1_CFGLOCK; 6186e08d6bbSMika Westerberg } 6196e08d6bbSMika Westerberg 6206e08d6bbSMika Westerberg static int chv_get_groups_count(struct pinctrl_dev *pctldev) 6216e08d6bbSMika Westerberg { 6223ea2e2caSAndy Shevchenko struct intel_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); 6236e08d6bbSMika Westerberg 624293428f9SAndy Shevchenko return pctrl->soc->ngroups; 6256e08d6bbSMika Westerberg } 6266e08d6bbSMika Westerberg 6276e08d6bbSMika Westerberg static const char *chv_get_group_name(struct pinctrl_dev *pctldev, 6284e737af8SAndy Shevchenko unsigned int group) 6296e08d6bbSMika Westerberg { 6303ea2e2caSAndy Shevchenko struct intel_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); 6316e08d6bbSMika Westerberg 6322c292a78SAndy Shevchenko return pctrl->soc->groups[group].grp.name; 6336e08d6bbSMika Westerberg } 6346e08d6bbSMika Westerberg 6354e737af8SAndy Shevchenko static int chv_get_group_pins(struct pinctrl_dev *pctldev, unsigned int group, 6364e737af8SAndy Shevchenko const unsigned int **pins, unsigned int *npins) 6376e08d6bbSMika Westerberg { 6383ea2e2caSAndy Shevchenko struct intel_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); 6396e08d6bbSMika Westerberg 6402c292a78SAndy Shevchenko *pins = pctrl->soc->groups[group].grp.pins; 6412c292a78SAndy Shevchenko *npins = pctrl->soc->groups[group].grp.npins; 6426e08d6bbSMika Westerberg return 0; 6436e08d6bbSMika Westerberg } 6446e08d6bbSMika Westerberg 6456e08d6bbSMika Westerberg static void chv_pin_dbg_show(struct pinctrl_dev *pctldev, struct seq_file *s, 6464e737af8SAndy Shevchenko unsigned int offset) 6476e08d6bbSMika Westerberg { 6483ea2e2caSAndy Shevchenko struct intel_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); 6496e08d6bbSMika Westerberg unsigned long flags; 6506e08d6bbSMika Westerberg u32 ctrl0, ctrl1; 6516e08d6bbSMika Westerberg bool locked; 6526e08d6bbSMika Westerberg 6530bd50d71SDan O'Donovan raw_spin_lock_irqsave(&chv_lock, flags); 6546e08d6bbSMika Westerberg 6554e7293e3SAndy Shevchenko ctrl0 = chv_readl(pctrl, offset, CHV_PADCTRL0); 6564e7293e3SAndy Shevchenko ctrl1 = chv_readl(pctrl, offset, CHV_PADCTRL1); 6576e08d6bbSMika Westerberg locked = chv_pad_locked(pctrl, offset); 6586e08d6bbSMika Westerberg 6590bd50d71SDan O'Donovan raw_spin_unlock_irqrestore(&chv_lock, flags); 6606e08d6bbSMika Westerberg 6616e08d6bbSMika Westerberg if (ctrl0 & CHV_PADCTRL0_GPIOEN) { 6626e08d6bbSMika Westerberg seq_puts(s, "GPIO "); 6636e08d6bbSMika Westerberg } else { 6646e08d6bbSMika Westerberg u32 mode; 6656e08d6bbSMika Westerberg 6666e08d6bbSMika Westerberg mode = ctrl0 & CHV_PADCTRL0_PMODE_MASK; 6676e08d6bbSMika Westerberg mode >>= CHV_PADCTRL0_PMODE_SHIFT; 6686e08d6bbSMika Westerberg 6696e08d6bbSMika Westerberg seq_printf(s, "mode %d ", mode); 6706e08d6bbSMika Westerberg } 6716e08d6bbSMika Westerberg 672684373eaSMika Westerberg seq_printf(s, "0x%08x 0x%08x", ctrl0, ctrl1); 6736e08d6bbSMika Westerberg 6746e08d6bbSMika Westerberg if (locked) 6756e08d6bbSMika Westerberg seq_puts(s, " [LOCKED]"); 6766e08d6bbSMika Westerberg } 6776e08d6bbSMika Westerberg 6786e08d6bbSMika Westerberg static const struct pinctrl_ops chv_pinctrl_ops = { 6796e08d6bbSMika Westerberg .get_groups_count = chv_get_groups_count, 6806e08d6bbSMika Westerberg .get_group_name = chv_get_group_name, 6816e08d6bbSMika Westerberg .get_group_pins = chv_get_group_pins, 6826e08d6bbSMika Westerberg .pin_dbg_show = chv_pin_dbg_show, 6836e08d6bbSMika Westerberg }; 6846e08d6bbSMika Westerberg 6856e08d6bbSMika Westerberg static int chv_get_functions_count(struct pinctrl_dev *pctldev) 6866e08d6bbSMika Westerberg { 6873ea2e2caSAndy Shevchenko struct intel_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); 6886e08d6bbSMika Westerberg 689293428f9SAndy Shevchenko return pctrl->soc->nfunctions; 6906e08d6bbSMika Westerberg } 6916e08d6bbSMika Westerberg 6926e08d6bbSMika Westerberg static const char *chv_get_function_name(struct pinctrl_dev *pctldev, 6934e737af8SAndy Shevchenko unsigned int function) 6946e08d6bbSMika Westerberg { 6953ea2e2caSAndy Shevchenko struct intel_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); 6966e08d6bbSMika Westerberg 697293428f9SAndy Shevchenko return pctrl->soc->functions[function].name; 6986e08d6bbSMika Westerberg } 6996e08d6bbSMika Westerberg 7006e08d6bbSMika Westerberg static int chv_get_function_groups(struct pinctrl_dev *pctldev, 7014e737af8SAndy Shevchenko unsigned int function, 7026e08d6bbSMika Westerberg const char * const **groups, 7034e737af8SAndy Shevchenko unsigned int * const ngroups) 7046e08d6bbSMika Westerberg { 7053ea2e2caSAndy Shevchenko struct intel_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); 7066e08d6bbSMika Westerberg 707293428f9SAndy Shevchenko *groups = pctrl->soc->functions[function].groups; 708293428f9SAndy Shevchenko *ngroups = pctrl->soc->functions[function].ngroups; 7096e08d6bbSMika Westerberg return 0; 7106e08d6bbSMika Westerberg } 7116e08d6bbSMika Westerberg 7124e737af8SAndy Shevchenko static int chv_pinmux_set_mux(struct pinctrl_dev *pctldev, 7134e737af8SAndy Shevchenko unsigned int function, unsigned int group) 7146e08d6bbSMika Westerberg { 7153ea2e2caSAndy Shevchenko struct intel_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); 716db1b2a8cSAndy Shevchenko struct device *dev = pctrl->dev; 71736ad7b24SAndy Shevchenko const struct intel_pingroup *grp; 7186e08d6bbSMika Westerberg unsigned long flags; 7196e08d6bbSMika Westerberg int i; 7206e08d6bbSMika Westerberg 721293428f9SAndy Shevchenko grp = &pctrl->soc->groups[group]; 7226e08d6bbSMika Westerberg 7230bd50d71SDan O'Donovan raw_spin_lock_irqsave(&chv_lock, flags); 7246e08d6bbSMika Westerberg 7256e08d6bbSMika Westerberg /* Check first that the pad is not locked */ 7262c292a78SAndy Shevchenko for (i = 0; i < grp->grp.npins; i++) { 7272c292a78SAndy Shevchenko if (chv_pad_locked(pctrl, grp->grp.pins[i])) { 7280bd50d71SDan O'Donovan raw_spin_unlock_irqrestore(&chv_lock, flags); 7292c292a78SAndy Shevchenko dev_warn(dev, "unable to set mode for locked pin %u\n", grp->grp.pins[i]); 7306e08d6bbSMika Westerberg return -EBUSY; 7316e08d6bbSMika Westerberg } 7326e08d6bbSMika Westerberg } 7336e08d6bbSMika Westerberg 7342c292a78SAndy Shevchenko for (i = 0; i < grp->grp.npins; i++) { 7352c292a78SAndy Shevchenko int pin = grp->grp.pins[i]; 73636ad7b24SAndy Shevchenko unsigned int mode; 73736ad7b24SAndy Shevchenko bool invert_oe; 7386e08d6bbSMika Westerberg u32 value; 7396e08d6bbSMika Westerberg 7406e08d6bbSMika Westerberg /* Check if there is pin-specific config */ 74136ad7b24SAndy Shevchenko if (grp->modes) 74236ad7b24SAndy Shevchenko mode = grp->modes[i]; 74336ad7b24SAndy Shevchenko else 74436ad7b24SAndy Shevchenko mode = grp->mode; 7456e08d6bbSMika Westerberg 74636ad7b24SAndy Shevchenko /* Extract OE inversion */ 74736ad7b24SAndy Shevchenko invert_oe = mode & PINMODE_INVERT_OE; 74836ad7b24SAndy Shevchenko mode &= ~PINMODE_INVERT_OE; 7496e08d6bbSMika Westerberg 7504e7293e3SAndy Shevchenko value = chv_readl(pctrl, pin, CHV_PADCTRL0); 7516e08d6bbSMika Westerberg /* Disable GPIO mode */ 7526e08d6bbSMika Westerberg value &= ~CHV_PADCTRL0_GPIOEN; 7536e08d6bbSMika Westerberg /* Set to desired mode */ 7546e08d6bbSMika Westerberg value &= ~CHV_PADCTRL0_PMODE_MASK; 75536ad7b24SAndy Shevchenko value |= mode << CHV_PADCTRL0_PMODE_SHIFT; 756bfc8a4baSAndy Shevchenko chv_writel(pctrl, pin, CHV_PADCTRL0, value); 7576e08d6bbSMika Westerberg 7586e08d6bbSMika Westerberg /* Update for invert_oe */ 7594e7293e3SAndy Shevchenko value = chv_readl(pctrl, pin, CHV_PADCTRL1) & ~CHV_PADCTRL1_INVRXTX_MASK; 76036ad7b24SAndy Shevchenko if (invert_oe) 7616e08d6bbSMika Westerberg value |= CHV_PADCTRL1_INVRXTX_TXENABLE; 762bfc8a4baSAndy Shevchenko chv_writel(pctrl, pin, CHV_PADCTRL1, value); 7636e08d6bbSMika Westerberg 764db1b2a8cSAndy Shevchenko dev_dbg(dev, "configured pin %u mode %u OE %sinverted\n", pin, mode, 765db1b2a8cSAndy Shevchenko invert_oe ? "" : "not "); 7666e08d6bbSMika Westerberg } 7676e08d6bbSMika Westerberg 7680bd50d71SDan O'Donovan raw_spin_unlock_irqrestore(&chv_lock, flags); 7696e08d6bbSMika Westerberg 7706e08d6bbSMika Westerberg return 0; 7716e08d6bbSMika Westerberg } 7726e08d6bbSMika Westerberg 7733ea2e2caSAndy Shevchenko static void chv_gpio_clear_triggering(struct intel_pinctrl *pctrl, 774b6fb6e11SHans de Goede unsigned int offset) 775b6fb6e11SHans de Goede { 776a0bf06dcSHans de Goede u32 invrxtx_mask = CHV_PADCTRL1_INVRXTX_MASK; 777b6fb6e11SHans de Goede u32 value; 778b6fb6e11SHans de Goede 779a0bf06dcSHans de Goede /* 780a0bf06dcSHans de Goede * One some devices the GPIO should output the inverted value from what 781a0bf06dcSHans de Goede * device-drivers / ACPI code expects (inverted external buffer?). The 782a0bf06dcSHans de Goede * BIOS makes this work by setting the CHV_PADCTRL1_INVRXTX_TXDATA flag, 783a0bf06dcSHans de Goede * preserve this flag if the pin is already setup as GPIO. 784a0bf06dcSHans de Goede */ 785a0bf06dcSHans de Goede value = chv_readl(pctrl, offset, CHV_PADCTRL0); 786a0bf06dcSHans de Goede if (value & CHV_PADCTRL0_GPIOEN) 787a0bf06dcSHans de Goede invrxtx_mask &= ~CHV_PADCTRL1_INVRXTX_TXDATA; 788a0bf06dcSHans de Goede 7894e7293e3SAndy Shevchenko value = chv_readl(pctrl, offset, CHV_PADCTRL1); 790b6fb6e11SHans de Goede value &= ~CHV_PADCTRL1_INTWAKECFG_MASK; 791a0bf06dcSHans de Goede value &= ~invrxtx_mask; 792bfc8a4baSAndy Shevchenko chv_writel(pctrl, offset, CHV_PADCTRL1, value); 793b6fb6e11SHans de Goede } 794b6fb6e11SHans de Goede 7956e08d6bbSMika Westerberg static int chv_gpio_request_enable(struct pinctrl_dev *pctldev, 7966e08d6bbSMika Westerberg struct pinctrl_gpio_range *range, 7974e737af8SAndy Shevchenko unsigned int offset) 7986e08d6bbSMika Westerberg { 7993ea2e2caSAndy Shevchenko struct intel_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); 8006e08d6bbSMika Westerberg unsigned long flags; 8016e08d6bbSMika Westerberg u32 value; 8026e08d6bbSMika Westerberg 8030bd50d71SDan O'Donovan raw_spin_lock_irqsave(&chv_lock, flags); 8046e08d6bbSMika Westerberg 8056e08d6bbSMika Westerberg if (chv_pad_locked(pctrl, offset)) { 8064e7293e3SAndy Shevchenko value = chv_readl(pctrl, offset, CHV_PADCTRL0); 8076e08d6bbSMika Westerberg if (!(value & CHV_PADCTRL0_GPIOEN)) { 8086e08d6bbSMika Westerberg /* Locked so cannot enable */ 8090bd50d71SDan O'Donovan raw_spin_unlock_irqrestore(&chv_lock, flags); 8106e08d6bbSMika Westerberg return -EBUSY; 8116e08d6bbSMika Westerberg } 8126e08d6bbSMika Westerberg } else { 8138a828570SAndy Shevchenko struct intel_community_context *cctx = &pctrl->context.communities[0]; 8146e08d6bbSMika Westerberg int i; 8156e08d6bbSMika Westerberg 8166e08d6bbSMika Westerberg /* Reset the interrupt mapping */ 8178a828570SAndy Shevchenko for (i = 0; i < ARRAY_SIZE(cctx->intr_lines); i++) { 8188a828570SAndy Shevchenko if (cctx->intr_lines[i] == offset) { 819bdfbef2dSHans de Goede cctx->intr_lines[i] = CHV_INVALID_HWIRQ; 8206e08d6bbSMika Westerberg break; 8216e08d6bbSMika Westerberg } 8226e08d6bbSMika Westerberg } 8236e08d6bbSMika Westerberg 8246e08d6bbSMika Westerberg /* Disable interrupt generation */ 825b6fb6e11SHans de Goede chv_gpio_clear_triggering(pctrl, offset); 8266e08d6bbSMika Westerberg 8274e7293e3SAndy Shevchenko value = chv_readl(pctrl, offset, CHV_PADCTRL0); 8282479c730SMika Westerberg 8292479c730SMika Westerberg /* 8302479c730SMika Westerberg * If the pin is in HiZ mode (both TX and RX buffers are 8312479c730SMika Westerberg * disabled) we turn it to be input now. 8322479c730SMika Westerberg */ 8332479c730SMika Westerberg if ((value & CHV_PADCTRL0_GPIOCFG_MASK) == 8342479c730SMika Westerberg (CHV_PADCTRL0_GPIOCFG_HIZ << CHV_PADCTRL0_GPIOCFG_SHIFT)) { 8352479c730SMika Westerberg value &= ~CHV_PADCTRL0_GPIOCFG_MASK; 836bfc8a4baSAndy Shevchenko value |= CHV_PADCTRL0_GPIOCFG_GPI << CHV_PADCTRL0_GPIOCFG_SHIFT; 8372479c730SMika Westerberg } 8382479c730SMika Westerberg 8392479c730SMika Westerberg /* Switch to a GPIO mode */ 8402479c730SMika Westerberg value |= CHV_PADCTRL0_GPIOEN; 841bfc8a4baSAndy Shevchenko chv_writel(pctrl, offset, CHV_PADCTRL0, value); 8426e08d6bbSMika Westerberg } 8436e08d6bbSMika Westerberg 8440bd50d71SDan O'Donovan raw_spin_unlock_irqrestore(&chv_lock, flags); 8456e08d6bbSMika Westerberg 8466e08d6bbSMika Westerberg return 0; 8476e08d6bbSMika Westerberg } 8486e08d6bbSMika Westerberg 8496e08d6bbSMika Westerberg static void chv_gpio_disable_free(struct pinctrl_dev *pctldev, 8506e08d6bbSMika Westerberg struct pinctrl_gpio_range *range, 8514e737af8SAndy Shevchenko unsigned int offset) 8526e08d6bbSMika Westerberg { 8533ea2e2caSAndy Shevchenko struct intel_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); 8546e08d6bbSMika Westerberg unsigned long flags; 8556e08d6bbSMika Westerberg 8560bd50d71SDan O'Donovan raw_spin_lock_irqsave(&chv_lock, flags); 8576e08d6bbSMika Westerberg 8581adde32aSHans de Goede if (!chv_pad_locked(pctrl, offset)) 8591adde32aSHans de Goede chv_gpio_clear_triggering(pctrl, offset); 8606e08d6bbSMika Westerberg 8610bd50d71SDan O'Donovan raw_spin_unlock_irqrestore(&chv_lock, flags); 8626e08d6bbSMika Westerberg } 8636e08d6bbSMika Westerberg 8646e08d6bbSMika Westerberg static int chv_gpio_set_direction(struct pinctrl_dev *pctldev, 8656e08d6bbSMika Westerberg struct pinctrl_gpio_range *range, 8664e737af8SAndy Shevchenko unsigned int offset, bool input) 8676e08d6bbSMika Westerberg { 8683ea2e2caSAndy Shevchenko struct intel_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); 8696e08d6bbSMika Westerberg unsigned long flags; 8706e08d6bbSMika Westerberg u32 ctrl0; 8716e08d6bbSMika Westerberg 8720bd50d71SDan O'Donovan raw_spin_lock_irqsave(&chv_lock, flags); 8736e08d6bbSMika Westerberg 8744e7293e3SAndy Shevchenko ctrl0 = chv_readl(pctrl, offset, CHV_PADCTRL0) & ~CHV_PADCTRL0_GPIOCFG_MASK; 8756e08d6bbSMika Westerberg if (input) 8766e08d6bbSMika Westerberg ctrl0 |= CHV_PADCTRL0_GPIOCFG_GPI << CHV_PADCTRL0_GPIOCFG_SHIFT; 8776e08d6bbSMika Westerberg else 8786e08d6bbSMika Westerberg ctrl0 |= CHV_PADCTRL0_GPIOCFG_GPO << CHV_PADCTRL0_GPIOCFG_SHIFT; 879bfc8a4baSAndy Shevchenko chv_writel(pctrl, offset, CHV_PADCTRL0, ctrl0); 8806e08d6bbSMika Westerberg 8810bd50d71SDan O'Donovan raw_spin_unlock_irqrestore(&chv_lock, flags); 8826e08d6bbSMika Westerberg 8836e08d6bbSMika Westerberg return 0; 8846e08d6bbSMika Westerberg } 8856e08d6bbSMika Westerberg 8866e08d6bbSMika Westerberg static const struct pinmux_ops chv_pinmux_ops = { 8876e08d6bbSMika Westerberg .get_functions_count = chv_get_functions_count, 8886e08d6bbSMika Westerberg .get_function_name = chv_get_function_name, 8896e08d6bbSMika Westerberg .get_function_groups = chv_get_function_groups, 8906e08d6bbSMika Westerberg .set_mux = chv_pinmux_set_mux, 8916e08d6bbSMika Westerberg .gpio_request_enable = chv_gpio_request_enable, 8926e08d6bbSMika Westerberg .gpio_disable_free = chv_gpio_disable_free, 8936e08d6bbSMika Westerberg .gpio_set_direction = chv_gpio_set_direction, 8946e08d6bbSMika Westerberg }; 8956e08d6bbSMika Westerberg 8964e737af8SAndy Shevchenko static int chv_config_get(struct pinctrl_dev *pctldev, unsigned int pin, 8976e08d6bbSMika Westerberg unsigned long *config) 8986e08d6bbSMika Westerberg { 8993ea2e2caSAndy Shevchenko struct intel_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); 9006e08d6bbSMika Westerberg enum pin_config_param param = pinconf_to_config_param(*config); 9016e08d6bbSMika Westerberg unsigned long flags; 9026e08d6bbSMika Westerberg u32 ctrl0, ctrl1; 9036e08d6bbSMika Westerberg u16 arg = 0; 9046e08d6bbSMika Westerberg u32 term; 9056e08d6bbSMika Westerberg 9060bd50d71SDan O'Donovan raw_spin_lock_irqsave(&chv_lock, flags); 9074e7293e3SAndy Shevchenko ctrl0 = chv_readl(pctrl, pin, CHV_PADCTRL0); 9084e7293e3SAndy Shevchenko ctrl1 = chv_readl(pctrl, pin, CHV_PADCTRL1); 9090bd50d71SDan O'Donovan raw_spin_unlock_irqrestore(&chv_lock, flags); 9106e08d6bbSMika Westerberg 9116e08d6bbSMika Westerberg term = (ctrl0 & CHV_PADCTRL0_TERM_MASK) >> CHV_PADCTRL0_TERM_SHIFT; 9126e08d6bbSMika Westerberg 9136e08d6bbSMika Westerberg switch (param) { 9146e08d6bbSMika Westerberg case PIN_CONFIG_BIAS_DISABLE: 9156e08d6bbSMika Westerberg if (term) 9166e08d6bbSMika Westerberg return -EINVAL; 9176e08d6bbSMika Westerberg break; 9186e08d6bbSMika Westerberg 9196e08d6bbSMika Westerberg case PIN_CONFIG_BIAS_PULL_UP: 9206e08d6bbSMika Westerberg if (!(ctrl0 & CHV_PADCTRL0_TERM_UP)) 9216e08d6bbSMika Westerberg return -EINVAL; 9226e08d6bbSMika Westerberg 9236e08d6bbSMika Westerberg switch (term) { 9246e08d6bbSMika Westerberg case CHV_PADCTRL0_TERM_20K: 9256e08d6bbSMika Westerberg arg = 20000; 9266e08d6bbSMika Westerberg break; 9276e08d6bbSMika Westerberg case CHV_PADCTRL0_TERM_5K: 9286e08d6bbSMika Westerberg arg = 5000; 9296e08d6bbSMika Westerberg break; 9306e08d6bbSMika Westerberg case CHV_PADCTRL0_TERM_1K: 9316e08d6bbSMika Westerberg arg = 1000; 9326e08d6bbSMika Westerberg break; 9336e08d6bbSMika Westerberg } 9346e08d6bbSMika Westerberg 9356e08d6bbSMika Westerberg break; 9366e08d6bbSMika Westerberg 9376e08d6bbSMika Westerberg case PIN_CONFIG_BIAS_PULL_DOWN: 9386e08d6bbSMika Westerberg if (!term || (ctrl0 & CHV_PADCTRL0_TERM_UP)) 9396e08d6bbSMika Westerberg return -EINVAL; 9406e08d6bbSMika Westerberg 9416e08d6bbSMika Westerberg switch (term) { 9426e08d6bbSMika Westerberg case CHV_PADCTRL0_TERM_20K: 9436e08d6bbSMika Westerberg arg = 20000; 9446e08d6bbSMika Westerberg break; 9456e08d6bbSMika Westerberg case CHV_PADCTRL0_TERM_5K: 9466e08d6bbSMika Westerberg arg = 5000; 9476e08d6bbSMika Westerberg break; 9486e08d6bbSMika Westerberg } 9496e08d6bbSMika Westerberg 9506e08d6bbSMika Westerberg break; 9516e08d6bbSMika Westerberg 9526e08d6bbSMika Westerberg case PIN_CONFIG_DRIVE_OPEN_DRAIN: 9536e08d6bbSMika Westerberg if (!(ctrl1 & CHV_PADCTRL1_ODEN)) 9546e08d6bbSMika Westerberg return -EINVAL; 9556e08d6bbSMika Westerberg break; 9566e08d6bbSMika Westerberg 9576e08d6bbSMika Westerberg case PIN_CONFIG_BIAS_HIGH_IMPEDANCE: { 9586e08d6bbSMika Westerberg u32 cfg; 9596e08d6bbSMika Westerberg 9606e08d6bbSMika Westerberg cfg = ctrl0 & CHV_PADCTRL0_GPIOCFG_MASK; 9616e08d6bbSMika Westerberg cfg >>= CHV_PADCTRL0_GPIOCFG_SHIFT; 9626e08d6bbSMika Westerberg if (cfg != CHV_PADCTRL0_GPIOCFG_HIZ) 9636e08d6bbSMika Westerberg return -EINVAL; 9646e08d6bbSMika Westerberg 9656e08d6bbSMika Westerberg break; 9666e08d6bbSMika Westerberg } 9676e08d6bbSMika Westerberg 9686e08d6bbSMika Westerberg default: 9696e08d6bbSMika Westerberg return -ENOTSUPP; 9706e08d6bbSMika Westerberg } 9716e08d6bbSMika Westerberg 9726e08d6bbSMika Westerberg *config = pinconf_to_config_packed(param, arg); 9736e08d6bbSMika Westerberg return 0; 9746e08d6bbSMika Westerberg } 9756e08d6bbSMika Westerberg 9763ea2e2caSAndy Shevchenko static int chv_config_set_pull(struct intel_pinctrl *pctrl, unsigned int pin, 97758957d2eSMika Westerberg enum pin_config_param param, u32 arg) 9786e08d6bbSMika Westerberg { 9796e08d6bbSMika Westerberg unsigned long flags; 9806e08d6bbSMika Westerberg u32 ctrl0, pull; 9816e08d6bbSMika Westerberg 9820bd50d71SDan O'Donovan raw_spin_lock_irqsave(&chv_lock, flags); 9834e7293e3SAndy Shevchenko ctrl0 = chv_readl(pctrl, pin, CHV_PADCTRL0); 9846e08d6bbSMika Westerberg 9856e08d6bbSMika Westerberg switch (param) { 9866e08d6bbSMika Westerberg case PIN_CONFIG_BIAS_DISABLE: 9876e08d6bbSMika Westerberg ctrl0 &= ~(CHV_PADCTRL0_TERM_MASK | CHV_PADCTRL0_TERM_UP); 9886e08d6bbSMika Westerberg break; 9896e08d6bbSMika Westerberg 9906e08d6bbSMika Westerberg case PIN_CONFIG_BIAS_PULL_UP: 9916e08d6bbSMika Westerberg ctrl0 &= ~(CHV_PADCTRL0_TERM_MASK | CHV_PADCTRL0_TERM_UP); 9926e08d6bbSMika Westerberg 9936e08d6bbSMika Westerberg switch (arg) { 9946e08d6bbSMika Westerberg case 1000: 9956e08d6bbSMika Westerberg /* For 1k there is only pull up */ 9966e08d6bbSMika Westerberg pull = CHV_PADCTRL0_TERM_1K << CHV_PADCTRL0_TERM_SHIFT; 9976e08d6bbSMika Westerberg break; 9986e08d6bbSMika Westerberg case 5000: 9996e08d6bbSMika Westerberg pull = CHV_PADCTRL0_TERM_5K << CHV_PADCTRL0_TERM_SHIFT; 10006e08d6bbSMika Westerberg break; 10016e08d6bbSMika Westerberg case 20000: 10026e08d6bbSMika Westerberg pull = CHV_PADCTRL0_TERM_20K << CHV_PADCTRL0_TERM_SHIFT; 10036e08d6bbSMika Westerberg break; 10046e08d6bbSMika Westerberg default: 10050bd50d71SDan O'Donovan raw_spin_unlock_irqrestore(&chv_lock, flags); 10066e08d6bbSMika Westerberg return -EINVAL; 10076e08d6bbSMika Westerberg } 10086e08d6bbSMika Westerberg 10096e08d6bbSMika Westerberg ctrl0 |= CHV_PADCTRL0_TERM_UP | pull; 10106e08d6bbSMika Westerberg break; 10116e08d6bbSMika Westerberg 10126e08d6bbSMika Westerberg case PIN_CONFIG_BIAS_PULL_DOWN: 10136e08d6bbSMika Westerberg ctrl0 &= ~(CHV_PADCTRL0_TERM_MASK | CHV_PADCTRL0_TERM_UP); 10146e08d6bbSMika Westerberg 10156e08d6bbSMika Westerberg switch (arg) { 10166e08d6bbSMika Westerberg case 5000: 10176e08d6bbSMika Westerberg pull = CHV_PADCTRL0_TERM_5K << CHV_PADCTRL0_TERM_SHIFT; 10186e08d6bbSMika Westerberg break; 10196e08d6bbSMika Westerberg case 20000: 10206e08d6bbSMika Westerberg pull = CHV_PADCTRL0_TERM_20K << CHV_PADCTRL0_TERM_SHIFT; 10216e08d6bbSMika Westerberg break; 10226e08d6bbSMika Westerberg default: 10230bd50d71SDan O'Donovan raw_spin_unlock_irqrestore(&chv_lock, flags); 10246e08d6bbSMika Westerberg return -EINVAL; 10256e08d6bbSMika Westerberg } 10266e08d6bbSMika Westerberg 10276e08d6bbSMika Westerberg ctrl0 |= pull; 10286e08d6bbSMika Westerberg break; 10296e08d6bbSMika Westerberg 10306e08d6bbSMika Westerberg default: 10310bd50d71SDan O'Donovan raw_spin_unlock_irqrestore(&chv_lock, flags); 10326e08d6bbSMika Westerberg return -EINVAL; 10336e08d6bbSMika Westerberg } 10346e08d6bbSMika Westerberg 1035bfc8a4baSAndy Shevchenko chv_writel(pctrl, pin, CHV_PADCTRL0, ctrl0); 10360bd50d71SDan O'Donovan raw_spin_unlock_irqrestore(&chv_lock, flags); 10376e08d6bbSMika Westerberg 10386e08d6bbSMika Westerberg return 0; 10396e08d6bbSMika Westerberg } 10406e08d6bbSMika Westerberg 10413ea2e2caSAndy Shevchenko static int chv_config_set_oden(struct intel_pinctrl *pctrl, unsigned int pin, 1042ccdf81d0SDan O'Donovan bool enable) 1043ccdf81d0SDan O'Donovan { 1044ccdf81d0SDan O'Donovan unsigned long flags; 1045ccdf81d0SDan O'Donovan u32 ctrl1; 1046ccdf81d0SDan O'Donovan 1047ccdf81d0SDan O'Donovan raw_spin_lock_irqsave(&chv_lock, flags); 10484e7293e3SAndy Shevchenko ctrl1 = chv_readl(pctrl, pin, CHV_PADCTRL1); 1049ccdf81d0SDan O'Donovan 1050ccdf81d0SDan O'Donovan if (enable) 1051ccdf81d0SDan O'Donovan ctrl1 |= CHV_PADCTRL1_ODEN; 1052ccdf81d0SDan O'Donovan else 1053ccdf81d0SDan O'Donovan ctrl1 &= ~CHV_PADCTRL1_ODEN; 1054ccdf81d0SDan O'Donovan 1055bfc8a4baSAndy Shevchenko chv_writel(pctrl, pin, CHV_PADCTRL1, ctrl1); 1056ccdf81d0SDan O'Donovan raw_spin_unlock_irqrestore(&chv_lock, flags); 1057ccdf81d0SDan O'Donovan 1058ccdf81d0SDan O'Donovan return 0; 1059ccdf81d0SDan O'Donovan } 1060ccdf81d0SDan O'Donovan 10614e737af8SAndy Shevchenko static int chv_config_set(struct pinctrl_dev *pctldev, unsigned int pin, 10624e737af8SAndy Shevchenko unsigned long *configs, unsigned int nconfigs) 10636e08d6bbSMika Westerberg { 10643ea2e2caSAndy Shevchenko struct intel_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); 1065db1b2a8cSAndy Shevchenko struct device *dev = pctrl->dev; 10666e08d6bbSMika Westerberg enum pin_config_param param; 10676e08d6bbSMika Westerberg int i, ret; 106858957d2eSMika Westerberg u32 arg; 10696e08d6bbSMika Westerberg 10706e08d6bbSMika Westerberg if (chv_pad_locked(pctrl, pin)) 10716e08d6bbSMika Westerberg return -EBUSY; 10726e08d6bbSMika Westerberg 10736e08d6bbSMika Westerberg for (i = 0; i < nconfigs; i++) { 10746e08d6bbSMika Westerberg param = pinconf_to_config_param(configs[i]); 10756e08d6bbSMika Westerberg arg = pinconf_to_config_argument(configs[i]); 10766e08d6bbSMika Westerberg 10776e08d6bbSMika Westerberg switch (param) { 10786e08d6bbSMika Westerberg case PIN_CONFIG_BIAS_DISABLE: 10796e08d6bbSMika Westerberg case PIN_CONFIG_BIAS_PULL_UP: 10806e08d6bbSMika Westerberg case PIN_CONFIG_BIAS_PULL_DOWN: 10816e08d6bbSMika Westerberg ret = chv_config_set_pull(pctrl, pin, param, arg); 10826e08d6bbSMika Westerberg if (ret) 10836e08d6bbSMika Westerberg return ret; 10846e08d6bbSMika Westerberg break; 10856e08d6bbSMika Westerberg 1086ccdf81d0SDan O'Donovan case PIN_CONFIG_DRIVE_PUSH_PULL: 1087ccdf81d0SDan O'Donovan ret = chv_config_set_oden(pctrl, pin, false); 1088ccdf81d0SDan O'Donovan if (ret) 1089ccdf81d0SDan O'Donovan return ret; 1090ccdf81d0SDan O'Donovan break; 1091ccdf81d0SDan O'Donovan 1092ccdf81d0SDan O'Donovan case PIN_CONFIG_DRIVE_OPEN_DRAIN: 1093ccdf81d0SDan O'Donovan ret = chv_config_set_oden(pctrl, pin, true); 1094ccdf81d0SDan O'Donovan if (ret) 1095ccdf81d0SDan O'Donovan return ret; 1096ccdf81d0SDan O'Donovan break; 1097ccdf81d0SDan O'Donovan 10986e08d6bbSMika Westerberg default: 10996e08d6bbSMika Westerberg return -ENOTSUPP; 11006e08d6bbSMika Westerberg } 11016e08d6bbSMika Westerberg 1102db1b2a8cSAndy Shevchenko dev_dbg(dev, "pin %d set config %d arg %u\n", pin, param, arg); 11036e08d6bbSMika Westerberg } 11046e08d6bbSMika Westerberg 11056e08d6bbSMika Westerberg return 0; 11066e08d6bbSMika Westerberg } 11076e08d6bbSMika Westerberg 110877401d7fSDan O'Donovan static int chv_config_group_get(struct pinctrl_dev *pctldev, 110977401d7fSDan O'Donovan unsigned int group, 111077401d7fSDan O'Donovan unsigned long *config) 111177401d7fSDan O'Donovan { 111277401d7fSDan O'Donovan const unsigned int *pins; 111377401d7fSDan O'Donovan unsigned int npins; 111477401d7fSDan O'Donovan int ret; 111577401d7fSDan O'Donovan 111677401d7fSDan O'Donovan ret = chv_get_group_pins(pctldev, group, &pins, &npins); 111777401d7fSDan O'Donovan if (ret) 111877401d7fSDan O'Donovan return ret; 111977401d7fSDan O'Donovan 112077401d7fSDan O'Donovan ret = chv_config_get(pctldev, pins[0], config); 112177401d7fSDan O'Donovan if (ret) 112277401d7fSDan O'Donovan return ret; 112377401d7fSDan O'Donovan 112477401d7fSDan O'Donovan return 0; 112577401d7fSDan O'Donovan } 112677401d7fSDan O'Donovan 112777401d7fSDan O'Donovan static int chv_config_group_set(struct pinctrl_dev *pctldev, 112877401d7fSDan O'Donovan unsigned int group, unsigned long *configs, 112977401d7fSDan O'Donovan unsigned int num_configs) 113077401d7fSDan O'Donovan { 113177401d7fSDan O'Donovan const unsigned int *pins; 113277401d7fSDan O'Donovan unsigned int npins; 113377401d7fSDan O'Donovan int i, ret; 113477401d7fSDan O'Donovan 113577401d7fSDan O'Donovan ret = chv_get_group_pins(pctldev, group, &pins, &npins); 113677401d7fSDan O'Donovan if (ret) 113777401d7fSDan O'Donovan return ret; 113877401d7fSDan O'Donovan 113977401d7fSDan O'Donovan for (i = 0; i < npins; i++) { 114077401d7fSDan O'Donovan ret = chv_config_set(pctldev, pins[i], configs, num_configs); 114177401d7fSDan O'Donovan if (ret) 114277401d7fSDan O'Donovan return ret; 114377401d7fSDan O'Donovan } 114477401d7fSDan O'Donovan 114577401d7fSDan O'Donovan return 0; 114677401d7fSDan O'Donovan } 114777401d7fSDan O'Donovan 11486e08d6bbSMika Westerberg static const struct pinconf_ops chv_pinconf_ops = { 11496e08d6bbSMika Westerberg .is_generic = true, 11506e08d6bbSMika Westerberg .pin_config_set = chv_config_set, 11516e08d6bbSMika Westerberg .pin_config_get = chv_config_get, 115277401d7fSDan O'Donovan .pin_config_group_get = chv_config_group_get, 115377401d7fSDan O'Donovan .pin_config_group_set = chv_config_group_set, 11546e08d6bbSMika Westerberg }; 11556e08d6bbSMika Westerberg 11566e08d6bbSMika Westerberg static struct pinctrl_desc chv_pinctrl_desc = { 11576e08d6bbSMika Westerberg .pctlops = &chv_pinctrl_ops, 11586e08d6bbSMika Westerberg .pmxops = &chv_pinmux_ops, 11596e08d6bbSMika Westerberg .confops = &chv_pinconf_ops, 11606e08d6bbSMika Westerberg .owner = THIS_MODULE, 11616e08d6bbSMika Westerberg }; 11626e08d6bbSMika Westerberg 11634e737af8SAndy Shevchenko static int chv_gpio_get(struct gpio_chip *chip, unsigned int offset) 11646e08d6bbSMika Westerberg { 11653ea2e2caSAndy Shevchenko struct intel_pinctrl *pctrl = gpiochip_get_data(chip); 11664585b000SMika Westerberg unsigned long flags; 11676e08d6bbSMika Westerberg u32 ctrl0, cfg; 11686e08d6bbSMika Westerberg 11690bd50d71SDan O'Donovan raw_spin_lock_irqsave(&chv_lock, flags); 11704e7293e3SAndy Shevchenko ctrl0 = chv_readl(pctrl, offset, CHV_PADCTRL0); 11710bd50d71SDan O'Donovan raw_spin_unlock_irqrestore(&chv_lock, flags); 11726e08d6bbSMika Westerberg 11736e08d6bbSMika Westerberg cfg = ctrl0 & CHV_PADCTRL0_GPIOCFG_MASK; 11746e08d6bbSMika Westerberg cfg >>= CHV_PADCTRL0_GPIOCFG_SHIFT; 11756e08d6bbSMika Westerberg 11766e08d6bbSMika Westerberg if (cfg == CHV_PADCTRL0_GPIOCFG_GPO) 11776e08d6bbSMika Westerberg return !!(ctrl0 & CHV_PADCTRL0_GPIOTXSTATE); 11786e08d6bbSMika Westerberg return !!(ctrl0 & CHV_PADCTRL0_GPIORXSTATE); 11796e08d6bbSMika Westerberg } 11806e08d6bbSMika Westerberg 11814e737af8SAndy Shevchenko static void chv_gpio_set(struct gpio_chip *chip, unsigned int offset, int value) 11826e08d6bbSMika Westerberg { 11833ea2e2caSAndy Shevchenko struct intel_pinctrl *pctrl = gpiochip_get_data(chip); 11846e08d6bbSMika Westerberg unsigned long flags; 11856e08d6bbSMika Westerberg u32 ctrl0; 11866e08d6bbSMika Westerberg 11870bd50d71SDan O'Donovan raw_spin_lock_irqsave(&chv_lock, flags); 11886e08d6bbSMika Westerberg 11894e7293e3SAndy Shevchenko ctrl0 = chv_readl(pctrl, offset, CHV_PADCTRL0); 11906e08d6bbSMika Westerberg 11916e08d6bbSMika Westerberg if (value) 11926e08d6bbSMika Westerberg ctrl0 |= CHV_PADCTRL0_GPIOTXSTATE; 11936e08d6bbSMika Westerberg else 11946e08d6bbSMika Westerberg ctrl0 &= ~CHV_PADCTRL0_GPIOTXSTATE; 11956e08d6bbSMika Westerberg 1196bfc8a4baSAndy Shevchenko chv_writel(pctrl, offset, CHV_PADCTRL0, ctrl0); 11976e08d6bbSMika Westerberg 11980bd50d71SDan O'Donovan raw_spin_unlock_irqrestore(&chv_lock, flags); 11996e08d6bbSMika Westerberg } 12006e08d6bbSMika Westerberg 12014e737af8SAndy Shevchenko static int chv_gpio_get_direction(struct gpio_chip *chip, unsigned int offset) 12026e08d6bbSMika Westerberg { 12033ea2e2caSAndy Shevchenko struct intel_pinctrl *pctrl = gpiochip_get_data(chip); 12046e08d6bbSMika Westerberg u32 ctrl0, direction; 12054585b000SMika Westerberg unsigned long flags; 12066e08d6bbSMika Westerberg 12070bd50d71SDan O'Donovan raw_spin_lock_irqsave(&chv_lock, flags); 12084e7293e3SAndy Shevchenko ctrl0 = chv_readl(pctrl, offset, CHV_PADCTRL0); 12090bd50d71SDan O'Donovan raw_spin_unlock_irqrestore(&chv_lock, flags); 12106e08d6bbSMika Westerberg 12116e08d6bbSMika Westerberg direction = ctrl0 & CHV_PADCTRL0_GPIOCFG_MASK; 12126e08d6bbSMika Westerberg direction >>= CHV_PADCTRL0_GPIOCFG_SHIFT; 12136e08d6bbSMika Westerberg 121490a1eb18SMatti Vaittinen if (direction == CHV_PADCTRL0_GPIOCFG_GPO) 121590a1eb18SMatti Vaittinen return GPIO_LINE_DIRECTION_OUT; 121690a1eb18SMatti Vaittinen 121790a1eb18SMatti Vaittinen return GPIO_LINE_DIRECTION_IN; 12186e08d6bbSMika Westerberg } 12196e08d6bbSMika Westerberg 12204e737af8SAndy Shevchenko static int chv_gpio_direction_input(struct gpio_chip *chip, unsigned int offset) 12216e08d6bbSMika Westerberg { 12226e08d6bbSMika Westerberg return pinctrl_gpio_direction_input(chip->base + offset); 12236e08d6bbSMika Westerberg } 12246e08d6bbSMika Westerberg 12254e737af8SAndy Shevchenko static int chv_gpio_direction_output(struct gpio_chip *chip, unsigned int offset, 12266e08d6bbSMika Westerberg int value) 12276e08d6bbSMika Westerberg { 1228549e783fSqipeng.zha chv_gpio_set(chip, offset, value); 12296e08d6bbSMika Westerberg return pinctrl_gpio_direction_output(chip->base + offset); 12306e08d6bbSMika Westerberg } 12316e08d6bbSMika Westerberg 12326e08d6bbSMika Westerberg static const struct gpio_chip chv_gpio_chip = { 12336e08d6bbSMika Westerberg .owner = THIS_MODULE, 123498c85d58SJonas Gorski .request = gpiochip_generic_request, 123598c85d58SJonas Gorski .free = gpiochip_generic_free, 12366e08d6bbSMika Westerberg .get_direction = chv_gpio_get_direction, 12376e08d6bbSMika Westerberg .direction_input = chv_gpio_direction_input, 12386e08d6bbSMika Westerberg .direction_output = chv_gpio_direction_output, 12396e08d6bbSMika Westerberg .get = chv_gpio_get, 12406e08d6bbSMika Westerberg .set = chv_gpio_set, 12416e08d6bbSMika Westerberg }; 12426e08d6bbSMika Westerberg 12436e08d6bbSMika Westerberg static void chv_gpio_irq_ack(struct irq_data *d) 12446e08d6bbSMika Westerberg { 12456e08d6bbSMika Westerberg struct gpio_chip *gc = irq_data_get_irq_chip_data(d); 12463ea2e2caSAndy Shevchenko struct intel_pinctrl *pctrl = gpiochip_get_data(gc); 1247df38990dSAndy Shevchenko irq_hw_number_t hwirq = irqd_to_hwirq(d); 12486e08d6bbSMika Westerberg u32 intr_line; 12496e08d6bbSMika Westerberg 12500bd50d71SDan O'Donovan raw_spin_lock(&chv_lock); 12516e08d6bbSMika Westerberg 1252df38990dSAndy Shevchenko intr_line = chv_readl(pctrl, hwirq, CHV_PADCTRL0); 12536e08d6bbSMika Westerberg intr_line &= CHV_PADCTRL0_INTSEL_MASK; 12546e08d6bbSMika Westerberg intr_line >>= CHV_PADCTRL0_INTSEL_SHIFT; 125599fd6512SAndy Shevchenko chv_pctrl_writel(pctrl, CHV_INTSTAT, BIT(intr_line)); 12566e08d6bbSMika Westerberg 12570bd50d71SDan O'Donovan raw_spin_unlock(&chv_lock); 12586e08d6bbSMika Westerberg } 12596e08d6bbSMika Westerberg 126068aa84ffSAndy Shevchenko static void chv_gpio_irq_mask_unmask(struct gpio_chip *gc, irq_hw_number_t hwirq, bool mask) 12616e08d6bbSMika Westerberg { 12623ea2e2caSAndy Shevchenko struct intel_pinctrl *pctrl = gpiochip_get_data(gc); 12636e08d6bbSMika Westerberg u32 value, intr_line; 12646e08d6bbSMika Westerberg unsigned long flags; 12656e08d6bbSMika Westerberg 12660bd50d71SDan O'Donovan raw_spin_lock_irqsave(&chv_lock, flags); 12676e08d6bbSMika Westerberg 1268df38990dSAndy Shevchenko intr_line = chv_readl(pctrl, hwirq, CHV_PADCTRL0); 12696e08d6bbSMika Westerberg intr_line &= CHV_PADCTRL0_INTSEL_MASK; 12706e08d6bbSMika Westerberg intr_line >>= CHV_PADCTRL0_INTSEL_SHIFT; 12716e08d6bbSMika Westerberg 127299fd6512SAndy Shevchenko value = chv_pctrl_readl(pctrl, CHV_INTMASK); 12736e08d6bbSMika Westerberg if (mask) 12746e08d6bbSMika Westerberg value &= ~BIT(intr_line); 12756e08d6bbSMika Westerberg else 12766e08d6bbSMika Westerberg value |= BIT(intr_line); 127799fd6512SAndy Shevchenko chv_pctrl_writel(pctrl, CHV_INTMASK, value); 12786e08d6bbSMika Westerberg 12790bd50d71SDan O'Donovan raw_spin_unlock_irqrestore(&chv_lock, flags); 12806e08d6bbSMika Westerberg } 12816e08d6bbSMika Westerberg 12826e08d6bbSMika Westerberg static void chv_gpio_irq_mask(struct irq_data *d) 12836e08d6bbSMika Westerberg { 1284df38990dSAndy Shevchenko struct gpio_chip *gc = irq_data_get_irq_chip_data(d); 1285df38990dSAndy Shevchenko irq_hw_number_t hwirq = irqd_to_hwirq(d); 1286df38990dSAndy Shevchenko 128768aa84ffSAndy Shevchenko chv_gpio_irq_mask_unmask(gc, hwirq, true); 1288df38990dSAndy Shevchenko gpiochip_disable_irq(gc, hwirq); 12896e08d6bbSMika Westerberg } 12906e08d6bbSMika Westerberg 12916e08d6bbSMika Westerberg static void chv_gpio_irq_unmask(struct irq_data *d) 12926e08d6bbSMika Westerberg { 1293df38990dSAndy Shevchenko struct gpio_chip *gc = irq_data_get_irq_chip_data(d); 1294df38990dSAndy Shevchenko irq_hw_number_t hwirq = irqd_to_hwirq(d); 1295df38990dSAndy Shevchenko 1296df38990dSAndy Shevchenko gpiochip_enable_irq(gc, hwirq); 129768aa84ffSAndy Shevchenko chv_gpio_irq_mask_unmask(gc, hwirq, false); 12986e08d6bbSMika Westerberg } 12996e08d6bbSMika Westerberg 1300e6c906deSMika Westerberg static unsigned chv_gpio_irq_startup(struct irq_data *d) 1301e6c906deSMika Westerberg { 1302e6c906deSMika Westerberg /* 1303e6c906deSMika Westerberg * Check if the interrupt has been requested with 0 as triggering 1304e6c906deSMika Westerberg * type. In that case it is assumed that the current values 1305e6c906deSMika Westerberg * programmed to the hardware are used (e.g BIOS configured 1306e6c906deSMika Westerberg * defaults). 1307e6c906deSMika Westerberg * 1308e6c906deSMika Westerberg * In that case ->irq_set_type() will never be called so we need to 1309e6c906deSMika Westerberg * read back the values from hardware now, set correct flow handler 1310e6c906deSMika Westerberg * and update mappings before the interrupt is being used. 1311e6c906deSMika Westerberg */ 1312e6c906deSMika Westerberg if (irqd_get_trigger_type(d) == IRQ_TYPE_NONE) { 1313e6c906deSMika Westerberg struct gpio_chip *gc = irq_data_get_irq_chip_data(d); 13143ea2e2caSAndy Shevchenko struct intel_pinctrl *pctrl = gpiochip_get_data(gc); 1315db1b2a8cSAndy Shevchenko struct device *dev = pctrl->dev; 13168a828570SAndy Shevchenko struct intel_community_context *cctx = &pctrl->context.communities[0]; 1317df38990dSAndy Shevchenko irq_hw_number_t hwirq = irqd_to_hwirq(d); 1318e6c906deSMika Westerberg irq_flow_handler_t handler; 1319e6c906deSMika Westerberg unsigned long flags; 1320e6c906deSMika Westerberg u32 intsel, value; 1321e6c906deSMika Westerberg 13220bd50d71SDan O'Donovan raw_spin_lock_irqsave(&chv_lock, flags); 1323df38990dSAndy Shevchenko intsel = chv_readl(pctrl, hwirq, CHV_PADCTRL0); 1324e6c906deSMika Westerberg intsel &= CHV_PADCTRL0_INTSEL_MASK; 1325e6c906deSMika Westerberg intsel >>= CHV_PADCTRL0_INTSEL_SHIFT; 1326e6c906deSMika Westerberg 1327df38990dSAndy Shevchenko value = chv_readl(pctrl, hwirq, CHV_PADCTRL1); 1328e6c906deSMika Westerberg if (value & CHV_PADCTRL1_INTWAKECFG_LEVEL) 1329e6c906deSMika Westerberg handler = handle_level_irq; 1330e6c906deSMika Westerberg else 1331e6c906deSMika Westerberg handler = handle_edge_irq; 1332e6c906deSMika Westerberg 1333bdfbef2dSHans de Goede if (cctx->intr_lines[intsel] == CHV_INVALID_HWIRQ) { 1334a4e3f783SThomas Gleixner irq_set_handler_locked(d, handler); 1335df38990dSAndy Shevchenko dev_dbg(dev, "using interrupt line %u for IRQ_TYPE_NONE on pin %lu\n", 1336df38990dSAndy Shevchenko intsel, hwirq); 1337df38990dSAndy Shevchenko cctx->intr_lines[intsel] = hwirq; 1338e6c906deSMika Westerberg } 13390bd50d71SDan O'Donovan raw_spin_unlock_irqrestore(&chv_lock, flags); 1340e6c906deSMika Westerberg } 1341e6c906deSMika Westerberg 1342e6c906deSMika Westerberg chv_gpio_irq_unmask(d); 1343e6c906deSMika Westerberg return 0; 1344e6c906deSMika Westerberg } 1345e6c906deSMika Westerberg 134607199dbfSHans de Goede static int chv_gpio_set_intr_line(struct intel_pinctrl *pctrl, unsigned int pin) 134707199dbfSHans de Goede { 1348db1b2a8cSAndy Shevchenko struct device *dev = pctrl->dev; 134907199dbfSHans de Goede struct intel_community_context *cctx = &pctrl->context.communities[0]; 135007199dbfSHans de Goede const struct intel_community *community = &pctrl->communities[0]; 135107199dbfSHans de Goede u32 value, intsel; 135207199dbfSHans de Goede int i; 135307199dbfSHans de Goede 135407199dbfSHans de Goede value = chv_readl(pctrl, pin, CHV_PADCTRL0); 135507199dbfSHans de Goede intsel = (value & CHV_PADCTRL0_INTSEL_MASK) >> CHV_PADCTRL0_INTSEL_SHIFT; 135607199dbfSHans de Goede 135707199dbfSHans de Goede if (cctx->intr_lines[intsel] == pin) 135807199dbfSHans de Goede return 0; 135907199dbfSHans de Goede 136007199dbfSHans de Goede if (cctx->intr_lines[intsel] == CHV_INVALID_HWIRQ) { 1361db1b2a8cSAndy Shevchenko dev_dbg(dev, "using interrupt line %u for pin %u\n", intsel, pin); 136207199dbfSHans de Goede cctx->intr_lines[intsel] = pin; 136307199dbfSHans de Goede return 0; 136407199dbfSHans de Goede } 136507199dbfSHans de Goede 136607199dbfSHans de Goede /* 136707199dbfSHans de Goede * The interrupt line selected by the BIOS is already in use by 136807199dbfSHans de Goede * another pin, this is a known BIOS bug found on several models. 136907199dbfSHans de Goede * But this may also be caused by Linux deciding to use a pin as 137007199dbfSHans de Goede * IRQ which was not expected to be used as such by the BIOS authors, 137107199dbfSHans de Goede * so log this at info level only. 137207199dbfSHans de Goede */ 1373db1b2a8cSAndy Shevchenko dev_info(dev, "interrupt line %u is used by both pin %u and pin %u\n", intsel, 1374db1b2a8cSAndy Shevchenko cctx->intr_lines[intsel], pin); 137507199dbfSHans de Goede 137607199dbfSHans de Goede if (chv_pad_locked(pctrl, pin)) 137707199dbfSHans de Goede return -EBUSY; 137807199dbfSHans de Goede 137907199dbfSHans de Goede /* 138007199dbfSHans de Goede * The BIOS fills the interrupt lines from 0 counting up, start at 138107199dbfSHans de Goede * the other end to find a free interrupt line to workaround this. 138207199dbfSHans de Goede */ 138307199dbfSHans de Goede for (i = community->nirqs - 1; i >= 0; i--) { 138407199dbfSHans de Goede if (cctx->intr_lines[i] == CHV_INVALID_HWIRQ) 138507199dbfSHans de Goede break; 138607199dbfSHans de Goede } 138707199dbfSHans de Goede if (i < 0) 138807199dbfSHans de Goede return -EBUSY; 138907199dbfSHans de Goede 1390db1b2a8cSAndy Shevchenko dev_info(dev, "changing the interrupt line for pin %u to %d\n", pin, i); 139107199dbfSHans de Goede 139207199dbfSHans de Goede value = (value & ~CHV_PADCTRL0_INTSEL_MASK) | (i << CHV_PADCTRL0_INTSEL_SHIFT); 139307199dbfSHans de Goede chv_writel(pctrl, pin, CHV_PADCTRL0, value); 139407199dbfSHans de Goede cctx->intr_lines[i] = pin; 139507199dbfSHans de Goede 139607199dbfSHans de Goede return 0; 139707199dbfSHans de Goede } 139807199dbfSHans de Goede 13994e737af8SAndy Shevchenko static int chv_gpio_irq_type(struct irq_data *d, unsigned int type) 14006e08d6bbSMika Westerberg { 14016e08d6bbSMika Westerberg struct gpio_chip *gc = irq_data_get_irq_chip_data(d); 14023ea2e2caSAndy Shevchenko struct intel_pinctrl *pctrl = gpiochip_get_data(gc); 1403df38990dSAndy Shevchenko irq_hw_number_t hwirq = irqd_to_hwirq(d); 14046e08d6bbSMika Westerberg unsigned long flags; 14056e08d6bbSMika Westerberg u32 value; 140607199dbfSHans de Goede int ret; 14076e08d6bbSMika Westerberg 14080bd50d71SDan O'Donovan raw_spin_lock_irqsave(&chv_lock, flags); 14096e08d6bbSMika Westerberg 1410df38990dSAndy Shevchenko ret = chv_gpio_set_intr_line(pctrl, hwirq); 141107199dbfSHans de Goede if (ret) 141207199dbfSHans de Goede goto out_unlock; 141307199dbfSHans de Goede 14146e08d6bbSMika Westerberg /* 14156e08d6bbSMika Westerberg * Pins which can be used as shared interrupt are configured in 14166e08d6bbSMika Westerberg * BIOS. Driver trusts BIOS configurations and assigns different 14176e08d6bbSMika Westerberg * handler according to the irq type. 14186e08d6bbSMika Westerberg * 14196e08d6bbSMika Westerberg * Driver needs to save the mapping between each pin and 14206e08d6bbSMika Westerberg * its interrupt line. 14216e08d6bbSMika Westerberg * 1. If the pin cfg is locked in BIOS: 14226e08d6bbSMika Westerberg * Trust BIOS has programmed IntWakeCfg bits correctly, 14236e08d6bbSMika Westerberg * driver just needs to save the mapping. 14246e08d6bbSMika Westerberg * 2. If the pin cfg is not locked in BIOS: 14256e08d6bbSMika Westerberg * Driver programs the IntWakeCfg bits and save the mapping. 14266e08d6bbSMika Westerberg */ 1427df38990dSAndy Shevchenko if (!chv_pad_locked(pctrl, hwirq)) { 1428df38990dSAndy Shevchenko value = chv_readl(pctrl, hwirq, CHV_PADCTRL1); 14296e08d6bbSMika Westerberg value &= ~CHV_PADCTRL1_INTWAKECFG_MASK; 14306e08d6bbSMika Westerberg value &= ~CHV_PADCTRL1_INVRXTX_MASK; 14316e08d6bbSMika Westerberg 14326e08d6bbSMika Westerberg if (type & IRQ_TYPE_EDGE_BOTH) { 14336e08d6bbSMika Westerberg if ((type & IRQ_TYPE_EDGE_BOTH) == IRQ_TYPE_EDGE_BOTH) 14346e08d6bbSMika Westerberg value |= CHV_PADCTRL1_INTWAKECFG_BOTH; 14356e08d6bbSMika Westerberg else if (type & IRQ_TYPE_EDGE_RISING) 14366e08d6bbSMika Westerberg value |= CHV_PADCTRL1_INTWAKECFG_RISING; 14376e08d6bbSMika Westerberg else if (type & IRQ_TYPE_EDGE_FALLING) 14386e08d6bbSMika Westerberg value |= CHV_PADCTRL1_INTWAKECFG_FALLING; 14396e08d6bbSMika Westerberg } else if (type & IRQ_TYPE_LEVEL_MASK) { 14406e08d6bbSMika Westerberg value |= CHV_PADCTRL1_INTWAKECFG_LEVEL; 14416e08d6bbSMika Westerberg if (type & IRQ_TYPE_LEVEL_LOW) 14426e08d6bbSMika Westerberg value |= CHV_PADCTRL1_INVRXTX_RXDATA; 14436e08d6bbSMika Westerberg } 14446e08d6bbSMika Westerberg 1445df38990dSAndy Shevchenko chv_writel(pctrl, hwirq, CHV_PADCTRL1, value); 14466e08d6bbSMika Westerberg } 14476e08d6bbSMika Westerberg 14486e08d6bbSMika Westerberg if (type & IRQ_TYPE_EDGE_BOTH) 1449a4e3f783SThomas Gleixner irq_set_handler_locked(d, handle_edge_irq); 14506e08d6bbSMika Westerberg else if (type & IRQ_TYPE_LEVEL_MASK) 1451a4e3f783SThomas Gleixner irq_set_handler_locked(d, handle_level_irq); 14526e08d6bbSMika Westerberg 145307199dbfSHans de Goede out_unlock: 14540bd50d71SDan O'Donovan raw_spin_unlock_irqrestore(&chv_lock, flags); 14556e08d6bbSMika Westerberg 145607199dbfSHans de Goede return ret; 14576e08d6bbSMika Westerberg } 14586e08d6bbSMika Westerberg 1459df38990dSAndy Shevchenko static const struct irq_chip chv_gpio_irq_chip = { 1460df38990dSAndy Shevchenko .name = "chv-gpio", 1461df38990dSAndy Shevchenko .irq_startup = chv_gpio_irq_startup, 1462df38990dSAndy Shevchenko .irq_ack = chv_gpio_irq_ack, 1463df38990dSAndy Shevchenko .irq_mask = chv_gpio_irq_mask, 1464df38990dSAndy Shevchenko .irq_unmask = chv_gpio_irq_unmask, 1465df38990dSAndy Shevchenko .irq_set_type = chv_gpio_irq_type, 1466df38990dSAndy Shevchenko .flags = IRQCHIP_SKIP_SET_WAKE | IRQCHIP_IMMUTABLE, 1467df38990dSAndy Shevchenko GPIOCHIP_IRQ_RESOURCE_HELPERS, 1468df38990dSAndy Shevchenko }; 1469df38990dSAndy Shevchenko 1470bd0b9ac4SThomas Gleixner static void chv_gpio_irq_handler(struct irq_desc *desc) 14716e08d6bbSMika Westerberg { 14726e08d6bbSMika Westerberg struct gpio_chip *gc = irq_desc_get_handler_data(desc); 14733ea2e2caSAndy Shevchenko struct intel_pinctrl *pctrl = gpiochip_get_data(gc); 1474db1b2a8cSAndy Shevchenko struct device *dev = pctrl->dev; 1475293428f9SAndy Shevchenko const struct intel_community *community = &pctrl->communities[0]; 14768a828570SAndy Shevchenko struct intel_community_context *cctx = &pctrl->context.communities[0]; 14775663bb27SJiang Liu struct irq_chip *chip = irq_desc_get_chip(desc); 14786e08d6bbSMika Westerberg unsigned long pending; 14793dbf1ee6SGrace Kao unsigned long flags; 14806e08d6bbSMika Westerberg u32 intr_line; 14816e08d6bbSMika Westerberg 14826e08d6bbSMika Westerberg chained_irq_enter(chip, desc); 14836e08d6bbSMika Westerberg 14843dbf1ee6SGrace Kao raw_spin_lock_irqsave(&chv_lock, flags); 148599fd6512SAndy Shevchenko pending = chv_pctrl_readl(pctrl, CHV_INTSTAT); 14863dbf1ee6SGrace Kao raw_spin_unlock_irqrestore(&chv_lock, flags); 14873dbf1ee6SGrace Kao 1488293428f9SAndy Shevchenko for_each_set_bit(intr_line, &pending, community->nirqs) { 1489a9cb09b7SMarc Zyngier unsigned int offset; 14906e08d6bbSMika Westerberg 14918a828570SAndy Shevchenko offset = cctx->intr_lines[intr_line]; 1492bdfbef2dSHans de Goede if (offset == CHV_INVALID_HWIRQ) { 1493aa285145SHans de Goede dev_warn_once(dev, "interrupt on unmapped interrupt line %u\n", intr_line); 1494aa285145SHans de Goede /* Some boards expect hwirq 0 to trigger in this case */ 1495aa285145SHans de Goede offset = 0; 1496bdfbef2dSHans de Goede } 1497bdfbef2dSHans de Goede 1498a9cb09b7SMarc Zyngier generic_handle_domain_irq(gc->irq.domain, offset); 14996e08d6bbSMika Westerberg } 15006e08d6bbSMika Westerberg 15016e08d6bbSMika Westerberg chained_irq_exit(chip, desc); 15026e08d6bbSMika Westerberg } 15036e08d6bbSMika Westerberg 150470365027SMika Westerberg /* 150570365027SMika Westerberg * Certain machines seem to hardcode Linux IRQ numbers in their ACPI 150670365027SMika Westerberg * tables. Since we leave GPIOs that are not capable of generating 150770365027SMika Westerberg * interrupts out of the irqdomain the numbering will be different and 150870365027SMika Westerberg * cause devices using the hardcoded IRQ numbers fail. In order not to 150970365027SMika Westerberg * break such machines we will only mask pins from irqdomain if the machine 151070365027SMika Westerberg * is not listed below. 151170365027SMika Westerberg */ 151270365027SMika Westerberg static const struct dmi_system_id chv_no_valid_mask[] = { 151370365027SMika Westerberg /* See https://bugzilla.kernel.org/show_bug.cgi?id=194945 */ 15142a8209faSMika Westerberg { 15152a8209faSMika Westerberg .ident = "Intel_Strago based Chromebooks (All models)", 151670365027SMika Westerberg .matches = { 151770365027SMika Westerberg DMI_MATCH(DMI_SYS_VENDOR, "GOOGLE"), 15182a8209faSMika Westerberg DMI_MATCH(DMI_PRODUCT_FAMILY, "Intel_Strago"), 15192a8209faSMika Westerberg }, 15202a8209faSMika Westerberg }, 15212a8209faSMika Westerberg { 15222d80bd3fSAndy Shevchenko .ident = "HP Chromebook 11 G5 (Setzer)", 15232d80bd3fSAndy Shevchenko .matches = { 15242d80bd3fSAndy Shevchenko DMI_MATCH(DMI_SYS_VENDOR, "HP"), 15252d80bd3fSAndy Shevchenko DMI_MATCH(DMI_PRODUCT_NAME, "Setzer"), 15262d80bd3fSAndy Shevchenko }, 15272d80bd3fSAndy Shevchenko }, 15282d80bd3fSAndy Shevchenko { 15292a8209faSMika Westerberg .ident = "Acer Chromebook R11 (Cyan)", 15302a8209faSMika Westerberg .matches = { 15312a8209faSMika Westerberg DMI_MATCH(DMI_SYS_VENDOR, "GOOGLE"), 15322a8209faSMika Westerberg DMI_MATCH(DMI_PRODUCT_NAME, "Cyan"), 15332a8209faSMika Westerberg }, 15342a8209faSMika Westerberg }, 15352a8209faSMika Westerberg { 15362a8209faSMika Westerberg .ident = "Samsung Chromebook 3 (Celes)", 15372a8209faSMika Westerberg .matches = { 15382a8209faSMika Westerberg DMI_MATCH(DMI_SYS_VENDOR, "GOOGLE"), 15392a8209faSMika Westerberg DMI_MATCH(DMI_PRODUCT_NAME, "Celes"), 154070365027SMika Westerberg }, 1541a9de080bSWei Yongjun }, 1542a9de080bSWei Yongjun {} 154370365027SMika Westerberg }; 154470365027SMika Westerberg 15455fbe5b58SLinus Walleij static void chv_init_irq_valid_mask(struct gpio_chip *chip, 15465fbe5b58SLinus Walleij unsigned long *valid_mask, 15475fbe5b58SLinus Walleij unsigned int ngpios) 15485fbe5b58SLinus Walleij { 15493ea2e2caSAndy Shevchenko struct intel_pinctrl *pctrl = gpiochip_get_data(chip); 1550293428f9SAndy Shevchenko const struct intel_community *community = &pctrl->communities[0]; 15515fbe5b58SLinus Walleij int i; 15525fbe5b58SLinus Walleij 15535fbe5b58SLinus Walleij /* Do not add GPIOs that can only generate GPEs to the IRQ domain */ 1554293428f9SAndy Shevchenko for (i = 0; i < pctrl->soc->npins; i++) { 15555fbe5b58SLinus Walleij const struct pinctrl_pin_desc *desc; 15565fbe5b58SLinus Walleij u32 intsel; 15575fbe5b58SLinus Walleij 1558293428f9SAndy Shevchenko desc = &pctrl->soc->pins[i]; 15595fbe5b58SLinus Walleij 15604e7293e3SAndy Shevchenko intsel = chv_readl(pctrl, desc->number, CHV_PADCTRL0); 15615fbe5b58SLinus Walleij intsel &= CHV_PADCTRL0_INTSEL_MASK; 15625fbe5b58SLinus Walleij intsel >>= CHV_PADCTRL0_INTSEL_SHIFT; 15635fbe5b58SLinus Walleij 15645fbe5b58SLinus Walleij if (intsel >= community->nirqs) 156537398985SHans de Goede clear_bit(desc->number, valid_mask); 15665fbe5b58SLinus Walleij } 15675fbe5b58SLinus Walleij } 15685fbe5b58SLinus Walleij 156982d9beb4SHans de Goede static int chv_gpio_irq_init_hw(struct gpio_chip *chip) 157082d9beb4SHans de Goede { 15713ea2e2caSAndy Shevchenko struct intel_pinctrl *pctrl = gpiochip_get_data(chip); 1572293428f9SAndy Shevchenko const struct intel_community *community = &pctrl->communities[0]; 157382d9beb4SHans de Goede 157482d9beb4SHans de Goede /* 157582d9beb4SHans de Goede * The same set of machines in chv_no_valid_mask[] have incorrectly 157682d9beb4SHans de Goede * configured GPIOs that generate spurious interrupts so we use 157782d9beb4SHans de Goede * this same list to apply another quirk for them. 157882d9beb4SHans de Goede * 157982d9beb4SHans de Goede * See also https://bugzilla.kernel.org/show_bug.cgi?id=197953. 158082d9beb4SHans de Goede */ 158182d9beb4SHans de Goede if (!pctrl->chip.irq.init_valid_mask) { 158282d9beb4SHans de Goede /* 158382d9beb4SHans de Goede * Mask all interrupts the community is able to generate 158482d9beb4SHans de Goede * but leave the ones that can only generate GPEs unmasked. 158582d9beb4SHans de Goede */ 1586293428f9SAndy Shevchenko chv_pctrl_writel(pctrl, CHV_INTMASK, GENMASK(31, community->nirqs)); 158782d9beb4SHans de Goede } 158882d9beb4SHans de Goede 158982d9beb4SHans de Goede /* Clear all interrupts */ 159099fd6512SAndy Shevchenko chv_pctrl_writel(pctrl, CHV_INTSTAT, 0xffff); 159182d9beb4SHans de Goede 159282d9beb4SHans de Goede return 0; 159382d9beb4SHans de Goede } 159482d9beb4SHans de Goede 1595bd90633aSHans de Goede static int chv_gpio_add_pin_ranges(struct gpio_chip *chip) 1596bd90633aSHans de Goede { 15973ea2e2caSAndy Shevchenko struct intel_pinctrl *pctrl = gpiochip_get_data(chip); 1598db1b2a8cSAndy Shevchenko struct device *dev = pctrl->dev; 1599293428f9SAndy Shevchenko const struct intel_community *community = &pctrl->communities[0]; 160036ad7b24SAndy Shevchenko const struct intel_padgroup *gpp; 1601bd90633aSHans de Goede int ret, i; 1602bd90633aSHans de Goede 160336ad7b24SAndy Shevchenko for (i = 0; i < community->ngpps; i++) { 160436ad7b24SAndy Shevchenko gpp = &community->gpps[i]; 1605db1b2a8cSAndy Shevchenko ret = gpiochip_add_pin_range(chip, dev_name(dev), gpp->base, gpp->base, gpp->size); 1606bd90633aSHans de Goede if (ret) { 1607db1b2a8cSAndy Shevchenko dev_err(dev, "failed to add GPIO pin range\n"); 1608bd90633aSHans de Goede return ret; 1609bd90633aSHans de Goede } 1610bd90633aSHans de Goede } 1611bd90633aSHans de Goede 1612bd90633aSHans de Goede return 0; 1613bd90633aSHans de Goede } 1614bd90633aSHans de Goede 16153ea2e2caSAndy Shevchenko static int chv_gpio_probe(struct intel_pinctrl *pctrl, int irq) 16166e08d6bbSMika Westerberg { 1617293428f9SAndy Shevchenko const struct intel_community *community = &pctrl->communities[0]; 161836ad7b24SAndy Shevchenko const struct intel_padgroup *gpp; 16196e08d6bbSMika Westerberg struct gpio_chip *chip = &pctrl->chip; 1620db1b2a8cSAndy Shevchenko struct device *dev = pctrl->dev; 162170365027SMika Westerberg bool need_valid_mask = !dmi_check_system(chv_no_valid_mask); 162203c4749dSMika Westerberg int ret, i, irq_base; 16236e08d6bbSMika Westerberg 16246e08d6bbSMika Westerberg *chip = chv_gpio_chip; 16256e08d6bbSMika Westerberg 1626293428f9SAndy Shevchenko chip->ngpio = pctrl->soc->pins[pctrl->soc->npins - 1].number + 1; 1627db1b2a8cSAndy Shevchenko chip->label = dev_name(dev); 1628bd90633aSHans de Goede chip->add_pin_ranges = chv_gpio_add_pin_ranges; 1629db1b2a8cSAndy Shevchenko chip->parent = dev; 16306e08d6bbSMika Westerberg chip->base = -1; 16316e08d6bbSMika Westerberg 1632b9a19bdbSHans de Goede pctrl->irq = irq; 1633e58e1773SAndy Shevchenko 1634df38990dSAndy Shevchenko gpio_irq_chip_set_chip(&chip->irq, &chv_gpio_irq_chip); 1635b9a19bdbSHans de Goede chip->irq.init_hw = chv_gpio_irq_init_hw; 1636b9a19bdbSHans de Goede chip->irq.parent_handler = chv_gpio_irq_handler; 1637b9a19bdbSHans de Goede chip->irq.num_parents = 1; 1638b9a19bdbSHans de Goede chip->irq.parents = &pctrl->irq; 1639b9a19bdbSHans de Goede chip->irq.default_type = IRQ_TYPE_NONE; 1640b9a19bdbSHans de Goede chip->irq.handler = handle_bad_irq; 1641b9a19bdbSHans de Goede if (need_valid_mask) { 1642b9a19bdbSHans de Goede chip->irq.init_valid_mask = chv_init_irq_valid_mask; 1643b9a19bdbSHans de Goede } else { 1644db1b2a8cSAndy Shevchenko irq_base = devm_irq_alloc_descs(dev, -1, 0, pctrl->soc->npins, NUMA_NO_NODE); 1645b9a19bdbSHans de Goede if (irq_base < 0) { 1646db1b2a8cSAndy Shevchenko dev_err(dev, "Failed to allocate IRQ numbers\n"); 1647b9a19bdbSHans de Goede return irq_base; 1648b9a19bdbSHans de Goede } 1649b9a19bdbSHans de Goede } 1650b9a19bdbSHans de Goede 1651db1b2a8cSAndy Shevchenko ret = devm_gpiochip_add_data(dev, chip, pctrl); 16526e08d6bbSMika Westerberg if (ret) { 1653db1b2a8cSAndy Shevchenko dev_err(dev, "Failed to register gpiochip\n"); 1654d1073418SMika Westerberg return ret; 16556e08d6bbSMika Westerberg } 16566e08d6bbSMika Westerberg 165783b9dc11SMika Westerberg if (!need_valid_mask) { 165836ad7b24SAndy Shevchenko for (i = 0; i < community->ngpps; i++) { 165936ad7b24SAndy Shevchenko gpp = &community->gpps[i]; 166083b9dc11SMika Westerberg 166183b9dc11SMika Westerberg irq_domain_associate_many(chip->irq.domain, irq_base, 166236ad7b24SAndy Shevchenko gpp->base, gpp->size); 166336ad7b24SAndy Shevchenko irq_base += gpp->size; 166483b9dc11SMika Westerberg } 166583b9dc11SMika Westerberg } 166683b9dc11SMika Westerberg 16676e08d6bbSMika Westerberg return 0; 16686e08d6bbSMika Westerberg } 16696e08d6bbSMika Westerberg 1670a0b02859SHans de Goede static acpi_status chv_pinctrl_mmio_access_handler(u32 function, 1671a0b02859SHans de Goede acpi_physical_address address, u32 bits, u64 *value, 1672a0b02859SHans de Goede void *handler_context, void *region_context) 1673a0b02859SHans de Goede { 16743ea2e2caSAndy Shevchenko struct intel_pinctrl *pctrl = region_context; 1675a0b02859SHans de Goede unsigned long flags; 1676a0b02859SHans de Goede acpi_status ret = AE_OK; 1677a0b02859SHans de Goede 1678a0b02859SHans de Goede raw_spin_lock_irqsave(&chv_lock, flags); 1679a0b02859SHans de Goede 1680a0b02859SHans de Goede if (function == ACPI_WRITE) 168199fd6512SAndy Shevchenko chv_pctrl_writel(pctrl, address, *value); 1682a0b02859SHans de Goede else if (function == ACPI_READ) 168399fd6512SAndy Shevchenko *value = chv_pctrl_readl(pctrl, address); 1684a0b02859SHans de Goede else 1685a0b02859SHans de Goede ret = AE_BAD_PARAMETER; 1686a0b02859SHans de Goede 1687a0b02859SHans de Goede raw_spin_unlock_irqrestore(&chv_lock, flags); 1688a0b02859SHans de Goede 1689a0b02859SHans de Goede return ret; 1690a0b02859SHans de Goede } 1691a0b02859SHans de Goede 16926e08d6bbSMika Westerberg static int chv_pinctrl_probe(struct platform_device *pdev) 16936e08d6bbSMika Westerberg { 169410c857f0SAndy Shevchenko const struct intel_pinctrl_soc_data *soc_data; 1695bdfbef2dSHans de Goede struct intel_community_context *cctx; 1696293428f9SAndy Shevchenko struct intel_community *community; 1697293428f9SAndy Shevchenko struct device *dev = &pdev->dev; 169810c857f0SAndy Shevchenko struct acpi_device *adev = ACPI_COMPANION(dev); 16993ea2e2caSAndy Shevchenko struct intel_pinctrl *pctrl; 1700a0b02859SHans de Goede acpi_status status; 1701bdfbef2dSHans de Goede unsigned int i; 170210c857f0SAndy Shevchenko int ret, irq; 17036e08d6bbSMika Westerberg 170410c857f0SAndy Shevchenko soc_data = intel_pinctrl_get_soc_data(pdev); 170510c857f0SAndy Shevchenko if (IS_ERR(soc_data)) 170610c857f0SAndy Shevchenko return PTR_ERR(soc_data); 1707293428f9SAndy Shevchenko 1708293428f9SAndy Shevchenko pctrl = devm_kzalloc(dev, sizeof(*pctrl), GFP_KERNEL); 17096e08d6bbSMika Westerberg if (!pctrl) 17106e08d6bbSMika Westerberg return -ENOMEM; 17116e08d6bbSMika Westerberg 1712359164faSAndy Shevchenko pctrl->dev = dev; 1713293428f9SAndy Shevchenko pctrl->soc = soc_data; 1714293428f9SAndy Shevchenko 1715293428f9SAndy Shevchenko pctrl->ncommunities = pctrl->soc->ncommunities; 1716293428f9SAndy Shevchenko pctrl->communities = devm_kmemdup(dev, pctrl->soc->communities, 1717293428f9SAndy Shevchenko pctrl->ncommunities * sizeof(*pctrl->communities), 1718293428f9SAndy Shevchenko GFP_KERNEL); 1719293428f9SAndy Shevchenko if (!pctrl->communities) 1720293428f9SAndy Shevchenko return -ENOMEM; 1721293428f9SAndy Shevchenko 1722293428f9SAndy Shevchenko community = &pctrl->communities[0]; 1723293428f9SAndy Shevchenko community->regs = devm_platform_ioremap_resource(pdev, 0); 1724293428f9SAndy Shevchenko if (IS_ERR(community->regs)) 1725293428f9SAndy Shevchenko return PTR_ERR(community->regs); 1726293428f9SAndy Shevchenko 1727293428f9SAndy Shevchenko community->pad_regs = community->regs + FAMILY_PAD_REGS_OFF; 17286e08d6bbSMika Westerberg 17299eb457b5SMika Westerberg #ifdef CONFIG_PM_SLEEP 1730293428f9SAndy Shevchenko pctrl->context.pads = devm_kcalloc(dev, pctrl->soc->npins, 1731293428f9SAndy Shevchenko sizeof(*pctrl->context.pads), 17329eb457b5SMika Westerberg GFP_KERNEL); 1733293428f9SAndy Shevchenko if (!pctrl->context.pads) 17349eb457b5SMika Westerberg return -ENOMEM; 17359eb457b5SMika Westerberg #endif 17369eb457b5SMika Westerberg 17378a828570SAndy Shevchenko pctrl->context.communities = devm_kcalloc(dev, pctrl->soc->ncommunities, 17388a828570SAndy Shevchenko sizeof(*pctrl->context.communities), 17398a828570SAndy Shevchenko GFP_KERNEL); 17408a828570SAndy Shevchenko if (!pctrl->context.communities) 17418a828570SAndy Shevchenko return -ENOMEM; 17428a828570SAndy Shevchenko 1743bdfbef2dSHans de Goede cctx = &pctrl->context.communities[0]; 1744bdfbef2dSHans de Goede for (i = 0; i < ARRAY_SIZE(cctx->intr_lines); i++) 1745bdfbef2dSHans de Goede cctx->intr_lines[i] = CHV_INVALID_HWIRQ; 1746bdfbef2dSHans de Goede 17476e08d6bbSMika Westerberg irq = platform_get_irq(pdev, 0); 174857afe3eaSStephen Boyd if (irq < 0) 17496e08d6bbSMika Westerberg return irq; 17506e08d6bbSMika Westerberg 17516e08d6bbSMika Westerberg pctrl->pctldesc = chv_pinctrl_desc; 1752359164faSAndy Shevchenko pctrl->pctldesc.name = dev_name(dev); 1753293428f9SAndy Shevchenko pctrl->pctldesc.pins = pctrl->soc->pins; 1754293428f9SAndy Shevchenko pctrl->pctldesc.npins = pctrl->soc->npins; 17556e08d6bbSMika Westerberg 1756359164faSAndy Shevchenko pctrl->pctldev = devm_pinctrl_register(dev, &pctrl->pctldesc, pctrl); 1757323de9efSMasahiro Yamada if (IS_ERR(pctrl->pctldev)) { 1758359164faSAndy Shevchenko dev_err(dev, "failed to register pinctrl driver\n"); 1759323de9efSMasahiro Yamada return PTR_ERR(pctrl->pctldev); 17606e08d6bbSMika Westerberg } 17616e08d6bbSMika Westerberg 17626e08d6bbSMika Westerberg ret = chv_gpio_probe(pctrl, irq); 17637cf061faSLaxman Dewangan if (ret) 17646e08d6bbSMika Westerberg return ret; 17656e08d6bbSMika Westerberg 1766a0b02859SHans de Goede status = acpi_install_address_space_handler(adev->handle, 1767293428f9SAndy Shevchenko community->acpi_space_id, 1768a0b02859SHans de Goede chv_pinctrl_mmio_access_handler, 1769a0b02859SHans de Goede NULL, pctrl); 1770a0b02859SHans de Goede if (ACPI_FAILURE(status)) 1771359164faSAndy Shevchenko dev_err(dev, "failed to install ACPI addr space handler\n"); 1772a0b02859SHans de Goede 17736e08d6bbSMika Westerberg platform_set_drvdata(pdev, pctrl); 17746e08d6bbSMika Westerberg 17756e08d6bbSMika Westerberg return 0; 17766e08d6bbSMika Westerberg } 17776e08d6bbSMika Westerberg 1778a0b02859SHans de Goede static int chv_pinctrl_remove(struct platform_device *pdev) 1779a0b02859SHans de Goede { 17803ea2e2caSAndy Shevchenko struct intel_pinctrl *pctrl = platform_get_drvdata(pdev); 1781293428f9SAndy Shevchenko const struct intel_community *community = &pctrl->communities[0]; 1782a0b02859SHans de Goede 1783a0b02859SHans de Goede acpi_remove_address_space_handler(ACPI_COMPANION(&pdev->dev), 1784293428f9SAndy Shevchenko community->acpi_space_id, 1785a0b02859SHans de Goede chv_pinctrl_mmio_access_handler); 1786a0b02859SHans de Goede 1787a0b02859SHans de Goede return 0; 1788a0b02859SHans de Goede } 1789a0b02859SHans de Goede 17909eb457b5SMika Westerberg #ifdef CONFIG_PM_SLEEP 1791d2cdf5dcSMika Westerberg static int chv_pinctrl_suspend_noirq(struct device *dev) 17929eb457b5SMika Westerberg { 17933ea2e2caSAndy Shevchenko struct intel_pinctrl *pctrl = dev_get_drvdata(dev); 17948a828570SAndy Shevchenko struct intel_community_context *cctx = &pctrl->context.communities[0]; 179556211121SMika Westerberg unsigned long flags; 17969eb457b5SMika Westerberg int i; 17979eb457b5SMika Westerberg 179856211121SMika Westerberg raw_spin_lock_irqsave(&chv_lock, flags); 179956211121SMika Westerberg 18008a828570SAndy Shevchenko cctx->saved_intmask = chv_pctrl_readl(pctrl, CHV_INTMASK); 18019eb457b5SMika Westerberg 1802293428f9SAndy Shevchenko for (i = 0; i < pctrl->soc->npins; i++) { 18039eb457b5SMika Westerberg const struct pinctrl_pin_desc *desc; 1804293428f9SAndy Shevchenko struct intel_pad_context *ctx = &pctrl->context.pads[i]; 18059eb457b5SMika Westerberg 1806293428f9SAndy Shevchenko desc = &pctrl->soc->pins[i]; 18079eb457b5SMika Westerberg if (chv_pad_locked(pctrl, desc->number)) 18089eb457b5SMika Westerberg continue; 18099eb457b5SMika Westerberg 18104e7293e3SAndy Shevchenko ctx->padctrl0 = chv_readl(pctrl, desc->number, CHV_PADCTRL0); 18114e7293e3SAndy Shevchenko ctx->padctrl0 &= ~CHV_PADCTRL0_GPIORXSTATE; 18129eb457b5SMika Westerberg 18134e7293e3SAndy Shevchenko ctx->padctrl1 = chv_readl(pctrl, desc->number, CHV_PADCTRL1); 18149eb457b5SMika Westerberg } 18159eb457b5SMika Westerberg 181656211121SMika Westerberg raw_spin_unlock_irqrestore(&chv_lock, flags); 181756211121SMika Westerberg 18189eb457b5SMika Westerberg return 0; 18199eb457b5SMika Westerberg } 18209eb457b5SMika Westerberg 1821d2cdf5dcSMika Westerberg static int chv_pinctrl_resume_noirq(struct device *dev) 18229eb457b5SMika Westerberg { 18233ea2e2caSAndy Shevchenko struct intel_pinctrl *pctrl = dev_get_drvdata(dev); 18248a828570SAndy Shevchenko struct intel_community_context *cctx = &pctrl->context.communities[0]; 182556211121SMika Westerberg unsigned long flags; 18269eb457b5SMika Westerberg int i; 18279eb457b5SMika Westerberg 182856211121SMika Westerberg raw_spin_lock_irqsave(&chv_lock, flags); 182956211121SMika Westerberg 18309eb457b5SMika Westerberg /* 18319eb457b5SMika Westerberg * Mask all interrupts before restoring per-pin configuration 18329eb457b5SMika Westerberg * registers because we don't know in which state BIOS left them 18339eb457b5SMika Westerberg * upon exiting suspend. 18349eb457b5SMika Westerberg */ 183599fd6512SAndy Shevchenko chv_pctrl_writel(pctrl, CHV_INTMASK, 0x0000); 18369eb457b5SMika Westerberg 1837293428f9SAndy Shevchenko for (i = 0; i < pctrl->soc->npins; i++) { 18389eb457b5SMika Westerberg const struct pinctrl_pin_desc *desc; 1839293428f9SAndy Shevchenko struct intel_pad_context *ctx = &pctrl->context.pads[i]; 18409eb457b5SMika Westerberg u32 val; 18419eb457b5SMika Westerberg 1842293428f9SAndy Shevchenko desc = &pctrl->soc->pins[i]; 18439eb457b5SMika Westerberg if (chv_pad_locked(pctrl, desc->number)) 18449eb457b5SMika Westerberg continue; 18459eb457b5SMika Westerberg 18469eb457b5SMika Westerberg /* Only restore if our saved state differs from the current */ 18474e7293e3SAndy Shevchenko val = chv_readl(pctrl, desc->number, CHV_PADCTRL0); 18484e7293e3SAndy Shevchenko val &= ~CHV_PADCTRL0_GPIORXSTATE; 18499eb457b5SMika Westerberg if (ctx->padctrl0 != val) { 1850bfc8a4baSAndy Shevchenko chv_writel(pctrl, desc->number, CHV_PADCTRL0, ctx->padctrl0); 1851db1b2a8cSAndy Shevchenko dev_dbg(dev, "restored pin %2u ctrl0 0x%08x\n", desc->number, 1852db1b2a8cSAndy Shevchenko chv_readl(pctrl, desc->number, CHV_PADCTRL0)); 18539eb457b5SMika Westerberg } 18549eb457b5SMika Westerberg 18554e7293e3SAndy Shevchenko val = chv_readl(pctrl, desc->number, CHV_PADCTRL1); 18569eb457b5SMika Westerberg if (ctx->padctrl1 != val) { 1857bfc8a4baSAndy Shevchenko chv_writel(pctrl, desc->number, CHV_PADCTRL1, ctx->padctrl1); 1858db1b2a8cSAndy Shevchenko dev_dbg(dev, "restored pin %2u ctrl1 0x%08x\n", desc->number, 1859db1b2a8cSAndy Shevchenko chv_readl(pctrl, desc->number, CHV_PADCTRL1)); 18609eb457b5SMika Westerberg } 18619eb457b5SMika Westerberg } 18629eb457b5SMika Westerberg 18639eb457b5SMika Westerberg /* 18649eb457b5SMika Westerberg * Now that all pins are restored to known state, we can restore 18659eb457b5SMika Westerberg * the interrupt mask register as well. 18669eb457b5SMika Westerberg */ 186799fd6512SAndy Shevchenko chv_pctrl_writel(pctrl, CHV_INTSTAT, 0xffff); 18688a828570SAndy Shevchenko chv_pctrl_writel(pctrl, CHV_INTMASK, cctx->saved_intmask); 18699eb457b5SMika Westerberg 187056211121SMika Westerberg raw_spin_unlock_irqrestore(&chv_lock, flags); 187156211121SMika Westerberg 18729eb457b5SMika Westerberg return 0; 18739eb457b5SMika Westerberg } 18749eb457b5SMika Westerberg #endif 18759eb457b5SMika Westerberg 18769eb457b5SMika Westerberg static const struct dev_pm_ops chv_pinctrl_pm_ops = { 1877d2cdf5dcSMika Westerberg SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(chv_pinctrl_suspend_noirq, 1878d2cdf5dcSMika Westerberg chv_pinctrl_resume_noirq) 18799eb457b5SMika Westerberg }; 18809eb457b5SMika Westerberg 18816e08d6bbSMika Westerberg static const struct acpi_device_id chv_pinctrl_acpi_match[] = { 1882293428f9SAndy Shevchenko { "INT33FF", (kernel_ulong_t)chv_soc_data }, 18836e08d6bbSMika Westerberg { } 18846e08d6bbSMika Westerberg }; 18856e08d6bbSMika Westerberg MODULE_DEVICE_TABLE(acpi, chv_pinctrl_acpi_match); 18866e08d6bbSMika Westerberg 18876e08d6bbSMika Westerberg static struct platform_driver chv_pinctrl_driver = { 18886e08d6bbSMika Westerberg .probe = chv_pinctrl_probe, 1889a0b02859SHans de Goede .remove = chv_pinctrl_remove, 18906e08d6bbSMika Westerberg .driver = { 18916e08d6bbSMika Westerberg .name = "cherryview-pinctrl", 18929eb457b5SMika Westerberg .pm = &chv_pinctrl_pm_ops, 18936e08d6bbSMika Westerberg .acpi_match_table = chv_pinctrl_acpi_match, 18946e08d6bbSMika Westerberg }, 18956e08d6bbSMika Westerberg }; 18966e08d6bbSMika Westerberg 18976e08d6bbSMika Westerberg static int __init chv_pinctrl_init(void) 18986e08d6bbSMika Westerberg { 18996e08d6bbSMika Westerberg return platform_driver_register(&chv_pinctrl_driver); 19006e08d6bbSMika Westerberg } 19016e08d6bbSMika Westerberg subsys_initcall(chv_pinctrl_init); 19026e08d6bbSMika Westerberg 19036e08d6bbSMika Westerberg static void __exit chv_pinctrl_exit(void) 19046e08d6bbSMika Westerberg { 19056e08d6bbSMika Westerberg platform_driver_unregister(&chv_pinctrl_driver); 19066e08d6bbSMika Westerberg } 19076e08d6bbSMika Westerberg module_exit(chv_pinctrl_exit); 19086e08d6bbSMika Westerberg 19096e08d6bbSMika Westerberg MODULE_AUTHOR("Mika Westerberg <mika.westerberg@linux.intel.com>"); 19106e08d6bbSMika Westerberg MODULE_DESCRIPTION("Intel Cherryview/Braswell pinctrl driver"); 19116e08d6bbSMika Westerberg MODULE_LICENSE("GPL v2"); 1912