Linux Serial subsystem development
 help / color / mirror / Atom feed
* Re: [PATCH v3 09/33] nds32: Cache and TLB routines
From: Greentime Hu @ 2017-12-13  5:45 UTC (permalink / raw)
  To: Guo Ren
  Cc: Greentime, Linux Kernel Mailing List, Arnd Bergmann, linux-arch,
	Thomas Gleixner, Jason Cooper, Marc Zyngier, Rob Herring, netdev,
	Vincent Chen, DTML, Al Viro, David Howells, Will Deacon,
	Daniel Lezcano, linux-serial, Geert Uytterhoeven, Linus Walleij,
	Mark Rutland, Greg KH
In-Reply-To: <20171213021619.GA6254@gary-OptiPlex-3050>

2017-12-13 10:16 GMT+08:00 Guo Ren <ren_guo@c-sky.com>:
> On Fri, Dec 08, 2017 at 05:11:52PM +0800, Greentime Hu wrote:
>> From: Greentime Hu <greentime@andestech.com>
>  [...]
>> diff --git a/arch/nds32/mm/cacheflush.c b/arch/nds32/mm/cacheflush.c
>  [...]
>> +#ifndef CONFIG_CPU_CACHE_ALIASING
>> +void update_mmu_cache(struct vm_area_struct *vma, unsigned long addr,
>> +                   pte_t * pte)
>  [...]
>> +     if (vma->vm_mm == current->active_mm) {
>> +
>> +             __nds32__mtsr_dsb(addr, NDS32_SR_TLB_VPN);
>> +             __nds32__tlbop_rwr(*pte);
>> +             __nds32__isb();
> If there is an interruption between "mtsr_dsb" and "tlbop_rwr" and a
> update_mmu_cache() is invoked again, then an error page mapping is
> set up in your tlb-buffer when tlbop_rwr is excuted from interrupt.
> Because it's another addr in NDS32_SR_TLB_VPN.
>
> It seems that tlb-hardrefill can help build tlb-buffer mapping, why you
> update it in this software way?
>

Hi, Guo Ren:

I think it should be fine if an interruption between mtsr_dsb and
tlbop_rwr because this is a optimization by sw.
The page mapping has been created and it is just not in TLB yet.
What we did is to insert this mapping to TLB by SW thus it can prevent
TLB miss one time.
It will be fine even if TLB miss. HW will walk through page table and
insert this mapping to TLB anyway.

Based on Documentation/cachetlb.txt
5) ``void update_mmu_cache(struct vm_area_struct *vma,
   unsigned long address, pte_t *ptep)``

        At the end of every page fault, this routine is invoked to
        tell the architecture specific code that a translation
        now exists at virtual address "address" for address space
        "vma->vm_mm", in the software page tables.

        A port may use this information in any way it so chooses.
        For example, it could use this event to pre-load TLB
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        translations for software managed TLB configurations.
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

^ permalink raw reply

* Re: [PATCH v3 09/33] nds32: Cache and TLB routines
From: Guo Ren @ 2017-12-13  2:16 UTC (permalink / raw)
  To: Greentime Hu
  Cc: greentime, linux-kernel, arnd, linux-arch, tglx, jason,
	marc.zyngier, robh+dt, netdev, deanbo422, devicetree, viro,
	dhowells, will.deacon, daniel.lezcano, linux-serial,
	geert.uytterhoeven, linus.walleij, mark.rutland, greg,
	Vincent Chen
In-Reply-To: <9d0e976c3e60bf6834dffb6ef798ad2a03e1c9ac.1512723245.git.green.hu@gmail.com>

On Fri, Dec 08, 2017 at 05:11:52PM +0800, Greentime Hu wrote:
> From: Greentime Hu <greentime@andestech.com>
 [...]
> diff --git a/arch/nds32/mm/cacheflush.c b/arch/nds32/mm/cacheflush.c
 [...]
> +#ifndef CONFIG_CPU_CACHE_ALIASING
> +void update_mmu_cache(struct vm_area_struct *vma, unsigned long addr,
> +		      pte_t * pte)
 [...]
> +	if (vma->vm_mm == current->active_mm) {
> +
> +		__nds32__mtsr_dsb(addr, NDS32_SR_TLB_VPN);
> +		__nds32__tlbop_rwr(*pte);
> +		__nds32__isb();
If there is an interruption between "mtsr_dsb" and "tlbop_rwr" and a
update_mmu_cache() is invoked again, then an error page mapping is
set up in your tlb-buffer when tlbop_rwr is excuted from interrupt.
Because it's another addr in NDS32_SR_TLB_VPN.

It seems that tlb-hardrefill can help build tlb-buffer mapping, why you
update it in this software way?

 Guo Ren

^ permalink raw reply

* Re: [PATCH v2 1/2] acpi, spcr: Make SPCR avialable to other architectures
From: Rafael J. Wysocki @ 2017-12-13  0:22 UTC (permalink / raw)
  To: Prarit Bhargava
  Cc: linux-acpi, linux-doc, linux-kernel, linux-arm-kernel, linux-pm,
	linux-serial, Bhupesh Sharma, Lv Zheng, Thomas Gleixner,
	Ingo Molnar, H. Peter Anvin, x86, Jonathan Corbet,
	Catalin Marinas, Will Deacon, Timur Tabi
In-Reply-To: <20171211155059.17062-2-prarit@redhat.com>

On Monday, December 11, 2017 4:50:58 PM CET Prarit Bhargava wrote:
> Other architectures can use SPCR to setup an early console or console
> but the current code is ARM64 specific.
> 
> Change the name of parse_spcr() to acpi_parse_spcr().  Add a weak
> function acpi_arch_setup_console() that can be used for arch-specific
> setup.  Move flags into ACPI code.  Update the Documention on the use of
> the SPCR.
> 
> [v2]: Don't return an error in the baud_rate check of acpi_parse_spcr().
> Keep ACPI_SPCR_TABLE selected for ARM64.  Fix 8-bit port access width
> mmio value.  Move baud rate check earlier.
> 
> Signed-off-by: Prarit Bhargava <prarit@redhat.com>

This mostly affects ARM64, so ACKs from that side are requisite for it.

> Cc: linux-doc@vger.kernel.org
> Cc: linux-kernel@vger.kernel.org
> Cc: linux-arm-kernel@lists.infradead.org
> Cc: linux-pm@vger.kernel.org
> Cc: linux-acpi@vger.kernel.org
> Cc: linux-serial@vger.kernel.org
> Cc: Bhupesh Sharma <bhsharma@redhat.com>
> Cc: Lv Zheng <lv.zheng@intel.com>
> Cc: Thomas Gleixner <tglx@linutronix.de>
> Cc: Ingo Molnar <mingo@redhat.com>
> Cc: "H. Peter Anvin" <hpa@zytor.com>
> Cc: x86@kernel.org
> Cc: Jonathan Corbet <corbet@lwn.net>
> Cc: Catalin Marinas <catalin.marinas@arm.com>
> Cc: Will Deacon <will.deacon@arm.com>
> Cc: "Rafael J. Wysocki" <rjw@rjwysocki.net>
> Cc: Timur Tabi <timur@codeaurora.org>
> ---
>  Documentation/admin-guide/kernel-parameters.txt |   6 +-
>  arch/arm64/kernel/acpi.c                        | 128 ++++++++++++++++-
>  drivers/acpi/Kconfig                            |   7 +-
>  drivers/acpi/spcr.c                             | 175 ++++++------------------
>  drivers/tty/serial/earlycon.c                   |  15 +-
>  include/linux/acpi.h                            |  11 +-
>  include/linux/serial_core.h                     |   2 -
>  7 files changed, 184 insertions(+), 160 deletions(-)
> 
> diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
> index 6571fbfdb2a1..0d173289c67e 100644
> --- a/Documentation/admin-guide/kernel-parameters.txt
> +++ b/Documentation/admin-guide/kernel-parameters.txt
> @@ -914,9 +914,9 @@
>  
>  	earlycon=	[KNL] Output early console device and options.
>  
> -			When used with no options, the early console is
> -			determined by the stdout-path property in device
> -			tree's chosen node.
> +			[ARM64] The early console is determined by the
> +			stdout-path property in device tree's chosen node,
> +			or determined by the ACPI SPCR table.
>  
>  		cdns,<addr>[,options]
>  			Start an early, polled-mode console on a Cadence
> diff --git a/arch/arm64/kernel/acpi.c b/arch/arm64/kernel/acpi.c
> index b3162715ed78..b3e33bbdf3b7 100644
> --- a/arch/arm64/kernel/acpi.c
> +++ b/arch/arm64/kernel/acpi.c
> @@ -25,7 +25,6 @@
>  #include <linux/memblock.h>
>  #include <linux/of_fdt.h>
>  #include <linux/smp.h>
> -#include <linux/serial_core.h>
>  
>  #include <asm/cputype.h>
>  #include <asm/cpu_ops.h>
> @@ -177,6 +176,128 @@ static int __init acpi_fadt_sanity_check(void)
>  	return ret;
>  }
>  
> +/*
> + * Erratum 44 for QDF2432v1 and QDF2400v1 SoCs describes the BUSY bit as
> + * occasionally getting stuck as 1. To avoid the potential for a hang, check
> + * TXFE == 0 instead of BUSY == 1. This may not be suitable for all UART
> + * implementations, so only do so if an affected platform is detected in
> + * acpi_parse_spcr().
> + */
> +bool qdf2400_e44_present;
> +EXPORT_SYMBOL(qdf2400_e44_present);
> +
> +/*
> + * Some Qualcomm Datacenter Technologies SoCs have a defective UART BUSY bit.
> + * Detect them by examining the OEM fields in the SPCR header, similar to PCI
> + * quirk detection in pci_mcfg.c.
> + */
> +static bool qdf2400_erratum_44_present(struct acpi_table_header *h)
> +{
> +	if (memcmp(h->oem_id, "QCOM  ", ACPI_OEM_ID_SIZE))
> +		return false;
> +
> +	if (!memcmp(h->oem_table_id, "QDF2432 ", ACPI_OEM_TABLE_ID_SIZE))
> +		return true;
> +
> +	if (!memcmp(h->oem_table_id, "QDF2400 ", ACPI_OEM_TABLE_ID_SIZE) &&
> +			h->oem_revision == 1)
> +		return true;
> +
> +	return false;
> +}
> +
> +/*
> + * APM X-Gene v1 and v2 UART hardware is an 16550 like device but has its
> + * register aligned to 32-bit. In addition, the BIOS also encoded the
> + * access width to be 8 bits. This function detects this errata condition.
> + */
> +static bool xgene_8250_erratum_present(struct acpi_table_spcr *tb)
> +{
> +	bool xgene_8250 = false;
> +
> +	if (tb->interface_type != ACPI_DBG2_16550_COMPATIBLE)
> +		return false;
> +
> +	if (memcmp(tb->header.oem_id, "APMC0D", ACPI_OEM_ID_SIZE) &&
> +	    memcmp(tb->header.oem_id, "HPE   ", ACPI_OEM_ID_SIZE))
> +		return false;
> +
> +	if (!memcmp(tb->header.oem_table_id, "XGENESPC",
> +	    ACPI_OEM_TABLE_ID_SIZE) && tb->header.oem_revision == 0)
> +		xgene_8250 = true;
> +
> +	if (!memcmp(tb->header.oem_table_id, "ProLiant",
> +	    ACPI_OEM_TABLE_ID_SIZE) && tb->header.oem_revision == 1)
> +		xgene_8250 = true;
> +
> +	return xgene_8250;
> +}
> +
> +int acpi_arch_setup_console(struct acpi_table_spcr *table,
> +			    char *opts, char *uart, char *iotype,
> +			    int baud_rate, bool earlycon)
> +{
> +	if (table->header.revision < 2) {
> +		pr_err("wrong table version\n");
> +		return -ENOENT;
> +	}
> +
> +	switch (table->interface_type) {
> +	case ACPI_DBG2_ARM_SBSA_32BIT:
> +		snprintf(iotype, ACPI_SPCR_BUF_SIZE, "mmio32");
> +		/* fall through */
> +	case ACPI_DBG2_ARM_PL011:
> +	case ACPI_DBG2_ARM_SBSA_GENERIC:
> +	case ACPI_DBG2_BCM2835:
> +		snprintf(uart, ACPI_SPCR_BUF_SIZE, "pl011");
> +		break;
> +	default:
> +		if (strlen(uart) == 0)
> +			return -ENOENT;
> +	}
> +
> +	/*
> +	 * If the E44 erratum is required, then we need to tell the pl011
> +	 * driver to implement the work-around.
> +	 *
> +	 * The global variable is used by the probe function when it
> +	 * creates the UARTs, whether or not they're used as a console.
> +	 *
> +	 * If the user specifies "traditional" earlycon, the qdf2400_e44
> +	 * console name matches the EARLYCON_DECLARE() statement, and
> +	 * SPCR is not used.  Parameter "earlycon" is false.
> +	 *
> +	 * If the user specifies "SPCR" earlycon, then we need to update
> +	 * the console name so that it also says "qdf2400_e44".  Parameter
> +	 * "earlycon" is true.
> +	 *
> +	 * For consistency, if we change the console name, then we do it
> +	 * for everyone, not just earlycon.
> +	 */
> +	if (qdf2400_erratum_44_present(&table->header)) {
> +		qdf2400_e44_present = true;
> +		if (earlycon)
> +			snprintf(uart, ACPI_SPCR_BUF_SIZE, "qdf2400_e44");
> +	}
> +
> +	if (xgene_8250_erratum_present(table)) {
> +		snprintf(iotype, ACPI_SPCR_BUF_SIZE, "mmio32");
> +
> +		/* for xgene v1 and v2 we don't know the clock rate of the
> +		 * UART so don't attempt to change to the baud rate state
> +		 * in the table because driver cannot calculate the dividers
> +		 */
> +		snprintf(opts, ACPI_SPCR_OPTS_SIZE, "%s,%s,0x%llx", uart,
> +			 iotype, table->serial_port.address);
> +	} else {
> +		snprintf(opts, ACPI_SPCR_OPTS_SIZE, "%s,%s,0x%llx,%d", uart,
> +			 iotype, table->serial_port.address, baud_rate);
> +	}
> +
> +	return 0;
> +}
> +EXPORT_SYMBOL(acpi_arch_setup_console);
> +
>  /*
>   * acpi_boot_table_init() called from setup_arch(), always.
>   *	1. find RSDP and get its address, and then find XSDT
> @@ -230,10 +351,11 @@ void __init acpi_boot_table_init(void)
>  
>  done:
>  	if (acpi_disabled) {
> -		if (earlycon_init_is_deferred)
> +		if (console_acpi_spcr_enable)
>  			early_init_dt_scan_chosen_stdout();
>  	} else {
> -		parse_spcr(earlycon_init_is_deferred);
> +		/* Always enable the ACPI SPCR console */
> +		acpi_parse_spcr(console_acpi_spcr_enable);
>  		if (IS_ENABLED(CONFIG_ACPI_BGRT))
>  			acpi_table_parse(ACPI_SIG_BGRT, acpi_parse_bgrt);
>  	}
> diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig
> index 46505396869e..9ae98eeada76 100644
> --- a/drivers/acpi/Kconfig
> +++ b/drivers/acpi/Kconfig
> @@ -79,7 +79,12 @@ config ACPI_DEBUGGER_USER
>  endif
>  
>  config ACPI_SPCR_TABLE
> -	bool
> +	bool "ACPI Serial Port Console Redirection Support"
> +	default y if ARM64
> +	help
> +	  Enable support for Serial Port Console Redirection (SPCR) Table.
> +	  This table provides information about the configuration of the
> +	  earlycon console.
>  
>  config ACPI_LPIT
>  	bool
> diff --git a/drivers/acpi/spcr.c b/drivers/acpi/spcr.c
> index 324b35bfe781..f4bb8110e404 100644
> --- a/drivers/acpi/spcr.c
> +++ b/drivers/acpi/spcr.c
> @@ -16,65 +16,18 @@
>  #include <linux/kernel.h>
>  #include <linux/serial_core.h>
>  
> -/*
> - * Erratum 44 for QDF2432v1 and QDF2400v1 SoCs describes the BUSY bit as
> - * occasionally getting stuck as 1. To avoid the potential for a hang, check
> - * TXFE == 0 instead of BUSY == 1. This may not be suitable for all UART
> - * implementations, so only do so if an affected platform is detected in
> - * parse_spcr().
> - */
> -bool qdf2400_e44_present;
> -EXPORT_SYMBOL(qdf2400_e44_present);
> -
> -/*
> - * Some Qualcomm Datacenter Technologies SoCs have a defective UART BUSY bit.
> - * Detect them by examining the OEM fields in the SPCR header, similiar to PCI
> - * quirk detection in pci_mcfg.c.
> - */
> -static bool qdf2400_erratum_44_present(struct acpi_table_header *h)
> -{
> -	if (memcmp(h->oem_id, "QCOM  ", ACPI_OEM_ID_SIZE))
> -		return false;
> -
> -	if (!memcmp(h->oem_table_id, "QDF2432 ", ACPI_OEM_TABLE_ID_SIZE))
> -		return true;
> -
> -	if (!memcmp(h->oem_table_id, "QDF2400 ", ACPI_OEM_TABLE_ID_SIZE) &&
> -			h->oem_revision == 1)
> -		return true;
> -
> -	return false;
> -}
> -
> -/*
> - * APM X-Gene v1 and v2 UART hardware is an 16550 like device but has its
> - * register aligned to 32-bit. In addition, the BIOS also encoded the
> - * access width to be 8 bits. This function detects this errata condition.
> - */
> -static bool xgene_8250_erratum_present(struct acpi_table_spcr *tb)
> +int __weak acpi_arch_setup_console(struct acpi_table_spcr *table,
> +				   char *opts, char *uart, char *iotype,
> +				   int baud_rate, bool earlycon)
>  {
> -	bool xgene_8250 = false;
> -
> -	if (tb->interface_type != ACPI_DBG2_16550_COMPATIBLE)
> -		return false;
> -
> -	if (memcmp(tb->header.oem_id, "APMC0D", ACPI_OEM_ID_SIZE) &&
> -	    memcmp(tb->header.oem_id, "HPE   ", ACPI_OEM_ID_SIZE))
> -		return false;
> -
> -	if (!memcmp(tb->header.oem_table_id, "XGENESPC",
> -	    ACPI_OEM_TABLE_ID_SIZE) && tb->header.oem_revision == 0)
> -		xgene_8250 = true;
> -
> -	if (!memcmp(tb->header.oem_table_id, "ProLiant",
> -	    ACPI_OEM_TABLE_ID_SIZE) && tb->header.oem_revision == 1)
> -		xgene_8250 = true;
> -
> -	return xgene_8250;
> +	snprintf(opts, ACPI_SPCR_OPTS_SIZE, "%s,%s,0x%llx,%d", uart, iotype,
> +		 table->serial_port.address, baud_rate);
> +	return 0;
>  }
>  
> +bool console_acpi_spcr_enable __initdata;
>  /**
> - * parse_spcr() - parse ACPI SPCR table and add preferred console
> + * acpi_parse_spcr() - parse ACPI SPCR table and add preferred console
>   *
>   * @earlycon: set up earlycon for the console specified by the table
>   *
> @@ -86,13 +39,13 @@ static bool xgene_8250_erratum_present(struct acpi_table_spcr *tb)
>   * from arch initialization code as soon as the DT/ACPI decision is made.
>   *
>   */
> -int __init parse_spcr(bool earlycon)
> +int __init acpi_parse_spcr(bool earlycon)
>  {
> -	static char opts[64];
> +	static char opts[ACPI_SPCR_OPTS_SIZE];
> +	static char uart[ACPI_SPCR_BUF_SIZE];
> +	static char iotype[ACPI_SPCR_BUF_SIZE];
>  	struct acpi_table_spcr *table;
>  	acpi_status status;
> -	char *uart;
> -	char *iotype;
>  	int baud_rate;
>  	int err;
>  
> @@ -105,48 +58,6 @@ int __init parse_spcr(bool earlycon)
>  	if (ACPI_FAILURE(status))
>  		return -ENOENT;
>  
> -	if (table->header.revision < 2) {
> -		err = -ENOENT;
> -		pr_err("wrong table version\n");
> -		goto done;
> -	}
> -
> -	if (table->serial_port.space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) {
> -		switch (ACPI_ACCESS_BIT_WIDTH((
> -			table->serial_port.access_width))) {
> -		default:
> -			pr_err("Unexpected SPCR Access Width.  Defaulting to byte size\n");
> -		case 8:
> -			iotype = "mmio";
> -			break;
> -		case 16:
> -			iotype = "mmio16";
> -			break;
> -		case 32:
> -			iotype = "mmio32";
> -			break;
> -		}
> -	} else
> -		iotype = "io";
> -
> -	switch (table->interface_type) {
> -	case ACPI_DBG2_ARM_SBSA_32BIT:
> -		iotype = "mmio32";
> -		/* fall through */
> -	case ACPI_DBG2_ARM_PL011:
> -	case ACPI_DBG2_ARM_SBSA_GENERIC:
> -	case ACPI_DBG2_BCM2835:
> -		uart = "pl011";
> -		break;
> -	case ACPI_DBG2_16550_COMPATIBLE:
> -	case ACPI_DBG2_16550_SUBSET:
> -		uart = "uart";
> -		break;
> -	default:
> -		err = -ENOENT;
> -		goto done;
> -	}
> -
>  	switch (table->baud_rate) {
>  	case 3:
>  		baud_rate = 9600;
> @@ -165,43 +76,36 @@ int __init parse_spcr(bool earlycon)
>  		goto done;
>  	}
>  
> -	/*
> -	 * If the E44 erratum is required, then we need to tell the pl011
> -	 * driver to implement the work-around.
> -	 *
> -	 * The global variable is used by the probe function when it
> -	 * creates the UARTs, whether or not they're used as a console.
> -	 *
> -	 * If the user specifies "traditional" earlycon, the qdf2400_e44
> -	 * console name matches the EARLYCON_DECLARE() statement, and
> -	 * SPCR is not used.  Parameter "earlycon" is false.
> -	 *
> -	 * If the user specifies "SPCR" earlycon, then we need to update
> -	 * the console name so that it also says "qdf2400_e44".  Parameter
> -	 * "earlycon" is true.
> -	 *
> -	 * For consistency, if we change the console name, then we do it
> -	 * for everyone, not just earlycon.
> -	 */
> -	if (qdf2400_erratum_44_present(&table->header)) {
> -		qdf2400_e44_present = true;
> -		if (earlycon)
> -			uart = "qdf2400_e44";
> +	switch (table->interface_type) {
> +	case ACPI_DBG2_16550_COMPATIBLE:
> +	case ACPI_DBG2_16550_SUBSET:
> +		snprintf(uart, ACPI_SPCR_BUF_SIZE, "uart");
> +		break;
> +	default:
> +		break;
>  	}
>  
> -	if (xgene_8250_erratum_present(table)) {
> -		iotype = "mmio32";
> +	if (table->serial_port.space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) {
> +		u8 width = ACPI_ACCESS_BIT_WIDTH((
> +					table->serial_port.access_width));
> +		switch (width) {
> +		default:
> +			pr_err("Unexpected SPCR Access Width.  Defaulting to byte size\n");
> +		case 8:
> +			snprintf(iotype, ACPI_SPCR_BUF_SIZE, "mmio");
> +			break;
> +		case 16:
> +		case 32:
> +			snprintf(iotype, ACPI_SPCR_BUF_SIZE, "mmio%d", width);
> +			break;
> +		}
> +	} else
> +		snprintf(iotype, ACPI_SPCR_BUF_SIZE, "io");
>  
> -		/* for xgene v1 and v2 we don't know the clock rate of the
> -		 * UART so don't attempt to change to the baud rate state
> -		 * in the table because driver cannot calculate the dividers
> -		 */
> -		snprintf(opts, sizeof(opts), "%s,%s,0x%llx", uart, iotype,
> -			 table->serial_port.address);
> -	} else {
> -		snprintf(opts, sizeof(opts), "%s,%s,0x%llx,%d", uart, iotype,
> -			 table->serial_port.address, baud_rate);
> -	}
> +	err = acpi_arch_setup_console(table, opts, uart, iotype, baud_rate,
> +				      earlycon);
> +	if (err)
> +		goto done;
>  
>  	pr_info("console: %s\n", opts);
>  
> @@ -209,7 +113,6 @@ int __init parse_spcr(bool earlycon)
>  		setup_earlycon(opts);
>  
>  	err = add_preferred_console(uart, 0, opts + strlen(uart) + 1);
> -
>  done:
>  	acpi_put_table((struct acpi_table_header *)table);
>  	return err;
> diff --git a/drivers/tty/serial/earlycon.c b/drivers/tty/serial/earlycon.c
> index 4c8b80f1c688..b22afb62c7a3 100644
> --- a/drivers/tty/serial/earlycon.c
> +++ b/drivers/tty/serial/earlycon.c
> @@ -196,26 +196,15 @@ int __init setup_earlycon(char *buf)
>  	return -ENOENT;
>  }
>  
> -/*
> - * When CONFIG_ACPI_SPCR_TABLE is defined, "earlycon" without parameters in
> - * command line does not start DT earlycon immediately, instead it defers
> - * starting it until DT/ACPI decision is made.  At that time if ACPI is enabled
> - * call parse_spcr(), else call early_init_dt_scan_chosen_stdout()
> - */
> -bool earlycon_init_is_deferred __initdata;
> -
>  /* early_param wrapper for setup_earlycon() */
>  static int __init param_setup_earlycon(char *buf)
>  {
>  	int err;
>  
> -	/*
> -	 * Just 'earlycon' is a valid param for devicetree earlycons;
> -	 * don't generate a warning from parse_early_params() in that case
> -	 */
> +	/* Just 'earlycon' is a valid param for devicetree and ACPI SPCR. */
>  	if (!buf || !buf[0]) {
>  		if (IS_ENABLED(CONFIG_ACPI_SPCR_TABLE)) {
> -			earlycon_init_is_deferred = true;
> +			console_acpi_spcr_enable = true;
>  			return 0;
>  		} else if (!buf) {
>  			return early_init_dt_scan_chosen_stdout();
> diff --git a/include/linux/acpi.h b/include/linux/acpi.h
> index dc1ebfeeb5ec..875d7327d91c 100644
> --- a/include/linux/acpi.h
> +++ b/include/linux/acpi.h
> @@ -1241,10 +1241,17 @@ static inline bool acpi_has_watchdog(void) { return false; }
>  #endif
>  
>  #ifdef CONFIG_ACPI_SPCR_TABLE
> +#define ACPI_SPCR_OPTS_SIZE 64
> +#define ACPI_SPCR_BUF_SIZE 32
>  extern bool qdf2400_e44_present;
> -int parse_spcr(bool earlycon);
> +extern bool console_acpi_spcr_enable __initdata;
> +extern int acpi_arch_setup_console(struct acpi_table_spcr *table,
> +				   char *opts, char *uart, char *iotype,
> +				   int baud_rate, bool earlycon);
> +int acpi_parse_spcr(bool earlycon);
>  #else
> -static inline int parse_spcr(bool earlycon) { return 0; }
> +static const bool console_acpi_spcr_enable;
> +static inline int acpi_parse_spcr(bool earlycon) { return 0; }
>  #endif
>  
>  #if IS_ENABLED(CONFIG_ACPI_GENERIC_GSI)
> diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h
> index 37b044e78333..abfffb4b1c37 100644
> --- a/include/linux/serial_core.h
> +++ b/include/linux/serial_core.h
> @@ -376,10 +376,8 @@ extern int of_setup_earlycon(const struct earlycon_id *match,
>  			     const char *options);
>  
>  #ifdef CONFIG_SERIAL_EARLYCON
> -extern bool earlycon_init_is_deferred __initdata;
>  int setup_earlycon(char *buf);
>  #else
> -static const bool earlycon_init_is_deferred;
>  static inline int setup_earlycon(char *buf) { return 0; }
>  #endif
>  
> 



^ permalink raw reply

* Re: [PATCH v3 30/33] dt-bindings: nds32 SoC Bindings
From: Rob Herring @ 2017-12-12 20:12 UTC (permalink / raw)
  To: Greentime Hu
  Cc: greentime, linux-kernel, arnd, linux-arch, tglx, jason,
	marc.zyngier, netdev, deanbo422, devicetree, viro, dhowells,
	will.deacon, daniel.lezcano, linux-serial, geert.uytterhoeven,
	linus.walleij, mark.rutland, greg
In-Reply-To: <4c33141ec34c73abe4a9106cbe71f2a97621958e.1512723245.git.green.hu@gmail.com>

On Fri, Dec 08, 2017 at 05:12:13PM +0800, Greentime Hu wrote:
> From: Greentime Hu <greentime@andestech.com>
> 
> This patch adds nds32 SoC(AE3XX and AG101P) binding documents.
> 
> Signed-off-by: Greentime Hu <greentime@andestech.com>
> ---
>  .../devicetree/bindings/nds32/andestech-boards     |   40 ++++++++++++++++++++
>  1 file changed, 40 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/nds32/andestech-boards

Reviewed-by: Rob Herring <robh@kernel.org>                  

^ permalink raw reply

* Re: Have my PA8800 back online... (serial port missing on v4.14)
From: Helge Deller @ 2017-12-12 20:11 UTC (permalink / raw)
  To: Andy Shevchenko, Frank Scheiner, linux-parisc, John David Anglin,
	linux-serial
  Cc: debian-hppa
In-Reply-To: <1512980798.25007.581.camel@linux.intel.com>

On 11.12.2017 09:26, Andy Shevchenko wrote:
> On Fri, 2017-12-08 at 20:06 +0100, Helge Deller wrote:
>>>> Anyway, the *only* problem we have right now is, that the Linux
>>>> kernel 4.14 doesn't detect all serial ports which were detected in
>>>> earlier kernels.
> 
>>>> Thus the kernel will talk to the non-existant serial port at
>>>> 0xfffffffff4050010 instead of 0xfffffffff4050000.
> 
> Wait, from this sentence you actually confirm that patch removes *non-
> existant* ports.
> 
> Can you elaborate what you imply here?

The PCI card is a HP "Diva" card, which is basically a server 
remote management board (like HP iLO). 

With "non-existant serial port" I was referring to those few ports
on the Diva card with which one can communicate directly via a proprietary
protocol with the management card.

In older kernels (before your patch) those ports showed up as serial
ports (although they were of no use for the Linux serial driver).
With v4.14 those ports don't show up as ttyS device any longer.  
 
>>>> 4.13:
>>>> [   28.882849] Serial: 8250/16550 driver, 4 ports, IRQ sharing
>>>> enabled
>>>> [   28.898720] 0000:e0:01.0: ttyS0 at MMIO 0xfffffffff4051000 (irq
>>>> = 73, base_baud = 115200) is a 16450
>>>> [   28.934669] 0000:e0:01.1: ttyS1 at MMIO 0xfffffffff4050000 (irq
>>>> = 73, base_baud = 115200) is a 16550A
>>>> [   28.963031] 0000:e0:01.1: ttyS2 at MMIO 0xfffffffff4050010 (irq
>>>> = 73, base_baud = 115200) is a 16550A
>>>> [   28.984946] 0000:e0:01.1: ttyS3 at MMIO 0xfffffffff4050038 (irq
>>>> = 73, base_baud = 115200) is a 16550A
> 
> From here it looks like multi-function PCI device with two functions
> with 1 + 3 serial ports each.
> 
>>>> ...but for v4.14.x only the following serial ports are detected:
>>>> [   28.671984] Serial: 8250/16550 driver, 4 ports, IRQ sharing
>>>> enabled
>>>> [   28.708902] 0000:e0:01.1: ttyS0 at MMIO 0xfffffffff4050000 (irq
>>>> = 73, base_baud = 115200) is a 16550A
>>>> [   28.731145] 0000:e0:01.1: ttyS1 at MMIO 0xfffffffff4050010 (irq
>>>> = 73, base_baud = 115200) is a 16550A
> 
> I'm quite curious how ttyS0 and ttyS3 in previous run (old kernel)
> appear.
> 
>>>>
>>>>
>>>> Maybe reverting this commit brings back the old behavior:
>>>> https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
>>>> /commit/?id=7d8905d064058f4b65057e0101588f362f288bc0
>>>
>>> I'm unsure about this commit, it speaks more of avoiding duplicate
>>> messages
>>> for device enabling.
> 
> No, it's about trying IRQs twice, though it might be not fully clear
> from commit message: the example there shows that IRQs are probed twice
> and on some platforms it may be a problem.
> 
>>
>> Reverting this commit:
>>
>> commit 7d8905d064058f4b65057e0101588f362f288bc0
>> Author: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
>> Date:   Mon Jul 24 20:28:32 2017 +0300
>>
>>     serial: 8250_pci: Enable device after we check black list
>>
>> indeed fixes the problem.
>>
>> After reverting, the serial port from the Diva card shows up as ttyS0
>> (as before).
> 
>> With that patch applied, the serial port from the Diva card gets
>> ignored and the previous ttyS1 port becomes ttyS0 which then breaks
>> booting the parisc machine because the kernel expects the serial port
>> on
>> ttyS1.
> 
>> I'm not sure what the best way forward is.
>> Fact is, that the patch above changes the behaviour and serial ports
>> which were existant before suddenly vanish with kernel 4.14.
> 
> As stated in the commit message there "We can do this since PCI
> specification requires class, device and vendor ID registers to be
> always present in the configuration space."

That's OK.

> So, my understanding that the patch reveals the issue with these ports.

Your patch indirectly changes the behavior.

You check with serial_pci_is_class_communication(dev) if this serial device
is of class SERIAL or MODEM.
If it isn't you exit pciserial_init_one() and don't register the device.

Before your patch this check was inside the function serial_pci_guess_board()
and if (ent->driver_data != pbn_default) the pci serial port got registered 
and initialized *even* if it's *not* of class SERIAL or MODEM.

> (Of course, I agree this is regression and needs to be fixed ASAP)

I don't know if it's easy to fix without reverting your patch.
On the other side, your patch is correct in the sense that it avoids
registering serial ports which shouldn't be registered.
It's just that it now behaves differently and that it breaks booting
Linux on some parisc machines.
 
>> This following patch does work, and adds back the Diva serial port on
>> parisc.
> 
>> Not sure if it's acceptable though.
> 
> For me it looks like the best quick solution right now.
> 
> The proper one sounds like a specific initialization routine for these
> ports.
> 
> Send it as a formal patch and you may add
> 
> Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>

Thanks for the offer to accept this patch, but maybe we are able
to come up with another patch which simply hides those unsupported
devices (serial port and ATI graphics card device on the Diva card).
I posted a proposed patch here:
http://www.spinics.net/lists/linux-parisc/msg08187.html

But I wonder if we are the only platform which notice this different
behavior now. I assume others will notice it soon too.

> P.S. Sorry, we have no parisc hardware around to test.

No problem.

Thanks!
Helge
 
>>
>> Helge
>>
>> diff --git a/drivers/tty/serial/8250/8250_pci.c
>> b/drivers/tty/serial/8250/8250_pci.c
>> index 0c101a7470b0..61319e968e8c 100644
>> --- a/drivers/tty/serial/8250/8250_pci.c
>> +++ b/drivers/tty/serial/8250/8250_pci.c
>> @@ -3393,6 +3393,10 @@ static int
>> serial_pci_is_class_communication(struct pci_dev *dev)
>>  	 * (Should we try to make guesses for multiport serial
>> devices
>>  	 * later?)
>>  	 */
>> +	if (IS_ENABLED(CONFIG_PARISC) &&
>> +	    (dev->class >> 8) == PCI_CLASS_COMMUNICATION_OTHER)
>> +		return 0;
>> +
>>  	if ((((dev->class >> 8) != PCI_CLASS_COMMUNICATION_SERIAL) &&
>>  	     ((dev->class >> 8) != PCI_CLASS_COMMUNICATION_MODEM)) ||
>>  	    (dev->class & 0xff) > 6)
> 


^ permalink raw reply

* Re: [PATCH v3 29/33] dt-bindings: nds32 CPU Bindings
From: Rob Herring @ 2017-12-12 20:10 UTC (permalink / raw)
  To: Greentime Hu
  Cc: greentime, linux-kernel, arnd, linux-arch, tglx, jason,
	marc.zyngier, netdev, deanbo422, devicetree, viro, dhowells,
	will.deacon, daniel.lezcano, linux-serial, geert.uytterhoeven,
	linus.walleij, mark.rutland, greg, Vincent Chen, Rick Chen,
	Zong Li
In-Reply-To: <b082ead87b647f6f0797e51d3ceeaf6c87038dd1.1512723245.git.green.hu@gmail.com>

On Fri, Dec 08, 2017 at 05:12:12PM +0800, Greentime Hu wrote:
> From: Greentime Hu <greentime@andestech.com>
> 
> This patch adds nds32 CPU binding documents.
> 
> Signed-off-by: Vincent Chen <vincentc@andestech.com>
> Signed-off-by: Rick Chen <rick@andestech.com>
> Signed-off-by: Zong Li <zong@andestech.com>
> Signed-off-by: Greentime Hu <greentime@andestech.com>
> ---
>  Documentation/devicetree/bindings/nds32/cpus.txt |   37 ++++++++++++++++++++++
>  1 file changed, 37 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/nds32/cpus.txt

Reviewed-by: Rob Herring <robh@kernel.org>                  

^ permalink raw reply

* Re: [PATCH] serial: forbid 8250 on s390
From: Christian Borntraeger @ 2017-12-12 17:50 UTC (permalink / raw)
  To: Alan Cox
  Cc: Greg Kroah-Hartman, Jiri Slaby, linux-serial, linux-s390,
	linux-kernel
In-Reply-To: <20171212155032.2d5ece72@alans-desktop>



On 12/12/2017 04:50 PM, Alan Cox wrote:
> On Tue, 12 Dec 2017 09:08:35 +0100
> Christian Borntraeger <borntraeger@de.ibm.com> wrote:
> 
>> Using "make kvmconfig" results in a potentially unusable linux image
>> on s390.  The reason is that both the (default on s390) sclp consoles
>> as well as the 8250 console register a ttyS<x> as console. Since there
>> will be no 8250 on s390 let's fence 8250. This will ensure that there
>> is always a working sclp console.
> 
> And there is no physical way to attach a PCI express UART to a 390 ?

There is (some sort of) PCI but these cards are packaged in ibm specific I/O cages.
So someone would need to apply some some serious hardware and firmware hacking (since
only IBM-approved PCi cards are allowed) and you would need to have an MSI-capable
8250 as well as an MSI capable driver. (we only support MSI, no classic interrupts)
In addition to that that 8250 probably needs to support virtual functions since we always
run with LPARs.
And even if we can solve all these issues I would say it really does not make any sense at
all, while the current situation obviously breaks the use case "make kvmconfig"

So unless IBM sees some serious business case for 8250, I am inclined to answer you
question with "no" :-)

^ permalink raw reply

* Re: [PATCH v3 31/33] dt-bindings: interrupt-controller: Andestech Internal Vector Interrupt Controller
From: Rob Herring @ 2017-12-12 17:33 UTC (permalink / raw)
  To: Greentime Hu
  Cc: greentime-MUIXKm3Oiri1Z/+hSey0Gg,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, arnd-r2nGTMty4D4,
	linux-arch-u79uwXL29TY76Z2rM5mHXA, tglx-hfZtesqFncYOwBW4kG4KsQ,
	jason-NLaQJdtUoK4Be96aLqz0jA, marc.zyngier-5wv7dgnIgG8,
	netdev-u79uwXL29TY76Z2rM5mHXA, deanbo422-Re5JQEeQqe8AvxtiuMwx3w,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	viro-RmSDqhL/yNMiFSDQTTA3OLVCufUGDwFn,
	dhowells-H+wXaHxf7aLQT0dZR+AlfA, will.deacon-5wv7dgnIgG8,
	daniel.lezcano-QSEj5FYQhm4dnm+yROfE0A,
	linux-serial-u79uwXL29TY76Z2rM5mHXA,
	geert.uytterhoeven-Re5JQEeQqe8AvxtiuMwx3w,
	linus.walleij-QSEj5FYQhm4dnm+yROfE0A, mark.rutland-5wv7dgnIgG8,
	greg-U8xfFu+wG4EAvxtiuMwx3w, Rick Chen
In-Reply-To: <a0bb0a384a74bc180c0d4e9aa5741bb52653211b.1512723245.git.green.hu-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>

On Fri, Dec 08, 2017 at 05:12:14PM +0800, Greentime Hu wrote:
> From: Greentime Hu <greentime-MUIXKm3Oiri1Z/+hSey0Gg@public.gmane.org>
> 
> This patch adds an irqchip driver document for the Andestech Internal Vector
> Interrupt Controller.
> 
> Signed-off-by: Rick Chen <rick-MUIXKm3Oiri1Z/+hSey0Gg@public.gmane.org>
> Signed-off-by: Greentime Hu <greentime-MUIXKm3Oiri1Z/+hSey0Gg@public.gmane.org>
> ---
>  .../interrupt-controller/andestech,ativic32.txt    |   19 +++++++++++++++++++
>  1 file changed, 19 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/interrupt-controller/andestech,ativic32.txt

I acked v2. Please add acks when posting new versions.

Rob
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* Re: [PATCH] serial: forbid 8250 on s390
From: Alan Cox @ 2017-12-12 15:50 UTC (permalink / raw)
  To: Christian Borntraeger
  Cc: Greg Kroah-Hartman, Jiri Slaby, linux-serial, linux-s390,
	linux-kernel
In-Reply-To: <20171212080835.23610-1-borntraeger@de.ibm.com>

On Tue, 12 Dec 2017 09:08:35 +0100
Christian Borntraeger <borntraeger@de.ibm.com> wrote:

> Using "make kvmconfig" results in a potentially unusable linux image
> on s390.  The reason is that both the (default on s390) sclp consoles
> as well as the 8250 console register a ttyS<x> as console. Since there
> will be no 8250 on s390 let's fence 8250. This will ensure that there
> is always a working sclp console.

And there is no physical way to attach a PCI express UART to a 390 ?

Alan

^ permalink raw reply

* Re: [PATCH v2 2/2] acpi, x86: Use SPCR table for earlycon on x86
From: Ingo Molnar @ 2017-12-12 10:41 UTC (permalink / raw)
  To: Prarit Bhargava
  Cc: linux-acpi, linux-doc, linux-kernel, linux-arm-kernel, linux-pm,
	linux-serial, Bhupesh Sharma, Lv Zheng, Thomas Gleixner,
	Ingo Molnar, H. Peter Anvin, x86, Jonathan Corbet,
	Catalin Marinas, Will Deacon, Rafael J. Wysocki, Timur Tabi
In-Reply-To: <20171211155059.17062-3-prarit@redhat.com>


* Prarit Bhargava <prarit@redhat.com> wrote:

> The ACPI SPCR code has been used to define an earlycon console for ARM64
> and can be used for x86.
> 
> Modify the ACPI SPCR parsing code to account for console behaviour
> differences between ARM64 and x86.  Initialize the SPCR code from
> x86 ACPI initialization code.
> 
> Signed-off-by: Prarit Bhargava <prarit@redhat.com>
> Cc: linux-doc@vger.kernel.org
> Cc: linux-kernel@vger.kernel.org
> Cc: linux-arm-kernel@lists.infradead.org
> Cc: linux-pm@vger.kernel.org
> Cc: linux-acpi@vger.kernel.org
> Cc: linux-serial@vger.kernel.org
> Cc: Bhupesh Sharma <bhsharma@redhat.com>
> Cc: Lv Zheng <lv.zheng@intel.com>
> Cc: Thomas Gleixner <tglx@linutronix.de>
> Cc: Ingo Molnar <mingo@redhat.com>
> Cc: "H. Peter Anvin" <hpa@zytor.com>
> Cc: x86@kernel.org
> Cc: Jonathan Corbet <corbet@lwn.net>
> Cc: Catalin Marinas <catalin.marinas@arm.com>
> Cc: Will Deacon <will.deacon@arm.com>
> Cc: "Rafael J. Wysocki" <rjw@rjwysocki.net>
> Cc: Timur Tabi <timur@codeaurora.org>
> ---
>  Documentation/admin-guide/kernel-parameters.txt | 3 +++
>  arch/arm64/kernel/acpi.c                        | 2 +-
>  arch/x86/kernel/acpi/boot.c                     | 4 ++++
>  drivers/acpi/Kconfig                            | 2 +-
>  drivers/acpi/spcr.c                             | 7 +++++--
>  include/linux/acpi.h                            | 7 +++++--
>  6 files changed, 19 insertions(+), 6 deletions(-)

LGTM from an x86 perspective:

  Acked-by: Ingo Molnar <mingo@kernel.org>

(assuming it causes no regressions in linux-next.)

Since patch #1 affects ARM64 significantly, once that patch is acceptable to the 
arm64 folks feel free to upstream this second patch via the ARM64 tree as well.

Thanks,

	Ingo

^ permalink raw reply

* Re: [PATCH v5 1/3] clocksource/drivers/atcpit100: Add andestech atcpit100 timer
From: Daniel Lezcano @ 2017-12-12 10:05 UTC (permalink / raw)
  To: Rick Chen, rick, linux-kernel, arnd, linus.walleij, linux-arch,
	tglx, jason, marc.zyngier, robh+dt, netdev, deanbo422, devicetree,
	viro, dhowells, will.deacon, linux-serial
  Cc: Greentime Hu
In-Reply-To: <1513057621-19084-2-git-send-email-rickchen36@gmail.com>

On 12/12/2017 06:46, Rick Chen wrote:
> ATCPIT100 is often used on the Andes architecture,
> This timer provide 4 PIT channels. Each PIT channel is a
> multi-function timer, can be configured as 32,16,8 bit timers
> or PWM as well.
> 
> For system timer it will set channel 1 32-bit timer0 as clock
> source and count downwards until underflow and restart again.

[ ... ]

> +config CLKSRC_ATCPIT100
> +	bool "Clocksource for AE3XX platform"
> +	depends on NDS32 || COMPILE_TEST
> +	depends on HAS_IOMEM
> +	help
> +	  This option enables support for the Andestech AE3XX platform timers.

Hi Rick,

the general rule for the Kconfig is:

bool "Clocksource for AE3XX platform" if COMPILE_TEST

and no deps on the platform.

It is up to the platform Kconfig to select the option.

We want here a silent option but make it selectable in case of
compilation test coverage.

Also, this driver is not a CLKSRC but a TIMER. Rename CLKSRC_ATCPIT100
to TIMER_ATCPIT100.

> +
>  endmenu
> diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile
> index 72711f1..7d072f5 100644
> --- a/drivers/clocksource/Makefile
> +++ b/drivers/clocksource/Makefile
> @@ -75,3 +75,4 @@ obj-$(CONFIG_H8300_TMR16)		+= h8300_timer16.o
>  obj-$(CONFIG_H8300_TPU)			+= h8300_tpu.o
>  obj-$(CONFIG_CLKSRC_ST_LPC)		+= clksrc_st_lpc.o
>  obj-$(CONFIG_X86_NUMACHIP)		+= numachip.o
> +obj-$(CONFIG_CLKSRC_ATCPIT100)		+= timer-atcpit100.o

[ ... ]

> +static struct timer_of to = {
> +	.flags = TIMER_OF_IRQ | TIMER_OF_CLOCK | TIMER_OF_BASE,
> +
> +	.clkevt = {
> +		.name = "atcpit100_tick",
> +		.rating = 300,
> +		.features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
> +		.set_state_shutdown = atcpit100_clkevt_shutdown,
> +		.set_state_periodic = atcpit100_clkevt_set_periodic,
> +		.set_state_oneshot = atcpit100_clkevt_set_oneshot,
> +		.tick_resume = atcpit100_clkevt_shutdown,
> +		.set_next_event = atcpit100_clkevt_next_event,
> +		.cpumask = cpu_all_mask,

You may consider CLOCK_EVT_DYN_IRQ
https://lwn.net/Articles/540160/

> +	},
> +
> +	.of_irq = {
> +		.handler = atcpit100_timer_interrupt,
> +		.flags = IRQF_TIMER | IRQF_IRQPOLL,
> +	},
> +
> +	/*
> +	 * FIXME: we currently only support clocking using PCLK
> +	 * and using EXTCLK is not supported in the driver.
> +	 */
> +	.of_clk = {
> +		.name = "PCLK",
> +	}

What do you mean ? We can't specify several clock names with timer-of?


-- 
 <http://www.linaro.org/> Linaro.org │ Open source software for ARM SoCs

Follow Linaro:  <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog

^ permalink raw reply

* Re: [PATCH] serial: forbid 8250 on s390
From: Christian Borntraeger @ 2017-12-12  8:56 UTC (permalink / raw)
  To: Greg Kroah-Hartman; +Cc: Jiri Slaby, linux-serial, linux-s390, linux-kernel
In-Reply-To: <20171212084808.GA14030@kroah.com>



On 12/12/2017 09:48 AM, Greg Kroah-Hartman wrote:
> On Tue, Dec 12, 2017 at 09:08:35AM +0100, Christian Borntraeger wrote:
>> Using "make kvmconfig" results in a potentially unusable linux image
>> on s390.  The reason is that both the (default on s390) sclp consoles
>> as well as the 8250 console register a ttyS<x> as console. Since there
>> will be no 8250 on s390 let's fence 8250. This will ensure that there
>> is always a working sclp console.
>>
>> Reported-by: Alice Frosi <alice@linux.vnet.ibm.com>
>> Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
>> Reviewed-by: Hendrik Brueckner <brueckner@linux.vnet.ibm.com>
>> ---
>>  drivers/tty/serial/8250/Kconfig | 1 +
>>  1 file changed, 1 insertion(+)
> 
> Does this need to be backported to any stable kernels?  Or does anyone
> who runs them on s390 already have this config option disabled?

All shipped s390 kernels have 8250 disabled anyway. A backport of this
patch could be helpful to let users who want to use "make kvmconfig" give 
a working configuration but it is certainly not critical.

Christian

^ permalink raw reply

* Re: [PATCH] serial: forbid 8250 on s390
From: Greg Kroah-Hartman @ 2017-12-12  8:48 UTC (permalink / raw)
  To: Christian Borntraeger; +Cc: Jiri Slaby, linux-serial, linux-s390, linux-kernel
In-Reply-To: <20171212080835.23610-1-borntraeger@de.ibm.com>

On Tue, Dec 12, 2017 at 09:08:35AM +0100, Christian Borntraeger wrote:
> Using "make kvmconfig" results in a potentially unusable linux image
> on s390.  The reason is that both the (default on s390) sclp consoles
> as well as the 8250 console register a ttyS<x> as console. Since there
> will be no 8250 on s390 let's fence 8250. This will ensure that there
> is always a working sclp console.
> 
> Reported-by: Alice Frosi <alice@linux.vnet.ibm.com>
> Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
> Reviewed-by: Hendrik Brueckner <brueckner@linux.vnet.ibm.com>
> ---
>  drivers/tty/serial/8250/Kconfig | 1 +
>  1 file changed, 1 insertion(+)

Does this need to be backported to any stable kernels?  Or does anyone
who runs them on s390 already have this config option disabled?

thanks,

greg k-h

^ permalink raw reply

* [PATCH] serial: forbid 8250 on s390
From: Christian Borntraeger @ 2017-12-12  8:08 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Jiri Slaby
  Cc: linux-serial, linux-s390, linux-kernel, Christian Borntraeger

Using "make kvmconfig" results in a potentially unusable linux image
on s390.  The reason is that both the (default on s390) sclp consoles
as well as the 8250 console register a ttyS<x> as console. Since there
will be no 8250 on s390 let's fence 8250. This will ensure that there
is always a working sclp console.

Reported-by: Alice Frosi <alice@linux.vnet.ibm.com>
Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
Reviewed-by: Hendrik Brueckner <brueckner@linux.vnet.ibm.com>
---
 drivers/tty/serial/8250/Kconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/tty/serial/8250/Kconfig b/drivers/tty/serial/8250/Kconfig
index a5c0ef1..16b1496 100644
--- a/drivers/tty/serial/8250/Kconfig
+++ b/drivers/tty/serial/8250/Kconfig
@@ -5,6 +5,7 @@
 
 config SERIAL_8250
 	tristate "8250/16550 and compatible serial support"
+	depends on !S390
 	select SERIAL_CORE
 	---help---
 	  This selects whether you want to include the driver for the standard
-- 
2.9.4

^ permalink raw reply related

* [PATCH v5 3/3] dt-bindings: timer: Add andestech atcpit100 timer binding doc
From: Rick Chen @ 2017-12-12  5:47 UTC (permalink / raw)
  To: rickchen36, rick, linux-kernel, arnd, linus.walleij,
	daniel.lezcano, linux-arch, tglx, jason, marc.zyngier, robh+dt,
	netdev, deanbo422, devicetree, viro, dhowells, will.deacon,
	linux-serial
  Cc: Greentime Hu
In-Reply-To: <1513057621-19084-1-git-send-email-rickchen36@gmail.com>

Add a document to describe Andestech atcpit100 timer and
binding information.

Signed-off-by: Rick Chen <rickchen36@gmail.com>
Signed-off-by: Greentime Hu <green.hu@gmail.com>
Acked-by: Rob Herring <robh@kernel.org>
---
 .../bindings/timer/andestech,atcpit100-timer.txt   | 33 ++++++++++++++++++++++
 1 file changed, 33 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/timer/andestech,atcpit100-timer.txt

diff --git a/Documentation/devicetree/bindings/timer/andestech,atcpit100-timer.txt b/Documentation/devicetree/bindings/timer/andestech,atcpit100-timer.txt
new file mode 100644
index 0000000..14812f68
--- /dev/null
+++ b/Documentation/devicetree/bindings/timer/andestech,atcpit100-timer.txt
@@ -0,0 +1,33 @@
+Andestech ATCPIT100 timer
+------------------------------------------------------------------
+ATCPIT100 is a generic IP block from Andes Technology, embedded in
+Andestech AE3XX platforms and other designs.
+
+This timer is a set of compact multi-function timers, which can be
+used as pulse width modulators (PWM) as well as simple timers.
+
+It supports up to 4 PIT channels. Each PIT channel is a
+multi-function timer and provide the following usage scenarios:
+One 32-bit timer
+Two 16-bit timers
+Four 8-bit timers
+One 16-bit PWM
+One 16-bit timer and one 8-bit PWM
+Two 8-bit timer and one 8-bit PWM
+
+Required properties:
+- compatible	: Should be "andestech,atcpit100"
+- reg		: Address and length of the register set
+- interrupts	: Reference to the timer interrupt
+- clocks : a clock to provide the tick rate for "andestech,atcpit100"
+- clock-names : should be "PCLK" for the peripheral clock source.
+
+Examples:
+
+timer0: timer@f0400000 {
+	compatible = "andestech,atcpit100";
+	reg = <0xf0400000 0x1000>;
+	interrupts = <2 4>;
+	clocks = <&apb>;
+	clock-names = "PCLK";
+};
-- 
2.7.4

^ permalink raw reply related

* [PATCH v5 2/3] clocksource/drivers/atcpit100: VDSO support
From: Rick Chen @ 2017-12-12  5:47 UTC (permalink / raw)
  To: rickchen36, rick, linux-kernel, arnd, linus.walleij,
	daniel.lezcano, linux-arch, tglx, jason, marc.zyngier, robh+dt,
	netdev, deanbo422, devicetree, viro, dhowells, will.deacon,
	linux-serial
  Cc: Vincent Chen, Greentime Hu
In-Reply-To: <1513057621-19084-1-git-send-email-rickchen36@gmail.com>

VDSO needs real-time cycle count to ensure the time accuracy.
Unlike others, nds32 architecture does not define clock source,
hence VDSO needs atcpit100 offering real-time cycle count
to derive the correct time.

Signed-off-by: Vincent Chen <vincentc@andestech.com>
Signed-off-by: Rick Chen <rickchen36@gmail.com>
Signed-off-by: Greentime Hu <green.hu@gmail.com>
---
 drivers/clocksource/timer-atcpit100.c | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/drivers/clocksource/timer-atcpit100.c b/drivers/clocksource/timer-atcpit100.c
index 0077fdb..1be6c0a 100644
--- a/drivers/clocksource/timer-atcpit100.c
+++ b/drivers/clocksource/timer-atcpit100.c
@@ -29,6 +29,9 @@
 #include <linux/of_irq.h>
 #include <linux/of_platform.h>
 #include "timer-of.h"
+#ifdef CONFIG_NDS32
+#include <asm/vdso_timer_info.h>
+#endif
 
 /*
  * Definition of register offsets
@@ -211,6 +214,14 @@ static u64 notrace atcpit100_timer_sched_read(void)
 	return ~readl(timer_of_base(&to) + CH1_CNT);
 }
 
+#ifdef CONFIG_NDS32
+static void fill_vdso_need_info(void)
+{
+	timer_info.cycle_count_down = true;
+	timer_info.cycle_count_reg_offset = CH1_CNT;
+}
+#endif
+
 static int __init atcpit100_timer_init(struct device_node *node)
 {
 	int ret;
@@ -249,6 +260,10 @@ static int __init atcpit100_timer_init(struct device_node *node)
 	val = readl(base + INT_EN);
 	writel(val | CH0INT0EN, base + INT_EN);
 
+#ifdef CONFIG_NDS32
+	fill_vdso_need_info();
+#endif
+
 	return ret;
 }
 
-- 
2.7.4

^ permalink raw reply related

* [PATCH v5 1/3] clocksource/drivers/atcpit100: Add andestech atcpit100 timer
From: Rick Chen @ 2017-12-12  5:46 UTC (permalink / raw)
  To: rickchen36, rick, linux-kernel, arnd, linus.walleij,
	daniel.lezcano, linux-arch, tglx, jason, marc.zyngier, robh+dt,
	netdev, deanbo422, devicetree, viro, dhowells, will.deacon,
	linux-serial
  Cc: Greentime Hu
In-Reply-To: <1513057621-19084-1-git-send-email-rickchen36@gmail.com>

ATCPIT100 is often used on the Andes architecture,
This timer provide 4 PIT channels. Each PIT channel is a
multi-function timer, can be configured as 32,16,8 bit timers
or PWM as well.

For system timer it will set channel 1 32-bit timer0 as clock
source and count downwards until underflow and restart again.

It also set channel 0 32-bit timer0 as clock event and count
downwards until condition match. It will generate an interrupt
for handling periodically.

Signed-off-by: Rick Chen <rickchen36@gmail.com>
Signed-off-by: Greentime Hu <green.hu@gmail.com>
Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
---
 drivers/clocksource/Kconfig           |   7 +
 drivers/clocksource/Makefile          |   1 +
 drivers/clocksource/timer-atcpit100.c | 255 ++++++++++++++++++++++++++++++++++
 3 files changed, 263 insertions(+)
 create mode 100644 drivers/clocksource/timer-atcpit100.c

diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
index cc60620..8c57ef2 100644
--- a/drivers/clocksource/Kconfig
+++ b/drivers/clocksource/Kconfig
@@ -615,4 +615,11 @@ config CLKSRC_ST_LPC
 	  Enable this option to use the Low Power controller timer
 	  as clocksource.
 
+config CLKSRC_ATCPIT100
+	bool "Clocksource for AE3XX platform"
+	depends on NDS32 || COMPILE_TEST
+	depends on HAS_IOMEM
+	help
+	  This option enables support for the Andestech AE3XX platform timers.
+
 endmenu
diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile
index 72711f1..7d072f5 100644
--- a/drivers/clocksource/Makefile
+++ b/drivers/clocksource/Makefile
@@ -75,3 +75,4 @@ obj-$(CONFIG_H8300_TMR16)		+= h8300_timer16.o
 obj-$(CONFIG_H8300_TPU)			+= h8300_tpu.o
 obj-$(CONFIG_CLKSRC_ST_LPC)		+= clksrc_st_lpc.o
 obj-$(CONFIG_X86_NUMACHIP)		+= numachip.o
+obj-$(CONFIG_CLKSRC_ATCPIT100)		+= timer-atcpit100.o
diff --git a/drivers/clocksource/timer-atcpit100.c b/drivers/clocksource/timer-atcpit100.c
new file mode 100644
index 0000000..0077fdb
--- /dev/null
+++ b/drivers/clocksource/timer-atcpit100.c
@@ -0,0 +1,255 @@
+/*
+ *  Andestech ATCPIT100 Timer Device Driver Implementation
+ *
+ * Copyright (C) 2017 Andes Technology Corporation
+ * Rick Chen, Andes Technology Corporation <rick@andestech.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ *
+ */
+
+#include <linux/irq.h>
+#include <linux/clocksource.h>
+#include <linux/clockchips.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/cpufreq.h>
+#include <linux/sched.h>
+#include <linux/sched_clock.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/of_platform.h>
+#include "timer-of.h"
+
+/*
+ * Definition of register offsets
+ */
+
+/* ID and Revision Register */
+#define ID_REV		0x0
+
+/* Configuration Register */
+#define CFG		0x10
+
+/* Interrupt Enable Register */
+#define INT_EN		0x14
+#define CH_INT_EN(c, i)	((1<<i)<<(4*c))
+#define CH0INT0EN	0x01
+
+/* Interrupt Status Register */
+#define INT_STA		0x18
+#define CH0INT0		0x01
+
+/* Channel Enable Register */
+#define CH_EN		0x1C
+#define CH0TMR0EN	0x1
+#define CH1TMR0EN	0x10
+
+/* Channel 0 , 1 Control Register */
+#define CH0_CTL		(0x20)
+#define CH1_CTL		(0x20 + 0x10)
+
+/* Channel clock source , bit 3 , 0:External clock , 1:APB clock */
+#define APB_CLK		BIT(3)
+
+/* Channel mode , bit 0~2 */
+#define TMR_32		0x1
+#define TMR_16		0x2
+#define TMR_8		0x3
+
+/* Channel 0 , 1 Reload Register */
+#define CH0_REL		(0x24)
+#define CH1_REL		(0x24 + 0x10)
+
+/* Channel 0 , 1 Counter Register */
+#define CH0_CNT		(0x28)
+#define CH1_CNT		(0x28 + 0x10)
+
+#define TIMER_SYNC_TICKS	3
+
+static void atcpit100_ch1_tmr0_en(void __iomem *base)
+{
+	writel(~0, base + CH1_REL);
+	writel(APB_CLK|TMR_32, base + CH1_CTL);
+}
+
+static void atcpit100_ch0_tmr0_en(void __iomem *base)
+{
+	writel(APB_CLK|TMR_32, base + CH0_CTL);
+}
+
+static void atcpit100_clkevt_time_setup(void __iomem *base, unsigned long delay)
+{
+	writel(delay, base + CH0_CNT);
+	writel(delay, base + CH0_REL);
+}
+
+static void atcpit100_timer_clear_interrupt(void __iomem *base)
+{
+	u32 val;
+
+	val = readl(base + INT_STA);
+	writel(val | CH0INT0, base + INT_STA);
+}
+
+static void atcpit100_clocksource_start(void __iomem *base)
+{
+	u32 val;
+
+	val = readl(base + CH_EN);
+	writel(val | CH1TMR0EN, base + CH_EN);
+}
+
+static void atcpit100_clkevt_time_start(void __iomem *base)
+{
+	u32 val;
+
+	val = readl(base + CH_EN);
+	writel(val | CH0TMR0EN, base + CH_EN);
+}
+
+static void atcpit100_clkevt_time_stop(void __iomem *base)
+{
+	u32 val;
+
+	atcpit100_timer_clear_interrupt(base);
+	val = readl(base + CH_EN);
+	writel(val & ~CH0TMR0EN, base + CH_EN);
+}
+
+static int atcpit100_clkevt_next_event(unsigned long evt,
+	struct clock_event_device *clkevt)
+{
+	struct timer_of *to = to_timer_of(clkevt);
+
+	writel(evt, timer_of_base(to) + CH0_REL);
+
+	return 0;
+}
+
+static int atcpit100_clkevt_set_periodic(struct clock_event_device *evt)
+{
+	struct timer_of *to = to_timer_of(evt);
+
+	atcpit100_clkevt_time_setup(timer_of_base(to), timer_of_period(to));
+	atcpit100_clkevt_time_start(timer_of_base(to));
+
+	return 0;
+}
+static int atcpit100_clkevt_shutdown(struct clock_event_device *evt)
+{
+	struct timer_of *to = to_timer_of(evt);
+
+	atcpit100_clkevt_time_stop(timer_of_base(to));
+
+	return 0;
+}
+static int atcpit100_clkevt_set_oneshot(struct clock_event_device *evt)
+{
+	struct timer_of *to = to_timer_of(evt);
+	u32 val;
+
+	writel(~0x0, timer_of_base(to) + CH0_REL);
+	val = readl(timer_of_base(to) + CH_EN);
+	writel(val | CH0TMR0EN, timer_of_base(to) + CH_EN);
+
+	return 0;
+}
+
+static irqreturn_t atcpit100_timer_interrupt(int irq, void *dev_id)
+{
+	struct clock_event_device *evt = (struct clock_event_device *)dev_id;
+	struct timer_of *to = to_timer_of(evt);
+
+	atcpit100_timer_clear_interrupt(timer_of_base(to));
+
+	evt->event_handler(evt);
+
+	return IRQ_HANDLED;
+}
+
+static struct timer_of to = {
+	.flags = TIMER_OF_IRQ | TIMER_OF_CLOCK | TIMER_OF_BASE,
+
+	.clkevt = {
+		.name = "atcpit100_tick",
+		.rating = 300,
+		.features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
+		.set_state_shutdown = atcpit100_clkevt_shutdown,
+		.set_state_periodic = atcpit100_clkevt_set_periodic,
+		.set_state_oneshot = atcpit100_clkevt_set_oneshot,
+		.tick_resume = atcpit100_clkevt_shutdown,
+		.set_next_event = atcpit100_clkevt_next_event,
+		.cpumask = cpu_all_mask,
+	},
+
+	.of_irq = {
+		.handler = atcpit100_timer_interrupt,
+		.flags = IRQF_TIMER | IRQF_IRQPOLL,
+	},
+
+	/*
+	 * FIXME: we currently only support clocking using PCLK
+	 * and using EXTCLK is not supported in the driver.
+	 */
+	.of_clk = {
+		.name = "PCLK",
+	}
+};
+
+static u64 notrace atcpit100_timer_sched_read(void)
+{
+	return ~readl(timer_of_base(&to) + CH1_CNT);
+}
+
+static int __init atcpit100_timer_init(struct device_node *node)
+{
+	int ret;
+	u32 val;
+	void __iomem *base;
+
+	ret = timer_of_init(node, &to);
+	if (ret)
+		return ret;
+
+	base = timer_of_base(&to);
+
+	sched_clock_register(atcpit100_timer_sched_read, 32,
+		timer_of_rate(&to));
+
+	ret = clocksource_mmio_init(base + CH1_CNT,
+		node->name, timer_of_rate(&to), 300, 32,
+		clocksource_mmio_readl_down);
+
+	if (ret) {
+		pr_err("Failed to register clocksource\n");
+		return ret;
+	}
+
+	/* clear channel 0 timer0 interrupt */
+	atcpit100_timer_clear_interrupt(base);
+
+	clockevents_config_and_register(&to.clkevt, timer_of_rate(&to),
+					TIMER_SYNC_TICKS, 0xffffffff);
+	atcpit100_ch0_tmr0_en(base);
+	atcpit100_ch1_tmr0_en(base);
+	atcpit100_clocksource_start(base);
+	atcpit100_clkevt_time_start(base);
+
+	/* Enable channel 0 timer0 interrupt */
+	val = readl(base + INT_EN);
+	writel(val | CH0INT0EN, base + INT_EN);
+
+	return ret;
+}
+
+TIMER_OF_DECLARE(atcpit100, "andestech,atcpit100", atcpit100_timer_init);
-- 
2.7.4

^ permalink raw reply related

* [PATCH v5 0/3] Add andestech atcpit100 timer
From: Rick Chen @ 2017-12-12  5:46 UTC (permalink / raw)
  To: rickchen36-Re5JQEeQqe8AvxtiuMwx3w, rick-MUIXKm3Oiri1Z/+hSey0Gg,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, arnd-r2nGTMty4D4,
	linus.walleij-QSEj5FYQhm4dnm+yROfE0A,
	daniel.lezcano-QSEj5FYQhm4dnm+yROfE0A,
	linux-arch-u79uwXL29TY76Z2rM5mHXA, tglx-hfZtesqFncYOwBW4kG4KsQ,
	jason-NLaQJdtUoK4Be96aLqz0jA, marc.zyngier-5wv7dgnIgG8,
	robh+dt-DgEjT+Ai2ygdnm+yROfE0A, netdev-u79uwXL29TY76Z2rM5mHXA,
	deanbo422-Re5JQEeQqe8AvxtiuMwx3w,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	viro-RmSDqhL/yNMiFSDQTTA3OLVCufUGDwFn,
	dhowells-H+wXaHxf7aLQT0dZR+AlfA, will.deacon-5wv7dgnIgG8,
	linux-serial-u79uwXL29TY76Z2rM5mHXA

Changelog v5:
 - Patch 1/3: Changes
 - Patch 2/3: New
 - Patch 3/3: Changes

[Patch 1/3] clocksource/drivers/atcpit100: Add andestech atcpit100 timer
 1 No need to split out the Makefile patch from the actual driver.
 	 Suggested by Arnd Bergmann
 2 Add of_clk.name = "PCLK" to be explicit on what we use.
   Suggested by Linus Walleij
 3 Remove the GENERIC_CLOCKEVENTS from Kconfig.
   Suggested by Daniel Lezcano
 4 Add depends on NDS32 || COMPILE_TEST in Kconfig
   Suggested by Greentime Hu

[Patch 2/3] clocksource/drivers/atcpit100: VDSO support
	 Why implemented in timer driver, please see details from
	 https://lkml.org/lkml/2017/12/8/362
	 [PATCH v3 17/33] nds32: VDSO support.
	 Suggested by Mark Rutland
	 Here Mark Rutlan suggested as below:
	 You should not add properties to arbitrary DT bindings to
	 handle a Linux implementation detail.
	 Please remove this DT code, and have the drivers for those
	 timer blocks export this information to your vdso code somehow.

[Patch 3/3] dt-bindings: timer: Add andestech atcpit100 timer binding doc
   Fix incorrect description about PCLK.
	 Suggested by Linus Walleij

Rick Chen (3):
  clocksource/drivers/atcpit100: Add andestech atcpit100 timer
  clocksource/drivers/atcpit100: VDSO support
  dt-bindings: timer: Add andestech atcpit100 timer binding doc

 .../bindings/timer/andestech,atcpit100-timer.txt   |  33 +++
 drivers/clocksource/Kconfig                        |   7 +
 drivers/clocksource/Makefile                       |   1 +
 drivers/clocksource/timer-atcpit100.c              | 270 +++++++++++++++++++++
 4 files changed, 311 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/timer/andestech,atcpit100-timer.txt
 create mode 100644 drivers/clocksource/timer-atcpit100.c

-- 
2.7.4

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* Re: [PATCH v3 17/33] nds32: VDSO support
From: Vincent Chen @ 2017-12-12  1:58 UTC (permalink / raw)
  To: Mark Rutland
  Cc: Greentime Hu, Greentime, Linux Kernel Mailing List, Arnd Bergmann,
	linux-arch, Thomas Gleixner, Jason Cooper, Marc Zyngier,
	Rob Herring, netdev, DTML, Al Viro, David Howells, Will Deacon,
	Daniel Lezcano, linux-serial, Geert Uytterhoeven, Linus Walleij,
	Greg KH, Vincent Chen
In-Reply-To: <20171208121405.dy6raczdlbxtbnfo@lakrids.cambridge.arm.com>

2017-12-08 20:14 GMT+08:00 Mark Rutland <mark.rutland@arm.com>:
> On Fri, Dec 08, 2017 at 07:54:42PM +0800, Greentime Hu wrote:
>> 2017-12-08 18:21 GMT+08:00 Mark Rutland <mark.rutland@arm.com>:
>> > On Fri, Dec 08, 2017 at 05:12:00PM +0800, Greentime Hu wrote:
>> >> +static int grab_timer_node_info(void)
>> >> +{
>> >> +     struct device_node *timer_node;
>> >> +
>> >> +     timer_node = of_find_node_by_name(NULL, "timer");
>> >
>> > Please use a compatible string, rather than matching the timer by name.
>> >
>> > It's plausible that you have multiple nodes called "timer" in the DT,
>> > under different parent nodes, and this might not be the device you
>> > think it is. I see your dt in patch 24 has two timer nodes.
>> >
>> > It would be best if your clocksource driver exposed some stuct that you
>> > looked at here, so that you're guaranteed to user the same device.
>>
>> We'd like to use "timer" here because there are 2 different timer IPs
>> and we are sure that they won't be in the same SoC.
>> We think this implementation in VDSO should be platform independent to
>> get cycle-count register.
>> Our customer or other SoC provider who can use "timer" and define
>> cycle-count-offset or cycle-count-down then we can get the correct
>> cycle-count.
>
> This is not the right way to do things.
>
> So from a DT perspective, NAK.
>
> You should not add properties to arbitrary DT bindings to handle a Linux
> implementation detail.
>
> Please remove this DT code, and have the drivers for those timer blocks
> export this information to your vdso code somehow.
>

Hi, Mark:
Based on your suggestion, we define a new sturct timer_info to let
timer driver record the value
of cycle-count-offset and cycle-count-down in timer_init function. The
above code in timer driver
is validate only when CONFIG_NDS32 is defined.

>> We sent atcpit100 patch last time along with our arch, however we'd
>> like to send it to its sub system this time and my colleague is still
>> working on it.
>> He may send the timer patch next week.
>
> I think that it would make sense for that patch to be part of the arch
> port, especially given that (AFAICT) there is no dirver for the other
> timer IP that you mention.
>
> [...]
>
>> >> +int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)
>> >> +{
>> >
>> >> +     /*Map timer to user space */
>> >> +     vdso_base += PAGE_SIZE;
>> >> +     prot = __pgprot(_PAGE_V | _PAGE_M_UR_KR | _PAGE_D |
>> >> +                     _PAGE_G | _PAGE_C_DEV);
>> >> +     ret = io_remap_pfn_range(vma, vdso_base, timer_res.start >> PAGE_SHIFT,
>> >> +                              PAGE_SIZE, prot);
>> >> +     if (ret)
>> >> +             goto up_fail;
>> >
>> > Maybe this is fine, but it looks a bit suspicious.
>> >
>> > Is it safe to map IO memory to a userspace process like this?
>> >
>> > In general that isn't safe, since userspace could access other registers
>> > (if those exist), perform accesses that change the state of hardware, or
>> > make unsupported access types (e.g. unaligned, atomic) that result in
>> > errors the kernel can't handle.
>> >
>> > Does none of that apply here?
>>
>> We only provide read permission to this page so hareware state won't
>> be chagned. It will trigger exception if we try to write.
>> We will check about the alignment/atomic issue of this region.
>

For alignment issue, we intentionally make an un-alignment read to
access this region and we
got "Segmentation fault" as expected.


Thanks,
Vincent

> Ok, thanks.
>
> This is another reason to only do this for devices/drivers that we have
> drivers for, since we can't know that this is safe in general.
>
> Thanks,
> Mark.

^ permalink raw reply

* Re: [PATCH 1/1] tty: serial: imx: allow breaks to be received when using dma
From: Troy Kisky @ 2017-12-11 20:52 UTC (permalink / raw)
  To: gregkh, nandor.han
  Cc: linux-serial, u.kleine-koenig, fabio.estevam, linux-arm-kernel,
	l.stach
In-Reply-To: <a3f0140a-92bb-ed59-ee79-971385634d4d@boundarydevices.com>

On 10/20/2017 3:17 PM, Troy Kisky wrote:
> On 10/20/2017 3:13 PM, Troy Kisky wrote:
>> This allows me to login after sending a break when service
>> serial-getty@ttymxc0.service is running
>>
>> Signed-off-by: Troy Kisky <troy.kisky@boundarydevices.com>
>> ---
>>  drivers/tty/serial/imx.c | 20 +++++++++++++-------
>>  1 file changed, 13 insertions(+), 7 deletions(-)
>>
>> diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c
>> index 506fcd742b47..39033f460a24 100644
>> --- a/drivers/tty/serial/imx.c
>> +++ b/drivers/tty/serial/imx.c
>> @@ -934,7 +934,6 @@ static void dma_rx_callback(void *data)
>>  	status = dmaengine_tx_status(chan, (dma_cookie_t)0, &state);
>>  
>>  	if (status == DMA_ERROR) {
>> -		dev_err(sport->port.dev, "DMA transaction error.\n");
>>  		clear_rx_errors(sport);
>>  		return;
>>  	}
>> @@ -1035,6 +1034,7 @@ static int start_rx_dma(struct imx_port *sport)
>>  
>>  static void clear_rx_errors(struct imx_port *sport)
>>  {
>> +	struct tty_port *port = &sport->port.state->port;
>>  	unsigned int status_usr1, status_usr2;
>>  
>>  	status_usr1 = readl(sport->port.membase + USR1);
>> @@ -1043,12 +1043,18 @@ static void clear_rx_errors(struct imx_port *sport)
>>  	if (status_usr2 & USR2_BRCD) {
>>  		sport->port.icount.brk++;
>>  		writel(USR2_BRCD, sport->port.membase + USR2);
>> -	} else if (status_usr1 & USR1_FRAMERR) {
>> -		sport->port.icount.frame++;
>> -		writel(USR1_FRAMERR, sport->port.membase + USR1);
>> -	} else if (status_usr1 & USR1_PARITYERR) {
>> -		sport->port.icount.parity++;
>> -		writel(USR1_PARITYERR, sport->port.membase + USR1);
>> +		if (tty_insert_flip_char(port, 0, TTY_BREAK) == 0)
>> +			sport->port.icount.buf_overrun++;
>> +		tty_flip_buffer_push(port);
>> +	} else {
>> +		dev_err(sport->port.dev, "DMA transaction error.\n");
>> +		if (status_usr1 & USR1_FRAMERR) {
>> +			sport->port.icount.frame++;
>> +			writel(USR1_FRAMERR, sport->port.membase + USR1);
>> +		} else if (status_usr1 & USR1_PARITYERR) {
>> +			sport->port.icount.parity++;
>> +			writel(USR1_PARITYERR, sport->port.membase + USR1);
>> +		}
>>  	}
>>  
>>  	if (status_usr2 & USR2_ORE) {
>>
> 
> 
> 
> Does this need to use
>  	spin_lock_irqsave(&sport->port.lock, flags);
> 
> 
> I would have, but dma_rx_callback doesn't.
> 
> BR
> Troy
> 
> 

I think the path is fine as is. Should I send a rebased version ?

Thanks
Troy

^ permalink raw reply

* [PATCH v2 2/2] acpi, x86: Use SPCR table for earlycon on x86
From: Prarit Bhargava @ 2017-12-11 15:50 UTC (permalink / raw)
  To: linux-acpi
  Cc: Prarit Bhargava, Jonathan Corbet, x86, linux-pm, Catalin Marinas,
	Bhupesh Sharma, linux-doc, Will Deacon, linux-kernel, Ingo Molnar,
	Rafael J. Wysocki, Lv Zheng, linux-serial, H. Peter Anvin,
	Thomas Gleixner, Timur Tabi, linux-arm-kernel
In-Reply-To: <20171211155059.17062-1-prarit@redhat.com>

The ACPI SPCR code has been used to define an earlycon console for ARM64
and can be used for x86.

Modify the ACPI SPCR parsing code to account for console behaviour
differences between ARM64 and x86.  Initialize the SPCR code from
x86 ACPI initialization code.

Signed-off-by: Prarit Bhargava <prarit@redhat.com>
Cc: linux-doc@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
Cc: linux-arm-kernel@lists.infradead.org
Cc: linux-pm@vger.kernel.org
Cc: linux-acpi@vger.kernel.org
Cc: linux-serial@vger.kernel.org
Cc: Bhupesh Sharma <bhsharma@redhat.com>
Cc: Lv Zheng <lv.zheng@intel.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: "H. Peter Anvin" <hpa@zytor.com>
Cc: x86@kernel.org
Cc: Jonathan Corbet <corbet@lwn.net>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Will Deacon <will.deacon@arm.com>
Cc: "Rafael J. Wysocki" <rjw@rjwysocki.net>
Cc: Timur Tabi <timur@codeaurora.org>
---
 Documentation/admin-guide/kernel-parameters.txt | 3 +++
 arch/arm64/kernel/acpi.c                        | 2 +-
 arch/x86/kernel/acpi/boot.c                     | 4 ++++
 drivers/acpi/Kconfig                            | 2 +-
 drivers/acpi/spcr.c                             | 7 +++++--
 include/linux/acpi.h                            | 7 +++++--
 6 files changed, 19 insertions(+), 6 deletions(-)

diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
index 0d173289c67e..c7cc890a0e81 100644
--- a/Documentation/admin-guide/kernel-parameters.txt
+++ b/Documentation/admin-guide/kernel-parameters.txt
@@ -918,6 +918,9 @@
 			stdout-path property in device tree's chosen node,
 			or determined by the ACPI SPCR table.
 
+			[X86] When used with no options the early console is
+			determined by the ACPI SPCR table.
+
 		cdns,<addr>[,options]
 			Start an early, polled-mode console on a Cadence
 			(xuartps) serial port at the specified address. Only
diff --git a/arch/arm64/kernel/acpi.c b/arch/arm64/kernel/acpi.c
index b3e33bbdf3b7..aaee4864b63e 100644
--- a/arch/arm64/kernel/acpi.c
+++ b/arch/arm64/kernel/acpi.c
@@ -355,7 +355,7 @@ void __init acpi_boot_table_init(void)
 			early_init_dt_scan_chosen_stdout();
 	} else {
 		/* Always enable the ACPI SPCR console */
-		acpi_parse_spcr(console_acpi_spcr_enable);
+		acpi_parse_spcr(console_acpi_spcr_enable, true);
 		if (IS_ENABLED(CONFIG_ACPI_BGRT))
 			acpi_table_parse(ACPI_SIG_BGRT, acpi_parse_bgrt);
 	}
diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c
index f4c463df8b08..f01a03643cff 100644
--- a/arch/x86/kernel/acpi/boot.c
+++ b/arch/x86/kernel/acpi/boot.c
@@ -36,6 +36,7 @@
 #include <linux/ioport.h>
 #include <linux/pci.h>
 #include <linux/efi-bgrt.h>
+#include <linux/serial_core.h>
 
 #include <asm/e820/api.h>
 #include <asm/irqdomain.h>
@@ -1626,6 +1627,9 @@ int __init acpi_boot_init(void)
 	if (!acpi_noirq)
 		x86_init.pci.init = pci_acpi_init;
 
+	/* Do not enable ACPI SPCR console by default */
+	acpi_parse_spcr(console_acpi_spcr_enable, console_acpi_spcr_enable);
+
 	return 0;
 }
 
diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig
index 9ae98eeada76..2d4e841e0682 100644
--- a/drivers/acpi/Kconfig
+++ b/drivers/acpi/Kconfig
@@ -80,7 +80,7 @@ endif
 
 config ACPI_SPCR_TABLE
 	bool "ACPI Serial Port Console Redirection Support"
-	default y if ARM64
+	default y if (X86 || ARM64)
 	help
 	  Enable support for Serial Port Console Redirection (SPCR) Table.
 	  This table provides information about the configuration of the
diff --git a/drivers/acpi/spcr.c b/drivers/acpi/spcr.c
index f4bb8110e404..c9469b488527 100644
--- a/drivers/acpi/spcr.c
+++ b/drivers/acpi/spcr.c
@@ -39,7 +39,7 @@ bool console_acpi_spcr_enable __initdata;
  * from arch initialization code as soon as the DT/ACPI decision is made.
  *
  */
-int __init acpi_parse_spcr(bool earlycon)
+int __init acpi_parse_spcr(bool earlycon, bool enable_console)
 {
 	static char opts[ACPI_SPCR_OPTS_SIZE];
 	static char uart[ACPI_SPCR_BUF_SIZE];
@@ -112,7 +112,10 @@ int __init acpi_parse_spcr(bool earlycon)
 	if (earlycon)
 		setup_earlycon(opts);
 
-	err = add_preferred_console(uart, 0, opts + strlen(uart) + 1);
+	if (enable_console)
+		err = add_preferred_console(uart, 0, opts + strlen(uart) + 1);
+	else
+		err = 0;
 done:
 	acpi_put_table((struct acpi_table_header *)table);
 	return err;
diff --git a/include/linux/acpi.h b/include/linux/acpi.h
index 875d7327d91c..4c2d449bab9b 100644
--- a/include/linux/acpi.h
+++ b/include/linux/acpi.h
@@ -1248,10 +1248,13 @@ extern bool console_acpi_spcr_enable __initdata;
 extern int acpi_arch_setup_console(struct acpi_table_spcr *table,
 				   char *opts, char *uart, char *iotype,
 				   int baud_rate, bool earlycon);
-int acpi_parse_spcr(bool earlycon);
+int acpi_parse_spcr(bool earlycon, bool enable_console);
 #else
 static const bool console_acpi_spcr_enable;
-static inline int acpi_parse_spcr(bool earlycon) { return 0; }
+static inline int acpi_parse_spcr(bool earlycon, bool enable_console)
+{
+	return 0;
+}
 #endif
 
 #if IS_ENABLED(CONFIG_ACPI_GENERIC_GSI)
-- 
2.15.0.rc0.39.g2f0e14e64

^ permalink raw reply related

* [PATCH v2 1/2] acpi, spcr: Make SPCR avialable to other architectures
From: Prarit Bhargava @ 2017-12-11 15:50 UTC (permalink / raw)
  To: linux-acpi
  Cc: Prarit Bhargava, linux-doc, linux-kernel, linux-arm-kernel,
	linux-pm, linux-serial, Bhupesh Sharma, Lv Zheng, Thomas Gleixner,
	Ingo Molnar, H. Peter Anvin, x86, Jonathan Corbet,
	Catalin Marinas, Will Deacon, Rafael J. Wysocki, Timur Tabi
In-Reply-To: <20171211155059.17062-1-prarit@redhat.com>

Other architectures can use SPCR to setup an early console or console
but the current code is ARM64 specific.

Change the name of parse_spcr() to acpi_parse_spcr().  Add a weak
function acpi_arch_setup_console() that can be used for arch-specific
setup.  Move flags into ACPI code.  Update the Documention on the use of
the SPCR.

[v2]: Don't return an error in the baud_rate check of acpi_parse_spcr().
Keep ACPI_SPCR_TABLE selected for ARM64.  Fix 8-bit port access width
mmio value.  Move baud rate check earlier.

Signed-off-by: Prarit Bhargava <prarit@redhat.com>
Cc: linux-doc@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
Cc: linux-arm-kernel@lists.infradead.org
Cc: linux-pm@vger.kernel.org
Cc: linux-acpi@vger.kernel.org
Cc: linux-serial@vger.kernel.org
Cc: Bhupesh Sharma <bhsharma@redhat.com>
Cc: Lv Zheng <lv.zheng@intel.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: "H. Peter Anvin" <hpa@zytor.com>
Cc: x86@kernel.org
Cc: Jonathan Corbet <corbet@lwn.net>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Will Deacon <will.deacon@arm.com>
Cc: "Rafael J. Wysocki" <rjw@rjwysocki.net>
Cc: Timur Tabi <timur@codeaurora.org>
---
 Documentation/admin-guide/kernel-parameters.txt |   6 +-
 arch/arm64/kernel/acpi.c                        | 128 ++++++++++++++++-
 drivers/acpi/Kconfig                            |   7 +-
 drivers/acpi/spcr.c                             | 175 ++++++------------------
 drivers/tty/serial/earlycon.c                   |  15 +-
 include/linux/acpi.h                            |  11 +-
 include/linux/serial_core.h                     |   2 -
 7 files changed, 184 insertions(+), 160 deletions(-)

diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
index 6571fbfdb2a1..0d173289c67e 100644
--- a/Documentation/admin-guide/kernel-parameters.txt
+++ b/Documentation/admin-guide/kernel-parameters.txt
@@ -914,9 +914,9 @@
 
 	earlycon=	[KNL] Output early console device and options.
 
-			When used with no options, the early console is
-			determined by the stdout-path property in device
-			tree's chosen node.
+			[ARM64] The early console is determined by the
+			stdout-path property in device tree's chosen node,
+			or determined by the ACPI SPCR table.
 
 		cdns,<addr>[,options]
 			Start an early, polled-mode console on a Cadence
diff --git a/arch/arm64/kernel/acpi.c b/arch/arm64/kernel/acpi.c
index b3162715ed78..b3e33bbdf3b7 100644
--- a/arch/arm64/kernel/acpi.c
+++ b/arch/arm64/kernel/acpi.c
@@ -25,7 +25,6 @@
 #include <linux/memblock.h>
 #include <linux/of_fdt.h>
 #include <linux/smp.h>
-#include <linux/serial_core.h>
 
 #include <asm/cputype.h>
 #include <asm/cpu_ops.h>
@@ -177,6 +176,128 @@ static int __init acpi_fadt_sanity_check(void)
 	return ret;
 }
 
+/*
+ * Erratum 44 for QDF2432v1 and QDF2400v1 SoCs describes the BUSY bit as
+ * occasionally getting stuck as 1. To avoid the potential for a hang, check
+ * TXFE == 0 instead of BUSY == 1. This may not be suitable for all UART
+ * implementations, so only do so if an affected platform is detected in
+ * acpi_parse_spcr().
+ */
+bool qdf2400_e44_present;
+EXPORT_SYMBOL(qdf2400_e44_present);
+
+/*
+ * Some Qualcomm Datacenter Technologies SoCs have a defective UART BUSY bit.
+ * Detect them by examining the OEM fields in the SPCR header, similar to PCI
+ * quirk detection in pci_mcfg.c.
+ */
+static bool qdf2400_erratum_44_present(struct acpi_table_header *h)
+{
+	if (memcmp(h->oem_id, "QCOM  ", ACPI_OEM_ID_SIZE))
+		return false;
+
+	if (!memcmp(h->oem_table_id, "QDF2432 ", ACPI_OEM_TABLE_ID_SIZE))
+		return true;
+
+	if (!memcmp(h->oem_table_id, "QDF2400 ", ACPI_OEM_TABLE_ID_SIZE) &&
+			h->oem_revision == 1)
+		return true;
+
+	return false;
+}
+
+/*
+ * APM X-Gene v1 and v2 UART hardware is an 16550 like device but has its
+ * register aligned to 32-bit. In addition, the BIOS also encoded the
+ * access width to be 8 bits. This function detects this errata condition.
+ */
+static bool xgene_8250_erratum_present(struct acpi_table_spcr *tb)
+{
+	bool xgene_8250 = false;
+
+	if (tb->interface_type != ACPI_DBG2_16550_COMPATIBLE)
+		return false;
+
+	if (memcmp(tb->header.oem_id, "APMC0D", ACPI_OEM_ID_SIZE) &&
+	    memcmp(tb->header.oem_id, "HPE   ", ACPI_OEM_ID_SIZE))
+		return false;
+
+	if (!memcmp(tb->header.oem_table_id, "XGENESPC",
+	    ACPI_OEM_TABLE_ID_SIZE) && tb->header.oem_revision == 0)
+		xgene_8250 = true;
+
+	if (!memcmp(tb->header.oem_table_id, "ProLiant",
+	    ACPI_OEM_TABLE_ID_SIZE) && tb->header.oem_revision == 1)
+		xgene_8250 = true;
+
+	return xgene_8250;
+}
+
+int acpi_arch_setup_console(struct acpi_table_spcr *table,
+			    char *opts, char *uart, char *iotype,
+			    int baud_rate, bool earlycon)
+{
+	if (table->header.revision < 2) {
+		pr_err("wrong table version\n");
+		return -ENOENT;
+	}
+
+	switch (table->interface_type) {
+	case ACPI_DBG2_ARM_SBSA_32BIT:
+		snprintf(iotype, ACPI_SPCR_BUF_SIZE, "mmio32");
+		/* fall through */
+	case ACPI_DBG2_ARM_PL011:
+	case ACPI_DBG2_ARM_SBSA_GENERIC:
+	case ACPI_DBG2_BCM2835:
+		snprintf(uart, ACPI_SPCR_BUF_SIZE, "pl011");
+		break;
+	default:
+		if (strlen(uart) == 0)
+			return -ENOENT;
+	}
+
+	/*
+	 * If the E44 erratum is required, then we need to tell the pl011
+	 * driver to implement the work-around.
+	 *
+	 * The global variable is used by the probe function when it
+	 * creates the UARTs, whether or not they're used as a console.
+	 *
+	 * If the user specifies "traditional" earlycon, the qdf2400_e44
+	 * console name matches the EARLYCON_DECLARE() statement, and
+	 * SPCR is not used.  Parameter "earlycon" is false.
+	 *
+	 * If the user specifies "SPCR" earlycon, then we need to update
+	 * the console name so that it also says "qdf2400_e44".  Parameter
+	 * "earlycon" is true.
+	 *
+	 * For consistency, if we change the console name, then we do it
+	 * for everyone, not just earlycon.
+	 */
+	if (qdf2400_erratum_44_present(&table->header)) {
+		qdf2400_e44_present = true;
+		if (earlycon)
+			snprintf(uart, ACPI_SPCR_BUF_SIZE, "qdf2400_e44");
+	}
+
+	if (xgene_8250_erratum_present(table)) {
+		snprintf(iotype, ACPI_SPCR_BUF_SIZE, "mmio32");
+
+		/* for xgene v1 and v2 we don't know the clock rate of the
+		 * UART so don't attempt to change to the baud rate state
+		 * in the table because driver cannot calculate the dividers
+		 */
+		snprintf(opts, ACPI_SPCR_OPTS_SIZE, "%s,%s,0x%llx", uart,
+			 iotype, table->serial_port.address);
+	} else {
+		snprintf(opts, ACPI_SPCR_OPTS_SIZE, "%s,%s,0x%llx,%d", uart,
+			 iotype, table->serial_port.address, baud_rate);
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL(acpi_arch_setup_console);
+
 /*
  * acpi_boot_table_init() called from setup_arch(), always.
  *	1. find RSDP and get its address, and then find XSDT
@@ -230,10 +351,11 @@ void __init acpi_boot_table_init(void)
 
 done:
 	if (acpi_disabled) {
-		if (earlycon_init_is_deferred)
+		if (console_acpi_spcr_enable)
 			early_init_dt_scan_chosen_stdout();
 	} else {
-		parse_spcr(earlycon_init_is_deferred);
+		/* Always enable the ACPI SPCR console */
+		acpi_parse_spcr(console_acpi_spcr_enable);
 		if (IS_ENABLED(CONFIG_ACPI_BGRT))
 			acpi_table_parse(ACPI_SIG_BGRT, acpi_parse_bgrt);
 	}
diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig
index 46505396869e..9ae98eeada76 100644
--- a/drivers/acpi/Kconfig
+++ b/drivers/acpi/Kconfig
@@ -79,7 +79,12 @@ config ACPI_DEBUGGER_USER
 endif
 
 config ACPI_SPCR_TABLE
-	bool
+	bool "ACPI Serial Port Console Redirection Support"
+	default y if ARM64
+	help
+	  Enable support for Serial Port Console Redirection (SPCR) Table.
+	  This table provides information about the configuration of the
+	  earlycon console.
 
 config ACPI_LPIT
 	bool
diff --git a/drivers/acpi/spcr.c b/drivers/acpi/spcr.c
index 324b35bfe781..f4bb8110e404 100644
--- a/drivers/acpi/spcr.c
+++ b/drivers/acpi/spcr.c
@@ -16,65 +16,18 @@
 #include <linux/kernel.h>
 #include <linux/serial_core.h>
 
-/*
- * Erratum 44 for QDF2432v1 and QDF2400v1 SoCs describes the BUSY bit as
- * occasionally getting stuck as 1. To avoid the potential for a hang, check
- * TXFE == 0 instead of BUSY == 1. This may not be suitable for all UART
- * implementations, so only do so if an affected platform is detected in
- * parse_spcr().
- */
-bool qdf2400_e44_present;
-EXPORT_SYMBOL(qdf2400_e44_present);
-
-/*
- * Some Qualcomm Datacenter Technologies SoCs have a defective UART BUSY bit.
- * Detect them by examining the OEM fields in the SPCR header, similiar to PCI
- * quirk detection in pci_mcfg.c.
- */
-static bool qdf2400_erratum_44_present(struct acpi_table_header *h)
-{
-	if (memcmp(h->oem_id, "QCOM  ", ACPI_OEM_ID_SIZE))
-		return false;
-
-	if (!memcmp(h->oem_table_id, "QDF2432 ", ACPI_OEM_TABLE_ID_SIZE))
-		return true;
-
-	if (!memcmp(h->oem_table_id, "QDF2400 ", ACPI_OEM_TABLE_ID_SIZE) &&
-			h->oem_revision == 1)
-		return true;
-
-	return false;
-}
-
-/*
- * APM X-Gene v1 and v2 UART hardware is an 16550 like device but has its
- * register aligned to 32-bit. In addition, the BIOS also encoded the
- * access width to be 8 bits. This function detects this errata condition.
- */
-static bool xgene_8250_erratum_present(struct acpi_table_spcr *tb)
+int __weak acpi_arch_setup_console(struct acpi_table_spcr *table,
+				   char *opts, char *uart, char *iotype,
+				   int baud_rate, bool earlycon)
 {
-	bool xgene_8250 = false;
-
-	if (tb->interface_type != ACPI_DBG2_16550_COMPATIBLE)
-		return false;
-
-	if (memcmp(tb->header.oem_id, "APMC0D", ACPI_OEM_ID_SIZE) &&
-	    memcmp(tb->header.oem_id, "HPE   ", ACPI_OEM_ID_SIZE))
-		return false;
-
-	if (!memcmp(tb->header.oem_table_id, "XGENESPC",
-	    ACPI_OEM_TABLE_ID_SIZE) && tb->header.oem_revision == 0)
-		xgene_8250 = true;
-
-	if (!memcmp(tb->header.oem_table_id, "ProLiant",
-	    ACPI_OEM_TABLE_ID_SIZE) && tb->header.oem_revision == 1)
-		xgene_8250 = true;
-
-	return xgene_8250;
+	snprintf(opts, ACPI_SPCR_OPTS_SIZE, "%s,%s,0x%llx,%d", uart, iotype,
+		 table->serial_port.address, baud_rate);
+	return 0;
 }
 
+bool console_acpi_spcr_enable __initdata;
 /**
- * parse_spcr() - parse ACPI SPCR table and add preferred console
+ * acpi_parse_spcr() - parse ACPI SPCR table and add preferred console
  *
  * @earlycon: set up earlycon for the console specified by the table
  *
@@ -86,13 +39,13 @@ static bool xgene_8250_erratum_present(struct acpi_table_spcr *tb)
  * from arch initialization code as soon as the DT/ACPI decision is made.
  *
  */
-int __init parse_spcr(bool earlycon)
+int __init acpi_parse_spcr(bool earlycon)
 {
-	static char opts[64];
+	static char opts[ACPI_SPCR_OPTS_SIZE];
+	static char uart[ACPI_SPCR_BUF_SIZE];
+	static char iotype[ACPI_SPCR_BUF_SIZE];
 	struct acpi_table_spcr *table;
 	acpi_status status;
-	char *uart;
-	char *iotype;
 	int baud_rate;
 	int err;
 
@@ -105,48 +58,6 @@ int __init parse_spcr(bool earlycon)
 	if (ACPI_FAILURE(status))
 		return -ENOENT;
 
-	if (table->header.revision < 2) {
-		err = -ENOENT;
-		pr_err("wrong table version\n");
-		goto done;
-	}
-
-	if (table->serial_port.space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) {
-		switch (ACPI_ACCESS_BIT_WIDTH((
-			table->serial_port.access_width))) {
-		default:
-			pr_err("Unexpected SPCR Access Width.  Defaulting to byte size\n");
-		case 8:
-			iotype = "mmio";
-			break;
-		case 16:
-			iotype = "mmio16";
-			break;
-		case 32:
-			iotype = "mmio32";
-			break;
-		}
-	} else
-		iotype = "io";
-
-	switch (table->interface_type) {
-	case ACPI_DBG2_ARM_SBSA_32BIT:
-		iotype = "mmio32";
-		/* fall through */
-	case ACPI_DBG2_ARM_PL011:
-	case ACPI_DBG2_ARM_SBSA_GENERIC:
-	case ACPI_DBG2_BCM2835:
-		uart = "pl011";
-		break;
-	case ACPI_DBG2_16550_COMPATIBLE:
-	case ACPI_DBG2_16550_SUBSET:
-		uart = "uart";
-		break;
-	default:
-		err = -ENOENT;
-		goto done;
-	}
-
 	switch (table->baud_rate) {
 	case 3:
 		baud_rate = 9600;
@@ -165,43 +76,36 @@ int __init parse_spcr(bool earlycon)
 		goto done;
 	}
 
-	/*
-	 * If the E44 erratum is required, then we need to tell the pl011
-	 * driver to implement the work-around.
-	 *
-	 * The global variable is used by the probe function when it
-	 * creates the UARTs, whether or not they're used as a console.
-	 *
-	 * If the user specifies "traditional" earlycon, the qdf2400_e44
-	 * console name matches the EARLYCON_DECLARE() statement, and
-	 * SPCR is not used.  Parameter "earlycon" is false.
-	 *
-	 * If the user specifies "SPCR" earlycon, then we need to update
-	 * the console name so that it also says "qdf2400_e44".  Parameter
-	 * "earlycon" is true.
-	 *
-	 * For consistency, if we change the console name, then we do it
-	 * for everyone, not just earlycon.
-	 */
-	if (qdf2400_erratum_44_present(&table->header)) {
-		qdf2400_e44_present = true;
-		if (earlycon)
-			uart = "qdf2400_e44";
+	switch (table->interface_type) {
+	case ACPI_DBG2_16550_COMPATIBLE:
+	case ACPI_DBG2_16550_SUBSET:
+		snprintf(uart, ACPI_SPCR_BUF_SIZE, "uart");
+		break;
+	default:
+		break;
 	}
 
-	if (xgene_8250_erratum_present(table)) {
-		iotype = "mmio32";
+	if (table->serial_port.space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) {
+		u8 width = ACPI_ACCESS_BIT_WIDTH((
+					table->serial_port.access_width));
+		switch (width) {
+		default:
+			pr_err("Unexpected SPCR Access Width.  Defaulting to byte size\n");
+		case 8:
+			snprintf(iotype, ACPI_SPCR_BUF_SIZE, "mmio");
+			break;
+		case 16:
+		case 32:
+			snprintf(iotype, ACPI_SPCR_BUF_SIZE, "mmio%d", width);
+			break;
+		}
+	} else
+		snprintf(iotype, ACPI_SPCR_BUF_SIZE, "io");
 
-		/* for xgene v1 and v2 we don't know the clock rate of the
-		 * UART so don't attempt to change to the baud rate state
-		 * in the table because driver cannot calculate the dividers
-		 */
-		snprintf(opts, sizeof(opts), "%s,%s,0x%llx", uart, iotype,
-			 table->serial_port.address);
-	} else {
-		snprintf(opts, sizeof(opts), "%s,%s,0x%llx,%d", uart, iotype,
-			 table->serial_port.address, baud_rate);
-	}
+	err = acpi_arch_setup_console(table, opts, uart, iotype, baud_rate,
+				      earlycon);
+	if (err)
+		goto done;
 
 	pr_info("console: %s\n", opts);
 
@@ -209,7 +113,6 @@ int __init parse_spcr(bool earlycon)
 		setup_earlycon(opts);
 
 	err = add_preferred_console(uart, 0, opts + strlen(uart) + 1);
-
 done:
 	acpi_put_table((struct acpi_table_header *)table);
 	return err;
diff --git a/drivers/tty/serial/earlycon.c b/drivers/tty/serial/earlycon.c
index 4c8b80f1c688..b22afb62c7a3 100644
--- a/drivers/tty/serial/earlycon.c
+++ b/drivers/tty/serial/earlycon.c
@@ -196,26 +196,15 @@ int __init setup_earlycon(char *buf)
 	return -ENOENT;
 }
 
-/*
- * When CONFIG_ACPI_SPCR_TABLE is defined, "earlycon" without parameters in
- * command line does not start DT earlycon immediately, instead it defers
- * starting it until DT/ACPI decision is made.  At that time if ACPI is enabled
- * call parse_spcr(), else call early_init_dt_scan_chosen_stdout()
- */
-bool earlycon_init_is_deferred __initdata;
-
 /* early_param wrapper for setup_earlycon() */
 static int __init param_setup_earlycon(char *buf)
 {
 	int err;
 
-	/*
-	 * Just 'earlycon' is a valid param for devicetree earlycons;
-	 * don't generate a warning from parse_early_params() in that case
-	 */
+	/* Just 'earlycon' is a valid param for devicetree and ACPI SPCR. */
 	if (!buf || !buf[0]) {
 		if (IS_ENABLED(CONFIG_ACPI_SPCR_TABLE)) {
-			earlycon_init_is_deferred = true;
+			console_acpi_spcr_enable = true;
 			return 0;
 		} else if (!buf) {
 			return early_init_dt_scan_chosen_stdout();
diff --git a/include/linux/acpi.h b/include/linux/acpi.h
index dc1ebfeeb5ec..875d7327d91c 100644
--- a/include/linux/acpi.h
+++ b/include/linux/acpi.h
@@ -1241,10 +1241,17 @@ static inline bool acpi_has_watchdog(void) { return false; }
 #endif
 
 #ifdef CONFIG_ACPI_SPCR_TABLE
+#define ACPI_SPCR_OPTS_SIZE 64
+#define ACPI_SPCR_BUF_SIZE 32
 extern bool qdf2400_e44_present;
-int parse_spcr(bool earlycon);
+extern bool console_acpi_spcr_enable __initdata;
+extern int acpi_arch_setup_console(struct acpi_table_spcr *table,
+				   char *opts, char *uart, char *iotype,
+				   int baud_rate, bool earlycon);
+int acpi_parse_spcr(bool earlycon);
 #else
-static inline int parse_spcr(bool earlycon) { return 0; }
+static const bool console_acpi_spcr_enable;
+static inline int acpi_parse_spcr(bool earlycon) { return 0; }
 #endif
 
 #if IS_ENABLED(CONFIG_ACPI_GENERIC_GSI)
diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h
index 37b044e78333..abfffb4b1c37 100644
--- a/include/linux/serial_core.h
+++ b/include/linux/serial_core.h
@@ -376,10 +376,8 @@ extern int of_setup_earlycon(const struct earlycon_id *match,
 			     const char *options);
 
 #ifdef CONFIG_SERIAL_EARLYCON
-extern bool earlycon_init_is_deferred __initdata;
 int setup_earlycon(char *buf);
 #else
-static const bool earlycon_init_is_deferred;
 static inline int setup_earlycon(char *buf) { return 0; }
 #endif
 
-- 
2.15.0.rc0.39.g2f0e14e64

^ permalink raw reply related

* [PATCH v2 0/2] acpi, x86: Add SPCR table support
From: Prarit Bhargava @ 2017-12-11 15:50 UTC (permalink / raw)
  To: linux-acpi
  Cc: Prarit Bhargava, linux-doc, linux-kernel, linux-arm-kernel,
	linux-pm, linux-serial, Bhupesh Sharma, Lv Zheng, Thomas Gleixner,
	Ingo Molnar, H. Peter Anvin, x86, Jonathan Corbet,
	Catalin Marinas, Will Deacon, Rafael J. Wysocki, Timur Tabi

The SPCR (Serial Port Console Redirection) Table provides information
about the configuration of the serial port.  This information can be used to
configure the early console.

SPCR support was added for ARM64 and is made available across all arches
in this patchset.  The first patch adds a weak per-arch configuration function
and moves the SPCR code into ACPI.  The second patch adds support to x86.

The existing behaviour on ARM64 is maintained.  If the SPCR exists the
earlycon and console are automatically configured.

The existing default behaviour on x86 is also maintained.  If no console or
earlycon parameter is defined and the SPCR exists, the serial port is not
configured.  If the earlycon parameter is used both the early console
and the console are configured using the data from the SPCR.

Additional testing (requested by Timur): On Gigabyte (no quirks), Qualcomm
Amberwing systems to test Qualcomm quirks, HPE Mantis system to test xgene
quirks.  Tested several x86 systems with and without a SPCR to confirm
no changes in default behaviour.

[v2]: See 1/2 for code changes.

Signed-off-by: Prarit Bhargava <prarit@redhat.com>
Cc: linux-doc@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
Cc: linux-arm-kernel@lists.infradead.org
Cc: linux-pm@vger.kernel.org
Cc: linux-acpi@vger.kernel.org
Cc: linux-serial@vger.kernel.org
Cc: Bhupesh Sharma <bhsharma@redhat.com>
Cc: Lv Zheng <lv.zheng@intel.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: "H. Peter Anvin" <hpa@zytor.com>
Cc: x86@kernel.org
Cc: Jonathan Corbet <corbet@lwn.net>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Will Deacon <will.deacon@arm.com>
Cc: "Rafael J. Wysocki" <rjw@rjwysocki.net>
Cc: Timur Tabi <timur@codeaurora.org>

Prarit Bhargava (2):
  acpi, spcr: Make SPCR avialable to other architectures
  acpi, x86: Use SPCR table for earlycon on x86

 Documentation/admin-guide/kernel-parameters.txt |   9 +-
 arch/arm64/kernel/acpi.c                        | 128 ++++++++++++++++-
 arch/x86/kernel/acpi/boot.c                     |   4 +
 drivers/acpi/Kconfig                            |   7 +-
 drivers/acpi/spcr.c                             | 180 ++++++------------------
 drivers/tty/serial/earlycon.c                   |  15 +-
 include/linux/acpi.h                            |  14 +-
 include/linux/serial_core.h                     |   2 -
 8 files changed, 198 insertions(+), 161 deletions(-)

-- 
2.15.0.rc0.39.g2f0e14e64


^ permalink raw reply

* Re: [PATCH 0/2] acpi, x86: Add SPCR table support
From: Ingo Molnar @ 2017-12-11 14:42 UTC (permalink / raw)
  To: Prarit Bhargava
  Cc: linux-acpi, linux-doc, linux-kernel, linux-arm-kernel, linux-pm,
	linux-serial, Bhupesh Sharma, Lv Zheng, Thomas Gleixner,
	Ingo Molnar, H. Peter Anvin, x86, Jonathan Corbet,
	Catalin Marinas, Will Deacon, Rafael J. Wysocki
In-Reply-To: <f078ada7-1e30-41cc-28dc-077ed2a5986d@redhat.com>


* Prarit Bhargava <prarit@redhat.com> wrote:

> If I disable "Serial Port Console Debug" in my BIOS I still see the SPCR configured:
> 
> [root@prarit-lab ~]# dmesg | grep SPCR
> [    0.000000] ACPI: SPCR 0x0000000069031000 000050 (v01
> 00000000      00000000)
> 
> AFAICT the SPCR is always enabled on some systems.

Fair enough.

> > If so then we should pick up that serial console configuration and activate it, 
> > regardless of any kernel boot options!
> 
> I'm worried about someone who doesn't want a console on ttyS0 suddenly ending up
> with one.  The SPCR could contain incorrect data, etc.

Yeah, that's not good.

Thanks,

	Ingo

^ permalink raw reply

* Re: [PATCH v3 32/33] irqchip: Andestech Internal Vector Interrupt Controller driver
From: Marc Zyngier @ 2017-12-11  9:16 UTC (permalink / raw)
  To: Greentime Hu, greentime-MUIXKm3Oiri1Z/+hSey0Gg,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, arnd-r2nGTMty4D4,
	linux-arch-u79uwXL29TY76Z2rM5mHXA, tglx-hfZtesqFncYOwBW4kG4KsQ,
	jason-NLaQJdtUoK4Be96aLqz0jA, robh+dt-DgEjT+Ai2ygdnm+yROfE0A,
	netdev-u79uwXL29TY76Z2rM5mHXA, deanbo422-Re5JQEeQqe8AvxtiuMwx3w,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	viro-RmSDqhL/yNMiFSDQTTA3OLVCufUGDwFn,
	dhowells-H+wXaHxf7aLQT0dZR+AlfA, will.deacon-5wv7dgnIgG8,
	daniel.lezcano-QSEj5FYQhm4dnm+yROfE0A,
	linux-serial-u79uwXL29TY76Z2rM5mHXA,
	geert.uytterhoeven-Re5JQEeQqe8AvxtiuMwx3w,
	linus.walleij-QSEj5FYQhm4dnm+yROfE0A, mark.rutland-5wv7dgnIgG8,
	greg-U8xfFu+wG4EAvxtiuMwx3w
  Cc: Rick Chen
In-Reply-To: <4fb7bd1cd2619287061fd68a38a774c8aef7dbe9.1512723245.git.green.hu-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>

On 08/12/17 09:12, Greentime Hu wrote:
> From: Greentime Hu <greentime-MUIXKm3Oiri1Z/+hSey0Gg@public.gmane.org>
> 
> This patch adds the Andestech Internal Vector Interrupt Controller
> driver. You can find the spec here. Ch4.9 of AndeStar SPA V3 Manual.
> http://www.andestech.com/product.php?cls=9
> 
> Signed-off-by: Rick Chen <rick-MUIXKm3Oiri1Z/+hSey0Gg@public.gmane.org>
> Signed-off-by: Greentime Hu <greentime-MUIXKm3Oiri1Z/+hSey0Gg@public.gmane.org>

Reviewed-by: Marc Zyngier <marc.zyngier-5wv7dgnIgG8@public.gmane.org>

Once there is an agreement on this series being fit for mainline, let me
know how you want to get this merged (either as a whole series, or with
this driver going through the irq tree).

Thanks,

	M.
-- 
Jazz is not dead. It just smells funny...
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox