From patchwork Mon Feb 26 16:40:41 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: John Garry X-Patchwork-Id: 129698 Delivered-To: patch@linaro.org Received: by 10.80.172.228 with SMTP id x91csp3978620edc; Mon, 26 Feb 2018 07:55:24 -0800 (PST) X-Google-Smtp-Source: AH8x224DAM7/XzUbbHQC0+6C7zPLTiAPa1RefkWUVrks09u5wR+H6Zj68ak6wGH2RnTxdi7cNFB2 X-Received: by 2002:a17:902:bcc6:: with SMTP id o6-v6mr11123699pls.16.1519660524751; Mon, 26 Feb 2018 07:55:24 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1519660524; cv=none; d=google.com; s=arc-20160816; b=hx4GsLVal6grnDh+U2WSslXK7ma/KI6pZjO6Qi40d5SDBFSRR3j5ZD0G6mYXTwnzKw rZA+CRZrmQFZLWssXk6O1HZ8dQdKjf6SZrUSMbp1RPD2uuTuNpgIiCRlGSqwU81W/i6d tNBc93n5Dm7v7O5cCQ7HrcaTUuQMsi4sKqxNr2+lH0YItntTWC6SYR6H7SuAf0qvt6Xq 5vmoG/Rd0hXvCER3/ptgBsGiklzOF8Q7c34xO+JuF+gXy0PRoG7Mqc4VHzzx1QWmM344 utkBZPser05qaBz28j0OWtU/PDCv8qjdfrBIrHsBzxIUXs5GXSzjv7LYLV4ElNDUcyvN XENA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:arc-authentication-results; bh=wdWI2gRciRB4IIG8BGLEZWXTtXTQipwlY+LXysOUNvg=; b=cxSahNUWq5KC/C0u+AJ30pxm1C3jqzEOH9ZqpM1nP4+DbhPnl55GzGIV4v+rWkYnRD pkssxmzI6WFoKixbhO6QHk+/aVCVoqOXqJw5Khsnjp5pgs9qH0+x+z30eIZI43nbh3Wu Bb80G2ybXswv3lDEyEdUldrgWb+XVg4LMABaiHWcCYfL30OqXOXw6+fxS/+ymOb8B05s 6PXOZRx9DWatb8wG8SJunf/AMdp3B/mz3Krai2glbexHiTsLeP8JzLuxXNnN1wOk/8vK 5Xy4N0S5+uZKRrky54fgUfApePq52mKT+3miKzFrggqLc8ueGGCVIQk3HAAE22V56CVb 4GdQ== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of devicetree-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=devicetree-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id u68si5674401pgb.287.2018.02.26.07.55.24; Mon, 26 Feb 2018 07:55:24 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of devicetree-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of devicetree-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=devicetree-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751961AbeBZPzW (ORCPT + 6 others); Mon, 26 Feb 2018 10:55:22 -0500 Received: from szxga07-in.huawei.com ([45.249.212.35]:49567 "EHLO huawei.com" rhost-flags-OK-FAIL-OK-FAIL) by vger.kernel.org with ESMTP id S1751654AbeBZPuP (ORCPT ); Mon, 26 Feb 2018 10:50:15 -0500 Received: from DGGEMS413-HUB.china.huawei.com (unknown [172.30.72.59]) by Forcepoint Email with ESMTP id 3F66A323EE2F4; Mon, 26 Feb 2018 23:50:06 +0800 (CST) Received: from localhost.localdomain (10.67.212.75) by DGGEMS413-HUB.china.huawei.com (10.3.19.213) with Microsoft SMTP Server id 14.3.361.1; Mon, 26 Feb 2018 23:49:57 +0800 From: John Garry To: , , , , , , , , , , , , , CC: , , , , , , , , , , , , , Subject: [PATCH v15 1/9] LIB: Introduce a generic PIO mapping method Date: Tue, 27 Feb 2018 00:40:41 +0800 Message-ID: <1519663249-9850-2-git-send-email-john.garry@huawei.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1519663249-9850-1-git-send-email-john.garry@huawei.com> References: <1519663249-9850-1-git-send-email-john.garry@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.67.212.75] X-CFilter-Loop: Reflected Sender: devicetree-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org From: Zhichang Yuan In commit 41f8bba7f555 ("of/pci: Add pci_register_io_range() and pci_pio_to_address()"), a new I/O space management was supported. With that driver, the I/O ranges configured for PCI/PCIe hosts on some architectures can be mapped to logical PIO, converted easily between CPU address and the corresponding logicial PIO. Based on this, PCI I/O devices can be accessed in a memory read/write way through the unified in/out accessors. But on some archs/platforms, there are bus hosts which access I/O peripherals with host-local I/O port addresses rather than memory addresses after memory-mapped. To support those devices, a more generic I/O mapping method is introduced here. Through this patch, both the CPU addresses and the host-local port can be mapped into the logical PIO space with different logical/fake PIOs. After this, all the I/O accesses to either PCI MMIO devices or host-local I/O peripherals can be unified into the existing I/O accessors defined in asm-generic/io.h and be redirected to the right device-specific hooks based on the input logical PIO. Signed-off-by: Zhichang Yuan Signed-off-by: Gabriele Paoloni Signed-off-by: John Garry Reviewed-by: Andy Shevchenko Tested-by: dann frazier --- include/asm-generic/io.h | 2 + include/linux/logic_pio.h | 127 +++++++++++++++++++++ lib/Kconfig | 15 +++ lib/Makefile | 2 + lib/logic_pio.c | 285 ++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 431 insertions(+) create mode 100644 include/linux/logic_pio.h create mode 100644 lib/logic_pio.c -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html diff --git a/include/asm-generic/io.h b/include/asm-generic/io.h index 7c6a39e..f76fbd6 100644 --- a/include/asm-generic/io.h +++ b/include/asm-generic/io.h @@ -351,6 +351,8 @@ static inline void writesq(volatile void __iomem *addr, const void *buffer, #define IO_SPACE_LIMIT 0xffff #endif +#include + /* * {in,out}{b,w,l}() access little endian I/O. {in,out}{b,w,l}_p() can be * implemented on hardware that needs an additional delay for I/O accesses to diff --git a/include/linux/logic_pio.h b/include/linux/logic_pio.h new file mode 100644 index 0000000..26fe14b --- /dev/null +++ b/include/linux/logic_pio.h @@ -0,0 +1,127 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2017 Hisilicon Limited, All Rights Reserved. + * Author: Gabriele Paoloni + * Author: Zhichang Yuan + * + */ + +#ifndef __LINUX_LOGIC_PIO_H +#define __LINUX_LOGIC_PIO_H + +#ifdef __KERNEL__ + +#include + +enum { + LOGIC_PIO_INDIRECT, /* Indirect IO flag */ + LOGIC_PIO_CPU_MMIO, /* Memory mapped IO flag */ +}; + +struct logic_pio_hwaddr { + struct list_head list; + struct fwnode_handle *fwnode; + resource_size_t hw_start; + resource_size_t io_start; + resource_size_t size; /* range size populated */ + unsigned long flags; + + void *hostdata; + const struct logic_pio_host_ops *ops; +}; + +struct logic_pio_host_ops { + u32 (*in)(void *hostdata, unsigned long addr, size_t dwidth); + void (*out)(void *hostdata, unsigned long addr, u32 val, + size_t dwidth); + u32 (*ins)(void *hostdata, unsigned long addr, void *buffer, + size_t dwidth, unsigned int count); + void (*outs)(void *hostdata, unsigned long addr, const void *buffer, + size_t dwidth, unsigned int count); +}; + +#ifdef CONFIG_INDIRECT_PIO +u8 logic_inb(unsigned long addr); +void logic_outb(u8 value, unsigned long addr); +void logic_outw(u16 value, unsigned long addr); +void logic_outl(u32 value, unsigned long addr); +u16 logic_inw(unsigned long addr); +u32 logic_inl(unsigned long addr); +void logic_outb(u8 value, unsigned long addr); +void logic_outw(u16 value, unsigned long addr); +void logic_outl(u32 value, unsigned long addr); +void logic_insb(unsigned long addr, void *buffer, unsigned int count); +void logic_insl(unsigned long addr, void *buffer, unsigned int count); +void logic_insw(unsigned long addr, void *buffer, unsigned int count); +void logic_outsb(unsigned long addr, const void *buffer, unsigned int count); +void logic_outsw(unsigned long addr, const void *buffer, unsigned int count); +void logic_outsl(unsigned long addr, const void *buffer, unsigned int count); + +#ifndef inb +#define inb logic_inb +#endif + +#ifndef inw +#define inw logic_inw +#endif + +#ifndef inl +#define inl logic_inl +#endif + +#ifndef outb +#define outb logic_outb +#endif + +#ifndef outw +#define outw logic_outw +#endif + +#ifndef outl +#define outl logic_outl +#endif + +#ifndef insb +#define insb logic_insb +#endif + +#ifndef insw +#define insw logic_insw +#endif + +#ifndef insl +#define insl logic_insl +#endif + +#ifndef outsb +#define outsb logic_outsb +#endif + +#ifndef outsw +#define outsw logic_outsw +#endif + +#ifndef outsl +#define outsl logic_outsl +#endif + +/* + * Below we reserve 0x4000 bytes for Indirect IO as so far this library is only + * used by Hisilicon LPC Host. If needed in future we may reserve a wider IO + * area by redefining the macro below. + */ +#define PIO_INDIRECT_SIZE 0x4000 +#define MMIO_UPPER_LIMIT (IO_SPACE_LIMIT - PIO_INDIRECT_SIZE) +#else +#define MMIO_UPPER_LIMIT IO_SPACE_LIMIT +#endif /* CONFIG_INDIRECT_PIO */ + +struct logic_pio_hwaddr *find_io_range_by_fwnode(struct fwnode_handle *fwnode); +unsigned long logic_pio_trans_hwaddr(struct fwnode_handle *fwnode, + resource_size_t hw_addr, resource_size_t size); +int logic_pio_register_range(struct logic_pio_hwaddr *newrange); +extern resource_size_t logic_pio_to_hwaddr(unsigned long pio); +extern unsigned long logic_pio_trans_cpuaddr(resource_size_t hw_addr); + +#endif /* __KERNEL__ */ +#endif /* __LINUX_LOGIC_PIO_H */ diff --git a/lib/Kconfig b/lib/Kconfig index e960894..d9dd02c 100644 --- a/lib/Kconfig +++ b/lib/Kconfig @@ -55,6 +55,21 @@ config ARCH_USE_CMPXCHG_LOCKREF config ARCH_HAS_FAST_MULTIPLIER bool +config INDIRECT_PIO + bool "Access I/O in non-MMIO mode" + depends on ARM64 + help + On some platforms where no separate I/O space exists, there are I/O + hosts which can not be accessed in MMIO mode. Using the logical PIO + mechanism, the host-local I/O resource can be mapped into system + logic PIO space shared with MMIO hosts, such as PCI/PCIE, then the + system can access the I/O devices with the mapped logic PIO through + I/O accessors. + This way has relatively little I/O performance cost. Please make + sure your devices really need this configure item enabled. + + When in doubt, say N. + config CRC_CCITT tristate "CRC-CCITT functions" help diff --git a/lib/Makefile b/lib/Makefile index a90d4fc..4a9eacd 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -81,6 +81,8 @@ obj-$(CONFIG_HAS_IOMEM) += iomap_copy.o devres.o obj-$(CONFIG_CHECK_SIGNATURE) += check_signature.o obj-$(CONFIG_DEBUG_LOCKING_API_SELFTESTS) += locking-selftest.o +obj-y += logic_pio.o + obj-$(CONFIG_GENERIC_HWEIGHT) += hweight.o obj-$(CONFIG_BTREE) += btree.o diff --git a/lib/logic_pio.c b/lib/logic_pio.c new file mode 100644 index 0000000..fd52d55 --- /dev/null +++ b/lib/logic_pio.c @@ -0,0 +1,285 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2017 Hisilicon Limited, All Rights Reserved. + * Author: Gabriele Paoloni + * Author: Zhichang Yuan + * + */ + +#define pr_fmt(fmt) "LOGIC PIO: " fmt + +#include +#include +#include +#include +#include +#include +#include + +/* The unique hardware address list. */ +static LIST_HEAD(io_range_list); +static DEFINE_MUTEX(io_range_mutex); + +/** + * logic_pio_register_range - register logical PIO range for a host + * @new_range: pointer to the io range to be registered. + * + * returns 0 on success, the error code in case of failure + * + * Register a new io range node in the io range list. + */ +int logic_pio_register_range(struct logic_pio_hwaddr *new_range) +{ + struct logic_pio_hwaddr *range; + resource_size_t start = new_range->hw_start; + resource_size_t end = new_range->hw_start + new_range->size; + resource_size_t allocated_mmio_size = 0; + resource_size_t allocated_iio_size = MMIO_UPPER_LIMIT; + int ret = 0; + + if (!new_range || !new_range->fwnode || !new_range->size) + return -EINVAL; + + mutex_lock(&io_range_mutex); + list_for_each_entry_rcu(range, &io_range_list, list) { + if (range->fwnode == new_range->fwnode) { + /* range already there */ + ret = -EFAULT; + goto end_register; + } + if (range->flags == LOGIC_PIO_CPU_MMIO && + new_range->flags == LOGIC_PIO_CPU_MMIO) { + /* for MMIO ranges we need to check for overlap */ + if (start >= range->hw_start + range->size || + end < range->hw_start) + allocated_mmio_size += range->size; + else { + ret = -EFAULT; + goto end_register; + } + } else if (range->flags == LOGIC_PIO_INDIRECT && + new_range->flags == LOGIC_PIO_INDIRECT) { + allocated_iio_size += range->size; + } + } + + /* range not registered yet, check for available space */ + if (new_range->flags == LOGIC_PIO_CPU_MMIO) { + if (allocated_mmio_size + new_range->size - 1 > + MMIO_UPPER_LIMIT) { + /* if it's too big check if 64K space can be reserved */ + if (allocated_mmio_size + SZ_64K - 1 > + MMIO_UPPER_LIMIT) { + ret = -E2BIG; + goto end_register; + } + new_range->size = SZ_64K; + pr_warn("Requested IO range too big, new size set to 64K\n"); + } + new_range->io_start = allocated_mmio_size; + } else if (new_range->flags == LOGIC_PIO_INDIRECT) { + if (allocated_iio_size + new_range->size - 1 > + IO_SPACE_LIMIT) { + ret = -E2BIG; + goto end_register; + } + new_range->io_start = allocated_iio_size; + } else { + /* invalid flag */ + ret = -EINVAL; + goto end_register; + } + + list_add_tail_rcu(&new_range->list, &io_range_list); + +end_register: + mutex_unlock(&io_range_mutex); + return ret; +} + +/** + * find_io_range_by_fwnode - find logical PIO range for given FW node + * @fwnode: FW node handle associated with logical PIO range + * + * Returns pointer to node on success, NULL otherwise + * + * Traverse the io_range_list to find the registered node whose device node + * and/or physical IO address match to. + */ +struct logic_pio_hwaddr *find_io_range_by_fwnode(struct fwnode_handle *fwnode) +{ + struct logic_pio_hwaddr *range; + + list_for_each_entry_rcu(range, &io_range_list, list) { + if (range->fwnode == fwnode) + return range; + } + return NULL; +} + +/* Return a registered range given an input PIO token */ +static struct logic_pio_hwaddr *find_io_range(unsigned long pio) +{ + struct logic_pio_hwaddr *range; + + list_for_each_entry_rcu(range, &io_range_list, list) { + if (pio >= range->io_start && + pio < range->io_start + range->size) + return range; + } + pr_err("PIO entry token invalid\n"); + return NULL; +} + +/** + * logic_pio_to_hwaddr - translate logical PIO to HW address + * @pio: logical PIO value + * + * Returns HW address if valid, -1 otherwise + * + * Translate the input logical pio to the corresponding hardware address. + * The input pio should be unique in the whole logical PIO space. + */ +resource_size_t logic_pio_to_hwaddr(unsigned long pio) +{ + struct logic_pio_hwaddr *range; + resource_size_t hwaddr = (resource_size_t)-1; + + range = find_io_range(pio); + if (range) + hwaddr = range->hw_start + pio - range->io_start; + + return hwaddr; +} + +/** + * logic_pio_trans_hwaddr - translate HW address to logical PIO + * @fwnode: FW node reference for the host + * @addr: Host-relative HW address + * @size: size to translate + * + * Returns Logical PIO value if successful, ~0UL otherwise + */ +unsigned long +logic_pio_trans_hwaddr(struct fwnode_handle *fwnode, resource_size_t addr, + resource_size_t size) +{ + struct logic_pio_hwaddr *range; + + range = find_io_range_by_fwnode(fwnode); + if (!range || range->flags == LOGIC_PIO_CPU_MMIO) { + pr_err("range not found or invalid\n"); + return ~0UL; + } + if (range->size < size) { + pr_err("resource size %pa cannot fit in IO range size %pa\n", + &size, &range->size); + return ~0UL; + } + return addr - range->hw_start + range->io_start; +} + +unsigned long +logic_pio_trans_cpuaddr(resource_size_t addr) +{ + struct logic_pio_hwaddr *range; + + list_for_each_entry_rcu(range, &io_range_list, list) { + if (range->flags != LOGIC_PIO_CPU_MMIO) + continue; + if (addr >= range->hw_start && + addr < range->hw_start + range->size) + return addr - range->hw_start + + range->io_start; + } + pr_err("addr not registered in io_range_list\n"); + return ~0UL; +} + +#if defined(CONFIG_INDIRECT_PIO) && defined(PCI_IOBASE) +#define BUILD_LOGIC_IO(bw, type) \ +type logic_in##bw(unsigned long addr) \ +{ \ + type ret = (type)~0; \ + \ + if (addr < MMIO_UPPER_LIMIT) { \ + ret = read##bw(PCI_IOBASE + addr); \ + } else if (addr >= MMIO_UPPER_LIMIT && addr < IO_SPACE_LIMIT) { \ + struct logic_pio_hwaddr *entry = find_io_range(addr); \ + \ + if (entry && entry->ops) \ + ret = entry->ops->in(entry->hostdata, \ + addr, sizeof(type)); \ + else \ + WARN_ON_ONCE(1); \ + } \ + return ret; \ +} \ + \ +void logic_out##bw(type value, unsigned long addr) \ +{ \ + if (addr < MMIO_UPPER_LIMIT) { \ + write##bw(value, PCI_IOBASE + addr); \ + } else if (addr >= MMIO_UPPER_LIMIT && addr < IO_SPACE_LIMIT) { \ + struct logic_pio_hwaddr *entry = find_io_range(addr); \ + \ + if (entry && entry->ops) \ + entry->ops->out(entry->hostdata, \ + addr, value, sizeof(type)); \ + else \ + WARN_ON_ONCE(1); \ + } \ +} \ + \ +void logic_ins##bw(unsigned long addr, void *buffer, \ + unsigned int count) \ +{ \ + if (addr < MMIO_UPPER_LIMIT) { \ + reads##bw(PCI_IOBASE + addr, buffer, count); \ + } else if (addr >= MMIO_UPPER_LIMIT && addr < IO_SPACE_LIMIT) { \ + struct logic_pio_hwaddr *entry = find_io_range(addr); \ + \ + if (entry && entry->ops) \ + entry->ops->ins(entry->hostdata, \ + addr, buffer, sizeof(type), count); \ + else \ + WARN_ON_ONCE(1); \ + } \ + \ +} \ + \ +void logic_outs##bw(unsigned long addr, const void *buffer, \ + unsigned int count) \ +{ \ + if (addr < MMIO_UPPER_LIMIT) { \ + writes##bw(PCI_IOBASE + addr, buffer, count); \ + } else if (addr >= MMIO_UPPER_LIMIT && addr < IO_SPACE_LIMIT) { \ + struct logic_pio_hwaddr *entry = find_io_range(addr); \ + \ + if (entry && entry->ops) \ + entry->ops->outs(entry->hostdata, \ + addr, buffer, sizeof(type), count); \ + else \ + WARN_ON_ONCE(1); \ + } \ +} + +BUILD_LOGIC_IO(b, u8) +EXPORT_SYMBOL(logic_inb); +EXPORT_SYMBOL(logic_insb); +EXPORT_SYMBOL(logic_outb); +EXPORT_SYMBOL(logic_outsb); + +BUILD_LOGIC_IO(w, u16) +EXPORT_SYMBOL(logic_inw); +EXPORT_SYMBOL(logic_insw); +EXPORT_SYMBOL(logic_outw); +EXPORT_SYMBOL(logic_outsw); + +BUILD_LOGIC_IO(l, u32) +EXPORT_SYMBOL(logic_inl); +EXPORT_SYMBOL(logic_insl); +EXPORT_SYMBOL(logic_outl); +EXPORT_SYMBOL(logic_outsl); + +#endif /* CONFIG_INDIRECT_PIO && PCI_IOBASE */ From patchwork Mon Feb 26 16:40:47 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: John Garry X-Patchwork-Id: 129691 Delivered-To: patch@linaro.org Received: by 10.80.172.228 with SMTP id x91csp3974914edc; Mon, 26 Feb 2018 07:51:28 -0800 (PST) X-Google-Smtp-Source: AH8x227YxPOyI4VFw+oZf29vmahm8a/rpuOHE1KZXEDHPAEAPikI6GbrK5Y2M+k0bcO5X4/+5SET X-Received: by 2002:a17:902:bf0a:: with SMTP id bi10-v6mr11046270plb.181.1519660288868; Mon, 26 Feb 2018 07:51:28 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1519660288; cv=none; d=google.com; s=arc-20160816; b=Y8nQoEhA/mk2SsWXr3B2gXk0TRGjdtv84YvuC2/vhXOoDG1MQD7gFzu94DVj5Vq4jV wuY55JTinQpfjc8B7E3SGwvF9fvo3i/7Q1Si3hsttrnZR8nyHsvxxB1iKggmXcUdom/A yro6MzEw2Z0EHJ9+yJuZgZWofjZmLbzjCTPsCVUW2skKAoWiojJ1rdeL09iYHXXDk8S1 De8AEYRQUfOJ0/ADgfuBrydY3A7MuYyBBykUsPSvJ66KtcwbmdoYhfIW7vKSFkPRxgm3 ntmRfwY0GXD6NPZSToyzbk/VdF2vN55JQRvafovQRggLlTzG/6luNVoI5mp7OFShes4x xFNw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:arc-authentication-results; bh=QX5KW62XWSE3YIiBXu+ldyU+8N3hBY76IQSb2rqWE74=; b=kse4kIWuZpfpMNpAClWjnPvs2IeEN5HkkFJxp3bBiZnflZkD/T+JspvFfXxnBdu/w1 01QbpVesL3LbmIgPYiISHbyfx4rbYB3brXCErpStr2dguXwi/0vxz8oKsVaCmRTnmAb3 LL4euhlBQNuKXfyFk7wj9DamiPQ07LAezmf65POk5wrHErGG+3jSKd+2wY/gGd3wmJZg 4AwCaUB7BWMUjZ5XdJe4B4scYrIWmXmqt/4UMddtKy/D7BlEecv8Z+ups/ZBePiLGty4 ERqSBlyYtzkh9BVjmTLN7724SgPxxYbLSb0C8UNY0TVAU/Ql4p6Y4qvW+wYf5znN6hRW 6R3Q== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of devicetree-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=devicetree-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id n27si6946683pfg.102.2018.02.26.07.51.28; Mon, 26 Feb 2018 07:51:28 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of devicetree-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of devicetree-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=devicetree-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752364AbeBZPv1 (ORCPT + 6 others); Mon, 26 Feb 2018 10:51:27 -0500 Received: from szxga07-in.huawei.com ([45.249.212.35]:49678 "EHLO huawei.com" rhost-flags-OK-FAIL-OK-FAIL) by vger.kernel.org with ESMTP id S1752046AbeBZPuV (ORCPT ); Mon, 26 Feb 2018 10:50:21 -0500 Received: from DGGEMS413-HUB.china.huawei.com (unknown [172.30.72.59]) by Forcepoint Email with ESMTP id CE84D24DC7D25; Mon, 26 Feb 2018 23:50:06 +0800 (CST) Received: from localhost.localdomain (10.67.212.75) by DGGEMS413-HUB.china.huawei.com (10.3.19.213) with Microsoft SMTP Server id 14.3.361.1; Mon, 26 Feb 2018 23:50:00 +0800 From: John Garry To: , , , , , , , , , , , , , CC: , , , , , , , , , , , , , Subject: [PATCH v15 7/9] ACPI / scan: do not enumerate Indirect IO host children Date: Tue, 27 Feb 2018 00:40:47 +0800 Message-ID: <1519663249-9850-8-git-send-email-john.garry@huawei.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1519663249-9850-1-git-send-email-john.garry@huawei.com> References: <1519663249-9850-1-git-send-email-john.garry@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.67.212.75] X-CFilter-Loop: Reflected Sender: devicetree-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org Through the logical PIO framework systems which otherwise have no IO space access to legacy ISA/LPC devices may access these devices through so-called "indirect IO" method. In this, IO space accesses for non-PCI hosts are redirected to a host LLDD to manually generate the IO space (bus) accesses. Hosts are able to register a region in logical PIO space to map to its bus address range. Indirect IO child devices have an associated host-specific bus address. Special translation is required to map between a logical PIO address for a device and it's host bus address. Since in the ACPI tables the child device IO resources would be the host-specific values, it is required the ACPI scan code should not enumerate these devices, and that this should be the responsibility of the host driver so that it can "fixup" the resources so that they map to the appropriate logical PIO addresses. To avoid enumerating these child devices, we check whether the parent for a device is a member of a known list of "indirect IO" hosts. For now, the HiSilicon LPC host controller ID is added. To flag a device to not be enumerated, we reuse the existing serial bus slave flag. Signed-off-by: John Garry Acked-by: Rafael J. Wysocki Reviewed-by: Andy Shevchenko Tested-by: dann frazier --- drivers/acpi/scan.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index 8e63d93..c1a60852 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c @@ -1524,11 +1524,25 @@ static int acpi_check_serial_bus_slave(struct acpi_resource *ares, void *data) return -1; } +static bool acpi_is_indirect_io_slave(struct acpi_device *device) +{ + struct acpi_device *parent = device->parent; + const struct acpi_device_id indirect_io_hosts[] = { + {"HISI0191", 0}, + {} + }; + + return parent && !acpi_match_device_ids(parent, indirect_io_hosts); +} + static bool acpi_is_serial_bus_slave(struct acpi_device *device) { struct list_head resource_list; bool is_serial_bus_slave = false; + if (acpi_is_indirect_io_slave(device)) + return true; + /* Macs use device properties in lieu of _CRS resources */ if (x86_apple_machine && (fwnode_property_present(&device->fwnode, "spiSclkPeriod") ||