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

da9052-irq.c (6037B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/*
      3 * DA9052 interrupt support
      4 *
      5 * Author: Fabio Estevam <fabio.estevam@freescale.com>
      6 * Based on arizona-irq.c, which is:
      7 *
      8 * Copyright 2012 Wolfson Microelectronics plc
      9 *
     10 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
     11 */
     12
     13#include <linux/device.h>
     14#include <linux/delay.h>
     15#include <linux/input.h>
     16#include <linux/interrupt.h>
     17#include <linux/irq.h>
     18#include <linux/irqdomain.h>
     19#include <linux/slab.h>
     20#include <linux/module.h>
     21
     22#include <linux/mfd/da9052/da9052.h>
     23#include <linux/mfd/da9052/reg.h>
     24
     25#define DA9052_NUM_IRQ_REGS		4
     26#define DA9052_IRQ_MASK_POS_1		0x01
     27#define DA9052_IRQ_MASK_POS_2		0x02
     28#define DA9052_IRQ_MASK_POS_3		0x04
     29#define DA9052_IRQ_MASK_POS_4		0x08
     30#define DA9052_IRQ_MASK_POS_5		0x10
     31#define DA9052_IRQ_MASK_POS_6		0x20
     32#define DA9052_IRQ_MASK_POS_7		0x40
     33#define DA9052_IRQ_MASK_POS_8		0x80
     34
     35static const struct regmap_irq da9052_irqs[] = {
     36	[DA9052_IRQ_DCIN] = {
     37		.reg_offset = 0,
     38		.mask = DA9052_IRQ_MASK_POS_1,
     39	},
     40	[DA9052_IRQ_VBUS] = {
     41		.reg_offset = 0,
     42		.mask = DA9052_IRQ_MASK_POS_2,
     43	},
     44	[DA9052_IRQ_DCINREM] = {
     45		.reg_offset = 0,
     46		.mask = DA9052_IRQ_MASK_POS_3,
     47	},
     48	[DA9052_IRQ_VBUSREM] = {
     49		.reg_offset = 0,
     50		.mask = DA9052_IRQ_MASK_POS_4,
     51	},
     52	[DA9052_IRQ_VDDLOW] = {
     53		.reg_offset = 0,
     54		.mask = DA9052_IRQ_MASK_POS_5,
     55	},
     56	[DA9052_IRQ_ALARM] = {
     57		.reg_offset = 0,
     58		.mask = DA9052_IRQ_MASK_POS_6,
     59	},
     60	[DA9052_IRQ_SEQRDY] = {
     61		.reg_offset = 0,
     62		.mask = DA9052_IRQ_MASK_POS_7,
     63	},
     64	[DA9052_IRQ_COMP1V2] = {
     65		.reg_offset = 0,
     66		.mask = DA9052_IRQ_MASK_POS_8,
     67	},
     68	[DA9052_IRQ_NONKEY] = {
     69		.reg_offset = 1,
     70		.mask = DA9052_IRQ_MASK_POS_1,
     71	},
     72	[DA9052_IRQ_IDFLOAT] = {
     73		.reg_offset = 1,
     74		.mask = DA9052_IRQ_MASK_POS_2,
     75	},
     76	[DA9052_IRQ_IDGND] = {
     77		.reg_offset = 1,
     78		.mask = DA9052_IRQ_MASK_POS_3,
     79	},
     80	[DA9052_IRQ_CHGEND] = {
     81		.reg_offset = 1,
     82		.mask = DA9052_IRQ_MASK_POS_4,
     83	},
     84	[DA9052_IRQ_TBAT] = {
     85		.reg_offset = 1,
     86		.mask = DA9052_IRQ_MASK_POS_5,
     87	},
     88	[DA9052_IRQ_ADC_EOM] = {
     89		.reg_offset = 1,
     90		.mask = DA9052_IRQ_MASK_POS_6,
     91	},
     92	[DA9052_IRQ_PENDOWN] = {
     93		.reg_offset = 1,
     94		.mask = DA9052_IRQ_MASK_POS_7,
     95	},
     96	[DA9052_IRQ_TSIREADY] = {
     97		.reg_offset = 1,
     98		.mask = DA9052_IRQ_MASK_POS_8,
     99	},
    100	[DA9052_IRQ_GPI0] = {
    101		.reg_offset = 2,
    102		.mask = DA9052_IRQ_MASK_POS_1,
    103	},
    104	[DA9052_IRQ_GPI1] = {
    105		.reg_offset = 2,
    106		.mask = DA9052_IRQ_MASK_POS_2,
    107	},
    108	[DA9052_IRQ_GPI2] = {
    109		.reg_offset = 2,
    110		.mask = DA9052_IRQ_MASK_POS_3,
    111	},
    112	[DA9052_IRQ_GPI3] = {
    113		.reg_offset = 2,
    114		.mask = DA9052_IRQ_MASK_POS_4,
    115	},
    116	[DA9052_IRQ_GPI4] = {
    117		.reg_offset = 2,
    118		.mask = DA9052_IRQ_MASK_POS_5,
    119	},
    120	[DA9052_IRQ_GPI5] = {
    121		.reg_offset = 2,
    122		.mask = DA9052_IRQ_MASK_POS_6,
    123	},
    124	[DA9052_IRQ_GPI6] = {
    125		.reg_offset = 2,
    126		.mask = DA9052_IRQ_MASK_POS_7,
    127	},
    128	[DA9052_IRQ_GPI7] = {
    129		.reg_offset = 2,
    130		.mask = DA9052_IRQ_MASK_POS_8,
    131	},
    132	[DA9052_IRQ_GPI8] = {
    133		.reg_offset = 3,
    134		.mask = DA9052_IRQ_MASK_POS_1,
    135	},
    136	[DA9052_IRQ_GPI9] = {
    137		.reg_offset = 3,
    138		.mask = DA9052_IRQ_MASK_POS_2,
    139	},
    140	[DA9052_IRQ_GPI10] = {
    141		.reg_offset = 3,
    142		.mask = DA9052_IRQ_MASK_POS_3,
    143	},
    144	[DA9052_IRQ_GPI11] = {
    145		.reg_offset = 3,
    146		.mask = DA9052_IRQ_MASK_POS_4,
    147	},
    148	[DA9052_IRQ_GPI12] = {
    149		.reg_offset = 3,
    150		.mask = DA9052_IRQ_MASK_POS_5,
    151	},
    152	[DA9052_IRQ_GPI13] = {
    153		.reg_offset = 3,
    154		.mask = DA9052_IRQ_MASK_POS_6,
    155	},
    156	[DA9052_IRQ_GPI14] = {
    157		.reg_offset = 3,
    158		.mask = DA9052_IRQ_MASK_POS_7,
    159	},
    160	[DA9052_IRQ_GPI15] = {
    161		.reg_offset = 3,
    162		.mask = DA9052_IRQ_MASK_POS_8,
    163	},
    164};
    165
    166static const struct regmap_irq_chip da9052_regmap_irq_chip = {
    167	.name = "da9052_irq",
    168	.status_base = DA9052_EVENT_A_REG,
    169	.mask_base = DA9052_IRQ_MASK_A_REG,
    170	.ack_base = DA9052_EVENT_A_REG,
    171	.num_regs = DA9052_NUM_IRQ_REGS,
    172	.irqs = da9052_irqs,
    173	.num_irqs = ARRAY_SIZE(da9052_irqs),
    174};
    175
    176static int da9052_map_irq(struct da9052 *da9052, int irq)
    177{
    178	return regmap_irq_get_virq(da9052->irq_data, irq);
    179}
    180
    181int da9052_enable_irq(struct da9052 *da9052, int irq)
    182{
    183	irq = da9052_map_irq(da9052, irq);
    184	if (irq < 0)
    185		return irq;
    186
    187	enable_irq(irq);
    188
    189	return 0;
    190}
    191EXPORT_SYMBOL_GPL(da9052_enable_irq);
    192
    193int da9052_disable_irq(struct da9052 *da9052, int irq)
    194{
    195	irq = da9052_map_irq(da9052, irq);
    196	if (irq < 0)
    197		return irq;
    198
    199	disable_irq(irq);
    200
    201	return 0;
    202}
    203EXPORT_SYMBOL_GPL(da9052_disable_irq);
    204
    205int da9052_disable_irq_nosync(struct da9052 *da9052, int irq)
    206{
    207	irq = da9052_map_irq(da9052, irq);
    208	if (irq < 0)
    209		return irq;
    210
    211	disable_irq_nosync(irq);
    212
    213	return 0;
    214}
    215EXPORT_SYMBOL_GPL(da9052_disable_irq_nosync);
    216
    217int da9052_request_irq(struct da9052 *da9052, int irq, char *name,
    218			   irq_handler_t handler, void *data)
    219{
    220	irq = da9052_map_irq(da9052, irq);
    221	if (irq < 0)
    222		return irq;
    223
    224	return request_threaded_irq(irq, NULL, handler,
    225				     IRQF_TRIGGER_LOW | IRQF_ONESHOT,
    226				     name, data);
    227}
    228EXPORT_SYMBOL_GPL(da9052_request_irq);
    229
    230void da9052_free_irq(struct da9052 *da9052, int irq, void *data)
    231{
    232	irq = da9052_map_irq(da9052, irq);
    233	if (irq < 0)
    234		return;
    235
    236	free_irq(irq, data);
    237}
    238EXPORT_SYMBOL_GPL(da9052_free_irq);
    239
    240static irqreturn_t da9052_auxadc_irq(int irq, void *irq_data)
    241{
    242	struct da9052 *da9052 = irq_data;
    243
    244	complete(&da9052->done);
    245
    246	return IRQ_HANDLED;
    247}
    248
    249int da9052_irq_init(struct da9052 *da9052)
    250{
    251	int ret;
    252
    253	ret = regmap_add_irq_chip(da9052->regmap, da9052->chip_irq,
    254				  IRQF_TRIGGER_LOW | IRQF_ONESHOT,
    255				  -1, &da9052_regmap_irq_chip,
    256				  &da9052->irq_data);
    257	if (ret < 0) {
    258		dev_err(da9052->dev, "regmap_add_irq_chip failed: %d\n", ret);
    259		goto regmap_err;
    260	}
    261
    262	enable_irq_wake(da9052->chip_irq);
    263
    264	ret = da9052_request_irq(da9052, DA9052_IRQ_ADC_EOM, "adc-irq",
    265			    da9052_auxadc_irq, da9052);
    266
    267	if (ret != 0) {
    268		dev_err(da9052->dev, "DA9052_IRQ_ADC_EOM failed: %d\n", ret);
    269		goto request_irq_err;
    270	}
    271
    272	return 0;
    273
    274request_irq_err:
    275	regmap_del_irq_chip(da9052->chip_irq, da9052->irq_data);
    276regmap_err:
    277	return ret;
    278
    279}
    280
    281int da9052_irq_exit(struct da9052 *da9052)
    282{
    283	da9052_free_irq(da9052, DA9052_IRQ_ADC_EOM, da9052);
    284	regmap_del_irq_chip(da9052->chip_irq, da9052->irq_data);
    285
    286	return 0;
    287}