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-adnp.c (12338B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/*
      3 * Copyright (C) 2011-2012 Avionic Design GmbH
      4 */
      5
      6#include <linux/gpio/driver.h>
      7#include <linux/i2c.h>
      8#include <linux/interrupt.h>
      9#include <linux/module.h>
     10#include <linux/of_irq.h>
     11#include <linux/seq_file.h>
     12#include <linux/slab.h>
     13
     14#define GPIO_DDR(gpio) (0x00 << (gpio)->reg_shift)
     15#define GPIO_PLR(gpio) (0x01 << (gpio)->reg_shift)
     16#define GPIO_IER(gpio) (0x02 << (gpio)->reg_shift)
     17#define GPIO_ISR(gpio) (0x03 << (gpio)->reg_shift)
     18#define GPIO_PTR(gpio) (0x04 << (gpio)->reg_shift)
     19
     20struct adnp {
     21	struct i2c_client *client;
     22	struct gpio_chip gpio;
     23	unsigned int reg_shift;
     24
     25	struct mutex i2c_lock;
     26	struct mutex irq_lock;
     27
     28	u8 *irq_enable;
     29	u8 *irq_level;
     30	u8 *irq_rise;
     31	u8 *irq_fall;
     32	u8 *irq_high;
     33	u8 *irq_low;
     34};
     35
     36static int adnp_read(struct adnp *adnp, unsigned offset, uint8_t *value)
     37{
     38	int err;
     39
     40	err = i2c_smbus_read_byte_data(adnp->client, offset);
     41	if (err < 0) {
     42		dev_err(adnp->gpio.parent, "%s failed: %d\n",
     43			"i2c_smbus_read_byte_data()", err);
     44		return err;
     45	}
     46
     47	*value = err;
     48	return 0;
     49}
     50
     51static int adnp_write(struct adnp *adnp, unsigned offset, uint8_t value)
     52{
     53	int err;
     54
     55	err = i2c_smbus_write_byte_data(adnp->client, offset, value);
     56	if (err < 0) {
     57		dev_err(adnp->gpio.parent, "%s failed: %d\n",
     58			"i2c_smbus_write_byte_data()", err);
     59		return err;
     60	}
     61
     62	return 0;
     63}
     64
     65static int adnp_gpio_get(struct gpio_chip *chip, unsigned offset)
     66{
     67	struct adnp *adnp = gpiochip_get_data(chip);
     68	unsigned int reg = offset >> adnp->reg_shift;
     69	unsigned int pos = offset & 7;
     70	u8 value;
     71	int err;
     72
     73	err = adnp_read(adnp, GPIO_PLR(adnp) + reg, &value);
     74	if (err < 0)
     75		return err;
     76
     77	return (value & BIT(pos)) ? 1 : 0;
     78}
     79
     80static void __adnp_gpio_set(struct adnp *adnp, unsigned offset, int value)
     81{
     82	unsigned int reg = offset >> adnp->reg_shift;
     83	unsigned int pos = offset & 7;
     84	int err;
     85	u8 val;
     86
     87	err = adnp_read(adnp, GPIO_PLR(adnp) + reg, &val);
     88	if (err < 0)
     89		return;
     90
     91	if (value)
     92		val |= BIT(pos);
     93	else
     94		val &= ~BIT(pos);
     95
     96	adnp_write(adnp, GPIO_PLR(adnp) + reg, val);
     97}
     98
     99static void adnp_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
    100{
    101	struct adnp *adnp = gpiochip_get_data(chip);
    102
    103	mutex_lock(&adnp->i2c_lock);
    104	__adnp_gpio_set(adnp, offset, value);
    105	mutex_unlock(&adnp->i2c_lock);
    106}
    107
    108static int adnp_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
    109{
    110	struct adnp *adnp = gpiochip_get_data(chip);
    111	unsigned int reg = offset >> adnp->reg_shift;
    112	unsigned int pos = offset & 7;
    113	u8 value;
    114	int err;
    115
    116	mutex_lock(&adnp->i2c_lock);
    117
    118	err = adnp_read(adnp, GPIO_DDR(adnp) + reg, &value);
    119	if (err < 0)
    120		goto out;
    121
    122	value &= ~BIT(pos);
    123
    124	err = adnp_write(adnp, GPIO_DDR(adnp) + reg, value);
    125	if (err < 0)
    126		goto out;
    127
    128	err = adnp_read(adnp, GPIO_DDR(adnp) + reg, &value);
    129	if (err < 0)
    130		goto out;
    131
    132	if (value & BIT(pos)) {
    133		err = -EPERM;
    134		goto out;
    135	}
    136
    137	err = 0;
    138
    139out:
    140	mutex_unlock(&adnp->i2c_lock);
    141	return err;
    142}
    143
    144static int adnp_gpio_direction_output(struct gpio_chip *chip, unsigned offset,
    145				      int value)
    146{
    147	struct adnp *adnp = gpiochip_get_data(chip);
    148	unsigned int reg = offset >> adnp->reg_shift;
    149	unsigned int pos = offset & 7;
    150	int err;
    151	u8 val;
    152
    153	mutex_lock(&adnp->i2c_lock);
    154
    155	err = adnp_read(adnp, GPIO_DDR(adnp) + reg, &val);
    156	if (err < 0)
    157		goto out;
    158
    159	val |= BIT(pos);
    160
    161	err = adnp_write(adnp, GPIO_DDR(adnp) + reg, val);
    162	if (err < 0)
    163		goto out;
    164
    165	err = adnp_read(adnp, GPIO_DDR(adnp) + reg, &val);
    166	if (err < 0)
    167		goto out;
    168
    169	if (!(val & BIT(pos))) {
    170		err = -EPERM;
    171		goto out;
    172	}
    173
    174	__adnp_gpio_set(adnp, offset, value);
    175	err = 0;
    176
    177out:
    178	mutex_unlock(&adnp->i2c_lock);
    179	return err;
    180}
    181
    182static void adnp_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip)
    183{
    184	struct adnp *adnp = gpiochip_get_data(chip);
    185	unsigned int num_regs = 1 << adnp->reg_shift, i, j;
    186	int err;
    187
    188	for (i = 0; i < num_regs; i++) {
    189		u8 ddr, plr, ier, isr;
    190
    191		mutex_lock(&adnp->i2c_lock);
    192
    193		err = adnp_read(adnp, GPIO_DDR(adnp) + i, &ddr);
    194		if (err < 0)
    195			goto unlock;
    196
    197		err = adnp_read(adnp, GPIO_PLR(adnp) + i, &plr);
    198		if (err < 0)
    199			goto unlock;
    200
    201		err = adnp_read(adnp, GPIO_IER(adnp) + i, &ier);
    202		if (err < 0)
    203			goto unlock;
    204
    205		err = adnp_read(adnp, GPIO_ISR(adnp) + i, &isr);
    206		if (err < 0)
    207			goto unlock;
    208
    209		mutex_unlock(&adnp->i2c_lock);
    210
    211		for (j = 0; j < 8; j++) {
    212			unsigned int bit = (i << adnp->reg_shift) + j;
    213			const char *direction = "input ";
    214			const char *level = "low ";
    215			const char *interrupt = "disabled";
    216			const char *pending = "";
    217
    218			if (ddr & BIT(j))
    219				direction = "output";
    220
    221			if (plr & BIT(j))
    222				level = "high";
    223
    224			if (ier & BIT(j))
    225				interrupt = "enabled ";
    226
    227			if (isr & BIT(j))
    228				pending = "pending";
    229
    230			seq_printf(s, "%2u: %s %s IRQ %s %s\n", bit,
    231				   direction, level, interrupt, pending);
    232		}
    233	}
    234
    235	return;
    236
    237unlock:
    238	mutex_unlock(&adnp->i2c_lock);
    239}
    240
    241static irqreturn_t adnp_irq(int irq, void *data)
    242{
    243	struct adnp *adnp = data;
    244	unsigned int num_regs, i;
    245
    246	num_regs = 1 << adnp->reg_shift;
    247
    248	for (i = 0; i < num_regs; i++) {
    249		unsigned int base = i << adnp->reg_shift, bit;
    250		u8 changed, level, isr, ier;
    251		unsigned long pending;
    252		int err;
    253
    254		mutex_lock(&adnp->i2c_lock);
    255
    256		err = adnp_read(adnp, GPIO_PLR(adnp) + i, &level);
    257		if (err < 0) {
    258			mutex_unlock(&adnp->i2c_lock);
    259			continue;
    260		}
    261
    262		err = adnp_read(adnp, GPIO_ISR(adnp) + i, &isr);
    263		if (err < 0) {
    264			mutex_unlock(&adnp->i2c_lock);
    265			continue;
    266		}
    267
    268		err = adnp_read(adnp, GPIO_IER(adnp) + i, &ier);
    269		if (err < 0) {
    270			mutex_unlock(&adnp->i2c_lock);
    271			continue;
    272		}
    273
    274		mutex_unlock(&adnp->i2c_lock);
    275
    276		/* determine pins that changed levels */
    277		changed = level ^ adnp->irq_level[i];
    278
    279		/* compute edge-triggered interrupts */
    280		pending = changed & ((adnp->irq_fall[i] & ~level) |
    281				     (adnp->irq_rise[i] & level));
    282
    283		/* add in level-triggered interrupts */
    284		pending |= (adnp->irq_high[i] & level) |
    285			   (adnp->irq_low[i] & ~level);
    286
    287		/* mask out non-pending and disabled interrupts */
    288		pending &= isr & ier;
    289
    290		for_each_set_bit(bit, &pending, 8) {
    291			unsigned int child_irq;
    292			child_irq = irq_find_mapping(adnp->gpio.irq.domain,
    293						     base + bit);
    294			handle_nested_irq(child_irq);
    295		}
    296	}
    297
    298	return IRQ_HANDLED;
    299}
    300
    301static void adnp_irq_mask(struct irq_data *d)
    302{
    303	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
    304	struct adnp *adnp = gpiochip_get_data(gc);
    305	unsigned int reg = d->hwirq >> adnp->reg_shift;
    306	unsigned int pos = d->hwirq & 7;
    307
    308	adnp->irq_enable[reg] &= ~BIT(pos);
    309}
    310
    311static void adnp_irq_unmask(struct irq_data *d)
    312{
    313	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
    314	struct adnp *adnp = gpiochip_get_data(gc);
    315	unsigned int reg = d->hwirq >> adnp->reg_shift;
    316	unsigned int pos = d->hwirq & 7;
    317
    318	adnp->irq_enable[reg] |= BIT(pos);
    319}
    320
    321static int adnp_irq_set_type(struct irq_data *d, unsigned int type)
    322{
    323	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
    324	struct adnp *adnp = gpiochip_get_data(gc);
    325	unsigned int reg = d->hwirq >> adnp->reg_shift;
    326	unsigned int pos = d->hwirq & 7;
    327
    328	if (type & IRQ_TYPE_EDGE_RISING)
    329		adnp->irq_rise[reg] |= BIT(pos);
    330	else
    331		adnp->irq_rise[reg] &= ~BIT(pos);
    332
    333	if (type & IRQ_TYPE_EDGE_FALLING)
    334		adnp->irq_fall[reg] |= BIT(pos);
    335	else
    336		adnp->irq_fall[reg] &= ~BIT(pos);
    337
    338	if (type & IRQ_TYPE_LEVEL_HIGH)
    339		adnp->irq_high[reg] |= BIT(pos);
    340	else
    341		adnp->irq_high[reg] &= ~BIT(pos);
    342
    343	if (type & IRQ_TYPE_LEVEL_LOW)
    344		adnp->irq_low[reg] |= BIT(pos);
    345	else
    346		adnp->irq_low[reg] &= ~BIT(pos);
    347
    348	return 0;
    349}
    350
    351static void adnp_irq_bus_lock(struct irq_data *d)
    352{
    353	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
    354	struct adnp *adnp = gpiochip_get_data(gc);
    355
    356	mutex_lock(&adnp->irq_lock);
    357}
    358
    359static void adnp_irq_bus_unlock(struct irq_data *d)
    360{
    361	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
    362	struct adnp *adnp = gpiochip_get_data(gc);
    363	unsigned int num_regs = 1 << adnp->reg_shift, i;
    364
    365	mutex_lock(&adnp->i2c_lock);
    366
    367	for (i = 0; i < num_regs; i++)
    368		adnp_write(adnp, GPIO_IER(adnp) + i, adnp->irq_enable[i]);
    369
    370	mutex_unlock(&adnp->i2c_lock);
    371	mutex_unlock(&adnp->irq_lock);
    372}
    373
    374static struct irq_chip adnp_irq_chip = {
    375	.name = "gpio-adnp",
    376	.irq_mask = adnp_irq_mask,
    377	.irq_unmask = adnp_irq_unmask,
    378	.irq_set_type = adnp_irq_set_type,
    379	.irq_bus_lock = adnp_irq_bus_lock,
    380	.irq_bus_sync_unlock = adnp_irq_bus_unlock,
    381};
    382
    383static int adnp_irq_setup(struct adnp *adnp)
    384{
    385	unsigned int num_regs = 1 << adnp->reg_shift, i;
    386	struct gpio_chip *chip = &adnp->gpio;
    387	int err;
    388
    389	mutex_init(&adnp->irq_lock);
    390
    391	/*
    392	 * Allocate memory to keep track of the current level and trigger
    393	 * modes of the interrupts. To avoid multiple allocations, a single
    394	 * large buffer is allocated and pointers are setup to point at the
    395	 * corresponding offsets. For consistency, the layout of the buffer
    396	 * is chosen to match the register layout of the hardware in that
    397	 * each segment contains the corresponding bits for all interrupts.
    398	 */
    399	adnp->irq_enable = devm_kcalloc(chip->parent, num_regs, 6,
    400					GFP_KERNEL);
    401	if (!adnp->irq_enable)
    402		return -ENOMEM;
    403
    404	adnp->irq_level = adnp->irq_enable + (num_regs * 1);
    405	adnp->irq_rise = adnp->irq_enable + (num_regs * 2);
    406	adnp->irq_fall = adnp->irq_enable + (num_regs * 3);
    407	adnp->irq_high = adnp->irq_enable + (num_regs * 4);
    408	adnp->irq_low = adnp->irq_enable + (num_regs * 5);
    409
    410	for (i = 0; i < num_regs; i++) {
    411		/*
    412		 * Read the initial level of all pins to allow the emulation
    413		 * of edge triggered interrupts.
    414		 */
    415		err = adnp_read(adnp, GPIO_PLR(adnp) + i, &adnp->irq_level[i]);
    416		if (err < 0)
    417			return err;
    418
    419		/* disable all interrupts */
    420		err = adnp_write(adnp, GPIO_IER(adnp) + i, 0);
    421		if (err < 0)
    422			return err;
    423
    424		adnp->irq_enable[i] = 0x00;
    425	}
    426
    427	err = devm_request_threaded_irq(chip->parent, adnp->client->irq,
    428					NULL, adnp_irq,
    429					IRQF_TRIGGER_RISING | IRQF_ONESHOT,
    430					dev_name(chip->parent), adnp);
    431	if (err != 0) {
    432		dev_err(chip->parent, "can't request IRQ#%d: %d\n",
    433			adnp->client->irq, err);
    434		return err;
    435	}
    436
    437	return 0;
    438}
    439
    440static int adnp_gpio_setup(struct adnp *adnp, unsigned int num_gpios,
    441			   bool is_irq_controller)
    442{
    443	struct gpio_chip *chip = &adnp->gpio;
    444	int err;
    445
    446	adnp->reg_shift = get_count_order(num_gpios) - 3;
    447
    448	chip->direction_input = adnp_gpio_direction_input;
    449	chip->direction_output = adnp_gpio_direction_output;
    450	chip->get = adnp_gpio_get;
    451	chip->set = adnp_gpio_set;
    452	chip->can_sleep = true;
    453
    454	if (IS_ENABLED(CONFIG_DEBUG_FS))
    455		chip->dbg_show = adnp_gpio_dbg_show;
    456
    457	chip->base = -1;
    458	chip->ngpio = num_gpios;
    459	chip->label = adnp->client->name;
    460	chip->parent = &adnp->client->dev;
    461	chip->owner = THIS_MODULE;
    462
    463	if (is_irq_controller) {
    464		struct gpio_irq_chip *girq;
    465
    466		err = adnp_irq_setup(adnp);
    467		if (err)
    468			return err;
    469
    470		girq = &chip->irq;
    471		girq->chip = &adnp_irq_chip;
    472		/* This will let us handle the parent IRQ in the driver */
    473		girq->parent_handler = NULL;
    474		girq->num_parents = 0;
    475		girq->parents = NULL;
    476		girq->default_type = IRQ_TYPE_NONE;
    477		girq->handler = handle_simple_irq;
    478		girq->threaded = true;
    479	}
    480
    481	err = devm_gpiochip_add_data(&adnp->client->dev, chip, adnp);
    482	if (err)
    483		return err;
    484
    485	return 0;
    486}
    487
    488static int adnp_i2c_probe(struct i2c_client *client,
    489				    const struct i2c_device_id *id)
    490{
    491	struct device_node *np = client->dev.of_node;
    492	struct adnp *adnp;
    493	u32 num_gpios;
    494	int err;
    495
    496	err = of_property_read_u32(np, "nr-gpios", &num_gpios);
    497	if (err < 0)
    498		return err;
    499
    500	client->irq = irq_of_parse_and_map(np, 0);
    501	if (!client->irq)
    502		return -EPROBE_DEFER;
    503
    504	adnp = devm_kzalloc(&client->dev, sizeof(*adnp), GFP_KERNEL);
    505	if (!adnp)
    506		return -ENOMEM;
    507
    508	mutex_init(&adnp->i2c_lock);
    509	adnp->client = client;
    510
    511	err = adnp_gpio_setup(adnp, num_gpios,
    512			of_property_read_bool(np, "interrupt-controller"));
    513	if (err)
    514		return err;
    515
    516	i2c_set_clientdata(client, adnp);
    517
    518	return 0;
    519}
    520
    521static const struct i2c_device_id adnp_i2c_id[] = {
    522	{ "gpio-adnp" },
    523	{ },
    524};
    525MODULE_DEVICE_TABLE(i2c, adnp_i2c_id);
    526
    527static const struct of_device_id adnp_of_match[] = {
    528	{ .compatible = "ad,gpio-adnp", },
    529	{ },
    530};
    531MODULE_DEVICE_TABLE(of, adnp_of_match);
    532
    533static struct i2c_driver adnp_i2c_driver = {
    534	.driver = {
    535		.name = "gpio-adnp",
    536		.of_match_table = adnp_of_match,
    537	},
    538	.probe = adnp_i2c_probe,
    539	.id_table = adnp_i2c_id,
    540};
    541module_i2c_driver(adnp_i2c_driver);
    542
    543MODULE_DESCRIPTION("Avionic Design N-bit GPIO expander");
    544MODULE_AUTHOR("Thierry Reding <thierry.reding@avionic-design.de>");
    545MODULE_LICENSE("GPL");