* Re: [PATCH v4 00/14] Add kdbus implementation
From: Andy Lutomirski @ 2015-03-31 13:58 UTC (permalink / raw)
To: David Herrmann
Cc: Greg Kroah-Hartman, Arnd Bergmann, Eric W. Biederman,
One Thousand Gnomes, Tom Gundersen, Jiri Kosina, Linux API,
linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org, Daniel Mack,
Djalal Harouni
In-Reply-To: <CANq1E4TTt3qanQse30KOZsuo2tfNoj7YSueh3AZ7bY1nQQeZNA-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
On Mon, Mar 30, 2015 at 9:56 AM, David Herrmann <dh.herrmann-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:
> Hi
>
> On Wed, Mar 25, 2015 at 7:12 PM, Andy Lutomirski <luto-kltTT9wpgjJwATOyAt5JVQ@public.gmane.org> wrote:
>> On Wed, Mar 25, 2015 at 10:29 AM, David Herrmann <dh.herrmann-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:
> [...]
>>>> I could be wrong about the lack of use cases. If so, please enlighten me.
>>>
>>> We have several dbus APIs that allow clients to register as a special
>>> handler/controller/etc. (eg., see systemd-logind TakeControl()). The
>>> API provider checks the privileges of a client on registration and
>>> then just tracks the client ID. This way, the client can be privileged
>>> when asking for special access, then drop privileges and still use the
>>> interface. You cannot re-connect in between, as the API provider
>>> tracks your bus ID. Without message-metadata, all your (other) calls
>>> on this bus would always be treated as privileged. We *really* want to
>>> avoid this.
>>
>> Connect twice?
>
> The remote peer might cache your connection ID to track you. You have
> to use the same connection to talk to that peer, in this given
> scenario. That's how D-Bus1 is used today, and we have to follow the
> semantics.
That's yet another reason that you really ought to disconnect and
reconnect after a privilege change -- the remote peer might remember
you.
The "might" will be a big problem. Users of kdbus can't rely on any
particular concept of privilege because you have too many of them.
>
>> You *already* have to reconnect or connect twice because you have
>> per-connection metadata. That's part of my problem with this scheme
>> -- you support *both styles*, which seems like it'll give you most of
>> the downsides of both without the upsides.
>
> Not necessarily. Connection metadata describes the state at the time
> you connected to the bus. If someone ask for this information, they
> will get exactly that. In this model, you cannot drop privileges, if
> you need to be privileged during setup.
> If someone asks for per-message metadata, they better ought not ask
> for per-connection creds. It's not the information they're looking
> for, so it will not match the data that at the time the message was
> sent.
>
> There is no immediate need to make both match. For security decisions,
> we mandate per-message creds. Per-connection creds are for
> backwards-compatibility to dbus1 and for passive introspection of bus
> connections.
Backwards compatibility doesn't magically exempt security
considerations. If new code is insecure when talking to a legacy
service, it's still insecure.
[...]
>> Again, you seem to be arguing that per-connection metadata is bad, but
>> you still have an implementation of per-connection metadata, so you
>> still have all these problems.
>
> I don't see why we get the problems of per-connection metadata. Just
> because you _can_ use it, doesn't mean you should use it for all
> imaginable use-cases. The same goes for reading information from
> /proc. There are valid use-cases to do so, but also a lot of cases
> where it will not provide the information you want.
>
Then you'll need to document really carefully which metadata is used
for which service. This actually seems impossible to do, since some
services will exist in legacy and kdbus forms.
>> I'm actually okay with per-message metadata in principle, but I'd like
>> to see evidence (with numbers, please) that a send+recv of per-message
>> metadata is *not* significantly slower than a recv of already-captured
>> per-connection metadata. If this is in fact the case, then maybe you
>> should trash per-connection metadata instead and the legacy
>> compatibility code can figure out a way to deal with it. IMO that
>> would be a pretty nice outcome, since you would never have to worry
>> whether your connection to the bus is inadvertantly privileged.
>
> Per-message metadata makes SEND about 25% slower, if you transmit the
> full set of all possible information. Just 3% if you only use
> PIDs+UIDs. The expensive metadata is cgroup-path and exe-path.
> If a service needs that information, however, and if that information
> is not guaranteed to be up-to-date, the service _will_ go and look it
> up in /proc or somewhere else, which is certainly a whole lot more
> expensive than the code in kdbus.
Can you give actual numbers, in ns or cycles, of how much overhead
metadata adds?
>
> In general, there seems to be a number of misconception in this thread
> about what kdbus is supposed to be. We're not inventing something new
> here with a clean slate, but we're moving parts of an existing
> implementation that has tons of users into the kernel, in order to fix
> issues that cannot be fixed otherwise in userspace (most notably, the
> race gaps that exist when retrieving per-message metadata). Therefore,
> we have to keep existing semantics stable, otherwise the exercise is
> somewhat pointless.
IOW you're taking something that you dislike aspects of and shoving
most of it in the kernel. That guarantees us an API in the kernel
that even the creators don't really like. This is, IMO, very
unfortunate.
Have you considered porting the kdbus per-message metadata mechanism to UDS?
--Andy
^ permalink raw reply
* Re: [PATCH v2 3/7] Introduce a new clone4 syscall with more flag bits and extensible arguments
From: David Drysdale @ 2015-03-31 14:41 UTC (permalink / raw)
To: Josh Triplett
Cc: Al Viro, Andrew Morton, Andy Lutomirski, Ingo Molnar, Kees Cook,
Oleg Nesterov, Paul E. McKenney, H. Peter Anvin, Rik van Riel,
Thomas Gleixner, Michael Kerrisk, Thiago Macieira,
linux-kernel@vger.kernel.org, Linux API, Linux FS Devel, X86 ML
In-Reply-To: <20150323150500.GB31561@cloud>
On Mon, Mar 23, 2015 at 3:05 PM, <josh@joshtriplett.org> wrote:
> On Mon, Mar 23, 2015 at 02:11:45PM +0000, David Drysdale wrote:
>> On Sun, Mar 15, 2015 at 7:59 AM, Josh Triplett <josh@joshtriplett.org> wrote:
>> > diff --git a/arch/x86/ia32/ia32entry.S b/arch/x86/ia32/ia32entry.S
>> > index 0286735..ba28306 100644
>> > --- a/arch/x86/ia32/ia32entry.S
>> > +++ b/arch/x86/ia32/ia32entry.S
>> > @@ -483,6 +483,7 @@ GLOBAL(\label)
>> > PTREGSCALL stub32_execveat, compat_sys_execveat
>> > PTREGSCALL stub32_fork, sys_fork
>> > PTREGSCALL stub32_vfork, sys_vfork
>> > + PTREGSCALL stub32_clone4, compat_sys_clone4
>> >
>> > ALIGN
>> > GLOBAL(stub32_clone)
>> > diff --git a/arch/x86/kernel/entry_64.S b/arch/x86/kernel/entry_64.S
>> > index 1d74d16..ead143f 100644
>> > --- a/arch/x86/kernel/entry_64.S
>> > +++ b/arch/x86/kernel/entry_64.S
>> > @@ -520,6 +520,7 @@ END(\label)
>> > FORK_LIKE clone
>> > FORK_LIKE fork
>> > FORK_LIKE vfork
>> > + FORK_LIKE clone4
>> > FIXED_FRAME stub_iopl, sys_iopl
>> >
>> > ENTRY(stub_execve)
>> > diff --git a/arch/x86/syscalls/syscall_32.tbl b/arch/x86/syscalls/syscall_32.tbl
>> > index b3560ec..56fcc90 100644
>> > --- a/arch/x86/syscalls/syscall_32.tbl
>> > +++ b/arch/x86/syscalls/syscall_32.tbl
>> > @@ -365,3 +365,4 @@
>> > 356 i386 memfd_create sys_memfd_create
>> > 357 i386 bpf sys_bpf
>> > 358 i386 execveat sys_execveat stub32_execveat
>> > +359 i386 clone4 sys_clone4 stub32_clone4
>> > diff --git a/arch/x86/syscalls/syscall_64.tbl b/arch/x86/syscalls/syscall_64.tbl
>> > index 8d656fb..af15b0f 100644
>> > --- a/arch/x86/syscalls/syscall_64.tbl
>> > +++ b/arch/x86/syscalls/syscall_64.tbl
>> > @@ -329,6 +329,7 @@
>> > 320 common kexec_file_load sys_kexec_file_load
>> > 321 common bpf sys_bpf
>> > 322 64 execveat stub_execveat
>> > +323 64 clone4 stub_clone4
>> >
>> > #
>> > # x32-specific system call numbers start at 512 to avoid cache impact
>> > @@ -368,3 +369,4 @@
>> > 543 x32 io_setup compat_sys_io_setup
>> > 544 x32 io_submit compat_sys_io_submit
>> > 545 x32 execveat stub_x32_execveat
>> > +546 x32 clone4 stub32_clone4
>>
>> Doesn't this need an x32 specific wrapper (to ensure the full
>> set of registers are saved)?
>
> I'm not an x32 expert; I don't know how x32 interacts with pt_regs and
> compat syscalls. Could an x32 expert weigh in, please?
>
> - Josh Triplett
(In the absence of an x32 expert chiming in...)
As I understand it:
- stub32_clone4 expects 32-bit calling conventions and calls compat_sys_clone4
- stub_clone4 expects 64-bit calling conventions and calls sys_clone4
- stub_x32_clone4 would expect 64-bit calling conventions but call
compat_sys_clone4.
Also, I have a suspicion that different field types in the [compat_]clone4_args
structure may cause problems -- I *think* its (final) layout will be 4+4+4+4+4+4
on 32-bit, 8+8+8+8+8+4 on 64-bit, but 4+4+8+8+4+4 on x32.
Have you tried running a test with a userspace program compiled with -mx32?
^ permalink raw reply
* Re: Revised futex(2) man page for review
From: Davidlohr Bueso @ 2015-03-31 14:45 UTC (permalink / raw)
To: Peter Zijlstra
Cc: Michael Kerrisk (man-pages), Thomas Gleixner, Darren Hart,
Carlos O'Donell, Ingo Molnar, Jakub Jelinek,
linux-man-u79uwXL29TY76Z2rM5mHXA@public.gmane.org, lkml,
Arnd Bergmann, Steven Rostedt, Linux API, Torvald Riegel,
Roland McGrath, Darren Hart, Anton Blanchard, Eric Dumazet,
bill o gallmeister, Jan Kiszka, Daniel Wagner, Rich Felker,
Andy Lutomirski, bert hubert, Rusty Russell
In-Reply-To: <20150328114725.GJ27490-IIpfhp3q70z/8w/KjCw3T+5/BudmfyzbbVWyRVo5IupeoWH0uzbU5w@public.gmane.org>
On Sat, 2015-03-28 at 12:47 +0100, Peter Zijlstra wrote:
> The condition is represented by the futex word, which is an address in
> memory supplied to the futex() system call, and the value at this mem‐
> ory location. (While the virtual addresses for the same memory in sep‐
> arate processes may not be equal, the kernel maps them internally so
> that the same memory mapped in different locations will correspond for
> futex() calls.)
>
> When executing a futex operation that requests to block a thread, the
> kernel will only block if the futex word has the value that the calling
Given the use of "word", you should probably state right away that
futexes are only 32bit.
Thanks,
Davidlohr
^ permalink raw reply
* [PATCH v2 01/10] KVM: add commentary for kvm_debug_exit_arch struct
From: Alex Bennée @ 2015-03-31 15:07 UTC (permalink / raw)
To: kvm, linux-arm-kernel, kvmarm, christoffer.dall, marc.zyngier,
peter.maydell, agraf, drjones, pbonzini, zhichao.huang
Cc: Gleb Natapov, jan.kiszka, open list, open list:ABI/API, dahi,
r65777, bp
In-Reply-To: <1427814488-28467-1-git-send-email-alex.bennee@linaro.org>
Bring into line with the commentary for the other structures and their
KVM_EXIT_* cases.
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
---
v2
- add comments for other exit types
diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h
index 8055706..5eedf84 100644
--- a/include/uapi/linux/kvm.h
+++ b/include/uapi/linux/kvm.h
@@ -226,6 +226,7 @@ struct kvm_run {
__u32 count;
__u64 data_offset; /* relative to kvm_run start */
} io;
+ /* KVM_EXIT_DEBUG */
struct {
struct kvm_debug_exit_arch arch;
} debug;
@@ -274,6 +275,7 @@ struct kvm_run {
__u32 data;
__u8 is_write;
} dcr;
+ /* KVM_EXIT_INTERNAL_ERROR */
struct {
__u32 suberror;
/* Available with KVM_CAP_INTERNAL_ERROR_DATA: */
@@ -284,6 +286,7 @@ struct kvm_run {
struct {
__u64 gprs[32];
} osi;
+ /* KVM_EXIT_PAPR_HCALL */
struct {
__u64 nr;
__u64 ret;
--
2.3.4
_______________________________________________
kvmarm mailing list
kvmarm@lists.cs.columbia.edu
https://lists.cs.columbia.edu/mailman/listinfo/kvmarm
^ permalink raw reply related
* [PATCH v2 02/10] KVM: define common __KVM_GUESTDBG_USE_SW/HW_BP values
From: Alex Bennée @ 2015-03-31 15:08 UTC (permalink / raw)
To: kvm, linux-arm-kernel, kvmarm, christoffer.dall, marc.zyngier,
peter.maydell, agraf, drjones, pbonzini, zhichao.huang
Cc: maintainer:X86 ARCHITECTURE..., Benjamin Herrenschmidt,
Alexey Kardashevskiy, Nadav Amit, Gleb Natapov, jan.kiszka,
H. Peter Anvin, open list:LINUX FOR POWERPC..., open list:ABI/API,
open list, dahi, Ingo Molnar, Paul Mackerras, Michael Ellerman,
r65777, Thomas Gleixner, bp
In-Reply-To: <1427814488-28467-1-git-send-email-alex.bennee@linaro.org>
Currently x86, powerpc and soon arm64 use the same two architecture
specific bits for guest debug support for software and hardware
breakpoints. This makes the shared values explicit while leaving the
gate open for another architecture to use some other value if they
really really want to.
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
diff --git a/arch/powerpc/include/uapi/asm/kvm.h b/arch/powerpc/include/uapi/asm/kvm.h
index ab4d473..1731569 100644
--- a/arch/powerpc/include/uapi/asm/kvm.h
+++ b/arch/powerpc/include/uapi/asm/kvm.h
@@ -310,8 +310,8 @@ struct kvm_guest_debug_arch {
* and upper 16 bits are architecture specific. Architecture specific defines
* that ioctl is for setting hardware breakpoint or software breakpoint.
*/
-#define KVM_GUESTDBG_USE_SW_BP 0x00010000
-#define KVM_GUESTDBG_USE_HW_BP 0x00020000
+#define KVM_GUESTDBG_USE_SW_BP __KVM_GUESTDBG_USE_SW_BP
+#define KVM_GUESTDBG_USE_HW_BP __KVM_GUESTDBG_USE_HW_BP
/* definition of registers in kvm_run */
struct kvm_sync_regs {
diff --git a/arch/x86/include/uapi/asm/kvm.h b/arch/x86/include/uapi/asm/kvm.h
index d7dcef5..1438202 100644
--- a/arch/x86/include/uapi/asm/kvm.h
+++ b/arch/x86/include/uapi/asm/kvm.h
@@ -250,8 +250,8 @@ struct kvm_debug_exit_arch {
__u64 dr7;
};
-#define KVM_GUESTDBG_USE_SW_BP 0x00010000
-#define KVM_GUESTDBG_USE_HW_BP 0x00020000
+#define KVM_GUESTDBG_USE_SW_BP __KVM_GUESTDBG_USE_SW_BP
+#define KVM_GUESTDBG_USE_HW_BP __KVM_GUESTDBG_USE_HW_BP
#define KVM_GUESTDBG_INJECT_DB 0x00040000
#define KVM_GUESTDBG_INJECT_BP 0x00080000
diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h
index 5eedf84..ce2db14 100644
--- a/include/uapi/linux/kvm.h
+++ b/include/uapi/linux/kvm.h
@@ -525,8 +525,16 @@ struct kvm_s390_irq {
/* for KVM_SET_GUEST_DEBUG */
-#define KVM_GUESTDBG_ENABLE 0x00000001
-#define KVM_GUESTDBG_SINGLESTEP 0x00000002
+#define KVM_GUESTDBG_ENABLE (1 << 0)
+#define KVM_GUESTDBG_SINGLESTEP (1 << 1)
+
+/*
+ * Architecture specific stuff uses the top 16 bits of the field,
+ * however there is some shared commonality for the common cases
+ */
+#define __KVM_GUESTDBG_USE_SW_BP (1 << 16)
+#define __KVM_GUESTDBG_USE_HW_BP (1 << 17)
+
struct kvm_guest_debug {
__u32 control;
--
2.3.4
_______________________________________________
kvmarm mailing list
kvmarm@lists.cs.columbia.edu
https://lists.cs.columbia.edu/mailman/listinfo/kvmarm
^ permalink raw reply related
* [PATCH v2 08/10] KVM: arm64: guest debug, HW assisted debug support
From: Alex Bennée @ 2015-03-31 15:08 UTC (permalink / raw)
To: kvm, linux-arm-kernel, kvmarm, christoffer.dall, marc.zyngier,
peter.maydell, agraf, drjones, pbonzini, zhichao.huang
Cc: Lorenzo Pieralisi, Russell King, Jonathan Corbet, Gleb Natapov,
jan.kiszka, AKASHI Takahiro, open list:DOCUMENTATION, Will Deacon,
open list, open list:ABI/API, dahi, Catalin Marinas, r65777, bp
In-Reply-To: <1427814488-28467-1-git-send-email-alex.bennee@linaro.org>
This adds support for userspace to control the HW debug registers for
guest debug. We'll only copy the $ARCH defined number across as that is
all that hyp.S will use anyway. I've moved some helper functions into
the hw_breakpoint.h header for re-use.
As with single step we need to tweak the guest registers to enable the
exceptions so we need to save and restore those bits.
Two new capabilities have been added to the KVM_EXTENSION ioctl to allow
userspace to query the number of hardware break and watch points
available on the host hardware.
As QEMU tests for watchpoints based on the address and not the PC we
also need to export the value of far_el2 to userspace.
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
---
v2
- switched to C setup
- replace host debug registers directly into context
- minor tweak to api docs
- setup right register for debug
- add FAR_EL2 to debug exit structure
- add support fro trapping debug register access
diff --git a/Documentation/virtual/kvm/api.txt b/Documentation/virtual/kvm/api.txt
index 17d4f9c..ac34093 100644
--- a/Documentation/virtual/kvm/api.txt
+++ b/Documentation/virtual/kvm/api.txt
@@ -2627,7 +2627,7 @@ The top 16 bits of the control field are architecture specific control
flags which can include the following:
- KVM_GUESTDBG_USE_SW_BP: using software breakpoints [x86, arm64]
- - KVM_GUESTDBG_USE_HW_BP: using hardware breakpoints [x86, s390]
+ - KVM_GUESTDBG_USE_HW_BP: using hardware breakpoints [x86, s390, arm64]
- KVM_GUESTDBG_INJECT_DB: inject DB type exception [x86]
- KVM_GUESTDBG_INJECT_BP: inject BP type exception [x86]
- KVM_GUESTDBG_EXIT_PENDING: trigger an immediate guest exit [s390]
@@ -2642,6 +2642,10 @@ updated to the correct (supplied) values.
The second part of the structure is architecture specific and
typically contains a set of debug registers.
+For arm64 the number of debug registers is implementation defined and
+can be determined by querying the KVM_CAP_GUEST_DEBUG_HW_BPS and
+KVM_CAP_GUEST_DEBUG_HW_WPS capabilities.
+
When debug events exit the main run loop with the reason
KVM_EXIT_DEBUG with the kvm_debug_exit_arch part of the kvm_run
structure containing architecture specific debug information.
diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c
index c1ed8cb..a286026 100644
--- a/arch/arm/kvm/arm.c
+++ b/arch/arm/kvm/arm.c
@@ -306,6 +306,7 @@ void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu)
#define KVM_GUESTDBG_VALID (KVM_GUESTDBG_ENABLE | \
KVM_GUESTDBG_USE_SW_BP | \
+ KVM_GUESTDBG_USE_HW_BP | \
KVM_GUESTDBG_SINGLESTEP)
/**
@@ -328,6 +329,26 @@ int kvm_arch_vcpu_ioctl_set_guest_debug(struct kvm_vcpu *vcpu,
return -EINVAL;
vcpu->guest_debug = dbg->control;
+
+ /* Hardware assisted Break and Watch points */
+ if (vcpu->guest_debug & KVM_GUESTDBG_USE_HW_BP) {
+ int nb = get_num_brps();
+ int nw = get_num_wrps();
+
+ /* Copy across up to IMPDEF debug registers to our
+ * shadow copy in the vcpu structure. The debug code
+ * will then set them up before we re-enter the guest.
+ */
+ memcpy(vcpu->arch.guest_debug_regs.dbg_bcr,
+ dbg->arch.dbg_bcr, sizeof(__u64)*nb);
+ memcpy(vcpu->arch.guest_debug_regs.dbg_bvr,
+ dbg->arch.dbg_bvr, sizeof(__u64)*nb);
+ memcpy(vcpu->arch.guest_debug_regs.dbg_wcr,
+ dbg->arch.dbg_wcr, sizeof(__u64)*nw);
+ memcpy(vcpu->arch.guest_debug_regs.dbg_wvr,
+ dbg->arch.dbg_wvr, sizeof(__u64)*nw);
+ }
+
} else {
/* If not enabled clear all flags */
vcpu->guest_debug = 0;
diff --git a/arch/arm64/include/asm/hw_breakpoint.h b/arch/arm64/include/asm/hw_breakpoint.h
index 52b484b..c450552 100644
--- a/arch/arm64/include/asm/hw_breakpoint.h
+++ b/arch/arm64/include/asm/hw_breakpoint.h
@@ -130,6 +130,18 @@ static inline void ptrace_hw_copy_thread(struct task_struct *task)
}
#endif
+/* Determine number of BRP registers available. */
+static inline int get_num_brps(void)
+{
+ return ((read_cpuid(ID_AA64DFR0_EL1) >> 12) & 0xf) + 1;
+}
+
+/* Determine number of WRP registers available. */
+static inline int get_num_wrps(void)
+{
+ return ((read_cpuid(ID_AA64DFR0_EL1) >> 20) & 0xf) + 1;
+}
+
extern struct pmu perf_ops_bp;
#endif /* __KERNEL__ */
diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index 6a33647..2c359c9 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -106,8 +106,9 @@ struct kvm_vcpu_arch {
/* Exception Information */
struct kvm_vcpu_fault_info fault;
- /* Debug state */
+ /* Guest debug state */
u64 debug_flags;
+ struct kvm_guest_debug_arch guest_debug_regs;
/* Pointer to host CPU context */
kvm_cpu_context_t *host_cpu_context;
@@ -126,6 +127,7 @@ struct kvm_vcpu_arch {
u32 pstate_ss_bit;
u32 mdscr_el1_bits;
+ struct kvm_guest_debug_arch debug_regs;
} debug_saved_regs;
/* Don't run the guest */
diff --git a/arch/arm64/include/uapi/asm/kvm.h b/arch/arm64/include/uapi/asm/kvm.h
index 6ee70a0..73f21e4 100644
--- a/arch/arm64/include/uapi/asm/kvm.h
+++ b/arch/arm64/include/uapi/asm/kvm.h
@@ -118,6 +118,7 @@ struct kvm_guest_debug_arch {
struct kvm_debug_exit_arch {
__u64 pc;
__u32 hsr;
+ __u64 far; /* used for watchpoints */
};
struct kvm_sync_regs {
diff --git a/arch/arm64/kernel/hw_breakpoint.c b/arch/arm64/kernel/hw_breakpoint.c
index 98bbe06..923be44 100644
--- a/arch/arm64/kernel/hw_breakpoint.c
+++ b/arch/arm64/kernel/hw_breakpoint.c
@@ -49,18 +49,6 @@ static DEFINE_PER_CPU(int, stepping_kernel_bp);
static int core_num_brps;
static int core_num_wrps;
-/* Determine number of BRP registers available. */
-static int get_num_brps(void)
-{
- return ((read_cpuid(ID_AA64DFR0_EL1) >> 12) & 0xf) + 1;
-}
-
-/* Determine number of WRP registers available. */
-static int get_num_wrps(void)
-{
- return ((read_cpuid(ID_AA64DFR0_EL1) >> 20) & 0xf) + 1;
-}
-
int hw_breakpoint_slots(int type)
{
/*
diff --git a/arch/arm64/kvm/debug.c b/arch/arm64/kvm/debug.c
index b32362c..3b368f3 100644
--- a/arch/arm64/kvm/debug.c
+++ b/arch/arm64/kvm/debug.c
@@ -50,14 +50,19 @@
void kvm_arch_setup_debug(struct kvm_vcpu *vcpu)
{
+ bool trap_debug = false;
+
vcpu->arch.mdcr_el2 |= (MDCR_EL2_TPM | MDCR_EL2_TPMCR);
vcpu->arch.mdcr_el2 |= (MDCR_EL2_TDRA | MDCR_EL2_TDOSA);
- /* Trap debug register access? */
+ trace_kvm_arch_setup_debug_reg32("MDCR_EL2", vcpu->arch.mdcr_el2);
+
+ /*
+ * If we are not treating debug registers are dirty we need
+ * to trap if the guest starts accessing them.
+ */
if (!vcpu->arch.debug_flags & KVM_ARM64_DEBUG_DIRTY)
- vcpu->arch.mdcr_el2 |= MDCR_EL2_TDA;
- else
- vcpu->arch.mdcr_el2 &= ~MDCR_EL2_TDA;
+ trap_debug = true;
/* Is Guest debugging in effect? */
if (vcpu->guest_debug) {
@@ -84,10 +89,69 @@ void kvm_arch_setup_debug(struct kvm_vcpu *vcpu)
vcpu_sys_reg(vcpu, MDSCR_EL1) &= ~DBG_MDSCR_SS;
}
+ /*
+ * HW Break/Watch points
+ */
+ if (vcpu->guest_debug & KVM_GUESTDBG_USE_HW_BP) {
+ int nb = get_num_brps();
+ int nw = get_num_wrps();
+ struct kvm_guest_debug_arch *saved, *host;
+
+ vcpu_sys_reg(vcpu, MDSCR_EL1) |=
+ (DBG_MDSCR_KDE|DBG_MDSCR_MDE);
+
+ /*
+ * First we need to make a copy of the guest
+ * debug registers before we wipe them out
+ * with the ones we want to use.
+ */
+ saved = &vcpu_debug_saved_reg(vcpu, debug_regs);
+ host = &vcpu->arch.guest_debug_regs;
+
+ /* Save guest values */
+ memcpy(&saved->dbg_bcr,
+ &vcpu_sys_reg(vcpu, DBGBCR0_EL1),
+ sizeof(__u64)*nb);
+ memcpy(&saved->dbg_bvr,
+ &vcpu_sys_reg(vcpu, DBGBVR0_EL1),
+ sizeof(__u64)*nb);
+ memcpy(&saved->dbg_wcr,
+ &vcpu_sys_reg(vcpu, DBGWCR0_EL1),
+ sizeof(__u64)*nw);
+ memcpy(&saved->dbg_wvr,
+ &vcpu_sys_reg(vcpu, DBGWVR0_EL1),
+ sizeof(__u64)*nw);
+
+ /* Copy in host values */
+ memcpy(&vcpu_sys_reg(vcpu, DBGBCR0_EL1),
+ &host->dbg_bcr,
+ sizeof(__u64)*nb);
+ memcpy(&vcpu_sys_reg(vcpu, DBGBVR0_EL1),
+ &host->dbg_bvr,
+ sizeof(__u64)*nb);
+ memcpy(&vcpu_sys_reg(vcpu, DBGWCR0_EL1),
+ &host->dbg_wcr,
+ sizeof(__u64)*nw);
+ memcpy(&vcpu_sys_reg(vcpu, DBGWVR0_EL1),
+ &host->dbg_wvr,
+ sizeof(__u64)*nw);
+
+ /* Make sure hyp.S copies them in/out */
+ vcpu->arch.debug_flags |= KVM_ARM64_DEBUG_DIRTY;
+ /* Also track guest changes */
+ trap_debug = true;
+ }
+
} else {
/* Debug operations can go straight to the guest */
vcpu->arch.mdcr_el2 &= ~MDCR_EL2_TDE;
}
+
+ /* Trap debug register access? */
+ if (trap_debug)
+ vcpu->arch.mdcr_el2 |= MDCR_EL2_TDA;
+ else
+ vcpu->arch.mdcr_el2 &= ~MDCR_EL2_TDA;
}
void kvm_arch_clear_debug(struct kvm_vcpu *vcpu)
@@ -100,5 +164,31 @@ void kvm_arch_clear_debug(struct kvm_vcpu *vcpu)
vcpu_sys_reg(vcpu, MDSCR_EL1) &= ~MDSCR_EL1_DEBUG_BITS;
vcpu_sys_reg(vcpu, MDSCR_EL1) |=
vcpu_debug_saved_reg(vcpu, mdscr_el1_bits);
+
+ /*
+ * If we were using HW debug we need to restore the
+ * values the guest had set them up with
+ */
+ if (vcpu->guest_debug & KVM_GUESTDBG_USE_HW_BP) {
+ struct kvm_guest_debug_arch *regs;
+ int nb = get_num_brps();
+ int nw = get_num_wrps();
+
+ regs = &vcpu_debug_saved_reg(vcpu, debug_regs);
+
+ /* Restore the saved debug register values */
+ memcpy(&vcpu_sys_reg(vcpu, DBGBCR0_EL1),
+ ®s->dbg_bcr,
+ sizeof(__u64)*nb);
+ memcpy(&vcpu_sys_reg(vcpu, DBGBVR0_EL1),
+ ®s->dbg_bvr,
+ sizeof(__u64)*nb);
+ memcpy(&vcpu_sys_reg(vcpu, DBGWCR0_EL1),
+ ®s->dbg_wcr,
+ sizeof(__u64)*nw);
+ memcpy(&vcpu_sys_reg(vcpu, DBGWVR0_EL1),
+ ®s->dbg_wvr,
+ sizeof(__u64)*nw);
+ }
}
}
diff --git a/arch/arm64/kvm/handle_exit.c b/arch/arm64/kvm/handle_exit.c
index 16accae..460a1aa 100644
--- a/arch/arm64/kvm/handle_exit.c
+++ b/arch/arm64/kvm/handle_exit.c
@@ -101,7 +101,11 @@ static int kvm_handle_guest_debug(struct kvm_vcpu *vcpu, struct kvm_run *run)
run->debug.arch.hsr = hsr;
switch (hsr >> ESR_ELx_EC_SHIFT) {
+ case ESR_ELx_EC_WATCHPT_LOW:
+ run->debug.arch.far = vcpu->arch.fault.far_el2;
+ /* fall through */
case ESR_ELx_EC_SOFTSTP_LOW:
+ case ESR_ELx_EC_BREAKPT_LOW:
case ESR_ELx_EC_BKPT32:
case ESR_ELx_EC_BRK64:
run->debug.arch.pc = *vcpu_pc(vcpu);
@@ -129,6 +133,8 @@ static exit_handle_fn arm_exit_handlers[] = {
[ESR_ELx_EC_IABT_LOW] = kvm_handle_guest_abort,
[ESR_ELx_EC_DABT_LOW] = kvm_handle_guest_abort,
[ESR_ELx_EC_SOFTSTP_LOW]= kvm_handle_guest_debug,
+ [ESR_ELx_EC_WATCHPT_LOW]= kvm_handle_guest_debug,
+ [ESR_ELx_EC_BREAKPT_LOW]= kvm_handle_guest_debug,
[ESR_ELx_EC_BKPT32] = kvm_handle_guest_debug,
[ESR_ELx_EC_BRK64] = kvm_handle_guest_debug,
};
diff --git a/arch/arm64/kvm/reset.c b/arch/arm64/kvm/reset.c
index 0b43265..c2732c7 100644
--- a/arch/arm64/kvm/reset.c
+++ b/arch/arm64/kvm/reset.c
@@ -64,6 +64,12 @@ int kvm_arch_dev_ioctl_check_extension(long ext)
case KVM_CAP_ARM_EL1_32BIT:
r = cpu_has_32bit_el1();
break;
+ case KVM_CAP_GUEST_DEBUG_HW_BPS:
+ r = get_num_brps();
+ break;
+ case KVM_CAP_GUEST_DEBUG_HW_WPS:
+ r = get_num_wrps();
+ break;
default:
r = 0;
}
diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
index c370b40..be9b188 100644
--- a/arch/arm64/kvm/sys_regs.c
+++ b/arch/arm64/kvm/sys_regs.c
@@ -196,16 +196,49 @@ static bool trap_dbgauthstatus_el1(struct kvm_vcpu *vcpu,
* - If the dirty bit is set, save guest registers, restore host
* registers and clear the dirty bit. This ensure that the host can
* now use the debug registers.
+ *
+ * We also use this mechanism to set-up the debug registers for guest
+ * debugging. If this is the case we want to ensure the guest sees
+ * the right versions of the registers - even if they are not going to
+ * be effective while guest debug is using HW debug.
+ *
*/
+
static bool trap_debug_regs(struct kvm_vcpu *vcpu,
const struct sys_reg_params *p,
const struct sys_reg_desc *r)
{
- if (p->is_write) {
- vcpu_sys_reg(vcpu, r->reg) = *vcpu_reg(vcpu, p->Rt);
- vcpu->arch.debug_flags |= KVM_ARM64_DEBUG_DIRTY;
+ if (vcpu->guest_debug & KVM_GUESTDBG_USE_HW_BP) {
+ struct kvm_guest_debug_arch *saved;
+ __u64 *val;
+
+ saved = &vcpu_debug_saved_reg(vcpu, debug_regs);
+
+ if (r->reg >= DBGBCR0_EL1 && r->reg <= DBGBCR15_EL1)
+ val = &saved->dbg_bcr[r->reg - DBGBCR0_EL1];
+ else if (r->reg >= DBGBVR0_EL1 && r->reg <= DBGBVR15_EL1)
+ val = &saved->dbg_bvr[r->reg - DBGBVR0_EL1];
+ else if (r->reg >= DBGWCR0_EL1 && r->reg <= DBGWCR15_EL1)
+ val = &saved->dbg_wcr[r->reg - DBGWCR0_EL1];
+ else if (r->reg >= DBGWVR0_EL1 && r->reg <= DBGWVR15_EL1)
+ val = &saved->dbg_wvr[r->reg - DBGWVR0_EL1];
+ else {
+ kvm_err("Bad register index %d\n", r->reg);
+ return false;
+ }
+
+ if (p->is_write)
+ *val = *vcpu_reg(vcpu, p->Rt);
+ else
+ *vcpu_reg(vcpu, p->Rt) = *val;
+
} else {
- *vcpu_reg(vcpu, p->Rt) = vcpu_sys_reg(vcpu, r->reg);
+ if (p->is_write) {
+ vcpu_sys_reg(vcpu, r->reg) = *vcpu_reg(vcpu, p->Rt);
+ vcpu->arch.debug_flags |= KVM_ARM64_DEBUG_DIRTY;
+ } else {
+ *vcpu_reg(vcpu, p->Rt) = vcpu_sys_reg(vcpu, r->reg);
+ }
}
return true;
diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h
index ce2db14..0e48c0d 100644
--- a/include/uapi/linux/kvm.h
+++ b/include/uapi/linux/kvm.h
@@ -771,6 +771,8 @@ struct kvm_ppc_smmu_info {
#define KVM_CAP_PPC_ENABLE_HCALL 104
#define KVM_CAP_CHECK_EXTENSION_VM 105
#define KVM_CAP_S390_USER_SIGP 106
+#define KVM_CAP_GUEST_DEBUG_HW_BPS 107
+#define KVM_CAP_GUEST_DEBUG_HW_WPS 108
#ifdef KVM_CAP_IRQ_ROUTING
--
2.3.4
_______________________________________________
kvmarm mailing list
kvmarm@lists.cs.columbia.edu
https://lists.cs.columbia.edu/mailman/listinfo/kvmarm
^ permalink raw reply related
* Re: [PATCH v4 00/14] Add kdbus implementation
From: Tom Gundersen @ 2015-03-31 15:10 UTC (permalink / raw)
To: Andy Lutomirski
Cc: David Herrmann, Greg Kroah-Hartman, Arnd Bergmann,
Eric W. Biederman, One Thousand Gnomes, Jiri Kosina, Linux API,
linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org, Daniel Mack,
Djalal Harouni
In-Reply-To: <CALCETrV-cHYzcWu3t6tJ1eP0UZHTqoGH0KTYHTpJNit9-59TAA-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
On Tue, Mar 31, 2015 at 3:58 PM, Andy Lutomirski <luto-kltTT9wpgjJwATOyAt5JVQ@public.gmane.org> wrote:
> On Mon, Mar 30, 2015 at 9:56 AM, David Herrmann <dh.herrmann-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:
>> Hi
>>
>> On Wed, Mar 25, 2015 at 7:12 PM, Andy Lutomirski <luto-kltTT9wpgjJwATOyAt5JVQ@public.gmane.org> wrote:
>>> On Wed, Mar 25, 2015 at 10:29 AM, David Herrmann <dh.herrmann-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:
>> [...]
>>>>> I could be wrong about the lack of use cases. If so, please enlighten me.
>>>>
>>>> We have several dbus APIs that allow clients to register as a special
>>>> handler/controller/etc. (eg., see systemd-logind TakeControl()). The
>>>> API provider checks the privileges of a client on registration and
>>>> then just tracks the client ID. This way, the client can be privileged
>>>> when asking for special access, then drop privileges and still use the
>>>> interface. You cannot re-connect in between, as the API provider
>>>> tracks your bus ID. Without message-metadata, all your (other) calls
>>>> on this bus would always be treated as privileged. We *really* want to
>>>> avoid this.
>>>
>>> Connect twice?
>>
>> The remote peer might cache your connection ID to track you. You have
>> to use the same connection to talk to that peer, in this given
>> scenario. That's how D-Bus1 is used today, and we have to follow the
>> semantics.
>
> That's yet another reason that you really ought to disconnect and
> reconnect after a privilege change -- the remote peer might remember
> you.
>
> The "might" will be a big problem. Users of kdbus can't rely on any
> particular concept of privilege because you have too many of them.
>
>>
>>> You *already* have to reconnect or connect twice because you have
>>> per-connection metadata. That's part of my problem with this scheme
>>> -- you support *both styles*, which seems like it'll give you most of
>>> the downsides of both without the upsides.
>>
>> Not necessarily. Connection metadata describes the state at the time
>> you connected to the bus. If someone ask for this information, they
>> will get exactly that. In this model, you cannot drop privileges, if
>> you need to be privileged during setup.
>> If someone asks for per-message metadata, they better ought not ask
>> for per-connection creds. It's not the information they're looking
>> for, so it will not match the data that at the time the message was
>> sent.
>>
>> There is no immediate need to make both match. For security decisions,
>> we mandate per-message creds. Per-connection creds are for
>> backwards-compatibility to dbus1 and for passive introspection of bus
>> connections.
>
> Backwards compatibility doesn't magically exempt security
> considerations.
No one is arguing that.
> If new code is insecure when talking to a legacy
> service, it's still insecure.
>
> [...]
>
>>> Again, you seem to be arguing that per-connection metadata is bad, but
>>> you still have an implementation of per-connection metadata, so you
>>> still have all these problems.
>>
>> I don't see why we get the problems of per-connection metadata. Just
>> because you _can_ use it, doesn't mean you should use it for all
>> imaginable use-cases. The same goes for reading information from
>> /proc. There are valid use-cases to do so, but also a lot of cases
>> where it will not provide the information you want.
>>
>
> Then you'll need to document really carefully which metadata is used
> for which service. This actually seems impossible to do, since some
> services will exist in legacy and kdbus forms.
>
>>> I'm actually okay with per-message metadata in principle, but I'd like
>>> to see evidence (with numbers, please) that a send+recv of per-message
>>> metadata is *not* significantly slower than a recv of already-captured
>>> per-connection metadata. If this is in fact the case, then maybe you
>>> should trash per-connection metadata instead and the legacy
>>> compatibility code can figure out a way to deal with it. IMO that
>>> would be a pretty nice outcome, since you would never have to worry
>>> whether your connection to the bus is inadvertantly privileged.
>>
>> Per-message metadata makes SEND about 25% slower, if you transmit the
>> full set of all possible information. Just 3% if you only use
>> PIDs+UIDs. The expensive metadata is cgroup-path and exe-path.
>> If a service needs that information, however, and if that information
>> is not guaranteed to be up-to-date, the service _will_ go and look it
>> up in /proc or somewhere else, which is certainly a whole lot more
>> expensive than the code in kdbus.
>
> Can you give actual numbers, in ns or cycles, of how much overhead
> metadata adds?
>
>>
>> In general, there seems to be a number of misconception in this thread
>> about what kdbus is supposed to be. We're not inventing something new
>> here with a clean slate, but we're moving parts of an existing
>> implementation that has tons of users into the kernel, in order to fix
>> issues that cannot be fixed otherwise in userspace (most notably, the
>> race gaps that exist when retrieving per-message metadata). Therefore,
>> we have to keep existing semantics stable, otherwise the exercise is
>> somewhat pointless.
>
> IOW you're taking something that you dislike aspects of and shoving
> most of it in the kernel. That guarantees us an API in the kernel
> that even the creators don't really like. This is, IMO, very
> unfortunate.
This is a misrepresentation of what David wrote. We do want this API
regardless of dbus1 compatibility, but compatibility is by itself a
sufficient motivation. A further motivation is reliable introspection,
since this meta-data allows listing current peers on the bus and
showing their identities. That's hugely useful to make the bus
transparent to admins.
> Have you considered porting the kdbus per-message metadata mechanism to UDS?
As outlined before, enhancing UDS by porting the metadata mechanism
from kdbus would not be sufficient to solve all the problems we need
to solve, so it is not something we are currently working on.
Cheers,
Tom
^ permalink raw reply
* Re: [GIT PULL] selftest: Add futex functional tests
From: Darren Hart @ 2015-03-31 16:24 UTC (permalink / raw)
To: Shuah Khan, Linux Kernel Mailing List
Cc: linux-api-u79uwXL29TY76Z2rM5mHXA, Ingo Molnar, Peter Zijlstra,
Thomas Gleixner, Davidlohr Bueso, KOSAKI Motohiro,
greg Kroah-Hartman, fengguang.wu-ral2JQCrhuEAvxtiuMwx3w,
Michael Ellerman
In-Reply-To: <551ABE00.9050003-JPH+aEBZ4P+UEJcrhfAQsw@public.gmane.org>
On 3/31/15, 8:32 AM, "Shuah Khan" <shuahkh-JPH+aEBZ4P+UEJcrhfAQsw@public.gmane.org> wrote:
>Hi Daren,
>
>On 03/27/2015 04:17 PM, Darren Hart wrote:
>> Hi Shuah,
>>
>> This series begins the process of migrating my futextest tests into
>>kselftest.
>> I've started with only the functional tests, as the performance and
>>stress may
>> not be appropriate for kselftest as they stand.
>>
>> I cleaned up various complaints from checkpatch, but I ignored others
>>that would
>> require significant rework of the testcases, such as not using volatile
>>and not
>> creating new typedefs.
>>
>> The patches will follow, but I'm providing a pull request for your
>>convenience
>> as well.
>
>Thanks for acting on this so quickly after we talked about it at ELC.
>Just a quick note that I am going to get to this soon once I get the
>4.1 content wrapped up. We can plan upon getting these into 4.2.
OK. Michael E. provided some feedback which I can either incorporate and
respin, or I can send as a follow-on to your -next after you merge these.
Which do you prefer?
--
Darren Hart
Intel Open Source Technology Center
^ permalink raw reply
* [PATCH v4 00/15] Add support to STMicroelectronics STM32 family
From: Maxime Coquelin @ 2015-03-31 16:24 UTC (permalink / raw)
To: u.kleine-koenig, afaerber, geert, Rob Herring, Philipp Zabel,
Linus Walleij, Arnd Bergmann, stefan, pmeerw, pebolle, peter,
andy.shevchenko, cw00.choi, Russell King, Daniel Lezcano
Cc: Jonathan Corbet, Pawel Moll, Mark Rutland, Ian Campbell,
Kumar Gala, Thomas Gleixner, Greg Kroah-Hartman, Jiri Slaby,
Andrew Morton, David S. Miller, Mauro Carvalho Chehab,
Joe Perches, Antti Palosaari, Tejun Heo, Will Deacon,
Nikolay Borisov, Rusty Russell, Kees Cook, Michal Marek,
linux-doc, linux-arm-kernel, linux-kernel, devicetree, linux-gpio,
linux-serial
This fourth round mainly addresses comments made on UART and clocksource
drivers. See below changelog for more details.
STM32 MCUs are Cortex-M CPU, used in various applications (consumer
electronics, industrial applications, hobbyists...).
Datasheets, user and programming manuals are publicly available on
STMicroelectronics website.
With this series applied, the STM32F419 Discovery can boot succesfully.
Changes since v3:
-----------------
- Fix and simplify error path in ARMv7-M Systick driver (Daniel)
- Improve reset bindings documentation (Philipp)
- Fix trailing lines anf typos in reset driver & doc (Philipp & Chanwoo)
- Fix MODULE_LICENCE in USART driver (Paul)
- Refactor USART baudrate calculation (Peter & Andy)
- Fix error path in USART init (Peter & Russell)
- Fix HW flow control in USART driver (Peter)
- Fix serial port type number to unused one (Peter)
- Applies Chanwoo's Tested-by on the series
Changes since v2:
-----------------
- Remove pinctrl driver from the series.
- Remove reset_controller_of_init(), and reset the timers in the bootloader
- Add HW flow contrl property for serial driver
- Lots of changes in the DTS file, as per Andreas recommendations
- Some Kconfig clean-ups
- Adapt the config to be compatible with Andreas' bootwrapper, except UART port.
- Various fixes in documentation
Changes since v1:
-----------------
- Move bindings documentation in their own patches (Andreas)
- Rename ARM System timer to armv7m-systick (Rob)
- Add clock-frequency property handling in armv7m-systick (Rob)
- Re-factor the reset controllers into a single controller (Philipp)
- Add kerneldoc to reset_controller_of_init (Philipp)
- Add named constants in include/dt-bindings/reset/ (Philipp)
- Make pinctrl driver to depend on ARCH_STM32 or COMPILE_TEST (Geert)
- Introduce CPUV7M_NUM_IRQ config flag to indicate the number of interrupts
supported by the MCU, in order to limit memory waste in vectors' table (Uwe)
Maxime Coquelin (15):
scripts: link-vmlinux: Don't pass page offset to kallsyms if XIP
Kernel
ARM: ARMv7-M: Enlarge vector table up to 256 entries
dt-bindings: Document the ARM System timer bindings
clocksource/drivers: Add ARM System timer driver
dt-bindings: Document the STM32 reset bindings
drivers: reset: Add STM32 reset driver
dt-bindings: Document the STM32 timer bindings
clockevents/drivers: Add STM32 Timer driver
dt-bindings: Document the STM32 USART bindings
serial: stm32-usart: Add STM32 USART Driver
ARM: Add STM32 family machine
ARM: dts: Add ARM System timer as clockevent in armv7m
ARM: dts: Introduce STM32F429 MCU
ARM: configs: Add STM32 defconfig
MAINTAINERS: Add entry for STM32 MCUs
Documentation/arm/stm32/overview.txt | 32 +
Documentation/arm/stm32/stm32f429-overview.txt | 22 +
.../devicetree/bindings/arm/armv7m_systick.txt | 26 +
.../devicetree/bindings/reset/st,stm32-rcc.txt | 107 +++
.../devicetree/bindings/serial/st,stm32-usart.txt | 32 +
.../devicetree/bindings/timer/st,stm32-timer.txt | 22 +
MAINTAINERS | 8 +
arch/arm/Kconfig | 18 +
arch/arm/Makefile | 1 +
arch/arm/boot/dts/Makefile | 1 +
arch/arm/boot/dts/armv7-m.dtsi | 6 +
arch/arm/boot/dts/stm32f429-disco.dts | 71 ++
arch/arm/boot/dts/stm32f429.dtsi | 226 +++++++
arch/arm/configs/stm32_defconfig | 71 ++
arch/arm/kernel/entry-v7m.S | 13 +-
arch/arm/mach-stm32/Makefile | 1 +
arch/arm/mach-stm32/Makefile.boot | 3 +
arch/arm/mach-stm32/board-dt.c | 19 +
arch/arm/mm/Kconfig | 15 +
drivers/clocksource/Kconfig | 15 +
drivers/clocksource/Makefile | 2 +
drivers/clocksource/armv7m_systick.c | 79 +++
drivers/clocksource/timer-stm32.c | 184 +++++
drivers/reset/Makefile | 1 +
drivers/reset/reset-stm32.c | 124 ++++
drivers/tty/serial/Kconfig | 17 +
drivers/tty/serial/Makefile | 1 +
drivers/tty/serial/stm32-usart.c | 743 +++++++++++++++++++++
include/uapi/linux/serial_core.h | 3 +
scripts/link-vmlinux.sh | 2 +-
30 files changed, 1860 insertions(+), 5 deletions(-)
create mode 100644 Documentation/arm/stm32/overview.txt
create mode 100644 Documentation/arm/stm32/stm32f429-overview.txt
create mode 100644 Documentation/devicetree/bindings/arm/armv7m_systick.txt
create mode 100644 Documentation/devicetree/bindings/reset/st,stm32-rcc.txt
create mode 100644 Documentation/devicetree/bindings/serial/st,stm32-usart.txt
create mode 100644 Documentation/devicetree/bindings/timer/st,stm32-timer.txt
create mode 100644 arch/arm/boot/dts/stm32f429-disco.dts
create mode 100644 arch/arm/boot/dts/stm32f429.dtsi
create mode 100644 arch/arm/configs/stm32_defconfig
create mode 100644 arch/arm/mach-stm32/Makefile
create mode 100644 arch/arm/mach-stm32/Makefile.boot
create mode 100644 arch/arm/mach-stm32/board-dt.c
create mode 100644 drivers/clocksource/armv7m_systick.c
create mode 100644 drivers/clocksource/timer-stm32.c
create mode 100644 drivers/reset/reset-stm32.c
create mode 100644 drivers/tty/serial/stm32-usart.c
--
1.9.1
^ permalink raw reply
* [PATCH v4 01/15] scripts: link-vmlinux: Don't pass page offset to kallsyms if XIP Kernel
From: Maxime Coquelin @ 2015-03-31 16:24 UTC (permalink / raw)
To: u.kleine-koenig, afaerber, geert, Rob Herring, Philipp Zabel,
Linus Walleij, Arnd Bergmann, stefan, pmeerw, pebolle, peter,
andy.shevchenko, cw00.choi, Russell King, Daniel Lezcano
Cc: Jonathan Corbet, Pawel Moll, Mark Rutland, Ian Campbell,
Kumar Gala, Thomas Gleixner, Greg Kroah-Hartman, Jiri Slaby,
Andrew Morton, David S. Miller, Mauro Carvalho Chehab,
Joe Perches, Antti Palosaari, Tejun Heo, Will Deacon,
Nikolay Borisov, Rusty Russell, Kees Cook, Michal Marek,
linux-doc, linux-arm-kernel, linux-kernel, devicetree, linux-gpio,
linux-serial
In-Reply-To: <1427819096-31109-1-git-send-email-mcoquelin.stm32@gmail.com>
When Kernel is executed in place from ROM, the symbol addresses can be
lower than the page offset.
Tested-by: Chanwoo Choi <cw00.choi@samsung.com>
Signed-off-by: Maxime Coquelin <mcoquelin.stm32@gmail.com>
---
scripts/link-vmlinux.sh | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/scripts/link-vmlinux.sh b/scripts/link-vmlinux.sh
index 86a4fe7..b055d9d 100755
--- a/scripts/link-vmlinux.sh
+++ b/scripts/link-vmlinux.sh
@@ -82,7 +82,7 @@ kallsyms()
kallsymopt="${kallsymopt} --all-symbols"
fi
- if [ -n "${CONFIG_ARM}" ] && [ -n "${CONFIG_PAGE_OFFSET}" ]; then
+ if [ -n "${CONFIG_ARM}" ] && [ -z "${CONFIG_XIP_KERNEL}" ] && [ -n "${CONFIG_PAGE_OFFSET}" ]; then
kallsymopt="${kallsymopt} --page-offset=$CONFIG_PAGE_OFFSET"
fi
--
1.9.1
^ permalink raw reply related
* [PATCH v4 02/15] ARM: ARMv7-M: Enlarge vector table up to 256 entries
From: Maxime Coquelin @ 2015-03-31 16:24 UTC (permalink / raw)
To: u.kleine-koenig, afaerber, geert, Rob Herring, Philipp Zabel,
Linus Walleij, Arnd Bergmann, stefan, pmeerw, pebolle, peter,
andy.shevchenko, cw00.choi, Russell King, Daniel Lezcano
Cc: Jonathan Corbet, Pawel Moll, Mark Rutland, Ian Campbell,
Kumar Gala, Thomas Gleixner, Greg Kroah-Hartman, Jiri Slaby,
Andrew Morton, David S. Miller, Mauro Carvalho Chehab,
Joe Perches, Antti Palosaari, Tejun Heo, Will Deacon,
Nikolay Borisov, Rusty Russell, Kees Cook, Michal Marek,
linux-doc, linux-arm-kernel, linux-kernel, devicetree, linux-gpio,
linux-serial
In-Reply-To: <1427819096-31109-1-git-send-email-mcoquelin.stm32@gmail.com>
From Cortex-M reference manuals, the nvic supports up to 240 interrupts.
So the number of entries in vectors table is up to 256.
This patch adds a new config flag to specify the number of external interrupts.
Some ifdeferies are added in order to respect the natural alignment without
wasting too much space on smaller systems.
Acked-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
Acked-by: Stefan Agner <stefan@agner.ch>
Tested-by: Chanwoo Choi <cw00.choi@samsung.com>
Signed-off-by: Maxime Coquelin <mcoquelin.stm32@gmail.com>
---
arch/arm/kernel/entry-v7m.S | 13 +++++++++----
arch/arm/mm/Kconfig | 15 +++++++++++++++
2 files changed, 24 insertions(+), 4 deletions(-)
diff --git a/arch/arm/kernel/entry-v7m.S b/arch/arm/kernel/entry-v7m.S
index 8944f49..b6c8bb9 100644
--- a/arch/arm/kernel/entry-v7m.S
+++ b/arch/arm/kernel/entry-v7m.S
@@ -117,9 +117,14 @@ ENTRY(__switch_to)
ENDPROC(__switch_to)
.data
- .align 8
+#if CONFIG_CPU_V7M_NUM_IRQ <= 112
+ .align 9
+#else
+ .align 10
+#endif
+
/*
- * Vector table (64 words => 256 bytes natural alignment)
+ * Vector table (Natural alignment need to be ensured)
*/
ENTRY(vector_table)
.long 0 @ 0 - Reset stack pointer
@@ -138,6 +143,6 @@ ENTRY(vector_table)
.long __invalid_entry @ 13 - Reserved
.long __pendsv_entry @ 14 - PendSV
.long __invalid_entry @ 15 - SysTick
- .rept 64 - 16
- .long __irq_entry @ 16..64 - External Interrupts
+ .rept CONFIG_CPU_V7M_NUM_IRQ
+ .long __irq_entry @ External Interrupts
.endr
diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig
index 9b4f29e..aec53b4 100644
--- a/arch/arm/mm/Kconfig
+++ b/arch/arm/mm/Kconfig
@@ -604,6 +604,21 @@ config CPU_USE_DOMAINS
This option enables or disables the use of domain switching
via the set_fs() function.
+config CPU_V7M_NUM_IRQ
+ int "Number of external interrupts connected to the NVIC"
+ depends on CPU_V7M
+ default 90 if ARCH_STM32
+ default 38 if ARCH_EFM32
+ default 240
+ help
+ This option indicates the number of interrupts connected to the NVIC.
+ The value can be larger than the real number of interrupts supported
+ by the system, but must not be lower.
+ The default value is 240, corresponding to the maximum number of
+ interrupts supported by the NVIC on Cortex-M family.
+
+ If unsure, keep default value.
+
#
# CPU supports 36-bit I/O
#
--
1.9.1
--
To unsubscribe from this list: send the line "unsubscribe linux-gpio" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* [PATCH v4 03/15] dt-bindings: Document the ARM System timer bindings
From: Maxime Coquelin @ 2015-03-31 16:24 UTC (permalink / raw)
To: u.kleine-koenig, afaerber, geert, Rob Herring, Philipp Zabel,
Linus Walleij, Arnd Bergmann, stefan, pmeerw, pebolle, peter,
andy.shevchenko, cw00.choi, Russell King, Daniel Lezcano
Cc: Mark Rutland, linux-doc, Will Deacon, Nikolay Borisov, linux-api,
Jiri Slaby, linux-arch, Jonathan Corbet, Mauro Carvalho Chehab,
Antti Palosaari, linux-serial, devicetree, Kees Cook, Pawel Moll,
Ian Campbell, Rusty Russell, Joe Perches, Thomas Gleixner,
linux-arm-kernel, Michal Marek, linux-gpio, Greg Kroah-Hartman,
linux-kernel, mcoquelin.stm32, Kumar Gala, Tejun Heo
In-Reply-To: <1427819096-31109-1-git-send-email-mcoquelin.stm32@gmail.com>
This adds documentation of device tree bindings for the
ARM System timer.
Tested-by: Chanwoo Choi <cw00.choi@samsung.com>
Signed-off-by: Maxime Coquelin <mcoquelin.stm32@gmail.com>
---
.../devicetree/bindings/arm/armv7m_systick.txt | 26 ++++++++++++++++++++++
1 file changed, 26 insertions(+)
create mode 100644 Documentation/devicetree/bindings/arm/armv7m_systick.txt
diff --git a/Documentation/devicetree/bindings/arm/armv7m_systick.txt b/Documentation/devicetree/bindings/arm/armv7m_systick.txt
new file mode 100644
index 0000000..7cf4a24
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/armv7m_systick.txt
@@ -0,0 +1,26 @@
+* ARMv7M System Timer
+
+ARMv7-M includes a system timer, known as SysTick. Current driver only
+implements the clocksource feature.
+
+Required properties:
+- compatible : Should be "arm,armv7m-systick"
+- reg : The address range of the timer
+
+Required clocking property, have to be one of:
+- clocks : The input clock of the timer
+- clock-frequency : The rate in HZ in input of the ARM SysTick
+
+Examples:
+
+systick: timer@e000e010 {
+ compatible = "arm,armv7m-systick";
+ reg = <0xe000e010 0x10>;
+ clocks = <&clk_systick>;
+};
+
+systick: timer@e000e010 {
+ compatible = "arm,armv7m-systick";
+ reg = <0xe000e010 0x10>;
+ clock-frequency = <90000000>;
+};
--
1.9.1
^ permalink raw reply related
* [PATCH v4 04/15] clocksource/drivers: Add ARM System timer driver
From: Maxime Coquelin @ 2015-03-31 16:24 UTC (permalink / raw)
To: u.kleine-koenig, afaerber, geert, Rob Herring, Philipp Zabel,
Linus Walleij, Arnd Bergmann, stefan, pmeerw, pebolle, peter,
andy.shevchenko, cw00.choi, Russell King, Daniel Lezcano
Cc: Mark Rutland, linux-doc, Will Deacon, Nikolay Borisov, linux-api,
Jiri Slaby, linux-arch, Jonathan Corbet, Mauro Carvalho Chehab,
Antti Palosaari, linux-serial, devicetree, Kees Cook, Pawel Moll,
Ian Campbell, Rusty Russell, Joe Perches, Thomas Gleixner,
linux-arm-kernel, Michal Marek, linux-gpio, Greg Kroah-Hartman,
linux-kernel, mcoquelin.stm32, Kumar Gala, Tejun Heo
In-Reply-To: <1427819096-31109-1-git-send-email-mcoquelin.stm32@gmail.com>
This patch adds clocksource support for ARMv7-M's System timer,
also known as SysTick.
Tested-by: Chanwoo Choi <cw00.choi@samsung.com>
Signed-off-by: Maxime Coquelin <mcoquelin.stm32@gmail.com>
---
drivers/clocksource/Kconfig | 7 ++++
drivers/clocksource/Makefile | 1 +
drivers/clocksource/armv7m_systick.c | 79 ++++++++++++++++++++++++++++++++++++
3 files changed, 87 insertions(+)
create mode 100644 drivers/clocksource/armv7m_systick.c
diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
index 1c2506f..b82e58b 100644
--- a/drivers/clocksource/Kconfig
+++ b/drivers/clocksource/Kconfig
@@ -134,6 +134,13 @@ config CLKSRC_ARM_GLOBAL_TIMER_SCHED_CLOCK
help
Use ARM global timer clock source as sched_clock
+config ARMV7M_SYSTICK
+ bool
+ select CLKSRC_OF if OF
+ select CLKSRC_MMIO
+ help
+ This options enables support for the ARMv7M system timer unit
+
config ATMEL_PIT
select CLKSRC_OF if OF
def_bool SOC_AT91SAM9 || SOC_SAMA5
diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile
index 752d5c7..1c9a643 100644
--- a/drivers/clocksource/Makefile
+++ b/drivers/clocksource/Makefile
@@ -44,6 +44,7 @@ obj-$(CONFIG_MTK_TIMER) += mtk_timer.o
obj-$(CONFIG_ARM_ARCH_TIMER) += arm_arch_timer.o
obj-$(CONFIG_ARM_GLOBAL_TIMER) += arm_global_timer.o
+obj-$(CONFIG_ARMV7M_SYSTICK) += armv7m_systick.o
obj-$(CONFIG_CLKSRC_METAG_GENERIC) += metag_generic.o
obj-$(CONFIG_ARCH_HAS_TICK_BROADCAST) += dummy_timer.o
obj-$(CONFIG_ARCH_KEYSTONE) += timer-keystone.o
diff --git a/drivers/clocksource/armv7m_systick.c b/drivers/clocksource/armv7m_systick.c
new file mode 100644
index 0000000..addfd2c
--- /dev/null
+++ b/drivers/clocksource/armv7m_systick.c
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) Maxime Coquelin 2015
+ * Author: Maxime Coquelin <mcoquelin.stm32@gmail.com>
+ * License terms: GNU General Public License (GPL), version 2
+ */
+
+#include <linux/kernel.h>
+#include <linux/clocksource.h>
+#include <linux/clockchips.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/clk.h>
+#include <linux/bitops.h>
+
+#define SYST_CSR 0x00
+#define SYST_RVR 0x04
+#define SYST_CVR 0x08
+#define SYST_CALIB 0x0c
+
+#define SYST_CSR_ENABLE BIT(0)
+
+#define SYSTICK_LOAD_RELOAD_MASK 0x00FFFFFF
+
+static void __init system_timer_of_register(struct device_node *np)
+{
+ struct clk *clk = NULL;
+ void __iomem *base;
+ u32 rate;
+ int ret;
+
+ base = of_iomap(np, 0);
+ if (!base) {
+ pr_warn("system-timer: invalid base address\n");
+ return;
+ }
+
+ ret = of_property_read_u32(np, "clock-frequency", &rate);
+ if (ret) {
+ clk = of_clk_get(np, 0);
+ if (IS_ERR(clk))
+ goto out_unmap;
+
+ ret = clk_prepare_enable(clk);
+ if (ret)
+ goto out_clk_put;
+
+ rate = clk_get_rate(clk);
+ if (!rate)
+ goto out_clk_disable;
+ }
+
+ writel_relaxed(SYSTICK_LOAD_RELOAD_MASK, base + SYST_RVR);
+ writel_relaxed(SYST_CSR_ENABLE, base + SYST_CSR);
+
+ ret = clocksource_mmio_init(base + SYST_CVR, "arm_system_timer", rate,
+ 200, 24, clocksource_mmio_readl_down);
+ if (ret) {
+ pr_err("failed to init clocksource (%d)\n", ret);
+ if (clk)
+ goto out_clk_disable;
+ else
+ goto out_unmap;
+ }
+
+ pr_info("ARM System timer initialized as clocksource\n");
+
+ return;
+
+out_clk_disable:
+ clk_disable_unprepare(clk);
+out_clk_put:
+ clk_put(clk);
+out_unmap:
+ iounmap(base);
+ pr_warn("ARM System timer register failed (%d)\n", ret);
+}
+
+CLOCKSOURCE_OF_DECLARE(arm_systick, "arm,armv7m-systick",
+ system_timer_of_register);
--
1.9.1
^ permalink raw reply related
* [PATCH v4 05/15] dt-bindings: Document the STM32 reset bindings
From: Maxime Coquelin @ 2015-03-31 16:24 UTC (permalink / raw)
To: u.kleine-koenig, afaerber, geert, Rob Herring, Philipp Zabel,
Linus Walleij, Arnd Bergmann, stefan, pmeerw, pebolle, peter,
andy.shevchenko, cw00.choi, Russell King, Daniel Lezcano
Cc: Jonathan Corbet, Pawel Moll, Mark Rutland, Ian Campbell,
Kumar Gala, Thomas Gleixner, Greg Kroah-Hartman, Jiri Slaby,
Andrew Morton, David S. Miller, Mauro Carvalho Chehab,
Joe Perches, Antti Palosaari, Tejun Heo, Will Deacon,
Nikolay Borisov, Rusty Russell, Kees Cook, Michal Marek,
linux-doc, linux-arm-kernel, linux-kernel, devicetree, linux-gpio,
linux-serial
In-Reply-To: <1427819096-31109-1-git-send-email-mcoquelin.stm32@gmail.com>
This adds documentation of device tree bindings for the
STM32 reset controller.
Tested-by: Chanwoo Choi <cw00.choi@samsung.com>
Signed-off-by: Maxime Coquelin <mcoquelin.stm32@gmail.com>
---
.../devicetree/bindings/reset/st,stm32-rcc.txt | 107 +++++++++++++++++++++
1 file changed, 107 insertions(+)
create mode 100644 Documentation/devicetree/bindings/reset/st,stm32-rcc.txt
diff --git a/Documentation/devicetree/bindings/reset/st,stm32-rcc.txt b/Documentation/devicetree/bindings/reset/st,stm32-rcc.txt
new file mode 100644
index 0000000..e2e2f25
--- /dev/null
+++ b/Documentation/devicetree/bindings/reset/st,stm32-rcc.txt
@@ -0,0 +1,107 @@
+STMicroelectronics STM32 Peripheral Reset Controller
+====================================================
+
+The RCC IP is both a reset and a clock controller. This documentation only
+document the reset part.
+
+Please also refer to reset.txt in this directory for common reset
+controller binding usage.
+
+Required properties:
+- compatible: Should be "st,stm32-rcc"
+- reg: should be register base and length as documented in the
+ datasheet
+- #reset-cells: 1, see below
+
+example:
+
+rcc: reset@40023800 {
+ #reset-cells = <1>;
+ compatible = "st,stm32-rcc";
+ reg = <0x40023800 0x400>;
+};
+
+Specifying softreset control of devices
+=======================================
+
+Device nodes should specify the reset channel required in their "resets"
+property, containing a phandle to the reset device node and an index specifying
+which channel to use.
+The index is the bit number within the RCC registers bank, starting from RCC
+base address.
+It is calculated as: index = register_offset / 4 * 32 + bit_offset.
+Where bit_offset is the bit offset within the register.
+For example, for CRC reset:
+ crc = AHB1RSTR_offset / 4 * 32 + CRCRST_bit_offset = 0x10 / 4 * 32 + 12 = 140
+
+example:
+
+ timer2 {
+ resets = <&rcc 256>;
+ };
+
+List of valid indices for STM32F429:
+ - gpioa: 128
+ - gpiob: 129
+ - gpioc: 130
+ - gpiod: 131
+ - gpioe: 132
+ - gpiof: 133
+ - gpiog: 134
+ - gpioh: 135
+ - gpioi: 136
+ - gpioj: 137
+ - gpiok: 138
+ - crc: 140
+ - dma1: 149
+ - dma2: 150
+ - dma2d: 151
+ - ethmac: 153
+ - otghs: 157
+ - dcmi: 160
+ - cryp: 164
+ - hash: 165
+ - rng: 166
+ - otgfs: 167
+ - fmc: 192
+ - tim2: 256
+ - tim3: 257
+ - tim4: 258
+ - tim5: 259
+ - tim6: 260
+ - tim7: 261
+ - tim12: 262
+ - tim13: 263
+ - tim14: 264
+ - wwdg: 267
+ - spi2: 270
+ - spi3: 271
+ - uart2: 273
+ - uart3: 274
+ - uart4: 275
+ - uart5: 276
+ - i2c1: 277
+ - i2c2: 278
+ - i2c3: 279
+ - can1: 281
+ - can2: 282
+ - pwr: 284
+ - dac: 285
+ - uart7: 286
+ - uart8: 287
+ - tim1: 288
+ - tim8: 289
+ - usart1: 292
+ - usart6: 293
+ - adc: 296
+ - sdio: 299
+ - spi1: 300
+ - spi4: 301
+ - syscfg: 302
+ - tim9: 304
+ - tim10: 305
+ - tim11: 306
+ - spi5: 308
+ - spi6: 309
+ - sai1: 310
+ - ltdc: 314
--
1.9.1
^ permalink raw reply related
* [PATCH v4 06/15] drivers: reset: Add STM32 reset driver
From: Maxime Coquelin @ 2015-03-31 16:24 UTC (permalink / raw)
To: u.kleine-koenig, afaerber, geert, Rob Herring, Philipp Zabel,
Linus Walleij, Arnd Bergmann, stefan, pmeerw, pebolle, peter,
andy.shevchenko, cw00.choi, Russell King, Daniel Lezcano
Cc: Jonathan Corbet, Pawel Moll, Mark Rutland, Ian Campbell,
Kumar Gala, Thomas Gleixner, Greg Kroah-Hartman, Jiri Slaby,
Andrew Morton, David S. Miller, Mauro Carvalho Chehab,
Joe Perches, Antti Palosaari, Tejun Heo, Will Deacon,
Nikolay Borisov, Rusty Russell, Kees Cook, Michal Marek,
linux-doc, linux-arm-kernel, linux-kernel, devicetree, linux-gpio,
linux-serial
In-Reply-To: <1427819096-31109-1-git-send-email-mcoquelin.stm32@gmail.com>
The STM32 MCUs family IPs can be reset by accessing some registers
from the RCC block.
The list of available reset lines is documented in the DT bindings.
Tested-by: Chanwoo Choi <cw00.choi@samsung.com>
Signed-off-by: Maxime Coquelin <mcoquelin.stm32@gmail.com>
---
drivers/reset/Makefile | 1 +
drivers/reset/reset-stm32.c | 124 ++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 125 insertions(+)
create mode 100644 drivers/reset/reset-stm32.c
diff --git a/drivers/reset/Makefile b/drivers/reset/Makefile
index 157d421..aed12d1 100644
--- a/drivers/reset/Makefile
+++ b/drivers/reset/Makefile
@@ -1,5 +1,6 @@
obj-$(CONFIG_RESET_CONTROLLER) += core.o
obj-$(CONFIG_ARCH_SOCFPGA) += reset-socfpga.o
obj-$(CONFIG_ARCH_BERLIN) += reset-berlin.o
+obj-$(CONFIG_ARCH_STM32) += reset-stm32.o
obj-$(CONFIG_ARCH_SUNXI) += reset-sunxi.o
obj-$(CONFIG_ARCH_STI) += sti/
diff --git a/drivers/reset/reset-stm32.c b/drivers/reset/reset-stm32.c
new file mode 100644
index 0000000..2c41858
--- /dev/null
+++ b/drivers/reset/reset-stm32.c
@@ -0,0 +1,124 @@
+/*
+ * Copyright (C) Maxime Coquelin 2015
+ * Author: Maxime Coquelin <mcoquelin.stm32@gmail.com>
+ * License terms: GNU General Public License (GPL), version 2
+ *
+ * Heavily based on sunxi driver from Maxime Ripard.
+ */
+
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/platform_device.h>
+#include <linux/reset-controller.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+#include <linux/types.h>
+
+struct stm32_reset_data {
+ spinlock_t lock;
+ void __iomem *membase;
+ struct reset_controller_dev rcdev;
+};
+
+static int stm32_reset_assert(struct reset_controller_dev *rcdev,
+ unsigned long id)
+{
+ struct stm32_reset_data *data = container_of(rcdev,
+ struct stm32_reset_data,
+ rcdev);
+ int bank = id / BITS_PER_LONG;
+ int offset = id % BITS_PER_LONG;
+ unsigned long flags;
+ u32 reg;
+
+ spin_lock_irqsave(&data->lock, flags);
+
+ reg = readl_relaxed(data->membase + (bank * 4));
+ writel_relaxed(reg | BIT(offset), data->membase + (bank * 4));
+
+ spin_unlock_irqrestore(&data->lock, flags);
+
+ return 0;
+}
+
+static int stm32_reset_deassert(struct reset_controller_dev *rcdev,
+ unsigned long id)
+{
+ struct stm32_reset_data *data = container_of(rcdev,
+ struct stm32_reset_data,
+ rcdev);
+ int bank = id / BITS_PER_LONG;
+ int offset = id % BITS_PER_LONG;
+ unsigned long flags;
+ u32 reg;
+
+ spin_lock_irqsave(&data->lock, flags);
+
+ reg = readl_relaxed(data->membase + (bank * 4));
+ writel_relaxed(reg & ~BIT(offset), data->membase + (bank * 4));
+
+ spin_unlock_irqrestore(&data->lock, flags);
+
+ return 0;
+}
+
+static struct reset_control_ops stm32_reset_ops = {
+ .assert = stm32_reset_assert,
+ .deassert = stm32_reset_deassert,
+};
+
+static const struct of_device_id stm32_reset_dt_ids[] = {
+ { .compatible = "st,stm32-rcc", },
+ { /* sentinel */ },
+};
+MODULE_DEVICE_TABLE(of, sstm32_reset_dt_ids);
+
+static int stm32_reset_probe(struct platform_device *pdev)
+{
+ struct stm32_reset_data *data;
+ struct resource *res;
+
+ data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
+ if (!data)
+ return -ENOMEM;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ data->membase = devm_ioremap_resource(&pdev->dev, res);
+ if (IS_ERR(data->membase))
+ return PTR_ERR(data->membase);
+
+ spin_lock_init(&data->lock);
+
+ data->rcdev.owner = THIS_MODULE;
+ data->rcdev.nr_resets = resource_size(res) * 8;
+ data->rcdev.ops = &stm32_reset_ops;
+ data->rcdev.of_node = pdev->dev.of_node;
+
+ return reset_controller_register(&data->rcdev);
+}
+
+static int stm32_reset_remove(struct platform_device *pdev)
+{
+ struct stm32_reset_data *data = platform_get_drvdata(pdev);
+
+ reset_controller_unregister(&data->rcdev);
+
+ return 0;
+}
+
+static struct platform_driver stm32_reset_driver = {
+ .probe = stm32_reset_probe,
+ .remove = stm32_reset_remove,
+ .driver = {
+ .name = "stm32-rcc-reset",
+ .of_match_table = stm32_reset_dt_ids,
+ },
+};
+module_platform_driver(stm32_reset_driver);
+
+MODULE_AUTHOR("Maxime Coquelin <maxime.coquelin@gmail.com>");
+MODULE_DESCRIPTION("STM32 MCUs Reset Controller Driver");
+MODULE_LICENSE("GPL");
--
1.9.1
^ permalink raw reply related
* [PATCH v4 07/15] dt-bindings: Document the STM32 timer bindings
From: Maxime Coquelin @ 2015-03-31 16:24 UTC (permalink / raw)
To: u.kleine-koenig, afaerber, geert, Rob Herring, Philipp Zabel,
Linus Walleij, Arnd Bergmann, stefan, pmeerw, pebolle, peter,
andy.shevchenko, cw00.choi, Russell King, Daniel Lezcano
Cc: Jonathan Corbet, Pawel Moll, Mark Rutland, Ian Campbell,
Kumar Gala, Thomas Gleixner, Greg Kroah-Hartman, Jiri Slaby,
Andrew Morton, David S. Miller, Mauro Carvalho Chehab,
Joe Perches, Antti Palosaari, Tejun Heo, Will Deacon,
Nikolay Borisov, Rusty Russell, Kees Cook, Michal Marek,
linux-doc, linux-arm-kernel, linux-kernel, devicetree, linux-gpio,
linux-serial
In-Reply-To: <1427819096-31109-1-git-send-email-mcoquelin.stm32@gmail.com>
This adds documentation of device tree bindings for the
STM32 timer.
Tested-by: Chanwoo Choi <cw00.choi@samsung.com>
Signed-off-by: Maxime Coquelin <mcoquelin.stm32@gmail.com>
---
.../devicetree/bindings/timer/st,stm32-timer.txt | 22 ++++++++++++++++++++++
1 file changed, 22 insertions(+)
create mode 100644 Documentation/devicetree/bindings/timer/st,stm32-timer.txt
diff --git a/Documentation/devicetree/bindings/timer/st,stm32-timer.txt b/Documentation/devicetree/bindings/timer/st,stm32-timer.txt
new file mode 100644
index 0000000..d3fdeb0
--- /dev/null
+++ b/Documentation/devicetree/bindings/timer/st,stm32-timer.txt
@@ -0,0 +1,22 @@
+. STMicroelectronics STM32 timer
+
+The STM32 MCUs family has several general-purpose 16 and 32 bits timers.
+
+Required properties:
+- compatible : Should be st,stm32-timer"
+- reg : Address and length of the register set
+- clocks : Reference on the timer input clock
+- interrupts : Reference to the timer interrupt
+
+Optional properties:
+- resets: Reference to a reset controller asserting the timer
+
+Example:
+
+timer5: timer@40000c00 {
+ compatible = "st,stm32-timer";
+ reg = <0x40000c00 0x400>;
+ interrupts = <50>;
+ resets = <&rrc 259>;
+ clocks = <&clk_pmtr1>;
+};
--
1.9.1
^ permalink raw reply related
* [PATCH v4 08/15] clockevents/drivers: Add STM32 Timer driver
From: Maxime Coquelin @ 2015-03-31 16:24 UTC (permalink / raw)
To: u.kleine-koenig, afaerber, geert, Rob Herring, Philipp Zabel,
Linus Walleij, Arnd Bergmann, stefan, pmeerw, pebolle, peter,
andy.shevchenko, cw00.choi, Russell King, Daniel Lezcano
Cc: Jonathan Corbet, Pawel Moll, Mark Rutland, Ian Campbell,
Kumar Gala, Thomas Gleixner, Greg Kroah-Hartman, Jiri Slaby,
Andrew Morton, David S. Miller, Mauro Carvalho Chehab,
Joe Perches, Antti Palosaari, Tejun Heo, Will Deacon,
Nikolay Borisov, Rusty Russell, Kees Cook, Michal Marek,
linux-doc, linux-arm-kernel, linux-kernel, devicetree, linux-gpio,
linux-serial
In-Reply-To: <1427819096-31109-1-git-send-email-mcoquelin.stm32@gmail.com>
STM32 MCUs feature 16 and 32 bits general purpose timers with prescalers.
The drivers detects whether the time is 16 or 32 bits, and applies a
1024 prescaler value if it is 16 bits.
Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
Tested-by: Chanwoo Choi <cw00.choi@samsung.com>
Signed-off-by: Maxime Coquelin <mcoquelin.stm32@gmail.com>
---
drivers/clocksource/Kconfig | 8 ++
drivers/clocksource/Makefile | 1 +
drivers/clocksource/timer-stm32.c | 184 ++++++++++++++++++++++++++++++++++++++
3 files changed, 193 insertions(+)
create mode 100644 drivers/clocksource/timer-stm32.c
diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
index b82e58b..519304b 100644
--- a/drivers/clocksource/Kconfig
+++ b/drivers/clocksource/Kconfig
@@ -101,6 +101,14 @@ config CLKSRC_EFM32
Support to use the timers of EFM32 SoCs as clock source and clock
event device.
+config CLKSRC_STM32
+ bool "Clocksource for STM32 SoCs" if !ARCH_STM32
+ depends on OF && ARM && (ARCH_STM32 || COMPILE_TEST)
+ select CLKSRC_MMIO
+ default ARCH_STM32
+ help
+ Support to use the timers of STM32 SoCs as clock event device.
+
config ARM_ARCH_TIMER
bool
select CLKSRC_OF if OF
diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile
index 1c9a643..525dafe 100644
--- a/drivers/clocksource/Makefile
+++ b/drivers/clocksource/Makefile
@@ -35,6 +35,7 @@ obj-$(CONFIG_ARCH_NSPIRE) += zevio-timer.o
obj-$(CONFIG_ARCH_BCM_MOBILE) += bcm_kona_timer.o
obj-$(CONFIG_CADENCE_TTC_TIMER) += cadence_ttc_timer.o
obj-$(CONFIG_CLKSRC_EFM32) += time-efm32.o
+obj-$(CONFIG_CLKSRC_STM32) += timer-stm32.o
obj-$(CONFIG_CLKSRC_EXYNOS_MCT) += exynos_mct.o
obj-$(CONFIG_CLKSRC_SAMSUNG_PWM) += samsung_pwm_timer.o
obj-$(CONFIG_FSL_FTM_TIMER) += fsl_ftm_timer.o
diff --git a/drivers/clocksource/timer-stm32.c b/drivers/clocksource/timer-stm32.c
new file mode 100644
index 0000000..fad2e2e
--- /dev/null
+++ b/drivers/clocksource/timer-stm32.c
@@ -0,0 +1,184 @@
+/*
+ * Copyright (C) Maxime Coquelin 2015
+ * Author: Maxime Coquelin <mcoquelin.stm32@gmail.com>
+ * License terms: GNU General Public License (GPL), version 2
+ *
+ * Inspired by time-efm32.c from Uwe Kleine-Koenig
+ */
+
+#include <linux/kernel.h>
+#include <linux/clocksource.h>
+#include <linux/clockchips.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/clk.h>
+#include <linux/reset.h>
+
+#define TIM_CR1 0x00
+#define TIM_DIER 0x0c
+#define TIM_SR 0x10
+#define TIM_EGR 0x14
+#define TIM_PSC 0x28
+#define TIM_ARR 0x2c
+
+#define TIM_CR1_CEN BIT(0)
+#define TIM_CR1_OPM BIT(3)
+#define TIM_CR1_ARPE BIT(7)
+
+#define TIM_DIER_UIE BIT(0)
+
+#define TIM_SR_UIF BIT(0)
+
+#define TIM_EGR_UG BIT(0)
+
+struct stm32_clock_event_ddata {
+ struct clock_event_device evtdev;
+ unsigned periodic_top;
+ void __iomem *base;
+};
+
+static void stm32_clock_event_set_mode(enum clock_event_mode mode,
+ struct clock_event_device *evtdev)
+{
+ struct stm32_clock_event_ddata *data =
+ container_of(evtdev, struct stm32_clock_event_ddata, evtdev);
+ void *base = data->base;
+
+ switch (mode) {
+ case CLOCK_EVT_MODE_PERIODIC:
+ writel_relaxed(data->periodic_top, base + TIM_ARR);
+ writel_relaxed(TIM_CR1_ARPE | TIM_CR1_CEN, base + TIM_CR1);
+ break;
+
+ case CLOCK_EVT_MODE_ONESHOT:
+ default:
+ writel_relaxed(0, base + TIM_CR1);
+ break;
+ }
+}
+
+static int stm32_clock_event_set_next_event(unsigned long evt,
+ struct clock_event_device *evtdev)
+{
+ struct stm32_clock_event_ddata *data =
+ container_of(evtdev, struct stm32_clock_event_ddata, evtdev);
+
+ writel_relaxed(evt, data->base + TIM_ARR);
+ writel_relaxed(TIM_CR1_ARPE | TIM_CR1_OPM | TIM_CR1_CEN,
+ data->base + TIM_CR1);
+
+ return 0;
+}
+
+static irqreturn_t stm32_clock_event_handler(int irq, void *dev_id)
+{
+ struct stm32_clock_event_ddata *data = dev_id;
+
+ writel_relaxed(0, data->base + TIM_SR);
+
+ data->evtdev.event_handler(&data->evtdev);
+
+ return IRQ_HANDLED;
+}
+
+static struct stm32_clock_event_ddata clock_event_ddata = {
+ .evtdev = {
+ .name = "stm32 clockevent",
+ .features = CLOCK_EVT_FEAT_ONESHOT | CLOCK_EVT_FEAT_PERIODIC,
+ .set_mode = stm32_clock_event_set_mode,
+ .set_next_event = stm32_clock_event_set_next_event,
+ .rating = 200,
+ },
+};
+
+static void __init stm32_clockevent_init(struct device_node *np)
+{
+ struct stm32_clock_event_ddata *data = &clock_event_ddata;
+ struct clk *clk;
+ struct reset_control *rstc;
+ unsigned long rate, max_delta;
+ int irq, ret, bits, prescaler = 1;
+
+ clk = of_clk_get(np, 0);
+ if (IS_ERR(clk)) {
+ ret = PTR_ERR(clk);
+ pr_err("failed to get clock for clockevent (%d)\n", ret);
+ goto err_clk_get;
+ }
+
+ ret = clk_prepare_enable(clk);
+ if (ret) {
+ pr_err("failed to enable timer clock for clockevent (%d)\n",
+ ret);
+ goto err_clk_enable;
+ }
+
+ rate = clk_get_rate(clk);
+
+ rstc = of_reset_control_get(np, NULL);
+ if (!IS_ERR(rstc)) {
+ reset_control_assert(rstc);
+ reset_control_deassert(rstc);
+ }
+
+ data->base = of_iomap(np, 0);
+ if (!data->base) {
+ pr_err("failed to map registers for clockevent\n");
+ goto err_iomap;
+ }
+
+ irq = irq_of_parse_and_map(np, 0);
+ if (!irq) {
+ pr_err("%s: failed to get irq.\n", np->full_name);
+ goto err_get_irq;
+ }
+
+ /* Detect whether the timer is 16 or 32 bits */
+ writel_relaxed(~0UL, data->base + TIM_ARR);
+ max_delta = readl_relaxed(data->base + TIM_ARR);
+ if (max_delta == ~0UL) {
+ prescaler = 1;
+ bits = 32;
+ } else {
+ prescaler = 1024;
+ bits = 16;
+ }
+ writel_relaxed(0, data->base + TIM_ARR);
+
+ writel_relaxed(prescaler - 1, data->base + TIM_PSC);
+ writel_relaxed(TIM_EGR_UG, data->base + TIM_EGR);
+ writel_relaxed(TIM_DIER_UIE, data->base + TIM_DIER);
+ writel_relaxed(0, data->base + TIM_SR);
+
+ data->periodic_top = DIV_ROUND_CLOSEST(rate, prescaler * HZ);
+
+ clockevents_config_and_register(&data->evtdev,
+ DIV_ROUND_CLOSEST(rate, prescaler),
+ 0x1, max_delta);
+
+ ret = request_irq(irq, stm32_clock_event_handler, IRQF_TIMER,
+ "stm32 clockevent", data);
+ if (ret) {
+ pr_err("%s: failed to request irq.\n", np->full_name);
+ goto err_get_irq;
+ }
+
+ pr_info("%s: STM32 clockevent driver initialized (%d bits)\n",
+ np->full_name, bits);
+
+ return;
+
+err_get_irq:
+ iounmap(data->base);
+err_iomap:
+ clk_disable_unprepare(clk);
+err_clk_enable:
+ clk_put(clk);
+err_clk_get:
+ return;
+}
+
+CLOCKSOURCE_OF_DECLARE(stm32, "st,stm32-timer", stm32_clockevent_init);
--
1.9.1
^ permalink raw reply related
* [PATCH v4 09/15] dt-bindings: Document the STM32 USART bindings
From: Maxime Coquelin @ 2015-03-31 16:24 UTC (permalink / raw)
To: u.kleine-koenig, afaerber, geert, Rob Herring, Philipp Zabel,
Linus Walleij, Arnd Bergmann, stefan, pmeerw, pebolle, peter,
andy.shevchenko, cw00.choi, Russell King, Daniel Lezcano
Cc: Jonathan Corbet, Pawel Moll, Mark Rutland, Ian Campbell,
Kumar Gala, Thomas Gleixner, Greg Kroah-Hartman, Jiri Slaby,
Andrew Morton, David S. Miller, Mauro Carvalho Chehab,
Joe Perches, Antti Palosaari, Tejun Heo, Will Deacon,
Nikolay Borisov, Rusty Russell, Kees Cook, Michal Marek,
linux-doc, linux-arm-kernel, linux-kernel, devicetree, linux-gpio,
linux-serial
In-Reply-To: <1427819096-31109-1-git-send-email-mcoquelin.stm32@gmail.com>
This adds documentation of device tree bindings for the
STM32 USART
Tested-by: Chanwoo Choi <cw00.choi@samsung.com>
Signed-off-by: Maxime Coquelin <mcoquelin.stm32@gmail.com>
---
.../devicetree/bindings/serial/st,stm32-usart.txt | 32 ++++++++++++++++++++++
1 file changed, 32 insertions(+)
create mode 100644 Documentation/devicetree/bindings/serial/st,stm32-usart.txt
diff --git a/Documentation/devicetree/bindings/serial/st,stm32-usart.txt b/Documentation/devicetree/bindings/serial/st,stm32-usart.txt
new file mode 100644
index 0000000..090a3a4
--- /dev/null
+++ b/Documentation/devicetree/bindings/serial/st,stm32-usart.txt
@@ -0,0 +1,32 @@
+* STMicroelectronics STM32 USART
+
+Required properties:
+- compatible: Can be either "st,stm32-usart" or "st,stm32-uart" depending on
+whether the device supports synchronous mode.
+- reg: The address and length of the peripheral registers space
+- interrupts: The interrupt line of the USART instance
+- clocks: The input clock of the USART instance
+
+Optional properties:
+- pinctrl: The reference on the pins configuration
+- st,hw-flow-ctrl: bool flag to enable hardware flow control.
+
+Examples:
+usart4: serial@40004c00 {
+ compatible = "st,stm32-uart";
+ reg = <0x40004c00 0x400>;
+ interrupts = <52>;
+ clocks = <&clk_pclk1>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usart4>;
+};
+
+usart2: serial@40004400 {
+ compatible = "st,stm32-usart", "st,stm32-uart";
+ reg = <0x40004400 0x400>;
+ interrupts = <38>;
+ clocks = <&clk_pclk1>;
+ st,hw-flow-ctrl;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usart2 &pinctrl_usart2_rtscts>;
+};
--
1.9.1
^ permalink raw reply related
* [PATCH v4 10/15] serial: stm32-usart: Add STM32 USART Driver
From: Maxime Coquelin @ 2015-03-31 16:24 UTC (permalink / raw)
To: u.kleine-koenig, afaerber, geert, Rob Herring, Philipp Zabel,
Linus Walleij, Arnd Bergmann, stefan, pmeerw, pebolle, peter,
andy.shevchenko, cw00.choi, Russell King, Daniel Lezcano
Cc: Jonathan Corbet, Pawel Moll, Mark Rutland, Ian Campbell,
Kumar Gala, Thomas Gleixner, Greg Kroah-Hartman, Jiri Slaby,
Andrew Morton, David S. Miller, Mauro Carvalho Chehab,
Joe Perches, Antti Palosaari, Tejun Heo, Will Deacon,
Nikolay Borisov, Rusty Russell, Kees Cook, Michal Marek,
linux-doc, linux-arm-kernel, linux-kernel, devicetree, linux-gpio,
linux-serial
In-Reply-To: <1427819096-31109-1-git-send-email-mcoquelin.stm32@gmail.com>
This drivers adds support to the STM32 USART controller, which is a
standard serial driver.
Tested-by: Chanwoo Choi <cw00.choi@samsung.com>
Signed-off-by: Maxime Coquelin <mcoquelin.stm32@gmail.com>
---
drivers/tty/serial/Kconfig | 17 +
drivers/tty/serial/Makefile | 1 +
drivers/tty/serial/stm32-usart.c | 743 +++++++++++++++++++++++++++++++++++++++
include/uapi/linux/serial_core.h | 3 +
4 files changed, 764 insertions(+)
create mode 100644 drivers/tty/serial/stm32-usart.c
diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig
index d2501f0..880cb4f 100644
--- a/drivers/tty/serial/Kconfig
+++ b/drivers/tty/serial/Kconfig
@@ -1611,6 +1611,23 @@ config SERIAL_SPRD_CONSOLE
with "earlycon" on the kernel command line. The console is
enabled when early_param is processed.
+config SERIAL_STM32
+ tristate "STMicroelectronics STM32 serial port support"
+ select SERIAL_CORE
+ depends on ARM || COMPILE_TEST
+ help
+ This driver is for the on-chip Serial Controller on
+ STMicroelectronics STM32 MCUs.
+ USART supports Rx & Tx functionality.
+ It support all industry standard baud rates.
+
+ If unsure, say N.
+
+config SERIAL_STM32_CONSOLE
+ bool "Support for console on STM32"
+ depends on SERIAL_STM32=y
+ select SERIAL_CORE_CONSOLE
+
endmenu
config SERIAL_MCTRL_GPIO
diff --git a/drivers/tty/serial/Makefile b/drivers/tty/serial/Makefile
index 599be4b..67c5023 100644
--- a/drivers/tty/serial/Makefile
+++ b/drivers/tty/serial/Makefile
@@ -95,6 +95,7 @@ obj-$(CONFIG_SERIAL_FSL_LPUART) += fsl_lpuart.o
obj-$(CONFIG_SERIAL_CONEXANT_DIGICOLOR) += digicolor-usart.o
obj-$(CONFIG_SERIAL_MEN_Z135) += men_z135_uart.o
obj-$(CONFIG_SERIAL_SPRD) += sprd_serial.o
+obj-$(CONFIG_SERIAL_STM32) += stm32-usart.o
# GPIOLIB helpers for modem control lines
obj-$(CONFIG_SERIAL_MCTRL_GPIO) += serial_mctrl_gpio.o
diff --git a/drivers/tty/serial/stm32-usart.c b/drivers/tty/serial/stm32-usart.c
new file mode 100644
index 0000000..126fbac
--- /dev/null
+++ b/drivers/tty/serial/stm32-usart.c
@@ -0,0 +1,743 @@
+/*
+ * Copyright (C) Maxime Coquelin 2015
+ * Author: Maxime Coquelin <mcoquelin.stm32@gmail.com>
+ * License terms: GNU General Public License (GPL), version 2
+ *
+ * Inspired by st-asc.c from STMicroelectronics (c)
+ */
+
+#if defined(CONFIG_SERIAL_STM32_USART_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
+#define SUPPORT_SYSRQ
+#endif
+
+#include <linux/module.h>
+#include <linux/serial.h>
+#include <linux/console.h>
+#include <linux/sysrq.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/tty.h>
+#include <linux/tty_flip.h>
+#include <linux/delay.h>
+#include <linux/spinlock.h>
+#include <linux/pm_runtime.h>
+#include <linux/of.h>
+#include <linux/of_platform.h>
+#include <linux/serial_core.h>
+#include <linux/clk.h>
+
+#define DRIVER_NAME "stm32-usart"
+
+/* Register offsets */
+#define USART_SR 0x00
+#define USART_DR 0x04
+#define USART_BRR 0x08
+#define USART_CR1 0x0c
+#define USART_CR2 0x10
+#define USART_CR3 0x14
+#define USART_GTPR 0x18
+
+/* USART_SR */
+#define USART_SR_PE BIT(0)
+#define USART_SR_FE BIT(1)
+#define USART_SR_NF BIT(2)
+#define USART_SR_ORE BIT(3)
+#define USART_SR_IDLE BIT(4)
+#define USART_SR_RXNE BIT(5)
+#define USART_SR_TC BIT(6)
+#define USART_SR_TXE BIT(7)
+#define USART_SR_LBD BIT(8)
+#define USART_SR_CTS BIT(9)
+#define USART_SR_ERR_MASK (USART_SR_LBD | USART_SR_ORE | \
+ USART_SR_FE | USART_SR_PE)
+/* Dummy bits */
+#define USART_SR_DUMMY_RX BIT(16)
+
+/* USART_DR */
+#define USART_DR_MASK GENMASK(8, 0)
+
+/* USART_BRR */
+#define USART_BRR_DIV_F_MASK GENMASK(3, 0)
+#define USART_BRR_DIV_M_MASK GENMASK(15, 4)
+#define USART_BRR_DIV_M_SHIFT 4
+
+/* USART_CR1 */
+#define USART_CR1_SBK BIT(0)
+#define USART_CR1_RWU BIT(1)
+#define USART_CR1_RE BIT(2)
+#define USART_CR1_TE BIT(3)
+#define USART_CR1_IDLEIE BIT(4)
+#define USART_CR1_RXNEIE BIT(5)
+#define USART_CR1_TCIE BIT(6)
+#define USART_CR1_TXEIE BIT(7)
+#define USART_CR1_PEIE BIT(8)
+#define USART_CR1_PS BIT(9)
+#define USART_CR1_PCE BIT(10)
+#define USART_CR1_WAKE BIT(11)
+#define USART_CR1_M BIT(12)
+#define USART_CR1_UE BIT(13)
+#define USART_CR1_OVER8 BIT(15)
+#define USART_CR1_IE_MASK GENMASK(8, 4)
+
+/* USART_CR2 */
+#define USART_CR2_ADD_MASK GENMASK(3, 0)
+#define USART_CR2_LBDL BIT(5)
+#define USART_CR2_LBDIE BIT(6)
+#define USART_CR2_LBCL BIT(8)
+#define USART_CR2_CPHA BIT(9)
+#define USART_CR2_CPOL BIT(10)
+#define USART_CR2_CLKEN BIT(11)
+#define USART_CR2_STOP_2B BIT(13)
+#define USART_CR2_STOP_MASK GENMASK(13, 12)
+#define USART_CR2_LINEN BIT(14)
+
+/* USART_CR3 */
+#define USART_CR3_EIE BIT(0)
+#define USART_CR3_IREN BIT(1)
+#define USART_CR3_IRLP BIT(2)
+#define USART_CR3_HDSEL BIT(3)
+#define USART_CR3_NACK BIT(4)
+#define USART_CR3_SCEN BIT(5)
+#define USART_CR3_DMAR BIT(6)
+#define USART_CR3_DMAT BIT(7)
+#define USART_CR3_RTSE BIT(8)
+#define USART_CR3_CTSE BIT(9)
+#define USART_CR3_CTSIE BIT(10)
+#define USART_CR3_ONEBIT BIT(11)
+
+/* USART_GTPR */
+#define USART_GTPR_PSC_MASK GENMASK(7, 0)
+#define USART_GTPR_GT_MASK GENMASK(15, 8)
+
+#define DRIVER_NAME "stm32-usart"
+#define STM32_SERIAL_NAME "ttyS"
+#define STM32_MAX_PORTS 6
+
+struct stm32_port {
+ struct uart_port port;
+ struct clk *clk;
+ bool hw_flow_control;
+};
+
+static struct stm32_port stm32_ports[STM32_MAX_PORTS];
+static struct uart_driver stm32_usart_driver;
+
+static void stm32_stop_tx(struct uart_port *port);
+
+static inline struct stm32_port *to_stm32_port(struct uart_port *port)
+{
+ return container_of(port, struct stm32_port, port);
+}
+
+static void stm32_set_bits(struct uart_port *port, u32 reg, u32 bits)
+{
+ u32 val;
+
+ val = readl_relaxed(port->membase + reg);
+ val |= bits;
+ writel_relaxed(val, port->membase + reg);
+}
+
+static void stm32_clr_bits(struct uart_port *port, u32 reg, u32 bits)
+{
+ u32 val;
+
+ val = readl_relaxed(port->membase + reg);
+ val &= ~bits;
+ writel_relaxed(val, port->membase + reg);
+}
+
+static void stm32_receive_chars(struct uart_port *port)
+{
+ struct tty_port *tport = &port->state->port;
+ unsigned long c;
+ u32 sr;
+ char flag;
+
+ if (port->irq_wake)
+ pm_wakeup_event(tport->tty->dev, 0);
+
+ while ((sr = readl_relaxed(port->membase + USART_SR)) & USART_SR_RXNE) {
+ sr |= USART_SR_DUMMY_RX;
+ c = readl_relaxed(port->membase + USART_DR);
+ flag = TTY_NORMAL;
+ port->icount.rx++;
+
+ if (sr & USART_SR_ERR_MASK) {
+ if (sr & USART_SR_LBD) {
+ port->icount.brk++;
+ if (uart_handle_break(port))
+ continue;
+ } else if (sr & USART_SR_ORE) {
+ port->icount.overrun++;
+ } else if (sr & USART_SR_PE) {
+ port->icount.parity++;
+ } else if (sr & USART_SR_FE) {
+ port->icount.frame++;
+ }
+
+ sr &= port->read_status_mask;
+
+ if (sr & USART_SR_LBD)
+ flag = TTY_BREAK;
+ else if (sr & USART_SR_PE)
+ flag = TTY_PARITY;
+ else if (sr & USART_SR_FE)
+ flag = TTY_FRAME;
+ }
+
+ if (uart_handle_sysrq_char(port, c))
+ continue;
+ uart_insert_char(port, sr, USART_SR_ORE, c, flag);
+ }
+
+ spin_unlock(&port->lock);
+ tty_flip_buffer_push(tport);
+ spin_lock(&port->lock);
+}
+
+static void stm32_transmit_chars(struct uart_port *port)
+{
+ struct circ_buf *xmit = &port->state->xmit;
+
+ if (port->x_char) {
+ writel_relaxed(port->x_char, port->membase + USART_DR);
+ port->x_char = 0;
+ port->icount.tx++;
+ return;
+ }
+
+ if (uart_tx_stopped(port)) {
+ stm32_stop_tx(port);
+ return;
+ }
+
+ if (uart_circ_empty(xmit)) {
+ stm32_stop_tx(port);
+ return;
+ }
+
+ writel_relaxed(xmit->buf[xmit->tail], port->membase + USART_DR);
+ xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
+ port->icount.tx++;
+
+ if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
+ uart_write_wakeup(port);
+
+ if (uart_circ_empty(xmit))
+ stm32_stop_tx(port);
+}
+
+static irqreturn_t stm32_interrupt(int irq, void *ptr)
+{
+ struct uart_port *port = ptr;
+ u32 sr;
+
+ spin_lock(&port->lock);
+
+ sr = readl_relaxed(port->membase + USART_SR);
+
+ if (sr & USART_SR_RXNE)
+ stm32_receive_chars(port);
+
+ if (sr & USART_SR_TXE)
+ stm32_transmit_chars(port);
+
+ spin_unlock(&port->lock);
+
+ return IRQ_HANDLED;
+}
+
+static unsigned int stm32_tx_empty(struct uart_port *port)
+{
+ return readl_relaxed(port->membase + USART_SR) & USART_SR_TXE;
+}
+
+static void stm32_set_mctrl(struct uart_port *port, unsigned int mctrl)
+{
+ if ((mctrl & TIOCM_RTS) && (port->status & UPSTAT_AUTORTS))
+ stm32_set_bits(port, USART_CR3, USART_CR3_RTSE);
+ else
+ stm32_clr_bits(port, USART_CR3, USART_CR3_RTSE);
+}
+
+static unsigned int stm32_get_mctrl(struct uart_port *port)
+{
+ /* This routine is used to get signals of: DCD, DSR, RI, and CTS */
+ return TIOCM_CAR | TIOCM_DSR | TIOCM_CTS;
+}
+
+/* Transmit stop */
+static void stm32_stop_tx(struct uart_port *port)
+{
+ stm32_clr_bits(port, USART_CR1, USART_CR1_TXEIE);
+}
+
+
+/* There are probably characters waiting to be transmitted. */
+static void stm32_start_tx(struct uart_port *port)
+{
+ struct circ_buf *xmit = &port->state->xmit;
+
+ if (uart_circ_empty(xmit))
+ return;
+
+ stm32_set_bits(port, USART_CR1, USART_CR1_TXEIE | USART_CR1_TE);
+}
+
+/* Throttle the remote when input buffer is about to overflow. */
+static void stm32_throttle(struct uart_port *port)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&port->lock, flags);
+ stm32_clr_bits(port, USART_CR1, USART_CR1_RXNEIE);
+ spin_unlock_irqrestore(&port->lock, flags);
+}
+
+/* Unthrottle the remote, the input buffer can now accept data. */
+static void stm32_unthrottle(struct uart_port *port)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&port->lock, flags);
+ stm32_set_bits(port, USART_CR1, USART_CR1_RXNEIE);
+ spin_unlock_irqrestore(&port->lock, flags);
+}
+
+/* Receive stop */
+static void stm32_stop_rx(struct uart_port *port)
+{
+ stm32_clr_bits(port, USART_CR1, USART_CR1_RXNEIE);
+}
+
+/* Handle breaks - ignored by us */
+static void stm32_break_ctl(struct uart_port *port, int break_state)
+{
+ /* Nothing here yet .. */
+}
+
+static int stm32_startup(struct uart_port *port)
+{
+ const char *name = to_platform_device(port->dev)->name;
+ u32 val;
+
+ if (request_irq(port->irq, stm32_interrupt, IRQF_NO_SUSPEND,
+ name, port)) {
+ dev_err(port->dev, "cannot allocate irq %d\n", port->irq);
+ return -ENODEV;
+ }
+
+ val = USART_CR1_RXNEIE | USART_CR1_TE | USART_CR1_RE;
+ stm32_set_bits(port, USART_CR1, val);
+
+ return 0;
+}
+
+static void stm32_shutdown(struct uart_port *port)
+{
+ u32 val;
+
+ val = USART_CR1_TXEIE | USART_CR1_RXNEIE | USART_CR1_TE | USART_CR1_RE;
+ stm32_set_bits(port, USART_CR1, val);
+
+ free_irq(port->irq, port);
+}
+
+static void stm32_set_termios(struct uart_port *port, struct ktermios *termios,
+ struct ktermios *old)
+{
+ struct stm32_port *stm32_port = to_stm32_port(port);
+ unsigned int baud;
+ u32 usartdiv, mantissa, fraction, oversampling;
+ tcflag_t cflag = termios->c_cflag;
+ u32 cr1, cr2, cr3;
+ unsigned long flags;
+
+ if (!stm32_port->hw_flow_control)
+ cflag &= ~CRTSCTS;
+
+ baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk / 8);
+
+ spin_lock_irqsave(&port->lock, flags);
+
+ /* Stop serial port and reset value */
+ writel_relaxed(0, port->membase + USART_CR1);
+
+ cr1 = USART_CR1_TE | USART_CR1_RE | USART_CR1_UE | USART_CR1_RXNEIE;
+
+ if (cflag & CSTOPB)
+ cr2 = USART_CR2_STOP_2B;
+
+ if (cflag & PARENB) {
+ cr1 |= USART_CR1_PCE;
+ if ((cflag & CSIZE) == CS8)
+ cr1 |= USART_CR1_M;
+ }
+
+ if (cflag & PARODD)
+ cr1 |= USART_CR1_PS;
+
+ port->status &= ~(UPSTAT_AUTOCTS | UPSTAT_AUTORTS);
+ if (cflag & CRTSCTS) {
+ port->status |= UPSTAT_AUTOCTS | UPSTAT_AUTORTS;
+ cr3 = USART_CR3_CTSE;
+ }
+
+ usartdiv = DIV_ROUND_CLOSEST(port->uartclk, baud);
+
+ /*
+ * The USART supports 16 or 8 times oversampling.
+ * By default we prefer 16 times oversampling, so that the receiver
+ * has a better tolerance to clock deviations.
+ * 8 times oversampling is only used to achieve higher speeds.
+ */
+ if (usartdiv < 16) {
+ oversampling = 8;
+ stm32_set_bits(port, USART_CR1, USART_CR1_OVER8);
+ } else {
+ oversampling = 16;
+ stm32_clr_bits(port, USART_CR1, USART_CR1_OVER8);
+ }
+
+ mantissa = (usartdiv / oversampling) << USART_BRR_DIV_M_SHIFT;
+ fraction = usartdiv % oversampling;
+ writel_relaxed(mantissa | fraction, port->membase + USART_BRR);
+
+ uart_update_timeout(port, cflag, baud);
+
+ port->read_status_mask = USART_SR_ORE;
+ if (termios->c_iflag & INPCK)
+ port->read_status_mask |= USART_SR_PE | USART_SR_FE;
+ if (termios->c_iflag & (IGNBRK | BRKINT | PARMRK))
+ port->read_status_mask |= USART_SR_LBD;
+
+ /* Characters to ignore */
+ port->ignore_status_mask = 0;
+ if (termios->c_iflag & IGNPAR)
+ port->ignore_status_mask = USART_SR_PE | USART_SR_FE;
+ if (termios->c_iflag & IGNBRK) {
+ port->ignore_status_mask |= USART_SR_LBD;
+ /*
+ * If we're ignoring parity and break indicators,
+ * ignore overruns too (for real raw support).
+ */
+ if (termios->c_iflag & IGNPAR)
+ port->ignore_status_mask |= USART_SR_ORE;
+ }
+
+ /*
+ * Ignore all characters if CREAD is not set.
+ */
+ if ((termios->c_cflag & CREAD) == 0)
+ port->ignore_status_mask |= USART_SR_DUMMY_RX;
+
+ writel_relaxed(cr3, port->membase + USART_CR3);
+ writel_relaxed(cr2, port->membase + USART_CR2);
+ writel_relaxed(cr1, port->membase + USART_CR1);
+
+ spin_unlock_irqrestore(&port->lock, flags);
+}
+
+static const char *stm32_type(struct uart_port *port)
+{
+ return (port->type == PORT_STM32) ? DRIVER_NAME : NULL;
+}
+
+static void stm32_release_port(struct uart_port *port)
+{
+}
+
+static int stm32_request_port(struct uart_port *port)
+{
+ return 0;
+}
+
+static void stm32_config_port(struct uart_port *port, int flags)
+{
+ if (flags & UART_CONFIG_TYPE)
+ port->type = PORT_STM32;
+}
+
+static int
+stm32_verify_port(struct uart_port *port, struct serial_struct *ser)
+{
+ /* No user changeable parameters */
+ return -EINVAL;
+}
+
+static void stm32_pm(struct uart_port *port, unsigned int state,
+ unsigned int oldstate)
+{
+ struct stm32_port *stm32port = container_of(port,
+ struct stm32_port, port);
+ unsigned long flags = 0;
+
+ switch (state) {
+ case UART_PM_STATE_ON:
+ clk_prepare_enable(stm32port->clk);
+ break;
+ case UART_PM_STATE_OFF:
+ spin_lock_irqsave(&port->lock, flags);
+ stm32_clr_bits(port, USART_CR1, USART_CR1_UE);
+ spin_unlock_irqrestore(&port->lock, flags);
+ clk_disable_unprepare(stm32port->clk);
+ break;
+ }
+}
+
+static struct uart_ops stm32_uart_ops = {
+ .tx_empty = stm32_tx_empty,
+ .set_mctrl = stm32_set_mctrl,
+ .get_mctrl = stm32_get_mctrl,
+ .stop_tx = stm32_stop_tx,
+ .start_tx = stm32_start_tx,
+ .throttle = stm32_throttle,
+ .unthrottle = stm32_unthrottle,
+ .stop_rx = stm32_stop_rx,
+ .break_ctl = stm32_break_ctl,
+ .startup = stm32_startup,
+ .shutdown = stm32_shutdown,
+ .set_termios = stm32_set_termios,
+ .pm = stm32_pm,
+ .type = stm32_type,
+ .release_port = stm32_release_port,
+ .request_port = stm32_request_port,
+ .config_port = stm32_config_port,
+ .verify_port = stm32_verify_port,
+};
+
+static int stm32_init_port(struct stm32_port *stm32port,
+ struct platform_device *pdev)
+{
+ struct uart_port *port = &stm32port->port;
+ struct resource *res;
+ int ret;
+
+ port->iotype = UPIO_MEM;
+ port->flags = UPF_BOOT_AUTOCONF;
+ port->ops = &stm32_uart_ops;
+ port->dev = &pdev->dev;
+ port->irq = platform_get_irq(pdev, 0);
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ port->membase = devm_ioremap_resource(&pdev->dev, res);
+ if (IS_ERR(port->membase))
+ return PTR_ERR(port->membase);
+ port->mapbase = res->start;
+
+ spin_lock_init(&port->lock);
+
+ stm32port->clk = devm_clk_get(&pdev->dev, NULL);
+ if (IS_ERR(stm32port->clk))
+ return PTR_ERR(stm32port->clk);
+
+ /* Ensure that clk rate is correct by enabling the clk */
+ ret = clk_prepare_enable(stm32port->clk);
+ if (ret)
+ return ret;
+
+ stm32port->port.uartclk = clk_get_rate(stm32port->clk);
+ if (!stm32port->port.uartclk)
+ ret = -EINVAL;
+
+ clk_disable_unprepare(stm32port->clk);
+
+ return ret;
+}
+
+static struct stm32_port *stm32_of_get_stm32_port(struct platform_device *pdev)
+{
+ struct device_node *np = pdev->dev.of_node;
+ int id;
+
+ if (!np)
+ return NULL;
+
+ id = of_alias_get_id(np, "serial");
+
+ if (id < 0)
+ id = 0;
+
+ if (WARN_ON(id >= STM32_MAX_PORTS))
+ return NULL;
+
+ stm32_ports[id].hw_flow_control = of_property_read_bool(np,
+ "st,hw-flow-control");
+ stm32_ports[id].port.line = id;
+ return &stm32_ports[id];
+}
+
+#ifdef CONFIG_OF
+static const struct of_device_id stm32_match[] = {
+ { .compatible = "st,stm32-usart", },
+ { .compatible = "st,stm32-uart", },
+ {},
+};
+
+MODULE_DEVICE_TABLE(of, stm32_match);
+#endif
+
+static int stm32_serial_probe(struct platform_device *pdev)
+{
+ int ret;
+ struct stm32_port *stm32port;
+
+ stm32port = stm32_of_get_stm32_port(pdev);
+ if (!stm32port)
+ return -ENODEV;
+
+ ret = stm32_init_port(stm32port, pdev);
+ if (ret)
+ return ret;
+
+ ret = uart_add_one_port(&stm32_usart_driver, &stm32port->port);
+ if (ret)
+ return ret;
+
+ platform_set_drvdata(pdev, &stm32port->port);
+
+ return 0;
+}
+
+static int stm32_serial_remove(struct platform_device *pdev)
+{
+ struct uart_port *port = platform_get_drvdata(pdev);
+
+ return uart_remove_one_port(&stm32_usart_driver, port);
+}
+
+
+#ifdef CONFIG_SERIAL_STM32_CONSOLE
+static void stm32_console_putchar(struct uart_port *port, int ch)
+{
+ while (!(readl_relaxed(port->membase + USART_SR) & USART_SR_TXE))
+ cpu_relax();
+
+ writel_relaxed(ch, port->membase + USART_DR);
+}
+
+static void stm32_console_write(struct console *co, const char *s, unsigned cnt)
+{
+ struct uart_port *port = &stm32_ports[co->index].port;
+ unsigned long flags;
+ u32 old_cr1, new_cr1;
+ int locked = 1;
+
+ if (oops_in_progress) {
+ locked = spin_trylock_irqsave(&port->lock, flags);
+ } else {
+ locked = 1;
+ spin_lock_irqsave(&port->lock, flags);
+ }
+
+ /* Save and disable interrupts */
+ old_cr1 = readl_relaxed(port->membase + USART_CR1);
+ new_cr1 = old_cr1 & ~USART_CR1_IE_MASK;
+ writel_relaxed(new_cr1, port->membase + USART_CR1);
+
+ uart_console_write(port, s, cnt, stm32_console_putchar);
+
+ /* Restore interrupt state */
+ writel_relaxed(old_cr1, port->membase + USART_CR1);
+
+ if (locked)
+ spin_unlock_irqrestore(&port->lock, flags);
+}
+
+static int stm32_console_setup(struct console *co, char *options)
+{
+ struct stm32_port *stm32port;
+ int baud = 9600;
+ int bits = 8;
+ int parity = 'n';
+ int flow = 'n';
+
+ if (co->index >= STM32_MAX_PORTS)
+ return -ENODEV;
+
+ stm32port = &stm32_ports[co->index];
+
+ /*
+ * This driver does not support early console initialization
+ * (use ARM early printk support instead), so we only expect
+ * this to be called during the uart port registration when the
+ * driver gets probed and the port should be mapped at that point.
+ */
+ if (stm32port->port.mapbase == 0 || stm32port->port.membase == NULL)
+ return -ENXIO;
+
+ if (options)
+ uart_parse_options(options, &baud, &parity, &bits, &flow);
+
+ return uart_set_options(&stm32port->port, co, baud, parity, bits, flow);
+}
+
+static struct console stm32_console = {
+ .name = STM32_SERIAL_NAME,
+ .device = uart_console_device,
+ .write = stm32_console_write,
+ .setup = stm32_console_setup,
+ .flags = CON_PRINTBUFFER,
+ .index = -1,
+ .data = &stm32_usart_driver,
+};
+
+#define STM32_SERIAL_CONSOLE (&stm32_console)
+
+#else
+#define STM32_SERIAL_CONSOLE NULL
+#endif /* CONFIG_SERIAL_STM32_CONSOLE */
+
+static struct uart_driver stm32_usart_driver = {
+ .owner = THIS_MODULE,
+ .driver_name = DRIVER_NAME,
+ .dev_name = STM32_SERIAL_NAME,
+ .major = 0,
+ .minor = 0,
+ .nr = STM32_MAX_PORTS,
+ .cons = STM32_SERIAL_CONSOLE,
+};
+
+static struct platform_driver stm32_serial_driver = {
+ .probe = stm32_serial_probe,
+ .remove = stm32_serial_remove,
+ .driver = {
+ .name = DRIVER_NAME,
+ .owner = THIS_MODULE,
+ .of_match_table = of_match_ptr(stm32_match),
+ },
+};
+
+static int __init usart_init(void)
+{
+ int ret;
+ static char banner[] __initdata =
+ KERN_INFO "STM32 USART driver initialized\n";
+
+ printk(banner);
+
+ ret = uart_register_driver(&stm32_usart_driver);
+ if (ret)
+ return ret;
+
+ ret = platform_driver_register(&stm32_serial_driver);
+ if (ret)
+ uart_unregister_driver(&stm32_usart_driver);
+
+ return ret;
+}
+
+static void __exit usart_exit(void)
+{
+ platform_driver_unregister(&stm32_serial_driver);
+ uart_unregister_driver(&stm32_usart_driver);
+}
+
+module_init(usart_init);
+module_exit(usart_exit);
+
+MODULE_ALIAS("platform:" DRIVER_NAME);
+MODULE_DESCRIPTION("STMicroelectronics STM32 serial port driver");
+MODULE_LICENSE("GPL v2");
diff --git a/include/uapi/linux/serial_core.h b/include/uapi/linux/serial_core.h
index b212281..93ba148 100644
--- a/include/uapi/linux/serial_core.h
+++ b/include/uapi/linux/serial_core.h
@@ -258,4 +258,7 @@
/* Cris v10 / v32 SoC */
#define PORT_CRIS 112
+/* STM32 USART */
+#define PORT_STM32 113
+
#endif /* _UAPILINUX_SERIAL_CORE_H */
--
1.9.1
^ permalink raw reply related
* [PATCH v4 11/15] ARM: Add STM32 family machine
From: Maxime Coquelin @ 2015-03-31 16:24 UTC (permalink / raw)
To: u.kleine-koenig, afaerber, geert, Rob Herring, Philipp Zabel,
Linus Walleij, Arnd Bergmann, stefan, pmeerw, pebolle, peter,
andy.shevchenko, cw00.choi, Russell King, Daniel Lezcano
Cc: Jonathan Corbet, Pawel Moll, Mark Rutland, Ian Campbell,
Kumar Gala, Thomas Gleixner, Greg Kroah-Hartman, Jiri Slaby,
Andrew Morton, David S. Miller, Mauro Carvalho Chehab,
Joe Perches, Antti Palosaari, Tejun Heo, Will Deacon,
Nikolay Borisov, Rusty Russell, Kees Cook, Michal Marek,
linux-doc, linux-arm-kernel, linux-kernel, devicetree, linux-gpio,
linux-serial
In-Reply-To: <1427819096-31109-1-git-send-email-mcoquelin.stm32@gmail.com>
STMicrolectronics's STM32 series is a family of Cortex-M
microcontrollers. It is used in various applications, and
proposes a wide range of peripherals.
Tested-by: Chanwoo Choi <cw00.choi@samsung.com>
Signed-off-by: Maxime Coquelin <mcoquelin.stm32@gmail.com>
---
Documentation/arm/stm32/overview.txt | 32 ++++++++++++++++++++++++++
Documentation/arm/stm32/stm32f429-overview.txt | 22 ++++++++++++++++++
arch/arm/Kconfig | 18 +++++++++++++++
arch/arm/Makefile | 1 +
arch/arm/mach-stm32/Makefile | 1 +
arch/arm/mach-stm32/Makefile.boot | 3 +++
arch/arm/mach-stm32/board-dt.c | 19 +++++++++++++++
7 files changed, 96 insertions(+)
create mode 100644 Documentation/arm/stm32/overview.txt
create mode 100644 Documentation/arm/stm32/stm32f429-overview.txt
create mode 100644 arch/arm/mach-stm32/Makefile
create mode 100644 arch/arm/mach-stm32/Makefile.boot
create mode 100644 arch/arm/mach-stm32/board-dt.c
diff --git a/Documentation/arm/stm32/overview.txt b/Documentation/arm/stm32/overview.txt
new file mode 100644
index 0000000..09aed55
--- /dev/null
+++ b/Documentation/arm/stm32/overview.txt
@@ -0,0 +1,32 @@
+ STM32 ARM Linux Overview
+ ========================
+
+Introduction
+------------
+
+ The STMicroelectronics family of Cortex-M based MCUs are supported by the
+ 'STM32' platform of ARM Linux. Currently only the STM32F429 is supported.
+
+
+Configuration
+-------------
+
+ A generic configuration is provided for STM32 family, and can be used as the
+ default by
+ make stm32_defconfig
+
+Layout
+------
+
+ All the files for multiple machine families are located in the platform code
+ contained in arch/arm/mach-stm32
+
+ There is a generic board board-dt.c in the mach folder which support
+ Flattened Device Tree, which means, it works with any compatible board with
+ Device Trees.
+
+
+Document Author
+---------------
+
+ Maxime Coquelin <mcoquelin.stm32@gmail.com>
diff --git a/Documentation/arm/stm32/stm32f429-overview.txt b/Documentation/arm/stm32/stm32f429-overview.txt
new file mode 100644
index 0000000..5206822
--- /dev/null
+++ b/Documentation/arm/stm32/stm32f429-overview.txt
@@ -0,0 +1,22 @@
+ STM32F429 Overview
+ ==================
+
+ Introduction
+ ------------
+ The STM32F429 is a Cortex-M4 MCU aimed at various applications.
+ It features:
+ - ARM Cortex-M4 up to 180MHz with FPU
+ - 2MB internal Flash Memory
+ - External memory support through FMC controller (PSRAM, SDRAM, NOR, NAND)
+ - I2C, SPI, SAI, CAN, USB OTG, Ethernet controllers
+ - LCD controller & Camera interface
+ - Cryptographic processor
+
+ Resources
+ ---------
+ Datasheet and reference manual are publicly available on ST website:
+ - http://www.st.com/web/en/catalog/mmc/FM141/SC1169/SS1577/LN1806?ecmp=stm32f429-439_pron_pr-ces2014_nov2013
+
+ Document Author
+ ---------------
+ Maxime Coquelin <mcoquelin.stm32@gmail.com>
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 9f1f09a..5b1157d 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -776,6 +776,24 @@ config ARCH_OMAP1
help
Support for older TI OMAP1 (omap7xx, omap15xx or omap16xx)
+config ARCH_STM32
+ bool "STMicrolectronics STM32"
+ depends on !MMU
+ select ARCH_HAS_RESET_CONTROLLER
+ select ARM_NVIC
+ select ARMV7M_SYSTICK
+ select AUTO_ZRELADDR
+ select CLKSRC_OF
+ select COMMON_CLK
+ select CPU_V7M
+ select GENERIC_CLOCKEVENTS
+ select NO_IOPORT_MAP
+ select RESET_CONTROLLER
+ select SPARSE_IRQ
+ select USE_OF
+ help
+ Support for STMicroelectronics STM32 processors.
+
endchoice
menu "Multiple platform selection"
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index 7f99cd6..982c104 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -196,6 +196,7 @@ machine-$(CONFIG_ARCH_SHMOBILE) += shmobile
machine-$(CONFIG_ARCH_SIRF) += prima2
machine-$(CONFIG_ARCH_SOCFPGA) += socfpga
machine-$(CONFIG_ARCH_STI) += sti
+machine-$(CONFIG_ARCH_STM32) += stm32
machine-$(CONFIG_ARCH_SUNXI) += sunxi
machine-$(CONFIG_ARCH_TEGRA) += tegra
machine-$(CONFIG_ARCH_U300) += u300
diff --git a/arch/arm/mach-stm32/Makefile b/arch/arm/mach-stm32/Makefile
new file mode 100644
index 0000000..bd0b7b5
--- /dev/null
+++ b/arch/arm/mach-stm32/Makefile
@@ -0,0 +1 @@
+obj-y += board-dt.o
diff --git a/arch/arm/mach-stm32/Makefile.boot b/arch/arm/mach-stm32/Makefile.boot
new file mode 100644
index 0000000..eacfc3f
--- /dev/null
+++ b/arch/arm/mach-stm32/Makefile.boot
@@ -0,0 +1,3 @@
+# Empty file waiting for deletion once Makefile.boot isn't needed any more.
+# Patch waits for application at
+# http://www.arm.linux.org.uk/developer/patches/viewpatch.php?id=7889/1 .
diff --git a/arch/arm/mach-stm32/board-dt.c b/arch/arm/mach-stm32/board-dt.c
new file mode 100644
index 0000000..f2ad772
--- /dev/null
+++ b/arch/arm/mach-stm32/board-dt.c
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) Maxime Coquelin 2015
+ * Author: Maxime Coquelin <mcoquelin.stm32@gmail.com>
+ * License terms: GNU General Public License (GPL), version 2
+ */
+
+#include <linux/kernel.h>
+#include <asm/v7m.h>
+#include <asm/mach/arch.h>
+
+static const char *const stm32_compat[] __initconst = {
+ "st,stm32f429",
+ NULL
+};
+
+DT_MACHINE_START(STM32DT, "STM32 (Device Tree Support)")
+ .dt_compat = stm32_compat,
+ .restart = armv7m_restart,
+MACHINE_END
--
1.9.1
^ permalink raw reply related
* [PATCH v4 12/15] ARM: dts: Add ARM System timer as clockevent in armv7m
From: Maxime Coquelin @ 2015-03-31 16:24 UTC (permalink / raw)
To: u.kleine-koenig, afaerber, geert, Rob Herring, Philipp Zabel,
Linus Walleij, Arnd Bergmann, stefan, pmeerw, pebolle, peter,
andy.shevchenko, cw00.choi, Russell King, Daniel Lezcano
Cc: Jonathan Corbet, Pawel Moll, Mark Rutland, Ian Campbell,
Kumar Gala, Thomas Gleixner, Greg Kroah-Hartman, Jiri Slaby,
Andrew Morton, David S. Miller, Mauro Carvalho Chehab,
Joe Perches, Antti Palosaari, Tejun Heo, Will Deacon,
Nikolay Borisov, Rusty Russell, Kees Cook, Michal Marek,
linux-doc, linux-arm-kernel, linux-kernel, devicetree, linux-gpio,
linux-serial
In-Reply-To: <1427819096-31109-1-git-send-email-mcoquelin.stm32@gmail.com>
Tested-by: Chanwoo Choi <cw00.choi@samsung.com>
Signed-off-by: Maxime Coquelin <mcoquelin.stm32@gmail.com>
---
arch/arm/boot/dts/armv7-m.dtsi | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/arch/arm/boot/dts/armv7-m.dtsi b/arch/arm/boot/dts/armv7-m.dtsi
index 5a660d0..b1ad7cf 100644
--- a/arch/arm/boot/dts/armv7-m.dtsi
+++ b/arch/arm/boot/dts/armv7-m.dtsi
@@ -8,6 +8,12 @@
reg = <0xe000e100 0xc00>;
};
+ systick: timer@e000e010 {
+ compatible = "arm,armv7m-systick";
+ reg = <0xe000e010 0x10>;
+ status = "disabled";
+ };
+
soc {
#address-cells = <1>;
#size-cells = <1>;
--
1.9.1
^ permalink raw reply related
* [PATCH v4 13/15] ARM: dts: Introduce STM32F429 MCU
From: Maxime Coquelin @ 2015-03-31 16:24 UTC (permalink / raw)
To: u.kleine-koenig, afaerber, geert, Rob Herring, Philipp Zabel,
Linus Walleij, Arnd Bergmann, stefan, pmeerw, pebolle, peter,
andy.shevchenko, cw00.choi, Russell King, Daniel Lezcano
Cc: Jonathan Corbet, Pawel Moll, Mark Rutland, Ian Campbell,
Kumar Gala, Thomas Gleixner, Greg Kroah-Hartman, Jiri Slaby,
Andrew Morton, David S. Miller, Mauro Carvalho Chehab,
Joe Perches, Antti Palosaari, Tejun Heo, Will Deacon,
Nikolay Borisov, Rusty Russell, Kees Cook, Michal Marek,
linux-doc, linux-arm-kernel, linux-kernel, devicetree, linux-gpio,
linux-serial
In-Reply-To: <1427819096-31109-1-git-send-email-mcoquelin.stm32@gmail.com>
The STMicrolectornics's STM32F419 MCU has the following main features:
- Cortex-M4 core running up to @180MHz
- 2MB internal flash, 256KBytes internal RAM
- FMC controller to connect SDRAM, NOR and NAND memories
- SD/MMC/SDIO support
- Ethernet controller
- USB OTFG FS & HS controllers
- I2C, SPI, CAN busses support
- Several 16 & 32 bits general purpose timers
- Serial Audio interface
- LCD controller
Tested-by: Chanwoo Choi <cw00.choi@samsung.com>
Signed-off-by: Maxime Coquelin <mcoquelin.stm32@gmail.com>
---
arch/arm/boot/dts/Makefile | 1 +
arch/arm/boot/dts/stm32f429-disco.dts | 71 +++++++++++
arch/arm/boot/dts/stm32f429.dtsi | 226 ++++++++++++++++++++++++++++++++++
3 files changed, 298 insertions(+)
create mode 100644 arch/arm/boot/dts/stm32f429-disco.dts
create mode 100644 arch/arm/boot/dts/stm32f429.dtsi
diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index a1c776b..e5dbd03 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -509,6 +509,7 @@ dtb-$(CONFIG_ARCH_STI) += \
stih416-b2020.dtb \
stih416-b2020e.dtb \
stih418-b2199.dtb
+dtb-$(CONFIG_ARCH_STM32)+= stm32f429-disco.dtb
dtb-$(CONFIG_MACH_SUN4I) += \
sun4i-a10-a1000.dtb \
sun4i-a10-ba10-tvbox.dtb \
diff --git a/arch/arm/boot/dts/stm32f429-disco.dts b/arch/arm/boot/dts/stm32f429-disco.dts
new file mode 100644
index 0000000..6b9aa59
--- /dev/null
+++ b/arch/arm/boot/dts/stm32f429-disco.dts
@@ -0,0 +1,71 @@
+/*
+ * Copyright 2015 - Maxime Coquelin <mcoquelin.stm32@gmail.com>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) This file is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This file is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this file; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ *
+ * Or, alternatively,
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/dts-v1/;
+#include "stm32f429.dtsi"
+
+/ {
+ model = "STMicroelectronics STM32F429i-DISCO board";
+ compatible = "st,stm32f429i-disco", "st,stm32f429";
+
+ chosen {
+ bootargs = "console=ttyS0,115200 root=/dev/ram rdinit=/linuxrc";
+ linux,stdout-path = &usart1;
+ };
+
+ memory {
+ reg = <0x90000000 0x800000>;
+ };
+
+ aliases {
+ serial0 = &usart1;
+ };
+};
+
+&usart1 {
+ status = "okay";
+};
diff --git a/arch/arm/boot/dts/stm32f429.dtsi b/arch/arm/boot/dts/stm32f429.dtsi
new file mode 100644
index 0000000..39ffdb8
--- /dev/null
+++ b/arch/arm/boot/dts/stm32f429.dtsi
@@ -0,0 +1,226 @@
+/*
+ * Copyright 2015 - Maxime Coquelin <mcoquelin.stm32@gmail.com>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ * a) This file is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This file is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this file; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ *
+ * Or, alternatively,
+ *
+ * b) Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "armv7-m.dtsi"
+
+/ {
+ clocks {
+ clk_sysclk: clk-sysclk {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <180000000>;
+ };
+
+ clk_hclk: clk-hclk {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <180000000>;
+ };
+
+ clk_pclk1: clk-pclk1 {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <45000000>;
+ };
+
+ clk_pclk2: clk-pclk2 {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <90000000>;
+ };
+
+ clk_pmtr1: clk-pmtr1 {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <90000000>;
+ };
+
+ clk_pmtr2: clk-pmtr2 {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <180000000>;
+ };
+
+ clk_systick: clk-systick {
+ compatible = "fixed-factor-clock";
+ clocks = <&clk_hclk>;
+ #clock-cells = <0>;
+ clock-div = <8>;
+ clock-mult = <1>;
+ };
+ };
+
+ soc {
+ timer2: timer@40000000 {
+ compatible = "st,stm32-timer";
+ reg = <0x40000000 0x400>;
+ interrupts = <28>;
+ resets = <&rcc 256>;
+ clocks = <&clk_pmtr1>;
+ status = "disabled";
+ };
+
+ timer3: timer@40000400 {
+ compatible = "st,stm32-timer";
+ reg = <0x40000400 0x400>;
+ interrupts = <29>;
+ resets = <&rcc 257>;
+ clocks = <&clk_pmtr1>;
+ status = "disabled";
+ };
+
+ timer4: timer@40000800 {
+ compatible = "st,stm32-timer";
+ reg = <0x40000800 0x400>;
+ interrupts = <30>;
+ resets = <&rcc 258>;
+ clocks = <&clk_pmtr1>;
+ status = "disabled";
+ };
+
+ timer5: timer@40000c00 {
+ compatible = "st,stm32-timer";
+ reg = <0x40000c00 0x400>;
+ interrupts = <50>;
+ resets = <&rcc 259>;
+ clocks = <&clk_pmtr1>;
+ };
+
+ timer6: timer@40001000 {
+ compatible = "st,stm32-timer";
+ reg = <0x40001000 0x400>;
+ interrupts = <54>;
+ resets = <&rcc 260>;
+ clocks = <&clk_pmtr1>;
+ status = "disabled";
+ };
+
+ timer7: timer@40001400 {
+ compatible = "st,stm32-timer";
+ reg = <0x40001400 0x400>;
+ interrupts = <55>;
+ resets = <&rcc 261>;
+ clocks = <&clk_pmtr1>;
+ status = "disabled";
+ };
+
+ usart2: serial@40004400 {
+ compatible = "st,stm32-usart", "st,stm32-uart";
+ reg = <0x40004400 0x400>;
+ interrupts = <38>;
+ clocks = <&clk_pclk1>;
+ status = "disabled";
+ };
+
+ usart3: serial@40004800 {
+ compatible = "st,stm32-usart", "st,stm32-uart";
+ reg = <0x40004800 0x400>;
+ interrupts = <39>;
+ clocks = <&clk_pclk1>;
+ status = "disabled";
+ };
+
+ usart4: serial@40004c00 {
+ compatible = "st,stm32-uart";
+ reg = <0x40004c00 0x400>;
+ interrupts = <52>;
+ clocks = <&clk_pclk1>;
+ status = "disabled";
+ };
+
+ usart5: serial@40005000 {
+ compatible = "st,stm32-uart";
+ reg = <0x40005000 0x400>;
+ interrupts = <53>;
+ clocks = <&clk_pclk1>;
+ status = "disabled";
+ };
+
+ usart7: serial@40007800 {
+ compatible = "st,stm32-usart", "st,stm32-uart";
+ reg = <0x40007800 0x400>;
+ interrupts = <82>;
+ clocks = <&clk_pclk1>;
+ status = "disabled";
+ };
+
+ usart8: serial@40007c00 {
+ compatible = "st,stm32-usart", "st,stm32-uart";
+ reg = <0x40007c00 0x400>;
+ interrupts = <83>;
+ clocks = <&clk_pclk1>;
+ status = "disabled";
+ };
+
+ usart1: serial@40011000 {
+ compatible = "st,stm32-usart", "st,stm32-uart";
+ reg = <0x40011000 0x400>;
+ interrupts = <37>;
+ clocks = <&clk_pclk2>;
+ status = "disabled";
+ };
+
+ usart6: serial@40011400 {
+ compatible = "st,stm32-usart", "st,stm32-uart";
+ reg = <0x40011400 0x400>;
+ interrupts = <71>;
+ clocks = <&clk_pclk2>;
+ status = "disabled";
+ };
+
+ rcc: rcc@40023810 {
+ #reset-cells = <1>;
+ compatible = "st,stm32-rcc";
+ reg = <0x40023800 0x400>;
+ };
+ };
+};
+
+&systick {
+ clocks = <&clk_systick>;
+ status = "okay";
+};
--
1.9.1
^ permalink raw reply related
* [PATCH v4 14/15] ARM: configs: Add STM32 defconfig
From: Maxime Coquelin @ 2015-03-31 16:24 UTC (permalink / raw)
To: u.kleine-koenig, afaerber, geert, Rob Herring, Philipp Zabel,
Linus Walleij, Arnd Bergmann, stefan, pmeerw, pebolle, peter,
andy.shevchenko, cw00.choi, Russell King, Daniel Lezcano
Cc: Jonathan Corbet, Pawel Moll, Mark Rutland, Ian Campbell,
Kumar Gala, Thomas Gleixner, Greg Kroah-Hartman, Jiri Slaby,
Andrew Morton, David S. Miller, Mauro Carvalho Chehab,
Joe Perches, Antti Palosaari, Tejun Heo, Will Deacon,
Nikolay Borisov, Rusty Russell, Kees Cook, Michal Marek,
linux-doc, linux-arm-kernel, linux-kernel, devicetree, linux-gpio,
linux-serial
In-Reply-To: <1427819096-31109-1-git-send-email-mcoquelin.stm32@gmail.com>
This patch adds a new config for STM32 MCUs.
STM32F429 Discovery board boots successfully with this config applied.
Tested-by: Chanwoo Choi <cw00.choi@samsung.com>
Signed-off-by: Maxime Coquelin <mcoquelin.stm32@gmail.com>
---
arch/arm/configs/stm32_defconfig | 71 ++++++++++++++++++++++++++++++++++++++++
1 file changed, 71 insertions(+)
create mode 100644 arch/arm/configs/stm32_defconfig
diff --git a/arch/arm/configs/stm32_defconfig b/arch/arm/configs/stm32_defconfig
new file mode 100644
index 0000000..412a9f9
--- /dev/null
+++ b/arch/arm/configs/stm32_defconfig
@@ -0,0 +1,71 @@
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_LOG_BUF_SHIFT=16
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE="./rootfs.cpio"
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+# CONFIG_UID16 is not set
+# CONFIG_BASE_FULL is not set
+# CONFIG_FUTEX is not set
+# CONFIG_EPOLL is not set
+# CONFIG_SIGNALFD is not set
+# CONFIG_EVENTFD is not set
+# CONFIG_AIO is not set
+CONFIG_EMBEDDED=y
+# CONFIG_VM_EVENT_COUNTERS is not set
+# CONFIG_SLUB_DEBUG is not set
+# CONFIG_LBDAF is not set
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_IOSCHED_DEADLINE is not set
+# CONFIG_IOSCHED_CFQ is not set
+# CONFIG_MMU is not set
+CONFIG_ARCH_STM32=y
+CONFIG_SET_MEM_PARAM=y
+CONFIG_DRAM_BASE=0x90000000
+CONFIG_FLASH_MEM_BASE=0x08000000
+CONFIG_FLASH_SIZE=0x00200000
+CONFIG_PREEMPT=y
+# CONFIG_ATAGS is not set
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_XIP_KERNEL=y
+CONFIG_XIP_PHYS_ADDR=0x08008000
+CONFIG_BINFMT_FLAT=y
+CONFIG_BINFMT_SHARED_FLAT=y
+# CONFIG_COREDUMP is not set
+CONFIG_DEVTMPFS=y
+CONFIG_DEVTMPFS_MOUNT=y
+# CONFIG_FW_LOADER is not set
+# CONFIG_BLK_DEV is not set
+CONFIG_EEPROM_93CX6=y
+# CONFIG_INPUT is not set
+# CONFIG_SERIO is not set
+# CONFIG_VT is not set
+# CONFIG_UNIX98_PTYS is not set
+# CONFIG_LEGACY_PTYS is not set
+CONFIG_SERIAL_NONSTANDARD=y
+# CONFIG_DEVKMEM is not set
+CONFIG_SERIAL_STM32=y
+CONFIG_SERIAL_STM32_CONSOLE=y
+# CONFIG_HW_RANDOM is not set
+CONFIG_GPIO_SYSFS=y
+# CONFIG_HWMON is not set
+CONFIG_USB=y
+CONFIG_USB_DWC2=y
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+CONFIG_LEDS_GPIO=y
+CONFIG_LEDS_TRIGGERS=y
+CONFIG_LEDS_TRIGGER_HEARTBEAT=y
+# CONFIG_FILE_LOCKING is not set
+# CONFIG_DNOTIFY is not set
+# CONFIG_INOTIFY_USER is not set
+CONFIG_PRINTK_TIME=y
+CONFIG_DEBUG_INFO=y
+# CONFIG_ENABLE_WARN_DEPRECATED is not set
+# CONFIG_ENABLE_MUST_CHECK is not set
+CONFIG_MAGIC_SYSRQ=y
+# CONFIG_SCHED_DEBUG is not set
+# CONFIG_DEBUG_BUGVERBOSE is not set
+# CONFIG_FTRACE is not set
+CONFIG_CRC_ITU_T=y
+CONFIG_CRC7=y
--
1.9.1
^ permalink raw reply related
* [PATCH v4 15/15] MAINTAINERS: Add entry for STM32 MCUs
From: Maxime Coquelin @ 2015-03-31 16:24 UTC (permalink / raw)
To: u.kleine-koenig-bIcnvbaLZ9MEGnE8C9+IrQ, afaerber-l3A5Bk7waGM,
geert-Td1EMuHUCqxL1ZNQvxDV9g, Rob Herring, Philipp Zabel,
Linus Walleij, Arnd Bergmann, stefan-XLVq0VzYD2Y,
pmeerw-jW+XmwGofnusTnJN9+BGXg, pebolle-IWqWACnzNjzz+pZb47iToQ,
peter-WaGBZJeGNqdsbIuE7sb01tBPR1lH4CV8,
andy.shevchenko-Re5JQEeQqe8AvxtiuMwx3w,
cw00.choi-Sze3O3UU22JBDgjK7y7TUQ, Russell King, Daniel Lezcano
Cc: Jonathan Corbet, Pawel Moll, Mark Rutland, Ian Campbell,
Kumar Gala, Thomas Gleixner, Greg Kroah-Hartman, Jiri Slaby,
Andrew Morton, David S. Miller, Mauro Carvalho Chehab,
Joe Perches, Antti Palosaari, Tejun Heo, Will Deacon,
Nikolay Borisov, Rusty Russell, Kees Cook, Michal Marek,
linux-doc-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-gpio-u79uwXL29TY76Z2rM5mHXA, linux-serial-fy+rA21nqHI
In-Reply-To: <1427819096-31109-1-git-send-email-mcoquelin.stm32-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
Add a MAINTAINER entry covering all STM32 machine and drivers files.
Signed-off-by: Maxime Coquelin <mcoquelin.stm32-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
---
MAINTAINERS | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/MAINTAINERS b/MAINTAINERS
index ddc5a8c..08c08c4 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1467,6 +1467,14 @@ F: drivers/usb/host/ehci-st.c
F: drivers/usb/host/ohci-st.c
F: drivers/ata/ahci_st.c
+ARM/STM32 ARCHITECTURE
+M: Maxime Coquelin <mcoquelin.stm32-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
+L: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org (moderated for non-subscribers)
+S: Maintained
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/mcoquelin/stm32.git
+N: stm32
+F: drivers/clocksource/armv7m_systick.c
+
ARM/TECHNOLOGIC SYSTEMS TS7250 MACHINE SUPPORT
M: Lennert Buytenhek <kernel-OLH4Qvv75CYX/NnBR394Jw@public.gmane.org>
L: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org (moderated for non-subscribers)
--
1.9.1
^ permalink raw reply related
* Re: [GIT PULL] selftest: Add futex functional tests
From: Shuah Khan @ 2015-03-31 16:37 UTC (permalink / raw)
To: Darren Hart, Linux Kernel Mailing List
Cc: linux-api, Ingo Molnar, Peter Zijlstra, Thomas Gleixner,
Davidlohr Bueso, KOSAKI Motohiro, greg Kroah-Hartman,
fengguang.wu, Michael Ellerman
In-Reply-To: <D14017F7.C46F0%dvhart@linux.intel.com>
On 03/31/2015 10:24 AM, Darren Hart wrote:
> On 3/31/15, 8:32 AM, "Shuah Khan" <shuahkh@osg.samsung.com> wrote:
>
>> Hi Daren,
>>
>> On 03/27/2015 04:17 PM, Darren Hart wrote:
>>> Hi Shuah,
>>>
>>> This series begins the process of migrating my futextest tests into
>>> kselftest.
>>> I've started with only the functional tests, as the performance and
>>> stress may
>>> not be appropriate for kselftest as they stand.
>>>
>>> I cleaned up various complaints from checkpatch, but I ignored others
>>> that would
>>> require significant rework of the testcases, such as not using volatile
>>> and not
>>> creating new typedefs.
>>>
>>> The patches will follow, but I'm providing a pull request for your
>>> convenience
>>> as well.
>>
>> Thanks for acting on this so quickly after we talked about it at ELC.
>> Just a quick note that I am going to get to this soon once I get the
>> 4.1 content wrapped up. We can plan upon getting these into 4.2.
>
> OK. Michael E. provided some feedback which I can either incorporate and
> respin, or I can send as a follow-on to your -next after you merge these.
> Which do you prefer?
>
Working through my email. Yes I see Michael had comments on install.
I would have the same ones. Please re-do the patch 2/5 to use shared
logic and install framework in lib.mk. This need to be done to
facilitate test install. If you were to create a script for running
tests, please make it non-generic and unique. For example, run.sh
is a very generic name.
[PATCH 2/5] selftest/futex: Update Makefile to use lib.mk
I took a quick look at the exit code discussion. If you would
like improve what is in kselftest.h, please re-do that patch.
[PATCH 5/5] kselftest: Add exit code defines
You can wait to re-do patches. I am planning to review the
patch set later on this week. That way you can avoid re-spin
just in case, I have other comments.
thanks,
-- Shuah
--
Shuah Khan
Sr. Linux Kernel Developer
Open Source Innovation Group
Samsung Research America (Silicon Valley)
shuahkh@osg.samsung.com | (970) 217-8978
^ permalink raw reply
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