All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] [media] drxk: change it to use request_firmware_nowait()
@ 2012-06-21 13:36 Mauro Carvalho Chehab
  2012-06-21 14:21 ` Devin Heitmueller
  2012-06-21 19:10 ` Mauro Carvalho Chehab
  0 siblings, 2 replies; 87+ messages in thread
From: Mauro Carvalho Chehab @ 2012-06-21 13:36 UTC (permalink / raw)
  Cc: Mauro Carvalho Chehab, Linux Media Mailing List, Antti Palosaari,
	Kay Sievers

The firmware blob may not be available when the driver probes.

Instead of blocking the whole kernel use request_firmware_nowait() and
continue without firmware.

This shouldn't be that bad on drx-k devices, as they all seem to have an
internal firmware. So, only the firmware update will take a little longer
to happen.

Cc: Antti Palosaari <crope@iki.fi>
Cc: Kay Sievers <kay@redhat.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
---
 drivers/media/dvb/frontends/drxk_hard.c |  109 +++++++++++++++++++------------
 drivers/media/dvb/frontends/drxk_hard.h |    3 +
 2 files changed, 72 insertions(+), 40 deletions(-)

diff --git a/drivers/media/dvb/frontends/drxk_hard.c b/drivers/media/dvb/frontends/drxk_hard.c
index 60b868f..4cb8d1e 100644
--- a/drivers/media/dvb/frontends/drxk_hard.c
+++ b/drivers/media/dvb/frontends/drxk_hard.c
@@ -5968,29 +5968,9 @@ error:
 	return status;
 }
 
-static int load_microcode(struct drxk_state *state, const char *mc_name)
-{
-	const struct firmware *fw = NULL;
-	int err = 0;
-
-	dprintk(1, "\n");
-
-	err = request_firmware(&fw, mc_name, state->i2c->dev.parent);
-	if (err < 0) {
-		printk(KERN_ERR
-		       "drxk: Could not load firmware file %s.\n", mc_name);
-		printk(KERN_INFO
-		       "drxk: Copy %s to your hotplug directory!\n", mc_name);
-		return err;
-	}
-	err = DownloadMicrocode(state, fw->data, fw->size);
-	release_firmware(fw);
-	return err;
-}
-
 static int init_drxk(struct drxk_state *state)
 {
-	int status = 0;
+	int status = 0, n = 0;
 	enum DRXPowerMode powerMode = DRXK_POWER_DOWN_OFDM;
 	u16 driverVersion;
 
@@ -6073,8 +6053,12 @@ static int init_drxk(struct drxk_state *state)
 		if (status < 0)
 			goto error;
 
-		if (state->microcode_name)
-			load_microcode(state, state->microcode_name);
+		if (state->fw) {
+			status = DownloadMicrocode(state, state->fw->data,
+						   state->fw->size);
+			if (status < 0)
+				goto error;
+		}
 
 		/* disable token-ring bus through OFDM block for possible ucode upload */
 		status = write16(state, SIO_OFDM_SH_OFDM_RING_ENABLE__A, SIO_OFDM_SH_OFDM_RING_ENABLE_OFF);
@@ -6167,6 +6151,20 @@ static int init_drxk(struct drxk_state *state)
 			state->m_DrxkState = DRXK_POWERED_DOWN;
 		} else
 			state->m_DrxkState = DRXK_STOPPED;
+
+		/* Initialize the supported delivery systems */
+		n = 0;
+		if (state->m_hasDVBC) {
+			state->frontend.ops.delsys[n++] = SYS_DVBC_ANNEX_A;
+			state->frontend.ops.delsys[n++] = SYS_DVBC_ANNEX_C;
+			strlcat(state->frontend.ops.info.name, " DVB-C",
+				sizeof(state->frontend.ops.info.name));
+		}
+		if (state->m_hasDVBT) {
+			state->frontend.ops.delsys[n++] = SYS_DVBT;
+			strlcat(state->frontend.ops.info.name, " DVB-T",
+				sizeof(state->frontend.ops.info.name));
+		}
 	}
 error:
 	if (status < 0)
@@ -6175,11 +6173,44 @@ error:
 	return status;
 }
 
+static void load_firmware_cb(const struct firmware *fw,
+			     void *context)
+{
+	struct drxk_state *state = context;
+
+	if (!fw) {
+		printk(KERN_ERR
+		       "drxk: Could not load firmware file %s.\n",
+			state->microcode_name);
+		printk(KERN_INFO
+		       "drxk: Copy %s to your hotplug directory!\n",
+			state->microcode_name);
+		state->microcode_name = NULL;
+
+		/*
+		 * As firmware is now load asynchronous, it is not possible
+		 * anymore to fail at frontend attach. We might silently
+		 * return here, and hope that the driver won't crash.
+		 * We might also change all DVB callbacks to return -ENODEV
+		 * if the device is not initialized.
+		 * As the DRX-K devices have their own internal firmware,
+		 * let's just hope that it will match a firmware revision
+		 * compatible with this driver and proceed.
+		 */
+	}
+	state->fw = fw;
+
+	init_drxk(state);
+}
+
 static void drxk_release(struct dvb_frontend *fe)
 {
 	struct drxk_state *state = fe->demodulator_priv;
 
 	dprintk(1, "\n");
+	if (state->fw)
+		release_firmware(state->fw);
+
 	kfree(state);
 }
 
@@ -6371,10 +6402,9 @@ static struct dvb_frontend_ops drxk_ops = {
 struct dvb_frontend *drxk_attach(const struct drxk_config *config,
 				 struct i2c_adapter *i2c)
 {
-	int n;
-
 	struct drxk_state *state = NULL;
 	u8 adr = config->adr;
+	int status;
 
 	dprintk(1, "\n");
 	state = kzalloc(sizeof(struct drxk_state), GFP_KERNEL);
@@ -6425,22 +6455,21 @@ struct dvb_frontend *drxk_attach(const struct drxk_config *config,
 	state->frontend.demodulator_priv = state;
 
 	init_state(state);
-	if (init_drxk(state) < 0)
-		goto error;
 
-	/* Initialize the supported delivery systems */
-	n = 0;
-	if (state->m_hasDVBC) {
-		state->frontend.ops.delsys[n++] = SYS_DVBC_ANNEX_A;
-		state->frontend.ops.delsys[n++] = SYS_DVBC_ANNEX_C;
-		strlcat(state->frontend.ops.info.name, " DVB-C",
-			sizeof(state->frontend.ops.info.name));
-	}
-	if (state->m_hasDVBT) {
-		state->frontend.ops.delsys[n++] = SYS_DVBT;
-		strlcat(state->frontend.ops.info.name, " DVB-T",
-			sizeof(state->frontend.ops.info.name));
-	}
+	/* Load firmware and initialize DRX-K */
+	if (state->microcode_name) {
+		status = request_firmware_nowait(THIS_MODULE, 1,
+					      state->microcode_name,
+					      state->i2c->dev.parent,
+					      GFP_KERNEL,
+					      state, load_firmware_cb);
+		if (status < 0) {
+			printk(KERN_ERR
+			"drxk: failed to request a firmware\n");
+			return NULL;
+		}
+	} else if (init_drxk(state) < 0)
+		goto error;
 
 	printk(KERN_INFO "drxk: frontend initialized.\n");
 	return &state->frontend;
diff --git a/drivers/media/dvb/frontends/drxk_hard.h b/drivers/media/dvb/frontends/drxk_hard.h
index 4bbf841..36677cd 100644
--- a/drivers/media/dvb/frontends/drxk_hard.h
+++ b/drivers/media/dvb/frontends/drxk_hard.h
@@ -338,7 +338,10 @@ struct drxk_state {
 	bool	antenna_dvbt;
 	u16	antenna_gpio;
 
+	/* Firmware */
 	const char *microcode_name;
+	struct completion fw_wait_load;
+	const struct firmware *fw;
 };
 
 #define NEVER_LOCK 0
-- 
1.7.10.2


^ permalink raw reply related	[flat|nested] 87+ messages in thread
[parent not found: <fa.90I1W/wmSTgRFXVG67o7Pp3+rKA@ifi.uio.no>]

end of thread, other threads:[~2012-10-12  1:55 UTC | newest]

Thread overview: 87+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-06-21 13:36 [PATCH] [media] drxk: change it to use request_firmware_nowait() Mauro Carvalho Chehab
2012-06-21 14:21 ` Devin Heitmueller
2012-06-21 15:09   ` Mauro Carvalho Chehab
2012-06-21 19:10 ` Mauro Carvalho Chehab
2012-06-22 14:11   ` Marko Ristola
2012-06-25 19:15   ` Antti Palosaari
2012-06-25 20:06     ` Mauro Carvalho Chehab
2012-06-25 20:47       ` Need of an ".async_probe()" type of callback at driver's core - Was: " Mauro Carvalho Chehab
2012-06-25 20:49       ` Mauro Carvalho Chehab
2012-06-25 22:33         ` Greg KH
2012-06-26  1:55           ` Mauro Carvalho Chehab
2012-06-26 19:34             ` [PATCH RFC 0/4] Defer probe() on em28xx when firmware load is required Mauro Carvalho Chehab
2012-06-26 19:34               ` [PATCH RFC 1/4] kmod: add a routine to return if usermode is disabled Mauro Carvalho Chehab
2012-06-26 20:38                 ` Greg KH
2012-06-26 21:05                   ` Mauro Carvalho Chehab
2012-06-26 19:34               ` [PATCH RFC 2/4] em28xx: defer probe() if userspace mode " Mauro Carvalho Chehab
2012-06-26 20:43                 ` Greg KH
2012-06-26 21:30                   ` Mauro Carvalho Chehab
2012-06-26 19:34               ` [PATCH RFC 3/4] em28xx: Workaround for new udev versions Mauro Carvalho Chehab
2012-06-26 20:40                 ` Greg KH
2012-06-26 21:07                   ` Mauro Carvalho Chehab
2012-06-26 21:56                     ` Kay Sievers
2012-06-26 20:42                 ` Greg KH
2012-06-26 21:21                   ` Mauro Carvalho Chehab
2012-06-26 21:27                     ` Greg KH
2012-06-26 22:01                       ` Mauro Carvalho Chehab
2012-06-28 17:51                         ` Mauro Carvalho Chehab
2012-06-26 19:34               ` [PATCH RFC 4/4] tuner-xc2028: tag the usual firmwares to help dracut Mauro Carvalho Chehab
2012-06-26 20:44                 ` Greg KH
2012-06-26 21:34                   ` Mauro Carvalho Chehab
2012-10-02 13:03             ` udev breakages - was: Re: Need of an ".async_probe()" type of callback at driver's core - Was: Re: [PATCH] [media] drxk: change it to use request_firmware_nowait() Mauro Carvalho Chehab
2012-10-02 16:33               ` Linus Torvalds
2012-10-02 21:03                 ` Ivan Kalvachev
2012-10-02 22:37                   ` Linus Torvalds
2012-10-03 22:15                     ` Lucas De Marchi
2012-10-11 18:33                     ` Shea Levy
2012-10-12  1:55                       ` Ming Lei
2012-10-02 22:12                 ` Greg KH
2012-10-02 22:23                   ` Greg KH
2012-10-02 22:47                     ` Linus Torvalds
2012-10-03  0:01                       ` Jiri Kosina
2012-10-03  0:12                         ` Linus Torvalds
2012-10-04 14:36                           ` Jiri Kosina
2012-10-03 15:13                       ` Mauro Carvalho Chehab
2012-10-03 16:38                         ` Linus Torvalds
2012-10-03 17:00                           ` Linus Torvalds
2012-10-03 17:09                           ` Al Viro
2012-10-03 17:32                             ` Linus Torvalds
2012-10-03 19:26                               ` Al Viro
2012-10-04  0:57                                 ` udev breakages - Nix
2012-10-04 10:35                                   ` Nix
2012-10-03 19:50                               ` udev breakages - was: Re: Need of an ".async_probe()" type of callback at driver's core - Was: Re: [PATCH] [media] drxk: change it to use request_firmware_nowait() Greg KH
2012-10-03 20:39                                 ` Linus Torvalds
2012-10-03 21:04                                   ` Kay Sievers
2012-10-03 21:05                                   ` Greg KH
2012-10-03 21:18                                     ` Kay Sievers
2012-10-03 21:45                                       ` Alan Cox
2012-10-03 21:58                                   ` Lucas De Marchi
2012-10-03 22:17                                     ` Linus Torvalds
2012-10-03 22:48                                   ` Andy Walls
2012-10-03 22:58                                     ` Linus Torvalds
2012-10-04  2:39                                       ` Kay Sievers
2012-10-04 17:29                                         ` udev breakages - Eric W. Biederman
2012-10-04 17:42                                           ` Greg KH
2012-10-04 19:17                                             ` Alan Cox
2012-10-10  3:19                                               ` Felipe Contreras
2012-10-10 16:08                                                 ` Geert Uytterhoeven
2012-10-11  3:32                                             ` Eric W. Biederman
2012-10-04 13:39                                       ` udev breakages - was: Re: Need of an ".async_probe()" type of callback at driver's core - Was: Re: [PATCH] [media] drxk: change it to use request_firmware_nowait() Josh Boyer
2012-10-04 13:58                                         ` Greg KH
2012-10-03 22:53                                   ` Stephen Rothwell
2012-10-03 21:10                                 ` Andy Walls
2012-10-03 19:48                           ` Access files from kernel Kirill A. Shutemov
2012-10-03 20:32                             ` Linus Torvalds
     [not found]                           ` <CACVXFVNTZmG+zTQNi9mCn9ynsCjkM084TmHKDcYYggtqLfhqNQ@mail.gmail.com>
2012-10-04  1:42                             ` udev breakages - was: Re: Need of an ".async_probe()" type of callback at driver's core - Was: Re: [PATCH] [media] drxk: change it to use request_firmware_nowait() Linus Torvalds
2012-10-03 14:12                     ` Mauro Carvalho Chehab
2012-10-03 14:36                   ` Kay Sievers
2012-10-03 14:44                     ` Linus Torvalds
2012-10-03 16:57                     ` Greg KH
2012-10-03 17:24                       ` Kay Sievers
2012-10-03 18:07                         ` Linus Torvalds
2012-10-03 19:46                       ` Mauro Carvalho Chehab
2012-06-29  8:26       ` Jean Delvare
     [not found] <fa.90I1W/wmSTgRFXVG67o7Pp3+rKA@ifi.uio.no>
     [not found] ` <fa.Oszo+r/ZqdTxC2FHqqg+CRVMJ5Y@ifi.uio.no>
     [not found]   ` <fa.CoxzZZId9dJONv353c+pFG/HO8E@ifi.uio.no>
     [not found]     ` <fa.ixJ/7D7BnMK8xp7CwikX7jbmnKU@ifi.uio.no>
     [not found]       ` <fa./ubRQE7P/T+ateohnOKdDxOFhL4@ifi.uio.no>
     [not found]         ` <fa.lpiFTa5CtuIkUf2Z5eJ0YlsNwYI@ifi.uio.no>
2012-10-04 14:50           ` udev breakages - was: Re: Need of an ".async_probe()" type of callback at driver's core - Was: " Kurt H Maier
2012-10-05  8:03             ` Emmanuel Benisty
2012-10-05 20:17               ` david
2012-10-05 21:43                 ` Henrique de Moraes Holschuh

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.