aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSahitya Tummala <stummala@codeaurora.org>2014-09-25 08:32:33 -0400
committerChristoph Hellwig <hch@lst.de>2014-10-01 07:11:25 -0400
commit4cff6d991e4a291cf50fe2659da2ea9ad46620bf (patch)
treec82f172707927470412a8ec0c2ff2feb5bc8baa7
parent1ab27c9cf8b63dd8dec9e17b5c17721c7f3b6cc7 (diff)
ufs: Add freq-table-hz property for UFS device
Add freq-table-hz propery for UFS device to keep track of <min max> frequencies supported by UFS clocks. Signed-off-by: Sahitya Tummala <stummala@codeaurora.org> Signed-off-by: Dolev Raviv <draviv@codeaurora.org> Signed-off-by: Christoph Hellwig <hch@lst.de>
-rw-r--r--Documentation/devicetree/bindings/ufs/ufshcd-pltfrm.txt12
-rw-r--r--drivers/scsi/ufs/ufshcd-pltfrm.c48
-rw-r--r--drivers/scsi/ufs/ufshcd.h2
3 files changed, 43 insertions, 19 deletions
diff --git a/Documentation/devicetree/bindings/ufs/ufshcd-pltfrm.txt b/Documentation/devicetree/bindings/ufs/ufshcd-pltfrm.txt
index fb1234e0532c..53579197eca2 100644
--- a/Documentation/devicetree/bindings/ufs/ufshcd-pltfrm.txt
+++ b/Documentation/devicetree/bindings/ufs/ufshcd-pltfrm.txt
@@ -26,11 +26,11 @@ Optional properties:
26- clocks : List of phandle and clock specifier pairs 26- clocks : List of phandle and clock specifier pairs
27- clock-names : List of clock input name strings sorted in the same 27- clock-names : List of clock input name strings sorted in the same
28 order as the clocks property. 28 order as the clocks property.
29- max-clock-frequency-hz : List of maximum operating frequency stored in the same 29- freq-table-hz : Array of <min max> operating frequencies stored in the same
30 order as the clocks property. If this property is not 30 order as the clocks property. If this property is not
31 defined or a value in the array is "0" then it is assumed 31 defined or a value in the array is "0" then it is assumed
32 that the frequency is set by the parent clock or a 32 that the frequency is set by the parent clock or a
33 fixed rate clock source. 33 fixed rate clock source.
34 34
35Note: If above properties are not defined it can be assumed that the supply 35Note: If above properties are not defined it can be assumed that the supply
36regulators or clocks are always on. 36regulators or clocks are always on.
@@ -53,5 +53,5 @@ Example:
53 53
54 clocks = <&core 0>, <&ref 0>, <&iface 0>; 54 clocks = <&core 0>, <&ref 0>, <&iface 0>;
55 clock-names = "core_clk", "ref_clk", "iface_clk"; 55 clock-names = "core_clk", "ref_clk", "iface_clk";
56 max-clock-frequency-hz = <100000000 19200000 0>; 56 freq-table-hz = <100000000 200000000>, <0 0>, <0 0>;
57 }; 57 };
diff --git a/drivers/scsi/ufs/ufshcd-pltfrm.c b/drivers/scsi/ufs/ufshcd-pltfrm.c
index 2482bbac3681..8adf067ff019 100644
--- a/drivers/scsi/ufs/ufshcd-pltfrm.c
+++ b/drivers/scsi/ufs/ufshcd-pltfrm.c
@@ -63,6 +63,8 @@ static int ufshcd_parse_clock_info(struct ufs_hba *hba)
63 char *name; 63 char *name;
64 u32 *clkfreq = NULL; 64 u32 *clkfreq = NULL;
65 struct ufs_clk_info *clki; 65 struct ufs_clk_info *clki;
66 int len = 0;
67 size_t sz = 0;
66 68
67 if (!np) 69 if (!np)
68 goto out; 70 goto out;
@@ -82,39 +84,59 @@ static int ufshcd_parse_clock_info(struct ufs_hba *hba)
82 if (cnt <= 0) 84 if (cnt <= 0)
83 goto out; 85 goto out;
84 86
85 clkfreq = kzalloc(cnt * sizeof(*clkfreq), GFP_KERNEL); 87 if (!of_get_property(np, "freq-table-hz", &len)) {
88 dev_info(dev, "freq-table-hz property not specified\n");
89 goto out;
90 }
91
92 if (len <= 0)
93 goto out;
94
95 sz = len / sizeof(*clkfreq);
96 if (sz != 2 * cnt) {
97 dev_err(dev, "%s len mismatch\n", "freq-table-hz");
98 ret = -EINVAL;
99 goto out;
100 }
101
102 clkfreq = devm_kzalloc(dev, sz * sizeof(*clkfreq),
103 GFP_KERNEL);
86 if (!clkfreq) { 104 if (!clkfreq) {
105 dev_err(dev, "%s: no memory\n", "freq-table-hz");
87 ret = -ENOMEM; 106 ret = -ENOMEM;
88 dev_err(dev, "%s: memory alloc failed\n", __func__);
89 goto out; 107 goto out;
90 } 108 }
91 109
92 ret = of_property_read_u32_array(np, 110 ret = of_property_read_u32_array(np, "freq-table-hz",
93 "max-clock-frequency-hz", clkfreq, cnt); 111 clkfreq, sz);
94 if (ret && (ret != -EINVAL)) { 112 if (ret && (ret != -EINVAL)) {
95 dev_err(dev, "%s: invalid max-clock-frequency-hz property, %d\n", 113 dev_err(dev, "%s: error reading array %d\n",
96 __func__, ret); 114 "freq-table-hz", ret);
97 goto out; 115 goto free_clkfreq;
98 } 116 }
99 117
100 for (i = 0; i < cnt; i++) { 118 for (i = 0; i < sz; i += 2) {
101 ret = of_property_read_string_index(np, 119 ret = of_property_read_string_index(np,
102 "clock-names", i, (const char **)&name); 120 "clock-names", i/2, (const char **)&name);
103 if (ret) 121 if (ret)
104 goto out; 122 goto free_clkfreq;
105 123
106 clki = devm_kzalloc(dev, sizeof(*clki), GFP_KERNEL); 124 clki = devm_kzalloc(dev, sizeof(*clki), GFP_KERNEL);
107 if (!clki) { 125 if (!clki) {
108 ret = -ENOMEM; 126 ret = -ENOMEM;
109 goto out; 127 goto free_clkfreq;
110 } 128 }
111 129
112 clki->max_freq = clkfreq[i]; 130 clki->min_freq = clkfreq[i];
131 clki->max_freq = clkfreq[i+1];
113 clki->name = kstrdup(name, GFP_KERNEL); 132 clki->name = kstrdup(name, GFP_KERNEL);
133 dev_dbg(dev, "%s: min %u max %u name %s\n", "freq-table-hz",
134 clki->min_freq, clki->max_freq, clki->name);
114 list_add_tail(&clki->list, &hba->clk_list_head); 135 list_add_tail(&clki->list, &hba->clk_list_head);
115 } 136 }
116out: 137free_clkfreq:
117 kfree(clkfreq); 138 kfree(clkfreq);
139out:
118 return ret; 140 return ret;
119} 141}
120 142
diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h
index 29d34d3aa5ee..ac72a6daf50e 100644
--- a/drivers/scsi/ufs/ufshcd.h
+++ b/drivers/scsi/ufs/ufshcd.h
@@ -209,6 +209,7 @@ struct ufs_dev_cmd {
209 * @clk: clock node 209 * @clk: clock node
210 * @name: clock name 210 * @name: clock name
211 * @max_freq: maximum frequency supported by the clock 211 * @max_freq: maximum frequency supported by the clock
212 * @min_freq: min frequency that can be used for clock scaling
212 * @enabled: variable to check against multiple enable/disable 213 * @enabled: variable to check against multiple enable/disable
213 */ 214 */
214struct ufs_clk_info { 215struct ufs_clk_info {
@@ -216,6 +217,7 @@ struct ufs_clk_info {
216 struct clk *clk; 217 struct clk *clk;
217 const char *name; 218 const char *name;
218 u32 max_freq; 219 u32 max_freq;
220 u32 min_freq;
219 bool enabled; 221 bool enabled;
220}; 222};
221 223