Re: [patch V4 part 1 12/36] x86/kvm: Sanitize kvm_async_pf_task_wait()
On 05/05/20 15:16, Thomas Gleixner wrote: > From: Thomas Gleixner > > While working on the entry consolidation I stumbled over the KVM async page > fault handler and kvm_async_pf_task_wait() in particular. It took me a > while to realize that the randomly sprinkled around rcu_irq_enter()/exit() > invocations are just cargo cult programming. Several patches "fixed" RCU > splats by curing the symptoms without noticing that the code is flawed > from a design perspective. > > The main problem is that this async injection is not based on a proper > handshake mechanism and only respects the minimal requirement, i.e. the > guest is not in a state where it has interrupts disabled. > > Aside of that the actual code is a convoluted one fits it all swiss army > knife. It is invoked from different places with different RCU constraints: > > 1) Host side: > > vcpu_enter_guest() >kvm_x86_ops->handle_exit() > kvm_handle_page_fault() >kvm_async_pf_task_wait() > > The invocation happens from fully preemptible context. > > 2) Guest side: > > The async page fault interrupted: > > a) user space > >b) preemptible kernel code which is not in a RCU read side > critical section > >c) non-preemtible kernel code or a RCU read side critical section > or kernel code with CONFIG_PREEMPTION=n which allows not to > differentiate between #2b and #2c. > > RCU is watching for: > > #1 The vCPU exited and current is definitely not the idle task > > #2a The #PF entry code on the guest went through enter_from_user_mode() > which reactivates RCU > > #2b There is no preemptible, interrupts enabled code in the kernel > which can run with RCU looking away. (The idle task is always > non preemptible). > > I.e. all schedulable states (#1, #2a, #2b) do not need any of this RCU > voodoo at all. > > In #2c RCU is eventually not watching, but as that state cannot schedule > anyway there is no point to worry about it so it has to invoke > rcu_irq_enter() before running that code. This can be optimized, but this > will be done as an extra step in course of the entry code consolidation > work. > > So the proper solution for this is to: > > - Split kvm_async_pf_task_wait() into schedule and halt based waiting > interfaces which share the enqueueing code. > > - Add comments (condensed form of this changelog) to spare others the > time waste and pain of reverse engineering all of this with the help of > uncomprehensible changelogs and code history. > > - Invoke kvm_async_pf_task_wait_schedule() from kvm_handle_page_fault(), > user mode and schedulable kernel side async page faults (#1, #2a, #2b) > > - Invoke kvm_async_pf_task_wait_halt() for the non schedulable kernel > case (#2c). > > For this case also remove the rcu_irq_exit()/enter() pair around the > halt as it is just a pointless exercise: > >- vCPUs can VMEXIT at any random point and can be scheduled out for > an arbitrary amount of time by the host and this is not any > different except that it voluntary triggers the exit via halt. > >- The interrupted context could have RCU watching already. So the >rcu_irq_exit() before the halt is not gaining anything aside of >confusing the reader. Claiming that this might prevent RCU stalls >is just an illusion. > > Signed-off-by: Thomas Gleixner > --- > V2: Panic if async #PF is injected into an interrupt disabled region. > --- > arch/x86/include/asm/kvm_para.h |4 > arch/x86/kernel/kvm.c | 201 > > arch/x86/kvm/mmu/mmu.c |2 > 3 files changed, 144 insertions(+), 63 deletions(-) > > --- a/arch/x86/include/asm/kvm_para.h > +++ b/arch/x86/include/asm/kvm_para.h > @@ -88,7 +88,7 @@ static inline long kvm_hypercall4(unsign > bool kvm_para_available(void); > unsigned int kvm_arch_para_features(void); > unsigned int kvm_arch_para_hints(void); > -void kvm_async_pf_task_wait(u32 token, int interrupt_kernel); > +void kvm_async_pf_task_wait_schedule(u32 token); > void kvm_async_pf_task_wake(u32 token); > u32 kvm_read_and_reset_pf_reason(void); > void kvm_disable_steal_time(void); > @@ -113,7 +113,7 @@ static inline void kvm_spinlock_init(voi > #endif /* CONFIG_PARAVIRT_SPINLOCKS */ > > #else /* CONFIG_KVM_GUEST */ > -#define kvm_async_pf_task_wait(T, I) do {} while(0) > +#define kvm_async_pf_task_wait_schedule(T) do {} while(0) > #define kvm_async_pf_task_wake(T) do {} while(0) > > static inline bool kvm_para_available(void) > --- a/arch/x86/kernel/kvm.c > +++ b/arch/x86/kernel/kvm.c > @@ -75,7 +75,7 @@ struct kvm_task_sleep_node { > struct swait_queue_head wq; > u32 token; > int cpu; > - bool halted; > + bool use_halt; > }; > > static struct kvm_task_sleep_head { > @@ -98,75 +98,145 @@ static struct kvm_task_s
Re: [patch V4 part 1 13/36] x86/kvm: Restrict ASYNC_PF to user space
On 05/05/20 15:16, Thomas Gleixner wrote: > The async page fault injection into kernel space creates more problems than > it solves. The host has absolutely no knowledge about the state of the > guest if the fault happens in CPL0. The only restriction for the host is > interrupt disabled state. If interrupts are enabled in the guest then the > exception can hit arbitrary code. The HALT based wait in non-preemotible > code is a hacky replacement for a proper hypercall. > > For the ongoing work to restrict instrumentation and make the RCU idle > interaction well defined the required extra work for supporting async > pagefault in CPL0 is just not justified and creates complexity for a > dubious benefit. > > The CPL3 injection is well defined and does not cause any issues as it is > more or less the same as a regular page fault from CPL3. > > Suggested-by: Andy Lutomirski > Signed-off-by: Thomas Gleixner > --- > arch/x86/kernel/kvm.c | 100 > +++--- > 1 file changed, 7 insertions(+), 93 deletions(-) > > --- a/arch/x86/kernel/kvm.c > +++ b/arch/x86/kernel/kvm.c > @@ -75,7 +75,6 @@ struct kvm_task_sleep_node { > struct swait_queue_head wq; > u32 token; > int cpu; > - bool use_halt; > }; > > static struct kvm_task_sleep_head { > @@ -98,8 +97,7 @@ static struct kvm_task_sleep_node *_find > return NULL; > } > > -static bool kvm_async_pf_queue_task(u32 token, bool use_halt, > - struct kvm_task_sleep_node *n) > +static bool kvm_async_pf_queue_task(u32 token, struct kvm_task_sleep_node *n) > { > u32 key = hash_32(token, KVM_TASK_SLEEP_HASHBITS); > struct kvm_task_sleep_head *b = &async_pf_sleepers[key]; > @@ -117,7 +115,6 @@ static bool kvm_async_pf_queue_task(u32 > > n->token = token; > n->cpu = smp_processor_id(); > - n->use_halt = use_halt; > init_swait_queue_head(&n->wq); > hlist_add_head(&n->link, &b->list); > raw_spin_unlock(&b->lock); > @@ -138,7 +135,7 @@ void kvm_async_pf_task_wait_schedule(u32 > > lockdep_assert_irqs_disabled(); > > - if (!kvm_async_pf_queue_task(token, false, &n)) > + if (!kvm_async_pf_queue_task(token, &n)) > return; > > for (;;) { > @@ -154,91 +151,10 @@ void kvm_async_pf_task_wait_schedule(u32 > } > EXPORT_SYMBOL_GPL(kvm_async_pf_task_wait_schedule); > > -/* > - * Invoked from the async page fault handler. > - */ > -static void kvm_async_pf_task_wait_halt(u32 token) > -{ > - struct kvm_task_sleep_node n; > - > - if (!kvm_async_pf_queue_task(token, true, &n)) > - return; > - > - for (;;) { > - if (hlist_unhashed(&n.link)) > - break; > - /* > - * No point in doing anything about RCU here. Any RCU read > - * side critical section or RCU watching section can be > - * interrupted by VMEXITs and the host is free to keep the > - * vCPU scheduled out as long as it sees fit. This is not > - * any different just because of the halt induced voluntary > - * VMEXIT. > - * > - * Also the async page fault could have interrupted any RCU > - * watching context, so invoking rcu_irq_exit()/enter() > - * around this is not gaining anything. > - */ > - native_safe_halt(); > - local_irq_disable(); > - } > -} > - > -/* Invoked from the async page fault handler */ > -static void kvm_async_pf_task_wait(u32 token, bool usermode) > -{ > - bool can_schedule; > - > - /* > - * No need to check whether interrupts were disabled because the > - * host will (hopefully) only inject an async page fault into > - * interrupt enabled regions. > - * > - * If CONFIG_PREEMPTION is enabled then check whether the code > - * which triggered the page fault is preemptible. This covers user > - * mode as well because preempt_count() is obviously 0 there. > - * > - * The check for rcu_preempt_depth() is also required because > - * voluntary scheduling inside a rcu read locked section is not > - * allowed. > - * > - * The idle task is already covered by this because idle always > - * has a preempt count > 0. > - * > - * If CONFIG_PREEMPTION is disabled only allow scheduling when > - * coming from user mode as there is no indication whether the > - * context which triggered the page fault could schedule or not. > - */ > - if (IS_ENABLED(CONFIG_PREEMPTION)) > - can_schedule = preempt_count() + rcu_preempt_depth() == 0; > - else > - can_schedule = usermode; > - > - /* > - * If the kernel context is allowed to schedule then RCU is > - * watching because no preemptible code in the kernel is inside RCU > - * idle state. So it can be treated like us
[PATCH v9 0/3] 32-bit access for TX/RX hold registers for samsung_tty driver
Change in v9: - move wr_reg_barrier into ifdef of CONFIG_SERIAL_SAMSUNG_CONSOLE to fix following build error for x86 build CC [M] drivers/tty/serial/samsung_tty.o drivers/tty/serial/samsung_tty.c:186:13: warning: ‘wr_reg_barrier’ defined but not used [-Wunused-function] Change in v8: - spit into 3 patch [1/3] create the new functions with no functional change to the code as-is. Replace rd_regb/wr_regb with rd_reg/wr_reg for general usage. [2/3] add the new binding reg-io-width in device tree [3/3] add the new funtinality of rd_reg / wr_reg and wr_reg_barrier to support 32-bit access for the TX/RX hold registers UTXH and URXH. Change in v7: - [1/2] correct build error on running 'make dt_binding_check' Documentation/devicetree/bindings/serial/samsung_uart.yaml: mapping values are not allowed in this context in "", line 36, column 13 Documentation/devicetree/bindings/Makefile:12: recipe for target 'Documentation/devicetree/bindings/serial/samsung_uart.example.dts' failed make[1]: *** [Documentation/devicetree/bindings/serial/samsung_uart.example.dts] Error 1 make[1]: *** Waiting for unfinished jobs Makefile:1262: recipe for target 'dt_binding_check' failed make: *** [dt_binding_check] Error 2 - [2/2] add commit message of reviewed by and tested by in commit message Reviewed-by: Krzysztof Kozlowski Tested on Odroid HC1 (Exynos5422): Tested-by: Krzysztof Kozlowski Change in v6: - [2/2] clean description of reg-io-width allOf is not needed. Just enum [1, 2] is enough. Changes in v5: - spit into 2 patch, newly added patch for dt-binding [1/2] newly added dt-binding and go as first patch in this series. [2/2] go as second patch in this series. Changes in v4: - correct variable types and change misleading function name Changes in v3: - line 2031: remove redundant init value for ourport->port.iotype Changes in v2: - line 954 : change rd_regl to rd_reg in for backward compatibility. - line 2031: Add init value for ourport->port.iotype to UPIO_MEM Hyunki Koo (3): serial: samsung: Replace rd_regb/wr_regb with rd_reg/wr_reg dt-bindings: serial: Add reg-io-width compatible tty: samsung_tty: 32-bit access for TX/RX hold registers .../devicetree/bindings/serial/samsung_uart.yaml | 8 +++ drivers/tty/serial/samsung_tty.c | 76 ++ 2 files changed, 72 insertions(+), 12 deletions(-) -- 2.15.0.rc1
Re: [patch V4 part 1 11/36] x86/kvm: Handle async page faults directly through do_page_fault()
On 05/05/20 15:16, Thomas Gleixner wrote: > From: Andy Lutomirski > > KVM overloads #PF to indicate two types of not-actually-page-fault > events. Right now, the KVM guest code intercepts them by modifying > the IDT and hooking the #PF vector. This makes the already fragile > fault code even harder to understand, and it also pollutes call > traces with async_page_fault and do_async_page_fault for normal page > faults. > > Clean it up by moving the logic into do_page_fault() using a static > branch. This gets rid of the platform trap_init override mechanism > completely. > > [ tglx: Fixed up 32bit, removed error code from the async functions and > massaged coding style ] > > Signed-off-by: Andy Lutomirski > Signed-off-by: Thomas Gleixner > Cc: Paolo Bonzini > Cc: Sean Christopherson > --- > arch/x86/entry/entry_32.S |8 > arch/x86/entry/entry_64.S |4 > arch/x86/include/asm/kvm_para.h | 19 +-- > arch/x86/include/asm/x86_init.h |2 -- > arch/x86/kernel/kvm.c | 39 > +-- > arch/x86/kernel/traps.c |2 -- > arch/x86/kernel/x86_init.c |1 - > arch/x86/mm/fault.c | 19 +++ > 8 files changed, 57 insertions(+), 37 deletions(-) > > --- a/arch/x86/entry/entry_32.S > +++ b/arch/x86/entry/entry_32.S > @@ -1693,14 +1693,6 @@ SYM_CODE_START(general_protection) > jmp common_exception > SYM_CODE_END(general_protection) > > -#ifdef CONFIG_KVM_GUEST > -SYM_CODE_START(async_page_fault) > - ASM_CLAC > - pushl $do_async_page_fault > - jmp common_exception_read_cr2 > -SYM_CODE_END(async_page_fault) > -#endif > - > SYM_CODE_START(rewind_stack_do_exit) > /* Prevent any naive code from trying to unwind to our caller. */ > xorl%ebp, %ebp > --- a/arch/x86/entry/entry_64.S > +++ b/arch/x86/entry/entry_64.S > @@ -1204,10 +1204,6 @@ idtentry xendebug do_debug > has_error_c > idtentry general_protection do_general_protection has_error_code=1 > idtentry page_fault do_page_fault has_error_code=1 > read_cr2=1 > > -#ifdef CONFIG_KVM_GUEST > -idtentry async_page_faultdo_async_page_fault has_error_code=1 > read_cr2=1 > -#endif > - > #ifdef CONFIG_X86_MCE > idtentry machine_check do_mce > has_error_code=0paranoid=1 > #endif > --- a/arch/x86/include/asm/kvm_para.h > +++ b/arch/x86/include/asm/kvm_para.h > @@ -91,8 +91,18 @@ unsigned int kvm_arch_para_hints(void); > void kvm_async_pf_task_wait(u32 token, int interrupt_kernel); > void kvm_async_pf_task_wake(u32 token); > u32 kvm_read_and_reset_pf_reason(void); > -extern void kvm_disable_steal_time(void); > -void do_async_page_fault(struct pt_regs *regs, unsigned long error_code, > unsigned long address); > +void kvm_disable_steal_time(void); > +bool __kvm_handle_async_pf(struct pt_regs *regs, u32 token); > + > +DECLARE_STATIC_KEY_FALSE(kvm_async_pf_enabled); > + > +static __always_inline bool kvm_handle_async_pf(struct pt_regs *regs, u32 > token) > +{ > + if (static_branch_unlikely(&kvm_async_pf_enabled)) > + return __kvm_handle_async_pf(regs, token); > + else > + return false; > +} > > #ifdef CONFIG_PARAVIRT_SPINLOCKS > void __init kvm_spinlock_init(void); > @@ -130,6 +140,11 @@ static inline void kvm_disable_steal_tim > { > return; > } > + > +static inline bool kvm_handle_async_pf(struct pt_regs *regs, u32 token) > +{ > + return false; > +} > #endif > > #endif /* _ASM_X86_KVM_PARA_H */ > --- a/arch/x86/include/asm/x86_init.h > +++ b/arch/x86/include/asm/x86_init.h > @@ -50,14 +50,12 @@ struct x86_init_resources { > * @pre_vector_init: init code to run before interrupt vectors > * are set up. > * @intr_init: interrupt init code > - * @trap_init: platform specific trap setup > * @intr_mode_select:interrupt delivery mode selection > * @intr_mode_init: interrupt delivery mode setup > */ > struct x86_init_irqs { > void (*pre_vector_init)(void); > void (*intr_init)(void); > - void (*trap_init)(void); > void (*intr_mode_select)(void); > void (*intr_mode_init)(void); > }; > --- a/arch/x86/kernel/kvm.c > +++ b/arch/x86/kernel/kvm.c > @@ -35,6 +35,8 @@ > #include > #include > > +DEFINE_STATIC_KEY_FALSE(kvm_async_pf_enabled); > + > static int kvmapf = 1; > > static int __init parse_no_kvmapf(char *arg) > @@ -242,25 +244,27 @@ u32 kvm_read_and_reset_pf_reason(void) > EXPORT_SYMBOL_GPL(kvm_read_and_reset_pf_reason); > NOKPROBE_SYMBOL(kvm_read_and_reset_pf_reason); > > -dotraplinkage void > -do_async_page_fault(struct pt_regs *regs, unsigned long error_code, unsigned > long address) > +bool __kvm_handle_async_pf(struct pt_regs *regs, u32 token) > { > +
[PATCH v9 1/3] serial: samsung: Replace rd_regb/wr_regb with rd_reg/wr_reg
This patch change the name of macro for general usage. Signed-off-by: Hyunki Koo --- drivers/tty/serial/samsung_tty.c | 18 +- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/drivers/tty/serial/samsung_tty.c b/drivers/tty/serial/samsung_tty.c index 73f951d65b93..326b0164609c 100644 --- a/drivers/tty/serial/samsung_tty.c +++ b/drivers/tty/serial/samsung_tty.c @@ -154,10 +154,10 @@ struct s3c24xx_uart_port { #define portaddrl(port, reg) \ ((unsigned long *)(unsigned long)((port)->membase + (reg))) -#define rd_regb(port, reg) (readb_relaxed(portaddr(port, reg))) +#define rd_reg(port, reg) (readb_relaxed(portaddr(port, reg))) #define rd_regl(port, reg) (readl_relaxed(portaddr(port, reg))) -#define wr_regb(port, reg, val) writeb_relaxed(val, portaddr(port, reg)) +#define wr_reg(port, reg, val) writeb_relaxed(val, portaddr(port, reg)) #define wr_regl(port, reg, val) writel_relaxed(val, portaddr(port, reg)) /* Byte-order aware bit setting/clearing functions. */ @@ -714,7 +714,7 @@ static void s3c24xx_serial_rx_drain_fifo(struct s3c24xx_uart_port *ourport) fifocnt--; uerstat = rd_regl(port, S3C2410_UERSTAT); - ch = rd_regb(port, S3C2410_URXH); + ch = rd_reg(port, S3C2410_URXH); if (port->flags & UPF_CONS_FLOW) { int txe = s3c24xx_serial_txempty_nofifo(port); @@ -826,7 +826,7 @@ static irqreturn_t s3c24xx_serial_tx_chars(int irq, void *id) } if (port->x_char) { - wr_regb(port, S3C2410_UTXH, port->x_char); + wr_reg(port, S3C2410_UTXH, port->x_char); port->icount.tx++; port->x_char = 0; goto out; @@ -852,7 +852,7 @@ static irqreturn_t s3c24xx_serial_tx_chars(int irq, void *id) if (rd_regl(port, S3C2410_UFSTAT) & ourport->info->tx_fifofull) break; - wr_regb(port, S3C2410_UTXH, xmit->buf[xmit->tail]); + wr_reg(port, S3C2410_UTXH, xmit->buf[xmit->tail]); xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); port->icount.tx++; count--; @@ -916,7 +916,7 @@ static unsigned int s3c24xx_serial_tx_empty(struct uart_port *port) /* no modem control lines */ static unsigned int s3c24xx_serial_get_mctrl(struct uart_port *port) { - unsigned int umstat = rd_regb(port, S3C2410_UMSTAT); + unsigned int umstat = rd_reg(port, S3C2410_UMSTAT); if (umstat & S3C2410_UMSTAT_CTS) return TIOCM_CAR | TIOCM_DSR | TIOCM_CTS; @@ -2185,7 +2185,7 @@ static int s3c24xx_serial_get_poll_char(struct uart_port *port) if (s3c24xx_serial_rx_fifocnt(ourport, ufstat) == 0) return NO_POLL_CHAR; - return rd_regb(port, S3C2410_URXH); + return rd_reg(port, S3C2410_URXH); } static void s3c24xx_serial_put_poll_char(struct uart_port *port, @@ -2200,7 +2200,7 @@ static void s3c24xx_serial_put_poll_char(struct uart_port *port, while (!s3c24xx_serial_console_txrdy(port, ufcon)) cpu_relax(); - wr_regb(port, S3C2410_UTXH, c); + wr_reg(port, S3C2410_UTXH, c); } #endif /* CONFIG_CONSOLE_POLL */ @@ -2212,7 +2212,7 @@ s3c24xx_serial_console_putchar(struct uart_port *port, int ch) while (!s3c24xx_serial_console_txrdy(port, ufcon)) cpu_relax(); - wr_regb(port, S3C2410_UTXH, ch); + wr_reg(port, S3C2410_UTXH, ch); } static void -- 2.15.0.rc1
Re: [PATCH] serial: lantiq: Add x86 in Kconfig dependencies for Lantiq serial driver
On 6/5/2020 2:41 pm, Greg KH wrote: > On Wed, May 06, 2020 at 12:49:57PM +0800, Tanwar, Rahul wrote: >> On 5/5/2020 10:25 pm, Greg KH wrote: >>> On Mon, May 04, 2020 at 04:03:52PM +0800, Rahul Tanwar wrote: Lantiq serial driver/IP is reused for a x86 based SoC as well. Update the Kconfig accordingly. Signed-off-by: Rahul Tanwar --- drivers/tty/serial/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig index 0aea76cd67ff..4b0a7b98f8c7 100644 --- a/drivers/tty/serial/Kconfig +++ b/drivers/tty/serial/Kconfig @@ -1035,7 +1035,7 @@ config SERIAL_SIFIVE_CONSOLE config SERIAL_LANTIQ bool "Lantiq serial driver" - depends on LANTIQ + depends on (LANTIQ || X86) || COMPILE_TEST select SERIAL_CORE select SERIAL_CORE_CONSOLE select SERIAL_EARLYCON -- 2.11.0 >>> Any reason this can't also be a module? >> Thanks a lot for accepting the patch. This driver is also used for >> console during bootup so we always have it as built in. > So no generic kernel images can ever be made for this driver? That's > not good, what about systems that have this serial port but does not > care about the console? > > That's just ensuring that it will not be built into any distro kernel > images, I suggest fixing this up please. I understand your concern. I will send out another incremental patch series to fix it assuming that this Kconfig change is already merged in tty tree. Thanks. Regards, Rahul > thanks, > > greg k-h
[PATCH v9 2/3] dt-bindings: serial: Add reg-io-width compatible
Add a description for reg-io-width options for the samsung serial UART peripheral. Signed-off-by: Hyunki Koo --- Documentation/devicetree/bindings/serial/samsung_uart.yaml | 8 1 file changed, 8 insertions(+) diff --git a/Documentation/devicetree/bindings/serial/samsung_uart.yaml b/Documentation/devicetree/bindings/serial/samsung_uart.yaml index 9d2ce347875b..a57b1233c691 100644 --- a/Documentation/devicetree/bindings/serial/samsung_uart.yaml +++ b/Documentation/devicetree/bindings/serial/samsung_uart.yaml @@ -29,6 +29,14 @@ properties: reg: maxItems: 1 + reg-io-width: +description: | + The size (in bytes) of the IO accesses that should be performed + on the device. +allOf: + - $ref: /schemas/types.yaml#/definitions/uint32 + - enum: [ 1, 4 ] + clocks: minItems: 2 maxItems: 5 -- 2.15.0.rc1
[PATCH v9 3/3] tty: samsung_tty: 32-bit access for TX/RX hold registers
Support 32-bit access for the TX/RX hold registers UTXH and URXH. This is required for some newer SoCs. Signed-off-by: Hyunki Koo --- drivers/tty/serial/samsung_tty.c | 62 1 file changed, 57 insertions(+), 5 deletions(-) diff --git a/drivers/tty/serial/samsung_tty.c b/drivers/tty/serial/samsung_tty.c index 326b0164609c..6ef614d8648c 100644 --- a/drivers/tty/serial/samsung_tty.c +++ b/drivers/tty/serial/samsung_tty.c @@ -154,10 +154,33 @@ struct s3c24xx_uart_port { #define portaddrl(port, reg) \ ((unsigned long *)(unsigned long)((port)->membase + (reg))) -#define rd_reg(port, reg) (readb_relaxed(portaddr(port, reg))) +static u32 rd_reg(struct uart_port *port, u32 reg) +{ + switch (port->iotype) { + case UPIO_MEM: + return readb_relaxed(portaddr(port, reg)); + case UPIO_MEM32: + return readl_relaxed(portaddr(port, reg)); + default: + return 0; + } + return 0; +} + #define rd_regl(port, reg) (readl_relaxed(portaddr(port, reg))) -#define wr_reg(port, reg, val) writeb_relaxed(val, portaddr(port, reg)) +static void wr_reg(struct uart_port *port, u32 reg, u32 val) +{ + switch (port->iotype) { + case UPIO_MEM: + writeb_relaxed(val, portaddr(port, reg)); + break; + case UPIO_MEM32: + writel_relaxed(val, portaddr(port, reg)); + break; + } +} + #define wr_regl(port, reg, val) writel_relaxed(val, portaddr(port, reg)) /* Byte-order aware bit setting/clearing functions. */ @@ -1974,7 +1997,7 @@ static int s3c24xx_serial_probe(struct platform_device *pdev) struct device_node *np = pdev->dev.of_node; struct s3c24xx_uart_port *ourport; int index = probe_index; - int ret; + int ret, prop = 0; if (np) { ret = of_alias_get_id(np, "serial"); @@ -2000,10 +2023,27 @@ static int s3c24xx_serial_probe(struct platform_device *pdev) dev_get_platdata(&pdev->dev) : ourport->drv_data->def_cfg; - if (np) + if (np) { of_property_read_u32(np, "samsung,uart-fifosize", &ourport->port.fifosize); + if (of_property_read_u32(np, "reg-io-width", &prop) == 0) { + switch (prop) { + case 1: + ourport->port.iotype = UPIO_MEM; + break; + case 4: + ourport->port.iotype = UPIO_MEM32; + break; + default: + dev_warn(&pdev->dev, "unsupported reg-io-width (%d)\n", + prop); + ret = -EINVAL; + break; + } + } + } + if (ourport->drv_data->fifosize[index]) ourport->port.fifosize = ourport->drv_data->fifosize[index]; else if (ourport->info->fifosize) @@ -2587,6 +2627,18 @@ module_platform_driver(samsung_serial_driver); * Early console. */ +static void wr_reg_barrier(struct uart_port *port, u32 reg, u32 val) +{ + switch (port->iotype) { + case UPIO_MEM: + writeb(val, portaddr(port, reg)); + break; + case UPIO_MEM32: + writel(val, portaddr(port, reg)); + break; + } +} + struct samsung_early_console_data { u32 txfull_mask; }; @@ -2612,7 +2664,7 @@ static void samsung_early_putc(struct uart_port *port, int c) else samsung_early_busyuart(port); - writeb(c, port->membase + S3C2410_UTXH); + wr_reg_barrier(port, S3C2410_UTXH, c); } static void samsung_early_write(struct console *con, const char *s, -- 2.15.0.rc1
[PATCH v10 0/2] Add initial support for slimport anx7625
Hi all, The following series add support for the Slimport ANX7625 transmitter, a ultra-low power Full-HD 4K MIPI to DP transmitter designed for portable device. This is the v10 version, any mistakes, please let me know, I will fix it in the next series. Change history: v10: Fix comments from Rob Herring, Daniel. - Fix dt_binding_check warning. - Update description. v9: Fix comments from Sam, Nicolas, Daniel - Remove extcon interface. - Remove DPI support. - Fix dt_binding_check complains. - Code clean up and update description. v8: Fix comments from Nicolas. - Fix several coding format. - Update description. v7: - Fix critical timing(eg:odd hfp/hbp) in "mode_fixup" interface, enhance MIPI RX tolerance by setting register MIPI_DIGITAL_ADJ_1 to 0x3D. Xin Ji (2): dt-bindings: drm/bridge: anx7625: MIPI to DP transmitter binding drm/bridge: anx7625: Add anx7625 MIPI DSI/DPI to DP bridge driver .../bindings/display/bridge/analogix,anx7625.yaml | 98 + drivers/gpu/drm/bridge/Makefile|2 +- drivers/gpu/drm/bridge/analogix/Kconfig|8 + drivers/gpu/drm/bridge/analogix/Makefile |1 + drivers/gpu/drm/bridge/analogix/anx7625.c | 1961 drivers/gpu/drm/bridge/analogix/anx7625.h | 397 6 files changed, 2466 insertions(+), 1 deletion(-) create mode 100644 Documentation/devicetree/bindings/display/bridge/analogix,anx7625.yaml create mode 100644 drivers/gpu/drm/bridge/analogix/anx7625.c create mode 100644 drivers/gpu/drm/bridge/analogix/anx7625.h -- 2.7.4
Re: [PATCH 06/11] net: ethernet: mtk-eth-mac: new driver
Hi Andrew, thanks for the review. wt., 5 maj 2020 o 19:47 Andrew Lunn napisał(a): > > > +static struct net_device *mtk_mac_get_netdev(struct mtk_mac_priv *priv) > > +{ > > + char *ptr = (char *)priv; > > + > > + return (struct net_device *)(ptr - ALIGN(sizeof(struct net_device), > > + NETDEV_ALIGN)); > > +} > > Bit of an odd way to do it. It is much more normal to just have > > return priv->netdev; > But then you store a pointer to the starting address of the structure in that very structure. This is actually weirder to me. :) I'd say: let's generalize it and provide a counterpart to netdev_priv(): priv_to_netdev(), how about that? For the other issues: I'll address them in v2. Bart
[PATCH v10 1/2] dt-bindings: drm/bridge: anx7625: MIPI to DP transmitter binding
The ANX7625 is an ultra-low power 4K Mobile HD Transmitter designed for portable device. It converts MIPI to DisplayPort 1.3 4K. You can add support to your board with binding. Example: anx7625_bridge: encoder@58 { compatible = "analogix,anx7625"; reg = <0x58>; status = "okay"; enable-gpios = <&pio 45 GPIO_ACTIVE_HIGH>; reset-gpios = <&pio 73 GPIO_ACTIVE_HIGH>; ports { #address-cells = <1>; #size-cells = <0>; mipi2dp_bridge_in: port@0 { reg = <0>; anx7625_in: endpoint { remote-endpoint = <&mipi_dsi>; }; }; mipi2dp_bridge_out: port@1 { reg = <1>; anx7625_out: endpoint { remote-endpoint = <&panel_in>; }; }; }; }; Signed-off-by: Xin Ji --- .../bindings/display/bridge/analogix,anx7625.yaml | 98 ++ 1 file changed, 98 insertions(+) create mode 100644 Documentation/devicetree/bindings/display/bridge/analogix,anx7625.yaml diff --git a/Documentation/devicetree/bindings/display/bridge/analogix,anx7625.yaml b/Documentation/devicetree/bindings/display/bridge/analogix,anx7625.yaml new file mode 100644 index 000..6e54176 --- /dev/null +++ b/Documentation/devicetree/bindings/display/bridge/analogix,anx7625.yaml @@ -0,0 +1,98 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +# Copyright 2019 Analogix Semiconductor, Inc. +%YAML 1.2 +--- +$id: "http://devicetree.org/schemas/display/bridge/analogix,anx7625.yaml#"; +$schema: "http://devicetree.org/meta-schemas/core.yaml#"; + +title: Analogix ANX7625 SlimPort (4K Mobile HD Transmitter) + +maintainers: + - Xin Ji + +description: | + The ANX7625 is an ultra-low power 4K Mobile HD Transmitter + designed for portable devices. + +properties: + "#address-cells": true + "#size-cells": true + + compatible: +items: + - const: analogix,anx7625 + + reg: +maxItems: 1 + + interrupts: +description: used for interrupt pin B8. +maxItems: 1 + + enable-gpios: +description: used for power on chip control, POWER_EN pin D2. +maxItems: 1 + + reset-gpios: +description: used for reset chip control, RESET_N pin B7. +maxItems: 1 + + ports: +type: object + +properties: + port@0: +type: object +description: + Video port for MIPI DSI input. + + port@1: +type: object +description: + Video port for panel or connector. + +required: +- port@0 +- port@1 + +required: + - compatible + - reg + - ports + +additionalProperties: false + +examples: + - | +#include + +i2c0 { +#address-cells = <1>; +#size-cells = <0>; + +anx7625_bridge: encoder@58 { +compatible = "analogix,anx7625"; +reg = <0x58>; +enable-gpios = <&pio 45 GPIO_ACTIVE_HIGH>; +reset-gpios = <&pio 73 GPIO_ACTIVE_HIGH>; + +ports { +#address-cells = <1>; +#size-cells = <0>; + +mipi2dp_bridge_in: port@0 { +reg = <0>; +anx7625_in: endpoint { +remote-endpoint = <&mipi_dsi>; +}; +}; + +mipi2dp_bridge_out: port@1 { +reg = <1>; +anx7625_out: endpoint { +remote-endpoint = <&panel_in>; +}; +}; +}; +}; +}; -- 2.7.4
Re: [RFC, WIP, v4 11/11] media: vidtv: Add a MPEG Transport Stream Multiplexer
Hi Mauro! Thank you for reviewing this! >> Add a MPEG Transport Stream multiplexer responsible for polling encoders, >> interleaving packets, padding the resulting stream with NULL packets if >> necessary and then delivering the resulting TS packets to the bridge >> driver so it can feed the demux. >> >> This patch includes a "channel" abstraction, which attempts to map a >> MPEG service into a struct that vidtv can work with. >> >> When vidtv boots, it will create some hardcoded channels: >> >> -Their services will be concatenated to populate the SDT. >> -Their programs will be concatenated to populate the PAT >> -For each program in the PAT, a PMT section will be created >> -The PMT section for a channel will be assigned its streams. >> -Every stream will have its corresponding encoder polled to produce >> TS packets >> -These packets may be interleaved by the mux and then delivered to >> the bridg >> >> Signed-off-by: Daniel W. S. Almeida > > The same notes I made on previous patches apply here. I did not understand this. Do you mean to say that I should remove these dashes in the beginning of the lines? thanks - Daniel
Re: [PATCH] arm64/mm: Remove add_huge_page_size()
On 05/06/2020 12:16 PM, Gavin Shan wrote: > The function add_huge_page_size(), wrapper of hugetlb_add_hstate(), > avoids to register duplicated huge page states for same size. However, > the same logic has been included in hugetlb_add_hstate(). So it seems > unnecessary to keep add_huge_page_size() and this just removes it. Makes sense. > > Signed-off-by: Gavin Shan > --- > arch/arm64/mm/hugetlbpage.c | 18 +- > 1 file changed, 5 insertions(+), 13 deletions(-) > > diff --git a/arch/arm64/mm/hugetlbpage.c b/arch/arm64/mm/hugetlbpage.c > index bbeb6a5a6ba6..ed7530413941 100644 > --- a/arch/arm64/mm/hugetlbpage.c > +++ b/arch/arm64/mm/hugetlbpage.c > @@ -441,22 +441,14 @@ void huge_ptep_clear_flush(struct vm_area_struct *vma, > clear_flush(vma->vm_mm, addr, ptep, pgsize, ncontig); > } > > -static void __init add_huge_page_size(unsigned long size) > -{ > - if (size_to_hstate(size)) > - return; > - > - hugetlb_add_hstate(ilog2(size) - PAGE_SHIFT); > -} > - > static int __init hugetlbpage_init(void) > { > #ifdef CONFIG_ARM64_4K_PAGES > - add_huge_page_size(PUD_SIZE); > + hugetlb_add_hstate(PUD_SHIFT - PAGE_SHIFT); > #endif > - add_huge_page_size(CONT_PMD_SIZE); > - add_huge_page_size(PMD_SIZE); > - add_huge_page_size(CONT_PTE_SIZE); > + hugetlb_add_hstate(CONT_PMD_SHIFT + PMD_SHIFT - PAGE_SHIFT); > + hugetlb_add_hstate(PMD_SHIFT - PAGE_SHIFT); > + hugetlb_add_hstate(CONT_PTE_SHIFT); Should these page order values be converted into macros instead. Also we should probably keep (CONT_PTE_SHIFT + PAGE_SHIFT - PAGE_SHIFT) as is to make things more clear.
Re: [PATCH RFC 1/2] tracing/block: cleanup rwbs filling in trace events
On 2020/5/4 23:16, Konstantin Khlebnikov wrote: > Define BLK_RWBS_LEN in blktrace_api.h > Bcache events use shorter 6 char buffer which could overflow. > > Also remove unsed "bytes" argument. > > Signed-off-by: Konstantin Khlebnikov The patch is good for me, it can be directly handled by block layer maintainer and skip me. Reviewed-by: Coly Li Thank you. Coly Li > --- > include/linux/blktrace_api.h |4 +- > include/trace/events/bcache.h | 20 +- > include/trace/events/block.h | 84 > - > kernel/trace/blktrace.c |2 - > 4 files changed, 55 insertions(+), 55 deletions(-) > > diff --git a/include/linux/blktrace_api.h b/include/linux/blktrace_api.h > index 3b6ff5902edc..ea9da15d32d9 100644 > --- a/include/linux/blktrace_api.h > +++ b/include/linux/blktrace_api.h > @@ -120,7 +120,9 @@ struct compat_blk_user_trace_setup { > > #endif > > -extern void blk_fill_rwbs(char *rwbs, unsigned int op, int bytes); > +#define BLK_RWBS_LEN 8 > + > +extern void blk_fill_rwbs(char *rwbs, unsigned int op); > > static inline sector_t blk_rq_trace_sector(struct request *rq) > { > diff --git a/include/trace/events/bcache.h b/include/trace/events/bcache.h > index 0bddea663b3b..7440d704c200 100644 > --- a/include/trace/events/bcache.h > +++ b/include/trace/events/bcache.h > @@ -18,7 +18,7 @@ DECLARE_EVENT_CLASS(bcache_request, > __field(sector_t, sector ) > __field(dev_t, orig_sector ) > __field(unsigned int, nr_sector ) > - __array(char, rwbs, 6 ) > + __array(char, rwbs, BLK_RWBS_LEN) > ), > > TP_fast_assign( > @@ -28,7 +28,7 @@ DECLARE_EVENT_CLASS(bcache_request, > __entry->sector = bio->bi_iter.bi_sector; > __entry->orig_sector= bio->bi_iter.bi_sector - 16; > __entry->nr_sector = bio->bi_iter.bi_size >> 9; > - blk_fill_rwbs(__entry->rwbs, bio->bi_opf, bio->bi_iter.bi_size); > + blk_fill_rwbs(__entry->rwbs, bio->bi_opf); > ), > > TP_printk("%d,%d %s %llu + %u (from %d,%d @ %llu)", > @@ -95,14 +95,14 @@ DECLARE_EVENT_CLASS(bcache_bio, > __field(dev_t, dev ) > __field(sector_t, sector ) > __field(unsigned int, nr_sector ) > - __array(char, rwbs, 6 ) > + __array(char, rwbs, BLK_RWBS_LEN) > ), > > TP_fast_assign( > __entry->dev= bio_dev(bio); > __entry->sector = bio->bi_iter.bi_sector; > __entry->nr_sector = bio->bi_iter.bi_size >> 9; > - blk_fill_rwbs(__entry->rwbs, bio->bi_opf, bio->bi_iter.bi_size); > + blk_fill_rwbs(__entry->rwbs, bio->bi_opf); > ), > > TP_printk("%d,%d %s %llu + %u", > @@ -128,7 +128,7 @@ TRACE_EVENT(bcache_read, > __field(dev_t, dev ) > __field(sector_t, sector ) > __field(unsigned int, nr_sector ) > - __array(char, rwbs, 6 ) > + __array(char, rwbs, BLK_RWBS_LEN) > __field(bool, cache_hit ) > __field(bool, bypass ) > ), > @@ -137,7 +137,7 @@ TRACE_EVENT(bcache_read, > __entry->dev= bio_dev(bio); > __entry->sector = bio->bi_iter.bi_sector; > __entry->nr_sector = bio->bi_iter.bi_size >> 9; > - blk_fill_rwbs(__entry->rwbs, bio->bi_opf, bio->bi_iter.bi_size); > + blk_fill_rwbs(__entry->rwbs, bio->bi_opf); > __entry->cache_hit = hit; > __entry->bypass = bypass; > ), > @@ -158,7 +158,7 @@ TRACE_EVENT(bcache_write, > __field(u64,inode ) > __field(sector_t, sector ) > __field(unsigned int, nr_sector ) > - __array(char, rwbs, 6 ) > + __array(char, rwbs, BLK_RWBS_LEN) > __field(bool, writeback ) > __field(bool, bypass ) > ), > @@ -168,7 +168,7 @@ TRACE_EVENT(bcache_write, > __entry->inode = inode; > __entry->sector = bio->bi_iter.bi_sector; > __entry->nr_sector = bio->bi_iter.bi_size >> 9; > - blk_fill_rwbs(__entry->rwbs, bio->bi_opf, bio->bi_iter.bi_size); > + blk_fill_rwbs(__entry->rwbs, bio->bi_opf); > __entry->writeback = writeba
Re: [PATCH bpf-next 0/4] RV64 BPF JIT Optimizations
On Wed, 6 May 2020 at 02:03, Luke Nelson wrote: > > This patch series introduces a set of optimizations to the BPF JIT > on RV64. The optimizations are related to the verifier zero-extension > optimization and BPF_JMP BPF_K. > > We tested the optimizations on a QEMU riscv64 virt machine, using > lib/test_bpf and test_verifier, and formally verified their correctness > using Serval. > Luke and Xi, Thanks a lot for working on this! Very nice series! For the series: Reviewed-by: Björn Töpel Acked-by: Björn Töpel > Luke Nelson (4): > bpf, riscv: Enable missing verifier_zext optimizations on RV64 > bpf, riscv: Optimize FROM_LE using verifier_zext on RV64 > bpf, riscv: Optimize BPF_JMP BPF_K when imm == 0 on RV64 > bpf, riscv: Optimize BPF_JSET BPF_K using andi on RV64 > > arch/riscv/net/bpf_jit_comp64.c | 64 ++--- > 1 file changed, 44 insertions(+), 20 deletions(-) > > Cc: Xi Wang > > -- > 2.17.1 >
[PATCH v10 2/2] drm/bridge: anx7625: Add anx7625 MIPI DSI/DPI to DP bridge driver
The ANX7625 is an ultra-low power 4K Mobile HD Transmitter designed for portable device. It converts MIPI DSI/DPI to DisplayPort 1.3 4K. The ANX7625 can support both USB Type-C PD feature and MIPI DSI/DPI to DP feature. This driver only enabled MIPI DSI/DPI to DP feature. Signed-off-by: Xin Ji --- drivers/gpu/drm/bridge/Makefile |2 +- drivers/gpu/drm/bridge/analogix/Kconfig |8 + drivers/gpu/drm/bridge/analogix/Makefile |1 + drivers/gpu/drm/bridge/analogix/anx7625.c | 1961 + drivers/gpu/drm/bridge/analogix/anx7625.h | 397 ++ 5 files changed, 2368 insertions(+), 1 deletion(-) create mode 100644 drivers/gpu/drm/bridge/analogix/anx7625.c create mode 100644 drivers/gpu/drm/bridge/analogix/anx7625.h diff --git a/drivers/gpu/drm/bridge/Makefile b/drivers/gpu/drm/bridge/Makefile index 4934fcf..bcd388a 100644 --- a/drivers/gpu/drm/bridge/Makefile +++ b/drivers/gpu/drm/bridge/Makefile @@ -12,8 +12,8 @@ obj-$(CONFIG_DRM_SII9234) += sii9234.o obj-$(CONFIG_DRM_THINE_THC63LVD1024) += thc63lvd1024.o obj-$(CONFIG_DRM_TOSHIBA_TC358764) += tc358764.o obj-$(CONFIG_DRM_TOSHIBA_TC358767) += tc358767.o -obj-$(CONFIG_DRM_ANALOGIX_DP) += analogix/ obj-$(CONFIG_DRM_I2C_ADV7511) += adv7511/ obj-$(CONFIG_DRM_TI_SN65DSI86) += ti-sn65dsi86.o obj-$(CONFIG_DRM_TI_TFP410) += ti-tfp410.o +obj-y += analogix/ obj-y += synopsys/ diff --git a/drivers/gpu/drm/bridge/analogix/Kconfig b/drivers/gpu/drm/bridge/analogix/Kconfig index e930ff9..c772be2 100644 --- a/drivers/gpu/drm/bridge/analogix/Kconfig +++ b/drivers/gpu/drm/bridge/analogix/Kconfig @@ -2,3 +2,11 @@ config DRM_ANALOGIX_DP tristate depends on DRM + +config DRM_ANALOGIX_ANX7625 + tristate "Analogix Anx7625 MIPI to DP interface support" + depends on DRM + depends on OF + help + ANX7625 is an ultra-low power 4K mobile HD transmitter designed + for portable devices. It converts MIPI/DPI to DisplayPort1.3 4K. diff --git a/drivers/gpu/drm/bridge/analogix/Makefile b/drivers/gpu/drm/bridge/analogix/Makefile index fdbf3fd..b6c4a19 100644 --- a/drivers/gpu/drm/bridge/analogix/Makefile +++ b/drivers/gpu/drm/bridge/analogix/Makefile @@ -1,3 +1,4 @@ # SPDX-License-Identifier: GPL-2.0-only +obj-$(CONFIG_DRM_ANALOGIX_ANX7625) += anx7625.o analogix_dp-objs := analogix_dp_core.o analogix_dp_reg.o obj-$(CONFIG_DRM_ANALOGIX_DP) += analogix_dp.o diff --git a/drivers/gpu/drm/bridge/analogix/anx7625.c b/drivers/gpu/drm/bridge/analogix/anx7625.c new file mode 100644 index 000..2afa869 --- /dev/null +++ b/drivers/gpu/drm/bridge/analogix/anx7625.c @@ -0,0 +1,1961 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright(c) 2020, Analogix Semiconductor. All rights reserved. + * + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "anx7625.h" + +/* + * There is a sync issue while access I2C register between AP(CPU) and + * internal firmware(OCM), to avoid the race condition, AP should access + * the reserved slave address before slave address occurs changes. + */ +static int i2c_access_workaround(struct anx7625_data *ctx, +struct i2c_client *client) +{ + u8 offset; + struct device *dev = &client->dev; + int ret; + + if (client == ctx->last_client) + return 0; + + ctx->last_client = client; + + if (client == ctx->i2c.tcpc_client) + offset = RSVD_00_ADDR; + else if (client == ctx->i2c.tx_p0_client) + offset = RSVD_D1_ADDR; + else if (client == ctx->i2c.tx_p1_client) + offset = RSVD_60_ADDR; + else if (client == ctx->i2c.rx_p0_client) + offset = RSVD_39_ADDR; + else if (client == ctx->i2c.rx_p1_client) + offset = RSVD_7F_ADDR; + else + offset = RSVD_00_ADDR; + + ret = i2c_smbus_write_byte_data(client, offset, 0x00); + if (ret < 0) + DRM_DEV_ERROR(dev, + "fail to access i2c id=%x\n:%x", + client->addr, offset); + + return ret; +} + +static int anx7625_reg_read(struct anx7625_data *ctx, + struct i2c_client *client, u8 reg_addr) +{ + int ret; + struct device *dev = &client->dev; + + i2c_access_workaround(ctx, client); + + ret = i2c_smbus_read_byte_data(client, reg_addr); + if (ret < 0) + DRM_DEV_ERROR(dev, "read i2c fail id=%x:%x\n", + client->addr, reg_addr); + + return ret; +} + +static int anx7625_reg_block_read(struct anx7625_data *ctx, + struct i2c_client *client, + u8 reg_addr, u
Re: [PATCH 06/11] net: ethernet: mtk-eth-mac: new driver
Hi Jakub, thanks for the review. wt., 5 maj 2020 o 20:04 Jakub Kicinski napisał(a): > > > +/* Represents the actual structure of descriptors used by the MAC. We can > > + * reuse the same structure for both TX and RX - the layout is the same, > > only > > + * the flags differ slightly. > > + */ > > +struct mtk_mac_ring_desc { > > + /* Contains both the status flags as well as packet length. */ > > + u32 status; > > + u32 data_ptr; > > + u32 vtag; > > + u32 reserved; > > +} __aligned(4) __packed; > > It will be aligned to 4, because the members are all 4B. And there is > no possibility of holes. You can safely remove those attrs. > I noticed some other drivers whose descriptors are well aligned define these attributes anyway so I assumed it's a convention. I'll drop them in v2. > > > + status = desc->status; > > + > > + if (!(status & MTK_MAC_DESC_BIT_COWN)) > > + return -1; > > + > > + desc_data->len = status & MTK_MAC_DESC_MSK_LEN; > > + desc_data->flags = status & ~MTK_MAC_DESC_MSK_LEN; > > + desc_data->dma_addr = desc->data_ptr; > > + desc_data->skb = ring->skbs[ring->tail]; > > + > > + desc->data_ptr = 0; > > + desc->status = MTK_MAC_DESC_BIT_COWN; > > + if (status & MTK_MAC_DESC_BIT_EOR) > > + desc->status |= MTK_MAC_DESC_BIT_EOR; > > + > > + dma_wmb(); > > What is this separating? I'll add comments to barriers in v2. > > > +/* All processing for TX and RX happens in the napi poll callback. */ > > +static irqreturn_t mtk_mac_handle_irq(int irq, void *data) > > +{ > > + struct mtk_mac_priv *priv; > > + struct net_device *ndev; > > + unsigned int status; > > + > > + ndev = data; > > + priv = netdev_priv(ndev); > > + > > + if (netif_running(ndev)) { > > + mtk_mac_intr_mask_all(priv); > > + status = mtk_mac_intr_read_and_clear(priv); > > + > > + /* RX Complete */ > > + if (status & MTK_MAC_BIT_INT_STS_FNRC) > > + napi_schedule(&priv->napi); > > + > > + /* TX Complete */ > > + if (status & MTK_MAC_BIT_INT_STS_TNTC) > > + schedule_work(&priv->tx_work); > > + > > + /* One of the counter reached 0x800 */ > > + if (status & MTK_MAC_REG_INT_STS_MIB_CNT_TH) { > > + mtk_mac_update_stats(priv); > > + mtk_mac_reset_counters(priv); > > + } > > + > > + mtk_mac_intr_unmask_all(priv); > > Why do you unmask all IRQs here? The usual way to operate is to leave > TX and RX IRQs masked until NAPI finishes. > I actually did it before as the leftover comment says above the function. Then I thought this way we mask interrupt for a shorter period of time. I can go back to the previous approach. > > + } > > + > > + return IRQ_HANDLED; > > +} > > > +static int mtk_mac_enable(struct net_device *ndev) > > +{ > > + /* Reset all counters */ > > + mtk_mac_reset_counters(priv); > > This doesn't reset the counters to zero, right? > Yes, it does actually. I'll drop it in v2 - it's not necessary. > > > +static void mtk_mac_tx_work(struct work_struct *work) > > +{ > > + struct mtk_mac_priv *priv; > > + struct mtk_mac_ring *ring; > > + struct net_device *ndev; > > + bool wake = false; > > + int ret; > > + > > + priv = container_of(work, struct mtk_mac_priv, tx_work); > > + ndev = mtk_mac_get_netdev(priv); > > + ring = &priv->tx_ring; > > + > > + for (;;) { > > + mtk_mac_lock(priv); > > + > > + if (!mtk_mac_ring_descs_available(ring)) { > > + mtk_mac_unlock(priv); > > + break; > > + } > > + > > + ret = mtk_mac_tx_complete(priv); > > + mtk_mac_unlock(priv); > > + if (ret) > > + break; > > + > > + wake = true; > > + } > > + > > + if (wake) > > + netif_wake_queue(ndev); > > This looks racy, if the TX path runs in parallel the queue may have > already been filled up at the point you wake it up. > > > +} > > Why do you clean the TX ring from a work rather than from the NAPI > context? > So this was unclear to me, that's why I went with a workqueue. The budget argument in napi poll is for RX. Should I put some cap on the number of TX descriptors processed in napi context? > > > +static int mtk_mac_receive_packet(struct mtk_mac_priv *priv) > > +{ > > + struct net_device *ndev = mtk_mac_get_netdev(priv); > > + struct mtk_mac_ring *ring = &priv->rx_ring; > > + struct device *dev = mtk_mac_get_dev(priv); > > + struct mtk_mac_ring_desc_data desc_data; > > + struct sk_buff *new_skb; > > + int ret; > > + > > + mtk_mac_lock(priv); > > + ret = mtk_mac_ring_pop_tail(ring, &desc_data); > > + mtk_mac_unlock(priv); > > + if (ret) > > + return -1; > > + > > + mtk_mac_dma_unm
Re: [EXT] [PATCH 1/2] net: qed*: Reduce RX and TX default ring count when running inside kdump kernel
Hello Igor, On Wed, May 6, 2020 at 12:21 PM Igor Russkikh wrote: > > > > > #include > > +#include > > #include > > #include > > #include > > @@ -574,13 +575,13 @@ int qede_add_tc_flower_fltr(struct qede_dev *edev, > > __be16 proto, > > #define RX_RING_SIZE ((u16)BIT(RX_RING_SIZE_POW)) > > #define NUM_RX_BDS_MAX (RX_RING_SIZE - 1) > > #define NUM_RX_BDS_MIN 128 > > -#define NUM_RX_BDS_DEF ((u16)BIT(10) - 1) > > +#define NUM_RX_BDS_DEF ((is_kdump_kernel()) ? ((u16)BIT(6) - > > 1) : > > ((u16)BIT(10) - 1)) > > > > #define TX_RING_SIZE_POW 13 > > #define TX_RING_SIZE ((u16)BIT(TX_RING_SIZE_POW)) > > #define NUM_TX_BDS_MAX (TX_RING_SIZE - 1) > > #define NUM_TX_BDS_MIN 128 > > -#define NUM_TX_BDS_DEF NUM_TX_BDS_MAX > > +#define NUM_TX_BDS_DEF ((is_kdump_kernel()) ? ((u16)BIT(6) - > > 1) : > > NUM_TX_BDS_MAX) > > > > Hi Bhupesh, > > Thanks for looking into this. We are also analyzing how to reduce qed* memory > usage even more. > > Patch is good, but may I suggest not to introduce conditional logic into the > defines but instead just add two new defines like NUM_[RT]X_BDS_MIN and check > for is_kdump_kernel() in the code explicitly? > > if (is_kdump_kernel()) { > edev->q_num_rx_buffers = NUM_RX_BDS_MIN; > edev->q_num_tx_buffers = NUM_TX_BDS_MIN; > } else { > edev->q_num_rx_buffers = NUM_RX_BDS_DEF; > edev->q_num_tx_buffers = NUM_TX_BDS_DEF; > } > > This may make configuration logic more explicit. If future we may want adding > more specific configs under this `if`. Thanks for the review comments. The suggestions seem fine to me. I will incorporate them in v2. Regards, Bhupesh
[PATCH 0/3] x86/cpu: More macros cleanup
From: Borislav Petkov Hi all, here are some more cleanups ontop of tglx's x86 CPU macros cleanup series. Thx. Borislav Petkov (2): x86/cpu: Add a X86_MATCH_INTEL_FAM6_MODEL_STEPPINGS() macro x86/apic: Convert the TSC deadline timer matching to steppings macro Mark Gross (1): x86/cpu: Add a steppings field to struct x86_cpu_id arch/x86/include/asm/cpu_device_id.h | 31 +-- arch/x86/kernel/apic/apic.c | 57 ++-- arch/x86/kernel/cpu/match.c | 7 +++- include/linux/mod_devicetable.h | 2 + 4 files changed, 48 insertions(+), 49 deletions(-) -- 2.21.0
[PATCH 2/3] x86/cpu: Add a X86_MATCH_INTEL_FAM6_MODEL_STEPPINGS() macro
From: Borislav Petkov ... to match Intel family 6 CPUs with steppings. Signed-off-by: Borislav Petkov --- arch/x86/include/asm/cpu_device_id.h | 4 1 file changed, 4 insertions(+) diff --git a/arch/x86/include/asm/cpu_device_id.h b/arch/x86/include/asm/cpu_device_id.h index 10426cd56dca..eb8fcede9e3b 100644 --- a/arch/x86/include/asm/cpu_device_id.h +++ b/arch/x86/include/asm/cpu_device_id.h @@ -160,6 +160,10 @@ #define X86_MATCH_INTEL_FAM6_MODEL(model, data) \ X86_MATCH_VENDOR_FAM_MODEL(INTEL, 6, INTEL_FAM6_##model, data) +#define X86_MATCH_INTEL_FAM6_MODEL_STEPPINGS(model, steppings, data) \ + X86_MATCH_VENDOR_FAM_MODEL_STEPPINGS_FEATURE(INTEL, 6, INTEL_FAM6_##model, \ +steppings, X86_FEATURE_ANY, data) + /* * Match specific microcode revisions. * -- 2.21.0
[PATCH 3/3] x86/apic: Convert the TSC deadline timer matching to steppings macro
From: Borislav Petkov ... and get rid of the function pointers which would spit out the microcode revision based on the CPU stepping. Signed-off-by: Borislav Petkov Cc: Peter Zijlstra (Intel) --- arch/x86/kernel/apic/apic.c | 57 - 1 file changed, 12 insertions(+), 45 deletions(-) diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c index e53dda210cd7..4b1d31be50b4 100644 --- a/arch/x86/kernel/apic/apic.c +++ b/arch/x86/kernel/apic/apic.c @@ -544,46 +544,20 @@ static struct clock_event_device lapic_clockevent = { }; static DEFINE_PER_CPU(struct clock_event_device, lapic_events); -static __init u32 hsx_deadline_rev(void) -{ - switch (boot_cpu_data.x86_stepping) { - case 0x02: return 0x3a; /* EP */ - case 0x04: return 0x0f; /* EX */ - } - - return ~0U; -} - -static __init u32 bdx_deadline_rev(void) -{ - switch (boot_cpu_data.x86_stepping) { - case 0x02: return 0x0011; - case 0x03: return 0x070e; - case 0x04: return 0x0f0c; - case 0x05: return 0x0e03; - } - - return ~0U; -} - -static __init u32 skx_deadline_rev(void) -{ - switch (boot_cpu_data.x86_stepping) { - case 0x03: return 0x01000136; - case 0x04: return 0x0214; - } +static const struct x86_cpu_id deadline_match[] __initconst = { + X86_MATCH_INTEL_FAM6_MODEL_STEPPINGS(HASWELL_X, X86_STEPPINGS(0x2, 0x2), 0x3a), /* EP */ + X86_MATCH_INTEL_FAM6_MODEL_STEPPINGS(HASWELL_X, X86_STEPPINGS(0x4, 0x4), 0x0f), /* EX */ - if (boot_cpu_data.x86_stepping > 4) - return 0; + X86_MATCH_INTEL_FAM6_MODEL( BROADWELL_X,0x0b20), - return ~0U; -} + X86_MATCH_INTEL_FAM6_MODEL_STEPPINGS(BROADWELL_D, X86_STEPPINGS(0x2, 0x2), 0x0011), + X86_MATCH_INTEL_FAM6_MODEL_STEPPINGS(BROADWELL_D, X86_STEPPINGS(0x3, 0x3), 0x070e), + X86_MATCH_INTEL_FAM6_MODEL_STEPPINGS(BROADWELL_D, X86_STEPPINGS(0x4, 0x4), 0x0f0c), + X86_MATCH_INTEL_FAM6_MODEL_STEPPINGS(BROADWELL_D, X86_STEPPINGS(0x5, 0x5), 0x0e03), -static const struct x86_cpu_id deadline_match[] __initconst = { - X86_MATCH_INTEL_FAM6_MODEL( HASWELL_X, &hsx_deadline_rev), - X86_MATCH_INTEL_FAM6_MODEL( BROADWELL_X,0x0b20), - X86_MATCH_INTEL_FAM6_MODEL( BROADWELL_D,&bdx_deadline_rev), - X86_MATCH_INTEL_FAM6_MODEL( SKYLAKE_X, &skx_deadline_rev), + X86_MATCH_INTEL_FAM6_MODEL_STEPPINGS(SKYLAKE_X, X86_STEPPINGS(0x3, 0x3), 0x01000136), + X86_MATCH_INTEL_FAM6_MODEL_STEPPINGS(SKYLAKE_X, X86_STEPPINGS(0x4, 0x4), 0x0214), + X86_MATCH_INTEL_FAM6_MODEL_STEPPINGS(SKYLAKE_X, X86_STEPPINGS(0x5, 0xf), 0), X86_MATCH_INTEL_FAM6_MODEL( HASWELL,0x22), X86_MATCH_INTEL_FAM6_MODEL( HASWELL_L, 0x20), @@ -615,14 +589,7 @@ static __init bool apic_validate_deadline_timer(void) if (!m) return true; - /* -* Function pointers will have the MSB set due to address layout, -* immediate revisions will not. -*/ - if ((long)m->driver_data < 0) - rev = ((u32 (*)(void))(m->driver_data))(); - else - rev = (u32)m->driver_data; + rev = (u32)m->driver_data; if (boot_cpu_data.microcode >= rev) return true; -- 2.21.0
[PATCH 1/3] x86/cpu: Add a steppings field to struct x86_cpu_id
From: Mark Gross Intel uses the same family/model for several CPUs. Sometimes the stepping must be checked to tell them apart. On x86 there can be at most 16 steppings. Add a steppings bitmask to x86_cpu_id and a X86_MATCH_VENDOR_FAMILY_MODEL_STEPPING_FEATURE macro and support for matching against family/model/stepping. [ bp: Massage. ] Signed-off-by: Mark Gross Signed-off-by: Borislav Petkov Signed-off-by: Thomas Gleixner Reviewed-by: Tony Luck Reviewed-by: Josh Poimboeuf --- arch/x86/include/asm/cpu_device_id.h | 27 --- arch/x86/kernel/cpu/match.c | 7 ++- include/linux/mod_devicetable.h | 2 ++ 3 files changed, 32 insertions(+), 4 deletions(-) diff --git a/arch/x86/include/asm/cpu_device_id.h b/arch/x86/include/asm/cpu_device_id.h index cf3d621c6892..10426cd56dca 100644 --- a/arch/x86/include/asm/cpu_device_id.h +++ b/arch/x86/include/asm/cpu_device_id.h @@ -20,12 +20,14 @@ #define X86_CENTAUR_FAM6_C7_D 0xd #define X86_CENTAUR_FAM6_NANO 0xf +#define X86_STEPPINGS(mins, maxs)GENMASK(maxs, mins) /** - * X86_MATCH_VENDOR_FAM_MODEL_FEATURE - Base macro for CPU matching + * X86_MATCH_VENDOR_FAM_MODEL_STEPPINGS_FEATURE - Base macro for CPU matching * @_vendor: The vendor name, e.g. INTEL, AMD, HYGON, ..., ANY * The name is expanded to X86_VENDOR_@_vendor * @_family: The family number or X86_FAMILY_ANY * @_model:The model number, model constant or X86_MODEL_ANY + * @_steppings:Bitmask for steppings, stepping constant or X86_STEPPING_ANY * @_feature: A X86_FEATURE bit or X86_FEATURE_ANY * @_data: Driver specific data or NULL. The internal storage * format is unsigned long. The supplied value, pointer @@ -37,15 +39,34 @@ * into another macro at the usage site for good reasons, then please * start this local macro with X86_MATCH to allow easy grepping. */ -#define X86_MATCH_VENDOR_FAM_MODEL_FEATURE(_vendor, _family, _model, \ - _feature, _data) { \ +#define X86_MATCH_VENDOR_FAM_MODEL_STEPPINGS_FEATURE(_vendor, _family, _model, \ + _steppings, _feature, _data) { \ .vendor = X86_VENDOR_##_vendor, \ .family = _family, \ .model = _model, \ + .steppings = _steppings, \ .feature= _feature, \ .driver_data= (unsigned long) _data \ } +/** + * X86_MATCH_VENDOR_FAM_MODEL_FEATURE - Macro for CPU matching + * @_vendor: The vendor name, e.g. INTEL, AMD, HYGON, ..., ANY + * The name is expanded to X86_VENDOR_@_vendor + * @_family: The family number or X86_FAMILY_ANY + * @_model:The model number, model constant or X86_MODEL_ANY + * @_feature: A X86_FEATURE bit or X86_FEATURE_ANY + * @_data: Driver specific data or NULL. The internal storage + * format is unsigned long. The supplied value, pointer + * etc. is casted to unsigned long internally. + * + * The steppings arguments of X86_MATCH_VENDOR_FAM_MODEL_STEPPINGS_FEATURE() is + * set to wildcards. + */ +#define X86_MATCH_VENDOR_FAM_MODEL_FEATURE(vendor, family, model, feature, data) \ + X86_MATCH_VENDOR_FAM_MODEL_STEPPINGS_FEATURE(vendor, family, model, \ + X86_STEPPING_ANY, feature, data) + /** * X86_MATCH_VENDOR_FAM_FEATURE - Macro for matching vendor, family and CPU feature * @vendor:The vendor name, e.g. INTEL, AMD, HYGON, ..., ANY diff --git a/arch/x86/kernel/cpu/match.c b/arch/x86/kernel/cpu/match.c index d3482eb43ff3..ad6776081e60 100644 --- a/arch/x86/kernel/cpu/match.c +++ b/arch/x86/kernel/cpu/match.c @@ -39,13 +39,18 @@ const struct x86_cpu_id *x86_match_cpu(const struct x86_cpu_id *match) const struct x86_cpu_id *m; struct cpuinfo_x86 *c = &boot_cpu_data; - for (m = match; m->vendor | m->family | m->model | m->feature; m++) { + for (m = match; +m->vendor | m->family | m->model | m->steppings | m->feature; +m++) { if (m->vendor != X86_VENDOR_ANY && c->x86_vendor != m->vendor) continue; if (m->family != X86_FAMILY_ANY && c->x86 != m->family) continue; if (m->model != X86_MODEL_ANY && c->x86_model != m->model) continue; + if (m->steppings != X86_STEPPING_ANY && + !(BIT(c->x86_stepping) & m->steppings)) + continue; if (m->feature != X86_FEATURE_ANY && !cpu_has(c, m->feature)) continue; return m; diff --git a/include/linux/mod_devicetable.h b/include/
RE: [PATCH v8 1/3] serial: samsung: Replace rd_regb/wr_regb with rd_reg/wr_reg
On Tuesday, May 5, 2020 at 2020 03:31:00 PM +0900, Greg Kroah-Hartman > On Wed, May 06, 2020 at 08:30:46AM +0900, Hyunki Koo wrote: > > On Tuesday, May 5, 2020 at 2020 11:23:00 PM +0900, Greg Kroah-Hartman > Hartman wrote: > > > On Mon, Apr 20, 2020 at 10:32:56AM +0900, Hyunki Koo wrote: > > > > This patch change the name of macro for general usage. > > > > > > > > Signed-off-by: Hyunki Koo > > > > > > This patch series creates the following build error, which is not > > > allowed: > > > > > > CC [M] drivers/tty/serial/samsung_tty.o > > > drivers/tty/serial/samsung_tty.c:186:13: warning: ‘wr_reg_barrier’ > > > defined but not used [-Wunused-function] > > > 186 | static void wr_reg_barrier(struct uart_port *port, u32 reg, u32 > val) > > > | ^~ > > > > > > Please fix up and resend. Always make sure you keep the reviewed-by > > > tags from others as well. > > > > > > greg k-h > > > > I tested on latest kernel today one more time, there is no error and > warning on my side, not only patch 1/3 and patch 3/3 > > Line 1735: CC drivers/tty/serial/samsung_tty.o > > Line 343: CC drivers/tty/serial/samsung_tty.o > > > > wr_reg_barrier is not defined in patch 1/3, and wr_reg_barrier is > > define and used in patch3/3 it might be no warning. > > After I apply this series, I got the above build warning on my normal > x86 system, so I can not take the patches. Please fix up and resend. > > greg k-h I'm so sorry, There is an warning if CONFIG_SERIAL_SAMSUNG_CONSOLE is not enabled. I've fix the patch and resend Thank you in advance.
Re: [PATCH] arm64/mm: Remove add_huge_page_size()
On Wed, May 06, 2020 at 12:36:43PM +0530, Anshuman Khandual wrote: > > > On 05/06/2020 12:16 PM, Gavin Shan wrote: > > The function add_huge_page_size(), wrapper of hugetlb_add_hstate(), > > avoids to register duplicated huge page states for same size. However, > > the same logic has been included in hugetlb_add_hstate(). So it seems > > unnecessary to keep add_huge_page_size() and this just removes it. > > Makes sense. > > > > > Signed-off-by: Gavin Shan > > --- > > arch/arm64/mm/hugetlbpage.c | 18 +- > > 1 file changed, 5 insertions(+), 13 deletions(-) > > > > diff --git a/arch/arm64/mm/hugetlbpage.c b/arch/arm64/mm/hugetlbpage.c > > index bbeb6a5a6ba6..ed7530413941 100644 > > --- a/arch/arm64/mm/hugetlbpage.c > > +++ b/arch/arm64/mm/hugetlbpage.c > > @@ -441,22 +441,14 @@ void huge_ptep_clear_flush(struct vm_area_struct *vma, > > clear_flush(vma->vm_mm, addr, ptep, pgsize, ncontig); > > } > > > > -static void __init add_huge_page_size(unsigned long size) > > -{ > > - if (size_to_hstate(size)) > > - return; > > - > > - hugetlb_add_hstate(ilog2(size) - PAGE_SHIFT); > > -} > > - > > static int __init hugetlbpage_init(void) > > { > > #ifdef CONFIG_ARM64_4K_PAGES > > - add_huge_page_size(PUD_SIZE); > > + hugetlb_add_hstate(PUD_SHIFT - PAGE_SHIFT); > > #endif > > - add_huge_page_size(CONT_PMD_SIZE); > > - add_huge_page_size(PMD_SIZE); > > - add_huge_page_size(CONT_PTE_SIZE); > > + hugetlb_add_hstate(CONT_PMD_SHIFT + PMD_SHIFT - PAGE_SHIFT); > > + hugetlb_add_hstate(PMD_SHIFT - PAGE_SHIFT); > > + hugetlb_add_hstate(CONT_PTE_SHIFT); Something similar has already been done in linux-next. > Should these page order values be converted into macros instead. Also > we should probably keep (CONT_PTE_SHIFT + PAGE_SHIFT - PAGE_SHIFT) as > is to make things more clear. I think the real confusion stems from us not being consistent with your *_SHIFT definitions on arm64. It's madness for CONT_PTE_SHIFT to be smaller than PAGE_SHIFT imo, but it's just cosmetic I guess. Will
Re: [GIT PULL] vhost: fixes
On Wed, May 06, 2020 at 03:28:47AM +, Justin He wrote: > Hi Michael > > > -Original Message- > > From: Michael S. Tsirkin > > Sent: Monday, May 4, 2020 8:16 PM > > To: Linus Torvalds > > Cc: k...@vger.kernel.org; virtualizat...@lists.linux-foundation.org; > > net...@vger.kernel.org; linux-kernel@vger.kernel.org; Justin He > > ; ldi...@redhat.com; m...@redhat.com; n...@live.com; > > stefa...@redhat.com > > Subject: [GIT PULL] vhost: fixes > > > > The following changes since commit > > 6a8b55ed4056ea5559ebe4f6a4b247f627870d4c: > > > > Linux 5.7-rc3 (2020-04-26 13:51:02 -0700) > > > > are available in the Git repository at: > > > > https://git.kernel.org/pub/scm/linux/kernel/git/mst/vhost.git > > tags/for_linus > > > > for you to fetch changes up to > > 0b841030625cde5f784dd62aec72d6a766faae70: > > > > vhost: vsock: kick send_pkt worker once device is started (2020-05-02 > > 10:28:21 -0400) > > > > > > virtio: fixes > > > > A couple of bug fixes. > > > > Signed-off-by: Michael S. Tsirkin > > > > > > Jia He (1): > > vhost: vsock: kick send_pkt worker once device is started > > Should this fix also be CC-ed to stable? Sorry I forgot to cc it to stable. > > -- > Cheers, > Justin (Jia He) Go ahead, though recently just including Fixes seems to be enough. > > > > > Stefan Hajnoczi (1): > > virtio-blk: handle block_device_operations callbacks after hot unplug > > > > drivers/block/virtio_blk.c | 86 > > +- > > drivers/vhost/vsock.c | 5 +++ > > 2 files changed, 83 insertions(+), 8 deletions(-) > > IMPORTANT NOTICE: The contents of this email and any attachments are > confidential and may also be privileged. If you are not the intended > recipient, please notify the sender immediately and do not disclose the > contents to any other person, use it for any purpose, or store or copy the > information in any medium. Thank you.
[PATCH 0/3] add wakeup_irq for in-band wakeup support
Since some uart controllers may be off in S3, add additional wakeup_irq to support in-band wakeup. Claire Chang (3): serdev: ttyport: add devt for tty port tty: serial_core: add wakeup_irq to support in-band wakeup uart: mediatek: move the in-band wakeup logic to core drivers/tty/serdev/serdev-ttyport.c | 2 ++ drivers/tty/serial/8250/8250_core.c | 1 + drivers/tty/serial/8250/8250_mtk.c | 24 +++- drivers/tty/serial/serial_core.c| 8 +--- include/linux/serial_core.h | 1 + 5 files changed, 12 insertions(+), 24 deletions(-) -- 2.26.2.526.g744177e7f7-goog
[PATCH 1/3] serdev: ttyport: add devt for tty port
serial_match_port() uses devt to match devices. However, when serdev registers a tty port, devt has never been set. This makes device_find_child() always return NULL. Assign devt in serdev_tty_port_register() to fix this. Signed-off-by: Claire Chang --- drivers/tty/serdev/serdev-ttyport.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/tty/serdev/serdev-ttyport.c b/drivers/tty/serdev/serdev-ttyport.c index d367803e2044f..9238119173a47 100644 --- a/drivers/tty/serdev/serdev-ttyport.c +++ b/drivers/tty/serdev/serdev-ttyport.c @@ -267,6 +267,7 @@ struct device *serdev_tty_port_register(struct tty_port *port, { struct serdev_controller *ctrl; struct serport *serport; + dev_t devt = MKDEV(drv->major, drv->minor_start) + idx; int ret; if (!port || !drv || !parent) @@ -282,6 +283,7 @@ struct device *serdev_tty_port_register(struct tty_port *port, serport->tty_drv = drv; ctrl->ops = &ctrl_ops; + ctrl->dev.devt = devt; port->client_ops = &client_ops; port->client_data = ctrl; -- 2.26.2.526.g744177e7f7-goog
Re: [PATCH] efi/libstub/x86: Free EFI map buffer in allocate_e820()
On Tue, 5 May 2020 at 21:00, Lenny Szubowicz wrote: > > In allocate_e820(), free the EFI map buffer that has been returned > by efi_get_memory_map(). The returned size of the EFI map buffer > is used to allocate an adequately sized e820ext buffer, if it's > needed. But the contents of that EFI map buffer is not used at all > and the local pointer to it is gone on return from allocate_e820(). > > Signed-off-by: Lenny Szubowicz > --- > drivers/firmware/efi/libstub/x86-stub.c | 3 +++ > 1 file changed, 3 insertions(+) > > diff --git a/drivers/firmware/efi/libstub/x86-stub.c > b/drivers/firmware/efi/libstub/x86-stub.c > index 05ccb229fb45..4efe3e7a218d 100644 > --- a/drivers/firmware/efi/libstub/x86-stub.c > +++ b/drivers/firmware/efi/libstub/x86-stub.c > @@ -623,6 +623,9 @@ static efi_status_t allocate_e820(struct boot_params > *params, > if (status != EFI_SUCCESS) > return status; > > + /* Allocated EFI map buf is not used here. Just need its size. */ > + efi_bs_call(free_pool, map); > + Wouldn't it be better to call BS->GetMemoryMap() directly here, with a zero size for the input buffer? > nr_desc = buff_size / desc_size; > > if (nr_desc > ARRAY_SIZE(params->e820_table)) { > -- > 2.18.4 >
[PATCH 3/3] uart: mediatek: move the in-band wakeup logic to core
Move the in-band wakeup logic to core so that we can control the wakeup behavior by serdev controller's power/wakeup node and align with other serial drivers. Signed-off-by: Claire Chang --- drivers/tty/serial/8250/8250_mtk.c | 24 +++- 1 file changed, 3 insertions(+), 21 deletions(-) diff --git a/drivers/tty/serial/8250/8250_mtk.c b/drivers/tty/serial/8250/8250_mtk.c index f839380c2f4c1..52cb41e4e493d 100644 --- a/drivers/tty/serial/8250/8250_mtk.c +++ b/drivers/tty/serial/8250/8250_mtk.c @@ -71,7 +71,6 @@ struct mtk8250_data { #ifdef CONFIG_SERIAL_8250_DMA enum dma_rx_status rx_status; #endif - int rx_wakeup_irq; }; /* flow control mode */ @@ -496,6 +495,8 @@ static int mtk8250_probe(struct platform_device *pdev) struct uart_8250_port uart = {}; struct resource *regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); struct resource *irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0); + struct resource *wakeup_irq = + platform_get_resource(pdev, IORESOURCE_IRQ, 1); struct mtk8250_data *data; int err; @@ -525,6 +526,7 @@ static int mtk8250_probe(struct platform_device *pdev) spin_lock_init(&uart.port.lock); uart.port.mapbase = regs->start; uart.port.irq = irq->start; + uart.port.wakeup_irq = wakeup_irq ? wakeup_irq->start : -ENXIO; uart.port.pm = mtk8250_do_pm; uart.port.type = PORT_16550; uart.port.flags = UPF_BOOT_AUTOCONF | UPF_FIXED_PORT; @@ -556,8 +558,6 @@ static int mtk8250_probe(struct platform_device *pdev) if (data->line < 0) return data->line; - data->rx_wakeup_irq = platform_get_irq_optional(pdev, 1); - return 0; } @@ -581,23 +581,9 @@ static int mtk8250_remove(struct platform_device *pdev) static int __maybe_unused mtk8250_suspend(struct device *dev) { struct mtk8250_data *data = dev_get_drvdata(dev); - int irq = data->rx_wakeup_irq; - int err; serial8250_suspend_port(data->line); - pinctrl_pm_select_sleep_state(dev); - if (irq >= 0) { - err = enable_irq_wake(irq); - if (err) { - dev_err(dev, - "failed to enable irq wake on IRQ %d: %d\n", - irq, err); - pinctrl_pm_select_default_state(dev); - serial8250_resume_port(data->line); - return err; - } - } return 0; } @@ -605,12 +591,8 @@ static int __maybe_unused mtk8250_suspend(struct device *dev) static int __maybe_unused mtk8250_resume(struct device *dev) { struct mtk8250_data *data = dev_get_drvdata(dev); - int irq = data->rx_wakeup_irq; - if (irq >= 0) - disable_irq_wake(irq); pinctrl_pm_select_default_state(dev); - serial8250_resume_port(data->line); return 0; -- 2.26.2.526.g744177e7f7-goog
[PATCH 2/3] tty: serial_core: add wakeup_irq to support in-band wakeup
Since some uart controllers may be off in S3, we won't be able to use the normal in-band wakeup. Take 8250_mtk.c as an example. The driver needs to allocate an edge sensitive interrupt as the wakeup_irq and use an addtional pinctrl to reconfigure Rx pin to normal GPIO in sleep state. Once host detects Rx falling, an interrupt is triggered, and the system leaves sleep state. Add the wakeup_irq logic in core to simplify and make the code more generic. Also, we can align with the original wakeup behavior and power/wakeup node. Signed-off-by: Claire Chang --- drivers/tty/serial/8250/8250_core.c | 1 + drivers/tty/serial/serial_core.c| 8 +--- include/linux/serial_core.h | 1 + 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/drivers/tty/serial/8250/8250_core.c b/drivers/tty/serial/8250/8250_core.c index 45d9117cab680..06214e9fdc8ff 100644 --- a/drivers/tty/serial/8250/8250_core.c +++ b/drivers/tty/serial/8250/8250_core.c @@ -1001,6 +1001,7 @@ int serial8250_register_8250_port(struct uart_8250_port *up) uart->port.membase = up->port.membase; uart->port.irq = up->port.irq; uart->port.irqflags = up->port.irqflags; + uart->port.wakeup_irq = up->port.wakeup_irq; uart->port.uartclk = up->port.uartclk; uart->port.fifosize = up->port.fifosize; uart->port.regshift = up->port.regshift; diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c index 66a5e2faf57ea..1796a33986613 100644 --- a/drivers/tty/serial/serial_core.c +++ b/drivers/tty/serial/serial_core.c @@ -2165,12 +2165,13 @@ int uart_suspend_port(struct uart_driver *drv, struct uart_port *uport) struct tty_port *port = &state->port; struct device *tty_dev; struct uart_match match = {uport, drv}; + int irq = uport->wakeup_irq > 0 ? uport->wakeup_irq : uport->irq; mutex_lock(&port->mutex); tty_dev = device_find_child(uport->dev, &match, serial_match_port); if (tty_dev && device_may_wakeup(tty_dev)) { - enable_irq_wake(uport->irq); + enable_irq_wake(irq); put_device(tty_dev); mutex_unlock(&port->mutex); return 0; @@ -2228,13 +2229,14 @@ int uart_resume_port(struct uart_driver *drv, struct uart_port *uport) struct device *tty_dev; struct uart_match match = {uport, drv}; struct ktermios termios; + int irq = uport->wakeup_irq > 0 ? uport->wakeup_irq : uport->irq; mutex_lock(&port->mutex); tty_dev = device_find_child(uport->dev, &match, serial_match_port); if (!uport->suspended && device_may_wakeup(tty_dev)) { - if (irqd_is_wakeup_set(irq_get_irq_data((uport->irq - disable_irq_wake(uport->irq); + if (irqd_is_wakeup_set(irq_get_irq_data((irq + disable_irq_wake(irq); put_device(tty_dev); mutex_unlock(&port->mutex); return 0; diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h index 92f5eba860528..5764687b90a36 100644 --- a/include/linux/serial_core.h +++ b/include/linux/serial_core.h @@ -136,6 +136,7 @@ struct uart_port { struct serial_iso7816 *iso7816); unsigned intirq;/* irq number */ unsigned long irqflags; /* irq flags */ + unsigned intwakeup_irq; /* wakeup irq number */ unsigned intuartclk;/* base uart clock */ unsigned intfifosize; /* tx fifo size */ unsigned char x_char; /* xon/xoff char */ -- 2.26.2.526.g744177e7f7-goog
Re: [PATCH 1/2] riscv: defconfig: enable spi nor on Hifive Unleashed A00 board.
On Mai 06 2020, Anup Patel wrote: > We had build issues in past by selecting major driver subsystems > in Kconfig.socs > > I suggest to select SPI_SIFIVE from Kconfig.socs SPI_SIFIVE can be m, don't override that. Andreas. -- Andreas Schwab, sch...@linux-m68k.org GPG Key fingerprint = 7578 EB47 D4E5 4D69 2510 2552 DF73 E780 A9DA AEC1 "And now for something completely different."
Re: [PATCH v3 0/4] floppy: suppress UBSAN warning in setup_rw_floppy()
On 5/1/20 4:44 PM, Denis Efremov wrote > > The first patch removes pr_cont() in setup_DMA() and prints the contents of > cmd buffer with print_hex_dump(). The last patch also touches these lines > and changes cmd buffer to fullcmd. The 2,3 patches introduce defines to > make it more clear why cmd_count in struct floppy_raw_cmd allows > out-of-bounds access for cmd, reply_count, reply fields. Last patch > handles the warning. Applied, https://github.com/evdenis/linux-floppy/tree/cleanups Denis
Re: [GIT PULL] vhost: fixes
On Wed, May 06, 2020 at 03:19:55AM -0400, Michael S. Tsirkin wrote: > On Wed, May 06, 2020 at 03:28:47AM +, Justin He wrote: > > Hi Michael > > > > > -Original Message- > > > From: Michael S. Tsirkin > > > Sent: Monday, May 4, 2020 8:16 PM > > > To: Linus Torvalds > > > Cc: k...@vger.kernel.org; virtualizat...@lists.linux-foundation.org; > > > net...@vger.kernel.org; linux-kernel@vger.kernel.org; Justin He > > > ; ldi...@redhat.com; m...@redhat.com; n...@live.com; > > > stefa...@redhat.com > > > Subject: [GIT PULL] vhost: fixes > > > > > > The following changes since commit > > > 6a8b55ed4056ea5559ebe4f6a4b247f627870d4c: > > > > > > Linux 5.7-rc3 (2020-04-26 13:51:02 -0700) > > > > > > are available in the Git repository at: > > > > > > https://git.kernel.org/pub/scm/linux/kernel/git/mst/vhost.git > > > tags/for_linus > > > > > > for you to fetch changes up to > > > 0b841030625cde5f784dd62aec72d6a766faae70: > > > > > > vhost: vsock: kick send_pkt worker once device is started (2020-05-02 > > > 10:28:21 -0400) > > > > > > > > > virtio: fixes > > > > > > A couple of bug fixes. > > > > > > Signed-off-by: Michael S. Tsirkin > > > > > > > > > Jia He (1): > > > vhost: vsock: kick send_pkt worker once device is started > > > > Should this fix also be CC-ed to stable? Sorry I forgot to cc it to stable. > > > > -- > > Cheers, > > Justin (Jia He) > > > Go ahead, though recently just including Fixes seems to be enough. You are getting lucky if you only apply a "Fixes:" tag, as that is much lower down our list of things to look at. We are forced to do that because of subsystems and maintainers that do not use the cc: stable tag, as has been documented for the patch 15+ years :( So please be explicit if you know you want it merged to the stable trees, otherwise it is not a guarantee at all if you only use "fixes:". thanks, greg k-h
Re: [PATCH] coresight: dynamic-replicator: Fix handling of multiple connections
Hi Suzuki, Mike, On 2020-04-29 22:41, Sai Prakash Ranjan wrote: Hi Mike, On 2020-04-29 22:28, Mike Leach wrote: Hi, [...] >> > You need to find what is resetting the IDFILTERs to 0 for replicator1. >> > >> >> That is right. >> > > By default all replicators have the IDFILTER registers set to 0 out of > hardware reset. This ensures that programmable replicators behave in > the same way as non-programmable replicators out of reset. > > The dynamic_replicator_reset() is of course a driver state reset - > which filters out all trace on the output ports. The trace is then > enabled when we set the trace path from source to sink. > Thanks for these explanations. > It seems to me that you have 2 problems that need solving here: > > 1) Why does the reset_replicator() called from probe() _not_ work > correctly on replicator 1? It seems to work later if you introduce a > reset after more of the system has powered and booted. This is > startiing to look a little like a PM / clocking issue. reset_replicator() does work in probe correctly for both replicators, below logs is collected before and after reset in probe. It is later that it's set back to 0x0 and hence the suggestion to look at firmware using this replicator1. OK - sorry I read your statement saying that replicator1 was 0 after the reset in probe(), rather than look at the logs. From the logs it is working at the time probe() occurs, but by the time we come to enable the replicator later, something has reset these registers / hardware outside the control of the replicator driver. Yes, I will try to get some more information from the firmware side if there is anything messing up. This turned out to be a clock/pm issue. To confirm, I just marked clk as critical so that it won't be gated and I saw the replicator1(swao_replicator) registers intact after probe. Also alternatively, I tried to comment out disabling pclk to check if there is something wrong in amba pm and this keeps the registers intact as well. @@ -288,7 +295,7 @@ static int amba_probe(struct device *dev) pm_runtime_set_suspended(dev); pm_runtime_put_noidle(dev); - amba_put_disable_pclk(pcdev); + //amba_put_disable_pclk(pcdev); dev_pm_domain_detach(dev, true); } while (0); Thanks, Sai -- QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation
Re: [PATCH net-next 2/2] virtio-net: fix the XDP truesize calculation for mergeable buffers
On Wed, May 06, 2020 at 02:16:33PM +0800, Jason Wang wrote: > We should not exclude headroom and tailroom when XDP is set. So this > patch fixes this by initializing the truesize from PAGE_SIZE when XDP > is set. > > Cc: Jesper Dangaard Brouer > Signed-off-by: Jason Wang Seems too aggressive, we do not use up the whole page for the size. > --- > drivers/net/virtio_net.c | 6 -- > 1 file changed, 4 insertions(+), 2 deletions(-) > > diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c > index 98dd75b665a5..3f3aa8308918 100644 > --- a/drivers/net/virtio_net.c > +++ b/drivers/net/virtio_net.c > @@ -1184,7 +1184,7 @@ static int add_recvbuf_mergeable(struct virtnet_info > *vi, > char *buf; > void *ctx; > int err; > - unsigned int len, hole; > + unsigned int len, hole, truesize; > > /* Extra tailroom is needed to satisfy XDP's assumption. This >* means rx frags coalescing won't work, but consider we've > @@ -1194,6 +1194,7 @@ static int add_recvbuf_mergeable(struct virtnet_info > *vi, > if (unlikely(!skb_page_frag_refill(len + room, alloc_frag, gfp))) > return -ENOMEM; > > + truesize = headroom ? PAGE_SIZE : len; > buf = (char *)page_address(alloc_frag->page) + alloc_frag->offset; > buf += headroom; /* advance address leaving hole at front of pkt */ > get_page(alloc_frag->page); Is this really just on the XDP path? Looks like a confusing way to detect that. > @@ -1205,11 +1206,12 @@ static int add_recvbuf_mergeable(struct virtnet_info > *vi, >* the current buffer. >*/ > len += hole; > + truesize += hole; > alloc_frag->offset += hole; > } > > sg_init_one(rq->sg, buf, len); > - ctx = mergeable_len_to_ctx(len, headroom); > + ctx = mergeable_len_to_ctx(truesize, headroom); > err = virtqueue_add_inbuf_ctx(rq->vq, rq->sg, 1, buf, ctx, gfp); > if (err < 0) > put_page(virt_to_head_page(buf)); > -- > 2.20.1
Re: [PATCH v9 2/3] dt-bindings: serial: Add reg-io-width compatible
On Wed, May 06, 2020 at 04:00:06PM +0900, Hyunki Koo wrote: > Add a description for reg-io-width options for the samsung serial > UART peripheral. > > Signed-off-by: Hyunki Koo > --- > Documentation/devicetree/bindings/serial/samsung_uart.yaml | 8 > 1 file changed, 8 insertions(+) You dropped the reviewed-by tag that Rob gave on the previous version of this patch. Please put that back and resend. thanks, greg k-h
Re: [PATCH 1/4] spi: lantiq: Synchronize interrupt handlers and transfers
On 5/5/2020 7:23 PM, Mark Brown wrote: On Mon, May 04, 2020 at 06:15:47PM +0800, Dilip Kota wrote: On 4/29/2020 8:13 PM, Mark Brown wrote: I just tried to get the history of removing workqueue in SPI driver, on GRX500 (earlier chipset of LGM) the SPI transfers got timedout with workqueues during regression testing. Once changed to threaded IRQs transfers are working successfully. That doesn't really explain why though, it just explains what. I didnt find more information about it. I will work to reproduce the issue and share the detailed information sooner i get the accessibility of the SoC (because of covid19 doing wfh) Regards, Dilip
[PATCH rdma-next 0/9] Enable asynchronous event FD per object
From: Leon Romanovsky >From Yishai: This series enables applicable events objects (i.e. QP, SRQ, CQ, WQ) to be created with their own asynchronous event FD. Before this series any affiliated event on an object was reported on the first asynchronous event FD that was created on the context without the ability to create and use a dedicated FD for it. With this series we enable granularity and control for the usage per object, according to the application's usage. For example, a secondary process that uses the same command FD as of the master one, can create its own objects with its dedicated event FD to be able to get the events for them once occurred, this couldn't be done before this series. To achieve the above, any 'create' method for the applicable objects was extended to get from rdma-core its optional event FD, if wasn't supplied, the default one from the context will be used. As we prefer to not extend the 'write' mode KABIs anymore and fully move to the 'ioct' mode, as part of this extension QP, SRQ and WQ create/destroy commands were introduced over 'ioctl', the CQ KABI was extended over its existing 'ioctl' create command. As part of moving to 'ioctl' for the above objects the frame work was improved to abort a fully created uobject upon some later error, some flows were consolidated with the 'write' mode and few bugs were found and fixed. Yishai Jason Gunthorpe (2): RDMA/core: Allow the ioctl layer to abort a fully created uobject RDMA/core: Consolidate ib_create_srq flows Yishai Hadas (7): IB/uverbs: Refactor related objects to use their own asynchronous event FD IB/uverbs: Extend CQ to get its own asynchronous event FD IB/uverbs: Cleanup wq/srq context usage from uverbs layer IB/uverbs: Introduce create/destroy SRQ commands over ioctl IB/uverbs: Fix create WQ to use the given user handle IB/uverbs: Introduce create/destroy WQ commands over ioctl IB/uverbs: Introduce create/destroy QP commands over ioctl drivers/infiniband/core/Makefile | 5 +- drivers/infiniband/core/rdma_core.c | 28 +- drivers/infiniband/core/rdma_core.h | 7 +- drivers/infiniband/core/uverbs.h | 21 +- drivers/infiniband/core/uverbs_cmd.c | 73 ++-- drivers/infiniband/core/uverbs_ioctl.c| 22 +- drivers/infiniband/core/uverbs_main.c | 16 +- drivers/infiniband/core/uverbs_std_types.c| 95 - drivers/infiniband/core/uverbs_std_types_cq.c | 17 +- drivers/infiniband/core/uverbs_std_types_mr.c | 12 +- drivers/infiniband/core/uverbs_std_types_qp.c | 401 ++ .../infiniband/core/uverbs_std_types_srq.c| 233 ++ drivers/infiniband/core/uverbs_std_types_wq.c | 194 + drivers/infiniband/core/uverbs_uapi.c | 3 + drivers/infiniband/core/verbs.c | 29 +- drivers/infiniband/hw/mlx5/devx.c | 10 +- drivers/infiniband/hw/mlx5/main.c | 24 +- drivers/infiniband/hw/mlx5/qos.c | 13 +- include/rdma/ib_verbs.h | 32 +- include/rdma/uverbs_ioctl.h | 3 + include/rdma/uverbs_std_types.h | 2 +- include/rdma/uverbs_types.h | 3 +- include/uapi/rdma/ib_user_ioctl_cmds.h| 81 include/uapi/rdma/ib_user_ioctl_verbs.h | 43 ++ 24 files changed, 1139 insertions(+), 228 deletions(-) create mode 100644 drivers/infiniband/core/uverbs_std_types_qp.c create mode 100644 drivers/infiniband/core/uverbs_std_types_srq.c create mode 100644 drivers/infiniband/core/uverbs_std_types_wq.c -- 2.26.2
Re: [PATCH v13 02/11] dt-bindings: soc: Add MT8183 power dt-bindings
On Fri, 2020-04-24 at 02:20 +0800, Enric Balletbo Serra wrote: > Hi Weiyi Lu, > > Thank you for the patch. Just a trivial comment below. > > Missatge de Weiyi Lu del dia dv., 20 de març > 2020 a les 8:33: > > > > Add power dt-bindings of MT8183 and introduces "BASIC" and > > "SUBSYS" clock types in binding document. > > The "BASIC" type is compatible to the original power control with > > clock name [a-z]+[0-9]*, e.g. mm, vpu1. > > The "SUBSYS" type is used for bus protection control with clock > > name [a-z]+-[0-9]+, e.g. isp-0, cam-1. > > > > Signed-off-by: Weiyi Lu > > --- > > .../devicetree/bindings/soc/mediatek/scpsys.txt| 20 ++--- > > include/dt-bindings/power/mt8183-power.h | 26 > > ++ > > 2 files changed, 43 insertions(+), 3 deletions(-) > > create mode 100644 include/dt-bindings/power/mt8183-power.h > > > > diff --git a/Documentation/devicetree/bindings/soc/mediatek/scpsys.txt > > b/Documentation/devicetree/bindings/soc/mediatek/scpsys.txt > > index 2bc3677..1baaa6f 100644 > > --- a/Documentation/devicetree/bindings/soc/mediatek/scpsys.txt > > +++ b/Documentation/devicetree/bindings/soc/mediatek/scpsys.txt > > @@ -15,6 +15,7 @@ power/power-domain.yaml. It provides the power domains > > defined in > > - include/dt-bindings/power/mt2701-power.h > > - include/dt-bindings/power/mt2712-power.h > > - include/dt-bindings/power/mt7622-power.h > > +- include/dt-bindings/power/mt8183-power.h > > > > Required properties: > > - compatible: Should be one of: > > @@ -27,12 +28,16 @@ Required properties: > > - "mediatek,mt7623a-scpsys": For MT7623A SoC > > - "mediatek,mt7629-scpsys", "mediatek,mt7622-scpsys": For MT7629 SoC > > - "mediatek,mt8173-scpsys" > > + - "mediatek,mt8183-scpsys" > > - #power-domain-cells: Must be 1 > > - reg: Address range of the SCPSYS unit > > - infracfg: must contain a phandle to the infracfg controller > > -- clock, clock-names: clocks according to the common clock binding. > > - These are clocks which hardware needs to be > > - enabled before enabling certain power domains. > > +- clock, clock-names: Clocks according to the common clock binding. > > + Some SoCs have to groups of clocks. > > + BASIC clocks need to be enabled before enabling the > > + corresponding power domain. > > + SUBSYS clocks need to be enabled before releasing the > > + bus protection. > > Required clocks for MT2701 or MT7623: "mm", "mfg", "ethif" > > Required clocks for MT2712: "mm", "mfg", "venc", "jpgdec", "audio", > > "vdec" > > Required clocks for MT6765: MUX: "mm", "mfg" > > @@ -43,6 +48,15 @@ Required properties: > > Required clocks for MT7622 or MT7629: "hif_sel" > > Required clocks for MT7623A: "ethif" > > Required clocks for MT8173: "mm", "mfg", "venc", "venc_lt" > > + Required clocks for MT8183: BASIC: "audio", "mfg", "mm", "cam", > > "isp", > > + "vpu", "vpu1", "vpu2", "vpu3" > > + SUBSYS: "mm-0", "mm-1", "mm-2", "mm-3", > > + "mm-4", "mm-5", "mm-6", "mm-7", > > + "mm-8", "mm-9", "isp-0", > > "isp-1", > > + "cam-0", "cam-1", "cam-2", > > "cam-3", > > + "cam-4", "cam-5", "cam-6", > > "vpu-0", > > + "vpu-1", "vpu-2", "vpu-3", > > "vpu-4", > > + "vpu-5" > > > > Optional properties: > > - vdec-supply: Power supply for the vdec power domain > > diff --git a/include/dt-bindings/power/mt8183-power.h > > b/include/dt-bindings/power/mt8183-power.h > > new file mode 100644 > > index 000..5c0c8c7 > > --- /dev/null > > +++ b/include/dt-bindings/power/mt8183-power.h > > @@ -0,0 +1,26 @@ > > +/* SPDX-License-Identifier: GPL-2.0 > > This line should end with a '*/' > > > + * > > And this line start with a '/' > Thanks, I'll fix it in next version. > > > + * Copyright (c) 2018 MediaTek Inc. > > + * Author: Weiyi Lu > > + */ > > + > > +#ifndef _DT_BINDINGS_POWER_MT8183_POWER_H > > +#define _DT_BINDINGS_POWER_MT8183_POWER_H > > + > > +#define MT8183_POWER_DOMAIN_AUDIO 0 > > +#define MT8183_POWER_DOMAIN_CONN 1 > > +#define MT8183_POWER_DOMAIN_MFG_ASYNC 2 > > +#define MT8183_POWER_DOMAIN_MFG3 > > +#define MT8183_POWER_DOMAIN_MFG_CORE0 4 > > +#define MT8183_POWER_DOMAIN_MFG_CORE1 5 > > +#define MT8183_POWER_DOMAIN_MFG_2D 6 > > +#define MT8183_POWER_DOMAIN_DISP 7 > > +#define MT8183_POWER_DOMAIN_CAM8 > > +#define MT8183_POWER_DOMAIN_ISP9 > > +#define MT8183_POWER_DOMAIN_VDEC 10 > > +#define MT8183_POWER_DOMAIN_V
Re: [PATCH v13 03/11] soc: mediatek: Add basic_clk_name to scp_power_data
On Fri, 2020-04-24 at 02:20 +0800, Enric Balletbo Serra wrote: > Hi Weiyi Lu, > > Thank you for your patch. > > Missatge de Weiyi Lu del dia dv., 20 de març > 2020 a les 8:33: > > > > Try to stop extending the clk_id or clk_names if there are > > more and more new BASIC clocks. To get its own clocks by the > > basic_clk_name of each power domain. > > And then use basic_clk_name strings for all compatibles, instead of > > mixing clk_id and clk_name. > > > > Signed-off-by: Weiyi Lu > > Reviewed-by: Nicolas Boichat > > --- > > drivers/soc/mediatek/mtk-scpsys.c | 138 > > +- > > 1 file changed, 45 insertions(+), 93 deletions(-) > > > > diff --git a/drivers/soc/mediatek/mtk-scpsys.c > > b/drivers/soc/mediatek/mtk-scpsys.c > > index f669d37..db35a28 100644 > > --- a/drivers/soc/mediatek/mtk-scpsys.c > > +++ b/drivers/soc/mediatek/mtk-scpsys.c > > @@ -78,34 +78,6 @@ > > #define PWR_STATUS_HIF1BIT(26) /* MT7622 */ > > #define PWR_STATUS_WB BIT(27) /* MT7622 */ > > > > -enum clk_id { > > - CLK_NONE, > > - CLK_MM, > > - CLK_MFG, > > - CLK_VENC, > > - CLK_VENC_LT, > > - CLK_ETHIF, > > - CLK_VDEC, > > - CLK_HIFSEL, > > - CLK_JPGDEC, > > - CLK_AUDIO, > > - CLK_MAX, > > -}; > > - > > -static const char * const clk_names[] = { > > - NULL, > > - "mm", > > - "mfg", > > - "venc", > > - "venc_lt", > > - "ethif", > > - "vdec", > > - "hif_sel", > > - "jpgdec", > > - "audio", > > - NULL, > > -}; > > - > > #define MAX_CLKS 3 > > > > /** > > @@ -116,7 +88,7 @@ enum clk_id { > > * @sram_pdn_bits: The mask for sram power control bits. > > * @sram_pdn_ack_bits: The mask for sram power control acked bits. > > * @bus_prot_mask: The mask for single step bus protection. > > - * @clk_id: The basic clocks required by this power domain. > > + * @basic_clk_name: The basic clocks required by this power domain. > > nit: what's the point on telling it basic_? why not just clk_names? > Because I'll introduce subsys clock for bus protection in the PATCH 06. > > * @caps: The flag for active wake-up action. > > */ > > struct scp_domain_data { > > @@ -126,7 +98,7 @@ struct scp_domain_data { > > u32 sram_pdn_bits; > > u32 sram_pdn_ack_bits; > > u32 bus_prot_mask; > > - enum clk_id clk_id[MAX_CLKS]; > > + const char *basic_clk_name[MAX_CLKS]; > > u8 caps; > > }; > > > > @@ -411,12 +383,23 @@ static int scpsys_power_off(struct generic_pm_domain > > *genpd) > > return ret; > > } > > > > -static void init_clks(struct platform_device *pdev, struct clk **clk) > > +static int init_basic_clks(struct platform_device *pdev, struct clk **clk, > > + const char * const *name) > > { > > int i; > > > > - for (i = CLK_NONE + 1; i < CLK_MAX; i++) > > - clk[i] = devm_clk_get(&pdev->dev, clk_names[i]); > > + for (i = 0; i < MAX_CLKS && name[i]; i++) { > > + clk[i] = devm_clk_get(&pdev->dev, name[i]); > > + > > + if (IS_ERR(clk[i])) { > > + dev_err(&pdev->dev, > > + "get basic clk %s fail %ld\n", > > + name[i], PTR_ERR(clk[i])); > > devm_clk_get() will already print an error if fails, this print is > redundant, so you can remove it. > Thanks, I'll fix it in next version. > > > + return PTR_ERR(clk[i]); > > + } > > + } > > + > > + return 0; > > } > > > > static struct scp *init_scp(struct platform_device *pdev, > > @@ -426,9 +409,8 @@ static struct scp *init_scp(struct platform_device > > *pdev, > > { > > struct genpd_onecell_data *pd_data; > > struct resource *res; > > - int i, j; > > + int i, ret; > > struct scp *scp; > > - struct clk *clk[CLK_MAX]; > > > > scp = devm_kzalloc(&pdev->dev, sizeof(*scp), GFP_KERNEL); > > if (!scp) > > @@ -481,8 +463,6 @@ static struct scp *init_scp(struct platform_device > > *pdev, > > > > pd_data->num_domains = num; > > > > - init_clks(pdev, clk); > > - > > for (i = 0; i < num; i++) { > > struct scp_domain *scpd = &scp->domains[i]; > > struct generic_pm_domain *genpd = &scpd->genpd; > > @@ -493,17 +473,9 @@ static struct scp *init_scp(struct platform_device > > *pdev, > > > > scpd->data = data; > > > > - for (j = 0; j < MAX_CLKS && data->clk_id[j]; j++) { > > - struct clk *c = clk[data->clk_id[j]]; > > - > > - if (IS_ERR(c)) { > > - dev_err(&pdev->dev, "%s: clk unavailable\n", > > - data->name); > > - return ERR_CAST(c); > > -
Re: [PATCH v13 05/11] soc: mediatek: Add multiple step bus protection control
On Fri, 2020-04-24 at 02:19 +0800, Enric Balletbo Serra wrote: > Hi Wiyi Lu, > > Thank you for your patch. > > Missatge de Weiyi Lu del dia dv., 20 de març > 2020 a les 8:33: > > > > Both MT8183 & MT6765 have more control steps of bus protection > > than previous project. And there add more bus protection registers > > reside at infracfg & smi-common. > > Extend function to support multiple step bus protection control > > with more customized arguments. > > And then use bp_table for bus protection of all compatibles, > > instead of mixing bus_prot_mask and bus_prot_reg_update. > > > > Signed-off-by: Weiyi Lu > > --- > > drivers/soc/mediatek/mtk-scpsys.c | 206 > > ++ > > drivers/soc/mediatek/scpsys.h | 42 +++- > > 2 files changed, 182 insertions(+), 66 deletions(-) > > > > diff --git a/drivers/soc/mediatek/mtk-scpsys.c > > b/drivers/soc/mediatek/mtk-scpsys.c > > index e50a568..a4fb0b23 100644 > > --- a/drivers/soc/mediatek/mtk-scpsys.c > > +++ b/drivers/soc/mediatek/mtk-scpsys.c > > @@ -88,9 +88,9 @@ > > * @ctl_offs: The offset for main power control register. > > * @sram_pdn_bits: The mask for sram power control bits. > > * @sram_pdn_ack_bits: The mask for sram power control acked bits. > > - * @bus_prot_mask: The mask for single step bus protection. > > * @basic_clk_name: The basic clocks required by this power domain. > > * @caps: The flag for active wake-up action. > > + * @bp_table: The mask table for multiple step bus protection. > > */ > > struct scp_domain_data { > > const char *name; > > @@ -98,9 +98,9 @@ struct scp_domain_data { > > int ctl_offs; > > u32 sram_pdn_bits; > > u32 sram_pdn_ack_bits; > > - u32 bus_prot_mask; > > const char *basic_clk_name[MAX_CLKS]; > > u8 caps; > > + struct bus_prot bp_table[MAX_STEPS]; > > }; > > > > struct scp; > > @@ -124,8 +124,8 @@ struct scp { > > struct device *dev; > > void __iomem *base; > > struct regmap *infracfg; > > + struct regmap *smi_common; > > struct scp_ctrl_reg ctrl_reg; > > - bool bus_prot_reg_update; > > }; > > > > struct scp_subdomain { > > @@ -139,7 +139,6 @@ struct scp_soc_data { > > const struct scp_subdomain *subdomains; > > int num_subdomains; > > const struct scp_ctrl_reg regs; > > - bool bus_prot_reg_update; > > }; > > > > static int scpsys_domain_is_on(struct scp_domain *scpd) > > @@ -249,53 +248,102 @@ static int scpsys_sram_disable(struct scp_domain > > *scpd, void __iomem *ctl_addr) > > MTK_POLL_DELAY_US, MTK_POLL_TIMEOUT); > > } > > > > +static int set_bus_protection(struct regmap *map, struct bus_prot *bp) > > +{ > > + u32 val; > > + u32 set_ofs = bp->set_ofs; > > + u32 en_ofs = bp->en_ofs; > > + u32 sta_ofs = bp->sta_ofs; > > + u32 mask = bp->mask; > > Remove unnecessary local variables (set_ofs, en_ofs, sta_ofs and > mask), and use their bp-> form directly. > OK, I'll fix it. > > + > > + if (set_ofs) > > + regmap_write(map, set_ofs, mask); > > + else > > + regmap_update_bits(map, en_ofs, mask, mask); > > + > > + return regmap_read_poll_timeout(map, sta_ofs, > > + val, (val & mask) == mask, > > + MTK_POLL_DELAY_US, MTK_POLL_TIMEOUT); > > +} > > + > > +static int clear_bus_protection(struct regmap *map, struct bus_prot *bp) > > +{ > > + u32 val; > > + u32 clr_ofs = bp->clr_ofs; > > + u32 en_ofs = bp->en_ofs; > > + u32 sta_ofs = bp->sta_ofs; > > + u32 mask = bp->mask; > > + bool ignore_ack = bp->ignore_clr_ack; > > Remove unnecessary local variables (clr_ofs, en_ofs, sta_ofs, mask and > ignore_ack), and use their bp-> form directly. > OK, I'll fix it. > > + > > + if (clr_ofs) > > + regmap_write(map, clr_ofs, mask); > > + else > > + regmap_update_bits(map, en_ofs, mask, 0); > > + > > + if (ignore_ack) > > + return 0; > > + > > + return regmap_read_poll_timeout(map, sta_ofs, > > + val, !(val & mask), > > + MTK_POLL_DELAY_US, MTK_POLL_TIMEOUT); > > +} > > + > > static int scpsys_bus_protect_enable(struct scp_domain *scpd) > > { > > struct scp *scp = scpd->scp; > > + const struct bus_prot *bp_table = scpd->data->bp_table; > > struct regmap *infracfg = scp->infracfg; > > - u32 mask = scpd->data->bus_prot_mask; > > - bool reg_update = scp->bus_prot_reg_update; > > - u32 val; > > - int ret; > > No need to remove ret if you're going to add anyway later. > Got it. > > + struct regmap *smi_common = scp->smi_common; > > + int i; > > > > - if (!mask) > > - return 0; > > + for (i = 0; i < MAX_STEPS; i++) { > > + struct regmap *map = NULL; > > De
Re: [PATCH v13 04/11] soc: mediatek: Remove infracfg misc driver support
On Fri, 2020-04-24 at 02:19 +0800, Enric Balletbo Serra wrote: > Hi Weiyi Lu, > > Thank you for the patch > > Missatge de Weiyi Lu del dia dv., 20 de març > 2020 a les 8:33: > > > > The functions provided by infracfg misc driver have no other user except > > the scpsys driver so move those into scpsys driver directly. > > And then, remove infracfg misc drvier which is no longer being used. > > BTW, in next patch, we're going to extend the bus protection functions > > with more customized arguments. > > > > Signed-off-by: Weiyi Lu > > --- > > drivers/soc/mediatek/Kconfig | 10 - > > drivers/soc/mediatek/Makefile | 1 - > > drivers/soc/mediatek/mtk-infracfg.c | 79 > > --- > > drivers/soc/mediatek/mtk-scpsys.c | 44 +++ > > drivers/soc/mediatek/scpsys.h | 28 + > > include/linux/soc/mediatek/infracfg.h | 39 - > > 6 files changed, 63 insertions(+), 138 deletions(-) > > delete mode 100644 drivers/soc/mediatek/mtk-infracfg.c > > create mode 100644 drivers/soc/mediatek/scpsys.h > > delete mode 100644 include/linux/soc/mediatek/infracfg.h > > > > diff --git a/drivers/soc/mediatek/Kconfig b/drivers/soc/mediatek/Kconfig > > index 2114b56..f837b3c 100644 > > --- a/drivers/soc/mediatek/Kconfig > > +++ b/drivers/soc/mediatek/Kconfig > > @@ -10,21 +10,12 @@ config MTK_CMDQ > > depends on ARCH_MEDIATEK || COMPILE_TEST > > select MAILBOX > > select MTK_CMDQ_MBOX > > - select MTK_INFRACFG > > help > > Say yes here to add support for the MediaTek Command Queue (CMDQ) > > driver. The CMDQ is used to help read/write registers with > > critical > > time limitation, such as updating display configuration during the > > vblank. > > > > -config MTK_INFRACFG > > - bool "MediaTek INFRACFG Support" > > - select REGMAP > > - help > > - Say yes here to add support for the MediaTek INFRACFG controller. > > The > > - INFRACFG controller contains various infrastructure registers not > > - directly associated to any device. > > - > > config MTK_PMIC_WRAP > > tristate "MediaTek PMIC Wrapper Support" > > depends on RESET_CONTROLLER > > @@ -38,7 +29,6 @@ config MTK_SCPSYS > > bool "MediaTek SCPSYS Support" > > default ARCH_MEDIATEK > > select REGMAP > > - select MTK_INFRACFG > > select PM_GENERIC_DOMAINS if PM > > help > > Say yes here to add support for the MediaTek SCPSYS power domain > > diff --git a/drivers/soc/mediatek/Makefile b/drivers/soc/mediatek/Makefile > > index b017330..2b2c2537 100644 > > --- a/drivers/soc/mediatek/Makefile > > +++ b/drivers/soc/mediatek/Makefile > > @@ -1,5 +1,4 @@ > > # SPDX-License-Identifier: GPL-2.0-only > > obj-$(CONFIG_MTK_CMDQ) += mtk-cmdq-helper.o > > -obj-$(CONFIG_MTK_INFRACFG) += mtk-infracfg.o > > obj-$(CONFIG_MTK_PMIC_WRAP) += mtk-pmic-wrap.o > > obj-$(CONFIG_MTK_SCPSYS) += mtk-scpsys.o > > diff --git a/drivers/soc/mediatek/mtk-infracfg.c > > b/drivers/soc/mediatek/mtk-infracfg.c > > deleted file mode 100644 > > index 341c7ac..000 > > --- a/drivers/soc/mediatek/mtk-infracfg.c > > +++ /dev/null > > @@ -1,79 +0,0 @@ > > -// SPDX-License-Identifier: GPL-2.0-only > > -/* > > - * Copyright (c) 2015 Pengutronix, Sascha Hauer > > - */ > > - > > -#include > > -#include > > -#include > > -#include > > -#include > > - > > -#define MTK_POLL_DELAY_US 10 > > -#define MTK_POLL_TIMEOUT(jiffies_to_usecs(HZ)) > > - > > -#define INFRA_TOPAXI_PROTECTEN 0x0220 > > -#define INFRA_TOPAXI_PROTECTSTA1 0x0228 > > -#define INFRA_TOPAXI_PROTECTEN_SET 0x0260 > > -#define INFRA_TOPAXI_PROTECTEN_CLR 0x0264 > > - > > -/** > > - * mtk_infracfg_set_bus_protection - enable bus protection > > - * @regmap: The infracfg regmap > > - * @mask: The mask containing the protection bits to be enabled. > > - * @reg_update: The boolean flag determines to set the protection bits > > - * by regmap_update_bits with enable register(PROTECTEN) or > > - * by regmap_write with set register(PROTECTEN_SET). > > - * > > - * This function enables the bus protection bits for disabled power > > - * domains so that the system does not hang when some unit accesses the > > - * bus while in power down. > > - */ > > -int mtk_infracfg_set_bus_protection(struct regmap *infracfg, u32 mask, > > - bool reg_update) > > -{ > > - u32 val; > > - int ret; > > - > > - if (reg_update) > > - regmap_update_bits(infracfg, INFRA_TOPAXI_PROTECTEN, mask, > > - mask); > > - else > > - regmap_write(infracfg, INFRA_TOPAXI_PROTECTEN_SET, mask); > > - > > - ret = regmap_read_poll_timeout(infracfg, INFRA_TOPAXI_PROTECTSTA1, > > - val, (val & mask) == mask, > > -
Re: [PATCH v13 06/11] soc: mediatek: Add subsys clock control for bus protection
On Fri, 2020-04-24 at 02:19 +0800, Enric Balletbo Serra wrote: > Hi Weiyi Lu, > > Thank you for the patch. > > Missatge de Weiyi Lu del dia dv., 20 de març > 2020 a les 8:33: > > > > For the bus protection operations, some subsys clocks need to be enabled > > before releasing the protection, and vise versa. > > typo s/vise/vice/ Thanks, I'll fix it. > > > But those subsys clocks could only be controlled once its corresponding > > power domain is turned on first. > > In this patch, we add the subsys clock control into its relavent steps. > > typo s/relavent/relevant/ > Thanks, I'll fix it. > > > > Signed-off-by: Weiyi Lu > > --- > > drivers/soc/mediatek/mtk-scpsys.c | 71 > > +-- > > 1 file changed, 69 insertions(+), 2 deletions(-) > > > > diff --git a/drivers/soc/mediatek/mtk-scpsys.c > > b/drivers/soc/mediatek/mtk-scpsys.c > > index a4fb0b23..2a9478f 100644 > > --- a/drivers/soc/mediatek/mtk-scpsys.c > > +++ b/drivers/soc/mediatek/mtk-scpsys.c > > @@ -80,6 +80,7 @@ > > #define PWR_STATUS_WB BIT(27) /* MT7622 */ > > > > #define MAX_CLKS 3 > > +#define MAX_SUBSYS_CLKS 10 > > > > /** > > * struct scp_domain_data - scp domain data for power on/off flow > > @@ -89,6 +90,8 @@ > > * @sram_pdn_bits: The mask for sram power control bits. > > * @sram_pdn_ack_bits: The mask for sram power control acked bits. > > * @basic_clk_name: The basic clocks required by this power domain. > > + * @subsys_clk_prefix: The prefix name of the clocks need to be enabled > > + * before releasing bus protection. > > * @caps: The flag for active wake-up action. > > * @bp_table: The mask table for multiple step bus protection. > > */ > > @@ -99,6 +102,7 @@ struct scp_domain_data { > > u32 sram_pdn_bits; > > u32 sram_pdn_ack_bits; > > const char *basic_clk_name[MAX_CLKS]; > > + const char *subsys_clk_prefix; > > u8 caps; > > struct bus_prot bp_table[MAX_STEPS]; > > }; > > @@ -109,6 +113,7 @@ struct scp_domain { > > struct generic_pm_domain genpd; > > struct scp *scp; > > struct clk *clk[MAX_CLKS]; > > + struct clk *subsys_clk[MAX_SUBSYS_CLKS]; > > const struct scp_domain_data *data; > > struct regulator *supply; > > }; > > @@ -384,16 +389,22 @@ static int scpsys_power_on(struct generic_pm_domain > > *genpd) > > val |= PWR_RST_B_BIT; > > writel(val, ctl_addr); > > > > - ret = scpsys_sram_enable(scpd, ctl_addr); > > + ret = scpsys_clk_enable(scpd->subsys_clk, MAX_SUBSYS_CLKS); > > if (ret < 0) > > goto err_pwr_ack; > > > > + ret = scpsys_sram_enable(scpd, ctl_addr); > > + if (ret < 0) > > + goto err_sram; > > + > > ret = scpsys_bus_protect_disable(scpd); > > if (ret < 0) > > - goto err_pwr_ack; > > + goto err_sram; > > > > return 0; > > > > +err_sram: > > + scpsys_clk_disable(scpd->subsys_clk, MAX_SUBSYS_CLKS); > > err_pwr_ack: > > scpsys_clk_disable(scpd->clk, MAX_CLKS); > > err_clk: > > @@ -420,6 +431,8 @@ static int scpsys_power_off(struct generic_pm_domain > > *genpd) > > if (ret < 0) > > goto out; > > > > + scpsys_clk_disable(scpd->subsys_clk, MAX_SUBSYS_CLKS); > > + > > /* subsys power off */ > > val = readl(ctl_addr); > > val |= PWR_ISO_BIT; > > @@ -457,6 +470,48 @@ static int scpsys_power_off(struct generic_pm_domain > > *genpd) > > return ret; > > } > > > > +static int init_subsys_clks(struct platform_device *pdev, > > + const char *prefix, struct clk **clk) > > +{ > > + struct device_node *node = pdev->dev.of_node; > > + u32 prefix_len, sub_clk_cnt = 0; > > + struct property *prop; > > + const char *clk_name; > > + > > + if (!node) { > > Is this possible? I suspect you can remove this check. > You're right. It never happens, I'll remove it. > > + dev_err(&pdev->dev, "Cannot find scpsys node: %ld\n", > > + PTR_ERR(node)); > > + return PTR_ERR(node); > > + } > > + > > + prefix_len = strlen(prefix); > > + > > + of_property_for_each_string(node, "clock-names", prop, clk_name) { > > + if (!strncmp(clk_name, prefix, prefix_len) && > > + (clk_name[prefix_len] == '-')) { > > + if (sub_clk_cnt >= MAX_SUBSYS_CLKS) { > > + dev_err(&pdev->dev, > > + "subsys clk out of range %d\n", > > + sub_clk_cnt); > > + return -EINVAL; > > + } > > + > > + clk[sub_clk_cnt] = devm_clk_get(&pdev->dev, > > + clk_name); > > + > > +
Re: [patch V4 part 2 13/18] x86/kvm: Move context tracking where it belongs
On 05/05/20 15:41, Thomas Gleixner wrote: > Context tracking for KVM happens way too early in the vcpu_run() > code. Anything after guest_enter_irqoff() and before guest_exit_irqoff() > cannot use RCU and should also be not instrumented. > > The current way of doing this covers way too much code. Move it closer to > the actual vmenter/exit code. > > Signed-off-by: Thomas Gleixner > Cc: Paolo Bonzini > Cc: Sean Christopherson > --- > arch/x86/kvm/svm/svm.c | 16 > arch/x86/kvm/vmx/vmx.c | 10 ++ > arch/x86/kvm/x86.c |2 -- > 3 files changed, 26 insertions(+), 2 deletions(-) > > --- a/arch/x86/kvm/svm/svm.c > +++ b/arch/x86/kvm/svm/svm.c > @@ -3330,6 +3330,14 @@ static void svm_vcpu_run(struct kvm_vcpu >*/ > x86_spec_ctrl_set_guest(svm->spec_ctrl, svm->virt_spec_ctrl); > > + /* > + * Tell context tracking that this CPU is about to enter guest > + * mode. This has to be after x86_spec_ctrl_set_guest() because > + * that can take locks (lockdep needs RCU) and calls into world and > + * some more. > + */ > + guest_enter_irqoff(); > + > __svm_vcpu_run(svm->vmcb_pa, (unsigned long *)&svm->vcpu.arch.regs); > > #ifdef CONFIG_X86_64 > @@ -3340,6 +3348,14 @@ static void svm_vcpu_run(struct kvm_vcpu > loadsegment(gs, svm->host.gs); > #endif > #endif > + /* > + * Tell context tracking that this CPU is back. > + * > + * This needs to be done before the below as native_read_msr() > + * contains a tracepoint and x86_spec_ctrl_restore_host() calls > + * into world and some more. > + */ > + guest_exit_irqoff(); > > /* >* We do not use IBRS in the kernel. If this vCPU has used the > --- a/arch/x86/kvm/vmx/vmx.c > +++ b/arch/x86/kvm/vmx/vmx.c > @@ -6603,6 +6603,11 @@ static void vmx_vcpu_run(struct kvm_vcpu >*/ > x86_spec_ctrl_set_guest(vmx->spec_ctrl, 0); > > + /* > + * Tell context tracking that this CPU is about to enter guest mode. > + */ > + guest_enter_irqoff(); > + > /* L1D Flush includes CPU buffer clear to mitigate MDS */ > if (static_branch_unlikely(&vmx_l1d_should_flush)) > vmx_l1d_flush(vcpu); > @@ -6618,6 +6623,11 @@ static void vmx_vcpu_run(struct kvm_vcpu > vcpu->arch.cr2 = read_cr2(); > > /* > + * Tell context tracking that this CPU is back. > + */ > + guest_exit_irqoff(); > + > + /* >* We do not use IBRS in the kernel. If this vCPU has used the >* SPEC_CTRL MSR it may have left it on; save the value and >* turn it off. This is much more efficient than blindly adding > --- a/arch/x86/kvm/x86.c > +++ b/arch/x86/kvm/x86.c > @@ -8404,7 +8404,6 @@ static int vcpu_enter_guest(struct kvm_v > } > > trace_kvm_entry(vcpu->vcpu_id); > - guest_enter_irqoff(); > > fpregs_assert_state_consistent(); > if (test_thread_flag(TIF_NEED_FPU_LOAD)) > @@ -8467,7 +8466,6 @@ static int vcpu_enter_guest(struct kvm_v > local_irq_disable(); > kvm_after_interrupt(vcpu); > > - guest_exit_irqoff(); > if (lapic_in_kernel(vcpu)) { > s64 delta = vcpu->arch.apic->lapic_timer.advance_expire_delta; > if (delta != S64_MIN) { > Acked-by: Paolo Bonzini
Re: [PATCH V2 1/3] arm64/mm: Drop __HAVE_ARCH_HUGE_PTEP_GET
On Wed, May 06, 2020 at 11:42:12AM +0530, Anshuman Khandual wrote: > Platform specific huge_ptep_get() is required only when fetching the huge > PTE involves more than just dereferencing the page table pointer. This is > not the case on arm64 platform. Hence huge_ptep_pte() can be dropped along > with it's __HAVE_ARCH_HUGE_PTEP_GET subscription. > > Cc: Catalin Marinas > Cc: Will Deacon > Cc: Andrew Morton > Cc: linux-arm-ker...@lists.infradead.org > Cc: linux...@kvack.org > Cc: linux-kernel@vger.kernel.org > Signed-off-by: Anshuman Khandual > --- > arch/arm64/include/asm/hugetlb.h | 6 -- > 1 file changed, 6 deletions(-) > > diff --git a/arch/arm64/include/asm/hugetlb.h > b/arch/arm64/include/asm/hugetlb.h > index 2eb6c234d594..b88878ddc88b 100644 > --- a/arch/arm64/include/asm/hugetlb.h > +++ b/arch/arm64/include/asm/hugetlb.h > @@ -17,12 +17,6 @@ > extern bool arch_hugetlb_migration_supported(struct hstate *h); > #endif > > -#define __HAVE_ARCH_HUGE_PTEP_GET > -static inline pte_t huge_ptep_get(pte_t *ptep) > -{ > - return READ_ONCE(*ptep); > -} Hmm, I'm nervous about dropping the READ_ONCE() here. We added them after running into page-table issues with THP [1] and it's really important to use them consistently to avoid hitting that again. If the generic code used READ_ONCE(), I'd be happy to switch to it. Will [1] https://lore.kernel.org/lkml/1506527369-19535-1-git-send-email-will.dea...@arm.com/
Re: [f2fs-dev] [PATCH] f2fs: change maximum zstd compression buffer size
On 2020/5/6 7:05, Jaegeuk Kim wrote: > On 05/05, Chao Yu wrote: >> On 2020-5-4 22:30, Jaegeuk Kim wrote: >>> From: Daeho Jeong >>> >>> Current zstd compression buffer size is one page and header size less >>> than cluster size. By this, zstd compression always succeeds even if >>> the real compression data is failed to fit into the buffer size, and >>> eventually reading the cluster returns I/O error with the corrupted >>> compression data. >> >> What's the root cause of this issue? I didn't get it. >> >>> >>> Signed-off-by: Daeho Jeong >>> --- >>> fs/f2fs/compress.c | 4 ++-- >>> 1 file changed, 2 insertions(+), 2 deletions(-) >>> >>> diff --git a/fs/f2fs/compress.c b/fs/f2fs/compress.c >>> index 4c7eaeee52336..a9fa8049b295f 100644 >>> --- a/fs/f2fs/compress.c >>> +++ b/fs/f2fs/compress.c >>> @@ -313,7 +313,7 @@ static int zstd_init_compress_ctx(struct compress_ctx >>> *cc) >>> cc->private = workspace; >>> cc->private2 = stream; >>> >>> - cc->clen = cc->rlen - PAGE_SIZE - COMPRESS_HEADER_SIZE; >>> + cc->clen = ZSTD_compressBound(PAGE_SIZE << cc->log_cluster_size); >> >> In my machine, the value is 66572 which is much larger than size of dst >> buffer, so, in where we can tell the real size of dst buffer to zstd >> compressor? Otherwise, if compressed data size is larger than dst buffer >> size, when we flush compressed data into dst buffer, we may suffer overflow. > > Could you give it a try compress_log_size=2 and check decompression works? I tried some samples before submitting the patch, did you encounter app's data corruption when using zstd algorithm? If so, let me check this issue. Thanks, > >> >>> return 0; >>> } >>> >>> @@ -330,7 +330,7 @@ static int zstd_compress_pages(struct compress_ctx *cc) >>> ZSTD_inBuffer inbuf; >>> ZSTD_outBuffer outbuf; >>> int src_size = cc->rlen; >>> - int dst_size = src_size - PAGE_SIZE - COMPRESS_HEADER_SIZE; >>> + int dst_size = cc->clen; >>> int ret; >>> >>> inbuf.pos = 0; >>> > > > ___ > Linux-f2fs-devel mailing list > linux-f2fs-de...@lists.sourceforge.net > https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel > . >
[PATCH rdma-next 00/10] Various clean ups to ib_cm
From: Leon Romanovsky >From Jason, These are intended to be no-functional change edits that tidy up the code flow or coding style. Thanks Danit Goldberg (1): RDMA/cm: Remove unused store to ret in cm_rej_handler Jason Gunthorpe (9): RDMA/addr: Mark addr_resolve as might_sleep() RDMA/cm: Remove return code from add_cm_id_to_port_list RDMA/cm: Pull duplicated code into cm_queue_work_unlock() RDMA/cm: Pass the cm_id_private into cm_cleanup_timewait RDMA/cm: Add a note explaining how the timewait is eventually freed RDMA/cm: Make find_remote_id() return a cm_id_private RDMA/cm: Remove the cm_free_id() wrapper function RDMA/cm: Remove needless cm_id variable RDMA/cm: Increment the refcount inside cm_find_listen() drivers/infiniband/core/addr.c | 4 + drivers/infiniband/core/cm.c | 239 +++-- 2 files changed, 85 insertions(+), 158 deletions(-) -- 2.26.2
[PATCH -next] scsi: qla2xxx: Use PTR_ERR_OR_ZERO() to simplify code
Fixes coccicheck warning: drivers/scsi/qla2xxx/tcm_qla2xxx.c:1488:1-3: WARNING: PTR_ERR_OR_ZERO can be used Reported-by: Hulk Robot Signed-off-by: Samuel Zou --- drivers/scsi/qla2xxx/tcm_qla2xxx.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/scsi/qla2xxx/tcm_qla2xxx.c b/drivers/scsi/qla2xxx/tcm_qla2xxx.c index 1f0a185..7c4157e 100644 --- a/drivers/scsi/qla2xxx/tcm_qla2xxx.c +++ b/drivers/scsi/qla2xxx/tcm_qla2xxx.c @@ -1485,10 +1485,8 @@ static int tcm_qla2xxx_check_initiator_node_acl( sizeof(struct qla_tgt_cmd), TARGET_PROT_ALL, port_name, qlat_sess, tcm_qla2xxx_session_cb); - if (IS_ERR(se_sess)) - return PTR_ERR(se_sess); - return 0; + return PTR_ERR_OR_ZERO(se_sess); } static void tcm_qla2xxx_update_sess(struct fc_port *sess, port_id_t s_id, -- 2.6.2
Re: [PATCH v2] usb: usbfs: correct kernel->user page attribute mismatch
On 20-05-04 15:13:48, Jeremy Linton wrote: > On some architectures (e.g. arm64) requests for > IO coherent memory may use non-cachable attributes if > the relevant device isn't cache coherent. If these > pages are then remapped into userspace as cacheable, > they may not be coherent with the non-cacheable mappings. > > In particular this happens with libusb, when it attempts > to create zero-copy buffers for use by rtl-sdr > (https://eur01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Fosmocom%2Frtl-sdr%2F&data=02%7C01%7Cpeter.chen%40nxp.com%7Cb088a6f1a4d5462d65e808d7f067b1b2%7C686ea1d3bc2b4c6fa92cd99c5c301635%7C0%7C1%7C637242200467457447&sdata=nPbLuHBIWqKSc0h4UGqRBv7W7wcQ0SYwq51ggLVcBVs%3D&reserved=0). > On low end arm > devices with non-coherent USB ports, the application will > be unexpectedly killed, while continuing to work fine on > arm machines with coherent USB controllers. > > This bug has been discovered/reported a few times over > the last few years. In the case of rtl-sdr a compile time > option to enable/disable zero copy was implemented to > work around it. > > Rather than relaying on application specific workarounds, > dma_mmap_coherent() can be used instead of remap_pfn_range(). > The page cache/etc attributes will then be correctly set in > userspace to match the kernel mapping. > > Signed-off-by: Jeremy Linton > --- > v1->v2: > Update commit message and change to dma_mmap_coherent() > from dma_mmap_attr(,,,0) which are the same. > > drivers/usb/core/devio.c | 5 ++--- > 1 file changed, 2 insertions(+), 3 deletions(-) > > diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c > index 6833c918abce..b9db9812d6c5 100644 > --- a/drivers/usb/core/devio.c > +++ b/drivers/usb/core/devio.c > @@ -217,6 +217,7 @@ static int usbdev_mmap(struct file *file, struct > vm_area_struct *vma) > { > struct usb_memory *usbm = NULL; > struct usb_dev_state *ps = file->private_data; > + struct usb_hcd *hcd = bus_to_hcd(ps->dev->bus); > size_t size = vma->vm_end - vma->vm_start; > void *mem; > unsigned long flags; > @@ -250,9 +251,7 @@ static int usbdev_mmap(struct file *file, struct > vm_area_struct *vma) > usbm->vma_use_count = 1; > INIT_LIST_HEAD(&usbm->memlist); > > - if (remap_pfn_range(vma, vma->vm_start, > - virt_to_phys(usbm->mem) >> PAGE_SHIFT, > - size, vma->vm_page_prot) < 0) { > + if (dma_mmap_coherent(hcd->self.sysdev, vma, mem, dma_handle, size)) { > dec_usb_memory_use_count(usbm, &usbm->vma_use_count); > return -EAGAIN; > } > -- > 2.24.1 > Tested at NXP imx8qm (ARM64) platform, it fixes mmap issue for using libusb. I am not sure if it covers all use cases at hcd_buffer_alloc. -- Thanks, Peter Chen
RE: [PATCH v3 4/4] MAINTAINERS: Add IPK MIPI DSI Host driver entry
From: Joe Perches Date: Mon, Apr 27, 2020 at 15:45:17 > On Mon, 2020-04-27 at 16:00 +0200, Angelo Ribeiro wrote: > > Creates entry for Synopsys DesignWare IPK DRM driver and > > adds myself as maintainer. > [] > > diff --git a/MAINTAINERS b/MAINTAINERS > [] > > @@ -5507,6 +5507,14 @@ T: git git://anongit.freedesktop.org/drm/drm-misc > > F: Documentation/devicetree/bindings/display/ste,mcde.txt > > F: drivers/gpu/drm/mcde/ > > > > +DRM DRIVER FOR SYNOPSYS DESIGNWARE IPK > > +M: Angelo Ribeiro > > +L: dri-de...@lists.freedesktop.org > > +S: Maintained > > +F: drivers/gpu/drm/ipk/ > > +F: Documentation/devicetree/bindings/display/ipk/ > > +T: git git://anongit.freedesktop.org/drm/drm-misc > > There is now a preferred order for the entries in a section. > > Please use: > > DRM DRIVER FOR SYNOPSYS DESIGNWARE IPK > M:Angelo Ribeiro > L:dri-de...@lists.freedesktop.org> > S:Maintained > T:git git://anongit.freedesktop.org/drm/drm-misc > F:Document > ation/devicetree/bindings/display/ipk/> > F:drivers/gpu/drm/ipk/ Hi Joe, Thanks for the review I will apply it. Angelo
Re: cgroup pointed by sock is leaked on mode switch
On 2020/5/6 10:16, Zefan Li wrote: On 2020/5/6 9:50, Yang Yingliang wrotee: +cc lize...@huawei.com On 2020/5/6 0:06, Tejun Heo wrote: Hello, Yang. On Sat, May 02, 2020 at 06:27:21PM +0800, Yang Yingliang wrote: I find the number nr_dying_descendants is increasing: linux-dVpNUK:~ # find /sys/fs/cgroup/ -name cgroup.stat -exec grep '^nr_dying_descendants [^0]' {} + /sys/fs/cgroup/unified/cgroup.stat:nr_dying_descendants 80 /sys/fs/cgroup/unified/system.slice/cgroup.stat:nr_dying_descendants 1 /sys/fs/cgroup/unified/system.slice/system-hostos.slice/cgroup.stat:nr_dying_descendants 1 /sys/fs/cgroup/unified/lxc/cgroup.stat:nr_dying_descendants 79 /sys/fs/cgroup/unified/lxc/5f1fdb8c54fa40c3e599613dab6e4815058b76ebada8a27bc1fe80c0d4801764/cgroup.stat:nr_dying_descendants 78 /sys/fs/cgroup/unified/lxc/5f1fdb8c54fa40c3e599613dab6e4815058b76ebada8a27bc1fe80c0d4801764/system.slice/cgroup.stat:nr_dying_descendants 78 Those numbers are nowhere close to causing oom issues. There are some aspects of page and other cache draining which is being improved but unless you're seeing numbers multiple orders of magnitude higher, this isn't the source of your problem. The situation is as same as the commit bd1060a1d671 ("sock, cgroup: add sock->sk_cgroup") describes. "On mode switch, cgroup references which are already being pointed to by socks may be leaked." I'm doubtful that you're hitting that issue. Mode switching means memcg being switched between cgroup1 and cgroup2 hierarchies, which is unlikely to be what's happening when you're launching docker containers. The first step would be identifying where memory is going and finding out whether memcg is actually being switched between cgroup1 and 2 - look at the hierarchy number in /proc/cgroups, if that's switching between 0 and someting not zero, it is switching. I think there's a bug here which can lead to unlimited memory leak. This should reproduce the bug: # mount -t cgroup -o netprio xxx /cgroup/netprio # mkdir /cgroup/netprio/xxx # echo PID > /cgroup/netprio/xxx/tasks /* this PID process starts to do some network thing and then exits */ # rmdir /cgroup/netprio/xxx /* now this cgroup will never be freed */ Correction (still not tested): # mount -t cgroup2 none /cgroup/v2 # mkdir /cgroup/v2/xxx # echo PID > /cgroup/v2/xxx/cgroup.procs /* this PID process starts to do some network thing */ # mount -t cgroup -o netprio xxx /cgroup/netprio # mkdir /cgroup/netprio/xxx # echo PID > /cgroup/netprio/xxx/tasks ... /* the PID process exits */ rmdir /cgroup/netprio/xxx rmdir /cgroup/v2/xxx /* now looks like this v2 cgroup will never be freed */ Look at the code: static inline void sock_update_netprioidx(struct sock_cgroup_data *skcd) { ... sock_cgroup_set_prioidx(skcd, task_netprioidx(current)); } static inline void sock_cgroup_set_prioidx(struct sock_cgroup_data *skcd, u16 prioidx) { ... if (sock_cgroup_prioidx(&skcd_buf) == prioidx) return ; ... skcd_buf.prioidx = prioidx; WRITE_ONCE(skcd->val, skcd_buf.val); } task_netprioidx() will be the cgrp id of xxx which is not 1, but sock_cgroup_prioidx(&skcd_buf) is 1 because it thought it's in v2 mode. Now we have a memory leak. I think the eastest fix is to do the mode switch here: diff --git a/net/core/netprio_cgroup.c b/net/core/netprio_cgroup.c index b905747..2397866 100644 --- a/net/core/netprio_cgroup.c +++ b/net/core/netprio_cgroup.c @@ -240,6 +240,8 @@ static void net_prio_attach(struct cgroup_taskset *tset) struct task_struct *p; struct cgroup_subsys_state *css; + cgroup_sk_alloc_disable(); + cgroup_taskset_for_each(p, css, tset) { void *v = (void *)(unsigned long)css->cgroup->id;
Re: [PATCH v3 10/14] remoteproc: Deal with synchronisation when shutting down
On 5/6/20 12:03 AM, Mathieu Poirier wrote: > On Mon, May 04, 2020 at 01:34:43PM +0200, Arnaud POULIQUEN wrote: >> >> >> On 4/30/20 10:23 PM, Mathieu Poirier wrote: >>> On Wed, Apr 29, 2020 at 10:19:49AM +0200, Arnaud POULIQUEN wrote: On 4/24/20 10:01 PM, Mathieu Poirier wrote: > The remoteproc core must not allow function rproc_shutdown() to > proceed if currently synchronising with a remote processor and > the synchronisation operations of that remote processor does not > support it. Also part of the process is to set the synchronisation > flag so that the remoteproc core can make the right decisions when > restarting the system. > > Signed-off-by: Mathieu Poirier > --- > drivers/remoteproc/remoteproc_core.c | 32 > drivers/remoteproc/remoteproc_internal.h | 7 ++ > 2 files changed, 39 insertions(+) > > diff --git a/drivers/remoteproc/remoteproc_core.c > b/drivers/remoteproc/remoteproc_core.c > index 3a84a38ba37b..48afa1f80a8f 100644 > --- a/drivers/remoteproc/remoteproc_core.c > +++ b/drivers/remoteproc/remoteproc_core.c > @@ -1849,6 +1849,27 @@ int rproc_boot(struct rproc *rproc) > } > EXPORT_SYMBOL(rproc_boot); > > +static bool rproc_can_shutdown(struct rproc *rproc) > +{ > + /* > + * The remoteproc core is the lifecycle manager, no problem > + * calling for a shutdown. > + */ > + if (!rproc_needs_syncing(rproc)) > + return true; > + > + /* > + * The remoteproc has been loaded by another entity (as per above > + * condition) and the platform code has given us the capability > + * of stopping it. > + */ > + if (rproc->sync_ops->stop) > + return true; This means that if rproc->sync_ops->stop is null rproc_stop_subdevices will not be called? seems not symmetric with the start sequence. >>> >>> If rproc->sync_ops->stop is not provided then the remoteproc core can't >>> stop the >>> remote processor at all after it has synchronised with it. If a usecase >>> requires some kind of soft reset then a stop() function that uses a mailbox >>> notification or some other mechanism can be provided to tell the remote >>> processor to put itself back in startup mode again. >>> >>> Is this fine with you or there is still something I don't get? >> >> My point here is more around the subdevices. But perhaps i missed >> something... >> >> In rproc_start rproc_start_subdevices is called, even if sync_start is null. > > Here I'll take that you mean sync_ops::start() > >> But in rproc_shutdown rproc_stop is not called, if sync_ops->stop is null. >> So rproc_stop_subdevices is not called in this case. > > Correct. I am pretty sure some people don't want the remoteproc core to be > able > to do anything other than synchronise with a remote processor, be it at boot > time or when the remote processor has crashed. > > I can also see scenarios where people want to be able to start and stop > subdevices from the remoteproc core, but _not_ power cycle the remote > processor. > In such cases the sync_ops::stop() should be some kind of notification telling > the remote processor to put itself back in initialisation mode and > sync_flags.after_stop should be set to true. > >> Then if sync_flags.after_stop is false, it looks like that something will go >> wrong >> at next start. > > If sync_ops::stop is NULL then the value of sync_flags.after_stop becomes > irrelevant because that state can't be reached. Let me know if you found a > condition where this isn't the case and I will correct it. The only condition i have in mind is that the sync_ops::stop() can not implemented in platform driver, just because nothing to do. But i don't know if it is a realistic use case and having a dummy stop function looks to me acceptable in this particular use case. This triggers me another comment :) the rproc_ops struct description is relevant for the "normal" ops but not adapted for the sync_ops. For instance the start & stop are mandatory for ops, optional for sync_ops As this description is a reference (at least for me) to determine optional and mandatory ops would be useful to update it. Regards, Arnaud > >> >>> Probably not useful to test it here as condition is already handled in rproc_stop_device... Regards Arnaud > + > + /* Any other condition should not be allowed */ > + return false; > +} > + > /** > * rproc_shutdown() - power off the remote processor > * @rproc: the remote processor > @@ -1879,6 +1900,9 @@ void rproc_shutdown(struct rproc *rproc) > return; > } > > + if (!rproc_can_shutdown(rproc)) > + goto out; > + > /* if the remote proc is still needed, bail out */ > if (!atomic_dec_and_test(&rproc->power)) > goto out; > @@
[PATCH v1 net-next 0/6] net: ocelot: VCAP IS1 and ES0 support
This series patches adds support for VCAP IS1 and ES0 module. VCAP IS1 supports FLOW_ACTION_VLAN_MANGLE action to filter MAC, IP, VLAN, protocol, and TCP/UDP ports keys and retag vlan tag. VCAP ES0 supports FLOW_ACTION_VLAN_PUSH action to filter vlan keys and push a specific vlan tag to frames. Vladimir Oltean (3): net: mscc: ocelot: introduce a new ocelot_target_{read,write} API net: mscc: ocelot: generalize existing code for VCAP IS2 net: dsa: tag_ocelot: use VLAN information from tagging header when available Xiaoliang Yang (3): net: mscc: ocelot: change vcap to be compatible with full and quad entry net: mscc: ocelot: VCAP IS1 support net: mscc: ocelot: VCAP ES0 support drivers/net/dsa/ocelot/felix.c| 2 - drivers/net/dsa/ocelot/felix.h| 2 - drivers/net/dsa/ocelot/felix_vsc9959.c| 186 +- drivers/net/ethernet/mscc/ocelot.c| 10 + drivers/net/ethernet/mscc/ocelot_ace.c| 727 -- drivers/net/ethernet/mscc/ocelot_ace.h| 12 + drivers/net/ethernet/mscc/ocelot_board.c | 5 +- drivers/net/ethernet/mscc/ocelot_flower.c | 33 +- drivers/net/ethernet/mscc/ocelot_io.c | 17 + drivers/net/ethernet/mscc/ocelot_regs.c | 21 +- drivers/net/ethernet/mscc/ocelot_s2.h | 64 -- include/soc/mscc/ocelot.h | 39 +- include/soc/mscc/ocelot_vcap.h| 200 +- net/dsa/tag_ocelot.c | 29 + 14 files changed, 1041 insertions(+), 306 deletions(-) delete mode 100644 drivers/net/ethernet/mscc/ocelot_s2.h -- 2.17.1
[PATCH v1 net-next 3/6] net: mscc: ocelot: change vcap to be compatible with full and quad entry
When calculating vcap data offset, the function only supports half key entry. This patch modify vcap_data_offset_get function to calculate a correct data offset when setting VCAP Type-Group to VCAP_TG_FULL or VCAP_TG_QUARTER. Signed-off-by: Xiaoliang Yang --- drivers/net/ethernet/mscc/ocelot_ace.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/mscc/ocelot_ace.c b/drivers/net/ethernet/mscc/ocelot_ace.c index 8a9c4515bb3b..29d61b89b73a 100644 --- a/drivers/net/ethernet/mscc/ocelot_ace.c +++ b/drivers/net/ethernet/mscc/ocelot_ace.c @@ -175,8 +175,8 @@ static void vcap_data_offset_get(const struct vcap_props *vcap, u32 i, col, offset, count, cnt, base; u32 width = vcap->tg_width; - count = (data->tg_sw == VCAP_TG_HALF ? 2 : 4); - col = (ix % 2); + count = (1 << (data->tg_sw - 1)); + col = (ix % count); cnt = (vcap->sw_count / count); base = (vcap->sw_count - col * cnt - cnt); data->tg_value = 0; -- 2.17.1
[PATCH v1 net-next 1/6] net: mscc: ocelot: introduce a new ocelot_target_{read,write} API
From: Vladimir Oltean There are some targets (register blocks) in the Ocelot switch that are instantiated more than once. For example, the VCAP IS1, IS2 and ES0 blocks all share the same register layout for interacting with the cache for the TCAM and the action RAM. For the VCAPs, the procedure for servicing them is actually common. We just need an API specifying which VCAP we are talking to, and we do that via these raw ocelot_target_read and ocelot_target_write accessors. In plain ocelot_read, the target is encoded into the register enum itself: u16 target = reg >> TARGET_OFFSET; For the VCAPs, the registers are currently defined like this: enum ocelot_reg { [...] S2_CORE_UPDATE_CTRL = S2 << TARGET_OFFSET, S2_CORE_MV_CFG, S2_CACHE_ENTRY_DAT, S2_CACHE_MASK_DAT, S2_CACHE_ACTION_DAT, S2_CACHE_CNT_DAT, S2_CACHE_TG_DAT, [...] }; which is precisely what we want to avoid, because we'd have to duplicate the same register map for S1 and for S0, and then figure out how to pass VCAP instance-specific registers to the ocelot_read calls (basically another lookup table that undoes the effect of shifting with TARGET_OFFSET). So for some targets, propose a more raw API, similar to what is currently done with ocelot_port_readl and ocelot_port_writel. Those targets can only be accessed with ocelot_target_{read,write} and not with ocelot_{read,write} after the conversion, which is fine. The VCAP registers are not actually modified to use this new API as of this patch. They will be modified in the next one. Signed-off-by: Vladimir Oltean --- drivers/net/ethernet/mscc/ocelot_io.c | 17 + include/soc/mscc/ocelot.h | 14 ++ 2 files changed, 31 insertions(+) diff --git a/drivers/net/ethernet/mscc/ocelot_io.c b/drivers/net/ethernet/mscc/ocelot_io.c index b229b1cb68ef..9b52d82f5399 100644 --- a/drivers/net/ethernet/mscc/ocelot_io.c +++ b/drivers/net/ethernet/mscc/ocelot_io.c @@ -59,6 +59,23 @@ void ocelot_port_writel(struct ocelot_port *port, u32 val, u32 reg) } EXPORT_SYMBOL(ocelot_port_writel); +u32 __ocelot_target_read_ix(struct ocelot *ocelot, enum ocelot_target target, + u32 reg, u32 offset) +{ + u32 val; + + regmap_read(ocelot->targets[target], + ocelot->map[target][reg] + offset, &val); + return val; +} + +void __ocelot_target_write_ix(struct ocelot *ocelot, enum ocelot_target target, + u32 val, u32 reg, u32 offset) +{ + regmap_write(ocelot->targets[target], +ocelot->map[target][reg] + offset, val); +} + int ocelot_regfields_init(struct ocelot *ocelot, const struct reg_field *const regfields) { diff --git a/include/soc/mscc/ocelot.h b/include/soc/mscc/ocelot.h index a025fb798164..ec95615ffe88 100644 --- a/include/soc/mscc/ocelot.h +++ b/include/soc/mscc/ocelot.h @@ -577,6 +577,16 @@ struct ocelot_policer { #define ocelot_rmw_rix(ocelot, val, m, reg, ri) __ocelot_rmw_ix(ocelot, val, m, reg, reg##_RSZ * (ri)) #define ocelot_rmw(ocelot, val, m, reg) __ocelot_rmw_ix(ocelot, val, m, reg, 0) +#define ocelot_target_read_ix(ocelot, target, reg, gi, ri) __ocelot_target_read_ix(ocelot, target, reg, reg##_GSZ * (gi) + reg##_RSZ * (ri)) +#define ocelot_target_read_gix(ocelot, target, reg, gi) __ocelot_target_read_ix(ocelot, target, reg, reg##_GSZ * (gi)) +#define ocelot_target_read_rix(ocelot, target, reg, ri) __ocelot_target_read_ix(ocelot, target, reg, reg##_RSZ * (ri)) +#define ocelot_target_read(ocelot, target, reg) __ocelot_target_read_ix(ocelot, target, reg, 0) + +#define ocelot_target_write_ix(ocelot, target, val, reg, gi, ri) __ocelot_target_write_ix(ocelot, target, val, reg, reg##_GSZ * (gi) + reg##_RSZ * (ri)) +#define ocelot_target_write_gix(ocelot, target, val, reg, gi) __ocelot_target_write_ix(ocelot, target, val, reg, reg##_GSZ * (gi)) +#define ocelot_target_write_rix(ocelot, target, val, reg, ri) __ocelot_target_write_ix(ocelot, target, val, reg, reg##_RSZ * (ri)) +#define ocelot_target_write(ocelot, target, val, reg) __ocelot_target_write_ix(ocelot, target, val, reg, 0) + /* I/O */ u32 ocelot_port_readl(struct ocelot_port *port, u32 reg); void ocelot_port_writel(struct ocelot_port *port, u32 val, u32 reg); @@ -584,6 +594,10 @@ u32 __ocelot_read_ix(struct ocelot *ocelot, u32 reg, u32 offset); void __ocelot_write_ix(struct ocelot *ocelot, u32 val, u32 reg, u32 offset); void __ocelot_rmw_ix(struct ocelot *ocelot, u32 val, u32 mask, u32 reg, u32 offset); +u32 __ocelot_target_read_ix(struct ocelot *ocelot, enum ocelot_target target, + u32 reg, u32 offset); +void __ocelot_target_write_ix(struct ocelot *ocelot, enum ocelot_target target, + u32 val, u32 reg, u32 offset); /* Hardwa
[PATCH v1 net-next 2/6] net: mscc: ocelot: generalize existing code for VCAP IS2
From: Vladimir Oltean The Ocelot driver only supports VCAP IS2, the security enforcement block which implements Access Control List actions (trap, drop, police). In preparation of VCAP IS1 support, generalize the existing code to work with any VCAP. In that direction, move all VCAP instantiation-specific data to struct vcap_props, and pass that as an argument to each function that does the key and action packing. Only the high-level functions need to have access to ocelot->vcap[VCAP_IS2]. Signed-off-by: Vladimir Oltean Signed-off-by: Xiaoliang Yang --- drivers/net/dsa/ocelot/felix.c| 2 - drivers/net/dsa/ocelot/felix.h| 2 - drivers/net/dsa/ocelot/felix_vsc9959.c| 25 +- drivers/net/ethernet/mscc/ocelot_ace.c| 458 -- drivers/net/ethernet/mscc/ocelot_ace.h| 1 + drivers/net/ethernet/mscc/ocelot_board.c | 5 +- drivers/net/ethernet/mscc/ocelot_flower.c | 4 + drivers/net/ethernet/mscc/ocelot_regs.c | 20 +- drivers/net/ethernet/mscc/ocelot_s2.h | 64 --- include/soc/mscc/ocelot.h | 23 +- include/soc/mscc/ocelot_vcap.h| 63 +++ 11 files changed, 367 insertions(+), 300 deletions(-) delete mode 100644 drivers/net/ethernet/mscc/ocelot_s2.h diff --git a/drivers/net/dsa/ocelot/felix.c b/drivers/net/dsa/ocelot/felix.c index e5b6748f6654..f5de3d84804b 100644 --- a/drivers/net/dsa/ocelot/felix.c +++ b/drivers/net/dsa/ocelot/felix.c @@ -401,8 +401,6 @@ static int felix_init_structs(struct felix *felix, int num_phys_ports) ocelot->stats_layout= felix->info->stats_layout; ocelot->num_stats = felix->info->num_stats; ocelot->shared_queue_sz = felix->info->shared_queue_sz; - ocelot->vcap_is2_keys = felix->info->vcap_is2_keys; - ocelot->vcap_is2_actions= felix->info->vcap_is2_actions; ocelot->vcap= felix->info->vcap; ocelot->ops = felix->info->ops; diff --git a/drivers/net/dsa/ocelot/felix.h b/drivers/net/dsa/ocelot/felix.h index 2ad793c0e1df..ce723deb9b5f 100644 --- a/drivers/net/dsa/ocelot/felix.h +++ b/drivers/net/dsa/ocelot/felix.h @@ -19,8 +19,6 @@ struct felix_info { const struct ocelot_stat_layout *stats_layout; unsigned intnum_stats; int num_ports; - struct vcap_field *vcap_is2_keys; - struct vcap_field *vcap_is2_actions; const struct vcap_props *vcap; int switch_pci_bar; int imdio_pci_bar; diff --git a/drivers/net/dsa/ocelot/felix_vsc9959.c b/drivers/net/dsa/ocelot/felix_vsc9959.c index 4fe707ef54b8..3b37c5f41fca 100644 --- a/drivers/net/dsa/ocelot/felix_vsc9959.c +++ b/drivers/net/dsa/ocelot/felix_vsc9959.c @@ -151,14 +151,16 @@ static const u32 vsc9959_qs_regmap[] = { REG_RESERVED(QS_INH_DBG), }; -static const u32 vsc9959_s2_regmap[] = { - REG(S2_CORE_UPDATE_CTRL,0x00), - REG(S2_CORE_MV_CFG, 0x04), - REG(S2_CACHE_ENTRY_DAT, 0x08), - REG(S2_CACHE_MASK_DAT, 0x000108), - REG(S2_CACHE_ACTION_DAT,0x000208), - REG(S2_CACHE_CNT_DAT, 0x000308), - REG(S2_CACHE_TG_DAT,0x000388), +static const u32 vsc9959_vcap_regmap[] = { + /* VCAP_CORE_CFG */ + REG(VCAP_CORE_UPDATE_CTRL, 0x00), + REG(VCAP_CORE_MV_CFG, 0x04), + /* VCAP_CORE_CACHE */ + REG(VCAP_CACHE_ENTRY_DAT, 0x08), + REG(VCAP_CACHE_MASK_DAT,0x000108), + REG(VCAP_CACHE_ACTION_DAT, 0x000208), + REG(VCAP_CACHE_CNT_DAT, 0x000308), + REG(VCAP_CACHE_TG_DAT, 0x000388), }; static const u32 vsc9959_qsys_regmap[] = { @@ -330,7 +332,7 @@ static const u32 *vsc9959_regmap[] = { [QSYS] = vsc9959_qsys_regmap, [REW] = vsc9959_rew_regmap, [SYS] = vsc9959_sys_regmap, - [S2]= vsc9959_s2_regmap, + [S2]= vsc9959_vcap_regmap, [PTP] = vsc9959_ptp_regmap, [GCB] = vsc9959_gcb_regmap, }; @@ -674,6 +676,9 @@ static const struct vcap_props vsc9959_vcap_props[] = { }, .counter_words = 4, .counter_width = 32, + .target = S2, + .keys = vsc9959_vcap_is2_keys, + .actions = vsc9959_vcap_is2_actions, }, }; @@ -1218,8 +1223,6 @@ struct felix_info felix_info_vsc9959 = { .ops= &vsc9959_ops, .stats_layout = vsc9959_stats_layout, .num_stats = ARRAY_SIZE(vsc9959_stats_layout), - .vcap_is2_keys = vsc9959_vcap_is2_keys, - .vcap_is2_actions = vsc9959_vcap_is2_actions, .vcap
[PATCH v1 net-next 4/6] net: mscc: ocelot: VCAP IS1 support
VCAP IS1 is a VCAP module which can filter MAC, IP, VLAN, protocol, and TCP/UDP ports keys, and do Qos and VLAN retag actions. This patch added VCAP IS1 support in ocelot ace driver, which can supports vlan modify action of tc filter. Usage: tc qdisc add dev swp0 ingress tc filter add dev swp0 protocol 802.1Q parent : flower \ skip_sw vlan_id 1 vlan_prio 1 action vlan modify id 2 priority 2 Signed-off-by: Xiaoliang Yang --- drivers/net/dsa/ocelot/felix_vsc9959.c| 102 +++ drivers/net/ethernet/mscc/ocelot.c| 7 + drivers/net/ethernet/mscc/ocelot_ace.c| 198 +- drivers/net/ethernet/mscc/ocelot_ace.h| 9 + drivers/net/ethernet/mscc/ocelot_flower.c | 6 + drivers/net/ethernet/mscc/ocelot_regs.c | 1 + include/soc/mscc/ocelot.h | 1 + include/soc/mscc/ocelot_vcap.h| 93 +- 8 files changed, 415 insertions(+), 2 deletions(-) diff --git a/drivers/net/dsa/ocelot/felix_vsc9959.c b/drivers/net/dsa/ocelot/felix_vsc9959.c index 3b37c5f41fca..1f5edabf5fd2 100644 --- a/drivers/net/dsa/ocelot/felix_vsc9959.c +++ b/drivers/net/dsa/ocelot/felix_vsc9959.c @@ -13,6 +13,8 @@ #define VSC9959_VCAP_IS2_CNT 1024 #define VSC9959_VCAP_IS2_ENTRY_WIDTH 376 #define VSC9959_VCAP_PORT_CNT 6 +#define VSC9959_VCAP_IS1_CNT 256 +#define VSC9959_VCAP_IS1_ENTRY_WIDTH 376 /* TODO: should find a better place for these */ #define USXGMII_BMCR_RESET BIT(15) @@ -332,6 +334,7 @@ static const u32 *vsc9959_regmap[] = { [QSYS] = vsc9959_qsys_regmap, [REW] = vsc9959_rew_regmap, [SYS] = vsc9959_sys_regmap, + [S1]= vsc9959_vcap_regmap, [S2]= vsc9959_vcap_regmap, [PTP] = vsc9959_ptp_regmap, [GCB] = vsc9959_gcb_regmap, @@ -366,6 +369,11 @@ static struct resource vsc9959_target_io_res[] = { .end= 0x001, .name = "sys", }, + [S1] = { + .start = 0x005, + .end= 0x00503ff, + .name = "s1", + }, [S2] = { .start = 0x006, .end= 0x00603ff, @@ -556,6 +564,80 @@ static const struct ocelot_stat_layout vsc9959_stats_layout[] = { { .offset = 0x111, .name = "drop_green_prio_7", }, }; +struct vcap_field vsc9959_vcap_is1_keys[] = { + [VCAP_IS1_HK_TYPE] = { 0, 1}, + [VCAP_IS1_HK_LOOKUP]= { 1, 2}, + [VCAP_IS1_HK_IGR_PORT_MASK] = { 3, 7}, + [VCAP_IS1_HK_RSV] = { 10, 9}, + [VCAP_IS1_HK_OAM_Y1731] = { 19, 1}, + [VCAP_IS1_HK_L2_MC] = { 20, 1}, + [VCAP_IS1_HK_L2_BC] = { 21, 1}, + [VCAP_IS1_HK_IP_MC] = { 22, 1}, + [VCAP_IS1_HK_VLAN_TAGGED] = { 23, 1}, + [VCAP_IS1_HK_VLAN_DBL_TAGGED] = { 24, 1}, + [VCAP_IS1_HK_TPID] = { 25, 1}, + [VCAP_IS1_HK_VID] = { 26, 12}, + [VCAP_IS1_HK_DEI] = { 38, 1}, + [VCAP_IS1_HK_PCP] = { 39, 3}, + /* Specific Fields for IS1 Half Key S1_NORMAL */ + [VCAP_IS1_HK_L2_SMAC] = { 42, 48}, + [VCAP_IS1_HK_ETYPE_LEN] = { 90, 1}, + [VCAP_IS1_HK_ETYPE] = { 91, 16}, + [VCAP_IS1_HK_IP_SNAP] = {107, 1}, + [VCAP_IS1_HK_IP4] = {108, 1}, + /* Layer-3 Information */ + [VCAP_IS1_HK_L3_FRAGMENT] = {109, 1}, + [VCAP_IS1_HK_L3_FRAG_OFS_GT0] = {110, 1}, + [VCAP_IS1_HK_L3_OPTIONS]= {111, 1}, + [VCAP_IS1_HK_L3_DSCP] = {112, 6}, + [VCAP_IS1_HK_L3_IP4_SIP]= {118, 32}, + /* Layer-4 Information */ + [VCAP_IS1_HK_TCP_UDP] = {150, 1}, + [VCAP_IS1_HK_TCP] = {151, 1}, + [VCAP_IS1_HK_L4_SPORT] = {152, 16}, + [VCAP_IS1_HK_L4_RNG]= {168, 8}, + /* Specific Fields for IS1 Half Key S1_5TUPLE_IP4 */ + [VCAP_IS1_HK_IP4_INNER_TPID]= { 42, 1}, + [VCAP_IS1_HK_IP4_INNER_VID] = { 43, 12}, + [VCAP_IS1_HK_IP4_INNER_DEI] = { 55, 1}, + [VCAP_IS1_HK_IP4_INNER_PCP] = { 56, 3}, + [VCAP_IS1_HK_IP4_IP4] = { 59, 1}, + [VCAP_IS1_HK_IP4_L3_FRAGMENT] = { 60, 1}, + [VCAP_IS1_HK_IP4_L3_FRAG_OFS_GT0] = { 61, 1}, + [VCAP_IS1_HK_IP4_L3_OPTIONS]= { 62, 1}, + [VCAP_IS1_HK_IP4_L3_DSCP] = { 63, 6}, + [VCAP_IS1_HK_IP4_L3_IP4_DIP]= { 69, 32}, + [VCAP_IS1_HK_IP4_L
Re: [PATCH net-next 1/2] virtio-net: don't reserve space for vnet header for XDP
On Wed, May 06, 2020 at 02:16:32PM +0800, Jason Wang wrote: > We tried to reserve space for vnet header before > xdp.data_hard_start. But this is useless since the packet could be > modified by XDP which may invalidate the information stored in the > header and there's no way for XDP to know the existence of the vnet > header currently. What do you mean? Doesn't XDP_PASS use the header in the buffer? > So let's just not reserve space for vnet header in this case. In any case, we can find out XDP does head adjustments if we need to. > Cc: Jesper Dangaard Brouer > Signed-off-by: Jason Wang > --- > drivers/net/virtio_net.c | 6 +++--- > 1 file changed, 3 insertions(+), 3 deletions(-) > > diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c > index 11f722460513..98dd75b665a5 100644 > --- a/drivers/net/virtio_net.c > +++ b/drivers/net/virtio_net.c > @@ -684,8 +684,8 @@ static struct sk_buff *receive_small(struct net_device > *dev, > page = xdp_page; > } > > - xdp.data_hard_start = buf + VIRTNET_RX_PAD + vi->hdr_len; > - xdp.data = xdp.data_hard_start + xdp_headroom; > + xdp.data_hard_start = buf + VIRTNET_RX_PAD; > + xdp.data = xdp.data_hard_start + xdp_headroom + vi->hdr_len; > xdp.data_end = xdp.data + len; > xdp.data_meta = xdp.data; > xdp.rxq = &rq->xdp_rxq; > @@ -845,7 +845,7 @@ static struct sk_buff *receive_mergeable(struct > net_device *dev, >* the descriptor on if we get an XDP_TX return code. >*/ > data = page_address(xdp_page) + offset; > - xdp.data_hard_start = data - VIRTIO_XDP_HEADROOM + vi->hdr_len; > + xdp.data_hard_start = data - VIRTIO_XDP_HEADROOM; > xdp.data = data + vi->hdr_len; > xdp.data_end = xdp.data + (len - vi->hdr_len); > xdp.data_meta = xdp.data; > -- > 2.20.1
[PATCH v1 net-next 5/6] net: mscc: ocelot: VCAP ES0 support
VCAP ES0 is an egress VCAP working on all outgoing frames. This patch added ES0 driver to support vlan push action of tc filter. Usage: tc filter add dev swp1 egress protocol 802.1Q flower skip_sw vlan_id 1 vlan_prio 1 action vlan push id 2 priority 2 Signed-off-by: Xiaoliang Yang --- drivers/net/dsa/ocelot/felix_vsc9959.c| 59 ++ drivers/net/ethernet/mscc/ocelot.c| 3 + drivers/net/ethernet/mscc/ocelot_ace.c| 73 ++- drivers/net/ethernet/mscc/ocelot_ace.h| 2 + drivers/net/ethernet/mscc/ocelot_flower.c | 23 ++- include/soc/mscc/ocelot.h | 1 + include/soc/mscc/ocelot_vcap.h| 44 +- 7 files changed, 200 insertions(+), 5 deletions(-) diff --git a/drivers/net/dsa/ocelot/felix_vsc9959.c b/drivers/net/dsa/ocelot/felix_vsc9959.c index 1f5edabf5fd2..ee3b1b2974a0 100644 --- a/drivers/net/dsa/ocelot/felix_vsc9959.c +++ b/drivers/net/dsa/ocelot/felix_vsc9959.c @@ -15,6 +15,7 @@ #define VSC9959_VCAP_PORT_CNT 6 #define VSC9959_VCAP_IS1_CNT 256 #define VSC9959_VCAP_IS1_ENTRY_WIDTH 376 +#define VSC9959_VCAP_ES0_CNT1024 /* TODO: should find a better place for these */ #define USXGMII_BMCR_RESET BIT(15) @@ -334,6 +335,7 @@ static const u32 *vsc9959_regmap[] = { [QSYS] = vsc9959_qsys_regmap, [REW] = vsc9959_rew_regmap, [SYS] = vsc9959_sys_regmap, + [S0]= vsc9959_vcap_regmap, [S1]= vsc9959_vcap_regmap, [S2]= vsc9959_vcap_regmap, [PTP] = vsc9959_ptp_regmap, @@ -369,6 +371,11 @@ static struct resource vsc9959_target_io_res[] = { .end= 0x001, .name = "sys", }, + [S0] = { + .start = 0x004, + .end= 0x00403ff, + .name = "s0", + }, [S1] = { .start = 0x005, .end= 0x00503ff, @@ -564,6 +571,38 @@ static const struct ocelot_stat_layout vsc9959_stats_layout[] = { { .offset = 0x111, .name = "drop_green_prio_7", }, }; +struct vcap_field vsc9959_vcap_es0_keys[] = { + [VCAP_ES0_EGR_PORT] = { 0, 3}, + [VCAP_ES0_IGR_PORT] = { 3, 3}, + [VCAP_ES0_RSV] = { 6, 2}, + [VCAP_ES0_L2_MC]= { 8, 1}, + [VCAP_ES0_L2_BC]= { 9, 1}, + [VCAP_ES0_VID] = { 10, 12}, + [VCAP_ES0_DP] = { 22, 1}, + [VCAP_ES0_PCP] = { 23, 3}, +}; + +struct vcap_field vsc9959_vcap_es0_actions[] = { + [VCAP_ES0_ACT_PUSH_OUTER_TAG] = { 0, 2}, + [VCAP_ES0_ACT_PUSH_INNER_TAG] = { 2, 1}, + [VCAP_ES0_ACT_TAG_A_TPID_SEL] = { 3, 2}, + [VCAP_ES0_ACT_TAG_A_VID_SEL]= { 5, 1}, + [VCAP_ES0_ACT_TAG_A_PCP_SEL]= { 6, 2}, + [VCAP_ES0_ACT_TAG_A_DEI_SEL]= { 8, 2}, + [VCAP_ES0_ACT_TAG_B_TPID_SEL] = { 10, 2}, + [VCAP_ES0_ACT_TAG_B_VID_SEL]= { 12, 1}, + [VCAP_ES0_ACT_TAG_B_PCP_SEL]= { 13, 2}, + [VCAP_ES0_ACT_TAG_B_DEI_SEL]= { 15, 2}, + [VCAP_ES0_ACT_VID_A_VAL]= { 17, 12}, + [VCAP_ES0_ACT_PCP_A_VAL]= { 29, 3}, + [VCAP_ES0_ACT_DEI_A_VAL]= { 32, 1}, + [VCAP_ES0_ACT_VID_B_VAL]= { 33, 12}, + [VCAP_ES0_ACT_PCP_B_VAL]= { 45, 3}, + [VCAP_ES0_ACT_DEI_B_VAL]= { 48, 1}, + [VCAP_ES0_ACT_RSV] = { 49, 23}, + [VCAP_ES0_ACT_HIT_STICKY] = { 72, 1}, +}; + struct vcap_field vsc9959_vcap_is1_keys[] = { [VCAP_IS1_HK_TYPE] = { 0, 1}, [VCAP_IS1_HK_LOOKUP]= { 1, 2}, @@ -737,6 +776,26 @@ struct vcap_field vsc9959_vcap_is2_actions[] = { }; static const struct vcap_props vsc9959_vcap_props[] = { + [VCAP_ES0] = { + .tg_width = 1, + .sw_count = 1, + .entry_count = VSC9959_VCAP_ES0_CNT, + .entry_width = 29, + .action_count = VSC9959_VCAP_ES0_CNT + 6, + .action_width = 72, + .action_type_width = 0, + .action_table = { + [ES0_ACTION_TYPE_NORMAL] = { + .width = 72, + .count = 1 + }, + }, + .counter_words = 1, + .counter_width = 1, + .target = S0, + .keys = vsc9959_vcap_es0_keys, + .actions = vsc9959_vcap_es0_actions, + }, [VCAP_IS1] = { .tg_width = 2, .sw_count = 4, diff --git a/drive
[PATCH v1 net-next 6/6] net: dsa: tag_ocelot: use VLAN information from tagging header when available
From: Vladimir Oltean When the Extraction Frame Header contains a valid classified VLAN, use that instead of the VLAN header present in the packet. Signed-off-by: Vladimir Oltean --- net/dsa/tag_ocelot.c | 29 + 1 file changed, 29 insertions(+) diff --git a/net/dsa/tag_ocelot.c b/net/dsa/tag_ocelot.c index 59de1315100f..8c93a78bda5b 100644 --- a/net/dsa/tag_ocelot.c +++ b/net/dsa/tag_ocelot.c @@ -181,9 +181,16 @@ static struct sk_buff *ocelot_rcv(struct sk_buff *skb, struct net_device *netdev, struct packet_type *pt) { + struct dsa_port *cpu_dp = netdev->dsa_ptr; + struct dsa_switch *ds = cpu_dp->ds; + struct ocelot *ocelot = ds->priv; + struct ocelot_port *ocelot_port; u64 src_port, qos_class; u8 *start = skb->data; + struct ethhdr *hdr; u8 *extraction; + u64 vlan_tci; + u16 vid; /* Revert skb->data by the amount consumed by the DSA master, * so it points to the beginning of the frame. @@ -211,6 +218,7 @@ static struct sk_buff *ocelot_rcv(struct sk_buff *skb, packing(extraction, &src_port, 46, 43, OCELOT_TAG_LEN, UNPACK, 0); packing(extraction, &qos_class, 19, 17, OCELOT_TAG_LEN, UNPACK, 0); + packing(extraction, &vlan_tci, 15, 0, OCELOT_TAG_LEN, UNPACK, 0); skb->dev = dsa_master_find_slave(netdev, 0, src_port); if (!skb->dev) @@ -225,6 +233,27 @@ static struct sk_buff *ocelot_rcv(struct sk_buff *skb, skb->offload_fwd_mark = 1; skb->priority = qos_class; + /* The VID from the extraction header contains the classified VLAN. But +* if VLAN awareness is off and no retagging is done via VCAP IS1, that +* classified VID will always be the pvid of the src_port. +* port. We want Linux to see the classified VID, but only if the switch +* intended to send the packet as untagged, i.e. if the VID is different +* than the CPU port's untagged (native) VID. +*/ + vid = vlan_tci & VLAN_VID_MASK; + hdr = eth_hdr(skb); + ocelot_port = ocelot->ports[src_port]; + if (hdr->h_proto == htons(ETH_P_8021Q) && vid != ocelot_port->pvid) { + u16 dummy_vlan_tci; + + skb_push_rcsum(skb, ETH_HLEN); + __skb_vlan_pop(skb, &dummy_vlan_tci); + skb_pull_rcsum(skb, ETH_HLEN); + skb_reset_network_header(skb); + skb_reset_transport_header(skb); + __vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q), vlan_tci); + } + return skb; } -- 2.17.1
Re: [patch V4 part 2 14/18] x86/kvm/vmx: Add hardirq tracing to guest enter/exit
On 05/05/20 15:41, Thomas Gleixner wrote: > Add hardirq tracing to guest enter/exit functions in the same way as it > is done in the user mode enter/exit code. > > Signed-off-by: Thomas Gleixner > Cc: Paolo Bonzini > Cc: Sean Christopherson > --- > arch/x86/kvm/vmx/vmx.c | 25 +++-- > 1 file changed, 23 insertions(+), 2 deletions(-) > > --- a/arch/x86/kvm/vmx/vmx.c > +++ b/arch/x86/kvm/vmx/vmx.c > @@ -6604,9 +6604,19 @@ static void vmx_vcpu_run(struct kvm_vcpu > x86_spec_ctrl_set_guest(vmx->spec_ctrl, 0); > > /* > - * Tell context tracking that this CPU is about to enter guest mode. > + * VMENTER enables interrupts (host state), but the kernel state is > + * interrupts disabled when this is invoked. Also tell RCU about > + * it. This is the same logic as for exit_to_user_mode(). > + * > + * 1) Trace interrupts on state > + * 2) Prepare lockdep with RCU on > + * 3) Invoke context tracking if enabled to adjust RCU state > + * 4) Tell lockdep that interrupts are enabled >*/ > + trace_hardirqs_on_prepare(); > + lockdep_hardirqs_on_prepare(CALLER_ADDR0); > guest_enter_irqoff(); > + lockdep_hardirqs_on(CALLER_ADDR0); > > /* L1D Flush includes CPU buffer clear to mitigate MDS */ > if (static_branch_unlikely(&vmx_l1d_should_flush)) > @@ -6623,9 +6633,20 @@ static void vmx_vcpu_run(struct kvm_vcpu > vcpu->arch.cr2 = read_cr2(); > > /* > - * Tell context tracking that this CPU is back. > + * VMEXIT disables interrupts (host state), but tracing and lockdep > + * have them in state 'on'. Same as enter_from_user_mode(). > + * > + * 1) Tell lockdep that interrupts are disabled > + * 2) Invoke context tracking if enabled to reactivate RCU > + * 3) Trace interrupts off state > + * > + * This needs to be done before the below as native_read_msr() > + * contains a tracepoint and x86_spec_ctrl_restore_host() calls > + * into world and some more. >*/ > + lockdep_hardirqs_off(CALLER_ADDR0); > guest_exit_irqoff(); > + trace_hardirqs_off_prepare(); > > /* >* We do not use IBRS in the kernel. If this vCPU has used the > Acked-by: Paolo Bonzini
[tip: x86/build] x86/build: Use $(CONFIG_SHELL)
The following commit has been merged into the x86/build branch of tip: Commit-ID: 950a37078aa0ab63a57673e7027e8735e73d4bc6 Gitweb: https://git.kernel.org/tip/950a37078aa0ab63a57673e7027e8735e73d4bc6 Author:Andrew Morton AuthorDate:Tue, 05 May 2020 14:26:51 -07:00 Committer: Borislav Petkov CommitterDate: Wed, 06 May 2020 09:46:26 +02:00 x86/build: Use $(CONFIG_SHELL) When scripts/x86-check-compiler.sh doesn't have the executable bit set: q:/usr/src/25> make clean make: execvp: ./scripts/x86-check-compiler.sh: Permission denied Fix this by using $(CONFIG_SHELL). This will happen if the user downloads and applies patch-5.7.tar.gz, since patch(1) doesn't preserve the x bit. Fixes: 73da86741e7f7 ("x86/build: Check whether the compiler is sane") Signed-off-by: Andrew Morton Signed-off-by: Borislav Petkov Link: https://lkml.kernel.org/r/20200505211932.ge6...@zn.tnic --- arch/x86/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/x86/Makefile b/arch/x86/Makefile index 38d3eec..9e22791 100644 --- a/arch/x86/Makefile +++ b/arch/x86/Makefile @@ -2,7 +2,7 @@ # Unified Makefile for i386 and x86_64 # Check the compiler -sane_compiler := $(shell $(srctree)/scripts/x86-check-compiler.sh $(CC)) +sane_compiler := $($(CONFIG_SHELL) $(srctree)/scripts/x86-check-compiler.sh $(CC)) $(if $(sane_compiler),$(error $(CC) check failed. Aborting),) # select defconfig based on actual architecture
Re: [RFC PATCH 54/61] afs: Wait on PG_fscache before modifying/releasing a page
Matthew Wilcox wrote: > > PG_fscache is going to be used to indicate that a page is being written to > > the cache, and that the page should not be modified or released until it's > > finished. > > > > Make afs_invalidatepage() and afs_releasepage() wait for it. > > Well, why? Keeping a refcount on the page will prevent it from going > away while it's being written to storage. And the fact that it's > being written to this cache is no reason to delay the truncate of a file > (is it?) Won't that screw up ITER_MAPPING? Does that mean that ITER_MAPPING isn't viable? David
[PATCH v10 0/3] 32-bit access for TX/RX hold registers for samsung_tty driver
Change in v10: - add reviewd by and tested by in commit of each patch Change in v9: - move wr_reg_barrier into ifdef of CONFIG_SERIAL_SAMSUNG_CONSOLE to fix following build error for x86 build CC [M] drivers/tty/serial/samsung_tty.o drivers/tty/serial/samsung_tty.c:186:13: warning: ‘wr_reg_barrier’ defined but not used [-Wunused-function] Change in v8: - spit into 3 patch [1/3] create the new functions with no functional change to the code as-is. Replace rd_regb/wr_regb with rd_reg/wr_reg for general usage. [2/3] add the new binding reg-io-width in device tree [3/3] add the new funtinality of rd_reg / wr_reg and wr_reg_barrier to support 32-bit access for the TX/RX hold registers UTXH and URXH. Change in v7: - [1/2] correct build error on running 'make dt_binding_check' Documentation/devicetree/bindings/serial/samsung_uart.yaml: mapping values are not allowed in this context in "", line 36, column 13 Documentation/devicetree/bindings/Makefile:12: recipe for target 'Documentation/devicetree/bindings/serial/samsung_uart.example.dts' failed make[1]: *** [Documentation/devicetree/bindings/serial/samsung_uart.example.dts] Error 1 make[1]: *** Waiting for unfinished jobs Makefile:1262: recipe for target 'dt_binding_check' failed make: *** [dt_binding_check] Error 2 - [2/2] add commit message of reviewed by and tested by in commit message Reviewed-by: Krzysztof Kozlowski Tested on Odroid HC1 (Exynos5422): Tested-by: Krzysztof Kozlowski Change in v6: - [2/2] clean description of reg-io-width allOf is not needed. Just enum [1, 2] is enough. Changes in v5: - spit into 2 patch, newly added patch for dt-binding [1/2] newly added dt-binding and go as first patch in this series. [2/2] go as second patch in this series. Changes in v4: - correct variable types and change misleading function name Changes in v3: - line 2031: remove redundant init value for ourport->port.iotype Changes in v2: - line 954 : change rd_regl to rd_reg in for backward compatibility. - line 2031: Add init value for ourport->port.iotype to UPIO_MEM Hyunki Koo (3): serial: samsung: Replace rd_regb/wr_regb with rd_reg/wr_reg dt-bindings: serial: Add reg-io-width compatible tty: samsung_tty: 32-bit access for TX/RX hold registers .../devicetree/bindings/serial/samsung_uart.yaml | 8 +++ drivers/tty/serial/samsung_tty.c | 76 ++ 2 files changed, 72 insertions(+), 12 deletions(-) -- 2.15.0.rc1
[PATCH v10 2/3] dt-bindings: serial: Add reg-io-width compatible
Add a description for reg-io-width options for the samsung serial UART peripheral. Signed-off-by: Hyunki Koo Reviewed-by: Rob Herring --- Documentation/devicetree/bindings/serial/samsung_uart.yaml | 8 1 file changed, 8 insertions(+) diff --git a/Documentation/devicetree/bindings/serial/samsung_uart.yaml b/Documentation/devicetree/bindings/serial/samsung_uart.yaml index 9d2ce347875b..a57b1233c691 100644 --- a/Documentation/devicetree/bindings/serial/samsung_uart.yaml +++ b/Documentation/devicetree/bindings/serial/samsung_uart.yaml @@ -29,6 +29,14 @@ properties: reg: maxItems: 1 + reg-io-width: +description: | + The size (in bytes) of the IO accesses that should be performed + on the device. +allOf: + - $ref: /schemas/types.yaml#/definitions/uint32 + - enum: [ 1, 4 ] + clocks: minItems: 2 maxItems: 5 -- 2.15.0.rc1
[PATCH v10 1/3] serial: samsung: Replace rd_regb/wr_regb with rd_reg/wr_reg
This patch change the name of macro for general usage. Signed-off-by: Hyunki Koo Reviewed-by: Krzysztof Kozlowski Tested on Odroid HC1 (Exynos5422): Tested-by: Krzysztof Kozlowski --- drivers/tty/serial/samsung_tty.c | 18 +- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/drivers/tty/serial/samsung_tty.c b/drivers/tty/serial/samsung_tty.c index 73f951d65b93..326b0164609c 100644 --- a/drivers/tty/serial/samsung_tty.c +++ b/drivers/tty/serial/samsung_tty.c @@ -154,10 +154,10 @@ struct s3c24xx_uart_port { #define portaddrl(port, reg) \ ((unsigned long *)(unsigned long)((port)->membase + (reg))) -#define rd_regb(port, reg) (readb_relaxed(portaddr(port, reg))) +#define rd_reg(port, reg) (readb_relaxed(portaddr(port, reg))) #define rd_regl(port, reg) (readl_relaxed(portaddr(port, reg))) -#define wr_regb(port, reg, val) writeb_relaxed(val, portaddr(port, reg)) +#define wr_reg(port, reg, val) writeb_relaxed(val, portaddr(port, reg)) #define wr_regl(port, reg, val) writel_relaxed(val, portaddr(port, reg)) /* Byte-order aware bit setting/clearing functions. */ @@ -714,7 +714,7 @@ static void s3c24xx_serial_rx_drain_fifo(struct s3c24xx_uart_port *ourport) fifocnt--; uerstat = rd_regl(port, S3C2410_UERSTAT); - ch = rd_regb(port, S3C2410_URXH); + ch = rd_reg(port, S3C2410_URXH); if (port->flags & UPF_CONS_FLOW) { int txe = s3c24xx_serial_txempty_nofifo(port); @@ -826,7 +826,7 @@ static irqreturn_t s3c24xx_serial_tx_chars(int irq, void *id) } if (port->x_char) { - wr_regb(port, S3C2410_UTXH, port->x_char); + wr_reg(port, S3C2410_UTXH, port->x_char); port->icount.tx++; port->x_char = 0; goto out; @@ -852,7 +852,7 @@ static irqreturn_t s3c24xx_serial_tx_chars(int irq, void *id) if (rd_regl(port, S3C2410_UFSTAT) & ourport->info->tx_fifofull) break; - wr_regb(port, S3C2410_UTXH, xmit->buf[xmit->tail]); + wr_reg(port, S3C2410_UTXH, xmit->buf[xmit->tail]); xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); port->icount.tx++; count--; @@ -916,7 +916,7 @@ static unsigned int s3c24xx_serial_tx_empty(struct uart_port *port) /* no modem control lines */ static unsigned int s3c24xx_serial_get_mctrl(struct uart_port *port) { - unsigned int umstat = rd_regb(port, S3C2410_UMSTAT); + unsigned int umstat = rd_reg(port, S3C2410_UMSTAT); if (umstat & S3C2410_UMSTAT_CTS) return TIOCM_CAR | TIOCM_DSR | TIOCM_CTS; @@ -2185,7 +2185,7 @@ static int s3c24xx_serial_get_poll_char(struct uart_port *port) if (s3c24xx_serial_rx_fifocnt(ourport, ufstat) == 0) return NO_POLL_CHAR; - return rd_regb(port, S3C2410_URXH); + return rd_reg(port, S3C2410_URXH); } static void s3c24xx_serial_put_poll_char(struct uart_port *port, @@ -2200,7 +2200,7 @@ static void s3c24xx_serial_put_poll_char(struct uart_port *port, while (!s3c24xx_serial_console_txrdy(port, ufcon)) cpu_relax(); - wr_regb(port, S3C2410_UTXH, c); + wr_reg(port, S3C2410_UTXH, c); } #endif /* CONFIG_CONSOLE_POLL */ @@ -2212,7 +2212,7 @@ s3c24xx_serial_console_putchar(struct uart_port *port, int ch) while (!s3c24xx_serial_console_txrdy(port, ufcon)) cpu_relax(); - wr_regb(port, S3C2410_UTXH, ch); + wr_reg(port, S3C2410_UTXH, ch); } static void -- 2.15.0.rc1
[PATCH v10 3/3] tty: samsung_tty: 32-bit access for TX/RX hold registers
Support 32-bit access for the TX/RX hold registers UTXH and URXH. This is required for some newer SoCs. Signed-off-by: Hyunki Koo Reviewed-by: Krzysztof Kozlowski Tested on Odroid HC1 (Exynos5422): Tested-by: Krzysztof Kozlowski --- drivers/tty/serial/samsung_tty.c | 62 1 file changed, 57 insertions(+), 5 deletions(-) diff --git a/drivers/tty/serial/samsung_tty.c b/drivers/tty/serial/samsung_tty.c index 326b0164609c..6ef614d8648c 100644 --- a/drivers/tty/serial/samsung_tty.c +++ b/drivers/tty/serial/samsung_tty.c @@ -154,10 +154,33 @@ struct s3c24xx_uart_port { #define portaddrl(port, reg) \ ((unsigned long *)(unsigned long)((port)->membase + (reg))) -#define rd_reg(port, reg) (readb_relaxed(portaddr(port, reg))) +static u32 rd_reg(struct uart_port *port, u32 reg) +{ + switch (port->iotype) { + case UPIO_MEM: + return readb_relaxed(portaddr(port, reg)); + case UPIO_MEM32: + return readl_relaxed(portaddr(port, reg)); + default: + return 0; + } + return 0; +} + #define rd_regl(port, reg) (readl_relaxed(portaddr(port, reg))) -#define wr_reg(port, reg, val) writeb_relaxed(val, portaddr(port, reg)) +static void wr_reg(struct uart_port *port, u32 reg, u32 val) +{ + switch (port->iotype) { + case UPIO_MEM: + writeb_relaxed(val, portaddr(port, reg)); + break; + case UPIO_MEM32: + writel_relaxed(val, portaddr(port, reg)); + break; + } +} + #define wr_regl(port, reg, val) writel_relaxed(val, portaddr(port, reg)) /* Byte-order aware bit setting/clearing functions. */ @@ -1974,7 +1997,7 @@ static int s3c24xx_serial_probe(struct platform_device *pdev) struct device_node *np = pdev->dev.of_node; struct s3c24xx_uart_port *ourport; int index = probe_index; - int ret; + int ret, prop = 0; if (np) { ret = of_alias_get_id(np, "serial"); @@ -2000,10 +2023,27 @@ static int s3c24xx_serial_probe(struct platform_device *pdev) dev_get_platdata(&pdev->dev) : ourport->drv_data->def_cfg; - if (np) + if (np) { of_property_read_u32(np, "samsung,uart-fifosize", &ourport->port.fifosize); + if (of_property_read_u32(np, "reg-io-width", &prop) == 0) { + switch (prop) { + case 1: + ourport->port.iotype = UPIO_MEM; + break; + case 4: + ourport->port.iotype = UPIO_MEM32; + break; + default: + dev_warn(&pdev->dev, "unsupported reg-io-width (%d)\n", + prop); + ret = -EINVAL; + break; + } + } + } + if (ourport->drv_data->fifosize[index]) ourport->port.fifosize = ourport->drv_data->fifosize[index]; else if (ourport->info->fifosize) @@ -2587,6 +2627,18 @@ module_platform_driver(samsung_serial_driver); * Early console. */ +static void wr_reg_barrier(struct uart_port *port, u32 reg, u32 val) +{ + switch (port->iotype) { + case UPIO_MEM: + writeb(val, portaddr(port, reg)); + break; + case UPIO_MEM32: + writel(val, portaddr(port, reg)); + break; + } +} + struct samsung_early_console_data { u32 txfull_mask; }; @@ -2612,7 +2664,7 @@ static void samsung_early_putc(struct uart_port *port, int c) else samsung_early_busyuart(port); - writeb(c, port->membase + S3C2410_UTXH); + wr_reg_barrier(port, S3C2410_UTXH, c); } static void samsung_early_write(struct console *con, const char *s, -- 2.15.0.rc1
[PATCH v3 0/9] clocksource/drivers/timer-atmel-tcb: add sama5d2 support
This series mainly adds sama5d2 support where we need to avoid using clock index 0 because that clock is never enabled by the driver. There is also a rework of the 32khz clock handling so it is not used for clockevents on 32 bit counter because the increased rate improves the resolution and doesn't have any drawback with that counter width. This replaces a patch that has been carried in the linux-rt tree for a while. Changes in v3: - Moved the child node documentation to the parent documentation Changes in v2: - Rebased on v5.7-rc1 - Moved the binding documentation to its proper place - Added back the atmel,tcb-timer child node documentation Alexandre Belloni (8): dt-bindings: atmel-tcb: convert bindings to json-schema dt-bindings: microchip: atmel,at91rm9200-tcb: add sama5d2 compatible ARM: dts: at91: sama5d2: add TCB GCLK clocksource/drivers/timer-atmel-tcb: rework 32khz clock selection clocksource/drivers/timer-atmel-tcb: fill tcb_config clocksource/drivers/timer-atmel-tcb: stop using the 32kHz for clockevents clocksource/drivers/timer-atmel-tcb: allow selecting first divider clocksource/drivers/timer-atmel-tcb: add sama5d2 support Kamel Bouhara (1): ARM: at91: add atmel tcb capabilities .../devicetree/bindings/mfd/atmel-tcb.txt | 56 --- .../soc/microchip/atmel,at91rm9200-tcb.yaml | 150 ++ arch/arm/boot/dts/sama5d2.dtsi| 12 +- drivers/clocksource/timer-atmel-tcb.c | 101 +++- include/soc/at91/atmel_tcb.h | 5 + 5 files changed, 219 insertions(+), 105 deletions(-) delete mode 100644 Documentation/devicetree/bindings/mfd/atmel-tcb.txt create mode 100644 Documentation/devicetree/bindings/soc/microchip/atmel,at91rm9200-tcb.yaml -- 2.26.2
[PATCH v2 0/2] arm64: meson-sm1: add support for Hardkernel ODROID-C4
This serie adds support for the Hardkernel Odroid-C4 single board computer. The Odroid-C4 is the Odroid-C2 successor with same form factor, but using a modern Amlogic S905X3 (SM1) SoC and 4x USB3 ports. Fully functionnal: - USB2+USB3 - USB2 OTG - eMMC - SDCard - HDMI - DVFS - Gigabit Ethernet with RTL8211F PHY - ADC - Debug UART - Infrared Receiver Missing: - HDMI audio Changes since v1 at [1]: - Add missing IR node [1] http://lore.kernel.org/r/20200424124406.13870-1-narmstr...@baylibre.com Dongjin Kim (1): arm64: dts: meson-sm1: add support for Hardkernel ODROID-C4 Neil Armstrong (1): dt-bindings: arm: amlogic: add odroid-c4 bindings .../devicetree/bindings/arm/amlogic.yaml | 1 + arch/arm64/boot/dts/amlogic/Makefile | 1 + .../boot/dts/amlogic/meson-sm1-odroid-c4.dts | 402 ++ 3 files changed, 404 insertions(+) create mode 100644 arch/arm64/boot/dts/amlogic/meson-sm1-odroid-c4.dts -- 2.22.0
[PATCH v2 1/2] dt-bindings: arm: amlogic: add odroid-c4 bindings
Add the board bindings for the Hardkernel Odroid-C4 single board computer. Signed-off-by: Neil Armstrong --- Documentation/devicetree/bindings/arm/amlogic.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/arm/amlogic.yaml b/Documentation/devicetree/bindings/arm/amlogic.yaml index f74aba48cec1..11908b151e0a 100644 --- a/Documentation/devicetree/bindings/arm/amlogic.yaml +++ b/Documentation/devicetree/bindings/arm/amlogic.yaml @@ -159,6 +159,7 @@ properties: - enum: - seirobotics,sei610 - khadas,vim3l + - hardkernel,odroid-c4 - const: amlogic,sm1 - description: Boards with the Amlogic Meson A1 A113L SoC -- 2.22.0
[PATCH v2 2/2] arm64: dts: meson-sm1: add support for Hardkernel ODROID-C4
From: Dongjin Kim Add the board support for the Hardkernel Odroid-C4 single board computer. The Odroid-C4 is the Odroid-C2 successor with same form factor, but using a modern Amlogic S905X3 (SM1) SoC and 4x USB3 ports. Signed-off-by: Dongjin Kim Signed-off-by: Neil Armstrong --- arch/arm64/boot/dts/amlogic/Makefile | 1 + .../boot/dts/amlogic/meson-sm1-odroid-c4.dts | 402 ++ 2 files changed, 403 insertions(+) create mode 100644 arch/arm64/boot/dts/amlogic/meson-sm1-odroid-c4.dts diff --git a/arch/arm64/boot/dts/amlogic/Makefile b/arch/arm64/boot/dts/amlogic/Makefile index eef0045320f2..5daab72f5639 100644 --- a/arch/arm64/boot/dts/amlogic/Makefile +++ b/arch/arm64/boot/dts/amlogic/Makefile @@ -40,4 +40,5 @@ dtb-$(CONFIG_ARCH_MESON) += meson-gxm-s912-libretech-pc.dtb dtb-$(CONFIG_ARCH_MESON) += meson-gxm-vega-s96.dtb dtb-$(CONFIG_ARCH_MESON) += meson-sm1-sei610.dtb dtb-$(CONFIG_ARCH_MESON) += meson-sm1-khadas-vim3l.dtb +dtb-$(CONFIG_ARCH_MESON) += meson-sm1-odroid-c4.dtb dtb-$(CONFIG_ARCH_MESON) += meson-a1-ad401.dtb diff --git a/arch/arm64/boot/dts/amlogic/meson-sm1-odroid-c4.dts b/arch/arm64/boot/dts/amlogic/meson-sm1-odroid-c4.dts new file mode 100644 index ..00d90b30f8b4 --- /dev/null +++ b/arch/arm64/boot/dts/amlogic/meson-sm1-odroid-c4.dts @@ -0,0 +1,402 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2020 Dongjin Kim + */ + +/dts-v1/; + +#include "meson-sm1.dtsi" +#include +#include + +/ { + compatible = "hardkernel,odroid-c4", "amlogic,sm1"; + model = "Hardkernel ODROID-C4"; + + aliases { + serial0 = &uart_AO; + ethernet0 = ðmac; + }; + + chosen { + stdout-path = "serial0:115200n8"; + }; + + memory@0 { + device_type = "memory"; + reg = <0x0 0x0 0x0 0x4000>; + }; + + emmc_pwrseq: emmc-pwrseq { + compatible = "mmc-pwrseq-emmc"; + reset-gpios = <&gpio BOOT_12 GPIO_ACTIVE_LOW>; + }; + + leds { + compatible = "gpio-leds"; + + led-blue { + color = ; + function = LED_FUNCTION_STATUS; + gpios = <&gpio_ao GPIOAO_11 GPIO_ACTIVE_HIGH>; + linux,default-trigger = "heartbeat"; + panic-indicator; + }; + }; + + tflash_vdd: regulator-tflash_vdd { + compatible = "regulator-fixed"; + + regulator-name = "TFLASH_VDD"; + regulator-min-microvolt = <330>; + regulator-max-microvolt = <330>; + + gpio = <&gpio_ao GPIOAO_3 GPIO_ACTIVE_HIGH>; + enable-active-high; + regulator-always-on; + }; + + tf_io: gpio-regulator-tf_io { + compatible = "regulator-gpio"; + + regulator-name = "TF_IO"; + regulator-min-microvolt = <180>; + regulator-max-microvolt = <330>; + + gpios = <&gpio_ao GPIOAO_6 GPIO_ACTIVE_HIGH>; + gpios-states = <0>; + + states = <330 0>, +<180 1>; + }; + + flash_1v8: regulator-flash_1v8 { + compatible = "regulator-fixed"; + regulator-name = "FLASH_1V8"; + regulator-min-microvolt = <180>; + regulator-max-microvolt = <180>; + vin-supply = <&vcc_3v3>; + regulator-always-on; + }; + + main_12v: regulator-main_12v { + compatible = "regulator-fixed"; + regulator-name = "12V"; + regulator-min-microvolt = <1200>; + regulator-max-microvolt = <1200>; + regulator-always-on; + }; + + vcc_5v: regulator-vcc_5v { + compatible = "regulator-fixed"; + regulator-name = "5V"; + regulator-min-microvolt = <500>; + regulator-max-microvolt = <500>; + regulator-always-on; + vin-supply = <&main_12v>; + }; + + vcc_1v8: regulator-vcc_1v8 { + compatible = "regulator-fixed"; + regulator-name = "VCC_1V8"; + regulator-min-microvolt = <180>; + regulator-max-microvolt = <180>; + vin-supply = <&vcc_3v3>; + regulator-always-on; + }; + + vcc_3v3: regulator-vcc_3v3 { + compatible = "regulator-fixed"; + regulator-name = "VCC_3V3"; + regulator-min-microvolt = <330>; + regulator-max-microvolt = <330>; + vin-supply = <&vddao_3v3>; + regulator-always-on; + /* FIXME: actually controlled by VDDCPU_B_EN */ + }; + + vddcpu: regulator-vddcpu { + /* +* MP875
RE: [PATCH v9 2/3] dt-bindings: serial: Add reg-io-width compatible
On Tuesday, May 5, 2020 at 2020 4:33:00 PM +0900, Greg Kroah-Hartman > On Wed, May 06, 2020 at 04:00:06PM +0900, Hyunki Koo wrote: > > Add a description for reg-io-width options for the samsung serial UART > > peripheral. > > > > Signed-off-by: Hyunki Koo > > --- > > Documentation/devicetree/bindings/serial/samsung_uart.yaml | 8 > > > > 1 file changed, 8 insertions(+) > > You dropped the reviewed-by tag that Rob gave on the previous version > of this patch. > > Please put that back and resend. > > thanks, > > greg k-h Thank you for your comment I add review tag by Krzysztof Kozlowski in all other patches not only patch2/3 Reviewed-by: Krzysztof Kozlowski Tested on Odroid HC1 (Exynos5422): Tested-by: Krzysztof Kozlowski
[PATCH v3 1/9] dt-bindings: atmel-tcb: convert bindings to json-schema
Convert Atmel Timer Counter Blocks bindings to DT schema format using json-schema. Also move it out of mfd as it is not and has never been related to mfd. Signed-off-by: Alexandre Belloni --- Cc: Rob Herring Changes in v3: - Moved the child node documentation to the parent documentation Changes in v2: - Rebased on v5.7-rc1 - Moved the binding documentation to its proper place - Added back the atmel,tcb-timer child node documentation .../devicetree/bindings/mfd/atmel-tcb.txt | 56 .../soc/microchip/atmel,at91rm9200-tcb.yaml | 126 ++ 2 files changed, 126 insertions(+), 56 deletions(-) delete mode 100644 Documentation/devicetree/bindings/mfd/atmel-tcb.txt create mode 100644 Documentation/devicetree/bindings/soc/microchip/atmel,at91rm9200-tcb.yaml diff --git a/Documentation/devicetree/bindings/mfd/atmel-tcb.txt b/Documentation/devicetree/bindings/mfd/atmel-tcb.txt deleted file mode 100644 index c4a83e364cb6.. --- a/Documentation/devicetree/bindings/mfd/atmel-tcb.txt +++ /dev/null @@ -1,56 +0,0 @@ -* Device tree bindings for Atmel Timer Counter Blocks -- compatible: Should be "atmel,-tcb", "simple-mfd", "syscon". - can be "at91rm9200" or "at91sam9x5" -- reg: Should contain registers location and length -- #address-cells: has to be 1 -- #size-cells: has to be 0 -- interrupts: Should contain all interrupts for the TC block - Note that you can specify several interrupt cells if the TC - block has one interrupt per channel. -- clock-names: tuple listing input clock names. - Required elements: "t0_clk", "slow_clk" - Optional elements: "t1_clk", "t2_clk" -- clocks: phandles to input clocks. - -The TCB can expose multiple subdevices: - * a timer - - compatible: Should be "atmel,tcb-timer" - - reg: Should contain the TCB channels to be used. If the - counter width is 16 bits (at91rm9200-tcb), two consecutive - channels are needed. Else, only one channel will be used. - -Examples: - -One interrupt per TC block: - tcb0: timer@fff7c000 { - compatible = "atmel,at91rm9200-tcb", "simple-mfd", "syscon"; - #address-cells = <1>; - #size-cells = <0>; - reg = <0xfff7c000 0x100>; - interrupts = <18 4>; - clocks = <&tcb0_clk>, <&clk32k>; - clock-names = "t0_clk", "slow_clk"; - - timer@0 { - compatible = "atmel,tcb-timer"; - reg = <0>, <1>; - }; - - timer@2 { - compatible = "atmel,tcb-timer"; - reg = <2>; - }; - }; - -One interrupt per TC channel in a TC block: - tcb1: timer@fffdc000 { - compatible = "atmel,at91rm9200-tcb", "simple-mfd", "syscon"; - #address-cells = <1>; - #size-cells = <0>; - reg = <0xfffdc000 0x100>; - interrupts = <26 4>, <27 4>, <28 4>; - clocks = <&tcb1_clk>, <&clk32k>; - clock-names = "t0_clk", "slow_clk"; - }; - - diff --git a/Documentation/devicetree/bindings/soc/microchip/atmel,at91rm9200-tcb.yaml b/Documentation/devicetree/bindings/soc/microchip/atmel,at91rm9200-tcb.yaml new file mode 100644 index ..4b683151265e --- /dev/null +++ b/Documentation/devicetree/bindings/soc/microchip/atmel,at91rm9200-tcb.yaml @@ -0,0 +1,126 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: "http://devicetree.org/schemas/soc/microchip/atmel,at91rm9200-tcb.yaml#"; +$schema: "http://devicetree.org/meta-schemas/core.yaml#"; + +title: Atmel Timer Counter Block + +maintainers: + - Alexandre Belloni + +description: | + The Atmel (now Microchip) SoCs have timers named Timer Counter Block. Each + timer has three channels with two counters each. + +properties: + compatible: +items: + - enum: + - atmel,at91rm9200-tcb + - atmel,at91sam9x5-tcb + - const: simple-mfd + - const: syscon + + reg: +maxItems: 1 + + interrupts: +description: + List of interrupts. One interrupt per TCB channel if available or one + interrupt for the TC block +minItems: 1 +maxItems: 3 + + clock-names: +description: + List of clock names. Always includes t0_clk and slow clk. Also includes + t1_clk and t2_clk if a clock per channel is available. +minItems: 2 +maxItems: 4 +items: + enum: +- t0_clk +- t1_clk +- t2_clk +- slow_clk + + clocks: +minItems: 2 +maxItems: 4 + + '#address-cells': +const: 1 + + '#size-cells': +const: 0 + +patternProperties: + "^timer@[0-2]$": +description: The timer block channels that are used as timers. +type: object +properties: + compatible: +const: atmel,tcb-timer + reg: +description: + List of channels to use for this particular timer. +minItems:
[PATCH v3 2/9] dt-bindings: microchip: atmel,at91rm9200-tcb: add sama5d2 compatible
The sama5d2 TC block TIMER_CLOCK1 is different from the at91sam9x5 one. Instead of being MCK / 2, it is the TCB GCLK. Signed-off-by: Alexandre Belloni --- Cc: Rob Herring .../soc/microchip/atmel,at91rm9200-tcb.yaml | 36 +++ 1 file changed, 30 insertions(+), 6 deletions(-) diff --git a/Documentation/devicetree/bindings/soc/microchip/atmel,at91rm9200-tcb.yaml b/Documentation/devicetree/bindings/soc/microchip/atmel,at91rm9200-tcb.yaml index 4b683151265e..38403760f64d 100644 --- a/Documentation/devicetree/bindings/soc/microchip/atmel,at91rm9200-tcb.yaml +++ b/Documentation/devicetree/bindings/soc/microchip/atmel,at91rm9200-tcb.yaml @@ -19,6 +19,7 @@ properties: - enum: - atmel,at91rm9200-tcb - atmel,at91sam9x5-tcb + - atmel,sama5d2-tcb - const: simple-mfd - const: syscon @@ -38,12 +39,6 @@ properties: t1_clk and t2_clk if a clock per channel is available. minItems: 2 maxItems: 4 -items: - enum: -- t0_clk -- t1_clk -- t2_clk -- slow_clk clocks: minItems: 2 @@ -72,6 +67,35 @@ patternProperties: - compatible - reg +allOf: + - if: + properties: +compatible: + contains: +const: atmel,sama5d2-tcb +then: + properties: +clocks: + minItems: 3 + maxItems: 3 +clock-names: + items: +- const: t0_clk +- const: gclk +- const: slow_clk +else: + properties: +clocks: + minItems: 2 + maxItems: 4 +clock-names: + items: +enum: + - t0_clk + - t1_clk + - t2_clk + - slow_clk + required: - compatible - reg -- 2.26.2
[PATCH -next] ASoC: sun4i-i2s: Use PTR_ERR_OR_ZERO() to simplify code
Fixes coccicheck warning: sound/soc/sunxi/sun4i-i2s.c:1177:1-3: WARNING: PTR_ERR_OR_ZERO can be used Reported-by: Hulk Robot Signed-off-by: Samuel Zou --- sound/soc/sunxi/sun4i-i2s.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/sound/soc/sunxi/sun4i-i2s.c b/sound/soc/sunxi/sun4i-i2s.c index d0a8d58..72012a6 100644 --- a/sound/soc/sunxi/sun4i-i2s.c +++ b/sound/soc/sunxi/sun4i-i2s.c @@ -1174,10 +1174,8 @@ static int sun4i_i2s_init_regmap_fields(struct device *dev, i2s->field_fmt_sr = devm_regmap_field_alloc(dev, i2s->regmap, i2s->variant->field_fmt_sr); - if (IS_ERR(i2s->field_fmt_sr)) - return PTR_ERR(i2s->field_fmt_sr); - return 0; + return PTR_ERR_OR_ZERO(i2s->field_fmt_sr); } static int sun4i_i2s_probe(struct platform_device *pdev) -- 2.6.2
Re: [PATCH bpf-next 0/4] RV64 BPF JIT Optimizations
On 5/6/20 9:08 AM, Björn Töpel wrote: On Wed, 6 May 2020 at 02:03, Luke Nelson wrote: This patch series introduces a set of optimizations to the BPF JIT on RV64. The optimizations are related to the verifier zero-extension optimization and BPF_JMP BPF_K. We tested the optimizations on a QEMU riscv64 virt machine, using lib/test_bpf and test_verifier, and formally verified their correctness using Serval. Luke and Xi, Thanks a lot for working on this! Very nice series! For the series: Reviewed-by: Björn Töpel Acked-by: Björn Töpel Luke Nelson (4): bpf, riscv: Enable missing verifier_zext optimizations on RV64 bpf, riscv: Optimize FROM_LE using verifier_zext on RV64 bpf, riscv: Optimize BPF_JMP BPF_K when imm == 0 on RV64 bpf, riscv: Optimize BPF_JSET BPF_K using andi on RV64 arch/riscv/net/bpf_jit_comp64.c | 64 ++--- 1 file changed, 44 insertions(+), 20 deletions(-) Cc: Xi Wang Applied, thanks everyone!
performance bug in virtio net xdp
So for mergeable bufs, we use ewma machinery to guess the correct buffer size. If we don't guess correctly, XDP has to do aggressive copies. Problem is, xdp paths do not update the ewma at all, except sometimes with XDP_PASS. So whatever we happen to have before we attach XDP, will mostly stay around. The fix is probably to update ewma unconditionally. -- MST
[PATCH v3 4/9] ARM: at91: add atmel tcb capabilities
From: Kamel Bouhara Some atmel socs have extra tcb capabilities that allow using a generic clock source or enabling a quadrature decoder. Signed-off-by: Kamel Bouhara Signed-off-by: Alexandre Belloni --- include/soc/at91/atmel_tcb.h | 5 + 1 file changed, 5 insertions(+) diff --git a/include/soc/at91/atmel_tcb.h b/include/soc/at91/atmel_tcb.h index c3c7200ce151..1d7071dc0bca 100644 --- a/include/soc/at91/atmel_tcb.h +++ b/include/soc/at91/atmel_tcb.h @@ -36,9 +36,14 @@ struct clk; /** * struct atmel_tcb_config - SoC data for a Timer/Counter Block * @counter_width: size in bits of a timer counter register + * @has_gclk: boolean indicating if a timer counter has a generic clock + * @has_qdec: boolean indicating if a timer counter has a quadrature + * decoder. */ struct atmel_tcb_config { size_t counter_width; + boolhas_gclk; + boolhas_qdec; }; /** -- 2.26.2
[PATCH v3 5/9] clocksource/drivers/timer-atmel-tcb: rework 32khz clock selection
On all the supported SoCs, the slow clock is always ATMEL_TC_TIMER_CLOCK5, avoid looking it up and pass it directly to setup_clkevents. Signed-off-by: Alexandre Belloni --- drivers/clocksource/timer-atmel-tcb.c | 11 ++- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/drivers/clocksource/timer-atmel-tcb.c b/drivers/clocksource/timer-atmel-tcb.c index 7427b07495a8..b255a4a1a36b 100644 --- a/drivers/clocksource/timer-atmel-tcb.c +++ b/drivers/clocksource/timer-atmel-tcb.c @@ -346,7 +346,7 @@ static void __init tcb_setup_single_chan(struct atmel_tc *tc, int mck_divisor_id writel(ATMEL_TC_SYNC, tcaddr + ATMEL_TC_BCR); } -static const u8 atmel_tcb_divisors[5] = { 2, 8, 32, 128, 0, }; +static const u8 atmel_tcb_divisors[] = { 2, 8, 32, 128 }; static const struct of_device_id atmel_tcb_of_match[] = { { .compatible = "atmel,at91rm9200-tcb", .data = (void *)16, }, @@ -362,7 +362,6 @@ static int __init tcb_clksrc_init(struct device_node *node) u64 (*tc_sched_clock)(void); u32 rate, divided_rate = 0; int best_divisor_idx = -1; - int clk32k_divisor_idx = -1; int bits; int i; int ret; @@ -416,12 +415,6 @@ static int __init tcb_clksrc_init(struct device_node *node) unsigned divisor = atmel_tcb_divisors[i]; unsigned tmp; - /* remember 32 KiHz clock for later */ - if (!divisor) { - clk32k_divisor_idx = i; - continue; - } - tmp = rate / divisor; pr_debug("TC: %u / %-3u [%d] --> %u\n", rate, divisor, i, tmp); if (best_divisor_idx > 0) { @@ -467,7 +460,7 @@ static int __init tcb_clksrc_init(struct device_node *node) goto err_disable_t1; /* channel 2: periodic and oneshot timer support */ - ret = setup_clkevents(&tc, clk32k_divisor_idx); + ret = setup_clkevents(&tc, ATMEL_TC_TIMER_CLOCK5); if (ret) goto err_unregister_clksrc; -- 2.26.2
[PATCH v3 3/9] ARM: dts: at91: sama5d2: add TCB GCLK
The sama5d2 tcbs take an extra input clock, their gclk. Signed-off-by: Alexandre Belloni --- arch/arm/boot/dts/sama5d2.dtsi | 12 ++-- 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/arch/arm/boot/dts/sama5d2.dtsi b/arch/arm/boot/dts/sama5d2.dtsi index ab550d69db91..996143e966d8 100644 --- a/arch/arm/boot/dts/sama5d2.dtsi +++ b/arch/arm/boot/dts/sama5d2.dtsi @@ -499,23 +499,23 @@ macb0: ethernet@f8008000 { }; tcb0: timer@f800c000 { - compatible = "atmel,at91sam9x5-tcb", "simple-mfd", "syscon"; + compatible = "atmel,sama5d2-tcb", "simple-mfd", "syscon"; #address-cells = <1>; #size-cells = <0>; reg = <0xf800c000 0x100>; interrupts = <35 IRQ_TYPE_LEVEL_HIGH 0>; - clocks = <&pmc PMC_TYPE_PERIPHERAL 35>, <&clk32k>; - clock-names = "t0_clk", "slow_clk"; + clocks = <&pmc PMC_TYPE_PERIPHERAL 35>, <&pmc PMC_TYPE_GCK 35>, <&clk32k>; + clock-names = "t0_clk", "gclk", "slow_clk"; }; tcb1: timer@f801 { - compatible = "atmel,at91sam9x5-tcb", "simple-mfd", "syscon"; + compatible = "atmel,sama5d2-tcb", "simple-mfd", "syscon"; #address-cells = <1>; #size-cells = <0>; reg = <0xf801 0x100>; interrupts = <36 IRQ_TYPE_LEVEL_HIGH 0>; - clocks = <&pmc PMC_TYPE_PERIPHERAL 36>, <&clk32k>; - clock-names = "t0_clk", "slow_clk"; + clocks = <&pmc PMC_TYPE_PERIPHERAL 36>, <&pmc PMC_TYPE_GCK 36>, <&clk32k>; + clock-names = "t0_clk", "gclk", "slow_clk"; }; hsmc: hsmc@f8014000 { -- 2.26.2
[PATCH v3 9/9] clocksource/drivers/timer-atmel-tcb: add sama5d2 support
The first divisor for the sama5d2 is actually the gclk selector. Because the currently remaining divisors are fitting the use case, currently ensure it is skipped. Signed-off-by: Alexandre Belloni --- drivers/clocksource/timer-atmel-tcb.c | 11 ++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/drivers/clocksource/timer-atmel-tcb.c b/drivers/clocksource/timer-atmel-tcb.c index ccb77b9cb489..e373b02d509a 100644 --- a/drivers/clocksource/timer-atmel-tcb.c +++ b/drivers/clocksource/timer-atmel-tcb.c @@ -359,9 +359,15 @@ static struct atmel_tcb_config tcb_sam9x5_config = { .counter_width = 32, }; +static struct atmel_tcb_config tcb_sama5d2_config = { + .counter_width = 32, + .has_gclk = 1, +}; + static const struct of_device_id atmel_tcb_of_match[] = { { .compatible = "atmel,at91rm9200-tcb", .data = &tcb_rm9200_config, }, { .compatible = "atmel,at91sam9x5-tcb", .data = &tcb_sam9x5_config, }, + { .compatible = "atmel,sama5d2-tcb", .data = &tcb_sama5d2_config, }, { /* sentinel */ } }; @@ -426,7 +432,10 @@ static int __init tcb_clksrc_init(struct device_node *node) /* How fast will we be counting? Pick something over 5 MHz. */ rate = (u32) clk_get_rate(t0_clk); - for (i = 0; i < ARRAY_SIZE(atmel_tcb_divisors); i++) { + i = 0; + if (tc.tcb_config->has_gclk) + i = 1; + for (; i < ARRAY_SIZE(atmel_tcb_divisors); i++) { unsigned divisor = atmel_tcb_divisors[i]; unsigned tmp; -- 2.26.2
[PATCH v3 8/9] clocksource/drivers/timer-atmel-tcb: allow selecting first divider
The divider selection algorithm never allowed to get index 0. It was also continuing to look for dividers, trying to find the slow clock selection. This is not necessary anymore. Signed-off-by: Alexandre Belloni --- drivers/clocksource/timer-atmel-tcb.c | 6 ++ 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/clocksource/timer-atmel-tcb.c b/drivers/clocksource/timer-atmel-tcb.c index 8fcd4d74c54b..ccb77b9cb489 100644 --- a/drivers/clocksource/timer-atmel-tcb.c +++ b/drivers/clocksource/timer-atmel-tcb.c @@ -432,10 +432,8 @@ static int __init tcb_clksrc_init(struct device_node *node) tmp = rate / divisor; pr_debug("TC: %u / %-3u [%d] --> %u\n", rate, divisor, i, tmp); - if (best_divisor_idx > 0) { - if (tmp < 5 * 1000 * 1000) - continue; - } + if ((best_divisor_idx >= 0) && (tmp < 5 * 1000 * 1000)) + break; divided_rate = tmp; best_divisor_idx = i; } -- 2.26.2
[PATCH v3 6/9] clocksource/drivers/timer-atmel-tcb: fill tcb_config
Use the tcb_config and struct atmel_tcb_config to get the timer counter width. This is necessary because atmel_tcb_config will be extended later on. Signed-off-by: Alexandre Belloni --- drivers/clocksource/timer-atmel-tcb.c | 18 +++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/drivers/clocksource/timer-atmel-tcb.c b/drivers/clocksource/timer-atmel-tcb.c index b255a4a1a36b..423af2f9835f 100644 --- a/drivers/clocksource/timer-atmel-tcb.c +++ b/drivers/clocksource/timer-atmel-tcb.c @@ -348,9 +348,17 @@ static void __init tcb_setup_single_chan(struct atmel_tc *tc, int mck_divisor_id static const u8 atmel_tcb_divisors[] = { 2, 8, 32, 128 }; +static struct atmel_tcb_config tcb_rm9200_config = { + .counter_width = 16, +}; + +static struct atmel_tcb_config tcb_sam9x5_config = { + .counter_width = 32, +}; + static const struct of_device_id atmel_tcb_of_match[] = { - { .compatible = "atmel,at91rm9200-tcb", .data = (void *)16, }, - { .compatible = "atmel,at91sam9x5-tcb", .data = (void *)32, }, + { .compatible = "atmel,at91rm9200-tcb", .data = &tcb_rm9200_config, }, + { .compatible = "atmel,at91sam9x5-tcb", .data = &tcb_sam9x5_config, }, { /* sentinel */ } }; @@ -398,7 +406,11 @@ static int __init tcb_clksrc_init(struct device_node *node) } match = of_match_node(atmel_tcb_of_match, node->parent); - bits = (uintptr_t)match->data; + if (!match) + return -ENODEV; + + tc.tcb_config = match->data; + bits = tc.tcb_config->counter_width; for (i = 0; i < ARRAY_SIZE(tc.irq); i++) writel(ATMEL_TC_ALL_IRQ, tc.regs + ATMEL_TC_REG(i, IDR)); -- 2.26.2
[PATCH v3 7/9] clocksource/drivers/timer-atmel-tcb: stop using the 32kHz for clockevents
Stop using the slow clock as the clock source for 32 bit counters because even at 10MHz, they are able to handle delays up to two minutes. This provides a way better resolution. Signed-off-by: Alexandre Belloni --- drivers/clocksource/timer-atmel-tcb.c | 61 ++- 1 file changed, 32 insertions(+), 29 deletions(-) diff --git a/drivers/clocksource/timer-atmel-tcb.c b/drivers/clocksource/timer-atmel-tcb.c index 423af2f9835f..8fcd4d74c54b 100644 --- a/drivers/clocksource/timer-atmel-tcb.c +++ b/drivers/clocksource/timer-atmel-tcb.c @@ -27,9 +27,10 @@ * - Some chips support 32 bit counter. A single channel is used for * this 32 bit free-running counter. the second channel is not used. * - * - The third channel may be used to provide a 16-bit clockevent - * source, used in either periodic or oneshot mode. This runs - * at 32 KiHZ, and can handle delays of up to two seconds. + * - The third channel may be used to provide a clockevent source, used in + * either periodic or oneshot mode. For 16-bit counter its runs at 32 KiHZ, + * and can handle delays of up to two seconds. For 32-bit counters, it runs at + * the same rate as the clocksource * * REVISIT behavior during system suspend states... we should disable * all clocks and save the power. Easily done for clockevent devices, @@ -47,6 +48,8 @@ static struct } tcb_cache[3]; static u32 bmr_cache; +static const u8 atmel_tcb_divisors[] = { 2, 8, 32, 128 }; + static u64 tc_get_cycles(struct clocksource *cs) { unsigned long flags; @@ -151,13 +154,6 @@ static struct tc_clkevt_device *to_tc_clkevt(struct clock_event_device *clkevt) return container_of(clkevt, struct tc_clkevt_device, clkevt); } -/* For now, we always use the 32K clock ... this optimizes for NO_HZ, - * because using one of the divided clocks would usually mean the - * tick rate can never be less than several dozen Hz (vs 0.5 Hz). - * - * A divided clock could be good for high resolution timers, since - * 30.5 usec resolution can seem "low". - */ static u32 timer_clock; static int tc_shutdown(struct clock_event_device *d) @@ -183,7 +179,7 @@ static int tc_set_oneshot(struct clock_event_device *d) clk_enable(tcd->clk); - /* slow clock, count up to RC, then irq and stop */ + /* count up to RC, then irq and stop */ writel(timer_clock | ATMEL_TC_CPCSTOP | ATMEL_TC_WAVE | ATMEL_TC_WAVESEL_UP_AUTO, regs + ATMEL_TC_REG(2, CMR)); writel(ATMEL_TC_CPCS, regs + ATMEL_TC_REG(2, IER)); @@ -205,7 +201,7 @@ static int tc_set_periodic(struct clock_event_device *d) */ clk_enable(tcd->clk); - /* slow clock, count up to RC, then irq and restart */ + /* count up to RC, then irq and restart */ writel(timer_clock | ATMEL_TC_WAVE | ATMEL_TC_WAVESEL_UP_AUTO, regs + ATMEL_TC_REG(2, CMR)); writel((32768 + HZ / 2) / HZ, tcaddr + ATMEL_TC_REG(2, RC)); @@ -256,47 +252,56 @@ static irqreturn_t ch2_irq(int irq, void *handle) return IRQ_NONE; } -static int __init setup_clkevents(struct atmel_tc *tc, int clk32k_divisor_idx) +static int __init setup_clkevents(struct atmel_tc *tc, int divisor_idx) { + u32 rate; int ret; struct clk *t2_clk = tc->clk[2]; int irq = tc->irq[2]; - - ret = clk_prepare_enable(tc->slow_clk); - if (ret) - return ret; + int bits = tc->tcb_config->counter_width; /* try to enable t2 clk to avoid future errors in mode change */ ret = clk_prepare_enable(t2_clk); - if (ret) { - clk_disable_unprepare(tc->slow_clk); + if (ret) return ret; - } - - clk_disable(t2_clk); clkevt.regs = tc->regs; clkevt.clk = t2_clk; - timer_clock = clk32k_divisor_idx; + if (bits == 32) { + timer_clock = divisor_idx; + rate = clk_get_rate(t2_clk) / atmel_tcb_divisors[divisor_idx]; + } else { + ret = clk_prepare_enable(tc->slow_clk); + if (ret) { + clk_disable_unprepare(t2_clk); + return ret; + } + + rate = clk_get_rate(tc->slow_clk); + timer_clock = ATMEL_TC_TIMER_CLOCK5; + } + + clk_disable(t2_clk); clkevt.clkevt.cpumask = cpumask_of(0); ret = request_irq(irq, ch2_irq, IRQF_TIMER, "tc_clkevt", &clkevt); if (ret) { clk_unprepare(t2_clk); - clk_disable_unprepare(tc->slow_clk); + if (bits != 32) + clk_disable_unprepare(tc->slow_clk); return ret; } - clockevents_config_and_register(&clkevt.clkevt, 32768, 1, 0x); + clockevents_config_and_register(&clkevt.clkevt, rate, 1, BIT(bits) - 1); return ret; } #else /* !CONFIG_GENERIC_CLOCKEVENTS */ -stati
[PATCH -next] nvmem: jz4780-efuse: Use PTR_ERR_OR_ZERO() to simplify code
Fixes coccicheck warning: drivers/nvmem/jz4780-efuse.c:214:1-3: WARNING: PTR_ERR_OR_ZERO can be used Reported-by: Hulk Robot Signed-off-by: Samuel Zou --- drivers/nvmem/jz4780-efuse.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/nvmem/jz4780-efuse.c b/drivers/nvmem/jz4780-efuse.c index 512e187..0b01b84 100644 --- a/drivers/nvmem/jz4780-efuse.c +++ b/drivers/nvmem/jz4780-efuse.c @@ -211,10 +211,8 @@ static int jz4780_efuse_probe(struct platform_device *pdev) cfg.priv = efuse; nvmem = devm_nvmem_register(dev, &cfg); - if (IS_ERR(nvmem)) - return PTR_ERR(nvmem); - return 0; + return PTR_ERR_OR_ZERO(nvmem); } static const struct of_device_id jz4780_efuse_match[] = { -- 2.6.2
Re: [patch V4 part 2 15/18] x86/kvm/svm: Handle hardirqs proper on guest enter/exit
On 05/05/20 15:41, Thomas Gleixner wrote: > + * VMENTER enables interrupts (host state), but the kernel state is > + * interrupts disabled when this is invoked. Also tell RCU about > + * it. This is the same logic as for exit_to_user_mode(). > + * > + * 1) Trace interrupts on state > + * 2) Prepare lockdep with RCU on > + * 3) Invoke context tracking if enabled to adjust RCU state > + * 4) Tell lockdep that interrupts are enabled > + * > + * This has to be after x86_spec_ctrl_set_guest() because that can > + * take locks (lockdep needs RCU) and calls into world and some > + * more. >*/ > + trace_hardirqs_on_prepare(); > + lockdep_hardirqs_on_prepare(CALLER_ADDR0); > guest_enter_irqoff(); > + lockdep_hardirqs_on(CALLER_ADDR0); > > __svm_vcpu_run(svm->vmcb_pa, (unsigned long *)&svm->vcpu.arch.regs); > > @@ -3348,14 +3359,23 @@ static void svm_vcpu_run(struct kvm_vcpu > loadsegment(gs, svm->host.gs); > #endif > #endif > + > /* > - * Tell context tracking that this CPU is back. > + * VMEXIT disables interrupts (host state, see the CLI in the ASM > + * above), Apart from the small inaccuracy in that CLI has moved to vmenter.S, the comments and commit message don't really help my understanding of why this is needed. It's true that interrupts cause a vmexit, and therefore from the processor point of view it's as if they are enabled. However, the interrupt remains latched until local_irq_enable() in vcpu_enter_guest, so from the point of view of the kernel interrupts are still disabled. I don't understand why it's necessary to inform tracing and lockdep about a processor-internal state that doesn't percolate up to the kernel. For VMX indeed some care is necessary, because we the interrupt is eaten rather than latched. Therefore, we call the interrupt handler from handle_external_interrupt_irqoff while EFLAGS.IF is still clear. However, if informing trace and lockdep turns out to be unnecessary after all for SVM, it should be okay (and clearer) to place the code in handle_external_interrupt_irqoff (also in arch/x86/kvm/vmx/vmx.c) . Instead, if I'm wrong, the four steps above are the same in code and comment, and same for the three steps in the comment below. Can you replace them with the "why" of this change? Thanks, Paolo > + but tracing and lockdep have them in state 'on'. Same as > + * enter_from_user_mode(). > + * > + * 1) Tell lockdep that interrupts are disabled > + * 2) Invoke context tracking if enabled to reactivate RCU > + * 3) Trace interrupts off state >* >* This needs to be done before the below as native_read_msr() >* contains a tracepoint and x86_spec_ctrl_restore_host() calls >* into world and some more. >*/ > + lockdep_hardirqs_off(CALLER_ADDR0); > guest_exit_irqoff(); > + trace_hardirqs_off_prepare(); >
Re: [patch V4 part 1 02/36] x86/hw_breakpoint: Prevent data breakpoints on cpu_entry_area
On Tue, May 05, 2020 at 03:16:04PM +0200, Thomas Gleixner wrote: > From: Andy Lutomirski > > A data breakpoint near the top of an IST stack will cause unresoverable unrecoverable > recursion. A data breakpoint on the GDT, IDT, or TSS is terrifying. "terrifying" huh? Colorful. :) > Prevent either of these from happening. > > Co-developed-by: Peter Zijlstra > Signed-off-by: Andy Lutomirski > Signed-off-by: Peter Zijlstra (Intel) > Signed-off-by: Thomas Gleixner > --- > arch/x86/kernel/hw_breakpoint.c | 25 + > 1 file changed, 25 insertions(+) Reviewed-by: Borislav Petkov -- Regards/Gruss, Boris. https://people.kernel.org/tglx/notes-about-netiquette
[PATCH v14 09/11] soc: mediatek: Add a comma at the end
A minor coding style fix Signed-off-by: Weiyi Lu --- drivers/soc/mediatek/mtk-scpsys.c | 14 +++--- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/soc/mediatek/mtk-scpsys.c b/drivers/soc/mediatek/mtk-scpsys.c index 15d018e..277ddbf 100644 --- a/drivers/soc/mediatek/mtk-scpsys.c +++ b/drivers/soc/mediatek/mtk-scpsys.c @@ -1430,7 +1430,7 @@ static void mtk_register_power_domains(struct platform_device *pdev, .num_domains = ARRAY_SIZE(scp_domain_data_mt2701), .regs = { .pwr_sta_offs = SPM_PWR_STATUS, - .pwr_sta2nd_offs = SPM_PWR_STATUS_2ND + .pwr_sta2nd_offs = SPM_PWR_STATUS_2ND, }, }; @@ -1441,7 +1441,7 @@ static void mtk_register_power_domains(struct platform_device *pdev, .num_subdomains = ARRAY_SIZE(scp_subdomain_mt2712), .regs = { .pwr_sta_offs = SPM_PWR_STATUS, - .pwr_sta2nd_offs = SPM_PWR_STATUS_2ND + .pwr_sta2nd_offs = SPM_PWR_STATUS_2ND, }, }; @@ -1452,7 +1452,7 @@ static void mtk_register_power_domains(struct platform_device *pdev, .num_subdomains = ARRAY_SIZE(scp_subdomain_mt6797), .regs = { .pwr_sta_offs = SPM_PWR_STATUS_MT6797, - .pwr_sta2nd_offs = SPM_PWR_STATUS_2ND_MT6797 + .pwr_sta2nd_offs = SPM_PWR_STATUS_2ND_MT6797, }, }; @@ -1461,7 +1461,7 @@ static void mtk_register_power_domains(struct platform_device *pdev, .num_domains = ARRAY_SIZE(scp_domain_data_mt7622), .regs = { .pwr_sta_offs = SPM_PWR_STATUS, - .pwr_sta2nd_offs = SPM_PWR_STATUS_2ND + .pwr_sta2nd_offs = SPM_PWR_STATUS_2ND, }, }; @@ -1470,7 +1470,7 @@ static void mtk_register_power_domains(struct platform_device *pdev, .num_domains = ARRAY_SIZE(scp_domain_data_mt7623a), .regs = { .pwr_sta_offs = SPM_PWR_STATUS, - .pwr_sta2nd_offs = SPM_PWR_STATUS_2ND + .pwr_sta2nd_offs = SPM_PWR_STATUS_2ND, }, }; @@ -1481,7 +1481,7 @@ static void mtk_register_power_domains(struct platform_device *pdev, .num_subdomains = ARRAY_SIZE(scp_subdomain_mt8173), .regs = { .pwr_sta_offs = SPM_PWR_STATUS, - .pwr_sta2nd_offs = SPM_PWR_STATUS_2ND + .pwr_sta2nd_offs = SPM_PWR_STATUS_2ND, }, }; @@ -1492,7 +1492,7 @@ static void mtk_register_power_domains(struct platform_device *pdev, .num_subdomains = ARRAY_SIZE(scp_subdomain_mt8183), .regs = { .pwr_sta_offs = 0x0180, - .pwr_sta2nd_offs = 0x0184 + .pwr_sta2nd_offs = 0x0184, } }; -- 1.8.1.1.dirty
[PATCH v14 02/11] dt-bindings: soc: Add MT8183 power dt-bindings
Add power dt-bindings of MT8183 and introduces "BASIC" and "SUBSYS" clock types in binding document. The "BASIC" type is compatible to the original power control with clock name [a-z]+[0-9]*, e.g. mm, vpu1. The "SUBSYS" type is used for bus protection control with clock name [a-z]+-[0-9]+, e.g. isp-0, cam-1. And add an optional smi-comm property for phandle to smi-common controller. Signed-off-by: Weiyi Lu --- .../devicetree/bindings/soc/mediatek/scpsys.txt| 21 ++--- include/dt-bindings/power/mt8183-power.h | 26 ++ 2 files changed, 44 insertions(+), 3 deletions(-) create mode 100644 include/dt-bindings/power/mt8183-power.h diff --git a/Documentation/devicetree/bindings/soc/mediatek/scpsys.txt b/Documentation/devicetree/bindings/soc/mediatek/scpsys.txt index 2bc3677..5424e66 100644 --- a/Documentation/devicetree/bindings/soc/mediatek/scpsys.txt +++ b/Documentation/devicetree/bindings/soc/mediatek/scpsys.txt @@ -15,6 +15,7 @@ power/power-domain.yaml. It provides the power domains defined in - include/dt-bindings/power/mt2701-power.h - include/dt-bindings/power/mt2712-power.h - include/dt-bindings/power/mt7622-power.h +- include/dt-bindings/power/mt8183-power.h Required properties: - compatible: Should be one of: @@ -27,12 +28,16 @@ Required properties: - "mediatek,mt7623a-scpsys": For MT7623A SoC - "mediatek,mt7629-scpsys", "mediatek,mt7622-scpsys": For MT7629 SoC - "mediatek,mt8173-scpsys" + - "mediatek,mt8183-scpsys" - #power-domain-cells: Must be 1 - reg: Address range of the SCPSYS unit - infracfg: must contain a phandle to the infracfg controller -- clock, clock-names: clocks according to the common clock binding. - These are clocks which hardware needs to be - enabled before enabling certain power domains. +- clock, clock-names: Clocks according to the common clock binding. + Some SoCs have to groups of clocks. + BASIC clocks need to be enabled before enabling the + corresponding power domain. + SUBSYS clocks need to be enabled before releasing the + bus protection. Required clocks for MT2701 or MT7623: "mm", "mfg", "ethif" Required clocks for MT2712: "mm", "mfg", "venc", "jpgdec", "audio", "vdec" Required clocks for MT6765: MUX: "mm", "mfg" @@ -43,6 +48,15 @@ Required properties: Required clocks for MT7622 or MT7629: "hif_sel" Required clocks for MT7623A: "ethif" Required clocks for MT8173: "mm", "mfg", "venc", "venc_lt" + Required clocks for MT8183: BASIC: "audio", "mfg", "mm", "cam", "isp", + "vpu", "vpu1", "vpu2", "vpu3" + SUBSYS: "mm-0", "mm-1", "mm-2", "mm-3", + "mm-4", "mm-5", "mm-6", "mm-7", + "mm-8", "mm-9", "isp-0", "isp-1", + "cam-0", "cam-1", "cam-2", "cam-3", + "cam-4", "cam-5", "cam-6", "vpu-0", + "vpu-1", "vpu-2", "vpu-3", "vpu-4", + "vpu-5" Optional properties: - vdec-supply: Power supply for the vdec power domain @@ -55,6 +69,7 @@ Optional properties: - mfg_async-supply: Power supply for the mfg_async power domain - mfg_2d-supply: Power supply for the mfg_2d power domain - mfg-supply: Power supply for the mfg power domain +- smi_comm: a phandle to the smi-common controller Example: diff --git a/include/dt-bindings/power/mt8183-power.h b/include/dt-bindings/power/mt8183-power.h new file mode 100644 index 000..d6b25f8 --- /dev/null +++ b/include/dt-bindings/power/mt8183-power.h @@ -0,0 +1,26 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2018 MediaTek Inc. + * Author: Weiyi Lu + */ + +#ifndef _DT_BINDINGS_POWER_MT8183_POWER_H +#define _DT_BINDINGS_POWER_MT8183_POWER_H + +#define MT8183_POWER_DOMAIN_AUDIO 0 +#define MT8183_POWER_DOMAIN_CONN 1 +#define MT8183_POWER_DOMAIN_MFG_ASYNC 2 +#define MT8183_POWER_DOMAIN_MFG3 +#define MT8183_POWER_DOMAIN_MFG_CORE0 4 +#define MT8183_POWER_DOMAIN_MFG_CORE1 5 +#define MT8183_POWER_DOMAIN_MFG_2D 6 +#define MT8183_POWER_DOMAIN_DISP 7 +#define MT8183_POWER_DOMAIN_CAM8 +#define MT8183_POWER_DOMAIN_ISP9 +#define MT8183_POWER_DOMAIN_VDEC 10 +#define MT8183_POWER_DOMAIN_VENC 11 +#define MT8183_POWER_DOMAIN_VPU_TOP12 +#define MT8183_POWER_DOMAIN_VPU_CORE0 13 +#define MT8183_POWER_DOMAIN_VPU_CORE1 14 + +#endif /* _DT_BINDINGS_POWER_MT8183_POWER_H */ -- 1.8.1.1.dirty
[PATCH v14 07/11] soc: mediatek: Add extra sram control
For some power domains like vpu_core on MT8183 whose sram need to do clock and internal isolation while power on/off sram. We add a cap "MTK_SCPD_SRAM_ISO" to judge if we need to do the extra sram isolation control or not. Signed-off-by: Weiyi Lu Reviewed-by: Nicolas Boichat --- drivers/soc/mediatek/mtk-scpsys.c | 22 -- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/drivers/soc/mediatek/mtk-scpsys.c b/drivers/soc/mediatek/mtk-scpsys.c index f76beca..f1949a9 100644 --- a/drivers/soc/mediatek/mtk-scpsys.c +++ b/drivers/soc/mediatek/mtk-scpsys.c @@ -25,6 +25,7 @@ #define MTK_SCPD_ACTIVE_WAKEUP BIT(0) #define MTK_SCPD_FWAIT_SRAMBIT(1) +#define MTK_SCPD_SRAM_ISO BIT(2) #define MTK_SCPD_CAPS(_scpd, _x) ((_scpd)->data->caps & (_x)) #define SPM_VDE_PWR_CON0x0210 @@ -56,6 +57,8 @@ #define PWR_ON_BIT BIT(2) #define PWR_ON_2ND_BIT BIT(3) #define PWR_CLK_DIS_BITBIT(4) +#define PWR_SRAM_CLKISO_BITBIT(5) +#define PWR_SRAM_ISOINT_B_BIT BIT(6) #define PWR_STATUS_CONNBIT(1) #define PWR_STATUS_DISPBIT(3) @@ -290,6 +293,14 @@ static int scpsys_sram_enable(struct scp_domain *scpd, void __iomem *ctl_addr) return ret; } + if (MTK_SCPD_CAPS(scpd, MTK_SCPD_SRAM_ISO)) { + val = readl(ctl_addr) | PWR_SRAM_ISOINT_B_BIT; + writel(val, ctl_addr); + udelay(1); + val &= ~PWR_SRAM_CLKISO_BIT; + writel(val, ctl_addr); + } + return 0; } @@ -299,8 +310,15 @@ static int scpsys_sram_disable(struct scp_domain *scpd, void __iomem *ctl_addr) u32 pdn_ack = scpd->data->sram_pdn_ack_bits; int tmp; - val = readl(ctl_addr); - val |= scpd->data->sram_pdn_bits; + if (MTK_SCPD_CAPS(scpd, MTK_SCPD_SRAM_ISO)) { + val = readl(ctl_addr) | PWR_SRAM_CLKISO_BIT; + writel(val, ctl_addr); + val &= ~PWR_SRAM_ISOINT_B_BIT; + writel(val, ctl_addr); + udelay(1); + } + + val = readl(ctl_addr) | scpd->data->sram_pdn_bits; writel(val, ctl_addr); /* Either wait until SRAM_PDN_ACK all 1 or 0 */ -- 1.8.1.1.dirty
[PATCH v14 10/11] arm64: dts: Add power controller device node of MT8183
Add power controller node and smi-common node for MT8183 In scpsys node, it contains clocks and regmapping of infracfg and smi-common for bus protection. Signed-off-by: Weiyi Lu --- arch/arm64/boot/dts/mediatek/mt8183.dtsi | 62 1 file changed, 62 insertions(+) diff --git a/arch/arm64/boot/dts/mediatek/mt8183.dtsi b/arch/arm64/boot/dts/mediatek/mt8183.dtsi index 97863ad..5dce7d6 100644 --- a/arch/arm64/boot/dts/mediatek/mt8183.dtsi +++ b/arch/arm64/boot/dts/mediatek/mt8183.dtsi @@ -8,6 +8,7 @@ #include #include #include +#include #include #include "mt8183-pinfunc.h" @@ -301,6 +302,62 @@ #interrupt-cells = <2>; }; + scpsys: power-controller@10006000 { + compatible = "mediatek,mt8183-scpsys", "syscon"; + #power-domain-cells = <1>; + reg = <0 0x10006000 0 0x1000>; + clocks = <&topckgen CLK_TOP_MUX_AUD_INTBUS>, +<&infracfg CLK_INFRA_AUDIO>, +<&infracfg CLK_INFRA_AUDIO_26M_BCLK>, +<&topckgen CLK_TOP_MUX_MFG>, +<&topckgen CLK_TOP_MUX_MM>, +<&topckgen CLK_TOP_MUX_CAM>, +<&topckgen CLK_TOP_MUX_IMG>, +<&topckgen CLK_TOP_MUX_IPU_IF>, +<&topckgen CLK_TOP_MUX_DSP>, +<&topckgen CLK_TOP_MUX_DSP1>, +<&topckgen CLK_TOP_MUX_DSP2>, +<&mmsys CLK_MM_SMI_COMMON>, +<&mmsys CLK_MM_SMI_LARB0>, +<&mmsys CLK_MM_SMI_LARB1>, +<&mmsys CLK_MM_GALS_COMM0>, +<&mmsys CLK_MM_GALS_COMM1>, +<&mmsys CLK_MM_GALS_CCU2MM>, +<&mmsys CLK_MM_GALS_IPU12MM>, +<&mmsys CLK_MM_GALS_IMG2MM>, +<&mmsys CLK_MM_GALS_CAM2MM>, +<&mmsys CLK_MM_GALS_IPU2MM>, +<&imgsys CLK_IMG_LARB5>, +<&imgsys CLK_IMG_LARB2>, +<&camsys CLK_CAM_LARB6>, +<&camsys CLK_CAM_LARB3>, +<&camsys CLK_CAM_SENINF>, +<&camsys CLK_CAM_CAMSV0>, +<&camsys CLK_CAM_CAMSV1>, +<&camsys CLK_CAM_CAMSV2>, +<&camsys CLK_CAM_CCU>, +<&ipu_conn CLK_IPU_CONN_IPU>, +<&ipu_conn CLK_IPU_CONN_AHB>, +<&ipu_conn CLK_IPU_CONN_AXI>, +<&ipu_conn CLK_IPU_CONN_ISP>, +<&ipu_conn CLK_IPU_CONN_CAM_ADL>, +<&ipu_conn CLK_IPU_CONN_IMG_ADL>; + clock-names = "audio", "audio1", "audio2", + "mfg", "mm", "cam", + "isp", "vpu", "vpu1", + "vpu2", "vpu3", "mm-0", + "mm-1", "mm-2", "mm-3", + "mm-4", "mm-5", "mm-6", + "mm-7", "mm-8", "mm-9", + "isp-0", "isp-1", "cam-0", + "cam-1", "cam-2", "cam-3", + "cam-4", "cam-5", "cam-6", + "vpu-0", "vpu-1", "vpu-2", + "vpu-3", "vpu-4", "vpu-5"; + infracfg = <&infracfg>; + smi_comm = <&smi_common>; + }; + watchdog: watchdog@10007000 { compatible = "mediatek,mt8183-wdt", "mediatek,mt6589-wdt"; @@ -658,6 +715,11 @@ #clock-cells = <1>; }; + smi_common: smi@14019000 { + compatible = "mediatek,mt8183-smi-common", "syscon"; + reg = <0 0x14019000 0 0x1000>; + }; + imgsys: syscon@1502 { compatible = "mediatek,mt8183-imgsys", "syscon"; reg = <0 0x1502 0 0x1000>; -- 1.8.1.1.dirty
[PATCH v14 04/11] soc: mediatek: Remove infracfg misc driver support
The functions provided by infracfg misc driver have no other user except the scpsys driver so move those into scpsys driver directly. And then, remove infracfg misc drvier which is no longer being used. BTW, in next patch, we're going to extend the bus protection functions with more customized arguments. Signed-off-by: Weiyi Lu --- drivers/soc/mediatek/Kconfig | 10 - drivers/soc/mediatek/Makefile | 1 - drivers/soc/mediatek/mtk-infracfg.c | 79 --- drivers/soc/mediatek/mtk-scpsys.c | 66 + include/linux/soc/mediatek/infracfg.h | 39 - 5 files changed, 57 insertions(+), 138 deletions(-) delete mode 100644 drivers/soc/mediatek/mtk-infracfg.c delete mode 100644 include/linux/soc/mediatek/infracfg.h diff --git a/drivers/soc/mediatek/Kconfig b/drivers/soc/mediatek/Kconfig index 2114b56..f837b3c 100644 --- a/drivers/soc/mediatek/Kconfig +++ b/drivers/soc/mediatek/Kconfig @@ -10,21 +10,12 @@ config MTK_CMDQ depends on ARCH_MEDIATEK || COMPILE_TEST select MAILBOX select MTK_CMDQ_MBOX - select MTK_INFRACFG help Say yes here to add support for the MediaTek Command Queue (CMDQ) driver. The CMDQ is used to help read/write registers with critical time limitation, such as updating display configuration during the vblank. -config MTK_INFRACFG - bool "MediaTek INFRACFG Support" - select REGMAP - help - Say yes here to add support for the MediaTek INFRACFG controller. The - INFRACFG controller contains various infrastructure registers not - directly associated to any device. - config MTK_PMIC_WRAP tristate "MediaTek PMIC Wrapper Support" depends on RESET_CONTROLLER @@ -38,7 +29,6 @@ config MTK_SCPSYS bool "MediaTek SCPSYS Support" default ARCH_MEDIATEK select REGMAP - select MTK_INFRACFG select PM_GENERIC_DOMAINS if PM help Say yes here to add support for the MediaTek SCPSYS power domain diff --git a/drivers/soc/mediatek/Makefile b/drivers/soc/mediatek/Makefile index b017330..2b2c2537 100644 --- a/drivers/soc/mediatek/Makefile +++ b/drivers/soc/mediatek/Makefile @@ -1,5 +1,4 @@ # SPDX-License-Identifier: GPL-2.0-only obj-$(CONFIG_MTK_CMDQ) += mtk-cmdq-helper.o -obj-$(CONFIG_MTK_INFRACFG) += mtk-infracfg.o obj-$(CONFIG_MTK_PMIC_WRAP) += mtk-pmic-wrap.o obj-$(CONFIG_MTK_SCPSYS) += mtk-scpsys.o diff --git a/drivers/soc/mediatek/mtk-infracfg.c b/drivers/soc/mediatek/mtk-infracfg.c deleted file mode 100644 index 341c7ac..000 --- a/drivers/soc/mediatek/mtk-infracfg.c +++ /dev/null @@ -1,79 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Copyright (c) 2015 Pengutronix, Sascha Hauer - */ - -#include -#include -#include -#include -#include - -#define MTK_POLL_DELAY_US 10 -#define MTK_POLL_TIMEOUT(jiffies_to_usecs(HZ)) - -#define INFRA_TOPAXI_PROTECTEN 0x0220 -#define INFRA_TOPAXI_PROTECTSTA1 0x0228 -#define INFRA_TOPAXI_PROTECTEN_SET 0x0260 -#define INFRA_TOPAXI_PROTECTEN_CLR 0x0264 - -/** - * mtk_infracfg_set_bus_protection - enable bus protection - * @regmap: The infracfg regmap - * @mask: The mask containing the protection bits to be enabled. - * @reg_update: The boolean flag determines to set the protection bits - * by regmap_update_bits with enable register(PROTECTEN) or - * by regmap_write with set register(PROTECTEN_SET). - * - * This function enables the bus protection bits for disabled power - * domains so that the system does not hang when some unit accesses the - * bus while in power down. - */ -int mtk_infracfg_set_bus_protection(struct regmap *infracfg, u32 mask, - bool reg_update) -{ - u32 val; - int ret; - - if (reg_update) - regmap_update_bits(infracfg, INFRA_TOPAXI_PROTECTEN, mask, - mask); - else - regmap_write(infracfg, INFRA_TOPAXI_PROTECTEN_SET, mask); - - ret = regmap_read_poll_timeout(infracfg, INFRA_TOPAXI_PROTECTSTA1, - val, (val & mask) == mask, - MTK_POLL_DELAY_US, MTK_POLL_TIMEOUT); - - return ret; -} - -/** - * mtk_infracfg_clear_bus_protection - disable bus protection - * @regmap: The infracfg regmap - * @mask: The mask containing the protection bits to be disabled. - * @reg_update: The boolean flag determines to clear the protection bits - * by regmap_update_bits with enable register(PROTECTEN) or - * by regmap_write with clear register(PROTECTEN_CLR). - * - * This function disables the bus protection bits previously enabled with - * mtk_infracfg_set_bus_protection. - */ - -int mtk_infracfg_clear_bus_protection(struct regmap *infracfg, u32 mask, - bool reg_update) -{ - int ret; - u32 val; - -
[PATCH v14 08/11] soc: mediatek: Add MT8183 scpsys support
Add scpsys driver for MT8183 Signed-off-by: Weiyi Lu Reviewed-by: Nicolas Boichat --- drivers/soc/mediatek/mtk-scpsys.c | 249 ++ 1 file changed, 249 insertions(+) diff --git a/drivers/soc/mediatek/mtk-scpsys.c b/drivers/soc/mediatek/mtk-scpsys.c index f1949a9..15d018e 100644 --- a/drivers/soc/mediatek/mtk-scpsys.c +++ b/drivers/soc/mediatek/mtk-scpsys.c @@ -19,6 +19,7 @@ #include #include #include +#include #define MTK_POLL_DELAY_US 10 #define MTK_POLL_TIMEOUTUSEC_PER_SEC @@ -99,6 +100,34 @@ #define MT8173_TOP_AXI_PROT_EN_MFG_M1 BIT(22) #define MT8173_TOP_AXI_PROT_EN_MFG_SNOOP_OUT BIT(23) +#define MT8183_TOP_AXI_PROT_EN_DISP(BIT(10) | BIT(11)) +#define MT8183_TOP_AXI_PROT_EN_CONN(BIT(13) | BIT(14)) +#define MT8183_TOP_AXI_PROT_EN_MFG (BIT(21) | BIT(22)) +#define MT8183_TOP_AXI_PROT_EN_CAM BIT(28) +#define MT8183_TOP_AXI_PROT_EN_VPU_TOP BIT(27) +#define MT8183_TOP_AXI_PROT_EN_1_DISP (BIT(16) | BIT(17)) +#define MT8183_TOP_AXI_PROT_EN_1_MFG GENMASK(21, 19) +#define MT8183_TOP_AXI_PROT_EN_MM_ISP (BIT(3) | BIT(8)) +#define MT8183_TOP_AXI_PROT_EN_MM_ISP_2ND BIT(10) +#define MT8183_TOP_AXI_PROT_EN_MM_CAM (BIT(4) | BIT(5) | \ +BIT(9) | BIT(13)) +#define MT8183_TOP_AXI_PROT_EN_MM_VPU_TOP (GENMASK(9, 6) | \ +BIT(12)) +#define MT8183_TOP_AXI_PROT_EN_MM_VPU_TOP_2ND (BIT(10) | BIT(11)) +#define MT8183_TOP_AXI_PROT_EN_MM_CAM_2ND BIT(11) +#define MT8183_TOP_AXI_PROT_EN_MCU_VPU_CORE0_2ND (BIT(0) | BIT(2) | \ +BIT(4)) +#define MT8183_TOP_AXI_PROT_EN_MCU_VPU_CORE1_2ND (BIT(1) | BIT(3) | \ +BIT(5)) +#define MT8183_TOP_AXI_PROT_EN_MCU_VPU_CORE0 BIT(6) +#define MT8183_TOP_AXI_PROT_EN_MCU_VPU_CORE1 BIT(7) +#define MT8183_SMI_COMMON_SMI_CLAMP_DISP GENMASK(7, 0) +#define MT8183_SMI_COMMON_SMI_CLAMP_VENC BIT(1) +#define MT8183_SMI_COMMON_SMI_CLAMP_ISPBIT(2) +#define MT8183_SMI_COMMON_SMI_CLAMP_CAM(BIT(3) | BIT(4)) +#define MT8183_SMI_COMMON_SMI_CLAMP_VPU_TOP(BIT(5) | BIT(6)) +#define MT8183_SMI_COMMON_SMI_CLAMP_VDEC BIT(7) + #define MAX_CLKS 3 #define MAX_SUBSYS_CLKS 10 @@ -1190,6 +1219,212 @@ static void mtk_register_power_domains(struct platform_device *pdev, {MT8173_POWER_DOMAIN_MFG_2D, MT8173_POWER_DOMAIN_MFG}, }; +/* + * MT8183 power domain support + */ + +static const struct scp_domain_data scp_domain_data_mt8183[] = { + [MT8183_POWER_DOMAIN_AUDIO] = { + .name = "audio", + .sta_mask = PWR_STATUS_AUDIO, + .ctl_offs = 0x0314, + .sram_pdn_bits = GENMASK(11, 8), + .sram_pdn_ack_bits = GENMASK(15, 12), + .basic_clk_name = {"audio", "audio1", "audio2"}, + }, + [MT8183_POWER_DOMAIN_CONN] = { + .name = "conn", + .sta_mask = PWR_STATUS_CONN, + .ctl_offs = 0x032c, + .sram_pdn_bits = 0, + .sram_pdn_ack_bits = 0, + .bp_table = { + BUS_PROT(IFR_TYPE, 0x2a0, 0x2a4, 0, 0x228, + MT8183_TOP_AXI_PROT_EN_CONN), + }, + }, + [MT8183_POWER_DOMAIN_MFG_ASYNC] = { + .name = "mfg_async", + .sta_mask = PWR_STATUS_MFG_ASYNC, + .ctl_offs = 0x0334, + .sram_pdn_bits = 0, + .sram_pdn_ack_bits = 0, + .basic_clk_name = {"mfg"}, + }, + [MT8183_POWER_DOMAIN_MFG] = { + .name = "mfg", + .sta_mask = PWR_STATUS_MFG, + .ctl_offs = 0x0338, + .sram_pdn_bits = GENMASK(8, 8), + .sram_pdn_ack_bits = GENMASK(12, 12), + }, + [MT8183_POWER_DOMAIN_MFG_CORE0] = { + .name = "mfg_core0", + .sta_mask = BIT(7), + .ctl_offs = 0x034c, + .sram_pdn_bits = GENMASK(8, 8), + .sram_pdn_ack_bits = GENMASK(12, 12), + }, + [MT8183_POWER_DOMAIN_MFG_CORE1] = { + .name = "mfg_core1", + .sta_mask = BIT(20), + .ctl_offs = 0x0310, + .sram_pdn_bits = GENMASK(8, 8), + .sram_pdn_ack_bits = GENMASK(12, 12), + }, + [MT8183_POWER_DOMAIN_MFG_2D] = { + .name = "mfg_2d", + .sta_mask = PWR_STATUS_MFG_2D, + .ctl_offs = 0x0348, + .sram_pdn_bits = GENMASK(8, 8), + .sram_pdn_ack_bits = GEN
[PATCH v14 00/11] Mediatek MT8183 scpsys support
This series is based on v5.7-rc1 changes since v13: - document optional property "smi-comm" - move defines in scpsyc.h to mtk-scpsys.c directly - minor coding sytle fixes change since v12: - separate the fix of comma at the end into a new patch [PATCH 09/11] changes since v11: - re-order patches "Remove infracfg misc driver support" and "Add multiple step bus protection" - add cap MTK_SCPD_SRAM_ISO for extra sram control - minor coding sytle fixes and reword commit messages changes since v10: - squash PATCH 04 and PATCH 06 in v9 into its previous patch - add "ignore_clr_ack" for multiple step bus protection control to have a clean definition of power domain data - keep the mask register bit definitions and do the same for MT8183 changes since v9: - add new PATCH 04 and PATCH 06 to replace by new method for all compatibles - add new PATCH 07 to remove infracfg misc driver - minor coding sytle fix changes since v7: - reword in binding document [PATCH 02/14] - fix error return checking bug in subsys clock control [PATCH 10/14] - add power domains properity to mfgcfg patch [PATCH 14/14] from https://patchwork.kernel.org/patch/11126199/ changes since v6: - remove the patch of SPDX license identifier because it's already fixed changes since v5: - fix documentation in [PATCH 04/14] - remove useless variable checking and reuse API of clock control in [PATCH 06/14] - coding style fix of bus protection control in [PATCH 08/14] - fix naming of new added data in [PATCH 09/14] - small refactor of multiple step bus protection control in [PATCH 10/14] changes since v4: - add property to mt8183 smi-common - seperate refactor patches and new add function - add power controller device node Weiyi Lu (11): dt-bindings: mediatek: Add property to mt8183 smi-common dt-bindings: soc: Add MT8183 power dt-bindings soc: mediatek: Add basic_clk_name to scp_power_data soc: mediatek: Remove infracfg misc driver support soc: mediatek: Add multiple step bus protection control soc: mediatek: Add subsys clock control for bus protection soc: mediatek: Add extra sram control soc: mediatek: Add MT8183 scpsys support soc: mediatek: Add a comma at the end arm64: dts: Add power controller device node of MT8183 arm64: dts: Add power-domains property to mfgcfg .../mediatek,smi-common.txt | 2 +- .../bindings/soc/mediatek/scpsys.txt | 21 +- arch/arm64/boot/dts/mediatek/mt8183.dtsi | 63 ++ drivers/soc/mediatek/Kconfig | 10 - drivers/soc/mediatek/Makefile | 1 - drivers/soc/mediatek/mtk-infracfg.c | 79 -- drivers/soc/mediatek/mtk-scpsys.c | 706 ++ include/dt-bindings/power/mt8183-power.h | 26 + include/linux/soc/mediatek/infracfg.h | 39 - 9 files changed, 672 insertions(+), 275 deletions(-) delete mode 100644 drivers/soc/mediatek/mtk-infracfg.c create mode 100644 include/dt-bindings/power/mt8183-power.h delete mode 100644 include/linux/soc/mediatek/infracfg.h
[PATCH v14 11/11] arm64: dts: Add power-domains property to mfgcfg
mfgcfg clock is under MFG_ASYNC power domain Signed-off-by: Weiyi Lu --- arch/arm64/boot/dts/mediatek/mt8183.dtsi | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm64/boot/dts/mediatek/mt8183.dtsi b/arch/arm64/boot/dts/mediatek/mt8183.dtsi index 5dce7d6..ca865ab 100644 --- a/arch/arm64/boot/dts/mediatek/mt8183.dtsi +++ b/arch/arm64/boot/dts/mediatek/mt8183.dtsi @@ -707,6 +707,7 @@ compatible = "mediatek,mt8183-mfgcfg", "syscon"; reg = <0 0x1300 0 0x1000>; #clock-cells = <1>; + power-domains = <&scpsys MT8183_POWER_DOMAIN_MFG_ASYNC>; }; mmsys: syscon@1400 { -- 1.8.1.1.dirty
[PATCH v14 05/11] soc: mediatek: Add multiple step bus protection control
Both MT8183 & MT6765 have more control steps of bus protection than previous project. And there add more bus protection registers reside at infracfg & smi-common. Extend function to support multiple step bus protection control with more customized arguments. And then use bp_table for bus protection of all compatibles, instead of mixing bus_prot_mask and bus_prot_reg_update. Signed-off-by: Weiyi Lu --- drivers/soc/mediatek/mtk-scpsys.c | 235 +++--- 1 file changed, 168 insertions(+), 67 deletions(-) diff --git a/drivers/soc/mediatek/mtk-scpsys.c b/drivers/soc/mediatek/mtk-scpsys.c index b603af7..5ce4be5 100644 --- a/drivers/soc/mediatek/mtk-scpsys.c +++ b/drivers/soc/mediatek/mtk-scpsys.c @@ -78,11 +78,6 @@ #define PWR_STATUS_HIF1BIT(26) /* MT7622 */ #define PWR_STATUS_WB BIT(27) /* MT7622 */ -#define INFRA_TOPAXI_PROTECTEN 0x0220 -#define INFRA_TOPAXI_PROTECTSTA1 0x0228 -#define INFRA_TOPAXI_PROTECTEN_SET 0x0260 -#define INFRA_TOPAXI_PROTECTEN_CLR 0x0264 - #define MT2701_TOP_AXI_PROT_EN_MM_M0 BIT(1) #define MT2701_TOP_AXI_PROT_EN_CONN_M BIT(2) #define MT2701_TOP_AXI_PROT_EN_CONN_S BIT(8) @@ -103,6 +98,45 @@ #define MAX_CLKS 3 +#define MAX_STEPS 4 + +#define _BUS_PROT(_type, _set_ofs, _clr_ofs, \ + _en_ofs, _sta_ofs, _mask, _ignore_clr_ack) {\ + .type = _type, \ + .set_ofs = _set_ofs,\ + .clr_ofs = _clr_ofs,\ + .en_ofs = _en_ofs, \ + .sta_ofs = _sta_ofs,\ + .mask = _mask, \ + .ignore_clr_ack = _ignore_clr_ack, \ + } + +#define BUS_PROT(_type, _set_ofs, _clr_ofs,\ + _en_ofs, _sta_ofs, _mask) \ + _BUS_PROT(_type, _set_ofs, _clr_ofs,\ + _en_ofs, _sta_ofs, _mask, false) + +#define BUS_PROT_IGN(_type, _set_ofs, _clr_ofs,\ + _en_ofs, _sta_ofs, _mask) \ + _BUS_PROT(_type, _set_ofs, _clr_ofs,\ + _en_ofs, _sta_ofs, _mask, true) + +enum regmap_type { + INVALID_TYPE = 0, + IFR_TYPE, + SMI_TYPE, +}; + +struct bus_prot { + enum regmap_type type; + u32 set_ofs; + u32 clr_ofs; + u32 en_ofs; + u32 sta_ofs; + u32 mask; + bool ignore_clr_ack; +}; + /** * struct scp_domain_data - scp domain data for power on/off flow * @name: The domain name. @@ -110,9 +144,9 @@ * @ctl_offs: The offset for main power control register. * @sram_pdn_bits: The mask for sram power control bits. * @sram_pdn_ack_bits: The mask for sram power control acked bits. - * @bus_prot_mask: The mask for single step bus protection. * @basic_clk_name: The basic clocks required by this power domain. * @caps: The flag for active wake-up action. + * @bp_table: The mask table for multiple step bus protection. */ struct scp_domain_data { const char *name; @@ -120,9 +154,9 @@ struct scp_domain_data { int ctl_offs; u32 sram_pdn_bits; u32 sram_pdn_ack_bits; - u32 bus_prot_mask; const char *basic_clk_name[MAX_CLKS]; u8 caps; + struct bus_prot bp_table[MAX_STEPS]; }; struct scp; @@ -146,8 +180,8 @@ struct scp { struct device *dev; void __iomem *base; struct regmap *infracfg; + struct regmap *smi_common; struct scp_ctrl_reg ctrl_reg; - bool bus_prot_reg_update; }; struct scp_subdomain { @@ -161,7 +195,6 @@ struct scp_soc_data { const struct scp_subdomain *subdomains; int num_subdomains; const struct scp_ctrl_reg regs; - bool bus_prot_reg_update; }; static int scpsys_domain_is_on(struct scp_domain *scpd) @@ -271,53 +304,87 @@ static int scpsys_sram_disable(struct scp_domain *scpd, void __iomem *ctl_addr) MTK_POLL_DELAY_US, MTK_POLL_TIMEOUT); } +static int set_bus_protection(struct regmap *map, const struct bus_prot *bp) +{ + u32 val; + + if (bp->set_ofs) + regmap_write(map, bp->set_ofs, bp->mask); + else + regmap_update_bits(map, bp->en_ofs, bp->mask, bp->mask); + + return regmap_read_poll_timeout(map, bp->sta_ofs, + val, (val & bp->mask) == bp->mask, + MTK_POLL_DELAY_US, MTK_POLL_TIMEOUT); +} + +static int clear_bus_protection(struct regmap *map, const struct bus_prot *bp) +{ + u32 val; + + if (bp->clr_ofs) + regmap_write(map, bp->clr_ofs, bp->mask); + else + regmap_update_bits(map, bp->en_ofs, bp->mask, 0); + + if (bp->ignore_clr_ack) + return 0; + +
[PATCH v14 06/11] soc: mediatek: Add subsys clock control for bus protection
For the bus protection operations, some subsys clocks need to be enabled before releasing the protection, and vice versa. But those subsys clocks could only be controlled once its corresponding power domain is turned on first. In this patch, we add the subsys clock control into its relevant steps. Signed-off-by: Weiyi Lu --- drivers/soc/mediatek/mtk-scpsys.c | 62 +-- 1 file changed, 60 insertions(+), 2 deletions(-) diff --git a/drivers/soc/mediatek/mtk-scpsys.c b/drivers/soc/mediatek/mtk-scpsys.c index 5ce4be5..f76beca 100644 --- a/drivers/soc/mediatek/mtk-scpsys.c +++ b/drivers/soc/mediatek/mtk-scpsys.c @@ -97,6 +97,7 @@ #define MT8173_TOP_AXI_PROT_EN_MFG_SNOOP_OUT BIT(23) #define MAX_CLKS 3 +#define MAX_SUBSYS_CLKS 10 #define MAX_STEPS 4 @@ -145,6 +146,8 @@ struct bus_prot { * @sram_pdn_bits: The mask for sram power control bits. * @sram_pdn_ack_bits: The mask for sram power control acked bits. * @basic_clk_name: The basic clocks required by this power domain. + * @subsys_clk_prefix: The prefix name of the clocks need to be enabled + * before releasing bus protection. * @caps: The flag for active wake-up action. * @bp_table: The mask table for multiple step bus protection. */ @@ -155,6 +158,7 @@ struct scp_domain_data { u32 sram_pdn_bits; u32 sram_pdn_ack_bits; const char *basic_clk_name[MAX_CLKS]; + const char *subsys_clk_prefix; u8 caps; struct bus_prot bp_table[MAX_STEPS]; }; @@ -165,6 +169,7 @@ struct scp_domain { struct generic_pm_domain genpd; struct scp *scp; struct clk *clk[MAX_CLKS]; + struct clk *subsys_clk[MAX_SUBSYS_CLKS]; const struct scp_domain_data *data; struct regulator *supply; }; @@ -425,16 +430,22 @@ static int scpsys_power_on(struct generic_pm_domain *genpd) val |= PWR_RST_B_BIT; writel(val, ctl_addr); - ret = scpsys_sram_enable(scpd, ctl_addr); + ret = scpsys_clk_enable(scpd->subsys_clk, MAX_SUBSYS_CLKS); if (ret < 0) goto err_pwr_ack; + ret = scpsys_sram_enable(scpd, ctl_addr); + if (ret < 0) + goto err_sram; + ret = scpsys_bus_protect_disable(scpd); if (ret < 0) - goto err_pwr_ack; + goto err_sram; return 0; +err_sram: + scpsys_clk_disable(scpd->subsys_clk, MAX_SUBSYS_CLKS); err_pwr_ack: scpsys_clk_disable(scpd->clk, MAX_CLKS); err_clk: @@ -461,6 +472,8 @@ static int scpsys_power_off(struct generic_pm_domain *genpd) if (ret < 0) goto out; + scpsys_clk_disable(scpd->subsys_clk, MAX_SUBSYS_CLKS); + /* subsys power off */ val = readl(ctl_addr); val |= PWR_ISO_BIT; @@ -498,6 +511,39 @@ static int scpsys_power_off(struct generic_pm_domain *genpd) return ret; } +static int init_subsys_clks(struct platform_device *pdev, + const char *prefix, struct clk **clk) +{ + struct device_node *node = pdev->dev.of_node; + u32 prefix_len, sub_clk_cnt = 0; + struct property *prop; + const char *clk_name; + + prefix_len = strlen(prefix); + + of_property_for_each_string(node, "clock-names", prop, clk_name) { + if (!strncmp(clk_name, prefix, prefix_len) && + (clk_name[prefix_len] == '-')) { + if (sub_clk_cnt >= MAX_SUBSYS_CLKS) { + dev_err(&pdev->dev, + "subsys clk out of range %d\n", + sub_clk_cnt); + return -EINVAL; + } + + clk[sub_clk_cnt] = devm_clk_get(&pdev->dev, + clk_name); + + if (IS_ERR(clk[sub_clk_cnt])) + return PTR_ERR(clk[sub_clk_cnt]); + + sub_clk_cnt++; + } + } + + return sub_clk_cnt; +} + static int init_basic_clks(struct platform_device *pdev, struct clk **clk, const char * const *name) { @@ -596,6 +642,18 @@ static struct scp *init_scp(struct platform_device *pdev, if (ret) return ERR_PTR(ret); + if (data->subsys_clk_prefix) { + ret = init_subsys_clks(pdev, + data->subsys_clk_prefix, + scpd->subsys_clk); + if (ret < 0) { + dev_err(&pdev->dev, + "%s: subsys clk unavailable\n", + data->name); + return ERR_PTR(ret); + } + } + genpd->name = data->name;
[PATCH v14 01/11] dt-bindings: mediatek: Add property to mt8183 smi-common
For scpsys driver using regmap based syscon driver API. Signed-off-by: Weiyi Lu --- .../devicetree/bindings/memory-controllers/mediatek,smi-common.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-common.txt b/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-common.txt index b478ade..01744ec 100644 --- a/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-common.txt +++ b/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-common.txt @@ -20,7 +20,7 @@ Required properties: "mediatek,mt2712-smi-common" "mediatek,mt7623-smi-common", "mediatek,mt2701-smi-common" "mediatek,mt8173-smi-common" - "mediatek,mt8183-smi-common" + "mediatek,mt8183-smi-common", "syscon" - reg : the register and size of the SMI block. - power-domains : a phandle to the power domain of this local arbiter. - clocks : Must contain an entry for each entry in clock-names. -- 1.8.1.1.dirty
[PATCH v14 03/11] soc: mediatek: Add basic_clk_name to scp_power_data
Try to stop extending the clk_id or clk_names if there are more and more new BASIC clocks. To get its own clocks by the basic_clk_name of each power domain. And then use basic_clk_name strings for all compatibles, instead of mixing clk_id and clk_name. Signed-off-by: Weiyi Lu Reviewed-by: Nicolas Boichat --- drivers/soc/mediatek/mtk-scpsys.c | 134 -- 1 file changed, 41 insertions(+), 93 deletions(-) diff --git a/drivers/soc/mediatek/mtk-scpsys.c b/drivers/soc/mediatek/mtk-scpsys.c index f669d37..c9c3cf7 100644 --- a/drivers/soc/mediatek/mtk-scpsys.c +++ b/drivers/soc/mediatek/mtk-scpsys.c @@ -78,34 +78,6 @@ #define PWR_STATUS_HIF1BIT(26) /* MT7622 */ #define PWR_STATUS_WB BIT(27) /* MT7622 */ -enum clk_id { - CLK_NONE, - CLK_MM, - CLK_MFG, - CLK_VENC, - CLK_VENC_LT, - CLK_ETHIF, - CLK_VDEC, - CLK_HIFSEL, - CLK_JPGDEC, - CLK_AUDIO, - CLK_MAX, -}; - -static const char * const clk_names[] = { - NULL, - "mm", - "mfg", - "venc", - "venc_lt", - "ethif", - "vdec", - "hif_sel", - "jpgdec", - "audio", - NULL, -}; - #define MAX_CLKS 3 /** @@ -116,7 +88,7 @@ enum clk_id { * @sram_pdn_bits: The mask for sram power control bits. * @sram_pdn_ack_bits: The mask for sram power control acked bits. * @bus_prot_mask: The mask for single step bus protection. - * @clk_id: The basic clocks required by this power domain. + * @basic_clk_name: The basic clocks required by this power domain. * @caps: The flag for active wake-up action. */ struct scp_domain_data { @@ -126,7 +98,7 @@ struct scp_domain_data { u32 sram_pdn_bits; u32 sram_pdn_ack_bits; u32 bus_prot_mask; - enum clk_id clk_id[MAX_CLKS]; + const char *basic_clk_name[MAX_CLKS]; u8 caps; }; @@ -411,12 +383,19 @@ static int scpsys_power_off(struct generic_pm_domain *genpd) return ret; } -static void init_clks(struct platform_device *pdev, struct clk **clk) +static int init_basic_clks(struct platform_device *pdev, struct clk **clk, + const char * const *name) { int i; - for (i = CLK_NONE + 1; i < CLK_MAX; i++) - clk[i] = devm_clk_get(&pdev->dev, clk_names[i]); + for (i = 0; i < MAX_CLKS && name[i]; i++) { + clk[i] = devm_clk_get(&pdev->dev, name[i]); + + if (IS_ERR(clk[i])) + return PTR_ERR(clk[i]); + } + + return 0; } static struct scp *init_scp(struct platform_device *pdev, @@ -426,9 +405,8 @@ static struct scp *init_scp(struct platform_device *pdev, { struct genpd_onecell_data *pd_data; struct resource *res; - int i, j; + int i, ret; struct scp *scp; - struct clk *clk[CLK_MAX]; scp = devm_kzalloc(&pdev->dev, sizeof(*scp), GFP_KERNEL); if (!scp) @@ -481,8 +459,6 @@ static struct scp *init_scp(struct platform_device *pdev, pd_data->num_domains = num; - init_clks(pdev, clk); - for (i = 0; i < num; i++) { struct scp_domain *scpd = &scp->domains[i]; struct generic_pm_domain *genpd = &scpd->genpd; @@ -493,17 +469,9 @@ static struct scp *init_scp(struct platform_device *pdev, scpd->data = data; - for (j = 0; j < MAX_CLKS && data->clk_id[j]; j++) { - struct clk *c = clk[data->clk_id[j]]; - - if (IS_ERR(c)) { - dev_err(&pdev->dev, "%s: clk unavailable\n", - data->name); - return ERR_CAST(c); - } - - scpd->clk[j] = c; - } + ret = init_basic_clks(pdev, scpd->clk, data->basic_clk_name); + if (ret) + return ERR_PTR(ret); genpd->name = data->name; genpd->power_off = scpsys_power_off; @@ -560,7 +528,6 @@ static void mtk_register_power_domains(struct platform_device *pdev, .ctl_offs = SPM_CONN_PWR_CON, .bus_prot_mask = MT2701_TOP_AXI_PROT_EN_CONN_M | MT2701_TOP_AXI_PROT_EN_CONN_S, - .clk_id = {CLK_NONE}, .caps = MTK_SCPD_ACTIVE_WAKEUP, }, [MT2701_POWER_DOMAIN_DISP] = { @@ -568,7 +535,7 @@ static void mtk_register_power_domains(struct platform_device *pdev, .sta_mask = PWR_STATUS_DISP, .ctl_offs = SPM_DIS_PWR_CON, .sram_pdn_bits = GENMASK(11, 8), - .clk_id = {CLK_MM}, + .basic_clk_name = {"mm"}, .bus_prot_mask = MT2701_TOP_AXI_PROT_EN_MM_M0, .caps = MTK_SCPD_ACTIVE_WAKEUP, }, @@ -578,7 +545,7 @@ static void mtk_register
Re: [patch V4 part 2 18/18] x86/kvm/svm: Move guest enter/exit into .noinstr.text
On 05/05/20 15:41, Thomas Gleixner wrote: > Move the functions which are inside the RCU off region into the > non-instrumentable text section. > > Signed-off-by: Thomas Gleixner > Cc: Paolo Bonzini > Cc: Sean Christopherson > --- > arch/x86/kvm/svm/svm.c | 102 > - > arch/x86/kvm/svm/vmenter.S |2 > 2 files changed, 57 insertions(+), 47 deletions(-) > > --- a/arch/x86/kvm/svm/svm.c > +++ b/arch/x86/kvm/svm/svm.c > @@ -3278,6 +3278,61 @@ static void svm_cancel_injection(struct > > void __svm_vcpu_run(unsigned long vmcb_pa, unsigned long *regs); > > +static noinstr void svm_vcpu_enter_exit(struct kvm_vcpu *vcpu, > + struct vcpu_svm *svm) > +{ > + /* > + * VMENTER enables interrupts (host state), but the kernel state is > + * interrupts disabled when this is invoked. Also tell RCU about > + * it. This is the same logic as for exit_to_user_mode(). > + * > + * 1) Trace interrupts on state > + * 2) Prepare lockdep with RCU on > + * 3) Invoke context tracking if enabled to adjust RCU state > + * 4) Tell lockdep that interrupts are enabled > + * > + * This has to be after x86_spec_ctrl_set_guest() because that can > + * take locks (lockdep needs RCU) and calls into world and some > + * more. > + */ > + instr_begin(); > + trace_hardirqs_on_prepare(); > + lockdep_hardirqs_on_prepare(CALLER_ADDR0); > + instr_end(); > + guest_enter_irqoff(); > + lockdep_hardirqs_on(CALLER_ADDR0); > + > + __svm_vcpu_run(svm->vmcb_pa, (unsigned long *)&svm->vcpu.arch.regs); > + > +#ifdef CONFIG_X86_64 > + native_wrmsrl(MSR_GS_BASE, svm->host.gs_base); > +#else > + loadsegment(fs, svm->host.fs); > +#ifndef CONFIG_X86_32_LAZY_GS > + loadsegment(gs, svm->host.gs); > +#endif > +#endif > + > + /* > + * VMEXIT disables interrupts (host state, see the CLI in the ASM > + * above), but tracing and lockdep have them in state 'on'. Same as > + * enter_from_user_mode(). > + * > + * 1) Tell lockdep that interrupts are disabled > + * 2) Invoke context tracking if enabled to reactivate RCU > + * 3) Trace interrupts off state > + * > + * This needs to be done before the below as native_read_msr() > + * contains a tracepoint and x86_spec_ctrl_restore_host() calls > + * into world and some more. > + */ > + lockdep_hardirqs_off(CALLER_ADDR0); > + guest_exit_irqoff(); > + instr_begin(); > + trace_hardirqs_off_prepare(); > + instr_end(); > +} > + > static void svm_vcpu_run(struct kvm_vcpu *vcpu) > { > struct vcpu_svm *svm = to_svm(vcpu); > @@ -3330,52 +3385,7 @@ static void svm_vcpu_run(struct kvm_vcpu >*/ > x86_spec_ctrl_set_guest(svm->spec_ctrl, svm->virt_spec_ctrl); > > - /* > - * VMENTER enables interrupts (host state), but the kernel state is > - * interrupts disabled when this is invoked. Also tell RCU about > - * it. This is the same logic as for exit_to_user_mode(). > - * > - * 1) Trace interrupts on state > - * 2) Prepare lockdep with RCU on > - * 3) Invoke context tracking if enabled to adjust RCU state > - * 4) Tell lockdep that interrupts are enabled > - * > - * This has to be after x86_spec_ctrl_set_guest() because that can > - * take locks (lockdep needs RCU) and calls into world and some > - * more. > - */ > - trace_hardirqs_on_prepare(); > - lockdep_hardirqs_on_prepare(CALLER_ADDR0); > - guest_enter_irqoff(); > - lockdep_hardirqs_on(CALLER_ADDR0); > - > - __svm_vcpu_run(svm->vmcb_pa, (unsigned long *)&svm->vcpu.arch.regs); > - > -#ifdef CONFIG_X86_64 > - wrmsrl(MSR_GS_BASE, svm->host.gs_base); > -#else > - loadsegment(fs, svm->host.fs); > -#ifndef CONFIG_X86_32_LAZY_GS > - loadsegment(gs, svm->host.gs); > -#endif > -#endif > - > - /* > - * VMEXIT disables interrupts (host state, see the CLI in the ASM > - * above), but tracing and lockdep have them in state 'on'. Same as > - * enter_from_user_mode(). > - * > - * 1) Tell lockdep that interrupts are disabled > - * 2) Invoke context tracking if enabled to reactivate RCU > - * 3) Trace interrupts off state > - * > - * This needs to be done before the below as native_read_msr() > - * contains a tracepoint and x86_spec_ctrl_restore_host() calls > - * into world and some more. > - */ > - lockdep_hardirqs_off(CALLER_ADDR0); > - guest_exit_irqoff(); > - trace_hardirqs_off_prepare(); > + svm_vcpu_enter_exit(vcpu, svm); > > /* >* We do not use IBRS in the kernel. If this vCPU has used the > --- a/arch/x86/kvm/svm/vmenter.S > +++ b/arch/x86/kvm/svm/vmenter.S > @@ -27,7 +27,7 @@ > #define VCPU_R15 __VCPU_REGS_R15 * WORD_SIZE > #endif > > - .text > +.section .noinstr.text, "ax" > > /*