mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Graeme Gregory <gg@slimlogic.co.uk>
To: Aleksey Makarov <aleksey.makarov@linaro.org>
Cc: linux-acpi@vger.kernel.org, Russell King <linux@arm.linux.org.uk>,
	Graeme Gregory <graeme.gregory@linaro.org>,
	Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	"Rafael J . Wysocki" <rjw@rjwysocki.net>,
	linux-kernel@vger.kernel.org,
	Leif Lindholm <leif.lindholm@linaro.org>,
	linux-serial@vger.kernel.org,
	Catalin Marinas <catalin.marinas@arm.com>,
	Will Deacon <will.deacon@arm.com>,
	linux-arm-kernel@lists.infradead.org, Len Brown <lenb@kernel.org>
Subject: Re: [PATCH 2/3] ACPI: parse SPCR and enable matching console
Date: Mon, 1 Feb 2016 09:01:26 +0000	[thread overview]
Message-ID: <20160201090126.GA18693@xora-haswell.xora.org.uk> (raw)
In-Reply-To: <1453722324-22407-3-git-send-email-aleksey.makarov@linaro.org>

On Mon, Jan 25, 2016 at 05:45:22PM +0600, Aleksey Makarov wrote:
> 'ARM Server Base Boot Requiremets' [1] mention SPCR
> (Serial Port Console Redirection Table) [2] as a mandatory ACPI table
> that specifies the configuration of serial console.
> 
> Parse this table and check if any registered console match
> the description.  If it does, enable that console.
> 
> To implement that, introduce a new member
> int (*acpi_match)(struct console *, struct acpi_table_spcr *)
> of struct console.  It allows drivers to check if they provide
> a matching console device.
> 

Fails to compile on x86

kernel/built-in.o: In function `register_console':
(.text+0x48cba): undefined reference to `console_acpi_match'
Makefile:929: recipe for target 'vmlinux' failed
make: *** [vmlinux] Error 1

Because CONFIG_ACPI_SPCR_TABLE is never set.

Graeme


> [1] http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.den0044a/index.html
> [2] http://msdn.microsoft.com/en-us/library/windows/hardware/dn639131(v=vs.85).aspx
> 
> Signed-off-by: Aleksey Makarov <aleksey.makarov@linaro.org>
> ---
>  arch/arm64/Kconfig      |  1 +
>  drivers/acpi/Kconfig    |  3 ++
>  drivers/acpi/Makefile   |  1 +
>  drivers/acpi/spcr.c     | 85 +++++++++++++++++++++++++++++++++++++++++++++++++
>  include/linux/console.h | 12 +++++++
>  kernel/printk/printk.c  | 82 +++++++++++++++++++++++++++++++++++++----------
>  6 files changed, 167 insertions(+), 17 deletions(-)
>  create mode 100644 drivers/acpi/spcr.c
> 
> diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
> index 573bebc..bf31e3c 100644
> --- a/arch/arm64/Kconfig
> +++ b/arch/arm64/Kconfig
> @@ -4,6 +4,7 @@ config ARM64
>  	select ACPI_GENERIC_GSI if ACPI
>  	select ACPI_PCI_HOST_GENERIC if ACPI
>  	select ACPI_REDUCED_HARDWARE_ONLY if ACPI
> +	select ACPI_SPCR_TABLE if ACPI
>  	select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE
>  	select ARCH_HAS_ELF_RANDOMIZE
>  	select ARCH_HAS_GCOV_PROFILE_ALL
> diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig
> index e315061..142a338 100644
> --- a/drivers/acpi/Kconfig
> +++ b/drivers/acpi/Kconfig
> @@ -60,6 +60,9 @@ config ACPI_CCA_REQUIRED
>  config IORT_TABLE
>  	bool
>  
> +config ACPI_SPCR_TABLE
> +	bool
> +
>  config ACPI_DEBUGGER
>  	bool "AML debugger interface (EXPERIMENTAL)"
>  	select ACPI_DEBUG
> diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile
> index 265eb90..8316859 100644
> --- a/drivers/acpi/Makefile
> +++ b/drivers/acpi/Makefile
> @@ -81,6 +81,7 @@ obj-$(CONFIG_ACPI_CUSTOM_METHOD)+= custom_method.o
>  obj-$(CONFIG_ACPI_BGRT)		+= bgrt.o
>  obj-$(CONFIG_ACPI_CPPC_LIB)	+= cppc_acpi.o
>  obj-$(CONFIG_IORT_TABLE) 	+= iort.o
> +obj-$(CONFIG_ACPI_SPCR_TABLE)	+= spcr.o
>  
>  # processor has its own "processor." module_param namespace
>  processor-y			:= processor_driver.o
> diff --git a/drivers/acpi/spcr.c b/drivers/acpi/spcr.c
> new file mode 100644
> index 0000000..ccb19a0
> --- /dev/null
> +++ b/drivers/acpi/spcr.c
> @@ -0,0 +1,85 @@
> +/*
> + * Copyright (c) 2012, Intel Corporation
> + * Copyright (c) 2015, Red Hat, Inc.
> + * Copyright (c) 2015, 2016 Linaro Ltd.
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + *
> + */
> +
> +#define pr_fmt(fmt) "ACPI: SPCR: " fmt
> +
> +#include <linux/acpi.h>
> +#include <linux/console.h>
> +#include <linux/kernel.h>
> +
> +static struct acpi_table_spcr *spcr_table;
> +
> +int console_acpi_match(struct console *c, char **options)
> +{
> +	int err;
> +
> +	if (!c->acpi_match)
> +		return -ENODEV;
> +
> +	if (!spcr_table)
> +		return -EAGAIN;
> +
> +	err = c->acpi_match(c, spcr_table);
> +	if (err < 0)
> +		return err;
> +
> +	if (options) {
> +		switch (spcr_table->baud_rate) {
> +		case 3:
> +			*options = "9600";
> +			break;
> +		case 4:
> +			*options = "19200";
> +			break;
> +		case 6:
> +			*options = "57600";
> +			break;
> +		case 7:
> +			*options = "115200";
> +			break;
> +		default:
> +			*options = "";
> +			break;
> +		}
> +	}
> +
> +	return err;
> +}
> +
> +static int __init spcr_table_detect(void)
> +{
> +	struct acpi_table_header *table;
> +	acpi_status status;
> +
> +	if (acpi_disabled)
> +		return -ENODEV;
> +
> +	status = acpi_get_table(ACPI_SIG_SPCR, 0, &table);
> +	if (ACPI_FAILURE(status)) {
> +		const char *msg = acpi_format_exception(status);
> +
> +		pr_err("Failed to get table, %s\n", msg);
> +		return -EINVAL;
> +	}
> +
> +	if (table->revision < 2)
> +		return -EOPNOTSUPP;
> +
> +	spcr_table = (struct acpi_table_spcr *)table;
> +
> +	pr_info("Console at 0x%016llx\n", spcr_table->serial_port.address);
> +
> +	acpi_register_consoles_try_again();
> +
> +	return 0;
> +}
> +
> +arch_initcall(spcr_table_detect);
> diff --git a/include/linux/console.h b/include/linux/console.h
> index bd19434..94d0bd8 100644
> --- a/include/linux/console.h
> +++ b/include/linux/console.h
> @@ -117,6 +117,7 @@ static inline int con_debug_leave(void)
>  #define CON_BRL		(32) /* Used for a braille device */
>  #define CON_EXTENDED	(64) /* Use the extended output format a la /dev/kmsg */
>  
> +struct acpi_table_spcr;
>  struct console {
>  	char	name[16];
>  	void	(*write)(struct console *, const char *, unsigned);
> @@ -125,6 +126,7 @@ struct console {
>  	void	(*unblank)(void);
>  	int	(*setup)(struct console *, char *);
>  	int	(*match)(struct console *, char *name, int idx, char *options);
> +	int	(*acpi_match)(struct console *, struct acpi_table_spcr *);
>  	short	flags;
>  	short	index;
>  	int	cflag;
> @@ -132,6 +134,16 @@ struct console {
>  	struct	 console *next;
>  };
>  
> +#ifdef CONFIG_ACPI
> +int console_acpi_match(struct console *c, char **options);
> +#else
> +static inline int console_acpi_match(struct console *c, char **options)
> +{
> +	return -ENODEV;
> +}
> +#endif
> +void acpi_register_consoles_try_again(void);
> +
>  /*
>   * for_each_console() allows you to iterate on each console
>   */
> diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c
> index 37e531f..3cf8cba 100644
> --- a/kernel/printk/printk.c
> +++ b/kernel/printk/printk.c
> @@ -2430,6 +2430,25 @@ static int __init keep_bootcon_setup(char *str)
>  
>  early_param("keep_bootcon", keep_bootcon_setup);
>  
> +static DEFINE_MUTEX(acpi_consoles_delayed_mutex);
> +static struct console *acpi_consoles_delayed;
> +
> +void acpi_register_consoles_try_again(void)
> +{
> +	mutex_lock(&acpi_consoles_delayed_mutex);
> +	while (acpi_consoles_delayed) {
> +
> +		struct console *c = acpi_consoles_delayed;
> +
> +		acpi_consoles_delayed = acpi_consoles_delayed->next;
> +
> +		mutex_unlock(&acpi_consoles_delayed_mutex);
> +		register_console(c);
> +		mutex_lock(&acpi_consoles_delayed_mutex);
> +	}
> +	mutex_unlock(&acpi_consoles_delayed_mutex);
> +}
> +
>  /*
>   * The console driver calls this routine during kernel initialization
>   * to register the console printing procedure with printk() and to
> @@ -2538,8 +2557,30 @@ void register_console(struct console *newcon)
>  		break;
>  	}
>  
> -	if (!(newcon->flags & CON_ENABLED))
> -		return;
> +	if (!(newcon->flags & CON_ENABLED)) {
> +		char *opts;
> +		int err;
> +
> +		if (newcon->index < 0)
> +			newcon->index = 0;
> +
> +		err = console_acpi_match(newcon, &opts);
> +
> +		if (err == -EAGAIN) {
> +			mutex_lock(&acpi_consoles_delayed_mutex);
> +			newcon->next = acpi_consoles_delayed;
> +			acpi_consoles_delayed = newcon;
> +			mutex_unlock(&acpi_consoles_delayed_mutex);
> +			return;
> +		} else if (err < 0) {
> +			return;
> +		} else {
> +			if (newcon->setup && newcon->setup(newcon, opts) != 0)
> +				return;
> +			newcon->flags |= CON_ENABLED | CON_CONSDEV;
> +			preferred_console = true;
> +		}
> +	}
>  
>  	/*
>  	 * If we have a bootconsole, and are switching to a real console,
> @@ -2612,34 +2653,41 @@ void register_console(struct console *newcon)
>  }
>  EXPORT_SYMBOL(register_console);
>  
> +static int delete_from_console_list(struct console **list, struct console *c)
> +{
> +	while (*list) {
> +		struct console *cur = *list;
> +
> +		if (cur == c) {
> +			*list = cur->next;
> +			return 0;
> +		}
> +		list = &cur->next;
> +	}
> +	return 1;
> +}
> +
>  int unregister_console(struct console *console)
>  {
> -        struct console *a, *b;
>  	int res;
>  
>  	pr_info("%sconsole [%s%d] disabled\n",
>  		(console->flags & CON_BOOT) ? "boot" : "" ,
>  		console->name, console->index);
>  
> +	mutex_lock(&acpi_consoles_delayed_mutex);
> +	res = delete_from_console_list(&acpi_consoles_delayed, console);
> +	mutex_unlock(&acpi_consoles_delayed_mutex);
> +	if (res == 0)
> +		return res;
> +
>  	res = _braille_unregister_console(console);
>  	if (res)
>  		return res;
>  
> -	res = 1;
>  	console_lock();
> -	if (console_drivers == console) {
> -		console_drivers=console->next;
> -		res = 0;
> -	} else if (console_drivers) {
> -		for (a=console_drivers->next, b=console_drivers ;
> -		     a; b=a, a=b->next) {
> -			if (a == console) {
> -				b->next = a->next;
> -				res = 0;
> -				break;
> -			}
> -		}
> -	}
> +
> +	res = delete_from_console_list(&console_drivers, console);
>  
>  	if (!res && (console->flags & CON_EXTENDED))
>  		nr_ext_console_drivers--;
> -- 
> 2.7.0
> 
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

  parent reply	other threads:[~2016-02-01  9:01 UTC|newest]

Thread overview: 31+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-01-25 11:45 [PATCH 0/3] ACPI: parse the SPCR table Aleksey Makarov
2016-01-25 11:45 ` [PATCH 1/3] printk: make preferred_console local static bool Aleksey Makarov
2016-01-25 12:45   ` Joe Perches
2016-01-25 12:51     ` Aleksey Makarov
2016-01-25 13:23       ` Joe Perches
2016-01-25 13:28         ` Aleksey Makarov
2016-01-25 16:14           ` Peter Hurley
2016-01-25 14:24   ` Andy Shevchenko
2016-01-25 14:55     ` Aleksey Makarov
2016-01-25 11:45 ` [PATCH 2/3] ACPI: parse SPCR and enable matching console Aleksey Makarov
2016-01-25 14:14   ` Andy Shevchenko
2016-01-25 15:07     ` Aleksey Makarov
2016-01-25 16:32   ` Peter Hurley
2016-01-27 13:57     ` Aleksey Makarov
2016-01-28  0:45       ` Peter Hurley
2016-01-28 13:23         ` Aleksey Makarov
2016-01-28 19:40           ` Peter Hurley
2016-02-01  9:01   ` Graeme Gregory [this message]
2016-02-01  9:13     ` Graeme Gregory
2016-01-25 11:45 ` [PATCH 3/3] serial: pl011: add acpi_match for amba-pl011.c Aleksey Makarov
2016-01-25 14:21   ` Andy Shevchenko
2016-01-25 14:22     ` Andy Shevchenko
2016-01-25 15:08       ` Aleksey Makarov
2016-01-25 16:11 ` [PATCH 0/3] ACPI: parse the SPCR table Peter Hurley
2016-01-27 12:17   ` Aleksey Makarov
2016-01-27 13:45     ` One Thousand Gnomes
2016-02-01  5:46       ` Jon Masters
2016-02-10 23:39     ` Al Stone
2016-03-03 20:08       ` Peter Hurley
     [not found]         ` <67709E22-E82E-40BA-A271-2107608F4EF3@redhat.com>
2016-03-04 19:34           ` Peter Hurley
2016-03-04 20:03             ` Peter Hurley

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20160201090126.GA18693@xora-haswell.xora.org.uk \
    --to=gg@slimlogic.co.uk \
    --cc=aleksey.makarov@linaro.org \
    --cc=catalin.marinas@arm.com \
    --cc=graeme.gregory@linaro.org \
    --cc=gregkh@linuxfoundation.org \
    --cc=leif.lindholm@linaro.org \
    --cc=lenb@kernel.org \
    --cc=linux-acpi@vger.kernel.org \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-serial@vger.kernel.org \
    --cc=linux@arm.linux.org.uk \
    --cc=rjw@rjwysocki.net \
    --cc=will.deacon@arm.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®