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

Commit eb697fba authored by Jinesh K. Jayakumar's avatar Jinesh K. Jayakumar Committed by Gerrit - the friendly Code Review server
Browse files

msm: ipa: eth: Register panic notifier for individual devices



Register kernel panic handler for each ethernet device individually in
order to avoid aquiring ipa_eth_devices_lock mutex.

Change-Id: I79546bde006439120dd0c5700a24d0b778408e28
Signed-off-by: default avatarJinesh K. Jayakumar <jineshk@codeaurora.org>
parent 4a09af30
Loading
Loading
Loading
Loading
+29 −38
Original line number Diff line number Diff line
@@ -530,6 +530,22 @@ static void ipa_eth_ipa_ready_cb(void *data)
	ipa_eth_global_refresh_sched();
}

static int ipa_eth_panic_notifier(struct notifier_block *nb,
	unsigned long event, void *ptr)
{
	struct ipa_eth_device_private *ipa_priv = container_of(nb,
				struct ipa_eth_device_private, panic_nb);
	struct ipa_eth_device *eth_dev = ipa_priv->eth_dev;

	if (!reachable(eth_dev))
		return -ENODEV;

	ipa_eth_net_save_regs(eth_dev);
	ipa_eth_offload_save_regs(eth_dev);

	return NOTIFY_DONE;
}

/*
 * ipa_eth_alloc_device() - Allocate an ipa_eth_device structure and initialize
 *                          all common fields
@@ -583,9 +599,13 @@ struct ipa_eth_device *ipa_eth_alloc_device(

	/* Initialize private data */

	ipa_priv->eth_dev = eth_dev;

	mutex_init(&ipa_priv->upper_mutex);
	INIT_LIST_HEAD(&ipa_priv->upper_devices);

	ipa_priv->panic_nb.notifier_call = ipa_eth_panic_notifier;

	eth_dev->ipa_priv = ipa_priv;

	return eth_dev;
@@ -615,9 +635,13 @@ void ipa_eth_free_device(struct ipa_eth_device *eth_dev)
int ipa_eth_register_device(struct ipa_eth_device *eth_dev)
{
	int rc;
	struct ipa_eth_device_private *ipa_priv = eth_dev->ipa_priv;

	ipa_eth_dev_log(eth_dev, "Registering new device");

	(void) atomic_notifier_chain_register(
			&panic_notifier_list, &ipa_priv->panic_nb);

	rc = ipa_eth_net_open_device(eth_dev);
	if (rc) {
		ipa_eth_dev_err(eth_dev, "Failed to open network device");
@@ -679,6 +703,8 @@ static void ipa_eth_unpair_device(struct ipa_eth_device *eth_dev)
 */
void ipa_eth_unregister_device(struct ipa_eth_device *eth_dev)
{
	struct ipa_eth_device_private *ipa_priv = eth_dev->ipa_priv;

	ipa_eth_dev_log(eth_dev, "Unregistering device");

	/* Set REMOVING flag so that device refreshes do not happen */
@@ -719,6 +745,9 @@ void ipa_eth_unregister_device(struct ipa_eth_device *eth_dev)
	 */
	clear_bit(IPA_ETH_DEV_F_REMOVING, &eth_dev->flags);

	(void) atomic_notifier_chain_unregister(
			&panic_notifier_list, &ipa_priv->panic_nb);

	ipa_eth_dev_log(eth_dev, "Device unregistered");
}

@@ -801,36 +830,6 @@ void ipa_eth_unregister_offload_driver(struct ipa_eth_offload_driver *od)
}
EXPORT_SYMBOL(ipa_eth_unregister_offload_driver);

static int ipa_eth_panic_save_device(struct ipa_eth_device *eth_dev)
{
	if (!reachable(eth_dev))
		return -ENODEV;

	ipa_eth_net_save_regs(eth_dev);
	ipa_eth_offload_save_regs(eth_dev);

	return 0;
}

static int ipa_eth_panic_notifier(struct notifier_block *nb,
	unsigned long event, void *ptr)
{
	struct ipa_eth_device *eth_dev;

	mutex_lock(&ipa_eth_devices_lock);

	list_for_each_entry(eth_dev, &ipa_eth_devices, device_list)
		ipa_eth_panic_save_device(eth_dev);

	mutex_unlock(&ipa_eth_devices_lock);

	return NOTIFY_DONE;
}

static struct notifier_block ipa_eth_panic_nb = {
	.notifier_call  = ipa_eth_panic_notifier,
};

static int ipa_eth_pm_notifier_cb(struct notifier_block *nb,
	unsigned long pm_event, void *unused)
{
@@ -858,9 +857,6 @@ int ipa_eth_init(void)
	int rc;
	unsigned int wq_flags = WQ_UNBOUND | WQ_MEM_RECLAIM;

	(void) atomic_notifier_chain_register(
			&panic_notifier_list, &ipa_eth_panic_nb);

	rc = ipa_eth_ipc_log_init();
	if (rc) {
		ipa_eth_err("Failed to initialize IPC logging");
@@ -932,8 +928,6 @@ int ipa_eth_init(void)
err_wq:
	ipa_eth_ipc_log_cleanup();
err_ipclog:
	(void) atomic_notifier_chain_unregister(
			&panic_notifier_list, &ipa_eth_panic_nb);
	return rc;
}

@@ -969,7 +963,4 @@ void ipa_eth_exit(void)
	ipa_eth_wq = NULL;

	ipa_eth_ipc_log_cleanup();

	(void) atomic_notifier_chain_unregister(
			&panic_notifier_list, &ipa_eth_panic_nb);
}
+4 −0
Original line number Diff line number Diff line
@@ -118,8 +118,12 @@ struct ipa_eth_upper_device {
};

struct ipa_eth_device_private {
	struct ipa_eth_device *eth_dev;

	struct mutex upper_mutex;
	struct list_head upper_devices;

	struct notifier_block panic_nb;
};

struct ipa_eth_bus {