diff options
Diffstat (limited to 'drivers/clk/clk-versaclock5.c')
-rw-r--r-- | drivers/clk/clk-versaclock5.c | 42 |
1 files changed, 33 insertions, 9 deletions
diff --git a/drivers/clk/clk-versaclock5.c b/drivers/clk/clk-versaclock5.c index 3c737742c2a9..c6d3b1ab3d55 100644 --- a/drivers/clk/clk-versaclock5.c +++ b/drivers/clk/clk-versaclock5.c @@ -907,6 +907,7 @@ static const struct of_device_id clk_vc5_of_match[]; static int vc5_probe(struct i2c_client *client, const struct i2c_device_id *id) { + unsigned int oe, sd, src_mask = 0, src_val = 0; struct vc5_driver_data *vc5; struct clk_init_data init; const char *parent_names[2]; @@ -930,11 +931,33 @@ static int vc5_probe(struct i2c_client *client, const struct i2c_device_id *id) return -EPROBE_DEFER; vc5->regmap = devm_regmap_init_i2c(client, &vc5_regmap_config); - if (IS_ERR(vc5->regmap)) { - dev_err(&client->dev, "failed to allocate register map\n"); - return PTR_ERR(vc5->regmap); + if (IS_ERR(vc5->regmap)) + return dev_err_probe(&client->dev, PTR_ERR(vc5->regmap), + "failed to allocate register map\n"); + + ret = of_property_read_u32(client->dev.of_node, "idt,shutdown", &sd); + if (!ret) { + src_mask |= VC5_PRIM_SRC_SHDN_EN_GBL_SHDN; + if (sd) + src_val |= VC5_PRIM_SRC_SHDN_EN_GBL_SHDN; + } else if (ret != -EINVAL) { + return dev_err_probe(&client->dev, ret, + "could not read idt,shutdown\n"); } + ret = of_property_read_u32(client->dev.of_node, + "idt,output-enable-active", &oe); + if (!ret) { + src_mask |= VC5_PRIM_SRC_SHDN_SP; + if (oe) + src_val |= VC5_PRIM_SRC_SHDN_SP; + } else if (ret != -EINVAL) { + return dev_err_probe(&client->dev, ret, + "could not read idt,output-enable-active\n"); + } + + regmap_update_bits(vc5->regmap, VC5_PRIM_SRC_SHDN, src_mask, src_val); + /* Register clock input mux */ memset(&init, 0, sizeof(init)); @@ -957,10 +980,9 @@ static int vc5_probe(struct i2c_client *client, const struct i2c_device_id *id) __clk_get_name(vc5->pin_clkin); } - if (!init.num_parents) { - dev_err(&client->dev, "no input clock specified!\n"); - return -EINVAL; - } + if (!init.num_parents) + return dev_err_probe(&client->dev, -EINVAL, + "no input clock specified!\n"); /* Configure Optional Loading Capacitance for external XTAL */ if (!(vc5->chip_info->flags & VC5_HAS_INTERNAL_XTAL)) { @@ -1099,14 +1121,16 @@ static int vc5_probe(struct i2c_client *client, const struct i2c_device_id *id) ret = of_clk_add_hw_provider(client->dev.of_node, vc5_of_clk_get, vc5); if (ret) { - dev_err(&client->dev, "unable to add clk provider\n"); + dev_err_probe(&client->dev, ret, + "unable to add clk provider\n"); goto err_clk; } return 0; err_clk_register: - dev_err(&client->dev, "unable to register %s\n", init.name); + dev_err_probe(&client->dev, ret, + "unable to register %s\n", init.name); kfree(init.name); /* clock framework made a copy of the name */ err_clk: if (vc5->chip_info->flags & VC5_HAS_INTERNAL_XTAL) |