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-altera-a10sr.c (2988B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/*
      3 *  Copyright Intel Corporation (C) 2014-2016. All Rights Reserved
      4 *
      5 * GPIO driver for  Altera Arria10 MAX5 System Resource Chip
      6 *
      7 * Adapted from gpio-tps65910.c
      8 */
      9
     10#include <linux/gpio/driver.h>
     11#include <linux/mfd/altera-a10sr.h>
     12#include <linux/module.h>
     13#include <linux/property.h>
     14
     15/**
     16 * struct altr_a10sr_gpio - Altera Max5 GPIO device private data structure
     17 * @gp:   : instance of the gpio_chip
     18 * @regmap: the regmap from the parent device.
     19 */
     20struct altr_a10sr_gpio {
     21	struct gpio_chip gp;
     22	struct regmap *regmap;
     23};
     24
     25static int altr_a10sr_gpio_get(struct gpio_chip *chip, unsigned int offset)
     26{
     27	struct altr_a10sr_gpio *gpio = gpiochip_get_data(chip);
     28	int ret, val;
     29
     30	ret = regmap_read(gpio->regmap, ALTR_A10SR_PBDSW_REG, &val);
     31	if (ret < 0)
     32		return ret;
     33
     34	return !!(val & BIT(offset - ALTR_A10SR_LED_VALID_SHIFT));
     35}
     36
     37static void altr_a10sr_gpio_set(struct gpio_chip *chip, unsigned int offset,
     38				int value)
     39{
     40	struct altr_a10sr_gpio *gpio = gpiochip_get_data(chip);
     41
     42	regmap_update_bits(gpio->regmap, ALTR_A10SR_LED_REG,
     43			   BIT(ALTR_A10SR_LED_VALID_SHIFT + offset),
     44			   value ? BIT(ALTR_A10SR_LED_VALID_SHIFT + offset)
     45			   : 0);
     46}
     47
     48static int altr_a10sr_gpio_direction_input(struct gpio_chip *gc,
     49					   unsigned int nr)
     50{
     51	if (nr < (ALTR_A10SR_IN_VALID_RANGE_LO - ALTR_A10SR_LED_VALID_SHIFT))
     52		return -EINVAL;
     53
     54	return 0;
     55}
     56
     57static int altr_a10sr_gpio_direction_output(struct gpio_chip *gc,
     58					    unsigned int nr, int value)
     59{
     60	if (nr > (ALTR_A10SR_OUT_VALID_RANGE_HI - ALTR_A10SR_LED_VALID_SHIFT))
     61		return -EINVAL;
     62
     63	altr_a10sr_gpio_set(gc, nr, value);
     64	return 0;
     65}
     66
     67static const struct gpio_chip altr_a10sr_gc = {
     68	.label = "altr_a10sr_gpio",
     69	.owner = THIS_MODULE,
     70	.get = altr_a10sr_gpio_get,
     71	.set = altr_a10sr_gpio_set,
     72	.direction_input = altr_a10sr_gpio_direction_input,
     73	.direction_output = altr_a10sr_gpio_direction_output,
     74	.can_sleep = true,
     75	.ngpio = 12,
     76	.base = -1,
     77};
     78
     79static int altr_a10sr_gpio_probe(struct platform_device *pdev)
     80{
     81	struct altr_a10sr_gpio *gpio;
     82	struct altr_a10sr *a10sr = dev_get_drvdata(pdev->dev.parent);
     83
     84	gpio = devm_kzalloc(&pdev->dev, sizeof(*gpio), GFP_KERNEL);
     85	if (!gpio)
     86		return -ENOMEM;
     87
     88	gpio->regmap = a10sr->regmap;
     89
     90	gpio->gp = altr_a10sr_gc;
     91	gpio->gp.parent = pdev->dev.parent;
     92	gpio->gp.fwnode = dev_fwnode(&pdev->dev);
     93
     94	return devm_gpiochip_add_data(&pdev->dev, &gpio->gp, gpio);
     95}
     96
     97static const struct of_device_id altr_a10sr_gpio_of_match[] = {
     98	{ .compatible = "altr,a10sr-gpio" },
     99	{ },
    100};
    101MODULE_DEVICE_TABLE(of, altr_a10sr_gpio_of_match);
    102
    103static struct platform_driver altr_a10sr_gpio_driver = {
    104	.probe = altr_a10sr_gpio_probe,
    105	.driver = {
    106		.name	= "altr_a10sr_gpio",
    107		.of_match_table = of_match_ptr(altr_a10sr_gpio_of_match),
    108	},
    109};
    110module_platform_driver(altr_a10sr_gpio_driver);
    111
    112MODULE_LICENSE("GPL v2");
    113MODULE_AUTHOR("Thor Thayer <tthayer@opensource.altera.com>");
    114MODULE_DESCRIPTION("Altera Arria10 System Resource Chip GPIO");