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-tqmx86.c (9041B)


      1// SPDX-License-Identifier: GPL-2.0
      2/*
      3 * TQ-Systems TQMx86 PLD GPIO driver
      4 *
      5 * Based on vendor driver by:
      6 *   Vadim V.Vlasov <vvlasov@dev.rtsoft.ru>
      7 */
      8
      9#include <linux/bitops.h>
     10#include <linux/errno.h>
     11#include <linux/gpio/driver.h>
     12#include <linux/init.h>
     13#include <linux/interrupt.h>
     14#include <linux/kernel.h>
     15#include <linux/module.h>
     16#include <linux/platform_device.h>
     17#include <linux/pm_runtime.h>
     18#include <linux/slab.h>
     19
     20#define TQMX86_NGPIO	8
     21#define TQMX86_NGPO	4	/* 0-3 - output */
     22#define TQMX86_NGPI	4	/* 4-7 - input */
     23#define TQMX86_DIR_INPUT_MASK	0xf0	/* 0-3 - output, 4-7 - input */
     24
     25#define TQMX86_GPIODD	0	/* GPIO Data Direction Register */
     26#define TQMX86_GPIOD	1	/* GPIO Data Register */
     27#define TQMX86_GPIIC	3	/* GPI Interrupt Configuration Register */
     28#define TQMX86_GPIIS	4	/* GPI Interrupt Status Register */
     29
     30#define TQMX86_GPII_FALLING	BIT(0)
     31#define TQMX86_GPII_RISING	BIT(1)
     32#define TQMX86_GPII_MASK	(BIT(0) | BIT(1))
     33#define TQMX86_GPII_BITS	2
     34
     35struct tqmx86_gpio_data {
     36	struct gpio_chip	chip;
     37	struct irq_chip		irq_chip;
     38	void __iomem		*io_base;
     39	int			irq;
     40	raw_spinlock_t		spinlock;
     41	u8			irq_type[TQMX86_NGPI];
     42};
     43
     44static u8 tqmx86_gpio_read(struct tqmx86_gpio_data *gd, unsigned int reg)
     45{
     46	return ioread8(gd->io_base + reg);
     47}
     48
     49static void tqmx86_gpio_write(struct tqmx86_gpio_data *gd, u8 val,
     50			      unsigned int reg)
     51{
     52	iowrite8(val, gd->io_base + reg);
     53}
     54
     55static int tqmx86_gpio_get(struct gpio_chip *chip, unsigned int offset)
     56{
     57	struct tqmx86_gpio_data *gpio = gpiochip_get_data(chip);
     58
     59	return !!(tqmx86_gpio_read(gpio, TQMX86_GPIOD) & BIT(offset));
     60}
     61
     62static void tqmx86_gpio_set(struct gpio_chip *chip, unsigned int offset,
     63			    int value)
     64{
     65	struct tqmx86_gpio_data *gpio = gpiochip_get_data(chip);
     66	unsigned long flags;
     67	u8 val;
     68
     69	raw_spin_lock_irqsave(&gpio->spinlock, flags);
     70	val = tqmx86_gpio_read(gpio, TQMX86_GPIOD);
     71	if (value)
     72		val |= BIT(offset);
     73	else
     74		val &= ~BIT(offset);
     75	tqmx86_gpio_write(gpio, val, TQMX86_GPIOD);
     76	raw_spin_unlock_irqrestore(&gpio->spinlock, flags);
     77}
     78
     79static int tqmx86_gpio_direction_input(struct gpio_chip *chip,
     80				       unsigned int offset)
     81{
     82	/* Direction cannot be changed. Validate is an input. */
     83	if (BIT(offset) & TQMX86_DIR_INPUT_MASK)
     84		return 0;
     85	else
     86		return -EINVAL;
     87}
     88
     89static int tqmx86_gpio_direction_output(struct gpio_chip *chip,
     90					unsigned int offset,
     91					int value)
     92{
     93	/* Direction cannot be changed, validate is an output */
     94	if (BIT(offset) & TQMX86_DIR_INPUT_MASK)
     95		return -EINVAL;
     96
     97	tqmx86_gpio_set(chip, offset, value);
     98	return 0;
     99}
    100
    101static int tqmx86_gpio_get_direction(struct gpio_chip *chip,
    102				     unsigned int offset)
    103{
    104	if (TQMX86_DIR_INPUT_MASK & BIT(offset))
    105		return GPIO_LINE_DIRECTION_IN;
    106
    107	return GPIO_LINE_DIRECTION_OUT;
    108}
    109
    110static void tqmx86_gpio_irq_mask(struct irq_data *data)
    111{
    112	unsigned int offset = (data->hwirq - TQMX86_NGPO);
    113	struct tqmx86_gpio_data *gpio = gpiochip_get_data(
    114		irq_data_get_irq_chip_data(data));
    115	unsigned long flags;
    116	u8 gpiic, mask;
    117
    118	mask = TQMX86_GPII_MASK << (offset * TQMX86_GPII_BITS);
    119
    120	raw_spin_lock_irqsave(&gpio->spinlock, flags);
    121	gpiic = tqmx86_gpio_read(gpio, TQMX86_GPIIC);
    122	gpiic &= ~mask;
    123	tqmx86_gpio_write(gpio, gpiic, TQMX86_GPIIC);
    124	raw_spin_unlock_irqrestore(&gpio->spinlock, flags);
    125}
    126
    127static void tqmx86_gpio_irq_unmask(struct irq_data *data)
    128{
    129	unsigned int offset = (data->hwirq - TQMX86_NGPO);
    130	struct tqmx86_gpio_data *gpio = gpiochip_get_data(
    131		irq_data_get_irq_chip_data(data));
    132	unsigned long flags;
    133	u8 gpiic, mask;
    134
    135	mask = TQMX86_GPII_MASK << (offset * TQMX86_GPII_BITS);
    136
    137	raw_spin_lock_irqsave(&gpio->spinlock, flags);
    138	gpiic = tqmx86_gpio_read(gpio, TQMX86_GPIIC);
    139	gpiic &= ~mask;
    140	gpiic |= gpio->irq_type[offset] << (offset * TQMX86_GPII_BITS);
    141	tqmx86_gpio_write(gpio, gpiic, TQMX86_GPIIC);
    142	raw_spin_unlock_irqrestore(&gpio->spinlock, flags);
    143}
    144
    145static int tqmx86_gpio_irq_set_type(struct irq_data *data, unsigned int type)
    146{
    147	struct tqmx86_gpio_data *gpio = gpiochip_get_data(
    148		irq_data_get_irq_chip_data(data));
    149	unsigned int offset = (data->hwirq - TQMX86_NGPO);
    150	unsigned int edge_type = type & IRQF_TRIGGER_MASK;
    151	unsigned long flags;
    152	u8 new_type, gpiic;
    153
    154	switch (edge_type) {
    155	case IRQ_TYPE_EDGE_RISING:
    156		new_type = TQMX86_GPII_RISING;
    157		break;
    158	case IRQ_TYPE_EDGE_FALLING:
    159		new_type = TQMX86_GPII_FALLING;
    160		break;
    161	case IRQ_TYPE_EDGE_BOTH:
    162		new_type = TQMX86_GPII_FALLING | TQMX86_GPII_RISING;
    163		break;
    164	default:
    165		return -EINVAL; /* not supported */
    166	}
    167
    168	gpio->irq_type[offset] = new_type;
    169
    170	raw_spin_lock_irqsave(&gpio->spinlock, flags);
    171	gpiic = tqmx86_gpio_read(gpio, TQMX86_GPIIC);
    172	gpiic &= ~((TQMX86_GPII_MASK) << (offset * TQMX86_GPII_BITS));
    173	gpiic |= new_type << (offset * TQMX86_GPII_BITS);
    174	tqmx86_gpio_write(gpio, gpiic, TQMX86_GPIIC);
    175	raw_spin_unlock_irqrestore(&gpio->spinlock, flags);
    176
    177	return 0;
    178}
    179
    180static void tqmx86_gpio_irq_handler(struct irq_desc *desc)
    181{
    182	struct gpio_chip *chip = irq_desc_get_handler_data(desc);
    183	struct tqmx86_gpio_data *gpio = gpiochip_get_data(chip);
    184	struct irq_chip *irq_chip = irq_desc_get_chip(desc);
    185	unsigned long irq_bits;
    186	int i = 0;
    187	u8 irq_status;
    188
    189	chained_irq_enter(irq_chip, desc);
    190
    191	irq_status = tqmx86_gpio_read(gpio, TQMX86_GPIIS);
    192	tqmx86_gpio_write(gpio, irq_status, TQMX86_GPIIS);
    193
    194	irq_bits = irq_status;
    195	for_each_set_bit(i, &irq_bits, TQMX86_NGPI)
    196		generic_handle_domain_irq(gpio->chip.irq.domain,
    197					  i + TQMX86_NGPO);
    198
    199	chained_irq_exit(irq_chip, desc);
    200}
    201
    202/* Minimal runtime PM is needed by the IRQ subsystem */
    203static int __maybe_unused tqmx86_gpio_runtime_suspend(struct device *dev)
    204{
    205	return 0;
    206}
    207
    208static int __maybe_unused tqmx86_gpio_runtime_resume(struct device *dev)
    209{
    210	return 0;
    211}
    212
    213static const struct dev_pm_ops tqmx86_gpio_dev_pm_ops = {
    214	SET_RUNTIME_PM_OPS(tqmx86_gpio_runtime_suspend,
    215			   tqmx86_gpio_runtime_resume, NULL)
    216};
    217
    218static void tqmx86_init_irq_valid_mask(struct gpio_chip *chip,
    219				       unsigned long *valid_mask,
    220				       unsigned int ngpios)
    221{
    222	/* Only GPIOs 4-7 are valid for interrupts. Clear the others */
    223	clear_bit(0, valid_mask);
    224	clear_bit(1, valid_mask);
    225	clear_bit(2, valid_mask);
    226	clear_bit(3, valid_mask);
    227}
    228
    229static int tqmx86_gpio_probe(struct platform_device *pdev)
    230{
    231	struct device *dev = &pdev->dev;
    232	struct tqmx86_gpio_data *gpio;
    233	struct gpio_chip *chip;
    234	struct gpio_irq_chip *girq;
    235	void __iomem *io_base;
    236	struct resource *res;
    237	int ret, irq;
    238
    239	irq = platform_get_irq_optional(pdev, 0);
    240	if (irq < 0 && irq != -ENXIO)
    241		return irq;
    242
    243	res = platform_get_resource(pdev, IORESOURCE_IO, 0);
    244	if (!res) {
    245		dev_err(&pdev->dev, "Cannot get I/O\n");
    246		return -ENODEV;
    247	}
    248
    249	io_base = devm_ioport_map(&pdev->dev, res->start, resource_size(res));
    250	if (!io_base)
    251		return -ENOMEM;
    252
    253	gpio = devm_kzalloc(dev, sizeof(*gpio), GFP_KERNEL);
    254	if (!gpio)
    255		return -ENOMEM;
    256
    257	raw_spin_lock_init(&gpio->spinlock);
    258	gpio->io_base = io_base;
    259
    260	tqmx86_gpio_write(gpio, (u8)~TQMX86_DIR_INPUT_MASK, TQMX86_GPIODD);
    261
    262	platform_set_drvdata(pdev, gpio);
    263
    264	chip = &gpio->chip;
    265	chip->label = "gpio-tqmx86";
    266	chip->owner = THIS_MODULE;
    267	chip->can_sleep = false;
    268	chip->base = -1;
    269	chip->direction_input = tqmx86_gpio_direction_input;
    270	chip->direction_output = tqmx86_gpio_direction_output;
    271	chip->get_direction = tqmx86_gpio_get_direction;
    272	chip->get = tqmx86_gpio_get;
    273	chip->set = tqmx86_gpio_set;
    274	chip->ngpio = TQMX86_NGPIO;
    275	chip->parent = pdev->dev.parent;
    276
    277	pm_runtime_enable(&pdev->dev);
    278
    279	if (irq > 0) {
    280		struct irq_chip *irq_chip = &gpio->irq_chip;
    281		u8 irq_status;
    282
    283		irq_chip->name = chip->label;
    284		irq_chip->irq_mask = tqmx86_gpio_irq_mask;
    285		irq_chip->irq_unmask = tqmx86_gpio_irq_unmask;
    286		irq_chip->irq_set_type = tqmx86_gpio_irq_set_type;
    287
    288		/* Mask all interrupts */
    289		tqmx86_gpio_write(gpio, 0, TQMX86_GPIIC);
    290
    291		/* Clear all pending interrupts */
    292		irq_status = tqmx86_gpio_read(gpio, TQMX86_GPIIS);
    293		tqmx86_gpio_write(gpio, irq_status, TQMX86_GPIIS);
    294
    295		girq = &chip->irq;
    296		girq->chip = irq_chip;
    297		girq->parent_handler = tqmx86_gpio_irq_handler;
    298		girq->num_parents = 1;
    299		girq->parents = devm_kcalloc(&pdev->dev, 1,
    300					     sizeof(*girq->parents),
    301					     GFP_KERNEL);
    302		if (!girq->parents) {
    303			ret = -ENOMEM;
    304			goto out_pm_dis;
    305		}
    306		girq->parents[0] = irq;
    307		girq->default_type = IRQ_TYPE_NONE;
    308		girq->handler = handle_simple_irq;
    309		girq->init_valid_mask = tqmx86_init_irq_valid_mask;
    310	}
    311
    312	ret = devm_gpiochip_add_data(dev, chip, gpio);
    313	if (ret) {
    314		dev_err(dev, "Could not register GPIO chip\n");
    315		goto out_pm_dis;
    316	}
    317
    318	irq_domain_set_pm_device(girq->domain, dev);
    319
    320	dev_info(dev, "GPIO functionality initialized with %d pins\n",
    321		 chip->ngpio);
    322
    323	return 0;
    324
    325out_pm_dis:
    326	pm_runtime_disable(&pdev->dev);
    327
    328	return ret;
    329}
    330
    331static struct platform_driver tqmx86_gpio_driver = {
    332	.driver = {
    333		.name = "tqmx86-gpio",
    334		.pm = &tqmx86_gpio_dev_pm_ops,
    335	},
    336	.probe		= tqmx86_gpio_probe,
    337};
    338
    339module_platform_driver(tqmx86_gpio_driver);
    340
    341MODULE_DESCRIPTION("TQMx86 PLD GPIO Driver");
    342MODULE_AUTHOR("Andrew Lunn <andrew@lunn.ch>");
    343MODULE_LICENSE("GPL");
    344MODULE_ALIAS("platform:tqmx86-gpio");