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

tps65217.c (10415B)


      1/*
      2 * tps65217.c
      3 *
      4 * TPS65217 chip family multi-function driver
      5 *
      6 * Copyright (C) 2011 Texas Instruments Incorporated - https://www.ti.com/
      7 *
      8 * This program is free software; you can redistribute it and/or
      9 * modify it under the terms of the GNU General Public License as
     10 * published by the Free Software Foundation version 2.
     11 *
     12 * This program is distributed "as is" WITHOUT ANY WARRANTY of any
     13 * kind, whether express or implied; without even the implied warranty
     14 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     15 * GNU General Public License for more details.
     16 */
     17
     18#include <linux/device.h>
     19#include <linux/err.h>
     20#include <linux/init.h>
     21#include <linux/interrupt.h>
     22#include <linux/i2c.h>
     23#include <linux/irq.h>
     24#include <linux/irqdomain.h>
     25#include <linux/kernel.h>
     26#include <linux/module.h>
     27#include <linux/of.h>
     28#include <linux/of_device.h>
     29#include <linux/platform_device.h>
     30#include <linux/regmap.h>
     31#include <linux/slab.h>
     32
     33#include <linux/mfd/core.h>
     34#include <linux/mfd/tps65217.h>
     35
     36static const struct resource charger_resources[] = {
     37	DEFINE_RES_IRQ_NAMED(TPS65217_IRQ_AC, "AC"),
     38	DEFINE_RES_IRQ_NAMED(TPS65217_IRQ_USB, "USB"),
     39};
     40
     41static const struct resource pb_resources[] = {
     42	DEFINE_RES_IRQ_NAMED(TPS65217_IRQ_PB, "PB"),
     43};
     44
     45static void tps65217_irq_lock(struct irq_data *data)
     46{
     47	struct tps65217 *tps = irq_data_get_irq_chip_data(data);
     48
     49	mutex_lock(&tps->irq_lock);
     50}
     51
     52static void tps65217_irq_sync_unlock(struct irq_data *data)
     53{
     54	struct tps65217 *tps = irq_data_get_irq_chip_data(data);
     55	int ret;
     56
     57	ret = tps65217_set_bits(tps, TPS65217_REG_INT, TPS65217_INT_MASK,
     58				tps->irq_mask, TPS65217_PROTECT_NONE);
     59	if (ret != 0)
     60		dev_err(tps->dev, "Failed to sync IRQ masks\n");
     61
     62	mutex_unlock(&tps->irq_lock);
     63}
     64
     65static void tps65217_irq_enable(struct irq_data *data)
     66{
     67	struct tps65217 *tps = irq_data_get_irq_chip_data(data);
     68	u8 mask = BIT(data->hwirq) << TPS65217_INT_SHIFT;
     69
     70	tps->irq_mask &= ~mask;
     71}
     72
     73static void tps65217_irq_disable(struct irq_data *data)
     74{
     75	struct tps65217 *tps = irq_data_get_irq_chip_data(data);
     76	u8 mask = BIT(data->hwirq) << TPS65217_INT_SHIFT;
     77
     78	tps->irq_mask |= mask;
     79}
     80
     81static struct irq_chip tps65217_irq_chip = {
     82	.name			= "tps65217",
     83	.irq_bus_lock		= tps65217_irq_lock,
     84	.irq_bus_sync_unlock	= tps65217_irq_sync_unlock,
     85	.irq_enable		= tps65217_irq_enable,
     86	.irq_disable		= tps65217_irq_disable,
     87};
     88
     89static struct mfd_cell tps65217s[] = {
     90	{
     91		.name = "tps65217-pmic",
     92		.of_compatible = "ti,tps65217-pmic",
     93	},
     94	{
     95		.name = "tps65217-bl",
     96		.of_compatible = "ti,tps65217-bl",
     97	},
     98	{
     99		.name = "tps65217-charger",
    100		.num_resources = ARRAY_SIZE(charger_resources),
    101		.resources = charger_resources,
    102		.of_compatible = "ti,tps65217-charger",
    103	},
    104	{
    105		.name = "tps65217-pwrbutton",
    106		.num_resources = ARRAY_SIZE(pb_resources),
    107		.resources = pb_resources,
    108		.of_compatible = "ti,tps65217-pwrbutton",
    109	},
    110};
    111
    112static irqreturn_t tps65217_irq_thread(int irq, void *data)
    113{
    114	struct tps65217 *tps = data;
    115	unsigned int status;
    116	bool handled = false;
    117	int i;
    118	int ret;
    119
    120	ret = tps65217_reg_read(tps, TPS65217_REG_INT, &status);
    121	if (ret < 0) {
    122		dev_err(tps->dev, "Failed to read IRQ status: %d\n",
    123			ret);
    124		return IRQ_NONE;
    125	}
    126
    127	for (i = 0; i < TPS65217_NUM_IRQ; i++) {
    128		if (status & BIT(i)) {
    129			handle_nested_irq(irq_find_mapping(tps->irq_domain, i));
    130			handled = true;
    131		}
    132	}
    133
    134	if (handled)
    135		return IRQ_HANDLED;
    136
    137	return IRQ_NONE;
    138}
    139
    140static int tps65217_irq_map(struct irq_domain *h, unsigned int virq,
    141			irq_hw_number_t hw)
    142{
    143	struct tps65217 *tps = h->host_data;
    144
    145	irq_set_chip_data(virq, tps);
    146	irq_set_chip_and_handler(virq, &tps65217_irq_chip, handle_edge_irq);
    147	irq_set_nested_thread(virq, 1);
    148	irq_set_parent(virq, tps->irq);
    149	irq_set_noprobe(virq);
    150
    151	return 0;
    152}
    153
    154static const struct irq_domain_ops tps65217_irq_domain_ops = {
    155	.map = tps65217_irq_map,
    156};
    157
    158static int tps65217_irq_init(struct tps65217 *tps, int irq)
    159{
    160	int ret;
    161
    162	mutex_init(&tps->irq_lock);
    163	tps->irq = irq;
    164
    165	/* Mask all interrupt sources */
    166	tps->irq_mask = TPS65217_INT_MASK;
    167	tps65217_set_bits(tps, TPS65217_REG_INT, TPS65217_INT_MASK,
    168			  TPS65217_INT_MASK, TPS65217_PROTECT_NONE);
    169
    170	tps->irq_domain = irq_domain_add_linear(tps->dev->of_node,
    171		TPS65217_NUM_IRQ, &tps65217_irq_domain_ops, tps);
    172	if (!tps->irq_domain) {
    173		dev_err(tps->dev, "Could not create IRQ domain\n");
    174		return -ENOMEM;
    175	}
    176
    177	ret = devm_request_threaded_irq(tps->dev, irq, NULL,
    178					tps65217_irq_thread, IRQF_ONESHOT,
    179					"tps65217-irq", tps);
    180	if (ret) {
    181		dev_err(tps->dev, "Failed to request IRQ %d: %d\n",
    182			irq, ret);
    183		return ret;
    184	}
    185
    186	enable_irq_wake(irq);
    187
    188	return 0;
    189}
    190
    191/**
    192 * tps65217_reg_read: Read a single tps65217 register.
    193 *
    194 * @tps: Device to read from.
    195 * @reg: Register to read.
    196 * @val: Contians the value
    197 */
    198int tps65217_reg_read(struct tps65217 *tps, unsigned int reg,
    199			unsigned int *val)
    200{
    201	return regmap_read(tps->regmap, reg, val);
    202}
    203EXPORT_SYMBOL_GPL(tps65217_reg_read);
    204
    205/**
    206 * tps65217_reg_write: Write a single tps65217 register.
    207 *
    208 * @tps: Device to write to.
    209 * @reg: Register to write to.
    210 * @val: Value to write.
    211 * @level: Password protected level
    212 */
    213int tps65217_reg_write(struct tps65217 *tps, unsigned int reg,
    214			unsigned int val, unsigned int level)
    215{
    216	int ret;
    217	unsigned int xor_reg_val;
    218
    219	switch (level) {
    220	case TPS65217_PROTECT_NONE:
    221		return regmap_write(tps->regmap, reg, val);
    222	case TPS65217_PROTECT_L1:
    223		xor_reg_val = reg ^ TPS65217_PASSWORD_REGS_UNLOCK;
    224		ret = regmap_write(tps->regmap, TPS65217_REG_PASSWORD,
    225							xor_reg_val);
    226		if (ret < 0)
    227			return ret;
    228
    229		return regmap_write(tps->regmap, reg, val);
    230	case TPS65217_PROTECT_L2:
    231		xor_reg_val = reg ^ TPS65217_PASSWORD_REGS_UNLOCK;
    232		ret = regmap_write(tps->regmap, TPS65217_REG_PASSWORD,
    233							xor_reg_val);
    234		if (ret < 0)
    235			return ret;
    236		ret = regmap_write(tps->regmap, reg, val);
    237		if (ret < 0)
    238			return ret;
    239		ret = regmap_write(tps->regmap, TPS65217_REG_PASSWORD,
    240							xor_reg_val);
    241		if (ret < 0)
    242			return ret;
    243		return regmap_write(tps->regmap, reg, val);
    244	default:
    245		return -EINVAL;
    246	}
    247}
    248EXPORT_SYMBOL_GPL(tps65217_reg_write);
    249
    250/**
    251 * tps65217_update_bits: Modify bits w.r.t mask, val and level.
    252 *
    253 * @tps: Device to write to.
    254 * @reg: Register to read-write to.
    255 * @mask: Mask.
    256 * @val: Value to write.
    257 * @level: Password protected level
    258 */
    259static int tps65217_update_bits(struct tps65217 *tps, unsigned int reg,
    260		unsigned int mask, unsigned int val, unsigned int level)
    261{
    262	int ret;
    263	unsigned int data;
    264
    265	ret = tps65217_reg_read(tps, reg, &data);
    266	if (ret) {
    267		dev_err(tps->dev, "Read from reg 0x%x failed\n", reg);
    268		return ret;
    269	}
    270
    271	data &= ~mask;
    272	data |= val & mask;
    273
    274	ret = tps65217_reg_write(tps, reg, data, level);
    275	if (ret)
    276		dev_err(tps->dev, "Write for reg 0x%x failed\n", reg);
    277
    278	return ret;
    279}
    280
    281int tps65217_set_bits(struct tps65217 *tps, unsigned int reg,
    282		unsigned int mask, unsigned int val, unsigned int level)
    283{
    284	return tps65217_update_bits(tps, reg, mask, val, level);
    285}
    286EXPORT_SYMBOL_GPL(tps65217_set_bits);
    287
    288int tps65217_clear_bits(struct tps65217 *tps, unsigned int reg,
    289		unsigned int mask, unsigned int level)
    290{
    291	return tps65217_update_bits(tps, reg, mask, 0, level);
    292}
    293EXPORT_SYMBOL_GPL(tps65217_clear_bits);
    294
    295static bool tps65217_volatile_reg(struct device *dev, unsigned int reg)
    296{
    297	switch (reg) {
    298	case TPS65217_REG_INT:
    299		return true;
    300	default:
    301		return false;
    302	}
    303}
    304
    305static const struct regmap_config tps65217_regmap_config = {
    306	.reg_bits = 8,
    307	.val_bits = 8,
    308
    309	.max_register = TPS65217_REG_MAX,
    310	.volatile_reg = tps65217_volatile_reg,
    311};
    312
    313static const struct of_device_id tps65217_of_match[] = {
    314	{ .compatible = "ti,tps65217"},
    315	{ /* sentinel */ },
    316};
    317MODULE_DEVICE_TABLE(of, tps65217_of_match);
    318
    319static int tps65217_probe(struct i2c_client *client)
    320{
    321	struct tps65217 *tps;
    322	unsigned int version;
    323	bool status_off = false;
    324	int ret;
    325
    326	status_off = of_property_read_bool(client->dev.of_node,
    327					   "ti,pmic-shutdown-controller");
    328
    329	tps = devm_kzalloc(&client->dev, sizeof(*tps), GFP_KERNEL);
    330	if (!tps)
    331		return -ENOMEM;
    332
    333	i2c_set_clientdata(client, tps);
    334	tps->dev = &client->dev;
    335
    336	tps->regmap = devm_regmap_init_i2c(client, &tps65217_regmap_config);
    337	if (IS_ERR(tps->regmap)) {
    338		ret = PTR_ERR(tps->regmap);
    339		dev_err(tps->dev, "Failed to allocate register map: %d\n",
    340			ret);
    341		return ret;
    342	}
    343
    344	if (client->irq) {
    345		tps65217_irq_init(tps, client->irq);
    346	} else {
    347		int i;
    348
    349		/* Don't tell children about IRQ resources which won't fire */
    350		for (i = 0; i < ARRAY_SIZE(tps65217s); i++)
    351			tps65217s[i].num_resources = 0;
    352	}
    353
    354	ret = devm_mfd_add_devices(tps->dev, -1, tps65217s,
    355				   ARRAY_SIZE(tps65217s), NULL, 0,
    356				   tps->irq_domain);
    357	if (ret < 0) {
    358		dev_err(tps->dev, "mfd_add_devices failed: %d\n", ret);
    359		return ret;
    360	}
    361
    362	ret = tps65217_reg_read(tps, TPS65217_REG_CHIPID, &version);
    363	if (ret < 0) {
    364		dev_err(tps->dev, "Failed to read revision register: %d\n",
    365			ret);
    366		return ret;
    367	}
    368
    369	/* Set the PMIC to shutdown on PWR_EN toggle */
    370	if (status_off) {
    371		ret = tps65217_set_bits(tps, TPS65217_REG_STATUS,
    372				TPS65217_STATUS_OFF, TPS65217_STATUS_OFF,
    373				TPS65217_PROTECT_NONE);
    374		if (ret)
    375			dev_warn(tps->dev, "unable to set the status OFF\n");
    376	}
    377
    378	dev_info(tps->dev, "TPS65217 ID %#x version 1.%d\n",
    379			(version & TPS65217_CHIPID_CHIP_MASK) >> 4,
    380			version & TPS65217_CHIPID_REV_MASK);
    381
    382	return 0;
    383}
    384
    385static int tps65217_remove(struct i2c_client *client)
    386{
    387	struct tps65217 *tps = i2c_get_clientdata(client);
    388	unsigned int virq;
    389	int i;
    390
    391	for (i = 0; i < TPS65217_NUM_IRQ; i++) {
    392		virq = irq_find_mapping(tps->irq_domain, i);
    393		if (virq)
    394			irq_dispose_mapping(virq);
    395	}
    396
    397	irq_domain_remove(tps->irq_domain);
    398	tps->irq_domain = NULL;
    399
    400	return 0;
    401}
    402
    403static const struct i2c_device_id tps65217_id_table[] = {
    404	{"tps65217", TPS65217},
    405	{ /* sentinel */ }
    406};
    407MODULE_DEVICE_TABLE(i2c, tps65217_id_table);
    408
    409static struct i2c_driver tps65217_driver = {
    410	.driver		= {
    411		.name	= "tps65217",
    412		.of_match_table = tps65217_of_match,
    413	},
    414	.id_table	= tps65217_id_table,
    415	.probe_new	= tps65217_probe,
    416	.remove		= tps65217_remove,
    417};
    418
    419static int __init tps65217_init(void)
    420{
    421	return i2c_add_driver(&tps65217_driver);
    422}
    423subsys_initcall(tps65217_init);
    424
    425static void __exit tps65217_exit(void)
    426{
    427	i2c_del_driver(&tps65217_driver);
    428}
    429module_exit(tps65217_exit);
    430
    431MODULE_AUTHOR("AnilKumar Ch <anilkumar@ti.com>");
    432MODULE_DESCRIPTION("TPS65217 chip family multi-function driver");
    433MODULE_LICENSE("GPL v2");