Instead of initializing the board during frontend attach, do it latter, when DVB core calls the .init() callback. Signed-off-by: Mauro Carvalho Chehab <mchehab@xxxxxxxxxxxxxxx> diff --git a/drivers/media/dvb-frontends/drxk_hard.c b/drivers/media/dvb-frontends/drxk_hard.c index f140b835c414..18c499acb4c8 100644 --- a/drivers/media/dvb-frontends/drxk_hard.c +++ b/drivers/media/dvb-frontends/drxk_hard.c @@ -541,7 +541,7 @@ error: } -static int init_state(struct drxk_state *state) +static void init_state(struct drxk_state *state) { /* * FIXME: most (all?) of the values bellow should be moved into @@ -773,7 +773,6 @@ static int init_state(struct drxk_state *state) state->m_rfmirror = (ul_rf_mirror == 0); state->m_if_agc_pol = false; - return 0; } static int drxx_open(struct drxk_state *state) @@ -6053,11 +6052,33 @@ error: static int init_drxk(struct drxk_state *state) { + struct dtv_frontend_properties *p; int status = 0, n = 0; enum drx_power_mode power_mode = DRXK_POWER_DOWN_OFDM; u16 driver_version; dprintk(1, "\n"); + + /* Initialize stats */ + p = &state->frontend.dtv_property_cache; + p->strength.len = 1; + p->cnr.len = 1; + p->block_error.len = 1; + p->block_count.len = 1; + p->pre_bit_error.len = 1; + p->pre_bit_count.len = 1; + p->post_bit_error.len = 1; + p->post_bit_count.len = 1; + + p->strength.stat[0].scale = FE_SCALE_RELATIVE; + p->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE; + p->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE; + p->block_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE; + p->pre_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE; + p->pre_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE; + p->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE; + p->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE; + if ((state->m_drxk_state == DRXK_UNINITIALIZED)) { drxk_i2c_lock(state); status = power_up_device(state); @@ -6276,33 +6297,32 @@ error: return status; } -static void load_firmware_cb(const struct firmware *fw, - void *context) +static void load_firmware_cb(struct drxk_state *state) { - struct drxk_state *state = context; + const struct firmware *fw = NULL; + int status; - dprintk(1, ": %s\n", fw ? "firmware loaded" : "firmware not loaded"); + status = request_firmware(&fw, state->microcode_name, + state->i2c->dev.parent); + if (status < 0) + fw = NULL; + + dprintk(1, ": firmware %s %s\n", state->microcode_name, + fw ? "loaded" : "not loaded"); if (!fw) { pr_err("Could not load firmware file %s.\n", state->microcode_name); pr_info("Copy %s to your hotplug directory!\n", state->microcode_name); - state->microcode_name = NULL; + pr_info("Trying to use the internal firmware, but this may not work well. Be warned.\n"); /* - * 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) @@ -6737,6 +6757,23 @@ static int drxk_get_tune_settings(struct dvb_frontend *fe, } } +static int drxk_init(struct dvb_frontend *fe) +{ + struct drxk_state *state = fe->demodulator_priv; + + /* + * FIXME: If we let init to run during resume, the frontend + * won't work anymore, on a suspend2ram. Letting it to be + * initialized also doesn't help for suspend2disk. So, let's + * just return for now. Probably, we need to do something else + * during suspend in order to allow to reload the firmware here. + */ + if (fe->exit == DVB_FE_DEVICE_RESUME) + return 0; + + return init_drxk(state); +} + static struct dvb_frontend_ops drxk_ops = { /* .delsys will be filled dynamically */ .info = { @@ -6760,6 +6797,7 @@ static struct dvb_frontend_ops drxk_ops = { .release = drxk_release, .sleep = drxk_sleep, .i2c_gate_ctrl = drxk_gate_ctrl, + .init = drxk_init, .set_frontend = drxk_set_parameters, .get_tune_settings = drxk_get_tune_settings, @@ -6773,10 +6811,8 @@ static struct dvb_frontend_ops drxk_ops = { struct dvb_frontend *drxk_attach(const struct drxk_config *config, struct i2c_adapter *i2c) { - struct dtv_frontend_properties *p; struct drxk_state *state = NULL; u8 adr = config->adr; - int status; dprintk(1, "\n"); state = kzalloc(sizeof(struct drxk_state), GFP_KERNEL); @@ -6802,7 +6838,6 @@ struct dvb_frontend *drxk_attach(const struct drxk_config *config, state->m_dvbc_static_clk = true; } - if (config->mpeg_out_clk_strength) state->m_ts_clockk_strength = config->mpeg_out_clk_strength & 0x07; else @@ -6827,48 +6862,14 @@ struct dvb_frontend *drxk_attach(const struct drxk_config *config, memcpy(&state->frontend.ops, &drxk_ops, sizeof(drxk_ops)); state->frontend.demodulator_priv = state; - init_state(state); - /* Load firmware and initialize DRX-K */ - if (state->microcode_name) { - const struct firmware *fw = NULL; + if (state->microcode_name) + load_firmware_cb(state); - status = request_firmware(&fw, state->microcode_name, - state->i2c->dev.parent); - if (status < 0) - fw = NULL; - load_firmware_cb(fw, state); - } else if (init_drxk(state) < 0) - goto error; + init_state(state); - - /* Initialize stats */ - p = &state->frontend.dtv_property_cache; - p->strength.len = 1; - p->cnr.len = 1; - p->block_error.len = 1; - p->block_count.len = 1; - p->pre_bit_error.len = 1; - p->pre_bit_count.len = 1; - p->post_bit_error.len = 1; - p->post_bit_count.len = 1; - - p->strength.stat[0].scale = FE_SCALE_RELATIVE; - p->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE; - p->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE; - p->block_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE; - p->pre_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE; - p->pre_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE; - p->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE; - p->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE; - - pr_info("frontend initialized.\n"); + pr_info("frontend attached.\n"); return &state->frontend; - -error: - pr_err("not found\n"); - kfree(state); - return NULL; } EXPORT_SYMBOL(drxk_attach); -- 1.9.3 -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html