* Query: Patches break with Microsoft exchange server.
From: Justin P. Mattock @ 2018-06-19 20:24 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <4C5F9B25.8080401@st.com>
On 08/08/2010 11:07 PM, viresh kumar wrote:
> Hello,
>
> Mail server in ST has recently changed and now we have Microsoft
> exchange server. We are using thunderbird as mail client.
> What we observed with this server is that patch are broken now while
> sending as well as receiving. Tabs are replaced by spaces and may
> be some other too which we haven't observed.
>
> Has anybody found a solution to this kind of issues? Are there any
> workarounds possible?
>
> viresh
> ST Microelectronics.
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at http://www.tux.org/lkml/
>
still trying to figure this out with thunderbird.. but did notice in
Documentation/email-clients.txt and SubmittingPatches
there's info about that(just haven't gotten around to reading use git
send-email for patches)
hope this helps.
Justin P. Mattock
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo at vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
^ permalink raw reply
* Query: Patches break with Microsoft exchange server.
From: Uwe Kleine-König @ 2018-06-19 20:24 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <4C5F9B25.8080401@st.com>
Hello,
On Mon, Aug 09, 2010 at 11:37:33AM +0530, viresh kumar wrote:
> Hello,
>
> Mail server in ST has recently changed and now we have Microsoft
> exchange server. We are using thunderbird as mail client.
> What we observed with this server is that patch are broken now while
> sending as well as receiving. Tabs are replaced by spaces and may
> be some other too which we haven't observed.
unlucky you.
> Has anybody found a solution to this kind of issues? Are there any
> workarounds possible?
git.git has some tips for thunderbird, see
http://git.kernel.org/?p=git/git.git;a=blob;f=Documentation/SubmittingPatches;hb=HEAD
and look for the section titled "Thunderbird" (small surprise).
Best regards
Uwe
--
Pengutronix e.K. | Uwe Kleine-K?nig |
Industrial Linux Solutions | http://www.pengutronix.de/ |
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo at vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
^ permalink raw reply
* Query: Patches break with Microsoft exchange server.
From: viresh kumar @ 2018-06-19 20:24 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <4C5FA35E.50309@gmail.com>
On 8/9/2010 12:12 PM, Justin P. Mattock wrote:
> On 08/08/2010 11:07 PM, viresh kumar wrote:
>> > Hello,
>> >
>> > Mail server in ST has recently changed and now we have Microsoft
>> > exchange server. We are using thunderbird as mail client.
>> > What we observed with this server is that patch are broken now while
>> > sending as well as receiving. Tabs are replaced by spaces and may
>> > be some other too which we haven't observed.
>> >
>> > Has anybody found a solution to this kind of issues? Are there any
>> > workarounds possible?
>> >
>
> still trying to figure this out with thunderbird.. but did notice in
> Documentation/email-clients.txt and SubmittingPatches
> there's info about that(just haven't gotten around to reading use git
> send-email for patches)
>
> hope this helps.
I missed this information in my last mail. We are using git send-email for
sending patches. As patches will go through Microsoft exchange server only,
so they are broken.
viresh.
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo at vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
^ permalink raw reply
* Query: Patches break with Microsoft exchange server.
From: viresh kumar @ 2018-06-19 20:24 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20100809064957.GB16661@pengutronix.de>
On 8/9/2010 12:19 PM, Uwe Kleine-K?nig wrote:
> Hello,
>
> On Mon, Aug 09, 2010 at 11:37:33AM +0530, viresh kumar wrote:
>> > Hello,
>> >
>> > Mail server in ST has recently changed and now we have Microsoft
>> > exchange server. We are using thunderbird as mail client.
>> > What we observed with this server is that patch are broken now while
>> > sending as well as receiving. Tabs are replaced by spaces and may
>> > be some other too which we haven't observed.
> unlucky you.
>
>> > Has anybody found a solution to this kind of issues? Are there any
>> > workarounds possible?
> git.git has some tips for thunderbird, see
>
> http://git.kernel.org/?p=git/git.git;a=blob;f=Documentation/SubmittingPatches;hb=HEAD
>
> and look for the section titled "Thunderbird" (small surprise).
I missed this information in my last mail. We are using git send-email for
sending patches. As patches will go through Microsoft exchange server only,
so they are broken.
With previous server everything was working fine.
viresh.
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo at vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
^ permalink raw reply
* Query: Patches break with Microsoft exchange server.
From: Justin P. Mattock @ 2018-06-19 20:24 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <4C5FA66D.7060404@st.com>
On 08/08/2010 11:55 PM, viresh kumar wrote:
> On 8/9/2010 12:12 PM, Justin P. Mattock wrote:
>> On 08/08/2010 11:07 PM, viresh kumar wrote:
>>>> Hello,
>>>>
>>>> Mail server in ST has recently changed and now we have Microsoft
>>>> exchange server. We are using thunderbird as mail client.
>>>> What we observed with this server is that patch are broken now while
>>>> sending as well as receiving. Tabs are replaced by spaces and may
>>>> be some other too which we haven't observed.
>>>>
>>>> Has anybody found a solution to this kind of issues? Are there any
>>>> workarounds possible?
>>>>
>>
>> still trying to figure this out with thunderbird.. but did notice in
>> Documentation/email-clients.txt and SubmittingPatches
>> there's info about that(just haven't gotten around to reading use git
>> send-email for patches)
>>
>> hope this helps.
>
> I missed this information in my last mail. We are using git send-email for
> sending patches. As patches will go through Microsoft exchange server only,
> so they are broken.
>
> viresh.
>
hmm.. then I don't know the answer to that.. always send through git
send-email(patches)and things are good(knock-on-wood)always ran into
issues with copy/pasting onto thunderbird. Hopefully somebody else with
more knowledge of using git send-email patches through microsoft
exchange answers this..
side note: maybe postfix or some type of wrapper around the wording
message(utf-8) to keep microsoft from mangling things or
something.(tough to say though)
Justin P. Mattock
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo at vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
^ permalink raw reply
* [PATCH 4/5] [omap1] Bluetooth device code common to HTC smartphones
From: Tony Lindgren @ 2018-06-19 20:24 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <AANLkTikGA9-TCM7v+_yivBYtxiX3ByJ7_ub1FOP0LgBO@mail.gmail.com>
* Cory Maccarrone <darkstar6262@gmail.com> [100808 20:22]:
> On Wed, Aug 4, 2010 at 3:15 AM, Tony Lindgren <tony@atomide.com> wrote:
> > * Cory Maccarrone <darkstar6262@gmail.com> [100802 18:23]:
> >> This change adds in a bluetooth controld driver/rfkill
> >> interface to the serial bluetooth controller found on many
> >> HTC smartphones such as the HTC Herald and HTC Wizard.
> >
> > To me it looks like most of this should be in drivers/bluetooth/omap7xx.c
> > or something like that. Then you can just pass it the gpio numbers in
> > the platform_data.
> >
>
> Not sure I agree that it fits there. The driver isn't really a
> bluetooth driver -- it's really just an RFKILL interface, and some
> code to toggle UART clocks on and off, plus GPIO work on a
> board-specific level. In principle, the gpios could be set and the
> clocks enabled in the board files, and this driver wouldn't be
> necessary to get working bluetooth (as we'd use hciattach on
> /dev/ttyS*). But then, we can't toggle it off for power saving.
> Maybe a better place would be plat-omap/? But it really is more
> specific to these HTC boards, not the architecture itself.
Hmm well what we've used earlier is to set something like set_power
function pointer in the platform data, then call that in the driver
if set. But in this case the driver is 8250.c, so let's not mess
with that..
This issue should get properly solved with the omap specific serial
driver once we get that merged as then we can have hooks for set_power
in addition to cutting serial clocks when idle.
> So really, the only point of this driver is to be able to power on and
> off the external bluetooth chip, which is why I submitted it as helper
> code to the board files.
Yeah. Can you take a look at the omap specific serial driver to get
it working on omap1?
Then you can have your GPIO functions set in the board-*.c file
as set_power or similar, and the UART driver can idle properly.
Regards,
Tony
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo at vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Query: Patches break with Microsoft exchange server.
From: Matti Aarnio @ 2018-06-19 20:26 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <4C5FA698.90904@st.com>
On Mon, Aug 09, 2010 at 12:26:24PM +0530, viresh kumar wrote:
>
> I missed this information in my last mail. We are using git send-email for
> sending patches. As patches will go through Microsoft exchange server only,
> so they are broken.
>
Let your boss complain to your IT keepers.
"These are Machine-to-Machine messages, they must not be modified!"
It would probably be "against corporate policy" to use gmail for these emails...
> With previous server everything was working fine.
> viresh.
Best Regards, Matti Aarnio, one of <postmaster@vger.kernel.org>
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo at vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
^ permalink raw reply
* [PATCH 1/3] ARM: mmu: Setup MT_MEMORY and MT_MEMORY_NONACHED L1 entries
From: Shilimkar, Santosh @ 2018-06-19 20:26 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <EAF47CD23C76F840A9E7FCE10091EFAB02C64A2363@dbde02.ent.ti.com>
> -----Original Message-----
> From: linux-omap-owner at vger.kernel.org [mailto:linux-omap-
> owner at vger.kernel.org] On Behalf Of Shilimkar, Santosh
> Sent: Sunday, August 08, 2010 5:16 PM
> To: Russell King - ARM Linux
> Cc: linux-omap at vger.kernel.org; linux-arm-kernel at lists.infradead.org
> Subject: RE: [PATCH 1/3] ARM: mmu: Setup MT_MEMORY and MT_MEMORY_NONACHED
> L1 entries
>
> > -----Original Message-----
> > From: Russell King - ARM Linux [mailto:linux at arm.linux.org.uk]
> > Sent: Sunday, August 08, 2010 5:04 PM
> > To: Shilimkar, Santosh
> > Cc: linux-omap at vger.kernel.org; linux-arm-kernel at lists.infradead.org
> > Subject: Re: [PATCH 1/3] ARM: mmu: Setup MT_MEMORY and
> MT_MEMORY_NONACHED
> > L1 entries
> >
> > On Sun, Aug 08, 2010 at 03:47:52PM +0530, Santosh Shilimkar wrote:
> > > @@ -475,6 +486,9 @@ static void __init build_mem_type_table(void)
> > > mem_types[MT_LOW_VECTORS].prot_l1 |= ecc_mask;
> > > mem_types[MT_HIGH_VECTORS].prot_l1 |= ecc_mask;
> > > mem_types[MT_MEMORY].prot_sect |= ecc_mask | cp->pmd;
> > > + mem_types[MT_MEMORY].prot_pte |= kern_pgprot;
> > > + mem_types[MT_MEMORY_NONCACHED].prot_sect |= ecc_mask | cp->pmd;
> > > + mem_types[MT_MEMORY_NONCACHED].prot_pte |= kern_pgprot;
> >
> > This is wrong - it will result in the non-cached memory mapped in as
> > sections having the same cache settings as MT_MEMORY - in other
> > words, probably write back.
> You are right. Will fix this in next version.
>
Updated version with Russell's comments incorporated.
--------------------------------------------------------------------
>From 23d712c1846d78bdb09979087261911e5d80f014 Mon Sep 17 00:00:00 2001
From: Santosh Shilimkar <santosh.shilimkar@ti.com>
Date: Sun, 8 Aug 2010 12:05:25 +0530
Subject: [PATCH 1/3 v2] ARM: mmu: Setup MT_MEMORY and MT_MEMORY_NONCACHED L1 entries
This patch populates the L1 entries for MT_MEMORY and MT_MEMORY_NONCACHED
types so that at boot-up, we can map memories outside system memory
at page level granularity
Previously the mapping was limiting to section level, which creates
unnecessary additional mapping for which physical memory may not
present. On the newer ARM with speculation, this is dangerous and can
result in untraceable aborts.
The patch is based on inputs from Russell King
Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
Cc: Russell King <linux@arm.linux.org.uk>
---
arch/arm/mm/mmu.c | 17 +++++++++++++++--
1 files changed, 15 insertions(+), 2 deletions(-)
diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c
index 6e1c4f6..3e986a6 100644
--- a/arch/arm/mm/mmu.c
+++ b/arch/arm/mm/mmu.c
@@ -246,6 +246,9 @@ static struct mem_type mem_types[] = {
.domain = DOMAIN_USER,
},
[MT_MEMORY] = {
+ .prot_pte = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY |
+ L_PTE_USER | L_PTE_EXEC,
+ .prot_l1 = PMD_TYPE_TABLE,
.prot_sect = PMD_TYPE_SECT | PMD_SECT_AP_WRITE,
.domain = DOMAIN_KERNEL,
},
@@ -254,6 +257,9 @@ static struct mem_type mem_types[] = {
.domain = DOMAIN_KERNEL,
},
[MT_MEMORY_NONCACHED] = {
+ .prot_pte = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY |
+ L_PTE_USER | L_PTE_EXEC | L_PTE_MT_BUFFERABLE,
+ .prot_l1 = PMD_TYPE_TABLE,
.prot_sect = PMD_TYPE_SECT | PMD_SECT_AP_WRITE,
.domain = DOMAIN_KERNEL,
},
@@ -411,9 +417,12 @@ static void __init build_mem_type_table(void)
* Enable CPU-specific coherency if supported.
* (Only available on XSC3 at the moment.)
*/
- if (arch_is_coherent() && cpu_is_xsc3())
+ if (arch_is_coherent() && cpu_is_xsc3()) {
mem_types[MT_MEMORY].prot_sect |= PMD_SECT_S;
-
+ mem_types[MT_MEMORY].prot_pte |= L_PTE_SHARED;
+ mem_types[MT_MEMORY_NONCACHED].prot_sect |= PMD_SECT_S;
+ mem_types[MT_MEMORY_NONCACHED].prot_pte |= L_PTE_SHARED;
+ }
/*
* ARMv6 and above have extended page tables.
*/
@@ -438,7 +447,9 @@ static void __init build_mem_type_table(void)
mem_types[MT_DEVICE_CACHED].prot_sect |= PMD_SECT_S;
mem_types[MT_DEVICE_CACHED].prot_pte |= L_PTE_SHARED;
mem_types[MT_MEMORY].prot_sect |= PMD_SECT_S;
+ mem_types[MT_MEMORY].prot_pte |= L_PTE_SHARED;
mem_types[MT_MEMORY_NONCACHED].prot_sect |= PMD_SECT_S;
+ mem_types[MT_MEMORY_NONCACHED].prot_pte |= L_PTE_SHARED;
#endif
}
@@ -475,6 +486,8 @@ static void __init build_mem_type_table(void)
mem_types[MT_LOW_VECTORS].prot_l1 |= ecc_mask;
mem_types[MT_HIGH_VECTORS].prot_l1 |= ecc_mask;
mem_types[MT_MEMORY].prot_sect |= ecc_mask | cp->pmd;
+ mem_types[MT_MEMORY].prot_pte |= kern_pgprot;
+ mem_types[MT_MEMORY_NONCACHED].prot_sect |= ecc_mask;
mem_types[MT_ROM].prot_sect |= cp->pmd;
switch (cp->pmd) {
--
1.6.0.4
-------------- next part --------------
A non-text attachment was scrubbed...
Name: 0001-ARM-mmu-Setup-MT_MEMORY-and-MT_MEMORY_NONCACHED-L1.patch
Type: application/octet-stream
Size: 3089 bytes
Desc: 0001-ARM-mmu-Setup-MT_MEMORY-and-MT_MEMORY_NONCACHED-L1.patch
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20180619/542cd699/attachment.obj>
^ permalink raw reply related
* Query: Patches break with Microsoft exchange server.
From: viresh kumar @ 2018-06-19 20:26 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20100809090137.GP13165@mea-ext.zmailer.org>
On 8/9/2010 2:31 PM, Matti Aarnio wrote:
> On Mon, Aug 09, 2010 at 12:26:24PM +0530, viresh kumar wrote:
>> >
>> > I missed this information in my last mail. We are using git send-email for
>> > sending patches. As patches will go through Microsoft exchange server only,
>> > so they are broken.
>> >
> Let your boss complain to your IT keepers.
> "These are Machine-to-Machine messages, they must not be modified!"
>
>
> It would probably be "against corporate policy" to use gmail for these emails...
>
We got one solution: Upgrade Exchange server to SP2.
Lets see if our IT department does this upgradation.
viresh.
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo at vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
^ permalink raw reply
* Query: Patches break with Microsoft exchange server.
From: Justin P. Mattock @ 2018-06-19 20:26 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <4C5FCBE1.2080303@st.com>
On 08/09/2010 02:35 AM, viresh kumar wrote:
> On 8/9/2010 2:31 PM, Matti Aarnio wrote:
>> On Mon, Aug 09, 2010 at 12:26:24PM +0530, viresh kumar wrote:
>>>>
>>>> I missed this information in my last mail. We are using git send-email for
>>>> sending patches. As patches will go through Microsoft exchange server only,
>>>> so they are broken.
>>>>
>> Let your boss complain to your IT keepers.
>> "These are Machine-to-Machine messages, they must not be modified!"
>>
>>
>> It would probably be "against corporate policy" to use gmail for these emails...
>>
>
> We got one solution: Upgrade Exchange server to SP2.
> Lets see if our IT department does this upgradation.
>
> viresh.
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at http://www.tux.org/lkml/
>
that or just blast them with some cryptology..i.e. pretty sure if your
message was encapsulated(AH/ESP) they couldn't tweak it.. but then
sending such encryption to a public list would require a _key_ on the
other side.. wishful thinking...
(just a thought)...
:-)
Justin P. Mattock
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo at vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
^ permalink raw reply
* Query: Patches break with Microsoft exchange server.
From: David Woodhouse @ 2018-06-19 20:26 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20100809090137.GP13165@mea-ext.zmailer.org>
On Mon, 2010-08-09 at 12:01 +0300, Matti Aarnio wrote:
> It would probably be "against corporate policy" to use gmail for these
> emails...
If that's the case, then you really *do* need to get your boss to fix
it.
If the company provides a working email account, it makes a certain
amount of sense for them to ask you to use it.
But if all they provide is Microsoft Exchange, that's insane -- what
Exchange provides is *like* email, but it is *not* email. Once you start
trying to use it for real email, you find it's broken by design in a
large number of ways. It makes no sense for them to require that you use
Exchange for Internet email, because that's not what Exchange does.
If my corporate overloads told me I had to use my Exchange "messaging"
account for external email communication, they would get a quite clear
'no' in response. My response may also contain suggestions that they use
certain other objects for purposes for which they were not designed.
Seriously, just use an external email account and ignore the broken
corporate policy. 'Policy' is just a euphemism for not having to think
for yourself.
--
dwmw2
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo at vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
^ permalink raw reply
* [RFC PATCH v2] driver core: add a debugfs entry to show deferred devices
From: Greg Kroah-Hartman @ 2018-06-19 20:29 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CAHp75VdpHdanWJmcwLBRTSDoDkbpPxuAGwwVO0hosXSRn4PUoA@mail.gmail.com>
On Tue, Jun 19, 2018 at 10:55:20PM +0300, Andy Shevchenko wrote:
> On Tue, Jun 19, 2018 at 10:53 PM, Andy Shevchenko
> <andy.shevchenko@gmail.com> wrote:
> > On Tue, Jun 19, 2018 at 9:33 PM, Javier Martinez Canillas
> > <javierm@redhat.com> wrote:
> >> For debugging purposes it may be useful to know what are the devices whose
> >> probe function was deferred. Add a debugfs entry showing that information.
>
> >> +static int deferred_devs_open(struct inode *inode, struct file *file)
> >> +{
> >> + return single_open(file, deferred_devs_show, inode->i_private);
> >> +}
> >> +
> >> +static const struct file_operations deferred_devs_fops = {
> >> + .owner = THIS_MODULE,
> >> + .open = deferred_devs_open,
> >> + .read = seq_read,
> >> + .llseek = seq_lseek,
> >> + .release = single_release,
> >> +};
> >
> > Isn't this DEFINE_SHOW_ATTRIBUTE() ?
>
> Besides that, you are summoning Greg's dark side :-)
> See below.
>
> >> + if (IS_ENABLED(CONFIG_DEBUG_FS)) {
> >> + deferred_devices = debugfs_create_file("deferred_devices",
> >> + 0444, NULL, NULL,
> >> + &deferred_devs_fops);
>
> >> + if (!deferred_devices)
> >> + return -ENOMEM;
>
> This must not prevent the execution. So, the check introduces actually
> a regression.
Awe, you beat me to it :)
Also, I don't usually comment on RFC patches, as that shows the author
really doesn't think that the code is ready to be reviewed/merged...
thanks,
greg k-h
^ permalink raw reply
* [PATCH 0/2] Make badr macro compatible with newer GAS versions
From: Guenter Roeck @ 2018-06-19 20:32 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180619192633.21846-1-ard.biesheuvel@linaro.org>
On Tue, Jun 19, 2018 at 09:26:31PM +0200, Ard Biesheuvel wrote:
> Work around the mindless and backward incompatible change in GAS that
> prevents us from using a simple addition to set the Thumb bit in local
> symbol references taken using 'adr' instructions (#2)
>
> As a preparatory step, remove badr occurrences in ARM code sequences
> contained in Thumb2 kernels.
>
> Ard Biesheuvel (2):
> ARM: avoid badr macro for switching to Thumb-2 mode
> ARM: assembler: prevent ADR from setting the Thumb bit twice
>
This doesn't work for images built with a toolchain based on gcc 7.3.0
and binutils 2.28.1. It _does_ work for images built with gcc 7.3.0/
binutils 2.30.
Guenter
^ permalink raw reply
* [PATCH 0/2] Make badr macro compatible with newer GAS versions
From: Ard Biesheuvel @ 2018-06-19 20:34 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180619203223.GA28370@roeck-us.net>
On 19 June 2018 at 22:32, Guenter Roeck <linux@roeck-us.net> wrote:
> On Tue, Jun 19, 2018 at 09:26:31PM +0200, Ard Biesheuvel wrote:
>> Work around the mindless and backward incompatible change in GAS that
>> prevents us from using a simple addition to set the Thumb bit in local
>> symbol references taken using 'adr' instructions (#2)
>>
>> As a preparatory step, remove badr occurrences in ARM code sequences
>> contained in Thumb2 kernels.
>>
>> Ard Biesheuvel (2):
>> ARM: avoid badr macro for switching to Thumb-2 mode
>> ARM: assembler: prevent ADR from setting the Thumb bit twice
>>
>
> This doesn't work for images built with a toolchain based on gcc 7.3.0
> and binutils 2.28.1. It _does_ work for images built with gcc 7.3.0/
> binutils 2.30.
>
Sigh.
So does it fail? Or is the resulting binary broken?
^ permalink raw reply
* Query: Patches break with Microsoft exchange server.
From: Willy Tarreau @ 2018-06-19 20:42 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1281348164.12908.47.camel@localhost>
On Mon, Aug 09, 2010 at 11:02:44AM +0100, David Woodhouse wrote:
> If my corporate overloads told me I had to use my Exchange "messaging"
> account for external email communication, they would get a quite clear
> 'no' in response. My response may also contain suggestions that they use
> certain other objects for purposes for which they were not designed.
I'd say that if, after having been calmly explained the nature of the
trouble caused, they don't care, it's a clear demonstration of total
lack of respect of your work by deliberately breaking the tools you
need to do it. Generally it's the signal that it's time to find a more
respectful employer.
Willy
^ permalink raw reply
* [PATCH 0/2] Make badr macro compatible with newer GAS versions
From: Guenter Roeck @ 2018-06-19 20:45 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CAKv+Gu-RHM7HAmzWw9Ge+w21kWxKxLbJT7DD5huv-7WWOPUVWA@mail.gmail.com>
On Tue, Jun 19, 2018 at 10:34:38PM +0200, Ard Biesheuvel wrote:
> On 19 June 2018 at 22:32, Guenter Roeck <linux@roeck-us.net> wrote:
> > On Tue, Jun 19, 2018 at 09:26:31PM +0200, Ard Biesheuvel wrote:
> >> Work around the mindless and backward incompatible change in GAS that
> >> prevents us from using a simple addition to set the Thumb bit in local
> >> symbol references taken using 'adr' instructions (#2)
> >>
> >> As a preparatory step, remove badr occurrences in ARM code sequences
> >> contained in Thumb2 kernels.
> >>
> >> Ard Biesheuvel (2):
> >> ARM: avoid badr macro for switching to Thumb-2 mode
> >> ARM: assembler: prevent ADR from setting the Thumb bit twice
> >>
> >
> > This doesn't work for images built with a toolchain based on gcc 7.3.0
> > and binutils 2.28.1. It _does_ work for images built with gcc 7.3.0/
> > binutils 2.30.
> >
>
> Sigh.
>
> So does it fail? Or is the resulting binary broken?
Hard to say. It crashes early in boot, even before earlycon can say
anything.
Qemu exec trace, broken:
race 0: 0x7fffcf92c0c0 [00000000/00000008/0x11080001]
Trace 0: 0x7fffcf92c300 [00000000/21008000/0x11080001] stext
Trace 0: 0x7fffcf92c480 [00000000/210099ce/0x11080001] __lookup_processor_type
Linking TBs 0x7fffcf92c480 [210099ce] index 1 -> 0x7fffcf92c780 [210099ea]
Trace 0: 0x7fffcf92c780 [00000000/210099ea/0x11080001] __lookup_processor_type
Linking TBs 0x7fffcf92c780 [210099ea] index 0 -> 0x7fffcf92c8c0 [210099dc]
Trace 0: 0x7fffcf92c8c0 [00000000/210099dc/0x11080001] __lookup_processor_type
Linking TBs 0x7fffcf92c8c0 [210099dc] index 1 -> 0x7fffcf92c780 [210099ea]
Trace 0: 0x7fffcf92c780 [00000000/210099ea/0x11080001] __lookup_processor_type
Linking TBs 0x7fffcf92c8c0 [210099dc] index 0 -> 0x7fffcf92ca80 [210099f6]
Trace 0: 0x7fffcf92ca80 [00000000/210099f6/0x11080001] __lookup_processor_type
Trace 0: 0x7fffcf92cb80 [00000000/2100800c/0x11080001] stext
Linking TBs 0x7fffcf92cb80 [2100800c] index 1 -> 0x7fffcf92cc80 [21008014]
Trace 0: 0x7fffcf92cc80 [00000000/21008014/0x11080001] stext
Trace 0: 0x7fffcf92cdc0 [00000000/2120477e/0x11080001] __v7m_setup
Trace 0: 0x7fffcf92d400 [00000000/212047bc/0x11080001] __v7m_setup
Trace 0: 0x7fffcf92d500 [00000000/212047be/0x11280000] __v7m_setup
^^^^^^^^^^
Trace 0: 0x7fffcf92d600 [00000000/2100b830/0x11280001] __invalid_entry
Trace 0: 0x7fffcf92d880 [00000000/2100b842/0x11280001] __invalid_entry
Trace 0: 0x7fffcf92e100 [00000000/21025780/0x11280001] printk
Trace 0: 0x7fffcf92e640 [00000000/21025a7c/0x11280001] vprintk_func
Qemu exec trace, ok:
Trace 0: 0x7fffcf92c0c0 [00000000/00000008/0x11080001]
Trace 0: 0x7fffcf92c300 [00000000/21008000/0x11080001] stext
Trace 0: 0x7fffcf92c480 [00000000/210099ce/0x11080001] __lookup_processor_type
Linking TBs 0x7fffcf92c480 [210099ce] index 1 -> 0x7fffcf92c780 [210099ea]
Trace 0: 0x7fffcf92c780 [00000000/210099ea/0x11080001] __lookup_processor_type
Linking TBs 0x7fffcf92c780 [210099ea] index 0 -> 0x7fffcf92c8c0 [210099dc]
Trace 0: 0x7fffcf92c8c0 [00000000/210099dc/0x11080001] __lookup_processor_type
Linking TBs 0x7fffcf92c8c0 [210099dc] index 1 -> 0x7fffcf92c780 [210099ea]
Trace 0: 0x7fffcf92c780 [00000000/210099ea/0x11080001] __lookup_processor_type
Linking TBs 0x7fffcf92c8c0 [210099dc] index 0 -> 0x7fffcf92ca80 [210099f6]
Trace 0: 0x7fffcf92ca80 [00000000/210099f6/0x11080001] __lookup_processor_type
Trace 0: 0x7fffcf92cb80 [00000000/2100800c/0x11080001] stext
Linking TBs 0x7fffcf92cb80 [2100800c] index 1 -> 0x7fffcf92cc80 [21008014]
Trace 0: 0x7fffcf92cc80 [00000000/21008014/0x11080001] stext
Trace 0: 0x7fffcf92cdc0 [00000000/2120477e/0x11080001] __v7m_setup
Trace 0: 0x7fffcf92d400 [00000000/212047bc/0x11080001] __v7m_setup
Trace 0: 0x7fffcf92d500 [00000000/212047be/0x11280001] __v7m_setup
Trace 0: 0x7fffcf92d600 [00000000/212047c0/0x11280001] __v7m_setup
Trace 0: 0x7fffcf92d900 [00000000/212047d2/0x11280001] __v7m_setup
Linking TBs 0x7fffcf92d900 [212047d2] index 1 -> 0x7fffcf92dcc0 [212047e0]
Trace 0: 0x7fffcf92dcc0 [00000000/212047e0/0x11280001] __v7m_setup
Trace 0: 0x7fffcf92e0c0 [00000000/21008020/0x11280001] stext
Trace 0: 0x7fffcf92e200 [00000000/210099c8/0x11280001] __after_proc_init
Guenter
^ permalink raw reply
* [RFC PATCH v2] driver core: add a debugfs entry to show deferred devices
From: Javier Martinez Canillas @ 2018-06-19 20:54 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CAHp75VdpHdanWJmcwLBRTSDoDkbpPxuAGwwVO0hosXSRn4PUoA@mail.gmail.com>
Hello Andy,
Thanks a lot for your feedback.
On 06/19/2018 09:55 PM, Andy Shevchenko wrote:
> On Tue, Jun 19, 2018 at 10:53 PM, Andy Shevchenko
> <andy.shevchenko@gmail.com> wrote:
>> On Tue, Jun 19, 2018 at 9:33 PM, Javier Martinez Canillas
>> <javierm@redhat.com> wrote:
>>> For debugging purposes it may be useful to know what are the devices whose
>>> probe function was deferred. Add a debugfs entry showing that information.
>
>>> +static int deferred_devs_open(struct inode *inode, struct file *file)
>>> +{
>>> + return single_open(file, deferred_devs_show, inode->i_private);
>>> +}
>>> +
>>> +static const struct file_operations deferred_devs_fops = {
>>> + .owner = THIS_MODULE,
>>> + .open = deferred_devs_open,
>>> + .read = seq_read,
>>> + .llseek = seq_lseek,
>>> + .release = single_release,
>>> +};
>>
>> Isn't this DEFINE_SHOW_ATTRIBUTE() ?
>
Indeed.
> Besides that, you are summoning Greg's dark side :-)
> See below.
>
>>> + if (IS_ENABLED(CONFIG_DEBUG_FS)) {
>>> + deferred_devices = debugfs_create_file("deferred_devices",
>>> + 0444, NULL, NULL,
>>> + &deferred_devs_fops);
>
>>> + if (!deferred_devices)
>>> + return -ENOMEM;
>
> This must not prevent the execution. So, the check introduces actually
> a regression.
>
Fair enough, I'll fix these an re-spin the patch.
>>> + }
>
Best regards,
--
Javier Martinez Canillas
Software Engineer - Desktop Hardware Enablement
Red Hat
^ permalink raw reply
* [PATCH] driver core: add a debugfs entry to show deferred devices
From: Javier Martinez Canillas @ 2018-06-19 20:59 UTC (permalink / raw)
To: linux-arm-kernel
For debugging purposes it may be useful to know what are the devices whose
probe function was deferred. Add a debugfs entry showing that information.
$ cat /sys/kernel/debug/deferred_devices
48070000.i2c:twl at 48:bci
musb-hdrc.0.auto
omapdrm.0
Signed-off-by: Javier Martinez Canillas <javierm@redhat.com>
---
Changes since RFC v1:
- Remove unneeded ret variable from deferred_devs_show()
Changes since RFC v2:
- Use DEFINE_SHOW_ATTRIBUTE() macro.
- Don't propagate debugfs_create_file() error.
- Remove IS_ENABLED(CONFIG_DEBUG_FS) guards.
- Drop RFC prefix.
drivers/base/dd.c | 22 ++++++++++++++++++++++
1 file changed, 22 insertions(+)
diff --git a/drivers/base/dd.c b/drivers/base/dd.c
index 1435d7281c6..8ec9e3cfbe4 100644
--- a/drivers/base/dd.c
+++ b/drivers/base/dd.c
@@ -16,6 +16,7 @@
* Copyright (c) 2007-2009 Novell Inc.
*/
+#include <linux/debugfs.h>
#include <linux/device.h>
#include <linux/delay.h>
#include <linux/dma-mapping.h>
@@ -224,6 +225,24 @@ void device_unblock_probing(void)
driver_deferred_probe_trigger();
}
+/*
+ * deferred_devs_show() - Show the devices in the deferred probe pending list.
+ */
+static int deferred_devs_show(struct seq_file *s, void *data)
+{
+ struct device_private *curr;
+
+ mutex_lock(&deferred_probe_mutex);
+
+ list_for_each_entry(curr, &deferred_probe_pending_list, deferred_probe)
+ seq_printf(s, "%s\n", dev_name(curr->device));
+
+ mutex_unlock(&deferred_probe_mutex);
+
+ return 0;
+}
+DEFINE_SHOW_ATTRIBUTE(deferred_devs);
+
/**
* deferred_probe_initcall() - Enable probing of deferred devices
*
@@ -233,6 +252,9 @@ void device_unblock_probing(void)
*/
static int deferred_probe_initcall(void)
{
+ debugfs_create_file("deferred_devices", 0444, NULL, NULL,
+ &deferred_devs_fops);
+
driver_deferred_probe_enable = true;
driver_deferred_probe_trigger();
/* Sort as many dependencies as possible before exiting initcalls */
--
2.17.1
^ permalink raw reply related
* [PATCH] driver core: add a debugfs entry to show deferred devices
From: Andy Shevchenko @ 2018-06-19 21:06 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180619205914.21375-1-javierm@redhat.com>
On Tue, Jun 19, 2018 at 11:59 PM, Javier Martinez Canillas
<javierm@redhat.com> wrote:
> For debugging purposes it may be useful to know what are the devices whose
> probe function was deferred. Add a debugfs entry showing that information.
>
> $ cat /sys/kernel/debug/deferred_devices
> 48070000.i2c:twl at 48:bci
> musb-hdrc.0.auto
> omapdrm.0
>
FWIW,
Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
> Signed-off-by: Javier Martinez Canillas <javierm@redhat.com>
>
> ---
>
> Changes since RFC v1:
> - Remove unneeded ret variable from deferred_devs_show()
>
> Changes since RFC v2:
> - Use DEFINE_SHOW_ATTRIBUTE() macro.
> - Don't propagate debugfs_create_file() error.
> - Remove IS_ENABLED(CONFIG_DEBUG_FS) guards.
> - Drop RFC prefix.
>
> drivers/base/dd.c | 22 ++++++++++++++++++++++
> 1 file changed, 22 insertions(+)
>
> diff --git a/drivers/base/dd.c b/drivers/base/dd.c
> index 1435d7281c6..8ec9e3cfbe4 100644
> --- a/drivers/base/dd.c
> +++ b/drivers/base/dd.c
> @@ -16,6 +16,7 @@
> * Copyright (c) 2007-2009 Novell Inc.
> */
>
> +#include <linux/debugfs.h>
> #include <linux/device.h>
> #include <linux/delay.h>
> #include <linux/dma-mapping.h>
> @@ -224,6 +225,24 @@ void device_unblock_probing(void)
> driver_deferred_probe_trigger();
> }
>
> +/*
> + * deferred_devs_show() - Show the devices in the deferred probe pending list.
> + */
> +static int deferred_devs_show(struct seq_file *s, void *data)
> +{
> + struct device_private *curr;
> +
> + mutex_lock(&deferred_probe_mutex);
> +
> + list_for_each_entry(curr, &deferred_probe_pending_list, deferred_probe)
> + seq_printf(s, "%s\n", dev_name(curr->device));
> +
> + mutex_unlock(&deferred_probe_mutex);
> +
> + return 0;
> +}
> +DEFINE_SHOW_ATTRIBUTE(deferred_devs);
> +
> /**
> * deferred_probe_initcall() - Enable probing of deferred devices
> *
> @@ -233,6 +252,9 @@ void device_unblock_probing(void)
> */
> static int deferred_probe_initcall(void)
> {
> + debugfs_create_file("deferred_devices", 0444, NULL, NULL,
> + &deferred_devs_fops);
> +
> driver_deferred_probe_enable = true;
> driver_deferred_probe_trigger();
> /* Sort as many dependencies as possible before exiting initcalls */
> --
> 2.17.1
>
--
With Best Regards,
Andy Shevchenko
^ permalink raw reply
* [PATCH v5 0/6] clocksource: rework Atmel TCB timer driver
From: Alexandre Belloni @ 2018-06-19 21:19 UTC (permalink / raw)
To: linux-arm-kernel
Hi,
This series reworks the Atmel TCB drivers. It introduces a new driver to handle
the clocksource and clockevent devices.
As a reminder, this is necessary because:
- the current tcb_clksrc driver is probed too late to be able to be used at
boot and we now have SoCs that don't have a PIT. They currently are not able
to boot a mainline kernel.
- using the PIT doesn't work well with preempt-rt because its interrupt is
shared (in particular with the UART and their interrupt flags are
incompatible)
- the current solution is wasting some TCB channels
The plan is to get this driver upstream, then convert the TCB PWM driver to be
able to get rid of the tcb_clksrc driver along with atmel_tclib now that AVR32
is gone.
changes in v5:
- rebased on v4.18-rc1
- fixed the clock enabling/disabling in atomic context under preempt-rt
Changes in v4:
- rebased on top of v4.17-rc1
- fixed an issue when setting max_delta for clockevents_config_and_register
Alexandre Belloni (6):
ARM: at91: add TCB registers definitions
clocksource/drivers: Add a new driver for the Atmel ARM TC blocks
clocksource/drivers: atmel-pit: make option silent
ARM: at91: Implement clocksource selection
ARM: configs: at91: use new TCB timer driver
ARM: configs: at91: unselect PIT
arch/arm/configs/at91_dt_defconfig | 2 +-
arch/arm/configs/sama5_defconfig | 2 +-
arch/arm/mach-at91/Kconfig | 25 +
drivers/clocksource/Kconfig | 13 +-
drivers/clocksource/Makefile | 3 +-
drivers/clocksource/timer-atmel-tcb.c | 630 ++++++++++++++++++++++++++
include/soc/at91/atmel_tcb.h | 216 +++++++++
7 files changed, 887 insertions(+), 4 deletions(-)
create mode 100644 drivers/clocksource/timer-atmel-tcb.c
create mode 100644 include/soc/at91/atmel_tcb.h
--
2.17.1
^ permalink raw reply
* [PATCH v5 1/6] ARM: at91: add TCB registers definitions
From: Alexandre Belloni @ 2018-06-19 21:19 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180619211929.22908-1-alexandre.belloni@bootlin.com>
Add registers and bits definitions for the timer counter blocks found on
Atmel ARM SoCs.
Tested-by: Alexander Dahl <ada@thorsis.com>
Tested-by: Andras Szemzo <szemzo.andras@gmail.com>
Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
---
include/soc/at91/atmel_tcb.h | 216 +++++++++++++++++++++++++++++++++++
1 file changed, 216 insertions(+)
create mode 100644 include/soc/at91/atmel_tcb.h
diff --git a/include/soc/at91/atmel_tcb.h b/include/soc/at91/atmel_tcb.h
new file mode 100644
index 000000000000..3ed66031fc76
--- /dev/null
+++ b/include/soc/at91/atmel_tcb.h
@@ -0,0 +1,216 @@
+//SPDX-License-Identifier: GPL-2.0
+/* Copyright (C) 2018 Microchip */
+
+#ifndef __SOC_ATMEL_TCB_H
+#define __SOC_ATMEL_TCB_H
+
+/* Channel registers */
+#define ATMEL_TC_COFFS(c) ((c) * 0x40)
+#define ATMEL_TC_CCR(c) ATMEL_TC_COFFS(c)
+#define ATMEL_TC_CMR(c) (ATMEL_TC_COFFS(c) + 0x4)
+#define ATMEL_TC_SMMR(c) (ATMEL_TC_COFFS(c) + 0x8)
+#define ATMEL_TC_RAB(c) (ATMEL_TC_COFFS(c) + 0xc)
+#define ATMEL_TC_CV(c) (ATMEL_TC_COFFS(c) + 0x10)
+#define ATMEL_TC_RA(c) (ATMEL_TC_COFFS(c) + 0x14)
+#define ATMEL_TC_RB(c) (ATMEL_TC_COFFS(c) + 0x18)
+#define ATMEL_TC_RC(c) (ATMEL_TC_COFFS(c) + 0x1c)
+#define ATMEL_TC_SR(c) (ATMEL_TC_COFFS(c) + 0x20)
+#define ATMEL_TC_IER(c) (ATMEL_TC_COFFS(c) + 0x24)
+#define ATMEL_TC_IDR(c) (ATMEL_TC_COFFS(c) + 0x28)
+#define ATMEL_TC_IMR(c) (ATMEL_TC_COFFS(c) + 0x2c)
+#define ATMEL_TC_EMR(c) (ATMEL_TC_COFFS(c) + 0x30)
+
+/* Block registers */
+#define ATMEL_TC_BCR 0xc0
+#define ATMEL_TC_BMR 0xc4
+#define ATMEL_TC_QIER 0xc8
+#define ATMEL_TC_QIDR 0xcc
+#define ATMEL_TC_QIMR 0xd0
+#define ATMEL_TC_QISR 0xd4
+#define ATMEL_TC_FMR 0xd8
+#define ATMEL_TC_WPMR 0xe4
+
+/* CCR fields */
+#define ATMEL_TC_CCR_CLKEN BIT(0)
+#define ATMEL_TC_CCR_CLKDIS BIT(1)
+#define ATMEL_TC_CCR_SWTRG BIT(2)
+
+/* Common CMR fields */
+#define ATMEL_TC_CMR_TCLKS_MSK GENMASK(2, 0)
+#define ATMEL_TC_CMR_TCLK(x) (x)
+#define ATMEL_TC_CMR_XC(x) ((x) + 5)
+#define ATMEL_TC_CMR_CLKI BIT(3)
+#define ATMEL_TC_CMR_BURST_MSK GENMASK(5, 4)
+#define ATMEL_TC_CMR_BURST_XC(x) (((x) + 1) << 4)
+#define ATMEL_TC_CMR_WAVE BIT(15)
+
+/* Capture mode CMR fields */
+#define ATMEL_TC_CMR_LDBSTOP BIT(6)
+#define ATMEL_TC_CMR_LDBDIS BIT(7)
+#define ATMEL_TC_CMR_ETRGEDG_MSK GENMASK(9, 8)
+#define ATMEL_TC_CMR_ETRGEDG_NONE (0 << 8)
+#define ATMEL_TC_CMR_ETRGEDG_RISING (1 << 8)
+#define ATMEL_TC_CMR_ETRGEDG_FALLING (2 << 8)
+#define ATMEL_TC_CMR_ETRGEDG_BOTH (3 << 8)
+#define ATMEL_TC_CMR_ABETRG BIT(10)
+#define ATMEL_TC_CMR_CPCTRG BIT(14)
+#define ATMEL_TC_CMR_LDRA_MSK GENMASK(17, 16)
+#define ATMEL_TC_CMR_LDRA_NONE (0 << 16)
+#define ATMEL_TC_CMR_LDRA_RISING (1 << 16)
+#define ATMEL_TC_CMR_LDRA_FALLING (2 << 16)
+#define ATMEL_TC_CMR_LDRA_BOTH (3 << 16)
+#define ATMEL_TC_CMR_LDRB_MSK GENMASK(19, 18)
+#define ATMEL_TC_CMR_LDRB_NONE (0 << 18)
+#define ATMEL_TC_CMR_LDRB_RISING (1 << 18)
+#define ATMEL_TC_CMR_LDRB_FALLING (2 << 18)
+#define ATMEL_TC_CMR_LDRB_BOTH (3 << 18)
+#define ATMEL_TC_CMR_SBSMPLR_MSK GENMASK(22, 20)
+#define ATMEL_TC_CMR_SBSMPLR(x) ((x) << 20)
+
+/* Waveform mode CMR fields */
+#define ATMEL_TC_CMR_CPCSTOP BIT(6)
+#define ATMEL_TC_CMR_CPCDIS BIT(7)
+#define ATMEL_TC_CMR_EEVTEDG_MSK GENMASK(9, 8)
+#define ATMEL_TC_CMR_EEVTEDG_NONE (0 << 8)
+#define ATMEL_TC_CMR_EEVTEDG_RISING (1 << 8)
+#define ATMEL_TC_CMR_EEVTEDG_FALLING (2 << 8)
+#define ATMEL_TC_CMR_EEVTEDG_BOTH (3 << 8)
+#define ATMEL_TC_CMR_EEVT_MSK GENMASK(11, 10)
+#define ATMEL_TC_CMR_EEVT_XC(x) (((x) + 1) << 10)
+#define ATMEL_TC_CMR_ENETRG BIT(12)
+#define ATMEL_TC_CMR_WAVESEL_MSK GENMASK(14, 13)
+#define ATMEL_TC_CMR_WAVESEL_UP (0 << 13)
+#define ATMEL_TC_CMR_WAVESEL_UPDOWN (1 << 13)
+#define ATMEL_TC_CMR_WAVESEL_UPRC (2 << 13)
+#define ATMEL_TC_CMR_WAVESEL_UPDOWNRC (3 << 13)
+#define ATMEL_TC_CMR_ACPA_MSK GENMASK(17, 16)
+#define ATMEL_TC_CMR_ACPA(a) (ATMEL_TC_CMR_ACTION_##a << 16)
+#define ATMEL_TC_CMR_ACPC_MSK GENMASK(19, 18)
+#define ATMEL_TC_CMR_ACPC(a) (ATMEL_TC_CMR_ACTION_##a << 18)
+#define ATMEL_TC_CMR_AEEVT_MSK GENMASK(21, 20)
+#define ATMEL_TC_CMR_AEEVT(a) (ATMEL_TC_CMR_ACTION_##a << 20)
+#define ATMEL_TC_CMR_ASWTRG_MSK GENMASK(23, 22)
+#define ATMEL_TC_CMR_ASWTRG(a) (ATMEL_TC_CMR_ACTION_##a << 22)
+#define ATMEL_TC_CMR_BCPB_MSK GENMASK(25, 24)
+#define ATMEL_TC_CMR_BCPB(a) (ATMEL_TC_CMR_ACTION_##a << 24)
+#define ATMEL_TC_CMR_BCPC_MSK GENMASK(27, 26)
+#define ATMEL_TC_CMR_BCPC(a) (ATMEL_TC_CMR_ACTION_##a << 26)
+#define ATMEL_TC_CMR_BEEVT_MSK GENMASK(29, 28)
+#define ATMEL_TC_CMR_BEEVT(a) (ATMEL_TC_CMR_ACTION_##a << 28)
+#define ATMEL_TC_CMR_BSWTRG_MSK GENMASK(31, 30)
+#define ATMEL_TC_CMR_BSWTRG(a) (ATMEL_TC_CMR_ACTION_##a << 30)
+#define ATMEL_TC_CMR_ACTION_NONE 0
+#define ATMEL_TC_CMR_ACTION_SET 1
+#define ATMEL_TC_CMR_ACTION_CLEAR 2
+#define ATMEL_TC_CMR_ACTION_TOGGLE 3
+
+/* SMMR fields */
+#define ATMEL_TC_SMMR_GCEN BIT(0)
+#define ATMEL_TC_SMMR_DOWN BIT(1)
+
+/* SR/IER/IDR/IMR fields */
+#define ATMEL_TC_COVFS BIT(0)
+#define ATMEL_TC_LOVRS BIT(1)
+#define ATMEL_TC_CPAS BIT(2)
+#define ATMEL_TC_CPBS BIT(3)
+#define ATMEL_TC_CPCS BIT(4)
+#define ATMEL_TC_LDRAS BIT(5)
+#define ATMEL_TC_LDRBS BIT(6)
+#define ATMEL_TC_ETRGS BIT(7)
+#define ATMEL_TC_CLKSTA BIT(16)
+#define ATMEL_TC_MTIOA BIT(17)
+#define ATMEL_TC_MTIOB BIT(18)
+
+/* EMR fields */
+#define ATMEL_TC_EMR_TRIGSRCA_MSK GENMASK(1, 0)
+#define ATMEL_TC_EMR_TRIGSRCA_TIOA 0
+#define ATMEL_TC_EMR_TRIGSRCA_PWMX 1
+#define ATMEL_TC_EMR_TRIGSRCB_MSK GENMASK(5, 4)
+#define ATMEL_TC_EMR_TRIGSRCB_TIOB (0 << 4)
+#define ATMEL_TC_EMR_TRIGSRCB_PWM (1 << 4)
+#define ATMEL_TC_EMR_NOCLKDIV BIT(8)
+
+/* BCR fields */
+#define ATMEL_TC_BCR_SYNC BIT(0)
+
+/* BMR fields */
+#define ATMEL_TC_BMR_TCXC_MSK(c) GENMASK(((c) * 2) + 1, (c) * 2)
+#define ATMEL_TC_BMR_TCXC(x, c) ((x) << (2 * (c)))
+#define ATMEL_TC_BMR_QDEN BIT(8)
+#define ATMEL_TC_BMR_POSEN BIT(9)
+#define ATMEL_TC_BMR_SPEEDEN BIT(10)
+#define ATMEL_TC_BMR_QDTRANS BIT(11)
+#define ATMEL_TC_BMR_EDGPHA BIT(12)
+#define ATMEL_TC_BMR_INVA BIT(13)
+#define ATMEL_TC_BMR_INVB BIT(14)
+#define ATMEL_TC_BMR_INVIDX BIT(15)
+#define ATMEL_TC_BMR_SWAP BIT(16)
+#define ATMEL_TC_BMR_IDXPHB BIT(17)
+#define ATMEL_TC_BMR_AUTOC BIT(18)
+#define ATMEL_TC_MAXFILT_MSK GENMASK(25, 20)
+#define ATMEL_TC_MAXFILT(x) (((x) - 1) << 20)
+#define ATMEL_TC_MAXCMP_MSK GENMASK(29, 26)
+#define ATMEL_TC_MAXCMP(x) ((x) << 26)
+
+/* QEDC fields */
+#define ATMEL_TC_QEDC_IDX BIT(0)
+#define ATMEL_TC_QEDC_DIRCHG BIT(1)
+#define ATMEL_TC_QEDC_QERR BIT(2)
+#define ATMEL_TC_QEDC_MPE BIT(3)
+#define ATMEL_TC_QEDC_DIR BIT(8)
+
+/* FMR fields */
+#define ATMEL_TC_FMR_ENCF(x) BIT(x)
+
+/* WPMR fields */
+#define ATMEL_TC_WPMR_WPKEY (0x54494d << 8)
+#define ATMEL_TC_WPMR_WPEN BIT(0)
+
+static inline struct clk *tcb_clk_get(struct device_node *node, int channel)
+{
+ struct clk *clk;
+ char clk_name[] = "t0_clk";
+
+ clk_name[1] += channel;
+ clk = of_clk_get_by_name(node->parent, clk_name);
+ if (!IS_ERR(clk))
+ return clk;
+
+ return of_clk_get_by_name(node->parent, "t0_clk");
+}
+
+static inline int tcb_irq_get(struct device_node *node, int channel)
+{
+ int irq;
+
+ irq = of_irq_get(node->parent, channel);
+ if (irq > 0)
+ return irq;
+
+ return of_irq_get(node->parent, 0);
+}
+
+static const u8 atmel_tc_divisors[5] = { 2, 8, 32, 128, 0, };
+
+struct atmel_tcb_info {
+ int bits;
+};
+
+static const struct atmel_tcb_info atmel_tcb_infos[] = {
+ { .bits = 16 },
+ { .bits = 32 },
+};
+
+static const struct of_device_id atmel_tcb_dt_ids[] = {
+ {
+ .compatible = "atmel,at91rm9200-tcb",
+ .data = &atmel_tcb_infos[0],
+ }, {
+ .compatible = "atmel,at91sam9x5-tcb",
+ .data = &atmel_tcb_infos[1],
+ }, {
+ /* sentinel */
+ }
+};
+
+#endif /* __SOC_ATMEL_TCB_H */
--
2.17.1
^ permalink raw reply related
* [PATCH v5 2/6] clocksource/drivers: Add a new driver for the Atmel ARM TC blocks
From: Alexandre Belloni @ 2018-06-19 21:19 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180619211929.22908-1-alexandre.belloni@bootlin.com>
Add a driver for the Atmel Timer Counter Blocks. This driver provides a
clocksource and two clockevent devices.
One of the clockevent device is linked to the clocksource counter and so it
will run at the same frequency. This will be used when there is only on TCB
channel available for timers.
The other clockevent device runs on a separate TCB channel when available.
This driver uses regmap and syscon to be able to probe early in the boot
and avoid having to switch on the TCB clocksource later. Using regmap also
means that unused TCB channels may be used by other drivers (PWM for
example). read/writel are still used to access channel specific registers
to avoid the performance impact of regmap (mainly locking).
Tested-by: Alexander Dahl <ada@thorsis.com>
Tested-by: Andras Szemzo <szemzo.andras@gmail.com>
Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
---
drivers/clocksource/Kconfig | 8 +
drivers/clocksource/Makefile | 3 +-
drivers/clocksource/timer-atmel-tcb.c | 630 ++++++++++++++++++++++++++
3 files changed, 640 insertions(+), 1 deletion(-)
create mode 100644 drivers/clocksource/timer-atmel-tcb.c
diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
index dec0dd88ec15..0b1b0de2abcc 100644
--- a/drivers/clocksource/Kconfig
+++ b/drivers/clocksource/Kconfig
@@ -403,6 +403,14 @@ config ATMEL_ST
help
Support for the Atmel ST timer.
+config ATMEL_ARM_TCB_CLKSRC
+ bool "Microchip ARM TC Block" if COMPILE_TEST
+ select REGMAP_MMIO
+ depends on GENERIC_CLOCKEVENTS
+ help
+ This enables build of clocksource and clockevent driver for
+ the integrated Timer Counter Blocks in Microchip ARM SoCs.
+
config CLKSRC_EXYNOS_MCT
bool "Exynos multi core timer driver" if COMPILE_TEST
depends on ARM || ARM64
diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile
index 00caf37e52f9..6991348aa24a 100644
--- a/drivers/clocksource/Makefile
+++ b/drivers/clocksource/Makefile
@@ -3,7 +3,8 @@ obj-$(CONFIG_TIMER_OF) += timer-of.o
obj-$(CONFIG_TIMER_PROBE) += timer-probe.o
obj-$(CONFIG_ATMEL_PIT) += timer-atmel-pit.o
obj-$(CONFIG_ATMEL_ST) += timer-atmel-st.o
-obj-$(CONFIG_ATMEL_TCB_CLKSRC) += tcb_clksrc.o
+obj-$(CONFIG_ATMEL_TCB_CLKSRC) += tcb_clksrc.o
+obj-$(CONFIG_ATMEL_ARM_TCB_CLKSRC) += timer-atmel-tcb.o
obj-$(CONFIG_X86_PM_TIMER) += acpi_pm.o
obj-$(CONFIG_SCx200HR_TIMER) += scx200_hrt.o
obj-$(CONFIG_CS5535_CLOCK_EVENT_SRC) += cs5535-clockevt.o
diff --git a/drivers/clocksource/timer-atmel-tcb.c b/drivers/clocksource/timer-atmel-tcb.c
new file mode 100644
index 000000000000..73e6b2783dda
--- /dev/null
+++ b/drivers/clocksource/timer-atmel-tcb.c
@@ -0,0 +1,630 @@
+// SPDX-License-Identifier: GPL-2.0
+#include <linux/clk.h>
+#include <linux/clockchips.h>
+#include <linux/clocksource.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/mfd/syscon.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/regmap.h>
+#include <linux/sched_clock.h>
+#include <soc/at91/atmel_tcb.h>
+
+static struct atmel_tcb_clksrc {
+ struct clocksource clksrc;
+ struct clock_event_device clkevt;
+ struct regmap *regmap;
+ void __iomem *base;
+ struct clk *clk[2];
+ char name[20];
+ int channels[2];
+ int bits;
+ int irq;
+ struct {
+ u32 cmr;
+ u32 imr;
+ u32 rc;
+ bool clken;
+ } cache[2];
+ u32 bmr_cache;
+ bool registered;
+} tc = {
+ .clksrc = {
+ .rating = 200,
+ .mask = CLOCKSOURCE_MASK(32),
+ .flags = CLOCK_SOURCE_IS_CONTINUOUS,
+ },
+ .clkevt = {
+ .features = CLOCK_EVT_FEAT_ONESHOT,
+ /* Should be lower than at91rm9200's system timer */
+ .rating = 125,
+ },
+};
+
+static struct tc_clkevt_device {
+ struct clock_event_device clkevt;
+ struct regmap *regmap;
+ void __iomem *base;
+ struct clk *slow_clk;
+ struct clk *clk;
+ char name[20];
+ int channel;
+ int irq;
+ struct {
+ u32 cmr;
+ u32 imr;
+ u32 rc;
+ bool clken;
+ } cache;
+ bool registered;
+ bool clk_enabled;
+} tce = {
+ .clkevt = {
+ .features = CLOCK_EVT_FEAT_PERIODIC |
+ CLOCK_EVT_FEAT_ONESHOT,
+ /*
+ * Should be lower than at91rm9200's system timer
+ * but higher than tc.clkevt.rating
+ */
+ .rating = 140,
+ },
+};
+
+/*
+ * Clockevent device using its own channel
+ */
+
+static void tc_clkevt2_clk_disable(struct clock_event_device *d)
+{
+ clk_disable(tce.clk);
+ tce.clk_enabled = false;
+}
+
+static void tc_clkevt2_clk_enable(struct clock_event_device *d)
+{
+ if (tce.clk_enabled)
+ return;
+ clk_enable(tce.clk);
+ tce.clk_enabled = true;
+}
+
+static int tc_clkevt2_stop(struct clock_event_device *d)
+{
+ writel(0xff, tce.base + ATMEL_TC_IDR(tce.channel));
+ writel(ATMEL_TC_CCR_CLKDIS, tce.base + ATMEL_TC_CCR(tce.channel));
+
+ return 0;
+}
+
+static int tc_clkevt2_shutdown(struct clock_event_device *d)
+{
+ tc_clkevt2_stop(d);
+ if (!clockevent_state_detached(d))
+ tc_clkevt2_clk_disable(d);
+
+ return 0;
+}
+
+/* For now, we always use the 32K clock ... this optimizes for NO_HZ,
+ * because using one of the divided clocks would usually mean the
+ * tick rate can never be less than several dozen Hz (vs 0.5 Hz).
+ *
+ * A divided clock could be good for high resolution timers, since
+ * 30.5 usec resolution can seem "low".
+ */
+static int tc_clkevt2_set_oneshot(struct clock_event_device *d)
+{
+ if (clockevent_state_oneshot(d) || clockevent_state_periodic(d))
+ tc_clkevt2_stop(d);
+
+ tc_clkevt2_clk_enable(d);
+
+ /* slow clock, count up to RC, then irq and stop */
+ writel(ATMEL_TC_CMR_TCLK(4) | ATMEL_TC_CMR_CPCSTOP |
+ ATMEL_TC_CMR_WAVE | ATMEL_TC_CMR_WAVESEL_UPRC,
+ tce.base + ATMEL_TC_CMR(tce.channel));
+ writel(ATMEL_TC_CPCS, tce.base + ATMEL_TC_IER(tce.channel));
+
+ return 0;
+}
+
+static int tc_clkevt2_set_periodic(struct clock_event_device *d)
+{
+ if (clockevent_state_oneshot(d) || clockevent_state_periodic(d))
+ tc_clkevt2_stop(d);
+
+ /* By not making the gentime core emulate periodic mode on top
+ * of oneshot, we get lower overhead and improved accuracy.
+ */
+ tc_clkevt2_clk_enable(d);
+
+ /* slow clock, count up to RC, then irq and restart */
+ writel(ATMEL_TC_CMR_TCLK(4) | ATMEL_TC_CMR_WAVE |
+ ATMEL_TC_CMR_WAVESEL_UPRC,
+ tce.base + ATMEL_TC_CMR(tce.channel));
+ writel((32768 + HZ / 2) / HZ, tce.base + ATMEL_TC_RC(tce.channel));
+
+ /* Enable clock and interrupts on RC compare */
+ writel(ATMEL_TC_CPCS, tce.base + ATMEL_TC_IER(tce.channel));
+ writel(ATMEL_TC_CCR_CLKEN | ATMEL_TC_CCR_SWTRG,
+ tce.base + ATMEL_TC_CCR(tce.channel));
+
+ return 0;
+}
+
+static int tc_clkevt2_next_event(unsigned long delta,
+ struct clock_event_device *d)
+{
+ writel(delta, tce.base + ATMEL_TC_RC(tce.channel));
+ writel(ATMEL_TC_CCR_CLKEN | ATMEL_TC_CCR_SWTRG,
+ tce.base + ATMEL_TC_CCR(tce.channel));
+
+ return 0;
+}
+
+static irqreturn_t tc_clkevt2_irq(int irq, void *handle)
+{
+ unsigned int sr;
+
+ sr = readl(tce.base + ATMEL_TC_SR(tce.channel));
+ if (sr & ATMEL_TC_CPCS) {
+ tce.clkevt.event_handler(&tce.clkevt);
+ return IRQ_HANDLED;
+ }
+
+ return IRQ_NONE;
+}
+
+static void tc_clkevt2_suspend(struct clock_event_device *d)
+{
+ tce.cache.cmr = readl(tce.base + ATMEL_TC_CMR(tce.channel));
+ tce.cache.imr = readl(tce.base + ATMEL_TC_IMR(tce.channel));
+ tce.cache.rc = readl(tce.base + ATMEL_TC_RC(tce.channel));
+ tce.cache.clken = !!(readl(tce.base + ATMEL_TC_SR(tce.channel)) &
+ ATMEL_TC_CLKSTA);
+}
+
+static void tc_clkevt2_resume(struct clock_event_device *d)
+{
+ /* Restore registers for the channel, RA and RB are not used */
+ writel(tce.cache.cmr, tc.base + ATMEL_TC_CMR(tce.channel));
+ writel(tce.cache.rc, tc.base + ATMEL_TC_RC(tce.channel));
+ writel(0, tc.base + ATMEL_TC_RA(tce.channel));
+ writel(0, tc.base + ATMEL_TC_RB(tce.channel));
+ /* Disable all the interrupts */
+ writel(0xff, tc.base + ATMEL_TC_IDR(tce.channel));
+ /* Reenable interrupts that were enabled before suspending */
+ writel(tce.cache.imr, tc.base + ATMEL_TC_IER(tce.channel));
+
+ /* Start the clock if it was used */
+ if (tce.cache.clken)
+ writel(ATMEL_TC_CCR_CLKEN | ATMEL_TC_CCR_SWTRG,
+ tc.base + ATMEL_TC_CCR(tce.channel));
+}
+
+static int __init tc_clkevt_register(struct device_node *node,
+ struct regmap *regmap, void __iomem *base,
+ int channel, int irq, int bits)
+{
+ int ret;
+
+ tce.regmap = regmap;
+ tce.base = base;
+ tce.channel = channel;
+ tce.irq = irq;
+
+ tce.slow_clk = of_clk_get_by_name(node->parent, "slow_clk");
+ if (IS_ERR(tce.slow_clk))
+ return PTR_ERR(tce.slow_clk);
+
+ ret = clk_prepare_enable(tce.slow_clk);
+ if (ret)
+ return ret;
+
+ tce.clk = tcb_clk_get(node, tce.channel);
+ if (IS_ERR(tce.clk)) {
+ ret = PTR_ERR(tce.clk);
+ goto err_slow;
+ }
+
+ snprintf(tce.name, sizeof(tce.name), "%s:%d",
+ kbasename(node->parent->full_name), channel);
+ tce.clkevt.cpumask = cpumask_of(0);
+ tce.clkevt.name = tce.name;
+ tce.clkevt.set_next_event = tc_clkevt2_next_event,
+ tce.clkevt.set_state_shutdown = tc_clkevt2_shutdown,
+ tce.clkevt.set_state_periodic = tc_clkevt2_set_periodic,
+ tce.clkevt.set_state_oneshot = tc_clkevt2_set_oneshot,
+ tce.clkevt.suspend = tc_clkevt2_suspend,
+ tce.clkevt.resume = tc_clkevt2_resume,
+
+ /* try to enable clk to avoid future errors in mode change */
+ ret = clk_prepare_enable(tce.clk);
+ if (ret)
+ goto err_slow;
+ clk_disable(tce.clk);
+
+ clockevents_config_and_register(&tce.clkevt, 32768, 1, BIT(bits) - 1);
+
+ ret = request_irq(tce.irq, tc_clkevt2_irq, IRQF_TIMER | IRQF_SHARED,
+ tce.clkevt.name, &tce);
+ if (ret)
+ goto err_clk;
+
+ tce.registered = true;
+
+ return 0;
+
+err_clk:
+ clk_unprepare(tce.clk);
+err_slow:
+ clk_disable_unprepare(tce.slow_clk);
+
+ return ret;
+}
+
+/*
+ * Clocksource and clockevent using the same channel(s)
+ */
+static u64 tc_get_cycles(struct clocksource *cs)
+{
+ u32 lower, upper;
+
+ do {
+ upper = readl_relaxed(tc.base + ATMEL_TC_CV(tc.channels[1]));
+ lower = readl_relaxed(tc.base + ATMEL_TC_CV(tc.channels[0]));
+ } while (upper != readl_relaxed(tc.base + ATMEL_TC_CV(tc.channels[1])));
+
+ return (upper << 16) | lower;
+}
+
+static u64 tc_get_cycles32(struct clocksource *cs)
+{
+ return readl_relaxed(tc.base + ATMEL_TC_CV(tc.channels[0]));
+}
+
+static u64 notrace tc_sched_clock_read(void)
+{
+ return tc_get_cycles(&tc.clksrc);
+}
+
+static u64 notrace tc_sched_clock_read32(void)
+{
+ return tc_get_cycles32(&tc.clksrc);
+}
+
+static int tcb_clkevt_next_event(unsigned long delta,
+ struct clock_event_device *d)
+{
+ u32 old, next, cur;
+
+ old = readl(tc.base + ATMEL_TC_CV(tc.channels[0]));
+ next = old + delta;
+ writel(next, tc.base + ATMEL_TC_RC(tc.channels[0]));
+ cur = readl(tc.base + ATMEL_TC_CV(tc.channels[0]));
+
+ /* check whether the delta elapsed while setting the register */
+ if ((next < old && cur < old && cur > next) ||
+ (next > old && (cur < old || cur > next))) {
+ /*
+ * Clear the CPCS bit in the status register to avoid
+ * generating a spurious interrupt next time a valid
+ * timer event is configured.
+ */
+ old = readl(tc.base + ATMEL_TC_SR(tc.channels[0]));
+ return -ETIME;
+ }
+
+ writel(ATMEL_TC_CPCS, tc.base + ATMEL_TC_IER(tc.channels[0]));
+
+ return 0;
+}
+
+static irqreturn_t tc_clkevt_irq(int irq, void *handle)
+{
+ unsigned int sr;
+
+ sr = readl(tc.base + ATMEL_TC_SR(tc.channels[0]));
+ if (sr & ATMEL_TC_CPCS) {
+ tc.clkevt.event_handler(&tc.clkevt);
+ return IRQ_HANDLED;
+ }
+
+ return IRQ_NONE;
+}
+
+static int tcb_clkevt_oneshot(struct clock_event_device *dev)
+{
+ if (clockevent_state_oneshot(dev))
+ return 0;
+
+ /*
+ * Because both clockevent devices may share the same IRQ, we don't want
+ * the less likely one to stay requested
+ */
+ return request_irq(tc.irq, tc_clkevt_irq, IRQF_TIMER | IRQF_SHARED,
+ tc.name, &tc);
+}
+
+static int tcb_clkevt_shutdown(struct clock_event_device *dev)
+{
+ writel(0xff, tc.base + ATMEL_TC_IDR(tc.channels[0]));
+ if (tc.bits == 16)
+ writel(0xff, tc.base + ATMEL_TC_IDR(tc.channels[1]));
+
+ if (!clockevent_state_detached(dev))
+ free_irq(tc.irq, &tc);
+
+ return 0;
+}
+
+static void __init tcb_setup_dual_chan(struct atmel_tcb_clksrc *tc,
+ int mck_divisor_idx)
+{
+ /* first channel: waveform mode, input mclk/8, clock TIOA on overflow */
+ writel(mck_divisor_idx /* likely divide-by-8 */
+ | ATMEL_TC_CMR_WAVE
+ | ATMEL_TC_CMR_WAVESEL_UP /* free-run */
+ | ATMEL_TC_CMR_ACPA(SET) /* TIOA rises at 0 */
+ | ATMEL_TC_CMR_ACPC(CLEAR), /* (duty cycle 50%) */
+ tc->base + ATMEL_TC_CMR(tc->channels[0]));
+ writel(0x0000, tc->base + ATMEL_TC_RA(tc->channels[0]));
+ writel(0x8000, tc->base + ATMEL_TC_RC(tc->channels[0]));
+ writel(0xff, tc->base + ATMEL_TC_IDR(tc->channels[0])); /* no irqs */
+ writel(ATMEL_TC_CCR_CLKEN, tc->base + ATMEL_TC_CCR(tc->channels[0]));
+
+ /* second channel: waveform mode, input TIOA */
+ writel(ATMEL_TC_CMR_XC(tc->channels[1]) /* input: TIOA */
+ | ATMEL_TC_CMR_WAVE
+ | ATMEL_TC_CMR_WAVESEL_UP, /* free-run */
+ tc->base + ATMEL_TC_CMR(tc->channels[1]));
+ writel(0xff, tc->base + ATMEL_TC_IDR(tc->channels[1])); /* no irqs */
+ writel(ATMEL_TC_CCR_CLKEN, tc->base + ATMEL_TC_CCR(tc->channels[1]));
+
+ /* chain both channel, we assume the previous channel */
+ regmap_write(tc->regmap, ATMEL_TC_BMR,
+ ATMEL_TC_BMR_TCXC(1 + tc->channels[1], tc->channels[1]));
+ /* then reset all the timers */
+ regmap_write(tc->regmap, ATMEL_TC_BCR, ATMEL_TC_BCR_SYNC);
+}
+
+static void __init tcb_setup_single_chan(struct atmel_tcb_clksrc *tc,
+ int mck_divisor_idx)
+{
+ /* channel 0: waveform mode, input mclk/8 */
+ writel(mck_divisor_idx /* likely divide-by-8 */
+ | ATMEL_TC_CMR_WAVE
+ | ATMEL_TC_CMR_WAVESEL_UP, /* free-run */
+ tc->base + ATMEL_TC_CMR(tc->channels[0]));
+ writel(0xff, tc->base + ATMEL_TC_IDR(tc->channels[0])); /* no irqs */
+ writel(ATMEL_TC_CCR_CLKEN, tc->base + ATMEL_TC_CCR(tc->channels[0]));
+
+ /* then reset all the timers */
+ regmap_write(tc->regmap, ATMEL_TC_BCR, ATMEL_TC_BCR_SYNC);
+}
+
+static void tc_clksrc_suspend(struct clocksource *cs)
+{
+ int i;
+
+ for (i = 0; i < 1 + (tc.bits == 16); i++) {
+ tc.cache[i].cmr = readl(tc.base + ATMEL_TC_CMR(tc.channels[i]));
+ tc.cache[i].imr = readl(tc.base + ATMEL_TC_IMR(tc.channels[i]));
+ tc.cache[i].rc = readl(tc.base + ATMEL_TC_RC(tc.channels[i]));
+ tc.cache[i].clken = !!(readl(tc.base +
+ ATMEL_TC_SR(tc.channels[i])) &
+ ATMEL_TC_CLKSTA);
+ }
+
+ if (tc.bits == 16)
+ regmap_read(tc.regmap, ATMEL_TC_BMR, &tc.bmr_cache);
+}
+
+static void tc_clksrc_resume(struct clocksource *cs)
+{
+ int i;
+
+ for (i = 0; i < 1 + (tc.bits == 16); i++) {
+ /* Restore registers for the channel, RA and RB are not used */
+ writel(tc.cache[i].cmr, tc.base + ATMEL_TC_CMR(tc.channels[i]));
+ writel(tc.cache[i].rc, tc.base + ATMEL_TC_RC(tc.channels[i]));
+ writel(0, tc.base + ATMEL_TC_RA(tc.channels[i]));
+ writel(0, tc.base + ATMEL_TC_RB(tc.channels[i]));
+ /* Disable all the interrupts */
+ writel(0xff, tc.base + ATMEL_TC_IDR(tc.channels[i]));
+ /* Reenable interrupts that were enabled before suspending */
+ writel(tc.cache[i].imr, tc.base + ATMEL_TC_IER(tc.channels[i]));
+
+ /* Start the clock if it was used */
+ if (tc.cache[i].clken)
+ writel(ATMEL_TC_CCR_CLKEN, tc.base +
+ ATMEL_TC_CCR(tc.channels[i]));
+ }
+
+ /* in case of dual channel, chain channels */
+ if (tc.bits == 16)
+ regmap_write(tc.regmap, ATMEL_TC_BMR, tc.bmr_cache);
+ /* Finally, trigger all the channels*/
+ regmap_write(tc.regmap, ATMEL_TC_BCR, ATMEL_TC_BCR_SYNC);
+}
+
+static int __init tcb_clksrc_register(struct device_node *node,
+ struct regmap *regmap, void __iomem *base,
+ int channel, int channel1, int irq,
+ int bits)
+{
+ u32 rate, divided_rate = 0;
+ int best_divisor_idx = -1;
+ int i, err = -1;
+ u64 (*tc_sched_clock)(void);
+
+ tc.regmap = regmap;
+ tc.base = base;
+ tc.channels[0] = channel;
+ tc.channels[1] = channel1;
+ tc.irq = irq;
+ tc.bits = bits;
+
+ tc.clk[0] = tcb_clk_get(node, tc.channels[0]);
+ if (IS_ERR(tc.clk[0]))
+ return PTR_ERR(tc.clk[0]);
+ err = clk_prepare_enable(tc.clk[0]);
+ if (err) {
+ pr_debug("can't enable T0 clk\n");
+ goto err_clk;
+ }
+
+ /* How fast will we be counting? Pick something over 5 MHz. */
+ rate = (u32)clk_get_rate(tc.clk[0]);
+ for (i = 0; i < 5; i++) {
+ unsigned int divisor = atmel_tc_divisors[i];
+ unsigned int tmp;
+
+ if (!divisor)
+ continue;
+
+ tmp = rate / divisor;
+ pr_debug("TC: %u / %-3u [%d] --> %u\n", rate, divisor, i, tmp);
+ if (best_divisor_idx > 0) {
+ if (tmp < 5 * 1000 * 1000)
+ continue;
+ }
+ divided_rate = tmp;
+ best_divisor_idx = i;
+ }
+
+ if (tc.bits == 32) {
+ tc.clksrc.read = tc_get_cycles32;
+ tcb_setup_single_chan(&tc, best_divisor_idx);
+ tc_sched_clock = tc_sched_clock_read32;
+ snprintf(tc.name, sizeof(tc.name), "%s:%d",
+ kbasename(node->parent->full_name), tc.channels[0]);
+ } else {
+ tc.clk[1] = tcb_clk_get(node, tc.channels[1]);
+ if (IS_ERR(tc.clk[1]))
+ goto err_disable_t0;
+
+ err = clk_prepare_enable(tc.clk[1]);
+ if (err) {
+ pr_debug("can't enable T1 clk\n");
+ goto err_clk1;
+ }
+ tc.clksrc.read = tc_get_cycles,
+ tcb_setup_dual_chan(&tc, best_divisor_idx);
+ tc_sched_clock = tc_sched_clock_read;
+ snprintf(tc.name, sizeof(tc.name), "%s:%d,%d",
+ kbasename(node->parent->full_name), tc.channels[0],
+ tc.channels[1]);
+ }
+
+ pr_debug("%s at %d.%03d MHz\n", tc.name,
+ divided_rate / 1000000,
+ ((divided_rate + 500000) % 1000000) / 1000);
+
+ tc.clksrc.name = tc.name;
+ tc.clksrc.suspend = tc_clksrc_suspend;
+ tc.clksrc.resume = tc_clksrc_resume;
+
+ err = clocksource_register_hz(&tc.clksrc, divided_rate);
+ if (err)
+ goto err_disable_t1;
+
+ sched_clock_register(tc_sched_clock, 32, divided_rate);
+
+ tc.registered = true;
+
+ /* Set up and register clockevents */
+ tc.clkevt.name = tc.name;
+ tc.clkevt.cpumask = cpumask_of(0);
+ tc.clkevt.set_next_event = tcb_clkevt_next_event;
+ tc.clkevt.set_state_oneshot = tcb_clkevt_oneshot;
+ tc.clkevt.set_state_shutdown = tcb_clkevt_shutdown;
+ clockevents_config_and_register(&tc.clkevt, divided_rate, 1,
+ BIT(tc.bits) - 1);
+
+ return 0;
+
+err_disable_t1:
+ if (tc.bits == 16)
+ clk_disable_unprepare(tc.clk[1]);
+
+err_clk1:
+ if (tc.bits == 16)
+ clk_put(tc.clk[1]);
+
+err_disable_t0:
+ clk_disable_unprepare(tc.clk[0]);
+
+err_clk:
+ clk_put(tc.clk[0]);
+
+ pr_err("%s: unable to register clocksource/clockevent\n",
+ tc.clksrc.name);
+
+ return err;
+}
+
+static int __init tcb_clksrc_init(struct device_node *node)
+{
+ const struct of_device_id *match;
+ const struct atmel_tcb_info *tcb_info;
+ struct regmap *regmap;
+ void __iomem *tcb_base;
+ u32 channel;
+ int bits, irq, err, chan1 = -1;
+
+ if (tc.registered && tce.registered)
+ return -ENODEV;
+
+ /*
+ * The regmap has to be used to access registers that are shared
+ * between channels on the same TCB but we keep direct IO access for
+ * the counters to avoid the impact on performance
+ */
+ regmap = syscon_node_to_regmap(node->parent);
+ if (IS_ERR(regmap))
+ return PTR_ERR(regmap);
+
+ tcb_base = of_iomap(node->parent, 0);
+ if (!tcb_base) {
+ pr_err("%s +%d %s\n", __FILE__, __LINE__, __func__);
+ return -ENXIO;
+ }
+
+ match = of_match_node(atmel_tcb_dt_ids, node->parent);
+ tcb_info = match->data;
+ bits = tcb_info->bits;
+
+ err = of_property_read_u32_index(node, "reg", 0, &channel);
+ if (err)
+ return err;
+
+ irq = tcb_irq_get(node, channel);
+ if (irq < 0)
+ return irq;
+
+ if (tc.registered)
+ return tc_clkevt_register(node, regmap, tcb_base, channel, irq,
+ bits);
+
+ if (bits == 16) {
+ of_property_read_u32_index(node, "reg", 1, &chan1);
+ if (chan1 == -1) {
+ if (tce.registered) {
+ pr_err("%s: clocksource needs two channels\n",
+ node->parent->full_name);
+ return -EINVAL;
+ } else {
+ return tc_clkevt_register(node, regmap,
+ tcb_base, channel,
+ irq, bits);
+ }
+ }
+ }
+
+ return tcb_clksrc_register(node, regmap, tcb_base, channel, chan1, irq,
+ bits);
+}
+CLOCKSOURCE_OF_DECLARE(atmel_tcb_clksrc, "atmel,tcb-timer",
+ tcb_clksrc_init);
--
2.17.1
^ permalink raw reply related
* [PATCH v5 3/6] clocksource/drivers: atmel-pit: make option silent
From: Alexandre Belloni @ 2018-06-19 21:19 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180619211929.22908-1-alexandre.belloni@bootlin.com>
To conform with the other option, make the ATMEL_PIT option silent so it
can be selected from the platform
Tested-by: Alexander Dahl <ada@thorsis.com>
Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
---
drivers/clocksource/Kconfig | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
index 0b1b0de2abcc..334591ff608e 100644
--- a/drivers/clocksource/Kconfig
+++ b/drivers/clocksource/Kconfig
@@ -392,8 +392,11 @@ config ARMV7M_SYSTICK
This options enables support for the ARMv7M system timer unit
config ATMEL_PIT
+ bool "Microchip ARM Periodic Interval Timer (PIT)" if COMPILE_TEST
select TIMER_OF if OF
- def_bool SOC_AT91SAM9 || SOC_SAMA5
+ help
+ This enables build of clocksource and clockevent driver for
+ the integrated PIT in Microchip ARM SoCs.
config ATMEL_ST
bool "Atmel ST timer support" if COMPILE_TEST
--
2.17.1
^ permalink raw reply related
* [PATCH v5 4/6] ARM: at91: Implement clocksource selection
From: Alexandre Belloni @ 2018-06-19 21:19 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180619211929.22908-1-alexandre.belloni@bootlin.com>
Allow selecting and unselecting the PIT clocksource driver so it doesn't
have to be compile when unused.
Tested-by: Alexander Dahl <ada@thorsis.com>
Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
---
arch/arm/mach-at91/Kconfig | 25 +++++++++++++++++++++++++
1 file changed, 25 insertions(+)
diff --git a/arch/arm/mach-at91/Kconfig b/arch/arm/mach-at91/Kconfig
index 1254bf9d91b4..64f18cd220b9 100644
--- a/arch/arm/mach-at91/Kconfig
+++ b/arch/arm/mach-at91/Kconfig
@@ -106,6 +106,31 @@ config SOC_AT91SAM9
AT91SAM9X35
AT91SAM9XE
+comment "Clocksource driver selection"
+
+config ATMEL_CLOCKSOURCE_PIT
+ bool "Periodic Interval Timer (PIT) support"
+ depends on SOC_AT91SAM9 || SOC_SAMA5
+ default SOC_AT91SAM9 || SOC_SAMA5
+ select ATMEL_PIT
+ help
+ Select this to get a clocksource based on the Atmel Periodic Interval
+ Timer. It has a relatively low resolution and the TC Block clocksource
+ should be preferred.
+
+config ATMEL_CLOCKSOURCE_TCB
+ bool "Timer Counter Blocks (TCB) support"
+ depends on SOC_AT91RM9200 || SOC_AT91SAM9 || SOC_SAMA5 || COMPILE_TEST
+ default SOC_AT91RM9200 || SOC_AT91SAM9 || SOC_SAMA5
+ depends on !ATMEL_TCLIB
+ select ATMEL_ARM_TCB_CLKSRC
+ help
+ Select this to get a high precision clocksource based on a
+ TC block with a 5+ MHz base clock rate.
+ On platforms with 16-bit counters, two timer channels are combined
+ to make a single 32-bit timer.
+ It can also be used as a clock event device supporting oneshot mode.
+
config HAVE_AT91_UTMI
bool
--
2.17.1
^ permalink raw reply related
* [PATCH v5 5/6] ARM: configs: at91: use new TCB timer driver
From: Alexandre Belloni @ 2018-06-19 21:19 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180619211929.22908-1-alexandre.belloni@bootlin.com>
Unselecting ATMEL_TCLIB switches the TCB timer driver from tcb_clksrc to
timer-atmel-tcb.
Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
---
arch/arm/configs/at91_dt_defconfig | 1 -
arch/arm/configs/sama5_defconfig | 1 -
2 files changed, 2 deletions(-)
diff --git a/arch/arm/configs/at91_dt_defconfig b/arch/arm/configs/at91_dt_defconfig
index e4b1be66b3f5..09f262e59fef 100644
--- a/arch/arm/configs/at91_dt_defconfig
+++ b/arch/arm/configs/at91_dt_defconfig
@@ -64,7 +64,6 @@ CONFIG_BLK_DEV_LOOP=y
CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_RAM_COUNT=4
CONFIG_BLK_DEV_RAM_SIZE=8192
-CONFIG_ATMEL_TCLIB=y
CONFIG_ATMEL_SSC=y
CONFIG_SCSI=y
CONFIG_BLK_DEV_SD=y
diff --git a/arch/arm/configs/sama5_defconfig b/arch/arm/configs/sama5_defconfig
index 2080025556b5..f2bbc6339ca6 100644
--- a/arch/arm/configs/sama5_defconfig
+++ b/arch/arm/configs/sama5_defconfig
@@ -75,7 +75,6 @@ CONFIG_BLK_DEV_LOOP=y
CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_RAM_COUNT=4
CONFIG_BLK_DEV_RAM_SIZE=8192
-CONFIG_ATMEL_TCLIB=y
CONFIG_ATMEL_SSC=y
CONFIG_EEPROM_AT24=y
CONFIG_SCSI=y
--
2.17.1
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox