Merge tag 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rdma/rdma
[linux-2.6-microblaze.git] / drivers / clk / clk-versaclock5.c
index 3c73774..c6d3b1a 100644 (file)
@@ -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)