All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Rafael J. Wysocki" <rjw@sisk.pl>
To: Myron Stowe <myron.stowe@redhat.com>
Cc: lenb@kernel.org, linux-acpi@vger.kernel.org,
	ying.huang@intel.com, bhelgaas@google.com
Subject: Re: [PATCH 2/2] ACPI: Convert acpi_pre_map_gar()/acpi_atomic_read() and remove ./drivers/acpi/atomicio.[ch]
Date: Sun, 6 Nov 2011 14:05:09 +0100	[thread overview]
Message-ID: <201111061405.09686.rjw@sisk.pl> (raw)
In-Reply-To: <20110929215920.21126.27856.stgit@amt.stowe>

On Thursday, September 29, 2011, Myron Stowe wrote:
> From: Myron Stowe <mstowe@redhat.com>
> 
> APEI needs memory access in interrupt context.  The obvious choice is
> acpi_read(), but originally it couldn't be used in interrupt context
> because it makes temporary mappings with ioremap().  Therefore, we added
> drivers/acpi/atomicio.c, which provides:
> 	acpi_pre_map_gar()      <-- ioremap in process context
>         acpi_atomic_read()      <-- memory access in interrupt context
>         acpi_post_unmap_gar()   <-- iounmap
> 
> Later we added acpi_os_map_generic_address() (2971852) and enhanced
> acpi_read() so it works in interrupt context as long as the address has
> been previously mapped (620242a).  Now this sequence:
>         acpi_os_map_generic_address()   <-- ioremap in process context
>         acpi_read()                     <-- now OK in interrupt context
>         acpi_os_unmap_generic_address()
> is equivalent to what atomicio.c provides.
> 
> 
> This patch converts APEI to use the existing calls within osl.c and the
> CA, based on the re-factoring that was done in an earlier patch series -
> http://marc.info/?l=linux-acpi&m=128769263327206&w=2
> 	acpi_pre_map_gar()	-->  acpi_os_map_generic_address()
> 	acpi_post_unmap_gar()	-->  acpi_os_unmap_generic_address()
> 	acpi_atomic_read()	-->  acpi_read()
> 	acpi_atomic_write()	-->  acpi_write()
> and removes atomicio.[ch].
> 
> Signed-off-by: Myron Stowe <myron.stowe@redhat.com>

Makes sense to me.

Reviewed-by: Rafael J. Wysocki <rjw@sisk.pl>

> ---
> 
>  drivers/acpi/Makefile         |    1 
>  drivers/acpi/apei/apei-base.c |   12 +
>  drivers/acpi/apei/ghes.c      |   10 +
>  drivers/acpi/atomicio.c       |  365 -----------------------------------------
>  include/acpi/atomicio.h       |   10 -
>  5 files changed, 11 insertions(+), 387 deletions(-)
>  delete mode 100644 drivers/acpi/atomicio.c
>  delete mode 100644 include/acpi/atomicio.h
> 
> diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile
> index ecb26b4..e7c1d0f 100644
> --- a/drivers/acpi/Makefile
> +++ b/drivers/acpi/Makefile
> @@ -19,7 +19,6 @@ obj-y				+= acpi.o \
>  
>  # All the builtin files are in the "acpi." module_param namespace.
>  acpi-y				+= osl.o utils.o reboot.o
> -acpi-y				+= atomicio.o
>  
>  # sleep related files
>  acpi-y				+= wakeup.o
> diff --git a/drivers/acpi/apei/apei-base.c b/drivers/acpi/apei/apei-base.c
> index 6154036..2ea95ec 100644
> --- a/drivers/acpi/apei/apei-base.c
> +++ b/drivers/acpi/apei/apei-base.c
> @@ -34,13 +34,13 @@
>  #include <linux/module.h>
>  #include <linux/init.h>
>  #include <linux/acpi.h>
> +#include <linux/acpi_io.h>
>  #include <linux/slab.h>
>  #include <linux/io.h>
>  #include <linux/kref.h>
>  #include <linux/rculist.h>
>  #include <linux/interrupt.h>
>  #include <linux/debugfs.h>
> -#include <acpi/atomicio.h>
>  
>  #include "apei-internal.h"
>  
> @@ -70,7 +70,7 @@ int __apei_exec_read_register(struct acpi_whea_header *entry, u64 *val)
>  {
>  	int rc;
>  
> -	rc = acpi_atomic_read(val, &entry->register_region);
> +	rc = acpi_read(val, &entry->register_region);
>  	if (rc)
>  		return rc;
>  	*val >>= entry->register_region.bit_offset;
> @@ -116,13 +116,13 @@ int __apei_exec_write_register(struct acpi_whea_header *entry, u64 val)
>  	val <<= entry->register_region.bit_offset;
>  	if (entry->flags & APEI_EXEC_PRESERVE_REGISTER) {
>  		u64 valr = 0;
> -		rc = acpi_atomic_read(&valr, &entry->register_region);
> +		rc = acpi_read(&valr, &entry->register_region);
>  		if (rc)
>  			return rc;
>  		valr &= ~(entry->mask << entry->register_region.bit_offset);
>  		val |= valr;
>  	}
> -	rc = acpi_atomic_write(val, &entry->register_region);
> +	rc = acpi_write(val, &entry->register_region);
>  
>  	return rc;
>  }
> @@ -243,7 +243,7 @@ static int pre_map_gar_callback(struct apei_exec_context *ctx,
>  	u8 ins = entry->instruction;
>  
>  	if (ctx->ins_table[ins].flags & APEI_EXEC_INS_ACCESS_REGISTER)
> -		return acpi_pre_map_gar(&entry->register_region);
> +		return acpi_os_map_generic_address(&entry->register_region);
>  
>  	return 0;
>  }
> @@ -276,7 +276,7 @@ static int post_unmap_gar_callback(struct apei_exec_context *ctx,
>  	u8 ins = entry->instruction;
>  
>  	if (ctx->ins_table[ins].flags & APEI_EXEC_INS_ACCESS_REGISTER)
> -		acpi_post_unmap_gar(&entry->register_region);
> +		acpi_os_unmap_generic_address(&entry->register_region);
>  
>  	return 0;
>  }
> diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c
> index 0784f99..9814e05 100644
> --- a/drivers/acpi/apei/ghes.c
> +++ b/drivers/acpi/apei/ghes.c
> @@ -33,6 +33,7 @@
>  #include <linux/module.h>
>  #include <linux/init.h>
>  #include <linux/acpi.h>
> +#include <linux/acpi_io.h>
>  #include <linux/io.h>
>  #include <linux/interrupt.h>
>  #include <linux/timer.h>
> @@ -46,7 +47,6 @@
>  #include <linux/llist.h>
>  #include <linux/genalloc.h>
>  #include <acpi/apei.h>
> -#include <acpi/atomicio.h>
>  #include <acpi/hed.h>
>  #include <asm/mce.h>
>  #include <asm/tlbflush.h>
> @@ -298,7 +298,7 @@ static struct ghes *ghes_new(struct acpi_hest_generic *generic)
>  	if (!ghes)
>  		return ERR_PTR(-ENOMEM);
>  	ghes->generic = generic;
> -	rc = acpi_pre_map_gar(&generic->error_status_address);
> +	rc = acpi_os_map_generic_address(&generic->error_status_address);
>  	if (rc)
>  		goto err_free;
>  	error_block_length = generic->error_block_length;
> @@ -318,7 +318,7 @@ static struct ghes *ghes_new(struct acpi_hest_generic *generic)
>  	return ghes;
>  
>  err_unmap:
> -	acpi_post_unmap_gar(&generic->error_status_address);
> +	acpi_os_unmap_generic_address(&generic->error_status_address);
>  err_free:
>  	kfree(ghes);
>  	return ERR_PTR(rc);
> @@ -327,7 +327,7 @@ err_free:
>  static void ghes_fini(struct ghes *ghes)
>  {
>  	kfree(ghes->estatus);
> -	acpi_post_unmap_gar(&ghes->generic->error_status_address);
> +	acpi_os_unmap_generic_address(&ghes->generic->error_status_address);
>  }
>  
>  enum {
> @@ -398,7 +398,7 @@ static int ghes_read_estatus(struct ghes *ghes, int silent)
>  	u32 len;
>  	int rc;
>  
> -	rc = acpi_atomic_read(&buf_paddr, &g->error_status_address);
> +	rc = acpi_read(&buf_paddr, &g->error_status_address);
>  	if (rc) {
>  		if (!silent && printk_ratelimit())
>  			pr_warning(FW_WARN GHES_PFX
> diff --git a/drivers/acpi/atomicio.c b/drivers/acpi/atomicio.c
> deleted file mode 100644
> index 7489b89..0000000
> --- a/drivers/acpi/atomicio.c
> +++ /dev/null
> @@ -1,365 +0,0 @@
> -/*
> - * atomicio.c - ACPI IO memory pre-mapping/post-unmapping, then
> - * accessing in atomic context.
> - *
> - * This is used for NMI handler to access IO memory area, because
> - * ioremap/iounmap can not be used in NMI handler. The IO memory area
> - * is pre-mapped in process context and accessed in NMI handler.
> - *
> - * Copyright (C) 2009-2010, Intel Corp.
> - *	Author: Huang Ying <ying.huang@intel.com>
> - *
> - * 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.
> - *
> - * 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.
> - *
> - * You should have received a copy of the GNU General Public License
> - * along with this program; if not, write to the Free Software
> - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
> - */
> -
> -#include <linux/kernel.h>
> -#include <linux/module.h>
> -#include <linux/init.h>
> -#include <linux/acpi.h>
> -#include <linux/io.h>
> -#include <linux/kref.h>
> -#include <linux/rculist.h>
> -#include <linux/interrupt.h>
> -#include <linux/slab.h>
> -#include <acpi/atomicio.h>
> -
> -#define ACPI_PFX "ACPI: "
> -
> -static LIST_HEAD(acpi_iomaps);
> -/*
> - * Used for mutual exclusion between writers of acpi_iomaps list, for
> - * synchronization between readers and writer, RCU is used.
> - */
> -static DEFINE_SPINLOCK(acpi_iomaps_lock);
> -
> -struct acpi_iomap {
> -	struct list_head list;
> -	void __iomem *vaddr;
> -	unsigned long size;
> -	phys_addr_t paddr;
> -	struct kref ref;
> -};
> -
> -/* acpi_iomaps_lock or RCU read lock must be held before calling */
> -static struct acpi_iomap *__acpi_find_iomap(phys_addr_t paddr,
> -					    unsigned long size)
> -{
> -	struct acpi_iomap *map;
> -
> -	list_for_each_entry_rcu(map, &acpi_iomaps, list) {
> -		if (map->paddr + map->size >= paddr + size &&
> -		    map->paddr <= paddr)
> -			return map;
> -	}
> -	return NULL;
> -}
> -
> -/*
> - * Atomic "ioremap" used by NMI handler, if the specified IO memory
> - * area is not pre-mapped, NULL will be returned.
> - *
> - * acpi_iomaps_lock or RCU read lock must be held before calling
> - */
> -static void __iomem *__acpi_ioremap_fast(phys_addr_t paddr,
> -					 unsigned long size)
> -{
> -	struct acpi_iomap *map;
> -
> -	map = __acpi_find_iomap(paddr, size);
> -	if (map)
> -		return map->vaddr + (paddr - map->paddr);
> -	else
> -		return NULL;
> -}
> -
> -/* acpi_iomaps_lock must be held before calling */
> -static void __iomem *__acpi_try_ioremap(phys_addr_t paddr,
> -					unsigned long size)
> -{
> -	struct acpi_iomap *map;
> -
> -	map = __acpi_find_iomap(paddr, size);
> -	if (map) {
> -		kref_get(&map->ref);
> -		return map->vaddr + (paddr - map->paddr);
> -	} else
> -		return NULL;
> -}
> -
> -/*
> - * Used to pre-map the specified IO memory area. First try to find
> - * whether the area is already pre-mapped, if it is, increase the
> - * reference count (in __acpi_try_ioremap) and return; otherwise, do
> - * the real ioremap, and add the mapping into acpi_iomaps list.
> - */
> -static void __iomem *acpi_pre_map(phys_addr_t paddr,
> -				  unsigned long size)
> -{
> -	void __iomem *vaddr;
> -	struct acpi_iomap *map;
> -	unsigned long pg_sz, flags;
> -	phys_addr_t pg_off;
> -
> -	spin_lock_irqsave(&acpi_iomaps_lock, flags);
> -	vaddr = __acpi_try_ioremap(paddr, size);
> -	spin_unlock_irqrestore(&acpi_iomaps_lock, flags);
> -	if (vaddr)
> -		return vaddr;
> -
> -	pg_off = paddr & PAGE_MASK;
> -	pg_sz = ((paddr + size + PAGE_SIZE - 1) & PAGE_MASK) - pg_off;
> -	vaddr = ioremap(pg_off, pg_sz);
> -	if (!vaddr)
> -		return NULL;
> -	map = kmalloc(sizeof(*map), GFP_KERNEL);
> -	if (!map)
> -		goto err_unmap;
> -	INIT_LIST_HEAD(&map->list);
> -	map->paddr = pg_off;
> -	map->size = pg_sz;
> -	map->vaddr = vaddr;
> -	kref_init(&map->ref);
> -
> -	spin_lock_irqsave(&acpi_iomaps_lock, flags);
> -	vaddr = __acpi_try_ioremap(paddr, size);
> -	if (vaddr) {
> -		spin_unlock_irqrestore(&acpi_iomaps_lock, flags);
> -		iounmap(map->vaddr);
> -		kfree(map);
> -		return vaddr;
> -	}
> -	list_add_tail_rcu(&map->list, &acpi_iomaps);
> -	spin_unlock_irqrestore(&acpi_iomaps_lock, flags);
> -
> -	return map->vaddr + (paddr - map->paddr);
> -err_unmap:
> -	iounmap(vaddr);
> -	return NULL;
> -}
> -
> -/* acpi_iomaps_lock must be held before calling */
> -static void __acpi_kref_del_iomap(struct kref *ref)
> -{
> -	struct acpi_iomap *map;
> -
> -	map = container_of(ref, struct acpi_iomap, ref);
> -	list_del_rcu(&map->list);
> -}
> -
> -/*
> - * Used to post-unmap the specified IO memory area. The iounmap is
> - * done only if the reference count goes zero.
> - */
> -static void acpi_post_unmap(phys_addr_t paddr, unsigned long size)
> -{
> -	struct acpi_iomap *map;
> -	unsigned long flags;
> -	int del;
> -
> -	spin_lock_irqsave(&acpi_iomaps_lock, flags);
> -	map = __acpi_find_iomap(paddr, size);
> -	BUG_ON(!map);
> -	del = kref_put(&map->ref, __acpi_kref_del_iomap);
> -	spin_unlock_irqrestore(&acpi_iomaps_lock, flags);
> -
> -	if (!del)
> -		return;
> -
> -	synchronize_rcu();
> -	iounmap(map->vaddr);
> -	kfree(map);
> -}
> -
> -/* In NMI handler, should set silent = 1 */
> -static int acpi_check_gar(struct acpi_generic_address *reg,
> -			  u64 *paddr, int silent)
> -{
> -	u32 width, space_id;
> -
> -	width = reg->bit_width;
> -	space_id = reg->space_id;
> -	/* Handle possible alignment issues */
> -	memcpy(paddr, &reg->address, sizeof(*paddr));
> -	if (!*paddr) {
> -		if (!silent)
> -			pr_warning(FW_BUG ACPI_PFX
> -			"Invalid physical address in GAR [0x%llx/%u/%u]\n",
> -				   *paddr, width, space_id);
> -		return -EINVAL;
> -	}
> -
> -	if ((width != 8) && (width != 16) && (width != 32) && (width != 64)) {
> -		if (!silent)
> -			pr_warning(FW_BUG ACPI_PFX
> -				   "Invalid bit width in GAR [0x%llx/%u/%u]\n",
> -				   *paddr, width, space_id);
> -		return -EINVAL;
> -	}
> -
> -	if (space_id != ACPI_ADR_SPACE_SYSTEM_MEMORY &&
> -	    space_id != ACPI_ADR_SPACE_SYSTEM_IO) {
> -		if (!silent)
> -			pr_warning(FW_BUG ACPI_PFX
> -			"Invalid address space type in GAR [0x%llx/%u/%u]\n",
> -				   *paddr, width, space_id);
> -		return -EINVAL;
> -	}
> -
> -	return 0;
> -}
> -
> -/* Pre-map, working on GAR */
> -int acpi_pre_map_gar(struct acpi_generic_address *reg)
> -{
> -	u64 paddr;
> -	void __iomem *vaddr;
> -	int rc;
> -
> -	if (reg->space_id != ACPI_ADR_SPACE_SYSTEM_MEMORY)
> -		return 0;
> -
> -	rc = acpi_check_gar(reg, &paddr, 0);
> -	if (rc)
> -		return rc;
> -
> -	vaddr = acpi_pre_map(paddr, reg->bit_width / 8);
> -	if (!vaddr)
> -		return -EIO;
> -
> -	return 0;
> -}
> -EXPORT_SYMBOL_GPL(acpi_pre_map_gar);
> -
> -/* Post-unmap, working on GAR */
> -int acpi_post_unmap_gar(struct acpi_generic_address *reg)
> -{
> -	u64 paddr;
> -	int rc;
> -
> -	if (reg->space_id != ACPI_ADR_SPACE_SYSTEM_MEMORY)
> -		return 0;
> -
> -	rc = acpi_check_gar(reg, &paddr, 0);
> -	if (rc)
> -		return rc;
> -
> -	acpi_post_unmap(paddr, reg->bit_width / 8);
> -
> -	return 0;
> -}
> -EXPORT_SYMBOL_GPL(acpi_post_unmap_gar);
> -
> -/*
> - * Can be used in atomic (including NMI) or process context. RCU read
> - * lock can only be released after the IO memory area accessing.
> - */
> -static int acpi_atomic_read_mem(u64 paddr, u64 *val, u32 width)
> -{
> -	void __iomem *addr;
> -
> -	rcu_read_lock();
> -	addr = __acpi_ioremap_fast(paddr, width);
> -	switch (width) {
> -	case 8:
> -		*val = readb(addr);
> -		break;
> -	case 16:
> -		*val = readw(addr);
> -		break;
> -	case 32:
> -		*val = readl(addr);
> -		break;
> -#ifdef readq
> -	case 64:
> -		*val = readq(addr);
> -		break;
> -#endif
> -	default:
> -		return -EINVAL;
> -	}
> -	rcu_read_unlock();
> -
> -	return 0;
> -}
> -
> -static int acpi_atomic_write_mem(u64 paddr, u64 val, u32 width)
> -{
> -	void __iomem *addr;
> -
> -	rcu_read_lock();
> -	addr = __acpi_ioremap_fast(paddr, width);
> -	switch (width) {
> -	case 8:
> -		writeb(val, addr);
> -		break;
> -	case 16:
> -		writew(val, addr);
> -		break;
> -	case 32:
> -		writel(val, addr);
> -		break;
> -#ifdef writeq
> -	case 64:
> -		writeq(val, addr);
> -		break;
> -#endif
> -	default:
> -		return -EINVAL;
> -	}
> -	rcu_read_unlock();
> -
> -	return 0;
> -}
> -
> -/* GAR accessing in atomic (including NMI) or process context */
> -int acpi_atomic_read(u64 *val, struct acpi_generic_address *reg)
> -{
> -	u64 paddr;
> -	int rc;
> -
> -	rc = acpi_check_gar(reg, &paddr, 1);
> -	if (rc)
> -		return rc;
> -
> -	*val = 0;
> -	switch (reg->space_id) {
> -	case ACPI_ADR_SPACE_SYSTEM_MEMORY:
> -		return acpi_atomic_read_mem(paddr, val, reg->bit_width);
> -	case ACPI_ADR_SPACE_SYSTEM_IO:
> -		return acpi_os_read_port(paddr, (u32 *)val, reg->bit_width);
> -	default:
> -		return -EINVAL;
> -	}
> -}
> -EXPORT_SYMBOL_GPL(acpi_atomic_read);
> -
> -int acpi_atomic_write(u64 val, struct acpi_generic_address *reg)
> -{
> -	u64 paddr;
> -	int rc;
> -
> -	rc = acpi_check_gar(reg, &paddr, 1);
> -	if (rc)
> -		return rc;
> -
> -	switch (reg->space_id) {
> -	case ACPI_ADR_SPACE_SYSTEM_MEMORY:
> -		return acpi_atomic_write_mem(paddr, val, reg->bit_width);
> -	case ACPI_ADR_SPACE_SYSTEM_IO:
> -		return acpi_os_write_port(paddr, val, reg->bit_width);
> -	default:
> -		return -EINVAL;
> -	}
> -}
> -EXPORT_SYMBOL_GPL(acpi_atomic_write);
> diff --git a/include/acpi/atomicio.h b/include/acpi/atomicio.h
> deleted file mode 100644
> index 8b9fb4b..0000000
> --- a/include/acpi/atomicio.h
> +++ /dev/null
> @@ -1,10 +0,0 @@
> -#ifndef ACPI_ATOMIC_IO_H
> -#define ACPI_ATOMIC_IO_H
> -
> -int acpi_pre_map_gar(struct acpi_generic_address *reg);
> -int acpi_post_unmap_gar(struct acpi_generic_address *reg);
> -
> -int acpi_atomic_read(u64 *val, struct acpi_generic_address *reg);
> -int acpi_atomic_write(u64 val, struct acpi_generic_address *reg);
> -
> -#endif
> 
> 
> 


  reply	other threads:[~2011-11-06 13:02 UTC|newest]

Thread overview: 31+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-09-29 21:59 [PATCH 0/2] ACPI: Re-factor and remove ./drivers/acpi/atomicio.[ch] Myron Stowe
2011-09-29 21:59 ` [PATCH 1/2] ACPI: Export interfaces for ioremapping/iounmapping ACPI registers Myron Stowe
2011-11-06 12:49   ` Rafael J. Wysocki
2011-09-29 21:59 ` [PATCH 2/2] ACPI: Convert acpi_pre_map_gar()/acpi_atomic_read() and remove ./drivers/acpi/atomicio.[ch] Myron Stowe
2011-11-06 13:05   ` Rafael J. Wysocki [this message]
2011-10-28  1:49 ` [PATCH 0/2] ACPI: Re-factor " Thomas Renninger
2011-10-28 15:03   ` Bjorn Helgaas
2011-10-31 10:47     ` Thomas Renninger
2011-11-03  1:42       ` Myron Stowe
2011-11-06 13:30         ` Rafael J. Wysocki
2011-11-04 23:54       ` Myron Stowe
2011-11-05  2:42         ` Thomas Renninger
2011-11-06 13:42           ` Rafael J. Wysocki
2011-11-15 18:45         ` Bjorn Helgaas
2011-11-06 13:25       ` Rafael J. Wysocki
2011-11-06 13:23     ` Rafael J. Wysocki
2011-10-28 15:14   ` Bjorn Helgaas
2011-10-31 10:33     ` Thomas Renninger
2011-10-31 15:51       ` Bjorn Helgaas
2011-11-03  9:16         ` Thomas Renninger
2011-11-03 13:53           ` Bjorn Helgaas
2011-11-03 16:18             ` Thomas Renninger
2011-11-03 16:44               ` Myron Stowe
2011-11-04  2:16                 ` Thomas Renninger
2011-11-04  1:55                   ` Myron Stowe
2011-10-28 22:40   ` Myron Stowe
2011-11-06 13:19   ` Rafael J. Wysocki
2011-11-03 16:31 ` Thomas Renninger
2011-11-04  0:56   ` Huang Ying
2011-11-04  2:24     ` Thomas Renninger
2011-11-04  1:32       ` Huang Ying

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=201111061405.09686.rjw@sisk.pl \
    --to=rjw@sisk.pl \
    --cc=bhelgaas@google.com \
    --cc=lenb@kernel.org \
    --cc=linux-acpi@vger.kernel.org \
    --cc=myron.stowe@redhat.com \
    --cc=ying.huang@intel.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.