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

qcom-labibb-regulator.c (26319B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2// Copyright (c) 2020, The Linux Foundation. All rights reserved.
      3
      4#include <linux/module.h>
      5#include <linux/of_irq.h>
      6#include <linux/of.h>
      7#include <linux/of_device.h>
      8#include <linux/platform_device.h>
      9#include <linux/regmap.h>
     10#include <linux/regulator/driver.h>
     11#include <linux/regulator/of_regulator.h>
     12
     13#define REG_PERPH_TYPE                  0x04
     14
     15#define QCOM_LAB_TYPE			0x24
     16#define QCOM_IBB_TYPE			0x20
     17
     18#define PMI8998_LAB_REG_BASE		0xde00
     19#define PMI8998_IBB_REG_BASE		0xdc00
     20#define PMI8998_IBB_LAB_REG_OFFSET	0x200
     21
     22#define REG_LABIBB_STATUS1		0x08
     23 #define LABIBB_STATUS1_SC_BIT		BIT(6)
     24 #define LABIBB_STATUS1_VREG_OK_BIT	BIT(7)
     25
     26#define REG_LABIBB_INT_SET_TYPE		0x11
     27#define REG_LABIBB_INT_POLARITY_HIGH	0x12
     28#define REG_LABIBB_INT_POLARITY_LOW	0x13
     29#define REG_LABIBB_INT_LATCHED_CLR	0x14
     30#define REG_LABIBB_INT_EN_SET		0x15
     31#define REG_LABIBB_INT_EN_CLR		0x16
     32 #define LABIBB_INT_VREG_OK		BIT(0)
     33 #define LABIBB_INT_VREG_TYPE_LEVEL	0
     34
     35#define REG_LABIBB_VOLTAGE		0x41
     36 #define LABIBB_VOLTAGE_OVERRIDE_EN	BIT(7)
     37 #define LAB_VOLTAGE_SET_MASK		GENMASK(3, 0)
     38 #define IBB_VOLTAGE_SET_MASK		GENMASK(5, 0)
     39
     40#define REG_LABIBB_ENABLE_CTL		0x46
     41 #define LABIBB_CONTROL_ENABLE		BIT(7)
     42
     43#define REG_LABIBB_PD_CTL		0x47
     44 #define LAB_PD_CTL_MASK		GENMASK(1, 0)
     45 #define IBB_PD_CTL_MASK		(BIT(0) | BIT(7))
     46 #define LAB_PD_CTL_STRONG_PULL		BIT(0)
     47 #define IBB_PD_CTL_HALF_STRENGTH	BIT(0)
     48 #define IBB_PD_CTL_EN			BIT(7)
     49
     50#define REG_LABIBB_CURRENT_LIMIT	0x4b
     51 #define LAB_CURRENT_LIMIT_MASK		GENMASK(2, 0)
     52 #define IBB_CURRENT_LIMIT_MASK		GENMASK(4, 0)
     53 #define LAB_CURRENT_LIMIT_OVERRIDE_EN	BIT(3)
     54 #define LABIBB_CURRENT_LIMIT_EN	BIT(7)
     55
     56#define REG_IBB_PWRUP_PWRDN_CTL_1	0x58
     57 #define IBB_CTL_1_DISCHARGE_EN		BIT(2)
     58
     59#define REG_LABIBB_SOFT_START_CTL	0x5f
     60#define REG_LABIBB_SEC_ACCESS		0xd0
     61 #define LABIBB_SEC_UNLOCK_CODE		0xa5
     62
     63#define LAB_ENABLE_CTL_MASK		BIT(7)
     64#define IBB_ENABLE_CTL_MASK		(BIT(7) | BIT(6))
     65
     66#define LABIBB_OFF_ON_DELAY		1000
     67#define LAB_ENABLE_TIME			(LABIBB_OFF_ON_DELAY * 2)
     68#define IBB_ENABLE_TIME			(LABIBB_OFF_ON_DELAY * 10)
     69#define LABIBB_POLL_ENABLED_TIME	1000
     70#define OCP_RECOVERY_INTERVAL_MS	500
     71#define SC_RECOVERY_INTERVAL_MS		250
     72#define LABIBB_MAX_OCP_COUNT		4
     73#define LABIBB_MAX_SC_COUNT		3
     74#define LABIBB_MAX_FATAL_COUNT		2
     75
     76struct labibb_current_limits {
     77	u32				uA_min;
     78	u32				uA_step;
     79	u8				ovr_val;
     80};
     81
     82struct labibb_regulator {
     83	struct regulator_desc		desc;
     84	struct device			*dev;
     85	struct regmap			*regmap;
     86	struct regulator_dev		*rdev;
     87	struct labibb_current_limits	uA_limits;
     88	struct delayed_work		ocp_recovery_work;
     89	struct delayed_work		sc_recovery_work;
     90	u16				base;
     91	u8				type;
     92	u8				dischg_sel;
     93	u8				soft_start_sel;
     94	int				sc_irq;
     95	int				sc_count;
     96	int				ocp_irq;
     97	int				ocp_irq_count;
     98	int				fatal_count;
     99};
    100
    101struct labibb_regulator_data {
    102	const char			*name;
    103	u8				type;
    104	u16				base;
    105	const struct regulator_desc	*desc;
    106};
    107
    108static int qcom_labibb_ocp_hw_enable(struct regulator_dev *rdev)
    109{
    110	struct labibb_regulator *vreg = rdev_get_drvdata(rdev);
    111	int ret;
    112
    113	/* Clear irq latch status to avoid spurious event */
    114	ret = regmap_update_bits(rdev->regmap,
    115				 vreg->base + REG_LABIBB_INT_LATCHED_CLR,
    116				 LABIBB_INT_VREG_OK, 1);
    117	if (ret)
    118		return ret;
    119
    120	/* Enable OCP HW interrupt */
    121	return regmap_update_bits(rdev->regmap,
    122				  vreg->base + REG_LABIBB_INT_EN_SET,
    123				  LABIBB_INT_VREG_OK, 1);
    124}
    125
    126static int qcom_labibb_ocp_hw_disable(struct regulator_dev *rdev)
    127{
    128	struct labibb_regulator *vreg = rdev_get_drvdata(rdev);
    129
    130	return regmap_update_bits(rdev->regmap,
    131				  vreg->base + REG_LABIBB_INT_EN_CLR,
    132				  LABIBB_INT_VREG_OK, 1);
    133}
    134
    135/**
    136 * qcom_labibb_check_ocp_status - Check the Over-Current Protection status
    137 * @vreg: Main driver structure
    138 *
    139 * This function checks the STATUS1 register for the VREG_OK bit: if it is
    140 * set, then there is no Over-Current event.
    141 *
    142 * Returns: Zero if there is no over-current, 1 if in over-current or
    143 *          negative number for error
    144 */
    145static int qcom_labibb_check_ocp_status(struct labibb_regulator *vreg)
    146{
    147	u32 cur_status;
    148	int ret;
    149
    150	ret = regmap_read(vreg->rdev->regmap, vreg->base + REG_LABIBB_STATUS1,
    151			  &cur_status);
    152	if (ret)
    153		return ret;
    154
    155	return !(cur_status & LABIBB_STATUS1_VREG_OK_BIT);
    156}
    157
    158/**
    159 * qcom_labibb_ocp_recovery_worker - Handle OCP event
    160 * @work: OCP work structure
    161 *
    162 * This is the worker function to handle the Over Current Protection
    163 * hardware event; This will check if the hardware is still
    164 * signaling an over-current condition and will eventually stop
    165 * the regulator if such condition is still signaled after
    166 * LABIBB_MAX_OCP_COUNT times.
    167 *
    168 * If the driver that is consuming the regulator did not take action
    169 * for the OCP condition, or the hardware did not stabilize, a cut
    170 * of the LAB and IBB regulators will be forced (regulators will be
    171 * disabled).
    172 *
    173 * As last, if the writes to shut down the LAB/IBB regulators fail
    174 * for more than LABIBB_MAX_FATAL_COUNT, then a kernel panic will be
    175 * triggered, as a last resort to protect the hardware from burning;
    176 * this, however, is expected to never happen, but this is kept to
    177 * try to further ensure that we protect the hardware at all costs.
    178 */
    179static void qcom_labibb_ocp_recovery_worker(struct work_struct *work)
    180{
    181	struct labibb_regulator *vreg;
    182	const struct regulator_ops *ops;
    183	int ret;
    184
    185	vreg = container_of(work, struct labibb_regulator,
    186			    ocp_recovery_work.work);
    187	ops = vreg->rdev->desc->ops;
    188
    189	if (vreg->ocp_irq_count >= LABIBB_MAX_OCP_COUNT) {
    190		/*
    191		 * If we tried to disable the regulator multiple times but
    192		 * we kept failing, there's only one last hope to save our
    193		 * hardware from the death: raise a kernel bug, reboot and
    194		 * hope that the bootloader kindly saves us. This, though
    195		 * is done only as paranoid checking, because failing the
    196		 * regmap write to disable the vreg is almost impossible,
    197		 * since we got here after multiple regmap R/W.
    198		 */
    199		BUG_ON(vreg->fatal_count > LABIBB_MAX_FATAL_COUNT);
    200		dev_err(&vreg->rdev->dev, "LABIBB: CRITICAL: Disabling regulator\n");
    201
    202		/* Disable the regulator immediately to avoid damage */
    203		ret = ops->disable(vreg->rdev);
    204		if (ret) {
    205			vreg->fatal_count++;
    206			goto reschedule;
    207		}
    208		enable_irq(vreg->ocp_irq);
    209		vreg->fatal_count = 0;
    210		return;
    211	}
    212
    213	ret = qcom_labibb_check_ocp_status(vreg);
    214	if (ret != 0) {
    215		vreg->ocp_irq_count++;
    216		goto reschedule;
    217	}
    218
    219	ret = qcom_labibb_ocp_hw_enable(vreg->rdev);
    220	if (ret) {
    221		/* We cannot trust it without OCP enabled. */
    222		dev_err(vreg->dev, "Cannot enable OCP IRQ\n");
    223		vreg->ocp_irq_count++;
    224		goto reschedule;
    225	}
    226
    227	enable_irq(vreg->ocp_irq);
    228	/* Everything went fine: reset the OCP count! */
    229	vreg->ocp_irq_count = 0;
    230	return;
    231
    232reschedule:
    233	mod_delayed_work(system_wq, &vreg->ocp_recovery_work,
    234			 msecs_to_jiffies(OCP_RECOVERY_INTERVAL_MS));
    235}
    236
    237/**
    238 * qcom_labibb_ocp_isr - Interrupt routine for OverCurrent Protection
    239 * @irq:  Interrupt number
    240 * @chip: Main driver structure
    241 *
    242 * Over Current Protection (OCP) will signal to the client driver
    243 * that an over-current event has happened and then will schedule
    244 * a recovery worker.
    245 *
    246 * Disabling and eventually re-enabling the regulator is expected
    247 * to be done by the driver, as some hardware may be triggering an
    248 * over-current condition only at first initialization or it may
    249 * be expected only for a very brief amount of time, after which
    250 * the attached hardware may be expected to stabilize its current
    251 * draw.
    252 *
    253 * Returns: IRQ_HANDLED for success or IRQ_NONE for failure.
    254 */
    255static irqreturn_t qcom_labibb_ocp_isr(int irq, void *chip)
    256{
    257	struct labibb_regulator *vreg = chip;
    258	const struct regulator_ops *ops = vreg->rdev->desc->ops;
    259	int ret;
    260
    261	/* If the regulator is not enabled, this is a fake event */
    262	if (!ops->is_enabled(vreg->rdev))
    263		return IRQ_HANDLED;
    264
    265	/* If we tried to recover for too many times it's not getting better */
    266	if (vreg->ocp_irq_count > LABIBB_MAX_OCP_COUNT)
    267		return IRQ_NONE;
    268
    269	/*
    270	 * If we (unlikely) can't read this register, to prevent hardware
    271	 * damage at all costs, we assume that the overcurrent event was
    272	 * real; Moreover, if the status register is not signaling OCP,
    273	 * it was a spurious event, so it's all ok.
    274	 */
    275	ret = qcom_labibb_check_ocp_status(vreg);
    276	if (ret == 0) {
    277		vreg->ocp_irq_count = 0;
    278		goto end;
    279	}
    280	vreg->ocp_irq_count++;
    281
    282	/*
    283	 * Disable the interrupt temporarily, or it will fire continuously;
    284	 * we will re-enable it in the recovery worker function.
    285	 */
    286	disable_irq_nosync(irq);
    287
    288	/* Warn the user for overcurrent */
    289	dev_warn(vreg->dev, "Over-Current interrupt fired!\n");
    290
    291	/* Disable the interrupt to avoid hogging */
    292	ret = qcom_labibb_ocp_hw_disable(vreg->rdev);
    293	if (ret)
    294		goto end;
    295
    296	/* Signal overcurrent event to drivers */
    297	regulator_notifier_call_chain(vreg->rdev,
    298				      REGULATOR_EVENT_OVER_CURRENT, NULL);
    299
    300end:
    301	/* Schedule the recovery work */
    302	schedule_delayed_work(&vreg->ocp_recovery_work,
    303			      msecs_to_jiffies(OCP_RECOVERY_INTERVAL_MS));
    304	if (ret)
    305		return IRQ_NONE;
    306
    307	return IRQ_HANDLED;
    308}
    309
    310static int qcom_labibb_set_ocp(struct regulator_dev *rdev, int lim,
    311			       int severity, bool enable)
    312{
    313	struct labibb_regulator *vreg = rdev_get_drvdata(rdev);
    314	char *ocp_irq_name;
    315	u32 irq_flags = IRQF_ONESHOT;
    316	int irq_trig_low, ret;
    317
    318	/*
    319	 * labibb supports only protection - and does not support setting
    320	 * limit. Furthermore, we don't support disabling protection.
    321	 */
    322	if (lim || severity != REGULATOR_SEVERITY_PROT || !enable)
    323		return -EINVAL;
    324
    325	/* If there is no OCP interrupt, there's nothing to set */
    326	if (vreg->ocp_irq <= 0)
    327		return -EINVAL;
    328
    329	ocp_irq_name = devm_kasprintf(vreg->dev, GFP_KERNEL, "%s-over-current",
    330				      vreg->desc.name);
    331	if (!ocp_irq_name)
    332		return -ENOMEM;
    333
    334	/* IRQ polarities - LAB: trigger-low, IBB: trigger-high */
    335	switch (vreg->type) {
    336	case QCOM_LAB_TYPE:
    337		irq_flags |= IRQF_TRIGGER_LOW;
    338		irq_trig_low = 1;
    339		break;
    340	case QCOM_IBB_TYPE:
    341		irq_flags |= IRQF_TRIGGER_HIGH;
    342		irq_trig_low = 0;
    343		break;
    344	default:
    345		return -EINVAL;
    346	}
    347
    348	/* Activate OCP HW level interrupt */
    349	ret = regmap_update_bits(rdev->regmap,
    350				 vreg->base + REG_LABIBB_INT_SET_TYPE,
    351				 LABIBB_INT_VREG_OK,
    352				 LABIBB_INT_VREG_TYPE_LEVEL);
    353	if (ret)
    354		return ret;
    355
    356	/* Set OCP interrupt polarity */
    357	ret = regmap_update_bits(rdev->regmap,
    358				 vreg->base + REG_LABIBB_INT_POLARITY_HIGH,
    359				 LABIBB_INT_VREG_OK, !irq_trig_low);
    360	if (ret)
    361		return ret;
    362	ret = regmap_update_bits(rdev->regmap,
    363				 vreg->base + REG_LABIBB_INT_POLARITY_LOW,
    364				 LABIBB_INT_VREG_OK, irq_trig_low);
    365	if (ret)
    366		return ret;
    367
    368	ret = qcom_labibb_ocp_hw_enable(rdev);
    369	if (ret)
    370		return ret;
    371
    372	return devm_request_threaded_irq(vreg->dev, vreg->ocp_irq, NULL,
    373					 qcom_labibb_ocp_isr, irq_flags,
    374					 ocp_irq_name, vreg);
    375}
    376
    377/**
    378 * qcom_labibb_check_sc_status - Check the Short Circuit Protection status
    379 * @vreg: Main driver structure
    380 *
    381 * This function checks the STATUS1 register on both LAB and IBB regulators
    382 * for the ShortCircuit bit: if it is set on *any* of them, then we have
    383 * experienced a short-circuit event.
    384 *
    385 * Returns: Zero if there is no short-circuit, 1 if in short-circuit or
    386 *          negative number for error
    387 */
    388static int qcom_labibb_check_sc_status(struct labibb_regulator *vreg)
    389{
    390	u32 ibb_status, ibb_reg, lab_status, lab_reg;
    391	int ret;
    392
    393	/* We have to work on both regulators due to PBS... */
    394	lab_reg = ibb_reg = vreg->base + REG_LABIBB_STATUS1;
    395	if (vreg->type == QCOM_LAB_TYPE)
    396		ibb_reg -= PMI8998_IBB_LAB_REG_OFFSET;
    397	else
    398		lab_reg += PMI8998_IBB_LAB_REG_OFFSET;
    399
    400	ret = regmap_read(vreg->rdev->regmap, lab_reg, &lab_status);
    401	if (ret)
    402		return ret;
    403	ret = regmap_read(vreg->rdev->regmap, ibb_reg, &ibb_status);
    404	if (ret)
    405		return ret;
    406
    407	return !!(lab_status & LABIBB_STATUS1_SC_BIT) ||
    408	       !!(ibb_status & LABIBB_STATUS1_SC_BIT);
    409}
    410
    411/**
    412 * qcom_labibb_sc_recovery_worker - Handle Short Circuit event
    413 * @work: SC work structure
    414 *
    415 * This is the worker function to handle the Short Circuit Protection
    416 * hardware event; This will check if the hardware is still
    417 * signaling a short-circuit condition and will eventually never
    418 * re-enable the regulator if such condition is still signaled after
    419 * LABIBB_MAX_SC_COUNT times.
    420 *
    421 * If the driver that is consuming the regulator did not take action
    422 * for the SC condition, or the hardware did not stabilize, this
    423 * worker will stop rescheduling, leaving the regulators disabled
    424 * as already done by the Portable Batch System (PBS).
    425 *
    426 * Returns: IRQ_HANDLED for success or IRQ_NONE for failure.
    427 */
    428static void qcom_labibb_sc_recovery_worker(struct work_struct *work)
    429{
    430	struct labibb_regulator *vreg;
    431	const struct regulator_ops *ops;
    432	u32 lab_reg, ibb_reg, lab_val, ibb_val, val;
    433	bool pbs_cut = false;
    434	int i, sc, ret;
    435
    436	vreg = container_of(work, struct labibb_regulator,
    437			    sc_recovery_work.work);
    438	ops = vreg->rdev->desc->ops;
    439
    440	/*
    441	 * If we tried to check the regulator status multiple times but we
    442	 * kept failing, then just bail out, as the Portable Batch System
    443	 * (PBS) will disable the vregs for us, preventing hardware damage.
    444	 */
    445	if (vreg->fatal_count > LABIBB_MAX_FATAL_COUNT)
    446		return;
    447
    448	/* Too many short-circuit events. Throw in the towel. */
    449	if (vreg->sc_count > LABIBB_MAX_SC_COUNT)
    450		return;
    451
    452	/*
    453	 * The Portable Batch System (PBS) automatically disables LAB
    454	 * and IBB when a short-circuit event is detected, so we have to
    455	 * check and work on both of them at the same time.
    456	 */
    457	lab_reg = ibb_reg = vreg->base + REG_LABIBB_ENABLE_CTL;
    458	if (vreg->type == QCOM_LAB_TYPE)
    459		ibb_reg -= PMI8998_IBB_LAB_REG_OFFSET;
    460	else
    461		lab_reg += PMI8998_IBB_LAB_REG_OFFSET;
    462
    463	sc = qcom_labibb_check_sc_status(vreg);
    464	if (sc)
    465		goto reschedule;
    466
    467	for (i = 0; i < LABIBB_MAX_SC_COUNT; i++) {
    468		ret = regmap_read(vreg->regmap, lab_reg, &lab_val);
    469		if (ret) {
    470			vreg->fatal_count++;
    471			goto reschedule;
    472		}
    473
    474		ret = regmap_read(vreg->regmap, ibb_reg, &ibb_val);
    475		if (ret) {
    476			vreg->fatal_count++;
    477			goto reschedule;
    478		}
    479		val = lab_val & ibb_val;
    480
    481		if (!(val & LABIBB_CONTROL_ENABLE)) {
    482			pbs_cut = true;
    483			break;
    484		}
    485		usleep_range(5000, 6000);
    486	}
    487	if (pbs_cut)
    488		goto reschedule;
    489
    490
    491	/*
    492	 * If we have reached this point, we either have successfully
    493	 * recovered from the SC condition or we had a spurious SC IRQ,
    494	 * which means that we can re-enable the regulators, if they
    495	 * have ever been disabled by the PBS.
    496	 */
    497	ret = ops->enable(vreg->rdev);
    498	if (ret)
    499		goto reschedule;
    500
    501	/* Everything went fine: reset the OCP count! */
    502	vreg->sc_count = 0;
    503	enable_irq(vreg->sc_irq);
    504	return;
    505
    506reschedule:
    507	/*
    508	 * Now that we have done basic handling of the short-circuit,
    509	 * reschedule this worker in the regular system workqueue, as
    510	 * taking action is not truly urgent anymore.
    511	 */
    512	vreg->sc_count++;
    513	mod_delayed_work(system_wq, &vreg->sc_recovery_work,
    514			 msecs_to_jiffies(SC_RECOVERY_INTERVAL_MS));
    515}
    516
    517/**
    518 * qcom_labibb_sc_isr - Interrupt routine for Short Circuit Protection
    519 * @irq:  Interrupt number
    520 * @chip: Main driver structure
    521 *
    522 * Short Circuit Protection (SCP) will signal to the client driver
    523 * that a regulation-out event has happened and then will schedule
    524 * a recovery worker.
    525 *
    526 * The LAB and IBB regulators will be automatically disabled by the
    527 * Portable Batch System (PBS) and they will be enabled again by
    528 * the worker function if the hardware stops signaling the short
    529 * circuit event.
    530 *
    531 * Returns: IRQ_HANDLED for success or IRQ_NONE for failure.
    532 */
    533static irqreturn_t qcom_labibb_sc_isr(int irq, void *chip)
    534{
    535	struct labibb_regulator *vreg = chip;
    536
    537	if (vreg->sc_count > LABIBB_MAX_SC_COUNT)
    538		return IRQ_NONE;
    539
    540	/* Warn the user for short circuit */
    541	dev_warn(vreg->dev, "Short-Circuit interrupt fired!\n");
    542
    543	/*
    544	 * Disable the interrupt temporarily, or it will fire continuously;
    545	 * we will re-enable it in the recovery worker function.
    546	 */
    547	disable_irq_nosync(irq);
    548
    549	/* Signal out of regulation event to drivers */
    550	regulator_notifier_call_chain(vreg->rdev,
    551				      REGULATOR_EVENT_REGULATION_OUT, NULL);
    552
    553	/* Schedule the short-circuit handling as high-priority work */
    554	mod_delayed_work(system_highpri_wq, &vreg->sc_recovery_work,
    555			 msecs_to_jiffies(SC_RECOVERY_INTERVAL_MS));
    556	return IRQ_HANDLED;
    557}
    558
    559
    560static int qcom_labibb_set_current_limit(struct regulator_dev *rdev,
    561					 int min_uA, int max_uA)
    562{
    563	struct labibb_regulator *vreg = rdev_get_drvdata(rdev);
    564	struct regulator_desc *desc = &vreg->desc;
    565	struct labibb_current_limits *lim = &vreg->uA_limits;
    566	u32 mask, val;
    567	int i, ret, sel = -1;
    568
    569	if (min_uA < lim->uA_min || max_uA < lim->uA_min)
    570		return -EINVAL;
    571
    572	for (i = 0; i < desc->n_current_limits; i++) {
    573		int uA_limit = (lim->uA_step * i) + lim->uA_min;
    574
    575		if (max_uA >= uA_limit && min_uA <= uA_limit)
    576			sel = i;
    577	}
    578	if (sel < 0)
    579		return -EINVAL;
    580
    581	/* Current limit setting needs secure access */
    582	ret = regmap_write(vreg->regmap, vreg->base + REG_LABIBB_SEC_ACCESS,
    583			   LABIBB_SEC_UNLOCK_CODE);
    584	if (ret)
    585		return ret;
    586
    587	mask = desc->csel_mask | lim->ovr_val;
    588	mask |= LABIBB_CURRENT_LIMIT_EN;
    589	val = (u32)sel | lim->ovr_val;
    590	val |= LABIBB_CURRENT_LIMIT_EN;
    591
    592	return regmap_update_bits(vreg->regmap, desc->csel_reg, mask, val);
    593}
    594
    595static int qcom_labibb_get_current_limit(struct regulator_dev *rdev)
    596{
    597	struct labibb_regulator *vreg = rdev_get_drvdata(rdev);
    598	struct regulator_desc *desc = &vreg->desc;
    599	struct labibb_current_limits *lim = &vreg->uA_limits;
    600	unsigned int cur_step;
    601	int ret;
    602
    603	ret = regmap_read(vreg->regmap, desc->csel_reg, &cur_step);
    604	if (ret)
    605		return ret;
    606	cur_step &= desc->csel_mask;
    607
    608	return (cur_step * lim->uA_step) + lim->uA_min;
    609}
    610
    611static int qcom_labibb_set_soft_start(struct regulator_dev *rdev)
    612{
    613	struct labibb_regulator *vreg = rdev_get_drvdata(rdev);
    614	u32 val = 0;
    615
    616	if (vreg->type == QCOM_IBB_TYPE)
    617		val = vreg->dischg_sel;
    618	else
    619		val = vreg->soft_start_sel;
    620
    621	return regmap_write(rdev->regmap, rdev->desc->soft_start_reg, val);
    622}
    623
    624static int qcom_labibb_get_table_sel(const int *table, int sz, u32 value)
    625{
    626	int i;
    627
    628	for (i = 0; i < sz; i++)
    629		if (table[i] == value)
    630			return i;
    631	return -EINVAL;
    632}
    633
    634/* IBB discharge resistor values in KOhms */
    635static const int dischg_resistor_values[] = { 300, 64, 32, 16 };
    636
    637/* Soft start time in microseconds */
    638static const int soft_start_values[] = { 200, 400, 600, 800 };
    639
    640static int qcom_labibb_of_parse_cb(struct device_node *np,
    641				   const struct regulator_desc *desc,
    642				   struct regulator_config *config)
    643{
    644	struct labibb_regulator *vreg = config->driver_data;
    645	u32 dischg_kohms, soft_start_time;
    646	int ret;
    647
    648	ret = of_property_read_u32(np, "qcom,discharge-resistor-kohms",
    649				       &dischg_kohms);
    650	if (ret)
    651		dischg_kohms = 300;
    652
    653	ret = qcom_labibb_get_table_sel(dischg_resistor_values,
    654					ARRAY_SIZE(dischg_resistor_values),
    655					dischg_kohms);
    656	if (ret < 0)
    657		return ret;
    658	vreg->dischg_sel = (u8)ret;
    659
    660	ret = of_property_read_u32(np, "qcom,soft-start-us",
    661				   &soft_start_time);
    662	if (ret)
    663		soft_start_time = 200;
    664
    665	ret = qcom_labibb_get_table_sel(soft_start_values,
    666					ARRAY_SIZE(soft_start_values),
    667					soft_start_time);
    668	if (ret < 0)
    669		return ret;
    670	vreg->soft_start_sel = (u8)ret;
    671
    672	return 0;
    673}
    674
    675static const struct regulator_ops qcom_labibb_ops = {
    676	.enable			= regulator_enable_regmap,
    677	.disable		= regulator_disable_regmap,
    678	.is_enabled		= regulator_is_enabled_regmap,
    679	.set_voltage_sel	= regulator_set_voltage_sel_regmap,
    680	.get_voltage_sel	= regulator_get_voltage_sel_regmap,
    681	.list_voltage		= regulator_list_voltage_linear,
    682	.map_voltage		= regulator_map_voltage_linear,
    683	.set_active_discharge	= regulator_set_active_discharge_regmap,
    684	.set_pull_down		= regulator_set_pull_down_regmap,
    685	.set_current_limit	= qcom_labibb_set_current_limit,
    686	.get_current_limit	= qcom_labibb_get_current_limit,
    687	.set_soft_start		= qcom_labibb_set_soft_start,
    688	.set_over_current_protection = qcom_labibb_set_ocp,
    689};
    690
    691static const struct regulator_desc pmi8998_lab_desc = {
    692	.enable_mask		= LAB_ENABLE_CTL_MASK,
    693	.enable_reg		= (PMI8998_LAB_REG_BASE + REG_LABIBB_ENABLE_CTL),
    694	.enable_val		= LABIBB_CONTROL_ENABLE,
    695	.enable_time		= LAB_ENABLE_TIME,
    696	.poll_enabled_time	= LABIBB_POLL_ENABLED_TIME,
    697	.soft_start_reg		= (PMI8998_LAB_REG_BASE + REG_LABIBB_SOFT_START_CTL),
    698	.pull_down_reg		= (PMI8998_LAB_REG_BASE + REG_LABIBB_PD_CTL),
    699	.pull_down_mask		= LAB_PD_CTL_MASK,
    700	.pull_down_val_on	= LAB_PD_CTL_STRONG_PULL,
    701	.vsel_reg		= (PMI8998_LAB_REG_BASE + REG_LABIBB_VOLTAGE),
    702	.vsel_mask		= LAB_VOLTAGE_SET_MASK,
    703	.apply_reg		= (PMI8998_LAB_REG_BASE + REG_LABIBB_VOLTAGE),
    704	.apply_bit		= LABIBB_VOLTAGE_OVERRIDE_EN,
    705	.csel_reg		= (PMI8998_LAB_REG_BASE + REG_LABIBB_CURRENT_LIMIT),
    706	.csel_mask		= LAB_CURRENT_LIMIT_MASK,
    707	.n_current_limits	= 8,
    708	.off_on_delay		= LABIBB_OFF_ON_DELAY,
    709	.owner			= THIS_MODULE,
    710	.type			= REGULATOR_VOLTAGE,
    711	.min_uV			= 4600000,
    712	.uV_step		= 100000,
    713	.n_voltages		= 16,
    714	.ops			= &qcom_labibb_ops,
    715	.of_parse_cb		= qcom_labibb_of_parse_cb,
    716};
    717
    718static const struct regulator_desc pmi8998_ibb_desc = {
    719	.enable_mask		= IBB_ENABLE_CTL_MASK,
    720	.enable_reg		= (PMI8998_IBB_REG_BASE + REG_LABIBB_ENABLE_CTL),
    721	.enable_val		= LABIBB_CONTROL_ENABLE,
    722	.enable_time		= IBB_ENABLE_TIME,
    723	.poll_enabled_time	= LABIBB_POLL_ENABLED_TIME,
    724	.soft_start_reg		= (PMI8998_IBB_REG_BASE + REG_LABIBB_SOFT_START_CTL),
    725	.active_discharge_off	= 0,
    726	.active_discharge_on	= IBB_CTL_1_DISCHARGE_EN,
    727	.active_discharge_mask	= IBB_CTL_1_DISCHARGE_EN,
    728	.active_discharge_reg	= (PMI8998_IBB_REG_BASE + REG_IBB_PWRUP_PWRDN_CTL_1),
    729	.pull_down_reg		= (PMI8998_IBB_REG_BASE + REG_LABIBB_PD_CTL),
    730	.pull_down_mask		= IBB_PD_CTL_MASK,
    731	.pull_down_val_on	= IBB_PD_CTL_HALF_STRENGTH | IBB_PD_CTL_EN,
    732	.vsel_reg		= (PMI8998_IBB_REG_BASE + REG_LABIBB_VOLTAGE),
    733	.vsel_mask		= IBB_VOLTAGE_SET_MASK,
    734	.apply_reg		= (PMI8998_IBB_REG_BASE + REG_LABIBB_VOLTAGE),
    735	.apply_bit		= LABIBB_VOLTAGE_OVERRIDE_EN,
    736	.csel_reg		= (PMI8998_IBB_REG_BASE + REG_LABIBB_CURRENT_LIMIT),
    737	.csel_mask		= IBB_CURRENT_LIMIT_MASK,
    738	.n_current_limits	= 32,
    739	.off_on_delay		= LABIBB_OFF_ON_DELAY,
    740	.owner			= THIS_MODULE,
    741	.type			= REGULATOR_VOLTAGE,
    742	.min_uV			= 1400000,
    743	.uV_step		= 100000,
    744	.n_voltages		= 64,
    745	.ops			= &qcom_labibb_ops,
    746	.of_parse_cb		= qcom_labibb_of_parse_cb,
    747};
    748
    749static const struct labibb_regulator_data pmi8998_labibb_data[] = {
    750	{"lab", QCOM_LAB_TYPE, PMI8998_LAB_REG_BASE, &pmi8998_lab_desc},
    751	{"ibb", QCOM_IBB_TYPE, PMI8998_IBB_REG_BASE, &pmi8998_ibb_desc},
    752	{ },
    753};
    754
    755static const struct of_device_id qcom_labibb_match[] = {
    756	{ .compatible = "qcom,pmi8998-lab-ibb", .data = &pmi8998_labibb_data},
    757	{ },
    758};
    759MODULE_DEVICE_TABLE(of, qcom_labibb_match);
    760
    761static int qcom_labibb_regulator_probe(struct platform_device *pdev)
    762{
    763	struct labibb_regulator *vreg;
    764	struct device *dev = &pdev->dev;
    765	struct regulator_config cfg = {};
    766	struct device_node *reg_node;
    767	const struct of_device_id *match;
    768	const struct labibb_regulator_data *reg_data;
    769	struct regmap *reg_regmap;
    770	unsigned int type;
    771	int ret;
    772
    773	reg_regmap = dev_get_regmap(pdev->dev.parent, NULL);
    774	if (!reg_regmap) {
    775		dev_err(&pdev->dev, "Couldn't get parent's regmap\n");
    776		return -ENODEV;
    777	}
    778
    779	match = of_match_device(qcom_labibb_match, &pdev->dev);
    780	if (!match)
    781		return -ENODEV;
    782
    783	for (reg_data = match->data; reg_data->name; reg_data++) {
    784		char *sc_irq_name;
    785		int irq = 0;
    786
    787		/* Validate if the type of regulator is indeed
    788		 * what's mentioned in DT.
    789		 */
    790		ret = regmap_read(reg_regmap, reg_data->base + REG_PERPH_TYPE,
    791				  &type);
    792		if (ret < 0) {
    793			dev_err(dev,
    794				"Peripheral type read failed ret=%d\n",
    795				ret);
    796			return -EINVAL;
    797		}
    798
    799		if (WARN_ON((type != QCOM_LAB_TYPE) && (type != QCOM_IBB_TYPE)) ||
    800		    WARN_ON(type != reg_data->type))
    801			return -EINVAL;
    802
    803		vreg  = devm_kzalloc(&pdev->dev, sizeof(*vreg),
    804					   GFP_KERNEL);
    805		if (!vreg)
    806			return -ENOMEM;
    807
    808		sc_irq_name = devm_kasprintf(dev, GFP_KERNEL,
    809					     "%s-short-circuit",
    810					     reg_data->name);
    811		if (!sc_irq_name)
    812			return -ENOMEM;
    813
    814		reg_node = of_get_child_by_name(pdev->dev.of_node,
    815						reg_data->name);
    816		if (!reg_node)
    817			return -EINVAL;
    818
    819		/* The Short Circuit interrupt is critical */
    820		irq = of_irq_get_byname(reg_node, "sc-err");
    821		if (irq <= 0) {
    822			if (irq == 0)
    823				irq = -EINVAL;
    824
    825			return dev_err_probe(vreg->dev, irq,
    826					     "Short-circuit irq not found.\n");
    827		}
    828		vreg->sc_irq = irq;
    829
    830		/* OverCurrent Protection IRQ is optional */
    831		irq = of_irq_get_byname(reg_node, "ocp");
    832		vreg->ocp_irq = irq;
    833		vreg->ocp_irq_count = 0;
    834		of_node_put(reg_node);
    835
    836		vreg->regmap = reg_regmap;
    837		vreg->dev = dev;
    838		vreg->base = reg_data->base;
    839		vreg->type = reg_data->type;
    840		INIT_DELAYED_WORK(&vreg->sc_recovery_work,
    841				  qcom_labibb_sc_recovery_worker);
    842
    843		if (vreg->ocp_irq > 0)
    844			INIT_DELAYED_WORK(&vreg->ocp_recovery_work,
    845					  qcom_labibb_ocp_recovery_worker);
    846
    847		switch (vreg->type) {
    848		case QCOM_LAB_TYPE:
    849			/* LAB Limits: 200-1600mA */
    850			vreg->uA_limits.uA_min  = 200000;
    851			vreg->uA_limits.uA_step = 200000;
    852			vreg->uA_limits.ovr_val = LAB_CURRENT_LIMIT_OVERRIDE_EN;
    853			break;
    854		case QCOM_IBB_TYPE:
    855			/* IBB Limits: 0-1550mA */
    856			vreg->uA_limits.uA_min  = 0;
    857			vreg->uA_limits.uA_step = 50000;
    858			vreg->uA_limits.ovr_val = 0; /* No override bit */
    859			break;
    860		default:
    861			return -EINVAL;
    862		}
    863
    864		memcpy(&vreg->desc, reg_data->desc, sizeof(vreg->desc));
    865		vreg->desc.of_match = reg_data->name;
    866		vreg->desc.name = reg_data->name;
    867
    868		cfg.dev = vreg->dev;
    869		cfg.driver_data = vreg;
    870		cfg.regmap = vreg->regmap;
    871
    872		vreg->rdev = devm_regulator_register(vreg->dev, &vreg->desc,
    873							&cfg);
    874
    875		if (IS_ERR(vreg->rdev)) {
    876			dev_err(dev, "qcom_labibb: error registering %s : %d\n",
    877					reg_data->name, ret);
    878			return PTR_ERR(vreg->rdev);
    879		}
    880
    881		ret = devm_request_threaded_irq(vreg->dev, vreg->sc_irq, NULL,
    882						qcom_labibb_sc_isr,
    883						IRQF_ONESHOT |
    884						IRQF_TRIGGER_RISING,
    885						sc_irq_name, vreg);
    886		if (ret)
    887			return ret;
    888	}
    889
    890	return 0;
    891}
    892
    893static struct platform_driver qcom_labibb_regulator_driver = {
    894	.driver	= {
    895		.name = "qcom-lab-ibb-regulator",
    896		.of_match_table	= qcom_labibb_match,
    897	},
    898	.probe = qcom_labibb_regulator_probe,
    899};
    900module_platform_driver(qcom_labibb_regulator_driver);
    901
    902MODULE_DESCRIPTION("Qualcomm labibb driver");
    903MODULE_AUTHOR("Nisha Kumari <nishakumari@codeaurora.org>");
    904MODULE_AUTHOR("Sumit Semwal <sumit.semwal@linaro.org>");
    905MODULE_LICENSE("GPL v2");