Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ab7b2c4f authored by qctecmdr's avatar qctecmdr Committed by Gerrit - the friendly Code Review server
Browse files

Merge "sx150x-pinctrl: Avoid i2c transfer during kexec"

parents 9af7706a 061cfeb8
Loading
Loading
Loading
Loading
+26 −1
Original line number Diff line number Diff line
/*
 * Copyright (c) 2019, The Linux Foundation. All rights reserved.
 * Copyright (c) 2019-2020, The Linux Foundation. All rights reserved.
 *
 * Copyright (c) 2016, BayLibre, SAS. All rights reserved.
 * Author: Neil Armstrong <narmstrong@baylibre.com>
@@ -40,6 +40,9 @@
#include "pinconf.h"
#include "pinctrl-utils.h"

static bool in_kexec_panic;
static struct notifier_block *panic_block;

/* The chip models of sx150x */
enum {
	SX150X_123 = 0,
@@ -581,6 +584,14 @@ static void sx150x_irq_bus_sync_unlock(struct irq_data *d)
	struct sx150x_pinctrl *pctl =
			gpiochip_get_data(irq_data_get_irq_chip_data(d));

	/* In crash kexec panic path interrupt is disabled.
	 * Writing to regmap will need interrupt/polling mode,
	 * as it goes though i2c.
	 */
	if (in_kexec_panic) {
		mutex_unlock(&pctl->lock);
		return;
	}
	regmap_write(pctl->regmap, pctl->data->reg_irq_mask, pctl->irq.masked);
	regmap_write(pctl->regmap, pctl->data->reg_sense, pctl->irq.sense);
	mutex_unlock(&pctl->lock);
@@ -1102,6 +1113,14 @@ const struct regmap_config sx150x_regmap_config = {
	.volatile_reg = sx150x_reg_volatile,
};

static int sx150x_panic_handler(struct notifier_block *this,
				unsigned long event, void *ptr)
{
	if (crash_kexec_post_notifiers)
		in_kexec_panic = 1;
	return NOTIFY_DONE;
}

static int sx150x_probe(struct i2c_client *client,
			const struct i2c_device_id *id)
{
@@ -1301,6 +1320,12 @@ static struct i2c_driver sx150x_driver = {

static int __init sx150x_init(void)
{
	panic_block = kzalloc(sizeof(*panic_block), GFP_KERNEL);
	if (!panic_block)
		return -ENOMEM;
	panic_block->notifier_call = sx150x_panic_handler;
	atomic_notifier_chain_register(&panic_notifier_list,
				       panic_block);
	return i2c_add_driver(&sx150x_driver);
}
subsys_initcall(sx150x_init);