Commit 268ca412 authored by David S. Miller's avatar David S. Miller
Browse files

Merge branch 'ipa-clock'



Alex Elder says:

====================
net: ipa: defer taking uC proxy clock

This series rearranges some of the IPA initialization code.

The first patch gets rid of two trivial setup and teardown
functions, open-coding them in their callers instead.

The second patch has memory regions get configured before endpoints.

IPA interrupts do not depend on GSI being initialized.  Therefore
they can be initialized in the config phase rather than waiting for
setup.  The third patch moves this initialization earlier; memory
regions must already be defined, so it's done after memory config.

The microcontroller also has no dependency on GSI, though it does
require IPA interrupts to be configured.  The fourth patch moves
microcontroller initialization so it too happens during the config
phase rather than setup.

Finally, we currently take a "proxy clock" for the microcontroller
during the config phase, dropping it only after we learn the
microcontroller is initialized.  But microcontroller initialization
is started by the modem, so there's no point in taking that clock
reference before we know the modem has booted.  So the last patch
arranges to wait to take the "proxy clock" for the microcontroller
until we know the modem is about to boot.
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 323e0cb4 e2f154e6
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -51,6 +51,7 @@ enum ipa_flag {
 * @table_addr:		DMA address of filter/route table content
 * @table_virt:		Virtual address of filter/route table content
 * @interrupt:		IPA Interrupt information
 * @uc_clocked:		true if clock is active by proxy for microcontroller
 * @uc_loaded:		true after microcontroller has reported it's ready
 * @reg_addr:		DMA address used for IPA register access
 * @reg_virt:		Virtual address used for IPA register access
@@ -95,6 +96,7 @@ struct ipa {
	__le64 *table_virt;

	struct ipa_interrupt *interrupt;
	bool uc_clocked;
	bool uc_loaded;

	dma_addr_t reg_addr;
+4 −4
Original line number Diff line number Diff line
@@ -233,8 +233,8 @@ ipa_interrupt_remove(struct ipa_interrupt *interrupt, enum ipa_irq_id ipa_irq)
	interrupt->handler[ipa_irq] = NULL;
}

/* Set up the IPA interrupt framework */
struct ipa_interrupt *ipa_interrupt_setup(struct ipa *ipa)
/* Configure the IPA interrupt framework */
struct ipa_interrupt *ipa_interrupt_config(struct ipa *ipa)
{
	struct device *dev = &ipa->pdev->dev;
	struct ipa_interrupt *interrupt;
@@ -283,8 +283,8 @@ struct ipa_interrupt *ipa_interrupt_setup(struct ipa *ipa)
	return ERR_PTR(ret);
}

/* Tear down the IPA interrupt framework */
void ipa_interrupt_teardown(struct ipa_interrupt *interrupt)
/* Inverse of ipa_interrupt_config() */
void ipa_interrupt_deconfig(struct ipa_interrupt *interrupt)
{
	struct device *dev = &interrupt->ipa->pdev->dev;
	int ret;
+4 −4
Original line number Diff line number Diff line
@@ -86,17 +86,17 @@ void ipa_interrupt_suspend_clear_all(struct ipa_interrupt *interrupt);
void ipa_interrupt_simulate_suspend(struct ipa_interrupt *interrupt);

/**
 * ipa_interrupt_setup() - Set up the IPA interrupt framework
 * ipa_interrupt_config() - Configure the IPA interrupt framework
 * @ipa:	IPA pointer
 *
 * Return:	Pointer to IPA SMP2P info, or a pointer-coded error
 */
struct ipa_interrupt *ipa_interrupt_setup(struct ipa *ipa);
struct ipa_interrupt *ipa_interrupt_config(struct ipa *ipa);

/**
 * ipa_interrupt_teardown() - Tear down the IPA interrupt framework
 * ipa_interrupt_deconfig() - Inverse of ipa_interrupt_config()
 * @interrupt:	IPA interrupt structure
 */
void ipa_interrupt_teardown(struct ipa_interrupt *interrupt);
void ipa_interrupt_deconfig(struct ipa_interrupt *interrupt);

#endif /* _IPA_INTERRUPT_H_ */
+28 −24
Original line number Diff line number Diff line
@@ -124,19 +124,12 @@ int ipa_setup(struct ipa *ipa)
	if (ret)
		return ret;

	ipa->interrupt = ipa_interrupt_setup(ipa);
	if (IS_ERR(ipa->interrupt)) {
		ret = PTR_ERR(ipa->interrupt);
		goto err_gsi_teardown;
	}
	ipa_interrupt_add(ipa->interrupt, IPA_IRQ_TX_SUSPEND,
			  ipa_suspend_handler);

	ipa_uc_setup(ipa);

	ret = device_init_wakeup(dev, true);
	if (ret)
		goto err_uc_teardown;
		goto err_interrupt_remove;

	ipa_endpoint_setup(ipa);

@@ -167,7 +160,7 @@ int ipa_setup(struct ipa *ipa)
	ipa_endpoint_default_route_set(ipa, exception_endpoint->endpoint_id);

	/* We're all set.  Now prepare for communication with the modem */
	ret = ipa_modem_setup(ipa);
	ret = ipa_qmi_setup(ipa);
	if (ret)
		goto err_default_route_clear;

@@ -185,11 +178,8 @@ int ipa_setup(struct ipa *ipa)
err_endpoint_teardown:
	ipa_endpoint_teardown(ipa);
	(void)device_init_wakeup(dev, false);
err_uc_teardown:
	ipa_uc_teardown(ipa);
err_interrupt_remove:
	ipa_interrupt_remove(ipa->interrupt, IPA_IRQ_TX_SUSPEND);
	ipa_interrupt_teardown(ipa->interrupt);
err_gsi_teardown:
	gsi_teardown(&ipa->gsi);

	return ret;
@@ -204,7 +194,7 @@ static void ipa_teardown(struct ipa *ipa)
	struct ipa_endpoint *exception_endpoint;
	struct ipa_endpoint *command_endpoint;

	ipa_modem_teardown(ipa);
	ipa_qmi_teardown(ipa);
	ipa_endpoint_default_route_clear(ipa);
	exception_endpoint = ipa->name_map[IPA_ENDPOINT_AP_LAN_RX];
	ipa_endpoint_disable_one(exception_endpoint);
@@ -212,9 +202,7 @@ static void ipa_teardown(struct ipa *ipa)
	ipa_endpoint_disable_one(command_endpoint);
	ipa_endpoint_teardown(ipa);
	(void)device_init_wakeup(&ipa->pdev->dev, false);
	ipa_uc_teardown(ipa);
	ipa_interrupt_remove(ipa->interrupt, IPA_IRQ_TX_SUSPEND);
	ipa_interrupt_teardown(ipa->interrupt);
	gsi_teardown(&ipa->gsi);
}

@@ -468,31 +456,44 @@ static int ipa_config(struct ipa *ipa, const struct ipa_data *data)

	ipa_hardware_config(ipa, data);

	ret = ipa_endpoint_config(ipa);
	ret = ipa_mem_config(ipa);
	if (ret)
		goto err_hardware_deconfig;

	ret = ipa_mem_config(ipa);
	ipa->interrupt = ipa_interrupt_config(ipa);
	if (IS_ERR(ipa->interrupt)) {
		ret = PTR_ERR(ipa->interrupt);
		ipa->interrupt = NULL;
		goto err_mem_deconfig;
	}

	ipa_uc_config(ipa);

	ret = ipa_endpoint_config(ipa);
	if (ret)
		goto err_endpoint_deconfig;
		goto err_interrupt_deconfig;

	ipa_table_config(ipa);		/* No deconfig required */

	/* Assign resource limitation to each group; no deconfig required */
	ret = ipa_resource_config(ipa, data->resource_data);
	if (ret)
		goto err_mem_deconfig;
		goto err_endpoint_deconfig;

	ret = ipa_modem_config(ipa);
	if (ret)
		goto err_mem_deconfig;
		goto err_endpoint_deconfig;

	return 0;

err_mem_deconfig:
	ipa_mem_deconfig(ipa);
err_endpoint_deconfig:
	ipa_endpoint_deconfig(ipa);
err_interrupt_deconfig:
	ipa_uc_deconfig(ipa);
	ipa_interrupt_deconfig(ipa->interrupt);
	ipa->interrupt = NULL;
err_mem_deconfig:
	ipa_mem_deconfig(ipa);
err_hardware_deconfig:
	ipa_hardware_deconfig(ipa);
	ipa_clock_put(ipa);
@@ -507,8 +508,11 @@ static int ipa_config(struct ipa *ipa, const struct ipa_data *data)
static void ipa_deconfig(struct ipa *ipa)
{
	ipa_modem_deconfig(ipa);
	ipa_mem_deconfig(ipa);
	ipa_endpoint_deconfig(ipa);
	ipa_uc_deconfig(ipa);
	ipa_interrupt_deconfig(ipa->interrupt);
	ipa->interrupt = NULL;
	ipa_mem_deconfig(ipa);
	ipa_hardware_deconfig(ipa);
	ipa_clock_put(ipa);
}
+2 −10
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@
#include "ipa_modem.h"
#include "ipa_smp2p.h"
#include "ipa_qmi.h"
#include "ipa_uc.h"

#define IPA_NETDEV_NAME		"rmnet_ipa%d"
#define IPA_NETDEV_TAILROOM	0	/* for padding by mux layer */
@@ -314,6 +315,7 @@ static int ipa_modem_notify(struct notifier_block *nb, unsigned long action,
	switch (action) {
	case QCOM_SSR_BEFORE_POWERUP:
		dev_info(dev, "received modem starting event\n");
		ipa_uc_clock(ipa);
		ipa_smp2p_notify_reset(ipa);
		break;

@@ -377,13 +379,3 @@ void ipa_modem_deconfig(struct ipa *ipa)
	ipa->notifier = NULL;
	memset(&ipa->nb, 0, sizeof(ipa->nb));
}

int ipa_modem_setup(struct ipa *ipa)
{
	return ipa_qmi_setup(ipa);
}

void ipa_modem_teardown(struct ipa *ipa)
{
	ipa_qmi_teardown(ipa);
}
Loading