[1/3] clocksource: rockchip: Make the driver more readability and compatible
diff mbox

Message ID 1442476272-31723-2-git-send-email-wxt@rock-chips.com
State New
Headers show

Commit Message

Caesar Wang Sept. 17, 2015, 7:51 a.m. UTC
Build the arm64 SoCs (e.g.: RK3368) on Rockchip platform,
There are some failure with build up on timer driver for rockchip.

logs:
...
drivers/clocksource/rockchip_timer.c:156:13: error: 'NO_IRQ' undeclared
/tmp/ccdAnNy5.s:47: Error: missing immediate expression at  operand 1 --
`dsb`
...

The problem was different semantics of dsb on btw arm32 and arm64,
Here we can convert the dsb with insteading of dsb(sy).

Meanwhile, I change a bit to make the code more readability for driver
when I check the code style.

Signed-off-by: Caesar Wang <wxt@rock-chips.com>
---

 drivers/clocksource/rockchip_timer.c | 29 +++++++++++++++--------------
 1 file changed, 15 insertions(+), 14 deletions(-)

Comments

Daniel Lezcano Sept. 17, 2015, 9:11 a.m. UTC | #1
Hi Caesar,


On 09/17/2015 09:51 AM, Caesar Wang wrote:
> Build the arm64 SoCs (e.g.: RK3368) on Rockchip platform,
> There are some failure with build up on timer driver for rockchip.
>
> logs:
> ...
> drivers/clocksource/rockchip_timer.c:156:13: error: 'NO_IRQ' undeclared

I think the NO_IRQ definition is missing for ARM64.

> /tmp/ccdAnNy5.s:47: Error: missing immediate expression at  operand 1 --
> `dsb`
> ...
>
> The problem was different semantics of dsb on btw arm32 and arm64,
> Here we can convert the dsb with insteading of dsb(sy).

What happens to ARM32 then ?

> Meanwhile, I change a bit to make the code more readability for driver
> when I check the code style.
>
> Signed-off-by: Caesar Wang <wxt@rock-chips.com>
Caesar Wang Sept. 17, 2015, 9:28 a.m. UTC | #2
Hi Daniel,


? 2015?09?17? 17:11, Daniel Lezcano ??:
>
> Hi Caesar,
>
>
> On 09/17/2015 09:51 AM, Caesar Wang wrote:
>> Build the arm64 SoCs (e.g.: RK3368) on Rockchip platform,
>> There are some failure with build up on timer driver for rockchip.
>>
>> logs:
>> ...
>> drivers/clocksource/rockchip_timer.c:156:13: error: 'NO_IRQ' undeclared
>
> I think the NO_IRQ definition is missing for ARM64.

Yep, Maybe better to compatible if we don't use the 'NO_IRQ',

>
>> /tmp/ccdAnNy5.s:47: Error: missing immediate expression at  operand 1 --
>> `dsb`
>> ...
>>
>> The problem was different semantics of dsb on btw arm32 and arm64,
>> Here we can convert the dsb with insteading of dsb(sy).
>
> What happens to ARM32 then ?
>

The dsb() is ok for ARM32, the ARM32/64 are OK if we can convert the 
dsb() to dsb(sy).
I believe all drivers with 'dsb()' have same issue on ARM64 platform.

>> Meanwhile, I change a bit to make the code more readability for driver
>> when I check the code style.
>>
>> Signed-off-by: Caesar Wang <wxt@rock-chips.com>
>
>
Heiko Stuebner Sept. 17, 2015, 9:43 a.m. UTC | #3
Hi,

Am Donnerstag, 17. September 2015, 17:28:10 schrieb Caesar Wang:
> >> The problem was different semantics of dsb on btw arm32 and arm64,
> >> Here we can convert the dsb with insteading of dsb(sy).
> > 
> > What happens to ARM32 then ?
> 
> The dsb() is ok for ARM32, the ARM32/64 are OK if we can convert the
> dsb() to dsb(sy).
> I believe all drivers with 'dsb()' have same issue on ARM64 platform.

correct ... I read this up in the ARM docs 2 days ago too for something.

The "sy" param is the default, which you are allow to omit, so on arm32 dsb() 
and dsb(sy) are the same.


Heiko
Daniel Lezcano Sept. 17, 2015, 10:06 a.m. UTC | #4
On 09/17/2015 11:28 AM, Caesar Wang wrote:
> Hi Daniel,
>
>
> ? 2015?09?17? 17:11, Daniel Lezcano ??:
>>
>> Hi Caesar,
>>
>>
>> On 09/17/2015 09:51 AM, Caesar Wang wrote:
>>> Build the arm64 SoCs (e.g.: RK3368) on Rockchip platform,
>>> There are some failure with build up on timer driver for rockchip.
>>>
>>> logs:
>>> ...
>>> drivers/clocksource/rockchip_timer.c:156:13: error: 'NO_IRQ' undeclared
>>
>> I think the NO_IRQ definition is missing for ARM64.
>
> Yep, Maybe better to compatible if we don't use the 'NO_IRQ',

Hmm, after digging into drivers/of/irq.c and kernel/irq/irqdomain.c

when there is an error it returns zero. So NO_IRQ and -1 are not correct 
and on the other side zero can be a valid irq. That sounds a little bit 
fuzzy to me.

>>> /tmp/ccdAnNy5.s:47: Error: missing immediate expression at  operand 1 --
>>> `dsb`
>>> ...
>>>
>>> The problem was different semantics of dsb on btw arm32 and arm64,
>>> Here we can convert the dsb with insteading of dsb(sy).
>>
>> What happens to ARM32 then ?
>>
>
> The dsb() is ok for ARM32, the ARM32/64 are OK if we can convert the
> dsb() to dsb(sy).
> I believe all drivers with 'dsb()' have same issue on ARM64 platform.
>
>>> Meanwhile, I change a bit to make the code more readability for driver
>>> when I check the code style.
>>>
>>> Signed-off-by: Caesar Wang <wxt@rock-chips.com>
>>
>>
>
>
Thomas Gleixner Sept. 17, 2015, 10:19 a.m. UTC | #5
On Thu, 17 Sep 2015, Daniel Lezcano wrote:
> On 09/17/2015 11:28 AM, Caesar Wang wrote:
> > > I think the NO_IRQ definition is missing for ARM64.
> > 
> > Yep, Maybe better to compatible if we don't use the 'NO_IRQ',
> 
> Hmm, after digging into drivers/of/irq.c and kernel/irq/irqdomain.c
> 
> when there is an error it returns zero. So NO_IRQ and -1 are not correct and
> on the other side zero can be a valid irq. That sounds a little bit fuzzy to
> me.

IRQ0 is invalid for historical reasons. End of story.

Thanks,

	tglx
Caesar Wang Sept. 17, 2015, 10:19 a.m. UTC | #6
? 2015?09?17? 18:06, Daniel Lezcano ??:
> On 09/17/2015 11:28 AM, Caesar Wang wrote:
>> Hi Daniel,
>>
>>
>> ? 2015?09?17? 17:11, Daniel Lezcano ??:
>>>
>>> Hi Caesar,
>>>
>>>
>>> On 09/17/2015 09:51 AM, Caesar Wang wrote:
>>>> Build the arm64 SoCs (e.g.: RK3368) on Rockchip platform,
>>>> There are some failure with build up on timer driver for rockchip.
>>>>
>>>> logs:
>>>> ...
>>>> drivers/clocksource/rockchip_timer.c:156:13: error: 'NO_IRQ' 
>>>> undeclared
>>>
>>> I think the NO_IRQ definition is missing for ARM64.
>>
>> Yep, Maybe better to compatible if we don't use the 'NO_IRQ',
>
> Hmm, after digging into drivers/of/irq.c and kernel/irq/irqdomain.c
>
> when there is an error it returns zero. So NO_IRQ and -1 are not 
> correct and on the other side zero can be a valid irq. That sounds a 
> little bit fuzzy to me.

I believe the 'NO_IRQ' is better select if 'NO_IRQ' is defined on ARM64 
platform.

     irq = irq_of_parse_and_map(np, 0);

     if (irq  == NO_IRQ)
...
Also, that's ok if we instead of the 'irq < 0'  or  '!irq' , right?






>
>>>> /tmp/ccdAnNy5.s:47: Error: missing immediate expression at  operand 
>>>> 1 --
>>>> `dsb`
>>>> ...
>>>>
>>>> The problem was different semantics of dsb on btw arm32 and arm64,
>>>> Here we can convert the dsb with insteading of dsb(sy).
>>>
>>> What happens to ARM32 then ?
>>>
>>
>> The dsb() is ok for ARM32, the ARM32/64 are OK if we can convert the
>> dsb() to dsb(sy).
>> I believe all drivers with 'dsb()' have same issue on ARM64 platform.
>>
>>>> Meanwhile, I change a bit to make the code more readability for driver
>>>> when I check the code style.
>>>>
>>>> Signed-off-by: Caesar Wang <wxt@rock-chips.com>
>>>
>>>
>>
>>
>
>
>
> -- 
> Thanks,
> Caesar
Daniel Lezcano Sept. 17, 2015, 10:57 a.m. UTC | #7
On 09/17/2015 12:19 PM, Thomas Gleixner wrote:
> On Thu, 17 Sep 2015, Daniel Lezcano wrote:
>> On 09/17/2015 11:28 AM, Caesar Wang wrote:
>>>> I think the NO_IRQ definition is missing for ARM64.
>>>
>>> Yep, Maybe better to compatible if we don't use the 'NO_IRQ',
>>
>> Hmm, after digging into drivers/of/irq.c and kernel/irq/irqdomain.c
>>
>> when there is an error it returns zero. So NO_IRQ and -1 are not correct and
>> on the other side zero can be a valid irq. That sounds a little bit fuzzy to
>> me.
>
> IRQ0 is invalid for historical reasons. End of story.

Hi Thomas,

there is one thing I don't understand.

If the IRQ0 is invalid, irq_of_parse_and_map returning zero means an 
error and from what you said it is ok.

But I see the NO_IRQ on ARM is (-1) and the drivers are checking with 
NO_IRQ the return code of irq_of_parse_and_map. So if there is an error, 
that won't be detected.

For this specific use case above, shall irq_of_parse_and_map returns 
NO_IRQ or the caller checks against zero ?

Beside that, some drivers are internally defining NO_IRQ:
drivers/scsi/NCR5380.h
drivers/ata/sata_dwc_460ex.c
drivers/input/touchscreen/ucb1400_ts.c
drivers/mmc/host/of_mmc_spi.c
drivers/rtc/rtc-m48t59.c
drivers/scsi/NCR5380.h

I don't know the historical changes and the subtleties of the irq 
subsystem (I guess it is considerably complicated by each architecture 
specific bits and the drivers supported on different architectures)

If you have the time, can you give some clarification ?

Thanks

   -- Daniel
Russell King - ARM Linux Sept. 17, 2015, 9:13 p.m. UTC | #8
On Thu, Sep 17, 2015 at 12:57:53PM +0200, Daniel Lezcano wrote:
> Hi Thomas,
> 
> there is one thing I don't understand.
> 
> If the IRQ0 is invalid, irq_of_parse_and_map returning zero means an error
> and from what you said it is ok.
> 
> But I see the NO_IRQ on ARM is (-1) and the drivers are checking with NO_IRQ
> the return code of irq_of_parse_and_map. So if there is an error, that won't
> be detected.

NO_IRQ being -1 is a legacy thing for ARM - all ARM drivers are supposed
to be converted to use <= 0 or == 0 to detect invalid IRQs, and _eventually_
once all users are gone, NO_IRQ deleted.

Moreover, there are supposed to be no _new_ users of NO_IRQ ever added to
the kernel.

Modern drivers should _all_ be using !irq to detect invalid IRQs, and not
using NO_IRQ.

The steps here are:

1. Convert all ARM platforms to start numbering IRQs from 1 rather than 0.
2. Convert all drivers used on ARM to detect lack of IRQ by checking for
   <= 0.
3. Replace NO_IRQ assignments with zero-initialisations.
4. Remove NO_IRQ.

The reason it hasn't happened is that it requires effort and testing,
and rather than running around getting old platforms to boot (which
includes remembering _how_ to get them to boot) with recent kernels,
I prefer to spend my time doing more productive work with modern code.
Daniel Lezcano Sept. 18, 2015, 7:53 a.m. UTC | #9
On 09/17/2015 11:13 PM, Russell King - ARM Linux wrote:
> On Thu, Sep 17, 2015 at 12:57:53PM +0200, Daniel Lezcano wrote:
>> Hi Thomas,
>>
>> there is one thing I don't understand.
>>
>> If the IRQ0 is invalid, irq_of_parse_and_map returning zero means an error
>> and from what you said it is ok.
>>
>> But I see the NO_IRQ on ARM is (-1) and the drivers are checking with NO_IRQ
>> the return code of irq_of_parse_and_map. So if there is an error, that won't
>> be detected.

Hi Russel,


> NO_IRQ being -1 is a legacy thing for ARM - all ARM drivers are supposed
> to be converted to use <= 0 or == 0 to detect invalid IRQs, and _eventually_
> once all users are gone, NO_IRQ deleted.
>
> Moreover, there are supposed to be no _new_ users of NO_IRQ ever added to
> the kernel.
>
> Modern drivers should _all_ be using !irq to detect invalid IRQs, and not
> using NO_IRQ.

Ah, ok. Thanks for the clarification.

> The steps here are:
>
> 1. Convert all ARM platforms to start numbering IRQs from 1 rather than 0.
> 2. Convert all drivers used on ARM to detect lack of IRQ by checking for
>     <= 0.
> 3. Replace NO_IRQ assignments with zero-initialisations.
> 4. Remove NO_IRQ.
>
> The reason it hasn't happened is that it requires effort and testing,
> and rather than running around getting old platforms to boot (which
> includes remembering _how_ to get them to boot) with recent kernels,
> I prefer to spend my time doing more productive work with modern code.

I understand. I will take the opportunity track down those NO_IRQ in the 
clocksource directory.

   -- Daniel
Daniel Lezcano Sept. 18, 2015, 7:55 a.m. UTC | #10
On 09/17/2015 12:19 PM, Caesar Wang wrote:
>
>
> ? 2015?09?17? 18:06, Daniel Lezcano ??:
>> On 09/17/2015 11:28 AM, Caesar Wang wrote:
>>> Hi Daniel,
>>>
>>>
>>> ? 2015?09?17? 17:11, Daniel Lezcano ??:
>>>>
>>>> Hi Caesar,
>>>>
>>>>
>>>> On 09/17/2015 09:51 AM, Caesar Wang wrote:
>>>>> Build the arm64 SoCs (e.g.: RK3368) on Rockchip platform,
>>>>> There are some failure with build up on timer driver for rockchip.
>>>>>
>>>>> logs:
>>>>> ...
>>>>> drivers/clocksource/rockchip_timer.c:156:13: error: 'NO_IRQ'
>>>>> undeclared
>>>>
>>>> I think the NO_IRQ definition is missing for ARM64.
>>>
>>> Yep, Maybe better to compatible if we don't use the 'NO_IRQ',
>>
>> Hmm, after digging into drivers/of/irq.c and kernel/irq/irqdomain.c
>>
>> when there is an error it returns zero. So NO_IRQ and -1 are not
>> correct and on the other side zero can be a valid irq. That sounds a
>> little bit fuzzy to me.
>
> I believe the 'NO_IRQ' is better select if 'NO_IRQ' is defined on ARM64
> platform.
>
>      irq = irq_of_parse_and_map(np, 0);
>
>      if (irq  == NO_IRQ)
> ...
> Also, that's ok if we instead of the 'irq < 0'  or  '!irq' , right?


Hi Caesar,

so regarding Thomas and Russel answers, let's replace NO_IRQ by '!irq'.

Thanks.

   -- Daniel
Caesar Wang Sept. 18, 2015, 8:22 a.m. UTC | #11
Hi Daniel,

? 2015?09?18? 15:55, Daniel Lezcano ??:
> On 09/17/2015 12:19 PM, Caesar Wang wrote:
>>
>>
>> ? 2015?09?17? 18:06, Daniel Lezcano ??:
>>> On 09/17/2015 11:28 AM, Caesar Wang wrote:
>>>> Hi Daniel,
>>>>
>>>>
>>>> ? 2015?09?17? 17:11, Daniel Lezcano ??:
>>>>>
>>>>> Hi Caesar,
>>>>>
>>>>>
>>>>> On 09/17/2015 09:51 AM, Caesar Wang wrote:
>>>>>> Build the arm64 SoCs (e.g.: RK3368) on Rockchip platform,
>>>>>> There are some failure with build up on timer driver for rockchip.
>>>>>>
>>>>>> logs:
>>>>>> ...
>>>>>> drivers/clocksource/rockchip_timer.c:156:13: error: 'NO_IRQ'
>>>>>> undeclared
>>>>>
>>>>> I think the NO_IRQ definition is missing for ARM64.
>>>>
>>>> Yep, Maybe better to compatible if we don't use the 'NO_IRQ',
>>>
>>> Hmm, after digging into drivers/of/irq.c and kernel/irq/irqdomain.c
>>>
>>> when there is an error it returns zero. So NO_IRQ and -1 are not
>>> correct and on the other side zero can be a valid irq. That sounds a
>>> little bit fuzzy to me.
>>
>> I believe the 'NO_IRQ' is better select if 'NO_IRQ' is defined on ARM64
>> platform.
>>
>>      irq = irq_of_parse_and_map(np, 0);
>>
>>      if (irq  == NO_IRQ)
>> ...
>> Also, that's ok if we instead of the 'irq < 0'  or  '!irq' , right?
>
>
> Hi Caesar,
>
> so regarding Thomas and Russel answers, let's replace NO_IRQ by '!irq'.

Fixed, I will send the patch v1.

>
> Thanks.
>
>   -- Daniel
>
>
Russell King - ARM Linux Sept. 18, 2015, 9:08 a.m. UTC | #12
On Fri, Sep 18, 2015 at 09:55:24AM +0200, Daniel Lezcano wrote:
> On 09/17/2015 12:19 PM, Caesar Wang wrote:
> >
> >
> >? 2015?09?17? 18:06, Daniel Lezcano ??:
> >>On 09/17/2015 11:28 AM, Caesar Wang wrote:
> >>>Hi Daniel,
> >>>
> >>>
> >>>? 2015?09?17? 17:11, Daniel Lezcano ??:
> >>>>
> >>>>Hi Caesar,
> >>>>
> >>>>
> >>>>On 09/17/2015 09:51 AM, Caesar Wang wrote:
> >>>>>Build the arm64 SoCs (e.g.: RK3368) on Rockchip platform,
> >>>>>There are some failure with build up on timer driver for rockchip.
> >>>>>
> >>>>>logs:
> >>>>>...
> >>>>>drivers/clocksource/rockchip_timer.c:156:13: error: 'NO_IRQ'
> >>>>>undeclared
> >>>>
> >>>>I think the NO_IRQ definition is missing for ARM64.
> >>>
> >>>Yep, Maybe better to compatible if we don't use the 'NO_IRQ',
> >>
> >>Hmm, after digging into drivers/of/irq.c and kernel/irq/irqdomain.c
> >>
> >>when there is an error it returns zero. So NO_IRQ and -1 are not
> >>correct and on the other side zero can be a valid irq. That sounds a
> >>little bit fuzzy to me.
> >
> >I believe the 'NO_IRQ' is better select if 'NO_IRQ' is defined on ARM64
> >platform.
> >
> >     irq = irq_of_parse_and_map(np, 0);
> >
> >     if (irq  == NO_IRQ)
> >...
> >Also, that's ok if we instead of the 'irq < 0'  or  '!irq' , right?
> 
> 
> Hi Caesar,
> 
> so regarding Thomas and Russel answers, let's replace NO_IRQ by '!irq'.
                                ^

Definitely in this case.  irq_create_of_mapping() and therefore
irq_of_parse_and_map() both return _zero_ when they fail, not whatever
happens to be NO_IRQ on a particular architecture.  New code should
_never_ be making any use of NO_IRQ.

That's why I said:

"Modern drivers should _all_ be using !irq to detect invalid IRQs, and not
using NO_IRQ."

Patch
diff mbox

diff --git a/drivers/clocksource/rockchip_timer.c b/drivers/clocksource/rockchip_timer.c
index bb2c2b0..c479d76 100644
--- a/drivers/clocksource/rockchip_timer.c
+++ b/drivers/clocksource/rockchip_timer.c
@@ -17,16 +17,16 @@ 
 
 #define TIMER_NAME "rk_timer"
 
-#define TIMER_LOAD_COUNT0 0x00
-#define TIMER_LOAD_COUNT1 0x04
-#define TIMER_CONTROL_REG 0x10
-#define TIMER_INT_STATUS 0x18
+#define TIMER_LOAD_COUNT0	0x00
+#define TIMER_LOAD_COUNT1	0x04
+#define TIMER_CONTROL_REG	0x10
+#define TIMER_INT_STATUS	0x18
 
-#define TIMER_DISABLE 0x0
-#define TIMER_ENABLE 0x1
-#define TIMER_MODE_FREE_RUNNING (0 << 1)
-#define TIMER_MODE_USER_DEFINED_COUNT (1 << 1)
-#define TIMER_INT_UNMASK (1 << 2)
+#define TIMER_DISABLE			(0 << 0)
+#define TIMER_ENABLE			(1 << 0)
+#define TIMER_MODE_FREE_RUNNING		(0 << 1)
+#define TIMER_MODE_USER_DEFINED_COUNT	(1 << 1)
+#define TIMER_INT_UNMASK		(1 << 2)
 
 struct bc_timer {
 	struct clock_event_device ce;
@@ -49,14 +49,14 @@  static inline void __iomem *rk_base(struct clock_event_device *ce)
 static inline void rk_timer_disable(struct clock_event_device *ce)
 {
 	writel_relaxed(TIMER_DISABLE, rk_base(ce) + TIMER_CONTROL_REG);
-	dsb();
+	dsb(sy);
 }
 
 static inline void rk_timer_enable(struct clock_event_device *ce, u32 flags)
 {
 	writel_relaxed(TIMER_ENABLE | TIMER_INT_UNMASK | flags,
 		       rk_base(ce) + TIMER_CONTROL_REG);
-	dsb();
+	dsb(sy);
 }
 
 static void rk_timer_update_counter(unsigned long cycles,
@@ -64,13 +64,13 @@  static void rk_timer_update_counter(unsigned long cycles,
 {
 	writel_relaxed(cycles, rk_base(ce) + TIMER_LOAD_COUNT0);
 	writel_relaxed(0, rk_base(ce) + TIMER_LOAD_COUNT1);
-	dsb();
+	dsb(sy);
 }
 
 static void rk_timer_interrupt_clear(struct clock_event_device *ce)
 {
 	writel_relaxed(1, rk_base(ce) + TIMER_INT_STATUS);
-	dsb();
+	dsb(sy);
 }
 
 static inline int rk_timer_set_next_event(unsigned long cycles,
@@ -148,7 +148,7 @@  static void __init rk_timer_init(struct device_node *np)
 	bc_timer.freq = clk_get_rate(timer_clk);
 
 	irq = irq_of_parse_and_map(np, 0);
-	if (irq == NO_IRQ) {
+	if (irq < 0) {
 		pr_err("Failed to map interrupts for '%s'\n", TIMER_NAME);
 		return;
 	}
@@ -173,4 +173,5 @@  static void __init rk_timer_init(struct device_node *np)
 
 	clockevents_config_and_register(ce, bc_timer.freq, 1, UINT_MAX);
 }
+
 CLOCKSOURCE_OF_DECLARE(rk_timer, "rockchip,rk3288-timer", rk_timer_init);