lkml.org 
[lkml]   [2018]   [Mar]   [21]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    SubjectRe: [PATCH v17 00/10] LPC: legacy ISA I/O support
    On Thu, Mar 15, 2018 at 02:15:49AM +0800, John Garry wrote:
    > This patchset supports the IPMI-bt device attached to the Low-Pin-Count
    > interface implemented on Hisilicon Hip06/Hip07 SoC.
    > -----------
    > | LPC host|
    > | |
    > -----------
    > |
    > _____________V_______________LPC
    > | |
    > V V
    > ------------
    > | BT(ipmi)|
    > ------------
    > ...

    > Gabriele Paoloni (2):
    > PCI: Remove unused __weak attribute in pci_register_io_range()
    > PCI: Add fwnode handler as input param of pci_register_io_range()
    >
    > John Garry (4):
    > ACPI / scan: rename acpi_is_serial_bus_slave() to widen use
    > ACPI / scan: do not enumerate Indirect IO host children
    > HISI LPC: Add ACPI support
    > MAINTAINERS: Add maintainer for HiSilicon LPC driver
    >
    > Zhichang Yuan (4):
    > LIB: Introduce a generic PIO mapping method
    > PCI: Apply the new generic I/O management on PCI IO hosts
    > OF: Add missing I/O range exception for indirect-IO devices
    > HISI LPC: Support the LPC host on Hip06/Hip07 with DT bindings
    >
    > .../arm/hisilicon/hisilicon-low-pin-count.txt | 33 ++
    > MAINTAINERS | 7 +
    > drivers/acpi/pci_root.c | 8 +-
    > drivers/acpi/scan.c | 33 +-
    > drivers/bus/Kconfig | 8 +
    > drivers/bus/Makefile | 2 +
    > drivers/bus/hisi_lpc.c | 623 +++++++++++++++++++++
    > drivers/of/address.c | 96 +++-
    > drivers/pci/pci.c | 95 +---
    > include/acpi/acpi_bus.h | 2 +-
    > include/asm-generic/io.h | 4 +-
    > include/linux/logic_pio.h | 124 ++++
    > include/linux/pci.h | 3 +-
    > lib/Kconfig | 15 +
    > lib/Makefile | 2 +
    > lib/logic_pio.c | 282 ++++++++++
    > 16 files changed, 1229 insertions(+), 108 deletions(-)
    > create mode 100644 Documentation/devicetree/bindings/arm/hisilicon/hisilicon-low-pin-count.txt
    > create mode 100644 drivers/bus/hisi_lpc.c
    > create mode 100644 include/linux/logic_pio.h
    > create mode 100644 lib/logic_pio.c

    I applied this whole series to pci/lpc for v4.17.

    I made the following whitespace and other trivial corrections.
    Hopefully I didn't break anything.


    --- changelogs.orig 2018-03-21 18:37:47.209217927 -0500
    +++ changelogs 2018-03-21 18:37:35.993074570 -0500
    @@ -1,29 +1,31 @@
    -commit cc88cacce96a
    +commit eb3a2ff7e72e
    Author: John Garry <john.garry@huawei.com>
    Date: Thu Mar 15 02:15:59 2018 +0800

    - MAINTAINERS: Add maintainer for HiSilicon LPC driver
    + MAINTAINERS: Add John Garry as maintainer for HiSilicon LPC driver

    - Added maintainer for drivers/bus/hisi_lpc.c
    + Add John Garry as maintainer for drivers/bus/hisi_lpc.c, the HiSilicon LPC
    + driver.

    Signed-off-by: John Garry <john.garry@huawei.com>
    Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>

    -commit e6e915fd9c90
    +commit 6d22e66ef6ea
    Author: John Garry <john.garry@huawei.com>
    Date: Thu Mar 15 02:15:58 2018 +0800

    HISI LPC: Add ACPI support

    - Based on the previous patches, this patch supports the
    - LPC host on hip06/hip07 for ACPI FW.
    + Based on the previous patches, this patch supports the LPC host on
    + Hip06/Hip07 for ACPI FW.

    - It is the responsibility of the LPC host driver to
    - enumerate the child devices, as the ACPI scan code will
    - not enumerate children of "indirect IO" hosts.
    + It is the responsibility of the LPC host driver to enumerate the child
    + devices, as the ACPI scan code will not enumerate children of "indirect IO"
    + hosts.
    +
    + The ACPI table for the LPC host controller and the child devices is in the
    + following format:

    - The ACPI table for the LPC host controller and the child
    - devices is in the following format:
    Device (LPC0) {
    Name (_HID, "HISI0191") // HiSi LPC
    Name (_CRS, ResourceTemplate () {
    @@ -50,216 +52,214 @@
    )
    })

    - Since the IO resources of the child devices need to be
    - translated from LPC bus addresses to logical PIO addresses,
    - and we shouldn't modify the resources of the devices
    - generated in the FW scan, a per-child MFD is created as
    - a substitute. The MFD IO resources will be the translated
    - bus addresses of the ACPI child.
    + Since the IO resources of the child devices need to be translated from LPC
    + bus addresses to logical PIO addresses, and we shouldn't modify the
    + resources of the devices generated in the FW scan, a per-child MFD is
    + created as a substitute. The MFD IO resources will be the translated bus
    + addresses of the ACPI child.

    + Tested-by: dann frazier <dann.frazier@canonical.com>
    Signed-off-by: John Garry <john.garry@huawei.com>
    Signed-off-by: Zhichang Yuan <yuanzhichang@hisilicon.com>
    Signed-off-by: Gabriele Paoloni <gabriele.paoloni@huawei.com>
    - Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
    - Tested-by: dann frazier <dann.frazier@canonical.com>
    Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
    + Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>

    -commit 3e1f89c344c6
    +commit ac3f7a357d2d
    Author: John Garry <john.garry@huawei.com>
    Date: Thu Mar 15 02:15:57 2018 +0800

    - ACPI / scan: do not enumerate Indirect IO host children
    + ACPI / scan: Do not enumerate Indirect IO host children

    - 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 add a check from
    - acpi_device_enumeration_by_parent() as to 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.
    + 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 its 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, add a check from
    + acpi_device_enumeration_by_parent() as to 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.

    - Signed-off-by: John Garry <john.garry@huawei.com>
    - Acked-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
    - Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
    Tested-by: dann frazier <dann.frazier@canonical.com>
    + Signed-off-by: John Garry <john.garry@huawei.com>
    Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
    + Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
    + Acked-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>

    -commit b4eee6c070c3
    +commit 87200d40b07a
    Author: John Garry <john.garry@huawei.com>
    Date: Thu Mar 15 02:15:56 2018 +0800

    - ACPI / scan: rename acpi_is_serial_bus_slave() to widen use
    + ACPI / scan: Rename acpi_is_serial_bus_slave() for more general use

    - Currently the ACPI scan has special handling for serial bus
    - slaves, in that it makes it the responsibility of the the slave
    - device's parent to enumerate the device.
    -
    - To support in future other types of slave devices which require
    - the same special handling, but where the bus is not strictly a
    - serial bus - such as devices on the HiSilicon LPC controller bus -
    - rename acpi_is_serial_bus_slave() to
    - acpi_device_enumeration_by_parent(), so that the name can fit the
    - wider purpose.
    + Currently the ACPI scan has special handling for serial bus slaves, in that
    + it makes it the responsibility of the slave device's parent to enumerate
    + the device.
    +
    + To support other types of slave devices which require the same special
    + handling but where the bus is not strictly a serial bus, such as devices on
    + the HiSilicon LPC controller bus, rename acpi_is_serial_bus_slave() to
    + acpi_device_enumeration_by_parent(), so that the name can fit the wider
    + purpose.

    - Associated device flag acpi_device_flags.serial_bus_slave is also
    - renamed to .enumeration_by_parent.
    + Also rename the associated device flag acpi_device_flags.serial_bus_slave
    + to .enumeration_by_parent.

    Signed-off-by: John Garry <john.garry@huawei.com>
    Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
    + Acked-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>

    -commit d9de40ca46a7
    +commit a9a860ecbea9
    Author: Zhichang Yuan <yuanzhichang@hisilicon.com>
    -Date: Wed Mar 21 18:33:39 2018 -0500
    +Date: Wed Mar 21 17:23:02 2018 -0500

    HISI LPC: Support the LPC host on Hip06/Hip07 with DT bindings

    - The low-pin-count(LPC) interface of Hip06/Hip07 accesses the peripherals in
    - I/O port addresses. This patch implements the LPC host controller driver
    - which perform the I/O operations on the underlying hardware.
    - We don't want to touch those existing peripherals' driver, such as ipmi-bt.
    - So this driver applies the indirect-IO introduced in the previous patch
    - after registering an indirect-IO node to the indirect-IO devices list which
    - will be searched in the I/O accessors to retrieve the host-local I/O port.
    -
    - The driver config is set as a bool instead of a trisate. The reason
    - here is that, by the very nature of the driver providing a logical
    - PIO range, it does not make sense to have this driver as a loadable
    - module. Another more specific reason is that the Huawei D03 board
    - which includes hip06 SoC requires the LPC bus for UART console, so
    - should be built in.
    + The low-pin-count (LPC) interface of Hip06/Hip07 accesses I/O port space of
    + peripherals.

    + Implement the LPC host controller driver which performs the I/O operations
    + on the underlying hardware. We don't want to touch existing drivers such
    + as ipmi-bt, so this driver applies the indirect-IO introduced in the
    + previous patch after registering an indirect-IO node to the indirect-IO
    + devices list which will be searched by the I/O accessors to retrieve the
    + host-local I/O port.
    +
    + The driver config is set as a bool instead of a tristate. The reason here
    + is that, by the very nature of the driver providing a logical PIO range, it
    + does not make sense to have this driver as a loadable module. Another more
    + specific reason is that the Huawei D03 board which includes Hip06 SoC
    + requires the LPC bus for UART console, so should be built in.
    +
    + Tested-by: dann frazier <dann.frazier@canonical.com>
    Signed-off-by: Zou Rongrong <zourongrong@huawei.com>
    Signed-off-by: Zhichang Yuan <yuanzhichang@hisilicon.com>
    Signed-off-by: John Garry <john.garry@huawei.com>
    - Acked-by: Rob Herring <robh@kernel.org> #dts part
    Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
    - Tested-by: dann frazier <dann.frazier@canonical.com>
    + Acked-by: Rob Herring <robh@kernel.org> #dts part

    -commit db64f8630d14
    +commit 03be72aeeb79
    Author: Zhichang Yuan <yuanzhichang@hisilicon.com>
    Date: Thu Mar 15 02:15:54 2018 +0800

    - OF: Add missing I/O range exception for indirect-IO devices
    + of: Add missing I/O range exception for indirect-IO devices

    There are some special ISA/LPC devices that work on a specific I/O range
    - where it is not correct to specify a 'ranges' property in DTS parent node
    - as CPU addresses translated from DTS node are only for memory space on
    - some architectures, such as Arm64. Without the parent 'ranges' property,
    - current of_translate_address() return an error.
    + where it is not correct to specify a 'ranges' property in the DTS parent
    + node as CPU addresses translated from DTS node are only for memory space on
    + some architectures, such as ARM64. Without the parent 'ranges' property,
    + of_translate_address() returns an error.
    +
    Here we add special handling for this case.
    +
    During the OF address translation, some checking will be performed to
    - identify whether the device node is registered as indirect-IO. If yes,
    + identify whether the device node is registered as indirect-IO. If it is,
    the I/O translation will be done in a different way from that one of PCI
    - MMIO. In this way, the I/O 'reg' property of the special ISA/LPC devices
    + MMIO. In this way, the I/O 'reg' property of the special ISA/LPC devices
    will be parsed correctly.

    + Tested-by: dann frazier <dann.frazier@canonical.com>
    Signed-off-by: Zhichang Yuan <yuanzhichang@hisilicon.com>
    Signed-off-by: Gabriele Paoloni <gabriele.paoloni@huawei.com>
    - Signed-off-by: Arnd Bergmann <arnd@arndb.de> #earlier draft
    - Acked-by: Rob Herring <robh@kernel.org>
    - Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
    - Tested-by: dann frazier <dann.frazier@canonical.com>
    + Signed-off-by: Arnd Bergmann <arnd@arndb.de> # earlier draft
    Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
    + Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
    + Acked-by: Rob Herring <robh@kernel.org>

    -commit 2add4c7b6bb7
    +commit 54106314daf5
    Author: Zhichang Yuan <yuanzhichang@hisilicon.com>
    Date: Thu Mar 15 02:15:53 2018 +0800

    PCI: Apply the new generic I/O management on PCI IO hosts

    - After introducing the new generic I/O space management(Logical PIO), the
    + After introducing the new generic I/O space management (Logical PIO), the
    original PCI MMIO relevant helpers need to be updated based on the new
    interfaces defined in logical PIO.
    - This patch adapts the corresponding code to match the changes introduced
    - by logical PIO.

    + Adapt the corresponding code to match the changes introduced by logical
    + PIO.
    +
    + Tested-by: dann frazier <dann.frazier@canonical.com>
    Signed-off-by: Zhichang Yuan <yuanzhichang@hisilicon.com>
    Signed-off-by: Gabriele Paoloni <gabriele.paoloni@huawei.com>
    - Signed-off-by: Arnd Bergmann <arnd@arndb.de> #earlier draft
    - Acked-by: Bjorn Helgaas <bhelgaas@google.com>
    - Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
    - Tested-by: dann frazier <dann.frazier@canonical.com>
    + Signed-off-by: Arnd Bergmann <arnd@arndb.de> # earlier draft
    Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
    + Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>

    -commit cb37d289dfc4
    +commit 32f7562cfd58
    Author: Gabriele Paoloni <gabriele.paoloni@huawei.com>
    Date: Thu Mar 15 02:15:52 2018 +0800

    PCI: Add fwnode handler as input param of pci_register_io_range()

    - In preparation for having the PCI MMIO helpers to use the new generic
    - I/O space management(logical PIO) we need to add the fwnode handler as
    + In preparation for having the PCI MMIO helpers use the new generic I/O
    + space management (logical PIO) we need to add the fwnode handler as an
    extra input parameter.
    - This patch changes the signature of pci_register_io_range() and of
    - its callers as needed.

    - Signed-off-by: Gabriele Paoloni <gabriele.paoloni@huawei.com>
    - Acked-by: Bjorn Helgaas <bhelgaas@google.com>
    - Acked-by: Rob Herring <robh@kernel.org>
    - Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
    + Changes the signature of pci_register_io_range() and its callers as
    + needed.
    +
    Tested-by: dann frazier <dann.frazier@canonical.com>
    + Signed-off-by: Gabriele Paoloni <gabriele.paoloni@huawei.com>
    Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
    + Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
    + Acked-by: Rob Herring <robh@kernel.org>

    -commit 0b0694ca8843
    +commit c9f9c9eed8e2
    Author: Gabriele Paoloni <gabriele.paoloni@huawei.com>
    Date: Thu Mar 15 02:15:51 2018 +0800

    - PCI: Remove unused __weak attribute in pci_register_io_range()
    + PCI: Remove __weak tag from pci_register_io_range()

    - Currently pci_register_io_range() has only one definition;
    - therefore there is no use of the __weak attribute.
    + pci_register_io_range() has only one definition, so there is no need for
    + the __weak attribute. Remove it.

    - Signed-off-by: Gabriele Paoloni <gabriele.paoloni@huawei.com>
    - Acked-by: Bjorn Helgaas <bhelgaas@google.com>
    - Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
    Tested-by: dann frazier <dann.frazier@canonical.com>
    + Signed-off-by: Gabriele Paoloni <gabriele.paoloni@huawei.com>
    Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
    + Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>

    -commit f3ac523feb71
    +commit e180fa3830cf
    Author: Zhichang Yuan <yuanzhichang@hisilicon.com>
    Date: Thu Mar 15 02:15:50 2018 +0800

    - LIB: Introduce a generic PIO mapping method
    + lib: Add generic PIO mapping method

    - 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.
    + 41f8bba7f555 ("of/pci: Add pci_register_io_range() and
    + pci_pio_to_address()") added support for PCI I/O space mapped into CPU
    + physical memory space. With that support, the I/O ranges configured for
    + PCI/PCIe hosts on some architectures can be mapped to logical PIO and
    + converted easily between CPU address and the corresponding logical PIO.
    + Based on this, PCI I/O port space can be accessed via in/out accessors that
    + use memory read/write.
    +
    + But on some platforms, there are bus hosts that access I/O port space with
    + host-local I/O port addresses rather than memory addresses.
    +
    + Add a more generic I/O mapping method to support those devices. With 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.

    + Tested-by: dann frazier <dann.frazier@canonical.com>
    Signed-off-by: Zhichang Yuan <yuanzhichang@hisilicon.com>
    Signed-off-by: Gabriele Paoloni <gabriele.paoloni@huawei.com>
    Signed-off-by: John Garry <john.garry@huawei.com>
    - Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
    - Tested-by: dann frazier <dann.frazier@canonical.com>
    Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
    + Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
    diff --git a/Documentation/devicetree/bindings/arm/hisilicon/hisilicon-low-pin-count.txt b/Documentation/devicetree/bindings/arm/hisilicon/hisilicon-low-pin-count.txt
    index 213181f3aff9..10bd35f9207f 100644
    --- a/Documentation/devicetree/bindings/arm/hisilicon/hisilicon-low-pin-count.txt
    +++ b/Documentation/devicetree/bindings/arm/hisilicon/hisilicon-low-pin-count.txt
    @@ -1,8 +1,8 @@
    -Hisilicon Hip06 low-pin-count device
    +Hisilicon Hip06 Low Pin Count device
    Hisilicon Hip06 SoCs implement a Low Pin Count (LPC) controller, which
    provides I/O access to some legacy ISA devices.
    Hip06 is based on arm64 architecture where there is no I/O space. So, the
    - I/O ports here are not cpu addresses, and there is no 'ranges' property in
    + I/O ports here are not CPU addresses, and there is no 'ranges' property in
    LPC device node.

    Required properties:
    diff --git a/drivers/bus/Kconfig b/drivers/bus/Kconfig
    index 88739f697ab5..a3fad0f0292f 100644
    --- a/drivers/bus/Kconfig
    +++ b/drivers/bus/Kconfig
    @@ -66,12 +66,12 @@ config BRCMSTB_GISB_ARB
    and internal bus master decoding.

    config HISILICON_LPC
    - bool "Support for ISA I/O space on Hisilicon hip06/7"
    + bool "Support for ISA I/O space on HiSilicon Hip06/7"
    depends on ARM64 && (ARCH_HISI || COMPILE_TEST)
    select INDIRECT_PIO
    help
    - Driver needed for some legacy ISA devices attached to Low-Pin-Count
    - on Hisilicon hip06/7 SoC.
    + Driver to enable I/O access to devices attached to the Low Pin
    + Count bus on the HiSilicon Hip06/7 SoC.

    config IMX_WEIM
    bool "Freescale EIM DRIVER"
    diff --git a/drivers/bus/hisi_lpc.c b/drivers/bus/hisi_lpc.c
    index 9d38cfa17da1..2d4611e4c339 100644
    --- a/drivers/bus/hisi_lpc.c
    +++ b/drivers/bus/hisi_lpc.c
    @@ -4,7 +4,6 @@
    * Author: Zhichang Yuan <yuanzhichang@hisilicon.com>
    * Author: Zou Rongrong <zourongrong@huawei.com>
    * Author: John Garry <john.garry@huawei.com>
    - *
    */

    #include <linux/acpi.h>
    @@ -23,16 +22,15 @@
    #define DRV_NAME "hisi-lpc"

    /*
    - * Setting this bit means each IO operation will target to a
    - * different port address:
    - * 0 means repeatedly IO operations will stick on the same port,
    - * such as BT;
    + * Setting this bit means each IO operation will target a different port
    + * address; 0 means repeated IO operations will use the same port,
    + * such as BT.
    */
    #define FG_INCRADDR_LPC 0x02

    struct lpc_cycle_para {
    unsigned int opflags;
    - unsigned int csize; /* the data length of each operation */
    + unsigned int csize; /* data length of each operation */
    };

    struct hisi_lpc_dev {
    @@ -41,7 +39,7 @@ struct hisi_lpc_dev {
    struct logic_pio_hwaddr *io_host;
    };

    -/* The maxIO cycle counts supported is four per operation at maximum */
    +/* The max IO cycle counts supported is four per operation at maximum */
    #define LPC_MAX_DWIDTH 4

    #define LPC_REG_STARTUP_SIGNAL 0x00
    @@ -57,27 +55,30 @@ struct hisi_lpc_dev {
    #define LPC_REG_WDATA 0x24 /* write FIFO */
    #define LPC_REG_RDATA 0x28 /* read FIFO */

    -/* The minimal nanosecond interval for each query on LPC cycle status. */
    +/* The minimal nanosecond interval for each query on LPC cycle status */
    #define LPC_NSEC_PERWAIT 100

    /*
    - * The maximum waiting time is about 128us.
    - * It is specific for stream I/O, such as ins.
    + * The maximum waiting time is about 128us. It is specific for stream I/O,
    + * such as ins.
    + *
    * The fastest IO cycle time is about 390ns, but the worst case will wait
    - * for extra 256 lpc clocks, so (256 + 13) * 30ns = 8 us. The maximum
    - * burst cycles is 16. So, the maximum waiting time is about 128us under
    - * worst case.
    - * choose 1300 as the maximum.
    + * for extra 256 lpc clocks, so (256 + 13) * 30ns = 8 us. The maximum burst
    + * cycles is 16. So, the maximum waiting time is about 128us under worst
    + * case.
    + *
    + * Choose 1300 as the maximum.
    */
    #define LPC_MAX_WAITCNT 1300
    -/* About 10us. This is specific for single IO operation, such as inb. */
    +
    +/* About 10us. This is specific for single IO operations, such as inb */
    #define LPC_PEROP_WAITCNT 100

    -static inline int wait_lpc_idle(unsigned char *mbase,
    - unsigned int waitcnt) {
    - do {
    - u32 status;
    +static int wait_lpc_idle(unsigned char *mbase, unsigned int waitcnt)
    +{
    + u32 status;

    + do {
    status = readl(mbase + LPC_REG_OP_STATUS);
    if (status & LPC_REG_OP_STATUS_IDLE)
    return (status & LPC_REG_OP_STATUS_FINISHED) ? 0 : -EIO;
    @@ -97,10 +98,9 @@ static inline int wait_lpc_idle(unsigned char *mbase,
    *
    * Returns 0 on success, non-zero on fail.
    */
    -static int
    -hisi_lpc_target_in(struct hisi_lpc_dev *lpcdev, struct lpc_cycle_para *para,
    - unsigned long addr, unsigned char *buf,
    - unsigned long opcnt)
    +static int hisi_lpc_target_in(struct hisi_lpc_dev *lpcdev,
    + struct lpc_cycle_para *para, unsigned long addr,
    + unsigned char *buf, unsigned long opcnt)
    {
    unsigned int cmd_word;
    unsigned int waitcnt;
    @@ -121,9 +121,7 @@ hisi_lpc_target_in(struct hisi_lpc_dev *lpcdev, struct lpc_cycle_para *para,
    spin_lock_irqsave(&lpcdev->cycle_lock, flags);

    writel_relaxed(opcnt, lpcdev->membase + LPC_REG_OP_LEN);
    -
    writel_relaxed(cmd_word, lpcdev->membase + LPC_REG_CMD);
    -
    writel_relaxed(addr, lpcdev->membase + LPC_REG_ADDR);

    writel(LPC_REG_STARTUP_SIGNAL_START,
    @@ -153,10 +151,9 @@ hisi_lpc_target_in(struct hisi_lpc_dev *lpcdev, struct lpc_cycle_para *para,
    *
    * Returns 0 on success, non-zero on fail.
    */
    -static int
    -hisi_lpc_target_out(struct hisi_lpc_dev *lpcdev, struct lpc_cycle_para *para,
    - unsigned long addr, const unsigned char *buf,
    - unsigned long opcnt)
    +static int hisi_lpc_target_out(struct hisi_lpc_dev *lpcdev,
    + struct lpc_cycle_para *para, unsigned long addr,
    + const unsigned char *buf, unsigned long opcnt)
    {
    unsigned int waitcnt;
    unsigned long flags;
    @@ -193,17 +190,17 @@ hisi_lpc_target_out(struct hisi_lpc_dev *lpcdev, struct lpc_cycle_para *para,
    return ret;
    }

    -static inline unsigned long
    -hisi_lpc_pio_to_addr(struct hisi_lpc_dev *lpcdev, unsigned long pio)
    +static unsigned long hisi_lpc_pio_to_addr(struct hisi_lpc_dev *lpcdev,
    + unsigned long pio)
    {
    return pio - lpcdev->io_host->io_start + lpcdev->io_host->hw_start;
    }

    /*
    * hisi_lpc_comm_in - input the data in a single operation
    - * @hostdata: pointer to the device information relevant to LPC controller.
    - * @pio: the target I/O port address.
    - * @dwidth: the data length required to read from the target I/O port.
    + * @hostdata: pointer to the device information relevant to LPC controller
    + * @pio: the target I/O port address
    + * @dwidth: the data length required to read from the target I/O port
    *
    * When success, data is returned. Otherwise, ~0 is returned.
    */
    @@ -233,16 +230,15 @@ static u32 hisi_lpc_comm_in(void *hostdata, unsigned long pio, size_t dwidth)

    /*
    * hisi_lpc_comm_out - output the data in a single operation
    - * @hostdata: pointer to the device information relevant to LPC controller.
    - * @pio: the target I/O port address.
    - * @val: a value to be outputted from caller, maximum is four bytes.
    - * @dwidth: the data width required writing to the target I/O port.
    - *
    - * This function is corresponding to out(b,w,l) only
    + * @hostdata: pointer to the device information relevant to LPC controller
    + * @pio: the target I/O port address
    + * @val: a value to be output from caller, maximum is four bytes
    + * @dwidth: the data width required writing to the target I/O port
    *
    + * This function corresponds to out(b,w,l) only.
    */
    static void hisi_lpc_comm_out(void *hostdata, unsigned long pio,
    - u32 val, size_t dwidth)
    + u32 val, size_t dwidth)
    {
    struct hisi_lpc_dev *lpcdev = hostdata;
    struct lpc_cycle_para iopara;
    @@ -265,19 +261,17 @@ static void hisi_lpc_comm_out(void *hostdata, unsigned long pio,

    /*
    * hisi_lpc_comm_ins - input the data in the buffer in multiple operations
    - * @hostdata: pointer to the device information relevant to LPC controller.
    - * @pio: the target I/O port address.
    - * @buffer: a buffer where read/input data bytes are stored.
    - * @dwidth: the data width required writing to the target I/O port.
    - * @count: how many data units whose length is dwidth will be read.
    + * @hostdata: pointer to the device information relevant to LPC controller
    + * @pio: the target I/O port address
    + * @buffer: a buffer where read/input data bytes are stored
    + * @dwidth: the data width required writing to the target I/O port
    + * @count: how many data units whose length is dwidth will be read
    *
    * When success, the data read back is stored in buffer pointed by buffer.
    - * Returns 0 on success, -errno otherwise
    - *
    + * Returns 0 on success, -errno otherwise.
    */
    -static u32
    -hisi_lpc_comm_ins(void *hostdata, unsigned long pio, void *buffer,
    - size_t dwidth, unsigned int count)
    +static u32 hisi_lpc_comm_ins(void *hostdata, unsigned long pio, void *buffer,
    + size_t dwidth, unsigned int count)
    {
    struct hisi_lpc_dev *lpcdev = hostdata;
    unsigned char *buf = buffer;
    @@ -308,16 +302,15 @@ hisi_lpc_comm_ins(void *hostdata, unsigned long pio, void *buffer,

    /*
    * hisi_lpc_comm_outs - output the data in the buffer in multiple operations
    - * @hostdata: pointer to the device information relevant to LPC controller.
    - * @pio: the target I/O port address.
    - * @buffer: a buffer where write/output data bytes are stored.
    - * @dwidth: the data width required writing to the target I/O port .
    - * @count: how many data units whose length is dwidth will be written.
    - *
    + * @hostdata: pointer to the device information relevant to LPC controller
    + * @pio: the target I/O port address
    + * @buffer: a buffer where write/output data bytes are stored
    + * @dwidth: the data width required writing to the target I/O port
    + * @count: how many data units whose length is dwidth will be written
    */
    -static void
    -hisi_lpc_comm_outs(void *hostdata, unsigned long pio, const void *buffer,
    - size_t dwidth, unsigned int count)
    +static void hisi_lpc_comm_outs(void *hostdata, unsigned long pio,
    + const void *buffer, size_t dwidth,
    + unsigned int count)
    {
    struct hisi_lpc_dev *lpcdev = hostdata;
    struct lpc_cycle_para iopara;
    @@ -384,13 +377,12 @@ static int hisi_lpc_acpi_xlat_io_res(struct acpi_device *adev,
    * Returns 0 when successful, and a negative value for failure.
    *
    * For a given host controller, each child device will have an associated
    - * host-relative address resource. This function will return the translated
    + * host-relative address resource. This function will return the translated
    * logical PIO addresses for each child devices resources.
    */
    static int hisi_lpc_acpi_set_io_res(struct device *child,
    struct device *hostdev,
    - const struct resource **res,
    - int *num_res)
    + const struct resource **res, int *num_res)
    {
    struct acpi_device *adev;
    struct acpi_device *host;
    @@ -406,12 +398,11 @@ static int hisi_lpc_acpi_set_io_res(struct device *child,
    host = to_acpi_device(hostdev);
    adev = to_acpi_device(child);

    - /* check the device state */
    if (!adev->status.present) {
    dev_dbg(child, "device is not present\n");
    return -EIO;
    }
    - /* whether the child had been enumerated? */
    +
    if (acpi_device_enumerated(adev)) {
    dev_dbg(child, "has been enumerated\n");
    return -EIO;
    @@ -450,7 +441,8 @@ static int hisi_lpc_acpi_set_io_res(struct device *child,
    continue;
    ret = hisi_lpc_acpi_xlat_io_res(adev, host, &resources[i]);
    if (ret) {
    - dev_err(child, "translate IO range failed(%d)\n", ret);
    + dev_err(child, "translate IO range %pR failed (%d)\n",
    + &resources[i], ret);
    return ret;
    }
    }
    @@ -501,7 +493,7 @@ static int hisi_lpc_acpi_probe(struct device *hostdev)
    };

    /*
    - * For any instances of this host controller (hip06 and hip07
    + * For any instances of this host controller (Hip06 and Hip07
    * are the only chipsets), we would not have multiple slaves
    * with the same HID. And in any system we would have just one
    * controller active. So don't worrry about MFD name clashes.
    @@ -518,7 +510,7 @@ static int hisi_lpc_acpi_probe(struct device *hostdev)
    &mfd_cell->resources,
    &mfd_cell->num_resources);
    if (ret) {
    - dev_warn(&child->dev, "set resource fail(%d)\n", ret);
    + dev_warn(&child->dev, "set resource fail (%d)\n", ret);
    return ret;
    }
    count++;
    @@ -576,6 +568,7 @@ static int hisi_lpc_probe(struct platform_device *pdev)
    range = devm_kzalloc(dev, sizeof(*range), GFP_KERNEL);
    if (!range)
    return -ENOMEM;
    +
    range->fwnode = dev->fwnode;
    range->flags = LOGIC_PIO_INDIRECT;
    range->size = PIO_INDIRECT_SIZE;
    @@ -588,10 +581,10 @@ static int hisi_lpc_probe(struct platform_device *pdev)
    lpcdev->io_host = range;

    /* register the LPC host PIO resources */
    - if (!acpi_device)
    - ret = of_platform_populate(dev->of_node, NULL, NULL, dev);
    - else
    + if (acpi_device)
    ret = hisi_lpc_acpi_probe(dev);
    + else
    + ret = of_platform_populate(dev->of_node, NULL, NULL, dev);
    if (ret)
    return ret;

    @@ -619,5 +612,4 @@ static struct platform_driver hisi_lpc_driver = {
    },
    .probe = hisi_lpc_probe,
    };
    -
    builtin_platform_driver(hisi_lpc_driver);
    diff --git a/drivers/of/address.c b/drivers/of/address.c
    index c434f65922bc..53349912ac75 100644
    --- a/drivers/of/address.c
    +++ b/drivers/of/address.c
    @@ -738,11 +738,11 @@ static u64 of_translate_ioport(struct device_node *dev, const __be32 *in_addr,

    taddr = __of_translate_address(dev, in_addr, "ranges", &host);
    if (host) {
    - /* host specific port access */
    + /* host-specific port access */
    port = logic_pio_trans_hwaddr(&host->fwnode, taddr, size);
    of_node_put(host);
    } else {
    - /* memory mapped I/O range */
    + /* memory-mapped I/O range */
    port = pci_address_to_pio(taddr);
    }

    diff --git a/include/linux/logic_pio.h b/include/linux/logic_pio.h
    index 8c78ff449d81..cbd9d8495690 100644
    --- a/include/linux/logic_pio.h
    +++ b/include/linux/logic_pio.h
    @@ -1,9 +1,8 @@
    // SPDX-License-Identifier: GPL-2.0+
    /*
    - * Copyright (C) 2017 Hisilicon Limited, All Rights Reserved.
    + * Copyright (C) 2017 HiSilicon Limited, All Rights Reserved.
    * Author: Gabriele Paoloni <gabriele.paoloni@huawei.com>
    * Author: Zhichang Yuan <yuanzhichang@hisilicon.com>
    - *
    */

    #ifndef __LINUX_LOGIC_PIO_H
    @@ -13,7 +12,7 @@

    enum {
    LOGIC_PIO_INDIRECT, /* Indirect IO flag */
    - LOGIC_PIO_CPU_MMIO, /* Memory mapped IO flag */
    + LOGIC_PIO_CPU_MMIO, /* Memory-mapped IO flag */
    };

    struct logic_pio_hwaddr {
    @@ -104,8 +103,8 @@ void logic_outsl(unsigned long addr, const void *buffer, unsigned int count);
    #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
    + * We reserve 0x4000 bytes for Indirect IO as so far this library is only
    + * used by the HiSilicon LPC Host. If needed, we can reserve a wider IO
    * area by redefining the macro below.
    */
    #define PIO_INDIRECT_SIZE 0x4000
    @@ -118,7 +117,7 @@ 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);
    +resource_size_t logic_pio_to_hwaddr(unsigned long pio);
    +unsigned long logic_pio_trans_cpuaddr(resource_size_t hw_addr);

    #endif /* __LINUX_LOGIC_PIO_H */
    diff --git a/lib/Kconfig b/lib/Kconfig
    index d9dd02cfe176..5fe577673b98 100644
    --- a/lib/Kconfig
    +++ b/lib/Kconfig
    @@ -62,9 +62,10 @@ config INDIRECT_PIO
    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
    + 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.

    diff --git a/lib/logic_pio.c b/lib/logic_pio.c
    index 8394c2d4e534..dc3e9695f7f5 100644
    --- a/lib/logic_pio.c
    +++ b/lib/logic_pio.c
    @@ -1,9 +1,8 @@
    // SPDX-License-Identifier: GPL-2.0+
    /*
    - * Copyright (C) 2017 Hisilicon Limited, All Rights Reserved.
    + * Copyright (C) 2017 HiSilicon Limited, All Rights Reserved.
    * Author: Gabriele Paoloni <gabriele.paoloni@huawei.com>
    * Author: Zhichang Yuan <yuanzhichang@hisilicon.com>
    - *
    */

    #define pr_fmt(fmt) "LOGIC PIO: " fmt
    @@ -16,7 +15,7 @@
    #include <linux/sizes.h>
    #include <linux/slab.h>

    -/* The unique hardware address list. */
    +/* The unique hardware address list */
    static LIST_HEAD(io_range_list);
    static DEFINE_MUTEX(io_range_mutex);

    @@ -25,11 +24,11 @@ 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.
    + * @new_range: pointer to the IO range to be registered.
    *
    - * returns 0 on success, the error code in case of failure
    + * Returns 0 on success, the error code in case of failure.
    *
    - * Register a new io range node in the io range list.
    + * Register a new IO range node in the IO range list.
    */
    int logic_pio_register_range(struct logic_pio_hwaddr *new_range)
    {
    @@ -101,10 +100,9 @@ int logic_pio_register_range(struct logic_pio_hwaddr *new_range)
    * 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
    + * 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.
    + * Traverse the io_range_list to find the registered node for @fwnode.
    */
    struct logic_pio_hwaddr *find_io_range_by_fwnode(struct fwnode_handle *fwnode)
    {
    @@ -126,7 +124,7 @@ static struct logic_pio_hwaddr *find_io_range(unsigned long pio)
    if (in_range(pio, range->io_start, range->size))
    return range;
    }
    - pr_err("PIO entry token invalid\n");
    + pr_err("PIO entry token %lx invalid\n", pio);
    return NULL;
    }

    @@ -134,21 +132,20 @@ static struct logic_pio_hwaddr *find_io_range(unsigned long pio)
    * logic_pio_to_hwaddr - translate logical PIO to HW address
    * @pio: logical PIO value
    *
    - * Returns HW address if valid, ~0 otherwise
    + * Returns HW address if valid, ~0 otherwise.
    *
    - * Translate the input logical pio to the corresponding hardware address.
    - * The input pio should be unique in the whole logical PIO space.
    + * 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)~0;

    range = find_io_range(pio);
    if (range)
    - hwaddr = range->hw_start + pio - range->io_start;
    + return = range->hw_start + pio - range->io_start;

    - return hwaddr;
    + return (resource_size_t)~0;
    }

    /**
    @@ -159,15 +156,14 @@ resource_size_t logic_pio_to_hwaddr(unsigned long pio)
    *
    * 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)
    +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");
    + pr_err("IO range not found or invalid\n");
    return ~0UL;
    }
    if (range->size < size) {
    @@ -178,8 +174,7 @@ logic_pio_trans_hwaddr(struct fwnode_handle *fwnode, resource_size_t addr,
    return addr - range->hw_start + range->io_start;
    }

    -unsigned long
    -logic_pio_trans_cpuaddr(resource_size_t addr)
    +unsigned long logic_pio_trans_cpuaddr(resource_size_t addr)
    {
    struct logic_pio_hwaddr *range;

    @@ -189,7 +184,8 @@ logic_pio_trans_cpuaddr(resource_size_t addr)
    if (in_range(addr, range->hw_start, range->size))
    return addr - range->hw_start + range->io_start;
    }
    - pr_err("addr not registered in io_range_list\n");
    + pr_err("addr %llx not registered in io_range_list\n",
    + (unsigned long long) addr);
    return ~0UL;
    }

    \
     
     \ /
      Last update: 2018-03-22 00:40    [W:7.002 / U:0.048 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site