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-104-dio-48e.c (13852B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/*
      3 * GPIO driver for the ACCES 104-DIO-48E series
      4 * Copyright (C) 2016 William Breathitt Gray
      5 *
      6 * This driver supports the following ACCES devices: 104-DIO-48E and
      7 * 104-DIO-24E.
      8 */
      9#include <linux/bitmap.h>
     10#include <linux/bitops.h>
     11#include <linux/device.h>
     12#include <linux/errno.h>
     13#include <linux/gpio/driver.h>
     14#include <linux/io.h>
     15#include <linux/ioport.h>
     16#include <linux/interrupt.h>
     17#include <linux/irqdesc.h>
     18#include <linux/isa.h>
     19#include <linux/kernel.h>
     20#include <linux/module.h>
     21#include <linux/moduleparam.h>
     22#include <linux/spinlock.h>
     23
     24#define DIO48E_EXTENT 16
     25#define MAX_NUM_DIO48E max_num_isa_dev(DIO48E_EXTENT)
     26
     27static unsigned int base[MAX_NUM_DIO48E];
     28static unsigned int num_dio48e;
     29module_param_hw_array(base, uint, ioport, &num_dio48e, 0);
     30MODULE_PARM_DESC(base, "ACCES 104-DIO-48E base addresses");
     31
     32static unsigned int irq[MAX_NUM_DIO48E];
     33module_param_hw_array(irq, uint, irq, NULL, 0);
     34MODULE_PARM_DESC(irq, "ACCES 104-DIO-48E interrupt line numbers");
     35
     36/**
     37 * struct dio48e_gpio - GPIO device private data structure
     38 * @chip:	instance of the gpio_chip
     39 * @io_state:	bit I/O state (whether bit is set to input or output)
     40 * @out_state:	output bits state
     41 * @control:	Control registers state
     42 * @lock:	synchronization lock to prevent I/O race conditions
     43 * @base:	base port address of the GPIO device
     44 * @irq_mask:	I/O bits affected by interrupts
     45 */
     46struct dio48e_gpio {
     47	struct gpio_chip chip;
     48	unsigned char io_state[6];
     49	unsigned char out_state[6];
     50	unsigned char control[2];
     51	raw_spinlock_t lock;
     52	void __iomem *base;
     53	unsigned char irq_mask;
     54};
     55
     56static int dio48e_gpio_get_direction(struct gpio_chip *chip, unsigned int offset)
     57{
     58	struct dio48e_gpio *const dio48egpio = gpiochip_get_data(chip);
     59	const unsigned int port = offset / 8;
     60	const unsigned int mask = BIT(offset % 8);
     61
     62	if (dio48egpio->io_state[port] & mask)
     63		return  GPIO_LINE_DIRECTION_IN;
     64
     65	return GPIO_LINE_DIRECTION_OUT;
     66}
     67
     68static int dio48e_gpio_direction_input(struct gpio_chip *chip, unsigned int offset)
     69{
     70	struct dio48e_gpio *const dio48egpio = gpiochip_get_data(chip);
     71	const unsigned int io_port = offset / 8;
     72	const unsigned int control_port = io_port / 3;
     73	void __iomem *const control_addr = dio48egpio->base + 3 + control_port * 4;
     74	unsigned long flags;
     75	unsigned int control;
     76
     77	raw_spin_lock_irqsave(&dio48egpio->lock, flags);
     78
     79	/* Check if configuring Port C */
     80	if (io_port == 2 || io_port == 5) {
     81		/* Port C can be configured by nibble */
     82		if (offset % 8 > 3) {
     83			dio48egpio->io_state[io_port] |= 0xF0;
     84			dio48egpio->control[control_port] |= BIT(3);
     85		} else {
     86			dio48egpio->io_state[io_port] |= 0x0F;
     87			dio48egpio->control[control_port] |= BIT(0);
     88		}
     89	} else {
     90		dio48egpio->io_state[io_port] |= 0xFF;
     91		if (io_port == 0 || io_port == 3)
     92			dio48egpio->control[control_port] |= BIT(4);
     93		else
     94			dio48egpio->control[control_port] |= BIT(1);
     95	}
     96
     97	control = BIT(7) | dio48egpio->control[control_port];
     98	iowrite8(control, control_addr);
     99	control &= ~BIT(7);
    100	iowrite8(control, control_addr);
    101
    102	raw_spin_unlock_irqrestore(&dio48egpio->lock, flags);
    103
    104	return 0;
    105}
    106
    107static int dio48e_gpio_direction_output(struct gpio_chip *chip, unsigned int offset,
    108					int value)
    109{
    110	struct dio48e_gpio *const dio48egpio = gpiochip_get_data(chip);
    111	const unsigned int io_port = offset / 8;
    112	const unsigned int control_port = io_port / 3;
    113	const unsigned int mask = BIT(offset % 8);
    114	void __iomem *const control_addr = dio48egpio->base + 3 + control_port * 4;
    115	const unsigned int out_port = (io_port > 2) ? io_port + 1 : io_port;
    116	unsigned long flags;
    117	unsigned int control;
    118
    119	raw_spin_lock_irqsave(&dio48egpio->lock, flags);
    120
    121	/* Check if configuring Port C */
    122	if (io_port == 2 || io_port == 5) {
    123		/* Port C can be configured by nibble */
    124		if (offset % 8 > 3) {
    125			dio48egpio->io_state[io_port] &= 0x0F;
    126			dio48egpio->control[control_port] &= ~BIT(3);
    127		} else {
    128			dio48egpio->io_state[io_port] &= 0xF0;
    129			dio48egpio->control[control_port] &= ~BIT(0);
    130		}
    131	} else {
    132		dio48egpio->io_state[io_port] &= 0x00;
    133		if (io_port == 0 || io_port == 3)
    134			dio48egpio->control[control_port] &= ~BIT(4);
    135		else
    136			dio48egpio->control[control_port] &= ~BIT(1);
    137	}
    138
    139	if (value)
    140		dio48egpio->out_state[io_port] |= mask;
    141	else
    142		dio48egpio->out_state[io_port] &= ~mask;
    143
    144	control = BIT(7) | dio48egpio->control[control_port];
    145	iowrite8(control, control_addr);
    146
    147	iowrite8(dio48egpio->out_state[io_port], dio48egpio->base + out_port);
    148
    149	control &= ~BIT(7);
    150	iowrite8(control, control_addr);
    151
    152	raw_spin_unlock_irqrestore(&dio48egpio->lock, flags);
    153
    154	return 0;
    155}
    156
    157static int dio48e_gpio_get(struct gpio_chip *chip, unsigned int offset)
    158{
    159	struct dio48e_gpio *const dio48egpio = gpiochip_get_data(chip);
    160	const unsigned int port = offset / 8;
    161	const unsigned int mask = BIT(offset % 8);
    162	const unsigned int in_port = (port > 2) ? port + 1 : port;
    163	unsigned long flags;
    164	unsigned int port_state;
    165
    166	raw_spin_lock_irqsave(&dio48egpio->lock, flags);
    167
    168	/* ensure that GPIO is set for input */
    169	if (!(dio48egpio->io_state[port] & mask)) {
    170		raw_spin_unlock_irqrestore(&dio48egpio->lock, flags);
    171		return -EINVAL;
    172	}
    173
    174	port_state = ioread8(dio48egpio->base + in_port);
    175
    176	raw_spin_unlock_irqrestore(&dio48egpio->lock, flags);
    177
    178	return !!(port_state & mask);
    179}
    180
    181static const size_t ports[] = { 0, 1, 2, 4, 5, 6 };
    182
    183static int dio48e_gpio_get_multiple(struct gpio_chip *chip, unsigned long *mask,
    184	unsigned long *bits)
    185{
    186	struct dio48e_gpio *const dio48egpio = gpiochip_get_data(chip);
    187	unsigned long offset;
    188	unsigned long gpio_mask;
    189	void __iomem *port_addr;
    190	unsigned long port_state;
    191
    192	/* clear bits array to a clean slate */
    193	bitmap_zero(bits, chip->ngpio);
    194
    195	for_each_set_clump8(offset, gpio_mask, mask, ARRAY_SIZE(ports) * 8) {
    196		port_addr = dio48egpio->base + ports[offset / 8];
    197		port_state = ioread8(port_addr) & gpio_mask;
    198
    199		bitmap_set_value8(bits, port_state, offset);
    200	}
    201
    202	return 0;
    203}
    204
    205static void dio48e_gpio_set(struct gpio_chip *chip, unsigned int offset, int value)
    206{
    207	struct dio48e_gpio *const dio48egpio = gpiochip_get_data(chip);
    208	const unsigned int port = offset / 8;
    209	const unsigned int mask = BIT(offset % 8);
    210	const unsigned int out_port = (port > 2) ? port + 1 : port;
    211	unsigned long flags;
    212
    213	raw_spin_lock_irqsave(&dio48egpio->lock, flags);
    214
    215	if (value)
    216		dio48egpio->out_state[port] |= mask;
    217	else
    218		dio48egpio->out_state[port] &= ~mask;
    219
    220	iowrite8(dio48egpio->out_state[port], dio48egpio->base + out_port);
    221
    222	raw_spin_unlock_irqrestore(&dio48egpio->lock, flags);
    223}
    224
    225static void dio48e_gpio_set_multiple(struct gpio_chip *chip,
    226	unsigned long *mask, unsigned long *bits)
    227{
    228	struct dio48e_gpio *const dio48egpio = gpiochip_get_data(chip);
    229	unsigned long offset;
    230	unsigned long gpio_mask;
    231	size_t index;
    232	void __iomem *port_addr;
    233	unsigned long bitmask;
    234	unsigned long flags;
    235
    236	for_each_set_clump8(offset, gpio_mask, mask, ARRAY_SIZE(ports) * 8) {
    237		index = offset / 8;
    238		port_addr = dio48egpio->base + ports[index];
    239
    240		bitmask = bitmap_get_value8(bits, offset) & gpio_mask;
    241
    242		raw_spin_lock_irqsave(&dio48egpio->lock, flags);
    243
    244		/* update output state data and set device gpio register */
    245		dio48egpio->out_state[index] &= ~gpio_mask;
    246		dio48egpio->out_state[index] |= bitmask;
    247		iowrite8(dio48egpio->out_state[index], port_addr);
    248
    249		raw_spin_unlock_irqrestore(&dio48egpio->lock, flags);
    250	}
    251}
    252
    253static void dio48e_irq_ack(struct irq_data *data)
    254{
    255}
    256
    257static void dio48e_irq_mask(struct irq_data *data)
    258{
    259	struct gpio_chip *chip = irq_data_get_irq_chip_data(data);
    260	struct dio48e_gpio *const dio48egpio = gpiochip_get_data(chip);
    261	const unsigned long offset = irqd_to_hwirq(data);
    262	unsigned long flags;
    263
    264	/* only bit 3 on each respective Port C supports interrupts */
    265	if (offset != 19 && offset != 43)
    266		return;
    267
    268	raw_spin_lock_irqsave(&dio48egpio->lock, flags);
    269
    270	if (offset == 19)
    271		dio48egpio->irq_mask &= ~BIT(0);
    272	else
    273		dio48egpio->irq_mask &= ~BIT(1);
    274
    275	if (!dio48egpio->irq_mask)
    276		/* disable interrupts */
    277		ioread8(dio48egpio->base + 0xB);
    278
    279	raw_spin_unlock_irqrestore(&dio48egpio->lock, flags);
    280}
    281
    282static void dio48e_irq_unmask(struct irq_data *data)
    283{
    284	struct gpio_chip *chip = irq_data_get_irq_chip_data(data);
    285	struct dio48e_gpio *const dio48egpio = gpiochip_get_data(chip);
    286	const unsigned long offset = irqd_to_hwirq(data);
    287	unsigned long flags;
    288
    289	/* only bit 3 on each respective Port C supports interrupts */
    290	if (offset != 19 && offset != 43)
    291		return;
    292
    293	raw_spin_lock_irqsave(&dio48egpio->lock, flags);
    294
    295	if (!dio48egpio->irq_mask) {
    296		/* enable interrupts */
    297		iowrite8(0x00, dio48egpio->base + 0xF);
    298		iowrite8(0x00, dio48egpio->base + 0xB);
    299	}
    300
    301	if (offset == 19)
    302		dio48egpio->irq_mask |= BIT(0);
    303	else
    304		dio48egpio->irq_mask |= BIT(1);
    305
    306	raw_spin_unlock_irqrestore(&dio48egpio->lock, flags);
    307}
    308
    309static int dio48e_irq_set_type(struct irq_data *data, unsigned int flow_type)
    310{
    311	const unsigned long offset = irqd_to_hwirq(data);
    312
    313	/* only bit 3 on each respective Port C supports interrupts */
    314	if (offset != 19 && offset != 43)
    315		return -EINVAL;
    316
    317	if (flow_type != IRQ_TYPE_NONE && flow_type != IRQ_TYPE_EDGE_RISING)
    318		return -EINVAL;
    319
    320	return 0;
    321}
    322
    323static struct irq_chip dio48e_irqchip = {
    324	.name = "104-dio-48e",
    325	.irq_ack = dio48e_irq_ack,
    326	.irq_mask = dio48e_irq_mask,
    327	.irq_unmask = dio48e_irq_unmask,
    328	.irq_set_type = dio48e_irq_set_type
    329};
    330
    331static irqreturn_t dio48e_irq_handler(int irq, void *dev_id)
    332{
    333	struct dio48e_gpio *const dio48egpio = dev_id;
    334	struct gpio_chip *const chip = &dio48egpio->chip;
    335	const unsigned long irq_mask = dio48egpio->irq_mask;
    336	unsigned long gpio;
    337
    338	for_each_set_bit(gpio, &irq_mask, 2)
    339		generic_handle_domain_irq(chip->irq.domain,
    340					  19 + gpio*24);
    341
    342	raw_spin_lock(&dio48egpio->lock);
    343
    344	iowrite8(0x00, dio48egpio->base + 0xF);
    345
    346	raw_spin_unlock(&dio48egpio->lock);
    347
    348	return IRQ_HANDLED;
    349}
    350
    351#define DIO48E_NGPIO 48
    352static const char *dio48e_names[DIO48E_NGPIO] = {
    353	"PPI Group 0 Port A 0", "PPI Group 0 Port A 1", "PPI Group 0 Port A 2",
    354	"PPI Group 0 Port A 3", "PPI Group 0 Port A 4", "PPI Group 0 Port A 5",
    355	"PPI Group 0 Port A 6", "PPI Group 0 Port A 7",	"PPI Group 0 Port B 0",
    356	"PPI Group 0 Port B 1", "PPI Group 0 Port B 2", "PPI Group 0 Port B 3",
    357	"PPI Group 0 Port B 4", "PPI Group 0 Port B 5", "PPI Group 0 Port B 6",
    358	"PPI Group 0 Port B 7", "PPI Group 0 Port C 0", "PPI Group 0 Port C 1",
    359	"PPI Group 0 Port C 2", "PPI Group 0 Port C 3", "PPI Group 0 Port C 4",
    360	"PPI Group 0 Port C 5", "PPI Group 0 Port C 6", "PPI Group 0 Port C 7",
    361	"PPI Group 1 Port A 0", "PPI Group 1 Port A 1", "PPI Group 1 Port A 2",
    362	"PPI Group 1 Port A 3", "PPI Group 1 Port A 4", "PPI Group 1 Port A 5",
    363	"PPI Group 1 Port A 6", "PPI Group 1 Port A 7",	"PPI Group 1 Port B 0",
    364	"PPI Group 1 Port B 1", "PPI Group 1 Port B 2", "PPI Group 1 Port B 3",
    365	"PPI Group 1 Port B 4", "PPI Group 1 Port B 5", "PPI Group 1 Port B 6",
    366	"PPI Group 1 Port B 7", "PPI Group 1 Port C 0", "PPI Group 1 Port C 1",
    367	"PPI Group 1 Port C 2", "PPI Group 1 Port C 3", "PPI Group 1 Port C 4",
    368	"PPI Group 1 Port C 5", "PPI Group 1 Port C 6", "PPI Group 1 Port C 7"
    369};
    370
    371static int dio48e_irq_init_hw(struct gpio_chip *gc)
    372{
    373	struct dio48e_gpio *const dio48egpio = gpiochip_get_data(gc);
    374
    375	/* Disable IRQ by default */
    376	ioread8(dio48egpio->base + 0xB);
    377
    378	return 0;
    379}
    380
    381static int dio48e_probe(struct device *dev, unsigned int id)
    382{
    383	struct dio48e_gpio *dio48egpio;
    384	const char *const name = dev_name(dev);
    385	struct gpio_irq_chip *girq;
    386	int err;
    387
    388	dio48egpio = devm_kzalloc(dev, sizeof(*dio48egpio), GFP_KERNEL);
    389	if (!dio48egpio)
    390		return -ENOMEM;
    391
    392	if (!devm_request_region(dev, base[id], DIO48E_EXTENT, name)) {
    393		dev_err(dev, "Unable to lock port addresses (0x%X-0x%X)\n",
    394			base[id], base[id] + DIO48E_EXTENT);
    395		return -EBUSY;
    396	}
    397
    398	dio48egpio->base = devm_ioport_map(dev, base[id], DIO48E_EXTENT);
    399	if (!dio48egpio->base)
    400		return -ENOMEM;
    401
    402	dio48egpio->chip.label = name;
    403	dio48egpio->chip.parent = dev;
    404	dio48egpio->chip.owner = THIS_MODULE;
    405	dio48egpio->chip.base = -1;
    406	dio48egpio->chip.ngpio = DIO48E_NGPIO;
    407	dio48egpio->chip.names = dio48e_names;
    408	dio48egpio->chip.get_direction = dio48e_gpio_get_direction;
    409	dio48egpio->chip.direction_input = dio48e_gpio_direction_input;
    410	dio48egpio->chip.direction_output = dio48e_gpio_direction_output;
    411	dio48egpio->chip.get = dio48e_gpio_get;
    412	dio48egpio->chip.get_multiple = dio48e_gpio_get_multiple;
    413	dio48egpio->chip.set = dio48e_gpio_set;
    414	dio48egpio->chip.set_multiple = dio48e_gpio_set_multiple;
    415
    416	girq = &dio48egpio->chip.irq;
    417	girq->chip = &dio48e_irqchip;
    418	/* This will let us handle the parent IRQ in the driver */
    419	girq->parent_handler = NULL;
    420	girq->num_parents = 0;
    421	girq->parents = NULL;
    422	girq->default_type = IRQ_TYPE_NONE;
    423	girq->handler = handle_edge_irq;
    424	girq->init_hw = dio48e_irq_init_hw;
    425
    426	raw_spin_lock_init(&dio48egpio->lock);
    427
    428	/* initialize all GPIO as output */
    429	iowrite8(0x80, dio48egpio->base + 3);
    430	iowrite8(0x00, dio48egpio->base);
    431	iowrite8(0x00, dio48egpio->base + 1);
    432	iowrite8(0x00, dio48egpio->base + 2);
    433	iowrite8(0x00, dio48egpio->base + 3);
    434	iowrite8(0x80, dio48egpio->base + 7);
    435	iowrite8(0x00, dio48egpio->base + 4);
    436	iowrite8(0x00, dio48egpio->base + 5);
    437	iowrite8(0x00, dio48egpio->base + 6);
    438	iowrite8(0x00, dio48egpio->base + 7);
    439
    440	err = devm_gpiochip_add_data(dev, &dio48egpio->chip, dio48egpio);
    441	if (err) {
    442		dev_err(dev, "GPIO registering failed (%d)\n", err);
    443		return err;
    444	}
    445
    446	err = devm_request_irq(dev, irq[id], dio48e_irq_handler, 0, name,
    447		dio48egpio);
    448	if (err) {
    449		dev_err(dev, "IRQ handler registering failed (%d)\n", err);
    450		return err;
    451	}
    452
    453	return 0;
    454}
    455
    456static struct isa_driver dio48e_driver = {
    457	.probe = dio48e_probe,
    458	.driver = {
    459		.name = "104-dio-48e"
    460	},
    461};
    462module_isa_driver(dio48e_driver, num_dio48e);
    463
    464MODULE_AUTHOR("William Breathitt Gray <vilhelm.gray@gmail.com>");
    465MODULE_DESCRIPTION("ACCES 104-DIO-48E GPIO driver");
    466MODULE_LICENSE("GPL v2");