cachepc-linux

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

gpio-max77620.c (9816B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/*
      3 * MAXIM MAX77620 GPIO driver
      4 *
      5 * Copyright (c) 2016, NVIDIA CORPORATION.  All rights reserved.
      6 */
      7
      8#include <linux/gpio/driver.h>
      9#include <linux/interrupt.h>
     10#include <linux/mfd/max77620.h>
     11#include <linux/module.h>
     12#include <linux/platform_device.h>
     13#include <linux/regmap.h>
     14
     15#define GPIO_REG_ADDR(offset) (MAX77620_REG_GPIO0 + offset)
     16
     17struct max77620_gpio {
     18	struct gpio_chip	gpio_chip;
     19	struct regmap		*rmap;
     20	struct device		*dev;
     21	struct mutex		buslock; /* irq_bus_lock */
     22	unsigned int		irq_type[MAX77620_GPIO_NR];
     23	bool			irq_enabled[MAX77620_GPIO_NR];
     24};
     25
     26static irqreturn_t max77620_gpio_irqhandler(int irq, void *data)
     27{
     28	struct max77620_gpio *gpio = data;
     29	unsigned int value, offset;
     30	unsigned long pending;
     31	int err;
     32
     33	err = regmap_read(gpio->rmap, MAX77620_REG_IRQ_LVL2_GPIO, &value);
     34	if (err < 0) {
     35		dev_err(gpio->dev, "REG_IRQ_LVL2_GPIO read failed: %d\n", err);
     36		return IRQ_NONE;
     37	}
     38
     39	pending = value;
     40
     41	for_each_set_bit(offset, &pending, MAX77620_GPIO_NR) {
     42		unsigned int virq;
     43
     44		virq = irq_find_mapping(gpio->gpio_chip.irq.domain, offset);
     45		handle_nested_irq(virq);
     46	}
     47
     48	return IRQ_HANDLED;
     49}
     50
     51static void max77620_gpio_irq_mask(struct irq_data *data)
     52{
     53	struct gpio_chip *chip = irq_data_get_irq_chip_data(data);
     54	struct max77620_gpio *gpio = gpiochip_get_data(chip);
     55
     56	gpio->irq_enabled[data->hwirq] = false;
     57	gpiochip_disable_irq(chip, data->hwirq);
     58}
     59
     60static void max77620_gpio_irq_unmask(struct irq_data *data)
     61{
     62	struct gpio_chip *chip = irq_data_get_irq_chip_data(data);
     63	struct max77620_gpio *gpio = gpiochip_get_data(chip);
     64
     65	gpiochip_enable_irq(chip, data->hwirq);
     66	gpio->irq_enabled[data->hwirq] = true;
     67}
     68
     69static int max77620_gpio_set_irq_type(struct irq_data *data, unsigned int type)
     70{
     71	struct gpio_chip *chip = irq_data_get_irq_chip_data(data);
     72	struct max77620_gpio *gpio = gpiochip_get_data(chip);
     73	unsigned int irq_type;
     74
     75	switch (type) {
     76	case IRQ_TYPE_EDGE_RISING:
     77		irq_type = MAX77620_CNFG_GPIO_INT_RISING;
     78		break;
     79
     80	case IRQ_TYPE_EDGE_FALLING:
     81		irq_type = MAX77620_CNFG_GPIO_INT_FALLING;
     82		break;
     83
     84	case IRQ_TYPE_EDGE_BOTH:
     85		irq_type = MAX77620_CNFG_GPIO_INT_RISING |
     86			   MAX77620_CNFG_GPIO_INT_FALLING;
     87		break;
     88
     89	default:
     90		return -EINVAL;
     91	}
     92
     93	gpio->irq_type[data->hwirq] = irq_type;
     94
     95	return 0;
     96}
     97
     98static void max77620_gpio_bus_lock(struct irq_data *data)
     99{
    100	struct gpio_chip *chip = irq_data_get_irq_chip_data(data);
    101	struct max77620_gpio *gpio = gpiochip_get_data(chip);
    102
    103	mutex_lock(&gpio->buslock);
    104}
    105
    106static void max77620_gpio_bus_sync_unlock(struct irq_data *data)
    107{
    108	struct gpio_chip *chip = irq_data_get_irq_chip_data(data);
    109	struct max77620_gpio *gpio = gpiochip_get_data(chip);
    110	unsigned int value, offset = data->hwirq;
    111	int err;
    112
    113	value = gpio->irq_enabled[offset] ? gpio->irq_type[offset] : 0;
    114
    115	err = regmap_update_bits(gpio->rmap, GPIO_REG_ADDR(offset),
    116				 MAX77620_CNFG_GPIO_INT_MASK, value);
    117	if (err < 0)
    118		dev_err(chip->parent, "failed to update interrupt mask: %d\n",
    119			err);
    120
    121	mutex_unlock(&gpio->buslock);
    122}
    123
    124static const struct irq_chip max77620_gpio_irqchip = {
    125	.name		= "max77620-gpio",
    126	.irq_mask	= max77620_gpio_irq_mask,
    127	.irq_unmask	= max77620_gpio_irq_unmask,
    128	.irq_set_type	= max77620_gpio_set_irq_type,
    129	.irq_bus_lock	= max77620_gpio_bus_lock,
    130	.irq_bus_sync_unlock = max77620_gpio_bus_sync_unlock,
    131	.flags		= IRQCHIP_IMMUTABLE | IRQCHIP_MASK_ON_SUSPEND,
    132	GPIOCHIP_IRQ_RESOURCE_HELPERS,
    133};
    134
    135static int max77620_gpio_dir_input(struct gpio_chip *gc, unsigned int offset)
    136{
    137	struct max77620_gpio *mgpio = gpiochip_get_data(gc);
    138	int ret;
    139
    140	ret = regmap_update_bits(mgpio->rmap, GPIO_REG_ADDR(offset),
    141				 MAX77620_CNFG_GPIO_DIR_MASK,
    142				 MAX77620_CNFG_GPIO_DIR_INPUT);
    143	if (ret < 0)
    144		dev_err(mgpio->dev, "CNFG_GPIOx dir update failed: %d\n", ret);
    145
    146	return ret;
    147}
    148
    149static int max77620_gpio_get(struct gpio_chip *gc, unsigned int offset)
    150{
    151	struct max77620_gpio *mgpio = gpiochip_get_data(gc);
    152	unsigned int val;
    153	int ret;
    154
    155	ret = regmap_read(mgpio->rmap, GPIO_REG_ADDR(offset), &val);
    156	if (ret < 0) {
    157		dev_err(mgpio->dev, "CNFG_GPIOx read failed: %d\n", ret);
    158		return ret;
    159	}
    160
    161	if  (val & MAX77620_CNFG_GPIO_DIR_MASK)
    162		return !!(val & MAX77620_CNFG_GPIO_INPUT_VAL_MASK);
    163	else
    164		return !!(val & MAX77620_CNFG_GPIO_OUTPUT_VAL_MASK);
    165}
    166
    167static int max77620_gpio_dir_output(struct gpio_chip *gc, unsigned int offset,
    168				    int value)
    169{
    170	struct max77620_gpio *mgpio = gpiochip_get_data(gc);
    171	u8 val;
    172	int ret;
    173
    174	val = (value) ? MAX77620_CNFG_GPIO_OUTPUT_VAL_HIGH :
    175				MAX77620_CNFG_GPIO_OUTPUT_VAL_LOW;
    176
    177	ret = regmap_update_bits(mgpio->rmap, GPIO_REG_ADDR(offset),
    178				 MAX77620_CNFG_GPIO_OUTPUT_VAL_MASK, val);
    179	if (ret < 0) {
    180		dev_err(mgpio->dev, "CNFG_GPIOx val update failed: %d\n", ret);
    181		return ret;
    182	}
    183
    184	ret = regmap_update_bits(mgpio->rmap, GPIO_REG_ADDR(offset),
    185				 MAX77620_CNFG_GPIO_DIR_MASK,
    186				 MAX77620_CNFG_GPIO_DIR_OUTPUT);
    187	if (ret < 0)
    188		dev_err(mgpio->dev, "CNFG_GPIOx dir update failed: %d\n", ret);
    189
    190	return ret;
    191}
    192
    193static int max77620_gpio_set_debounce(struct max77620_gpio *mgpio,
    194				      unsigned int offset,
    195				      unsigned int debounce)
    196{
    197	u8 val;
    198	int ret;
    199
    200	switch (debounce) {
    201	case 0:
    202		val = MAX77620_CNFG_GPIO_DBNC_None;
    203		break;
    204	case 1 ... 8000:
    205		val = MAX77620_CNFG_GPIO_DBNC_8ms;
    206		break;
    207	case 8001 ... 16000:
    208		val = MAX77620_CNFG_GPIO_DBNC_16ms;
    209		break;
    210	case 16001 ... 32000:
    211		val = MAX77620_CNFG_GPIO_DBNC_32ms;
    212		break;
    213	default:
    214		dev_err(mgpio->dev, "Illegal value %u\n", debounce);
    215		return -EINVAL;
    216	}
    217
    218	ret = regmap_update_bits(mgpio->rmap, GPIO_REG_ADDR(offset),
    219				 MAX77620_CNFG_GPIO_DBNC_MASK, val);
    220	if (ret < 0)
    221		dev_err(mgpio->dev, "CNFG_GPIOx_DBNC update failed: %d\n", ret);
    222
    223	return ret;
    224}
    225
    226static void max77620_gpio_set(struct gpio_chip *gc, unsigned int offset,
    227			      int value)
    228{
    229	struct max77620_gpio *mgpio = gpiochip_get_data(gc);
    230	u8 val;
    231	int ret;
    232
    233	val = (value) ? MAX77620_CNFG_GPIO_OUTPUT_VAL_HIGH :
    234				MAX77620_CNFG_GPIO_OUTPUT_VAL_LOW;
    235
    236	ret = regmap_update_bits(mgpio->rmap, GPIO_REG_ADDR(offset),
    237				 MAX77620_CNFG_GPIO_OUTPUT_VAL_MASK, val);
    238	if (ret < 0)
    239		dev_err(mgpio->dev, "CNFG_GPIO_OUT update failed: %d\n", ret);
    240}
    241
    242static int max77620_gpio_set_config(struct gpio_chip *gc, unsigned int offset,
    243				    unsigned long config)
    244{
    245	struct max77620_gpio *mgpio = gpiochip_get_data(gc);
    246
    247	switch (pinconf_to_config_param(config)) {
    248	case PIN_CONFIG_DRIVE_OPEN_DRAIN:
    249		return regmap_update_bits(mgpio->rmap, GPIO_REG_ADDR(offset),
    250					  MAX77620_CNFG_GPIO_DRV_MASK,
    251					  MAX77620_CNFG_GPIO_DRV_OPENDRAIN);
    252	case PIN_CONFIG_DRIVE_PUSH_PULL:
    253		return regmap_update_bits(mgpio->rmap, GPIO_REG_ADDR(offset),
    254					  MAX77620_CNFG_GPIO_DRV_MASK,
    255					  MAX77620_CNFG_GPIO_DRV_PUSHPULL);
    256	case PIN_CONFIG_INPUT_DEBOUNCE:
    257		return max77620_gpio_set_debounce(mgpio, offset,
    258			pinconf_to_config_argument(config));
    259	default:
    260		break;
    261	}
    262
    263	return -ENOTSUPP;
    264}
    265
    266static int max77620_gpio_irq_init_hw(struct gpio_chip *gc)
    267{
    268	struct max77620_gpio *gpio = gpiochip_get_data(gc);
    269	unsigned int i;
    270	int err;
    271
    272	/*
    273	 * GPIO interrupts may be left ON after bootloader, hence let's
    274	 * pre-initialize hardware to the expected state by disabling all
    275	 * the interrupts.
    276	 */
    277	for (i = 0; i < MAX77620_GPIO_NR; i++) {
    278		err = regmap_update_bits(gpio->rmap, GPIO_REG_ADDR(i),
    279					 MAX77620_CNFG_GPIO_INT_MASK, 0);
    280		if (err < 0) {
    281			dev_err(gpio->dev,
    282				"failed to disable interrupt: %d\n", err);
    283			return err;
    284		}
    285	}
    286
    287	return 0;
    288}
    289
    290static int max77620_gpio_probe(struct platform_device *pdev)
    291{
    292	struct max77620_chip *chip =  dev_get_drvdata(pdev->dev.parent);
    293	struct max77620_gpio *mgpio;
    294	struct gpio_irq_chip *girq;
    295	unsigned int gpio_irq;
    296	int ret;
    297
    298	ret = platform_get_irq(pdev, 0);
    299	if (ret < 0)
    300		return ret;
    301
    302	gpio_irq = ret;
    303
    304	mgpio = devm_kzalloc(&pdev->dev, sizeof(*mgpio), GFP_KERNEL);
    305	if (!mgpio)
    306		return -ENOMEM;
    307
    308	mutex_init(&mgpio->buslock);
    309	mgpio->rmap = chip->rmap;
    310	mgpio->dev = &pdev->dev;
    311
    312	mgpio->gpio_chip.label = pdev->name;
    313	mgpio->gpio_chip.parent = pdev->dev.parent;
    314	mgpio->gpio_chip.direction_input = max77620_gpio_dir_input;
    315	mgpio->gpio_chip.get = max77620_gpio_get;
    316	mgpio->gpio_chip.direction_output = max77620_gpio_dir_output;
    317	mgpio->gpio_chip.set = max77620_gpio_set;
    318	mgpio->gpio_chip.set_config = max77620_gpio_set_config;
    319	mgpio->gpio_chip.ngpio = MAX77620_GPIO_NR;
    320	mgpio->gpio_chip.can_sleep = 1;
    321	mgpio->gpio_chip.base = -1;
    322
    323	girq = &mgpio->gpio_chip.irq;
    324	gpio_irq_chip_set_chip(girq, &max77620_gpio_irqchip);
    325	/* This will let us handle the parent IRQ in the driver */
    326	girq->parent_handler = NULL;
    327	girq->num_parents = 0;
    328	girq->parents = NULL;
    329	girq->default_type = IRQ_TYPE_NONE;
    330	girq->handler = handle_edge_irq;
    331	girq->init_hw = max77620_gpio_irq_init_hw;
    332	girq->threaded = true;
    333
    334	platform_set_drvdata(pdev, mgpio);
    335
    336	ret = devm_gpiochip_add_data(&pdev->dev, &mgpio->gpio_chip, mgpio);
    337	if (ret < 0) {
    338		dev_err(&pdev->dev, "gpio_init: Failed to add max77620_gpio\n");
    339		return ret;
    340	}
    341
    342	ret = devm_request_threaded_irq(&pdev->dev, gpio_irq, NULL,
    343					max77620_gpio_irqhandler, IRQF_ONESHOT,
    344					"max77620-gpio", mgpio);
    345	if (ret < 0) {
    346		dev_err(&pdev->dev, "failed to request IRQ: %d\n", ret);
    347		return ret;
    348	}
    349
    350	return 0;
    351}
    352
    353static const struct platform_device_id max77620_gpio_devtype[] = {
    354	{ .name = "max77620-gpio", },
    355	{ .name = "max20024-gpio", },
    356	{},
    357};
    358MODULE_DEVICE_TABLE(platform, max77620_gpio_devtype);
    359
    360static struct platform_driver max77620_gpio_driver = {
    361	.driver.name	= "max77620-gpio",
    362	.probe		= max77620_gpio_probe,
    363	.id_table	= max77620_gpio_devtype,
    364};
    365
    366module_platform_driver(max77620_gpio_driver);
    367
    368MODULE_DESCRIPTION("GPIO interface for MAX77620 and MAX20024 PMIC");
    369MODULE_AUTHOR("Laxman Dewangan <ldewangan@nvidia.com>");
    370MODULE_AUTHOR("Chaitanya Bandi <bandik@nvidia.com>");
    371MODULE_LICENSE("GPL v2");