* [PATCH v1 1/5] rtc: m41t80: m41t80_sqw_set_rate should return 0 on success
@ 2017-11-03 1:58 Troy Kisky
2017-11-03 1:58 ` [PATCH v1 2/5] rtc: m41t80: fix m41t80_sqw_round_rate return value Troy Kisky
` (4 more replies)
0 siblings, 5 replies; 6+ messages in thread
From: Troy Kisky @ 2017-11-03 1:58 UTC (permalink / raw)
To: a.zummo, alexandre.belloni; +Cc: gary.bisson, linux-rtc, Troy Kisky
Previously it was returning -EINVAL upon success.
Signed-off-by: Troy Kisky <troy.kisky@boundarydevices.com>
---
drivers/rtc/rtc-m41t80.c | 5 +----
1 file changed, 1 insertion(+), 4 deletions(-)
diff --git a/drivers/rtc/rtc-m41t80.c b/drivers/rtc/rtc-m41t80.c
index f4c070ea8384..8f5843169dc2 100644
--- a/drivers/rtc/rtc-m41t80.c
+++ b/drivers/rtc/rtc-m41t80.c
@@ -510,10 +510,7 @@ static int m41t80_sqw_set_rate(struct clk_hw *hw, unsigned long rate,
reg = (reg & 0x0f) | (val << 4);
ret = i2c_smbus_write_byte_data(client, reg_sqw, reg);
- if (ret < 0)
- return ret;
-
- return -EINVAL;
+ return ret;
}
static int m41t80_sqw_control(struct clk_hw *hw, bool enable)
--
2.11.0
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH v1 2/5] rtc: m41t80: fix m41t80_sqw_round_rate return value
2017-11-03 1:58 [PATCH v1 1/5] rtc: m41t80: m41t80_sqw_set_rate should return 0 on success Troy Kisky
@ 2017-11-03 1:58 ` Troy Kisky
2017-11-03 1:58 ` [PATCH v1 3/5] rtc: m41t80: avoid i2c read in m41t80_sqw_recalc_rate Troy Kisky
` (3 subsequent siblings)
4 siblings, 0 replies; 6+ messages in thread
From: Troy Kisky @ 2017-11-03 1:58 UTC (permalink / raw)
To: a.zummo, alexandre.belloni; +Cc: gary.bisson, linux-rtc, Troy Kisky
Previously it was returning the best of
32768, 8192, 1024, 64, 2, 0
Now, best of
32768, 8192, 4096, 2048, 1024, 512, 256, 128,
64, 32, 16, 8, 4, 2, 1, 0
Signed-off-by: Troy Kisky <troy.kisky@boundarydevices.com>
---
drivers/rtc/rtc-m41t80.c | 19 +++++++------------
1 file changed, 7 insertions(+), 12 deletions(-)
diff --git a/drivers/rtc/rtc-m41t80.c b/drivers/rtc/rtc-m41t80.c
index 8f5843169dc2..42fc735a5446 100644
--- a/drivers/rtc/rtc-m41t80.c
+++ b/drivers/rtc/rtc-m41t80.c
@@ -468,18 +468,13 @@ static unsigned long m41t80_sqw_recalc_rate(struct clk_hw *hw,
static long m41t80_sqw_round_rate(struct clk_hw *hw, unsigned long rate,
unsigned long *prate)
{
- int i, freq = M41T80_SQW_MAX_FREQ;
-
- if (freq <= rate)
- return freq;
-
- for (i = 2; i <= ilog2(M41T80_SQW_MAX_FREQ); i++) {
- freq /= 1 << i;
- if (freq <= rate)
- return freq;
- }
-
- return 0;
+ if (rate >= M41T80_SQW_MAX_FREQ)
+ return M41T80_SQW_MAX_FREQ;
+ if (rate >= M41T80_SQW_MAX_FREQ / 4)
+ return M41T80_SQW_MAX_FREQ / 4;
+ if (!rate)
+ return 0;
+ return 1 << ilog2(rate);
}
static int m41t80_sqw_set_rate(struct clk_hw *hw, unsigned long rate,
--
2.11.0
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH v1 3/5] rtc: m41t80: avoid i2c read in m41t80_sqw_recalc_rate
2017-11-03 1:58 [PATCH v1 1/5] rtc: m41t80: m41t80_sqw_set_rate should return 0 on success Troy Kisky
2017-11-03 1:58 ` [PATCH v1 2/5] rtc: m41t80: fix m41t80_sqw_round_rate return value Troy Kisky
@ 2017-11-03 1:58 ` Troy Kisky
2017-11-03 1:58 ` [PATCH v1 4/5] rtc: m41t80: avoid i2c read in m41t80_sqw_is_prepared Troy Kisky
` (2 subsequent siblings)
4 siblings, 0 replies; 6+ messages in thread
From: Troy Kisky @ 2017-11-03 1:58 UTC (permalink / raw)
To: a.zummo, alexandre.belloni; +Cc: gary.bisson, linux-rtc, Troy Kisky
This is a little more efficient, and avoids the warning
WARNING: possible circular locking dependency detected
4.14.0-rc7-00007 #14 Not tainted
------------------------------------------------------
alsactl/330 is trying to acquire lock:
(prepare_lock){+.+.}, at: [<c049300c>] clk_prepare_lock+0x80/0xf4
but task is already holding lock:
(i2c_register_adapter){+.+.}, at: [<c0690ae0>]
i2c_adapter_lock_bus+0x14/0x18
which lock already depends on the new lock.
the existing dependency chain (in reverse order) is:
-> #1 (i2c_register_adapter){+.+.}:
rt_mutex_lock+0x44/0x5c
i2c_adapter_lock_bus+0x14/0x18
i2c_transfer+0xa8/0xbc
i2c_smbus_xfer+0x20c/0x5d8
i2c_smbus_read_byte_data+0x38/0x48
m41t80_sqw_recalc_rate+0x24/0x58
Signed-off-by: Troy Kisky <troy.kisky@boundarydevices.com>
---
drivers/rtc/rtc-m41t80.c | 28 +++++++++++++++++-----------
1 file changed, 17 insertions(+), 11 deletions(-)
diff --git a/drivers/rtc/rtc-m41t80.c b/drivers/rtc/rtc-m41t80.c
index 42fc735a5446..f44dcf628c87 100644
--- a/drivers/rtc/rtc-m41t80.c
+++ b/drivers/rtc/rtc-m41t80.c
@@ -154,6 +154,7 @@ struct m41t80_data {
struct rtc_device *rtc;
#ifdef CONFIG_COMMON_CLK
struct clk_hw sqw;
+ unsigned long freq;
#endif
};
@@ -443,26 +444,28 @@ static SIMPLE_DEV_PM_OPS(m41t80_pm, m41t80_suspend, m41t80_resume);
#ifdef CONFIG_COMMON_CLK
#define sqw_to_m41t80_data(_hw) container_of(_hw, struct m41t80_data, sqw)
-static unsigned long m41t80_sqw_recalc_rate(struct clk_hw *hw,
- unsigned long parent_rate)
+static unsigned long m41t80_decode_freq(int setting)
+{
+ return (setting == 0) ? 0 : (setting == 1) ? M41T80_SQW_MAX_FREQ :
+ M41T80_SQW_MAX_FREQ >> setting;
+}
+
+static unsigned long m41t80_get_freq(struct m41t80_data *m41t80)
{
- struct m41t80_data *m41t80 = sqw_to_m41t80_data(hw);
struct i2c_client *client = m41t80->client;
int reg_sqw = (m41t80->features & M41T80_FEATURE_SQ_ALT) ?
M41T80_REG_WDAY : M41T80_REG_SQW;
int ret = i2c_smbus_read_byte_data(client, reg_sqw);
- unsigned long val = M41T80_SQW_MAX_FREQ;
if (ret < 0)
return 0;
+ return m41t80_decode_freq(ret >> 4);
+}
- ret >>= 4;
- if (ret == 0)
- val = 0;
- else if (ret > 1)
- val = val / (1 << ret);
-
- return val;
+static unsigned long m41t80_sqw_recalc_rate(struct clk_hw *hw,
+ unsigned long parent_rate)
+{
+ return sqw_to_m41t80_data(hw)->freq;
}
static long m41t80_sqw_round_rate(struct clk_hw *hw, unsigned long rate,
@@ -505,6 +508,8 @@ static int m41t80_sqw_set_rate(struct clk_hw *hw, unsigned long rate,
reg = (reg & 0x0f) | (val << 4);
ret = i2c_smbus_write_byte_data(client, reg_sqw, reg);
+ if (!ret)
+ m41t80->freq = m41t80_decode_freq(val);
return ret;
}
@@ -579,6 +584,7 @@ static struct clk *m41t80_sqw_register_clk(struct m41t80_data *m41t80)
init.parent_names = NULL;
init.num_parents = 0;
m41t80->sqw.init = &init;
+ m41t80->freq = m41t80_get_freq(m41t80);
/* optional override of the clockname */
of_property_read_string(node, "clock-output-names", &init.name);
--
2.11.0
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH v1 4/5] rtc: m41t80: avoid i2c read in m41t80_sqw_is_prepared
2017-11-03 1:58 [PATCH v1 1/5] rtc: m41t80: m41t80_sqw_set_rate should return 0 on success Troy Kisky
2017-11-03 1:58 ` [PATCH v1 2/5] rtc: m41t80: fix m41t80_sqw_round_rate return value Troy Kisky
2017-11-03 1:58 ` [PATCH v1 3/5] rtc: m41t80: avoid i2c read in m41t80_sqw_recalc_rate Troy Kisky
@ 2017-11-03 1:58 ` Troy Kisky
2017-11-03 1:58 ` [PATCH v1 5/5] rtc: m41t80: remove unneeded checks from m41t80_sqw_set_rate Troy Kisky
2017-11-08 2:13 ` [PATCH v1 1/5] rtc: m41t80: m41t80_sqw_set_rate should return 0 on success Alexandre Belloni
4 siblings, 0 replies; 6+ messages in thread
From: Troy Kisky @ 2017-11-03 1:58 UTC (permalink / raw)
To: a.zummo, alexandre.belloni; +Cc: gary.bisson, linux-rtc, Troy Kisky
This is a little more efficient and avoids the warning
WARNING: possible circular locking dependency detected
4.14.0-rc7-00010 #16 Not tainted
------------------------------------------------------
kworker/2:1/70 is trying to acquire lock:
(prepare_lock){+.+.}, at: [<c049300c>] clk_prepare_lock+0x80/0xf4
but task is already holding lock:
(i2c_register_adapter){+.+.}, at: [<c0690b04>]
i2c_adapter_lock_bus+0x14/0x18
which lock already depends on the new lock.
the existing dependency chain (in reverse order) is:
-> #1 (i2c_register_adapter){+.+.}:
rt_mutex_lock+0x44/0x5c
i2c_adapter_lock_bus+0x14/0x18
i2c_transfer+0xa8/0xbc
i2c_smbus_xfer+0x20c/0x5d8
i2c_smbus_read_byte_data+0x38/0x48
m41t80_sqw_is_prepared+0x18/0x28
Signed-off-by: Troy Kisky <troy.kisky@boundarydevices.com>
---
drivers/rtc/rtc-m41t80.c | 15 ++++++---------
1 file changed, 6 insertions(+), 9 deletions(-)
diff --git a/drivers/rtc/rtc-m41t80.c b/drivers/rtc/rtc-m41t80.c
index f44dcf628c87..96a606d5f6e6 100644
--- a/drivers/rtc/rtc-m41t80.c
+++ b/drivers/rtc/rtc-m41t80.c
@@ -155,6 +155,7 @@ struct m41t80_data {
#ifdef CONFIG_COMMON_CLK
struct clk_hw sqw;
unsigned long freq;
+ unsigned int sqwe;
#endif
};
@@ -527,7 +528,10 @@ static int m41t80_sqw_control(struct clk_hw *hw, bool enable)
else
ret &= ~M41T80_ALMON_SQWE;
- return i2c_smbus_write_byte_data(client, M41T80_REG_ALARM_MON, ret);
+ ret = i2c_smbus_write_byte_data(client, M41T80_REG_ALARM_MON, ret);
+ if (!ret)
+ m41t80->sqwe = enable;
+ return ret;
}
static int m41t80_sqw_prepare(struct clk_hw *hw)
@@ -542,14 +546,7 @@ static void m41t80_sqw_unprepare(struct clk_hw *hw)
static int m41t80_sqw_is_prepared(struct clk_hw *hw)
{
- struct m41t80_data *m41t80 = sqw_to_m41t80_data(hw);
- struct i2c_client *client = m41t80->client;
- int ret = i2c_smbus_read_byte_data(client, M41T80_REG_ALARM_MON);
-
- if (ret < 0)
- return ret;
-
- return !!(ret & M41T80_ALMON_SQWE);
+ return sqw_to_m41t80_data(hw)->sqwe;
}
static const struct clk_ops m41t80_sqw_ops = {
--
2.11.0
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH v1 5/5] rtc: m41t80: remove unneeded checks from m41t80_sqw_set_rate
2017-11-03 1:58 [PATCH v1 1/5] rtc: m41t80: m41t80_sqw_set_rate should return 0 on success Troy Kisky
` (2 preceding siblings ...)
2017-11-03 1:58 ` [PATCH v1 4/5] rtc: m41t80: avoid i2c read in m41t80_sqw_is_prepared Troy Kisky
@ 2017-11-03 1:58 ` Troy Kisky
2017-11-08 2:13 ` [PATCH v1 1/5] rtc: m41t80: m41t80_sqw_set_rate should return 0 on success Alexandre Belloni
4 siblings, 0 replies; 6+ messages in thread
From: Troy Kisky @ 2017-11-03 1:58 UTC (permalink / raw)
To: a.zummo, alexandre.belloni; +Cc: gary.bisson, linux-rtc, Troy Kisky
m41t80_sqw_set_rate will be called with the result from
m41t80_sqw_round_rate, so might as well make
m41t80_sqw_set_rate(n) same as
m41t80_sqw_set_rate(m41t80_sqw_round_rate(n))
As Russell King wrote[1],
"clk_round_rate() is supposed to tell you what you end up with if you
ask clk_set_rate() to set the exact same value you passed in - but
clk_round_rate() won't modify the hardware."
[1]
http://lists.infradead.org/pipermail/linux-arm-kernel/2012-January/080175.html
Signed-off-by: Troy Kisky <troy.kisky@boundarydevices.com>
---
drivers/rtc/rtc-m41t80.c | 17 ++++++-----------
1 file changed, 6 insertions(+), 11 deletions(-)
diff --git a/drivers/rtc/rtc-m41t80.c b/drivers/rtc/rtc-m41t80.c
index 96a606d5f6e6..c90fba3ed861 100644
--- a/drivers/rtc/rtc-m41t80.c
+++ b/drivers/rtc/rtc-m41t80.c
@@ -490,17 +490,12 @@ static int m41t80_sqw_set_rate(struct clk_hw *hw, unsigned long rate,
M41T80_REG_WDAY : M41T80_REG_SQW;
int reg, ret, val = 0;
- if (rate) {
- if (!is_power_of_2(rate))
- return -EINVAL;
- val = ilog2(rate);
- if (val == ilog2(M41T80_SQW_MAX_FREQ))
- val = 1;
- else if (val < (ilog2(M41T80_SQW_MAX_FREQ) - 1))
- val = ilog2(M41T80_SQW_MAX_FREQ) - val;
- else
- return -EINVAL;
- }
+ if (rate >= M41T80_SQW_MAX_FREQ)
+ val = 1;
+ else if (rate >= M41T80_SQW_MAX_FREQ / 4)
+ val = 2;
+ else if (rate)
+ val = 15 - ilog2(rate);
reg = i2c_smbus_read_byte_data(client, reg_sqw);
if (reg < 0)
--
2.11.0
^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH v1 1/5] rtc: m41t80: m41t80_sqw_set_rate should return 0 on success
2017-11-03 1:58 [PATCH v1 1/5] rtc: m41t80: m41t80_sqw_set_rate should return 0 on success Troy Kisky
` (3 preceding siblings ...)
2017-11-03 1:58 ` [PATCH v1 5/5] rtc: m41t80: remove unneeded checks from m41t80_sqw_set_rate Troy Kisky
@ 2017-11-08 2:13 ` Alexandre Belloni
4 siblings, 0 replies; 6+ messages in thread
From: Alexandre Belloni @ 2017-11-08 2:13 UTC (permalink / raw)
To: Troy Kisky; +Cc: a.zummo, gary.bisson, linux-rtc
On 02/11/2017 at 18:58:12 -0700, Troy Kisky wrote:
> Previously it was returning -EINVAL upon success.
>
> Signed-off-by: Troy Kisky <troy.kisky@boundarydevices.com>
> ---
> drivers/rtc/rtc-m41t80.c | 5 +----
> 1 file changed, 1 insertion(+), 4 deletions(-)
>
All applied, thanks.
--
Alexandre Belloni, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2017-11-08 2:13 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-11-03 1:58 [PATCH v1 1/5] rtc: m41t80: m41t80_sqw_set_rate should return 0 on success Troy Kisky
2017-11-03 1:58 ` [PATCH v1 2/5] rtc: m41t80: fix m41t80_sqw_round_rate return value Troy Kisky
2017-11-03 1:58 ` [PATCH v1 3/5] rtc: m41t80: avoid i2c read in m41t80_sqw_recalc_rate Troy Kisky
2017-11-03 1:58 ` [PATCH v1 4/5] rtc: m41t80: avoid i2c read in m41t80_sqw_is_prepared Troy Kisky
2017-11-03 1:58 ` [PATCH v1 5/5] rtc: m41t80: remove unneeded checks from m41t80_sqw_set_rate Troy Kisky
2017-11-08 2:13 ` [PATCH v1 1/5] rtc: m41t80: m41t80_sqw_set_rate should return 0 on success Alexandre Belloni
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.