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

Commit 488c3ee7 authored by Daniel Drake's avatar Daniel Drake Committed by John W. Linville
Browse files

libertas CS: convert to asynchronous firmware loading

parent 990e08a0
Loading
Loading
Loading
Loading
+49 −39
Original line number Diff line number Diff line
@@ -738,6 +738,50 @@ static int if_cs_prog_real(struct if_cs_card *card, const struct firmware *fw)
	return ret;
}

static void if_cs_prog_firmware(struct lbs_private *priv, int ret,
				 const struct firmware *helper,
				 const struct firmware *mainfw)
{
	struct if_cs_card *card = priv->card;

	if (ret) {
		pr_err("failed to find firmware (%d)\n", ret);
		return;
	}

	/* Load the firmware */
	ret = if_cs_prog_helper(card, helper);
	if (ret == 0 && (card->model != MODEL_8305))
		ret = if_cs_prog_real(card, mainfw);
	if (ret)
		goto out;

	/* Now actually get the IRQ */
	ret = request_irq(card->p_dev->irq, if_cs_interrupt,
		IRQF_SHARED, DRV_NAME, card);
	if (ret) {
		pr_err("error in request_irq\n");
		goto out;
	}

	/*
	 * Clear any interrupt cause that happened while sending
	 * firmware/initializing card
	 */
	if_cs_write16(card, IF_CS_CARD_INT_CAUSE, IF_CS_BIT_MASK);
	if_cs_enable_ints(card);

	/* And finally bring the card up */
	priv->fw_ready = 1;
	if (lbs_start_card(priv) != 0) {
		pr_err("could not activate card\n");
		free_irq(card->p_dev->irq, card);
	}

out:
	release_firmware(helper);
	release_firmware(mainfw);
}


/********************************************************************/
@@ -809,8 +853,6 @@ static int if_cs_probe(struct pcmcia_device *p_dev)
	unsigned int prod_id;
	struct lbs_private *priv;
	struct if_cs_card *card;
	const struct firmware *helper = NULL;
	const struct firmware *mainfw = NULL;

	lbs_deb_enter(LBS_DEB_CS);

@@ -890,20 +932,6 @@ static int if_cs_probe(struct pcmcia_device *p_dev)
		goto out2;
	}

	ret = lbs_get_firmware(&p_dev->dev, card->model, &fw_table[0],
				&helper, &mainfw);
	if (ret) {
		pr_err("failed to find firmware (%d)\n", ret);
		goto out2;
	}

	/* Load the firmware early, before calling into libertas.ko */
	ret = if_cs_prog_helper(card, helper);
	if (ret == 0 && (card->model != MODEL_8305))
		ret = if_cs_prog_real(card, mainfw);
	if (ret)
		goto out2;

	/* Make this card known to the libertas driver */
	priv = lbs_add_card(card, &p_dev->dev);
	if (!priv) {
@@ -911,37 +939,22 @@ static int if_cs_probe(struct pcmcia_device *p_dev)
		goto out2;
	}

	/* Finish setting up fields in lbs_private */
	/* Set up fields in lbs_private */
	card->priv = priv;
	priv->card = card;
	priv->hw_host_to_card = if_cs_host_to_card;
	priv->enter_deep_sleep = NULL;
	priv->exit_deep_sleep = NULL;
	priv->reset_deep_sleep_wakeup = NULL;
	priv->fw_ready = 1;

	/* Now actually get the IRQ */
	ret = request_irq(p_dev->irq, if_cs_interrupt,
		IRQF_SHARED, DRV_NAME, card);
	/* Get firmware */
	ret = lbs_get_firmware_async(priv, &p_dev->dev, card->model, fw_table,
				     if_cs_prog_firmware);
	if (ret) {
		pr_err("error in request_irq\n");
		goto out3;
	}

	/*
	 * Clear any interrupt cause that happened while sending
	 * firmware/initializing card
	 */
	if_cs_write16(card, IF_CS_CARD_INT_CAUSE, IF_CS_BIT_MASK);
	if_cs_enable_ints(card);

	/* And finally bring the card up */
	if (lbs_start_card(priv) != 0) {
		pr_err("could not activate card\n");
		pr_err("failed to find firmware (%d)\n", ret);
		goto out3;
	}

	ret = 0;
	goto out;

out3:
@@ -951,9 +964,6 @@ static int if_cs_probe(struct pcmcia_device *p_dev)
out1:
	pcmcia_disable_device(p_dev);
out:
	release_firmware(helper);
	release_firmware(mainfw);

	lbs_deb_leave_args(LBS_DEB_CS, "ret %d", ret);
	return ret;
}