cachepc-linux

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

pinctrl-as3722.c (17629B)


      1/*
      2 * ams AS3722 pin control and GPIO driver.
      3 *
      4 * Copyright (c) 2013, NVIDIA Corporation.
      5 *
      6 * Author: Laxman Dewangan <ldewangan@nvidia.com>
      7 *
      8 * This program is free software; you can redistribute it and/or
      9 * modify it under the terms of the GNU General Public License as
     10 * published by the Free Software Foundation version 2.
     11 *
     12 * This program is distributed "as is" WITHOUT ANY WARRANTY of any kind,
     13 * whether express or implied; without even the implied warranty of
     14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     15 * General Public License for more details.
     16 *
     17 * You should have received a copy of the GNU General Public License
     18 * along with this program; if not, write to the Free Software
     19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
     20 * 02111-1307, USA
     21 */
     22
     23#include <linux/delay.h>
     24#include <linux/gpio/driver.h>
     25#include <linux/kernel.h>
     26#include <linux/mod_devicetable.h>
     27#include <linux/module.h>
     28#include <linux/mfd/as3722.h>
     29#include <linux/platform_device.h>
     30#include <linux/pm.h>
     31#include <linux/property.h>
     32#include <linux/slab.h>
     33
     34#include <linux/pinctrl/consumer.h>
     35#include <linux/pinctrl/machine.h>
     36#include <linux/pinctrl/pinctrl.h>
     37#include <linux/pinctrl/pinconf-generic.h>
     38#include <linux/pinctrl/pinconf.h>
     39#include <linux/pinctrl/pinmux.h>
     40
     41#include "core.h"
     42#include "pinconf.h"
     43#include "pinctrl-utils.h"
     44
     45#define AS3722_PIN_GPIO0		0
     46#define AS3722_PIN_GPIO1		1
     47#define AS3722_PIN_GPIO2		2
     48#define AS3722_PIN_GPIO3		3
     49#define AS3722_PIN_GPIO4		4
     50#define AS3722_PIN_GPIO5		5
     51#define AS3722_PIN_GPIO6		6
     52#define AS3722_PIN_GPIO7		7
     53#define AS3722_PIN_NUM			(AS3722_PIN_GPIO7 + 1)
     54
     55#define AS3722_GPIO_MODE_PULL_UP           BIT(PIN_CONFIG_BIAS_PULL_UP)
     56#define AS3722_GPIO_MODE_PULL_DOWN         BIT(PIN_CONFIG_BIAS_PULL_DOWN)
     57#define AS3722_GPIO_MODE_HIGH_IMPED        BIT(PIN_CONFIG_BIAS_HIGH_IMPEDANCE)
     58#define AS3722_GPIO_MODE_OPEN_DRAIN        BIT(PIN_CONFIG_DRIVE_OPEN_DRAIN)
     59
     60struct as3722_pin_function {
     61	const char *name;
     62	const char * const *groups;
     63	unsigned ngroups;
     64	int mux_option;
     65};
     66
     67struct as3722_gpio_pin_control {
     68	unsigned mode_prop;
     69	int io_function;
     70};
     71
     72struct as3722_pingroup {
     73	const char *name;
     74	const unsigned pins[1];
     75	unsigned npins;
     76};
     77
     78struct as3722_pctrl_info {
     79	struct device *dev;
     80	struct pinctrl_dev *pctl;
     81	struct as3722 *as3722;
     82	struct gpio_chip gpio_chip;
     83	int pins_current_opt[AS3722_PIN_NUM];
     84	const struct as3722_pin_function *functions;
     85	unsigned num_functions;
     86	const struct as3722_pingroup *pin_groups;
     87	int num_pin_groups;
     88	const struct pinctrl_pin_desc *pins;
     89	unsigned num_pins;
     90	struct as3722_gpio_pin_control gpio_control[AS3722_PIN_NUM];
     91};
     92
     93static const struct pinctrl_pin_desc as3722_pins_desc[] = {
     94	PINCTRL_PIN(AS3722_PIN_GPIO0, "gpio0"),
     95	PINCTRL_PIN(AS3722_PIN_GPIO1, "gpio1"),
     96	PINCTRL_PIN(AS3722_PIN_GPIO2, "gpio2"),
     97	PINCTRL_PIN(AS3722_PIN_GPIO3, "gpio3"),
     98	PINCTRL_PIN(AS3722_PIN_GPIO4, "gpio4"),
     99	PINCTRL_PIN(AS3722_PIN_GPIO5, "gpio5"),
    100	PINCTRL_PIN(AS3722_PIN_GPIO6, "gpio6"),
    101	PINCTRL_PIN(AS3722_PIN_GPIO7, "gpio7"),
    102};
    103
    104static const char * const gpio_groups[] = {
    105	"gpio0",
    106	"gpio1",
    107	"gpio2",
    108	"gpio3",
    109	"gpio4",
    110	"gpio5",
    111	"gpio6",
    112	"gpio7",
    113};
    114
    115enum as3722_pinmux_option {
    116	AS3722_PINMUX_GPIO			= 0,
    117	AS3722_PINMUX_INTERRUPT_OUT		= 1,
    118	AS3722_PINMUX_VSUB_VBAT_UNDEB_LOW_OUT	= 2,
    119	AS3722_PINMUX_GPIO_INTERRUPT		= 3,
    120	AS3722_PINMUX_PWM_INPUT			= 4,
    121	AS3722_PINMUX_VOLTAGE_IN_STBY		= 5,
    122	AS3722_PINMUX_OC_PG_SD0			= 6,
    123	AS3722_PINMUX_PG_OUT			= 7,
    124	AS3722_PINMUX_CLK32K_OUT		= 8,
    125	AS3722_PINMUX_WATCHDOG_INPUT		= 9,
    126	AS3722_PINMUX_SOFT_RESET_IN		= 11,
    127	AS3722_PINMUX_PWM_OUTPUT		= 12,
    128	AS3722_PINMUX_VSUB_VBAT_LOW_DEB_OUT	= 13,
    129	AS3722_PINMUX_OC_PG_SD6			= 14,
    130};
    131
    132#define FUNCTION_GROUP(fname, mux)			\
    133	{						\
    134		.name = #fname,				\
    135		.groups = gpio_groups,			\
    136		.ngroups = ARRAY_SIZE(gpio_groups),	\
    137		.mux_option = AS3722_PINMUX_##mux,	\
    138	}
    139
    140static const struct as3722_pin_function as3722_pin_function[] = {
    141	FUNCTION_GROUP(gpio, GPIO),
    142	FUNCTION_GROUP(interrupt-out, INTERRUPT_OUT),
    143	FUNCTION_GROUP(gpio-in-interrupt, GPIO_INTERRUPT),
    144	FUNCTION_GROUP(vsup-vbat-low-undebounce-out, VSUB_VBAT_UNDEB_LOW_OUT),
    145	FUNCTION_GROUP(vsup-vbat-low-debounce-out, VSUB_VBAT_LOW_DEB_OUT),
    146	FUNCTION_GROUP(voltage-in-standby, VOLTAGE_IN_STBY),
    147	FUNCTION_GROUP(oc-pg-sd0, OC_PG_SD0),
    148	FUNCTION_GROUP(oc-pg-sd6, OC_PG_SD6),
    149	FUNCTION_GROUP(powergood-out, PG_OUT),
    150	FUNCTION_GROUP(pwm-in, PWM_INPUT),
    151	FUNCTION_GROUP(pwm-out, PWM_OUTPUT),
    152	FUNCTION_GROUP(clk32k-out, CLK32K_OUT),
    153	FUNCTION_GROUP(watchdog-in, WATCHDOG_INPUT),
    154	FUNCTION_GROUP(soft-reset-in, SOFT_RESET_IN),
    155};
    156
    157#define AS3722_PINGROUP(pg_name, pin_id) \
    158	{								\
    159		.name = #pg_name,					\
    160		.pins = {AS3722_PIN_##pin_id},				\
    161		.npins = 1,						\
    162	}
    163
    164static const struct as3722_pingroup as3722_pingroups[] = {
    165	AS3722_PINGROUP(gpio0,	GPIO0),
    166	AS3722_PINGROUP(gpio1,	GPIO1),
    167	AS3722_PINGROUP(gpio2,	GPIO2),
    168	AS3722_PINGROUP(gpio3,	GPIO3),
    169	AS3722_PINGROUP(gpio4,	GPIO4),
    170	AS3722_PINGROUP(gpio5,	GPIO5),
    171	AS3722_PINGROUP(gpio6,	GPIO6),
    172	AS3722_PINGROUP(gpio7,	GPIO7),
    173};
    174
    175static int as3722_pinctrl_get_groups_count(struct pinctrl_dev *pctldev)
    176{
    177	struct as3722_pctrl_info *as_pci = pinctrl_dev_get_drvdata(pctldev);
    178
    179	return as_pci->num_pin_groups;
    180}
    181
    182static const char *as3722_pinctrl_get_group_name(struct pinctrl_dev *pctldev,
    183		unsigned group)
    184{
    185	struct as3722_pctrl_info *as_pci = pinctrl_dev_get_drvdata(pctldev);
    186
    187	return as_pci->pin_groups[group].name;
    188}
    189
    190static int as3722_pinctrl_get_group_pins(struct pinctrl_dev *pctldev,
    191		unsigned group, const unsigned **pins, unsigned *num_pins)
    192{
    193	struct as3722_pctrl_info *as_pci = pinctrl_dev_get_drvdata(pctldev);
    194
    195	*pins = as_pci->pin_groups[group].pins;
    196	*num_pins = as_pci->pin_groups[group].npins;
    197	return 0;
    198}
    199
    200static const struct pinctrl_ops as3722_pinctrl_ops = {
    201	.get_groups_count = as3722_pinctrl_get_groups_count,
    202	.get_group_name = as3722_pinctrl_get_group_name,
    203	.get_group_pins = as3722_pinctrl_get_group_pins,
    204	.dt_node_to_map = pinconf_generic_dt_node_to_map_pin,
    205	.dt_free_map = pinctrl_utils_free_map,
    206};
    207
    208static int as3722_pinctrl_get_funcs_count(struct pinctrl_dev *pctldev)
    209{
    210	struct as3722_pctrl_info *as_pci = pinctrl_dev_get_drvdata(pctldev);
    211
    212	return as_pci->num_functions;
    213}
    214
    215static const char *as3722_pinctrl_get_func_name(struct pinctrl_dev *pctldev,
    216			unsigned function)
    217{
    218	struct as3722_pctrl_info *as_pci = pinctrl_dev_get_drvdata(pctldev);
    219
    220	return as_pci->functions[function].name;
    221}
    222
    223static int as3722_pinctrl_get_func_groups(struct pinctrl_dev *pctldev,
    224		unsigned function, const char * const **groups,
    225		unsigned * const num_groups)
    226{
    227	struct as3722_pctrl_info *as_pci = pinctrl_dev_get_drvdata(pctldev);
    228
    229	*groups = as_pci->functions[function].groups;
    230	*num_groups = as_pci->functions[function].ngroups;
    231	return 0;
    232}
    233
    234static int as3722_pinctrl_set(struct pinctrl_dev *pctldev, unsigned function,
    235		unsigned group)
    236{
    237	struct as3722_pctrl_info *as_pci = pinctrl_dev_get_drvdata(pctldev);
    238	int gpio_cntr_reg = AS3722_GPIOn_CONTROL_REG(group);
    239	u8 val = AS3722_GPIO_IOSF_VAL(as_pci->functions[function].mux_option);
    240	int ret;
    241
    242	dev_dbg(as_pci->dev, "%s(): GPIO %u pin to function %u and val %u\n",
    243		__func__, group, function, val);
    244
    245	ret = as3722_update_bits(as_pci->as3722, gpio_cntr_reg,
    246			AS3722_GPIO_IOSF_MASK, val);
    247	if (ret < 0) {
    248		dev_err(as_pci->dev, "GPIO%d_CTRL_REG update failed %d\n",
    249			group, ret);
    250		return ret;
    251	}
    252	as_pci->gpio_control[group].io_function = function;
    253
    254	switch (val) {
    255	case AS3722_GPIO_IOSF_SD0_OUT:
    256	case AS3722_GPIO_IOSF_PWR_GOOD_OUT:
    257	case AS3722_GPIO_IOSF_Q32K_OUT:
    258	case AS3722_GPIO_IOSF_PWM_OUT:
    259	case AS3722_GPIO_IOSF_SD6_LOW_VOLT_LOW:
    260		ret = as3722_update_bits(as_pci->as3722, gpio_cntr_reg,
    261			AS3722_GPIO_MODE_MASK, AS3722_GPIO_MODE_OUTPUT_VDDH);
    262		if (ret < 0) {
    263			dev_err(as_pci->dev, "GPIO%d_CTRL update failed %d\n",
    264				group, ret);
    265			return ret;
    266		}
    267		as_pci->gpio_control[group].mode_prop =
    268				AS3722_GPIO_MODE_OUTPUT_VDDH;
    269		break;
    270	default:
    271		break;
    272	}
    273	return ret;
    274}
    275
    276static int as3722_pinctrl_gpio_get_mode(unsigned gpio_mode_prop, bool input)
    277{
    278	if (gpio_mode_prop & AS3722_GPIO_MODE_HIGH_IMPED)
    279		return -EINVAL;
    280
    281	if (gpio_mode_prop & AS3722_GPIO_MODE_OPEN_DRAIN) {
    282		if (gpio_mode_prop & AS3722_GPIO_MODE_PULL_UP)
    283			return AS3722_GPIO_MODE_IO_OPEN_DRAIN_PULL_UP;
    284		return AS3722_GPIO_MODE_IO_OPEN_DRAIN;
    285	}
    286	if (input) {
    287		if (gpio_mode_prop & AS3722_GPIO_MODE_PULL_UP)
    288			return AS3722_GPIO_MODE_INPUT_PULL_UP;
    289		else if (gpio_mode_prop & AS3722_GPIO_MODE_PULL_DOWN)
    290			return AS3722_GPIO_MODE_INPUT_PULL_DOWN;
    291		return AS3722_GPIO_MODE_INPUT;
    292	}
    293	if (gpio_mode_prop & AS3722_GPIO_MODE_PULL_DOWN)
    294		return AS3722_GPIO_MODE_OUTPUT_VDDL;
    295	return AS3722_GPIO_MODE_OUTPUT_VDDH;
    296}
    297
    298static int as3722_pinctrl_gpio_request_enable(struct pinctrl_dev *pctldev,
    299		struct pinctrl_gpio_range *range, unsigned offset)
    300{
    301	struct as3722_pctrl_info *as_pci = pinctrl_dev_get_drvdata(pctldev);
    302
    303	if (as_pci->gpio_control[offset].io_function)
    304		return -EBUSY;
    305	return 0;
    306}
    307
    308static int as3722_pinctrl_gpio_set_direction(struct pinctrl_dev *pctldev,
    309		struct pinctrl_gpio_range *range, unsigned offset, bool input)
    310{
    311	struct as3722_pctrl_info *as_pci = pinctrl_dev_get_drvdata(pctldev);
    312	struct as3722 *as3722 = as_pci->as3722;
    313	int mode;
    314
    315	mode = as3722_pinctrl_gpio_get_mode(
    316			as_pci->gpio_control[offset].mode_prop, input);
    317	if (mode < 0) {
    318		dev_err(as_pci->dev, "%s direction for GPIO %d not supported\n",
    319			(input) ? "Input" : "Output", offset);
    320		return mode;
    321	}
    322
    323	return as3722_update_bits(as3722, AS3722_GPIOn_CONTROL_REG(offset),
    324				AS3722_GPIO_MODE_MASK, mode);
    325}
    326
    327static const struct pinmux_ops as3722_pinmux_ops = {
    328	.get_functions_count	= as3722_pinctrl_get_funcs_count,
    329	.get_function_name	= as3722_pinctrl_get_func_name,
    330	.get_function_groups	= as3722_pinctrl_get_func_groups,
    331	.set_mux		= as3722_pinctrl_set,
    332	.gpio_request_enable	= as3722_pinctrl_gpio_request_enable,
    333	.gpio_set_direction	= as3722_pinctrl_gpio_set_direction,
    334};
    335
    336static int as3722_pinconf_get(struct pinctrl_dev *pctldev,
    337			unsigned pin, unsigned long *config)
    338{
    339	struct as3722_pctrl_info *as_pci = pinctrl_dev_get_drvdata(pctldev);
    340	enum pin_config_param param = pinconf_to_config_param(*config);
    341	int arg = 0;
    342	u16 prop;
    343
    344	switch (param) {
    345	case PIN_CONFIG_BIAS_DISABLE:
    346		prop = AS3722_GPIO_MODE_PULL_UP |
    347				AS3722_GPIO_MODE_PULL_DOWN;
    348		if (!(as_pci->gpio_control[pin].mode_prop & prop))
    349			arg = 1;
    350		prop = 0;
    351		break;
    352
    353	case PIN_CONFIG_BIAS_PULL_UP:
    354		prop = AS3722_GPIO_MODE_PULL_UP;
    355		break;
    356
    357	case PIN_CONFIG_BIAS_PULL_DOWN:
    358		prop = AS3722_GPIO_MODE_PULL_DOWN;
    359		break;
    360
    361	case PIN_CONFIG_DRIVE_OPEN_DRAIN:
    362		prop = AS3722_GPIO_MODE_OPEN_DRAIN;
    363		break;
    364
    365	case PIN_CONFIG_BIAS_HIGH_IMPEDANCE:
    366		prop = AS3722_GPIO_MODE_HIGH_IMPED;
    367		break;
    368
    369	default:
    370		dev_err(as_pci->dev, "Properties not supported\n");
    371		return -ENOTSUPP;
    372	}
    373
    374	if (as_pci->gpio_control[pin].mode_prop & prop)
    375		arg = 1;
    376
    377	*config = pinconf_to_config_packed(param, (u16)arg);
    378	return 0;
    379}
    380
    381static int as3722_pinconf_set(struct pinctrl_dev *pctldev,
    382			unsigned pin, unsigned long *configs,
    383			unsigned num_configs)
    384{
    385	struct as3722_pctrl_info *as_pci = pinctrl_dev_get_drvdata(pctldev);
    386	enum pin_config_param param;
    387	int mode_prop;
    388	int i;
    389
    390	for (i = 0; i < num_configs; i++) {
    391		param = pinconf_to_config_param(configs[i]);
    392		mode_prop = as_pci->gpio_control[pin].mode_prop;
    393
    394		switch (param) {
    395		case PIN_CONFIG_BIAS_PULL_PIN_DEFAULT:
    396			break;
    397
    398		case PIN_CONFIG_BIAS_DISABLE:
    399			mode_prop &= ~(AS3722_GPIO_MODE_PULL_UP |
    400					AS3722_GPIO_MODE_PULL_DOWN);
    401			break;
    402		case PIN_CONFIG_BIAS_PULL_UP:
    403			mode_prop |= AS3722_GPIO_MODE_PULL_UP;
    404			break;
    405
    406		case PIN_CONFIG_BIAS_PULL_DOWN:
    407			mode_prop |= AS3722_GPIO_MODE_PULL_DOWN;
    408			break;
    409
    410		case PIN_CONFIG_BIAS_HIGH_IMPEDANCE:
    411			mode_prop |= AS3722_GPIO_MODE_HIGH_IMPED;
    412			break;
    413
    414		case PIN_CONFIG_DRIVE_OPEN_DRAIN:
    415			mode_prop |= AS3722_GPIO_MODE_OPEN_DRAIN;
    416			break;
    417
    418		default:
    419			dev_err(as_pci->dev, "Properties not supported\n");
    420			return -ENOTSUPP;
    421		}
    422
    423		as_pci->gpio_control[pin].mode_prop = mode_prop;
    424	}
    425	return 0;
    426}
    427
    428static const struct pinconf_ops as3722_pinconf_ops = {
    429	.pin_config_get = as3722_pinconf_get,
    430	.pin_config_set = as3722_pinconf_set,
    431};
    432
    433static struct pinctrl_desc as3722_pinctrl_desc = {
    434	.pctlops = &as3722_pinctrl_ops,
    435	.pmxops = &as3722_pinmux_ops,
    436	.confops = &as3722_pinconf_ops,
    437	.owner = THIS_MODULE,
    438};
    439
    440static int as3722_gpio_get(struct gpio_chip *chip, unsigned offset)
    441{
    442	struct as3722_pctrl_info *as_pci = gpiochip_get_data(chip);
    443	struct as3722 *as3722 = as_pci->as3722;
    444	int ret;
    445	u32 reg;
    446	u32 control;
    447	u32 val;
    448	int mode;
    449	int invert_enable;
    450
    451	ret = as3722_read(as3722, AS3722_GPIOn_CONTROL_REG(offset), &control);
    452	if (ret < 0) {
    453		dev_err(as_pci->dev,
    454			"GPIO_CONTROL%d_REG read failed: %d\n", offset, ret);
    455		return ret;
    456	}
    457
    458	invert_enable = !!(control & AS3722_GPIO_INV);
    459	mode = control & AS3722_GPIO_MODE_MASK;
    460	switch (mode) {
    461	case AS3722_GPIO_MODE_INPUT:
    462	case AS3722_GPIO_MODE_INPUT_PULL_UP:
    463	case AS3722_GPIO_MODE_INPUT_PULL_DOWN:
    464	case AS3722_GPIO_MODE_IO_OPEN_DRAIN:
    465	case AS3722_GPIO_MODE_IO_OPEN_DRAIN_PULL_UP:
    466		reg = AS3722_GPIO_SIGNAL_IN_REG;
    467		break;
    468	case AS3722_GPIO_MODE_OUTPUT_VDDH:
    469	case AS3722_GPIO_MODE_OUTPUT_VDDL:
    470		reg = AS3722_GPIO_SIGNAL_OUT_REG;
    471		break;
    472	default:
    473		return -EINVAL;
    474	}
    475
    476	ret = as3722_read(as3722, reg, &val);
    477	if (ret < 0) {
    478		dev_err(as_pci->dev,
    479			"GPIO_SIGNAL_IN_REG read failed: %d\n", ret);
    480		return ret;
    481	}
    482
    483	val = !!(val & AS3722_GPIOn_SIGNAL(offset));
    484	return (invert_enable) ? !val : val;
    485}
    486
    487static void as3722_gpio_set(struct gpio_chip *chip, unsigned offset,
    488		int value)
    489{
    490	struct as3722_pctrl_info *as_pci = gpiochip_get_data(chip);
    491	struct as3722 *as3722 = as_pci->as3722;
    492	int en_invert;
    493	u32 val;
    494	int ret;
    495
    496	ret = as3722_read(as3722, AS3722_GPIOn_CONTROL_REG(offset), &val);
    497	if (ret < 0) {
    498		dev_err(as_pci->dev,
    499			"GPIO_CONTROL%d_REG read failed: %d\n", offset, ret);
    500		return;
    501	}
    502	en_invert = !!(val & AS3722_GPIO_INV);
    503
    504	if (value)
    505		val = (en_invert) ? 0 : AS3722_GPIOn_SIGNAL(offset);
    506	else
    507		val = (en_invert) ? AS3722_GPIOn_SIGNAL(offset) : 0;
    508
    509	ret = as3722_update_bits(as3722, AS3722_GPIO_SIGNAL_OUT_REG,
    510			AS3722_GPIOn_SIGNAL(offset), val);
    511	if (ret < 0)
    512		dev_err(as_pci->dev,
    513			"GPIO_SIGNAL_OUT_REG update failed: %d\n", ret);
    514}
    515
    516static int as3722_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
    517{
    518	return pinctrl_gpio_direction_input(chip->base + offset);
    519}
    520
    521static int as3722_gpio_direction_output(struct gpio_chip *chip,
    522		unsigned offset, int value)
    523{
    524	as3722_gpio_set(chip, offset, value);
    525	return pinctrl_gpio_direction_output(chip->base + offset);
    526}
    527
    528static int as3722_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
    529{
    530	struct as3722_pctrl_info *as_pci = gpiochip_get_data(chip);
    531
    532	return as3722_irq_get_virq(as_pci->as3722, offset);
    533}
    534
    535static const struct gpio_chip as3722_gpio_chip = {
    536	.label			= "as3722-gpio",
    537	.owner			= THIS_MODULE,
    538	.request		= gpiochip_generic_request,
    539	.free			= gpiochip_generic_free,
    540	.get			= as3722_gpio_get,
    541	.set			= as3722_gpio_set,
    542	.direction_input	= as3722_gpio_direction_input,
    543	.direction_output	= as3722_gpio_direction_output,
    544	.to_irq			= as3722_gpio_to_irq,
    545	.can_sleep		= true,
    546	.ngpio			= AS3722_PIN_NUM,
    547	.base			= -1,
    548};
    549
    550static int as3722_pinctrl_probe(struct platform_device *pdev)
    551{
    552	struct as3722_pctrl_info *as_pci;
    553	int ret;
    554
    555	device_set_node(&pdev->dev, dev_fwnode(pdev->dev.parent));
    556
    557	as_pci = devm_kzalloc(&pdev->dev, sizeof(*as_pci), GFP_KERNEL);
    558	if (!as_pci)
    559		return -ENOMEM;
    560
    561	as_pci->dev = &pdev->dev;
    562	as_pci->as3722 = dev_get_drvdata(pdev->dev.parent);
    563	platform_set_drvdata(pdev, as_pci);
    564
    565	as_pci->pins = as3722_pins_desc;
    566	as_pci->num_pins = ARRAY_SIZE(as3722_pins_desc);
    567	as_pci->functions = as3722_pin_function;
    568	as_pci->num_functions = ARRAY_SIZE(as3722_pin_function);
    569	as_pci->pin_groups = as3722_pingroups;
    570	as_pci->num_pin_groups = ARRAY_SIZE(as3722_pingroups);
    571	as3722_pinctrl_desc.name = dev_name(&pdev->dev);
    572	as3722_pinctrl_desc.pins = as3722_pins_desc;
    573	as3722_pinctrl_desc.npins = ARRAY_SIZE(as3722_pins_desc);
    574	as_pci->pctl = devm_pinctrl_register(&pdev->dev, &as3722_pinctrl_desc,
    575					     as_pci);
    576	if (IS_ERR(as_pci->pctl)) {
    577		dev_err(&pdev->dev, "Couldn't register pinctrl driver\n");
    578		return PTR_ERR(as_pci->pctl);
    579	}
    580
    581	as_pci->gpio_chip = as3722_gpio_chip;
    582	as_pci->gpio_chip.parent = &pdev->dev;
    583	ret = gpiochip_add_data(&as_pci->gpio_chip, as_pci);
    584	if (ret < 0) {
    585		dev_err(&pdev->dev, "Couldn't register gpiochip, %d\n", ret);
    586		return ret;
    587	}
    588
    589	ret = gpiochip_add_pin_range(&as_pci->gpio_chip, dev_name(&pdev->dev),
    590				0, 0, AS3722_PIN_NUM);
    591	if (ret < 0) {
    592		dev_err(&pdev->dev, "Couldn't add pin range, %d\n", ret);
    593		goto fail_range_add;
    594	}
    595
    596	return 0;
    597
    598fail_range_add:
    599	gpiochip_remove(&as_pci->gpio_chip);
    600	return ret;
    601}
    602
    603static int as3722_pinctrl_remove(struct platform_device *pdev)
    604{
    605	struct as3722_pctrl_info *as_pci = platform_get_drvdata(pdev);
    606
    607	gpiochip_remove(&as_pci->gpio_chip);
    608	return 0;
    609}
    610
    611static const struct of_device_id as3722_pinctrl_of_match[] = {
    612	{ .compatible = "ams,as3722-pinctrl", },
    613	{ },
    614};
    615MODULE_DEVICE_TABLE(of, as3722_pinctrl_of_match);
    616
    617static struct platform_driver as3722_pinctrl_driver = {
    618	.driver = {
    619		.name = "as3722-pinctrl",
    620		.of_match_table = as3722_pinctrl_of_match,
    621	},
    622	.probe = as3722_pinctrl_probe,
    623	.remove = as3722_pinctrl_remove,
    624};
    625module_platform_driver(as3722_pinctrl_driver);
    626
    627MODULE_ALIAS("platform:as3722-pinctrl");
    628MODULE_DESCRIPTION("AS3722 pin control and GPIO driver");
    629MODULE_AUTHOR("Laxman Dewangan<ldewangan@nvidia.com>");
    630MODULE_LICENSE("GPL v2");