summaryrefslogtreecommitdiff
path: root/drivers/scsi
diff options
context:
space:
mode:
authorSahitya Tummala <stummala@codeaurora.org>2014-09-25 15:32:33 +0300
committerChristoph Hellwig <hch@lst.de>2014-10-01 13:11:25 +0200
commit4cff6d991e4a291cf50fe2659da2ea9ad46620bf (patch)
treec82f172707927470412a8ec0c2ff2feb5bc8baa7 /drivers/scsi
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>
Diffstat (limited to 'drivers/scsi')
-rw-r--r--drivers/scsi/ufs/ufshcd-pltfrm.c48
-rw-r--r--drivers/scsi/ufs/ufshcd.h2
2 files changed, 37 insertions, 13 deletions
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)
char *name;
u32 *clkfreq = NULL;
struct ufs_clk_info *clki;
+ int len = 0;
+ size_t sz = 0;
if (!np)
goto out;
@@ -82,39 +84,59 @@ static int ufshcd_parse_clock_info(struct ufs_hba *hba)
if (cnt <= 0)
goto out;
- clkfreq = kzalloc(cnt * sizeof(*clkfreq), GFP_KERNEL);
+ if (!of_get_property(np, "freq-table-hz", &len)) {
+ dev_info(dev, "freq-table-hz property not specified\n");
+ goto out;
+ }
+
+ if (len <= 0)
+ goto out;
+
+ sz = len / sizeof(*clkfreq);
+ if (sz != 2 * cnt) {
+ dev_err(dev, "%s len mismatch\n", "freq-table-hz");
+ ret = -EINVAL;
+ goto out;
+ }
+
+ clkfreq = devm_kzalloc(dev, sz * sizeof(*clkfreq),
+ GFP_KERNEL);
if (!clkfreq) {
+ dev_err(dev, "%s: no memory\n", "freq-table-hz");
ret = -ENOMEM;
- dev_err(dev, "%s: memory alloc failed\n", __func__);
goto out;
}
- ret = of_property_read_u32_array(np,
- "max-clock-frequency-hz", clkfreq, cnt);
+ ret = of_property_read_u32_array(np, "freq-table-hz",
+ clkfreq, sz);
if (ret && (ret != -EINVAL)) {
- dev_err(dev, "%s: invalid max-clock-frequency-hz property, %d\n",
- __func__, ret);
- goto out;
+ dev_err(dev, "%s: error reading array %d\n",
+ "freq-table-hz", ret);
+ goto free_clkfreq;
}
- for (i = 0; i < cnt; i++) {
+ for (i = 0; i < sz; i += 2) {
ret = of_property_read_string_index(np,
- "clock-names", i, (const char **)&name);
+ "clock-names", i/2, (const char **)&name);
if (ret)
- goto out;
+ goto free_clkfreq;
clki = devm_kzalloc(dev, sizeof(*clki), GFP_KERNEL);
if (!clki) {
ret = -ENOMEM;
- goto out;
+ goto free_clkfreq;
}
- clki->max_freq = clkfreq[i];
+ clki->min_freq = clkfreq[i];
+ clki->max_freq = clkfreq[i+1];
clki->name = kstrdup(name, GFP_KERNEL);
+ dev_dbg(dev, "%s: min %u max %u name %s\n", "freq-table-hz",
+ clki->min_freq, clki->max_freq, clki->name);
list_add_tail(&clki->list, &hba->clk_list_head);
}
-out:
+free_clkfreq:
kfree(clkfreq);
+out:
return ret;
}
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 {
* @clk: clock node
* @name: clock name
* @max_freq: maximum frequency supported by the clock
+ * @min_freq: min frequency that can be used for clock scaling
* @enabled: variable to check against multiple enable/disable
*/
struct ufs_clk_info {
@@ -216,6 +217,7 @@ struct ufs_clk_info {
struct clk *clk;
const char *name;
u32 max_freq;
+ u32 min_freq;
bool enabled;
};