mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-06 02:50:49 +09:00
mfd: display-serdes: Fix system crash caused by serdes_init_seq being a null pointer
When the serdes-init-sequence is not configured, serdes_init_seq is a null pointer. However, some serdes initializations do not require the serdes_init_seq configuration, so the driver needs to execute normally even when the serdes-init-sequence is not configured. Change-Id: Id01f0921c9050db5c20f6ad075ddd47891f68bcb Signed-off-by: Zitong Cai <zitong.cai@rock-chips.com>
This commit is contained in:
@@ -17,6 +17,9 @@ int serdes_i2c_set_sequence(struct serdes *serdes)
|
||||
int i, num = 0, ret = 0;
|
||||
unsigned int def = 0;
|
||||
|
||||
if (!serdes->serdes_init_seq)
|
||||
return 0;
|
||||
|
||||
for (i = 0; i < serdes->serdes_init_seq->reg_seq_cnt; i++) {
|
||||
if (serdes->serdes_init_seq->reg_sequence[i].reg == 0xffff) {
|
||||
SERDES_DBG_MFD("%s: delay 0x%04x us\n", __func__,
|
||||
@@ -195,10 +198,13 @@ static void serdes_reg_check_work(struct kthread_work *work)
|
||||
}
|
||||
|
||||
serdes_i2c_check_register(serdes, &flag);
|
||||
|
||||
if (flag) {
|
||||
|
||||
if (serdes->chip_data->chip_init)
|
||||
serdes->chip_data->chip_init(serdes);
|
||||
serdes_i2c_set_sequence_backup(serdes);
|
||||
|
||||
msleep(500);
|
||||
SERDES_DBG_MFD("%s %s\n", __func__, serdes->chip_data->name);
|
||||
}
|
||||
@@ -208,6 +214,9 @@ static void serdes_reg_check_work(struct kthread_work *work)
|
||||
|
||||
static int serdes_reg_check_work_setup(struct serdes *serdes)
|
||||
{
|
||||
if (!serdes->serdes_backup_seq || !serdes->serdes_backup_seq->reg_seq_cnt)
|
||||
return 0;
|
||||
|
||||
kthread_init_delayed_work(&serdes->reg_check_work,
|
||||
serdes_reg_check_work);
|
||||
|
||||
@@ -220,6 +229,8 @@ static int serdes_reg_check_work_setup(struct serdes *serdes)
|
||||
kthread_queue_delayed_work(serdes->kworker, &serdes->reg_check_work,
|
||||
msecs_to_jiffies(20000));
|
||||
|
||||
SERDES_DBG_MFD("serdes %s use_reg_check_work\n", serdes->chip_data->name);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -285,7 +296,7 @@ static int serdes_get_init_seq(struct serdes *serdes)
|
||||
data = of_get_property(np, "serdes-init-sequence", &len);
|
||||
if (!data) {
|
||||
dev_err(dev, "failed to get serdes-init-sequence\n");
|
||||
return -EINVAL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
serdes->serdes_init_seq = devm_kzalloc(dev, sizeof(*serdes->serdes_init_seq),
|
||||
@@ -310,8 +321,6 @@ static int serdes_get_init_seq(struct serdes *serdes)
|
||||
return err;
|
||||
}
|
||||
|
||||
serdes->dual_link = of_property_read_bool(dev->of_node, "dual-link");
|
||||
|
||||
/* init ser register(not des register) more early if uboot logo disabled */
|
||||
serdes->route_enable = of_property_read_bool(dev->of_node, "route-enable");
|
||||
if ((!serdes->route_enable) && (serdes->chip_data->serdes_type == TYPE_SER)) {
|
||||
@@ -374,6 +383,8 @@ static int serdes_i2c_probe(struct i2c_client *client,
|
||||
}
|
||||
}
|
||||
|
||||
serdes->dual_link = of_property_read_bool(dev->of_node, "dual-link");
|
||||
|
||||
serdes->extcon = devm_extcon_dev_allocate(dev, serdes_cable);
|
||||
if (IS_ERR(serdes->extcon))
|
||||
return dev_err_probe(dev, PTR_ERR(serdes->extcon),
|
||||
@@ -442,12 +453,9 @@ static int serdes_i2c_probe(struct i2c_client *client,
|
||||
}
|
||||
|
||||
serdes->use_reg_check_work = of_property_read_bool(dev->of_node, "use-reg-check-work");
|
||||
if (serdes->use_reg_check_work) {
|
||||
if (serdes->use_reg_check_work)
|
||||
serdes_reg_check_work_setup(serdes);
|
||||
|
||||
SERDES_DBG_MFD("%s: use_reg_check_work=%d\n", __func__, serdes->use_reg_check_work);
|
||||
}
|
||||
|
||||
serdes_create_debugfs(serdes);
|
||||
|
||||
dev_info(dev, "serdes %s serdes_i2c_probe successful version %s\n",
|
||||
@@ -469,7 +477,7 @@ static void serdes_i2c_remove(struct i2c_client *client)
|
||||
struct device *dev = &client->dev;
|
||||
struct serdes *serdes = dev_get_drvdata(dev);
|
||||
|
||||
if (serdes->use_reg_check_work)
|
||||
if (!IS_ERR_OR_NULL(serdes->kworker))
|
||||
serdes_reg_check_work_free(serdes);
|
||||
|
||||
if (serdes->use_delay_work) {
|
||||
|
||||
Reference in New Issue
Block a user