aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/clk/clk-versaclock5.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/clk/clk-versaclock5.c')
-rw-r--r--drivers/clk/clk-versaclock5.c42
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)