* [PATCH 3/6] reset: hisilicon: add reset-hi3660
From: zhangfei @ 2016-11-22 10:02 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <3166877.sQekoU5ezv@wuerfel>
On 2016?11?22? 17:42, Arnd Bergmann wrote:
> On Tuesday, November 22, 2016 5:34:05 PM CET zhangfei wrote:
>> On 2016?11?22? 16:50, Arnd Bergmann wrote:
>>> On Tuesday, November 22, 2016 3:49:18 PM CET Zhangfei Gao wrote:
>>>> +static const struct hisi_reset_channel_data hi3660_iomcu_rst[] = {
>>>> + [HI3660_RST_I2C0] = HISI_RST_SEP(0x20, 3),
>>>> + [HI3660_RST_I2C1] = HISI_RST_SEP(0x20, 4),
>>>> + [HI3660_RST_I2C2] = HISI_RST_SEP(0x20, 5),
>>>> + [HI3660_RST_I2C6] = HISI_RST_SEP(0x20, 27),
>>>> +};
>>>> +
>>>> +static struct hisi_reset_controller_data hi3660_iomcu_controller = {
>>>> + .nr_channels = ARRAY_SIZE(hi3660_iomcu_rst),
>>>> + .channels = hi3660_iomcu_rst,
>>>> +};
>>>> +
>>>> +static const struct hisi_reset_channel_data hi3660_crgctrl_rst[] = {
>>>> + [HI3660_RST_I2C3] = HISI_RST_SEP(0x78, 7),
>>>> + [HI3660_RST_I2C4] = HISI_RST_SEP(0x78, 27),
>>>> + [HI3660_RST_I2C7] = HISI_RST_SEP(0x60, 14),
>>>> + [HI3660_RST_SD] = HISI_RST_SEP(0x90, 18),
>>>> + [HI3660_RST_SDIO] = HISI_RST_SEP(0x90, 20),
>>>> + [HI3660_RST_UFS] = HISI_RST_SEP(0x84, 12),
>>>> + [HI3660_RST_UFS_ASSERT] = HISI_RST_SEP(0x84, 7),
>>>> + [HI3660_RST_PCIE_SYS] = HISI_RST_SEP(0x84, 26),
>>>> + [HI3660_RST_PCIE_PHY] = HISI_RST_SEP(0x84, 27),
>>>> + [HI3660_RST_PCIE_BUS] = HISI_RST_SEP(0x84, 31),
>>>> + [HI3660_RST_USB3OTG_PHY] = HISI_RST_SEP(0x90, 3),
>>>> + [HI3660_RST_USB3OTG] = HISI_RST_SEP(0x90, 5),
>>>> + [HI3660_RST_USB3OTG_32K] = HISI_RST_SEP(0x90, 6),
>>>> + [HI3660_RST_USB3OTG_AHB] = HISI_RST_SEP(0x90, 7),
>>>> + [HI3660_RST_USB3OTG_MUX] = HISI_RST_SEP(0x90, 8),
>>>> +};
>>> I think you can avoid the trap of the ABI incompatibility if
>>> you just define those as in the binding as tuples, using #reset-cells=2.
>>>
>>> In particular for the first set, it seems really silly to redefine
>>> the numbers when there is just a simple integer number.
>> Could you clarify more, still not understand.
>> The number is index of the arrays, and the index will be used in dts.
>> The arrays lists the registers offset and bit shift.
>> For example:
>>
>> [HI3660_RST_I2C0] = HISI_RST_SEP(0x20, 3), means register offset : 0x20, and bit shift = 3.
>>
>> And Documentation/devicetree/bindings/reset/reset.txt
>> Required properties:
>> #reset-cells: Number of cells in a reset specifier; Typically 0 for nodes
>> with a single reset output and 1 for nodes with multiple
>> reset outputs.
> You can easily enumerate the registers that contain reset bits here,
> so just use one cell for the register and another one for the index.
/* reset separated register offset is 0x4 */
#define HISI_RST_SEP(off, bit) \
{ .enable = REG_FIELD(off, bit, bit), \
.disable = REG_FIELD(off + 0x4, bit, bit), \
.status = REG_FIELD(off + 0x8, bit, bit), }
We not only provide the off and bit shift, but fulfill the members in
the meantime.
Thanks
^ permalink raw reply
* [RFC PATCH 06/11] ARM: tlbflush: drop dependency on CONFIG_SMP
From: Russell King - ARM Linux @ 2016-11-22 10:03 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1479806768-39911-7-git-send-email-vladimir.murzin@arm.com>
On Tue, Nov 22, 2016 at 09:26:03AM +0000, Vladimir Murzin wrote:
> It can be referenced in UP case as well.
What's missing is an explanation of why you want this change.
Exposing the local_* stuff doesn't make sense for UP.
> Cc: Russell King <linux@armlinux.org.uk>
> Signed-off-by: Vladimir Murzin <vladimir.murzin@arm.com>
> ---
> arch/arm/include/asm/tlbflush.h | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/arch/arm/include/asm/tlbflush.h b/arch/arm/include/asm/tlbflush.h
> index def9e57..d9a6e2e 100644
> --- a/arch/arm/include/asm/tlbflush.h
> +++ b/arch/arm/include/asm/tlbflush.h
> @@ -641,7 +641,7 @@ static inline void update_mmu_cache(struct vm_area_struct *vma,
>
> #endif
>
> -#elif defined(CONFIG_SMP) /* !CONFIG_MMU */
> +#else /* !CONFIG_MMU */
>
> #ifndef __ASSEMBLY__
>
> --
> 1.7.9.5
>
--
RMK's Patch system: http://www.armlinux.org.uk/developer/patches/
FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up
according to speedtest.net.
^ permalink raw reply
* [RFC PATCH 09/11] ARM: NOMMU: define SECTION_xxx macros
From: Russell King - ARM Linux @ 2016-11-22 10:07 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1479806768-39911-10-git-send-email-vladimir.murzin@arm.com>
On Tue, Nov 22, 2016 at 09:26:06AM +0000, Vladimir Murzin wrote:
> Pickup defines from pgtable-2level.h to make NOMMU build happy.
This needs more detail.
>
> Cc: Russell King <linux@armlinux.org.uk>
> Signed-off-by: Vladimir Murzin <vladimir.murzin@arm.com>
> ---
> arch/arm/include/asm/pgtable-nommu.h | 5 +++++
> 1 file changed, 5 insertions(+)
>
> diff --git a/arch/arm/include/asm/pgtable-nommu.h b/arch/arm/include/asm/pgtable-nommu.h
> index add094d..9115801 100644
> --- a/arch/arm/include/asm/pgtable-nommu.h
> +++ b/arch/arm/include/asm/pgtable-nommu.h
> @@ -35,6 +35,11 @@
>
> #define PGDIR_SIZE (1UL << PGDIR_SHIFT)
> #define PGDIR_MASK (~(PGDIR_SIZE-1))
> +
> +#define SECTION_SHIFT 20
> +#define SECTION_SIZE (1UL << SECTION_SHIFT)
> +#define SECTION_MASK (~(SECTION_SIZE-1))
> +
> /* FIXME */
>
> #define PAGE_NONE __pgprot(0)
> --
> 1.7.9.5
>
--
RMK's Patch system: http://www.armlinux.org.uk/developer/patches/
FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up
according to speedtest.net.
^ permalink raw reply
* [PATCH] PCI: Add information about describing PCI in ACPI
From: Ard Biesheuvel @ 2016-11-22 10:09 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161117175938.17465.45820.stgit@bhelgaas-glaptop.roam.corp.google.com>
On 17 November 2016 at 17:59, Bjorn Helgaas <bhelgaas@google.com> wrote:
> Add a writeup about how PCI host bridges should be described in ACPI
> using PNP0A03/PNP0A08 devices, PNP0C02 devices, and the MCFG table.
>
> Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
> ---
> Documentation/PCI/00-INDEX | 2 +
> Documentation/PCI/acpi-info.txt | 136 +++++++++++++++++++++++++++++++++++++++
> 2 files changed, 138 insertions(+)
> create mode 100644 Documentation/PCI/acpi-info.txt
>
> diff --git a/Documentation/PCI/00-INDEX b/Documentation/PCI/00-INDEX
> index 147231f..0780280 100644
> --- a/Documentation/PCI/00-INDEX
> +++ b/Documentation/PCI/00-INDEX
> @@ -1,5 +1,7 @@
> 00-INDEX
> - this file
> +acpi-info.txt
> + - info on how PCI host bridges are represented in ACPI
> MSI-HOWTO.txt
> - the Message Signaled Interrupts (MSI) Driver Guide HOWTO and FAQ.
> PCIEBUS-HOWTO.txt
> diff --git a/Documentation/PCI/acpi-info.txt b/Documentation/PCI/acpi-info.txt
> new file mode 100644
> index 0000000..ccbcfda
> --- /dev/null
> +++ b/Documentation/PCI/acpi-info.txt
> @@ -0,0 +1,136 @@
> + ACPI considerations for PCI host bridges
> +
> +The basic requirement is that the ACPI namespace should describe
> +*everything* that consumes address space unless there's another
> +standard way for the OS to find it [1, 2]. For example, windows that
> +are forwarded to PCI by a PCI host bridge should be described via ACPI
> +devices, since the OS can't locate the host bridge by itself. PCI
> +devices *below* the host bridge do not need to be described via ACPI,
> +because the resources they consume are inside the host bridge windows,
> +and the OS can discover them via the standard PCI enumeration
> +mechanism (using config accesses to read and size the BARs).
> +
> +This ACPI resource description is done via _CRS methods of devices in
> +the ACPI namespace [2]. _CRS methods are like generalized PCI BARs:
> +the OS can read _CRS and figure out what resource is being consumed
> +even if it doesn't have a driver for the device [3]. That's important
> +because it means an old OS can work correctly even on a system with
> +new devices unknown to the OS. The new devices won't do anything, but
> +the OS can at least make sure no resources conflict with them.
> +
> +Static tables like MCFG, HPET, ECDT, etc., are *not* mechanisms for
> +reserving address space! The static tables are for things the OS
> +needs to know early in boot, before it can parse the ACPI namespace.
> +If a new table is defined, an old OS needs to operate correctly even
> +though it ignores the table. _CRS allows that because it is generic
> +and understood by the old OS; a static table does not.
> +
> +If the OS is expected to manage an ACPI device, that device will have
> +a specific _HID/_CID that tells the OS what driver to bind to it, and
> +the _CRS tells the OS and the driver where the device's registers are.
> +
> +PNP0C02 "motherboard" devices are basically a catch-all. There's no
> +programming model for them other than "don't use these resources for
> +anything else." So any address space that is (1) not claimed by some
> +other ACPI device and (2) should not be assigned by the OS to
> +something else, should be claimed by a PNP0C02 _CRS method.
> +
> +PCI host bridges are PNP0A03 or PNP0A08 devices. Their _CRS should
> +describe all the address space they consume. In principle, this would
> +be all the windows they forward down to the PCI bus, as well as the
> +bridge registers themselves. The bridge registers include things like
> +secondary/subordinate bus registers that determine the bus range below
> +the bridge, window registers that describe the apertures, etc. These
> +are all device-specific, non-architected things, so the only way a
> +PNP0A03/PNP0A08 driver can manage them is via _PRS/_CRS/_SRS, which
> +contain the device-specific details. These bridge registers also
> +include ECAM space, since it is consumed by the bridge.
> +
> +ACPI defined a Producer/Consumer bit that was intended to distinguish
> +the bridge apertures from the bridge registers [4, 5]. However,
> +BIOSes didn't use that bit correctly, and the result is that OSes have
> +to assume that everything in a PCI host bridge _CRS is a window. That
> +leaves no way to describe the bridge registers in the PNP0A03/PNP0A08
> +device itself.
> +
Is that universally true? Or is it still possible to do the right
thing here on new ACPI architectures such as arm64?
> +The workaround is to describe the bridge registers (including ECAM
> +space) in PNP0C02 catch-all devices [6]. With the exception of ECAM,
> +the bridge register space is device-specific anyway, so the generic
> +PNP0A03/PNP0A08 driver (pci_root.c) has no need to know about it. For
> +ECAM, pci_root.c learns about the space from either MCFG or the _CBA
> +method.
> +
> +Note that the PCIe spec actually does require ECAM unless there's a
> +standard firmware interface for config access, e.g., the ia64 SAL
> +interface [7]. One reason is that we want a generic host bridge
> +driver (pci_root.c), and a generic driver requires a generic way to
> +access config space.
> +
> +
> +[1] ACPI 6.0, sec 6.1:
> + For any device that is on a non-enumerable type of bus (for
> + example, an ISA bus), OSPM enumerates the devices' identifier(s)
> + and the ACPI system firmware must supply an _HID object ... for
> + each device to enable OSPM to do that.
> +
> +[2] ACPI 6.0, sec 3.7:
> + The OS enumerates motherboard devices simply by reading through
> + the ACPI Namespace looking for devices with hardware IDs.
> +
> + Each device enumerated by ACPI includes ACPI-defined objects in
> + the ACPI Namespace that report the hardware resources the device
> + could occupy [_PRS], an object that reports the resources that are
> + currently used by the device [_CRS], and objects for configuring
> + those resources [_SRS]. The information is used by the Plug and
> + Play OS (OSPM) to configure the devices.
> +
> +[3] ACPI 6.0, sec 6.2:
> + OSPM uses device configuration objects to configure hardware
> + resources for devices enumerated via ACPI. Device configuration
> + objects provide information about current and possible resource
> + requirements, the relationship between shared resources, and
> + methods for configuring hardware resources.
> +
> + When OSPM enumerates a device, it calls _PRS to determine the
> + resource requirements of the device. It may also call _CRS to
> + find the current resource settings for the device. Using this
> + information, the Plug and Play system determines what resources
> + the device should consume and sets those resources by calling the
> + device?s _SRS control method.
> +
> + In ACPI, devices can consume resources (for example, legacy
> + keyboards), provide resources (for example, a proprietary PCI
> + bridge), or do both. Unless otherwise specified, resources for a
> + device are assumed to be taken from the nearest matching resource
> + above the device in the device hierarchy.
> +
> +[4] ACPI 6.0, sec 6.4.3.5.4:
> + Extended Address Space Descriptor
> + General Flags: Bit [0] Consumer/Producer:
> + 1?This device consumes this resource
> + 0?This device produces and consumes this resource
> +
> +[5] ACPI 6.0, sec 19.6.43:
> + ResourceUsage specifies whether the Memory range is consumed by
> + this device (ResourceConsumer) or passed on to child devices
> + (ResourceProducer). If nothing is specified, then
> + ResourceConsumer is assumed.
> +
> +[6] PCI Firmware 3.0, sec 4.1.2:
> + If the operating system does not natively comprehend reserving the
> + MMCFG region, the MMCFG region must be reserved by firmware. The
> + address range reported in the MCFG table or by _CBA method (see
> + Section 4.1.3) must be reserved by declaring a motherboard
> + resource. For most systems, the motherboard resource would appear
> + at the root of the ACPI namespace (under \_SB) in a node with a
> + _HID of EISAID (PNP0C02), and the resources in this case should
> + not be claimed in the root PCI bus?s _CRS. The resources can
> + optionally be returned in Int15 E820 or EFIGetMemoryMap as
> + reserved memory but must always be reported through ACPI as a
> + motherboard resource.
> +
> +[7] PCI Express 3.0, sec 7.2.2:
> + For systems that are PC-compatible, or that do not implement a
> + processor-architecture-specific firmware interface standard that
> + allows access to the Configuration Space, the ECAM is required as
> + defined in this section.
>
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* [PATCH 1/3] ARM: davinci: hawk: fix mmc card detect gpio
From: Axel Haslam @ 2016-11-22 10:10 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <8ced1194-4c68-7385-1594-0983855e7c89@ti.com>
On Tue, Nov 22, 2016 at 10:53 AM, Sekhar Nori <nsekhar@ti.com> wrote:
> On Monday 21 November 2016 09:45 PM, Axel Haslam wrote:
>> The card detect gpio on the hawk board is gpio4_0 and not gpio3_12
>>
>> Signed-off-by: Axel Haslam <ahaslam@baylibre.com>
>
> The LCDK and HawkBoard are different boards. The HawkBoard schematic
> from eLinux.org page is broken, but looking for it on the net, I found
> one and the MMC/SD CD pin in that schematic is indeed connected to GPIO3_12.
>
> So I believe the original code is correct.
mmm, ok, the lcdk is booted using the hawk board file,
so we should differentiate the two boards?
or should we just live with inconsistencies on the lcdk?
(im guessing the same will be ture for the usb)
Regards
Axel.
>
> Thanks,
> Sekhar
>
^ permalink raw reply
* [RFC PATCH net v2 2/3] dt: bindings: add ethernet phy eee-disable-advert option documentation
From: Jerome Brunet @ 2016-11-22 10:13 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <e792c889-8725-3952-ca28-a08537d9f87a@gmail.com>
On Mon, 2016-11-21 at 21:35 -0800, Florian Fainelli wrote:
> Le 21/11/2016 ? 08:47, Andrew Lunn a ?crit :
> >
> > >
> > > What I did not realize when doing this patch for the realtek
> > > driver is
> > > that there is already 6 valid modes defined in the kernel
> > >
> > > #define MDIO_EEE_100TX MDIO_AN_EEE_ADV_100TX
> > > /*
> > > 100TX EEE cap */
> > > #define MDIO_EEE_1000T MDIO_AN_EEE_ADV_1000T
> > > /*
> > > 1000T EEE cap */
> > > #define MDIO_EEE_10GT 0x0008 /* 10GT EEE
> > > cap */
> > > #define MDIO_EEE_1000KX 0x0010 /* 1000KX
> > > EEE cap
> > > */
> > > #define MDIO_EEE_10GKX4 0x0020 /* 10G KX4
> > > EEE cap
> > > */
> > > #define MDIO_EEE_10GKR 0x0040 /* 10G KR EEE
> > > cap
> > > */
> > >
> > > I took care of only 2 in the case of realtek.c since it only
> > > support
> > > MDIO_EEE_100TX and MDIO_EEE_1000T.
> > >
> > > Defining a property for each is certainly doable but it does not
> > > look
> > > very nice either. If it extends in the future, it will get even
> > > more
> > > messier, especially if you want to disable everything.
> >
> > Yes, agreed.
>
> One risk with the definition a group of advertisement capabilities
> (under the form of a bitmask for instance) to enable/disable is that
> we
> end up with Device Tree contain some kind of configuration policy as
> opposed to just flagging particular hardware features as broken.
The code proposed only allows to disable EEE advertisement (not
enable), so we should not see it used as a configuration policy in DT.
To make this more explicit, I could replace the property "eee-advert-
disable" by "eee-broken" ?
>
> Fortunately, there does not seem to be a ton of PHYs out there which
> require EEE
It is quite difficult to have the real picture here because some PHYs
have EEE disabled by default and you have to explicitly enable it.
I have no idea of the ratio between the 2 phy policies.
> to be disabled to function properly so having individual
> properties vs. bitmasks/groups is kind of speculative here.
In the particular instance of the OdroidC2, disabling EEE for GbE only
enough. However, If you have a PHY broken with, I think it is likely
that you might want to disable all (supported) EEE modes. That's reason
why I prefer bitmask. I agree both are functionally similar, this is
kind of a cosmetic debate.
>
> Another approach to solving this problem could be to register a PHY
> fixup which disables EEE at the PHY level, and which is only called
> for
> specific boards affected by this problem
> (of_machine_is_compatible()).
> This code can leave in arch/*/* when that is possible,
That something I was looking at, but we don't have these files anymore
on ARM64 (looking at your comment, you already know this)
> or it can just be
> somewhere where it is relevant, e.g; in the PHY driver for instance
> (similarly to how PCI fixups are done).
Do you prefer having board specific code inside generic driver than
having the setting living in DT? Peppe told me they also had a few
platform with similar issues. The point is that this could be useful to
other people, so it could spread a grow a bit.
I would prefer having this in the DT, but I can definitely do it the
PHY with?of_machine_is_compatible() and register_fixup is this what you
prefer/want.?
Cheers
Jerome
^ permalink raw reply
* [PATCH v3] arm64/crypto: Accelerated CRC T10 DIF computation
From: YueHaibing @ 2016-11-22 10:14 UTC (permalink / raw)
To: linux-arm-kernel
This is the ARM64 CRC T10 DIF transform accelerated with the ARMv8
NEON instruction.The config CRYPTO_CRCT10DIF_NEON should be turned
on to enable the feature.The crc_t10dif crypto library function will
use this faster algorithm when crct10dif_neon module is loaded.
Tcrypt benchmark results:
HIP06 (mode=320 sec=2)
The ratio of bytes/sec crct10dif-neon Vs. crct10dif-generic:
TEST neon generic ratio
16 byte blocks, 16 bytes per update, 1 updates 214506112 171095400 1.25
64 byte blocks, 16 bytes per update, 4 updates 139385312 119036352 1.17
64 byte blocks, 64 bytes per update, 1 updates 671523712 198945344 3.38
256 byte blocks, 16 bytes per update, 16 updates 157674880 125146752 1.26
256 byte blocks, 64 bytes per update, 4 updates 491888128 175764096 2.80
256 byte blocks, 256 bytes per update, 1 updates 2123298176 206995200 10.26
1024 byte blocks, 16 bytes per update, 64 updates 161243136 126460416 1.28
1024 byte blocks, 256 bytes per update, 4 updates 1643020800 200027136 8.21
1024 byte blocks, 1024 bytes per update, 1 updates 4238239232 209106432 20.27
2048 byte blocks, 16 bytes per update, 128 updates 162079744 126953472 1.28
2048 byte blocks, 256 bytes per update, 8 updates 1693587456 200867840 8.43
2048 byte blocks, 1024 bytes per update, 2 updates 3424323584 206330880 16.60
2048 byte blocks, 2048 bytes per update, 1 updates 5228207104 208620544 25.06
4096 byte blocks, 16 bytes per update, 256 updates 162304000 126894080 1.28
4096 byte blocks, 256 bytes per update, 16 updates 1731862528 201197568 8.61
4096 byte blocks, 1024 bytes per update, 4 updates 3668625408 207003648 17.72
4096 byte blocks, 4096 bytes per update, 1 updates 5551239168 209127424 26.54
8192 byte blocks, 16 bytes per update, 512 updates 162779136 126984192 1.28
8192 byte blocks, 256 bytes per update, 32 updates 1753702400 201420800 8.71
8192 byte blocks, 1024 bytes per update, 8 updates 3760918528 207351808 18.14
8192 byte blocks, 4096 bytes per update, 2 updates 5483655168 208928768 26.25
8192 byte blocks, 8192 bytes per update, 1 updates 5623377920 209108992 26.89
Signed-off-by: YueHaibing <yuehaibing@huawei.com>
Signed-off-by: YangShengkai <yangshengkai@huawei.com>
Signed-off-by: Ding Tianhong <dingtianhong@huawei.com>
Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org>
---
arch/arm64/crypto/Kconfig | 5 +
arch/arm64/crypto/Makefile | 4 +
arch/arm64/crypto/crct10dif-neon-asm_64.S | 751 ++++++++++++++++++++++++++++++
arch/arm64/crypto/crct10dif-neon_glue.c | 115 +++++
4 files changed, 875 insertions(+)
create mode 100644 arch/arm64/crypto/crct10dif-neon-asm_64.S
create mode 100644 arch/arm64/crypto/crct10dif-neon_glue.c
diff --git a/arch/arm64/crypto/Kconfig b/arch/arm64/crypto/Kconfig
index 2cf32e9..2e450bf 100644
--- a/arch/arm64/crypto/Kconfig
+++ b/arch/arm64/crypto/Kconfig
@@ -23,6 +23,11 @@ config CRYPTO_GHASH_ARM64_CE
depends on ARM64 && KERNEL_MODE_NEON
select CRYPTO_HASH
+config CRYPTO_CRCT10DIF_NEON
+ tristate "CRCT10DIF hardware acceleration using NEON instructions"
+ depends on ARM64 && KERNEL_MODE_NEON
+ select CRYPTO_HASH
+
config CRYPTO_AES_ARM64_CE
tristate "AES core cipher using ARMv8 Crypto Extensions"
depends on ARM64 && KERNEL_MODE_NEON
diff --git a/arch/arm64/crypto/Makefile b/arch/arm64/crypto/Makefile
index abb79b3..6c9ff2c 100644
--- a/arch/arm64/crypto/Makefile
+++ b/arch/arm64/crypto/Makefile
@@ -29,6 +29,10 @@ aes-ce-blk-y := aes-glue-ce.o aes-ce.o
obj-$(CONFIG_CRYPTO_AES_ARM64_NEON_BLK) += aes-neon-blk.o
aes-neon-blk-y := aes-glue-neon.o aes-neon.o
+obj-$(CONFIG_CRYPTO_CRCT10DIF_NEON) += crct10dif-neon.o
+crct10dif-neon-y := crct10dif-neon-asm_64.o crct10dif-neon_glue.o
+AFLAGS_crct10dif-neon-asm_64.o := -march=armv8-a+crypto
+
AFLAGS_aes-ce.o := -DINTERLEAVE=4
AFLAGS_aes-neon.o := -DINTERLEAVE=4
diff --git a/arch/arm64/crypto/crct10dif-neon-asm_64.S b/arch/arm64/crypto/crct10dif-neon-asm_64.S
new file mode 100644
index 0000000..2ae3033
--- /dev/null
+++ b/arch/arm64/crypto/crct10dif-neon-asm_64.S
@@ -0,0 +1,751 @@
+/*
+ * Copyright (c) 2016-2017 Hisilicon Limited.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+
+.global crc_t10dif_neon
+.text
+
+/* X0 is initial CRC value
+ * X1 is data buffer
+ * X2 is the length of buffer
+ * X3 is the backup buffer(for extend)
+ * X4 for other extend parameter(for extend)
+ * Q0, Q1, Q2, Q3 maybe as parameter for other functions,
+ * the value of Q0, Q1, Q2, Q3 maybe modified.
+ *
+ * suggestion:
+ * 1. dont use general purpose register for calculation
+ * 2. set data endianness outside of the kernel
+ * 3. use ext as shifting around
+ * 4. dont use LD3/LD4, ST3/ST4
+ */
+
+crc_t10dif_neon:
+ /* push the register to stack that CRC16 will use */
+ STP X5, X6, [sp, #-0x10]!
+ STP X7, X8, [sp, #-0x10]!
+ STP X9, X10, [sp, #-0x10]!
+ STP X11, X12, [sp, #-0x10]!
+ STP X13, X14, [sp, #-0x10]!
+ STP Q10, Q11, [sp, #-0x20]!
+ STP Q12, Q13, [sp, #-0x20]!
+ STP Q4, Q5, [sp, #-0x20]!
+ STP Q6, Q7, [sp, #-0x20]!
+ STP Q8, Q9, [sp, #-0x20]!
+ STP Q14, Q15, [sp, #-0x20]!
+ STP Q16, Q17, [sp, #-0x20]!
+ STP Q18, Q19, [sp, #-0x20]!
+
+ SUB sp,sp,#0x20
+
+ MOV X11, #0 // PUSH STACK FLAG
+
+ CMP X2, #0x80
+ B.LT 2f // _less_than_128, <128
+
+ /* V10/V11/V12/V13 is 128bit.
+ * we get data 512bit( by cacheline ) each time
+ */
+ LDP Q10, Q11, [X1], #0x20
+ LDP Q12, Q13, [X1], #0x20
+
+ /* move the initial value to V6 register */
+ LSL X0, X0, #48
+ EOR V6.16B, V6.16B, V6.16B
+ MOV V6.D[1], X0
+
+ /* big-little end change. because the data in memory is little-end,
+ * we deal the data for bigend
+ */
+
+ REV64 V10.16B, V10.16B
+ REV64 V11.16B, V11.16B
+ REV64 V12.16B, V12.16B
+ REV64 V13.16B, V13.16B
+ EXT V10.16B, V10.16B, V10.16B, #8
+ EXT V11.16B, V11.16B, V11.16B, #8
+ EXT V12.16B, V12.16B, V12.16B, #8
+ EXT V13.16B, V13.16B, V13.16B, #8
+
+ EOR V10.16B, V10.16B, V6.16B
+
+ SUB X2, X2, #0x80
+ ADD X5, X1, #0x20
+
+ /* deal data when the size of buffer bigger than 128 bytes */
+ /* _fold_64_B_loop */
+ LDR Q6,=0xe658000000000000044c000000000000
+1:
+
+ LDP Q16, Q17, [X1] ,#0x40
+ LDP Q18, Q19, [X5], #0x40
+
+ /* carry-less multiply.
+ * V10 high-64bits carry-less multiply
+ * V6 high-64bits(PMULL2)
+ * V11 low-64bits carry-less multiply V6 low-64bits(PMULL)
+ */
+
+ PMULL2 V4.1Q, V10.2D, V6.2D
+ PMULL V10.1Q, V10.1D, V6.1D
+ PMULL2 V5.1Q, V11.2D, V6.2D
+ PMULL V11.1Q, V11.1D, V6.1D
+
+ REV64 V16.16B, V16.16B
+ REV64 V17.16B, V17.16B
+ REV64 V18.16B, V18.16B
+ REV64 V19.16B, V19.16B
+
+ PMULL2 V14.1Q, V12.2D, V6.2D
+ PMULL V12.1Q, V12.1D, V6.1D
+ PMULL2 V15.1Q, V13.2D, V6.2D
+ PMULL V13.1Q, V13.1D, V6.1D
+
+ EXT V16.16B, V16.16B, V16.16B, #8
+ EOR V10.16B, V10.16B, V4.16B
+
+ EXT V17.16B, V17.16B, V17.16B, #8
+ EOR V11.16B, V11.16B, V5.16B
+
+ EXT V18.16B, V18.16B, V18.16B, #8
+ EOR V12.16B, V12.16B, V14.16B
+
+ EXT V19.16B, V19.16B, V19.16B, #8
+ EOR V13.16B, V13.16B, V15.16B
+
+ SUB X2, X2, #0x40
+
+
+ EOR V10.16B, V10.16B, V16.16B
+ EOR V11.16B, V11.16B, V17.16B
+
+ EOR V12.16B, V12.16B, V18.16B
+ EOR V13.16B, V13.16B, V19.16B
+
+ CMP X2, #0x0
+ B.GE 1b // >=0
+
+ LDR Q6, =0x06df0000000000002d56000000000000
+ MOV V4.16B, V10.16B
+ /* V10 carry-less 0x06df000000000000([127:64]*[127:64]) */
+ PMULL V4.1Q, V4.1D, V6.1D //switch PMULL & PMULL2 order
+ PMULL2 V10.1Q, V10.2D, V6.2D
+ EOR V11.16B, V11.16B, V4.16B
+ EOR V11.16B, V11.16B, V10.16B
+
+ MOV V4.16B, V11.16B
+ PMULL V4.1Q, V4.1D, V6.1D //switch PMULL & PMULL2 order
+ PMULL2 V11.1Q, V11.2D, V6.2D
+ EOR V12.16B, V12.16B, V4.16B
+ EOR V12.16B, V12.16B, V11.16B
+
+ MOV V4.16B, V12.16B
+ PMULL V4.1Q, V4.1D, V6.1D //switch PMULL & PMULL2 order
+ PMULL2 V12.1Q, V12.2D, V6.2D
+ EOR V13.16B, V13.16B, V4.16B
+ EOR V13.16B, V13.16B, V12.16B
+
+ ADD X2, X2, #48
+ CMP X2, #0x0
+ B.LT 3f // _final_reduction_for_128, <0
+
+ /* _16B_reduction_loop */
+4:
+ /* unrelated load as early as possible*/
+ LDR Q10, [X1], #0x10
+
+ MOV V4.16B, V13.16B
+ PMULL2 V13.1Q, V13.2D, V6.2D
+ PMULL V4.1Q, V4.1D, V6.1D
+ EOR V13.16B, V13.16B, V4.16B
+
+ REV64 V10.16B, V10.16B
+ EXT V10.16B, V10.16B, V10.16B, #8
+
+ EOR V13.16B, V13.16B, V10.16B
+
+ SUB X2, X2, #0x10
+ CMP X2, #0x0
+ B.GE 4b // _16B_reduction_loop, >=0
+
+ /* _final_reduction_for_128 */
+3: ADD X2, X2, #0x10
+ CMP X2, #0x0
+ B.EQ 5f // _128_done, ==0
+
+ /* _get_last_two_xmms */
+6: MOV V12.16B, V13.16B
+ SUB X1, X1, #0x10
+ ADD X1, X1, X2
+ LDR Q11, [X1], #0x10
+ REV64 V11.16B, V11.16B
+ EXT V11.16B, V11.16B, V11.16B, #8
+
+ CMP X2, #8
+ B.EQ 50f
+ B.LT 51f
+ B.GT 52f
+
+50:
+ /* dont use X register as temp one */
+ FMOV D14, D12
+ MOVI D12, #0
+ MOV V12.D[1],V14.D[0]
+ B 53f
+51:
+ MOV X9, #64
+ LSL X13, X2, #3 // <<3 equal x8
+ SUB X9, X9, X13
+ MOV X5, V12.D[0] // low 64-bit
+ MOV X6, V12.D[1] // high 64-bit
+ LSR X10, X5, X9 // high bit of low 64-bit
+ LSL X7, X5, X13
+ LSL X8, X6, X13
+ ORR X8, X8, X10 // combination of high 64-bit
+ MOV V12.D[1], X8
+ MOV V12.D[0], X7
+
+ B 53f
+52:
+ LSL X13, X2, #3 // <<3 equal x8
+ SUB X13, X13, #64
+
+ DUP V18.2D, X13
+ FMOV D16, D12
+ USHL D16, D16, D18
+ EXT V12.16B, V16.16B, V16.16B, #8
+
+53:
+ MOVI D14, #0 //add one zero constant
+
+ CMP X2, #0
+ B.EQ 30f
+ CMP X2, #1
+ B.EQ 31f
+ CMP X2, #2
+ B.EQ 32f
+ CMP X2, #3
+ B.EQ 33f
+ CMP X2, #4
+ B.EQ 34f
+ CMP X2, #5
+ B.EQ 35f
+ CMP X2, #6
+ B.EQ 36f
+ CMP X2, #7
+ B.EQ 37f
+ CMP X2, #8
+ B.EQ 38f
+ CMP X2, #9
+ B.EQ 39f
+ CMP X2, #10
+ B.EQ 40f
+ CMP X2, #11
+ B.EQ 41f
+ CMP X2, #12
+ B.EQ 42f
+ CMP X2, #13
+ B.EQ 43f
+ CMP X2, #14
+ B.EQ 44f
+ CMP X2, #15
+ B.EQ 45f
+
+ // >> 128bit
+30:
+ EOR V13.16B, V13.16B, V13.16B
+ EOR V8.16B, V8.16B, V8.16B
+ LDR Q9,=0xffffffffffffffffffffffffffffffff
+ B 46f
+
+ // >> 120bit
+31:
+ USHR V13.2D, V13.2D, #56
+ EXT V13.16B, V13.16B, V14.16B, #8
+ LDR Q8,=0xff
+ LDR Q9,=0xffffffffffffffffffffffffffffff00
+ B 46f
+
+ // >> 112bit
+32:
+ USHR V13.2D, V13.2D, #48
+ EXT V13.16B, V13.16B, V14.16B, #8
+ LDR Q8,=0xffff
+ LDR Q9,=0xffffffffffffffffffffffffffff0000
+ B 46f
+
+ // >> 104bit
+33:
+ USHR V13.2D, V13.2D, #40
+ EXT V13.16B, V13.16B, V14.16B, #8
+ LDR Q8,=0xffffff
+ LDR Q9,=0xffffffffffffffffffffffffff000000
+ B 46f
+
+ // >> 96bit
+34:
+ USHR V13.2D, V13.2D, #32
+ EXT V13.16B, V13.16B, V14.16B, #8
+ LDR Q8,=0xffffffff
+ LDR Q9,=0xffffffffffffffffffffffff00000000
+ B 46f
+
+ // >> 88bit
+35:
+ USHR V13.2D, V13.2D, #24
+ EXT V13.16B, V13.16B, V14.16B, #8
+ LDR Q8,=0xffffffffff
+ LDR Q9,=0xffffffffffffffffffffff0000000000
+ B 46f
+
+ // >> 80bit
+36:
+ USHR V13.2D, V13.2D, #16
+ EXT V13.16B, V13.16B, V14.16B, #8
+ LDR Q8,=0xffffffffffff
+ LDR Q9,=0xffffffffffffffffffff000000000000
+ B 46f
+
+ // >> 72bit
+37:
+ USHR V13.2D, V13.2D, #8
+ EXT V13.16B, V13.16B, V14.16B, #8
+ LDR Q8,=0xffffffffffffff
+ LDR Q9,=0xffffffffffffffffff00000000000000
+ B 46f
+
+ // >> 64bit
+38:
+ EXT V13.16B, V13.16B, V14.16B, #8
+ LDR Q8,=0xffffffffffffffff
+ LDR Q9,=0xffffffffffffffff0000000000000000
+ B 46f
+
+ // >> 56bit
+39:
+ EXT V13.16B, V13.16B, V13.16B, #7
+ MOV V13.S[3], V14.S[0]
+ MOV V13.H[5], V14.H[0]
+ MOV V13.B[9], V14.B[0]
+
+ LDR Q8,=0xffffffffffffffffff
+ LDR Q9,=0xffffffffffffff000000000000000000
+ B 46f
+
+ // >> 48bit
+40:
+ EXT V13.16B, V13.16B, V13.16B, #6
+ MOV V13.S[3], V14.S[0]
+ MOV V13.H[5], V14.H[0]
+
+ LDR Q8,=0xffffffffffffffffffff
+ LDR Q9,=0xffffffffffff00000000000000000000
+ B 46f
+
+ // >> 40bit
+41:
+ EXT V13.16B, V13.16B, V13.16B, #5
+ MOV V13.S[3], V14.S[0]
+ MOV V13.B[11], V14.B[0]
+
+ LDR Q8,=0xffffffffffffffffffffff
+ LDR Q9,=0xffffffffff0000000000000000000000
+ B 46f
+
+ // >> 32bit
+42:
+ EXT V13.16B, V13.16B, V13.16B, #4
+ MOV V13.S[3], V14.S[0]
+
+ LDR Q8,=0xffffffffffffffffffffffff
+ LDR Q9,=0xffffffff000000000000000000000000
+ B 46f
+
+ // >> 24bit
+43:
+ EXT V13.16B, V13.16B, V13.16B, #3
+ MOV V13.H[7], V14.H[0]
+ MOV V13.B[13], V14.B[0]
+
+ LDR Q8,=0xffffffffffffffffffffffffff
+ LDR Q9,=0xffffff00000000000000000000000000
+ B 46f
+
+ // >> 16bit
+44:
+ EXT V13.16B, V13.16B, V13.16B, #2
+ MOV V13.H[7], V14.H[0]
+
+ LDR Q8,=0xffffffffffffffffffffffffffff
+ LDR Q9,=0xffff0000000000000000000000000000
+ B 46f
+
+ // >> 8bit
+45:
+ EXT V13.16B, V13.16B, V13.16B, #1
+ MOV V13.B[15], V14.B[0]
+
+ LDR Q8,=0xffffffffffffffffffffffffffffff
+ LDR Q9,=0xff000000000000000000000000000000
+
+ // backup V12 first
+ // pblendvb xmm1, xmm2
+46:
+ AND V12.16B, V12.16B, V9.16B
+ AND V11.16B, V11.16B, V8.16B
+ ORR V11.16B, V11.16B, V12.16B
+
+ MOV V12.16B, V11.16B
+ MOV V4.16B, V13.16B
+ PMULL2 V13.1Q, V13.2D, V6.2D
+ PMULL V4.1Q, V4.1D, V6.1D
+ EOR V13.16B, V13.16B, V4.16B
+ EOR V13.16B, V13.16B, V12.16B
+
+ /* _128_done. we change the Q6 D[0] and D[1] */
+5: LDR Q6, =0x2d560000000000001368000000000000
+ MOVI D14, #0
+ MOV V10.16B, V13.16B
+ PMULL2 V13.1Q, V13.2D, V6.2D
+
+ MOV V10.D[1], V10.D[0]
+ MOV V10.D[0], V14.D[0] //set zero
+
+ EOR V13.16B, V13.16B, V10.16B
+
+ MOV V10.16B, V13.16B
+ LDR Q7, =0x00000000FFFFFFFFFFFFFFFFFFFFFFFF
+ AND V10.16B, V10.16B, V7.16B
+
+ MOV S13, V13.S[3]
+
+ PMULL V13.1Q, V13.1D, V6.1D
+ EOR V13.16B, V13.16B, V10.16B
+
+ /* _barrett */
+7: LDR Q6, =0x00000001f65a57f8000000018bb70000
+ MOVI D14, #0
+ MOV V10.16B, V13.16B
+ PMULL2 V13.1Q, V13.2D, V6.2D
+
+ EXT V13.16B, V13.16B, V13.16B, #12
+ MOV V13.S[0], V14.S[0]
+
+ EXT V6.16B, V6.16B, V6.16B, #8
+ PMULL2 V13.1Q, V13.2D, V6.2D
+
+ EXT V13.16B, V13.16B, V13.16B, #12
+ MOV V13.S[0], V14.S[0]
+
+ EOR V13.16B, V13.16B, V10.16B
+ MOV X0, V13.D[0]
+
+ /* _cleanup */
+8: MOV X14, #48
+ LSR X0, X0, X14
+99:
+ ADD sp, sp, #0x20
+
+ LDP Q18, Q19, [sp], #0x20
+ LDP Q16, Q17, [sp], #0x20
+ LDP Q14, Q15, [sp], #0x20
+
+ LDP Q8, Q9, [sp], #0x20
+ LDP Q6, Q7, [sp], #0x20
+ LDP Q4, Q5, [sp], #0x20
+ LDP Q12, Q13, [sp], #0x20
+ LDP Q10, Q11, [sp], #0x20
+ LDP X13, X14, [sp], #0x10
+ LDP X11, X12, [sp], #0x10
+ LDP X9, X10, [sp], #0x10
+ LDP X7, X8, [sp], #0x10
+ LDP X5, X6, [sp], #0x10
+
+ RET
+
+ /* _less_than_128 */
+2: CMP X2, #32
+ B.LT 9f // _less_than_32
+ LDR Q6, =0x06df0000000000002d56000000000000
+
+ LSL X0, X0, #48
+ LDR Q10, =0x0
+ MOV V10.D[1], X0
+ LDR Q13, [X1], #0x10
+ REV64 V13.16B, V13.16B
+ EXT V13.16B, V13.16B, V13.16B, #8
+
+ EOR V13.16B, V13.16B, V10.16B
+
+ SUB X2, X2, #32
+ B 4b
+
+ /* _less_than_32 */
+9: CMP X2, #0
+ B.EQ 99b // _cleanup
+ LSL X0, X0, #48
+ LDR Q10,=0x0
+ MOV V10.D[1], X0
+
+ CMP X2, #16
+ B.EQ 10f // _exact_16_left
+ B.LE 11f // _less_than_16_left
+ LDR Q13, [X1], #0x10
+
+ REV64 V13.16B, V13.16B
+ EXT V13.16B, V13.16B, V13.16B, #8
+
+ EOR V13.16B, V13.16B, V10.16B
+ SUB X2, X2, #16
+ LDR Q6, =0x06df0000000000002d56000000000000
+ B 6b // _get_last_two_xmms
+
+ /* _less_than_16_left */
+11: CMP X2, #4
+ B.LT 13f // _only_less_than_4
+
+ /* backup the length of data, we used in _less_than_2_left */
+ MOV X8, X2
+ CMP X2, #8
+ B.LT 14f // _less_than_8_left
+
+ LDR X14, [X1], #8
+ /* push the data to stack, we backup the data to V10 */
+ STR X14, [sp, #0]
+ SUB X2, X2, #8
+ ADD X11, X11, #8
+
+ /* _less_than_8_left */
+14: CMP X2, #4
+ B.LT 15f // _less_than_4_left
+
+ /* get 32bit data */
+ LDR W5, [X1], #4
+
+ /* push the data to stack */
+ STR W5, [sp, X11]
+ SUB X2, X2, #4
+ ADD X11, X11, #4
+
+ /* _less_than_4_left */
+15: CMP X2, #2
+ B.LT 16f // _less_than_2_left
+
+ /* get 16bits data */
+ LDRH W6, [X1], #2
+
+ /* push the data to stack */
+ STRH W6, [sp, X11]
+ SUB X2, X2, #2
+ ADD X11, X11, #2
+
+ /* _less_than_2_left */
+16:
+ /* get 8bits data */
+ LDRB W7, [X1], #1
+ STRB W7, [sp, X11]
+ ADD X11, X11, #1
+
+ /* POP data from stack, store to V13 */
+ LDR Q13, [sp]
+ MOVI D14, #0
+ REV64 V13.16B, V13.16B
+ MOV V8.16B, V13.16B
+ MOV V13.D[1], V8.D[0]
+ MOV V13.D[0], V8.D[1]
+
+ EOR V13.16B, V13.16B, V10.16B
+ CMP X8, #15
+ B.EQ 80f
+ CMP X8, #14
+ B.EQ 81f
+ CMP X8, #13
+ B.EQ 82f
+ CMP X8, #12
+ B.EQ 83f
+ CMP X8, #11
+ B.EQ 84f
+ CMP X8, #10
+ B.EQ 85f
+ CMP X8, #9
+ B.EQ 86f
+ CMP X8, #8
+ B.EQ 87f
+ CMP X8, #7
+ B.EQ 88f
+ CMP X8, #6
+ B.EQ 89f
+ CMP X8, #5
+ B.EQ 90f
+ CMP X8, #4
+ B.EQ 91f
+ CMP X8, #3
+ B.EQ 92f
+ CMP X8, #2
+ B.EQ 93f
+ CMP X8, #1
+ B.EQ 94f
+ CMP X8, #0
+ B.EQ 95f
+
+80:
+ EXT V13.16B, V13.16B, V13.16B, #1
+ MOV V13.B[15], V14.B[0]
+ B 5b
+
+81:
+ EXT V13.16B, V13.16B, V13.16B, #2
+ MOV V13.H[7], V14.H[0]
+ B 5b
+
+82:
+ EXT V13.16B, V13.16B, V13.16B, #3
+ MOV V13.H[7], V14.H[0]
+ MOV V13.B[13], V14.B[0]
+ B 5b
+83:
+
+ EXT V13.16B, V13.16B, V13.16B, #4
+ MOV V13.S[3], V14.S[0]
+ B 5b
+
+84:
+ EXT V13.16B, V13.16B, V13.16B, #5
+ MOV V13.S[3], V14.S[0]
+ MOV V13.B[11], V14.B[0]
+ B 5b
+
+85:
+ EXT V13.16B, V13.16B, V13.16B, #6
+ MOV V13.S[3], V14.S[0]
+ MOV V13.H[5], V14.H[0]
+ B 5b
+
+86:
+ EXT V13.16B, V13.16B, V13.16B, #7
+ MOV V13.S[3], V14.S[0]
+ MOV V13.H[5], V14.H[0]
+ MOV V13.B[9], V14.B[0]
+ B 5b
+
+87:
+ MOV V13.D[0], V13.D[1]
+ MOV V13.D[1], V14.D[0]
+ B 5b
+
+88:
+ EXT V13.16B, V13.16B, V13.16B, #9
+ MOV V13.D[1], V14.D[0]
+ MOV V13.B[7], V14.B[0]
+ B 5b
+
+89:
+ EXT V13.16B, V13.16B, V13.16B, #10
+ MOV V13.D[1], V14.D[0]
+ MOV V13.H[3], V14.H[0]
+ B 5b
+
+90:
+ EXT V13.16B, V13.16B, V13.16B, #11
+ MOV V13.D[1], V14.D[0]
+ MOV V13.H[3], V14.H[0]
+ MOV V13.B[5], V14.B[0]
+ B 5b
+
+91:
+ MOV V13.S[0], V13.S[3]
+ MOV V13.D[1], V14.D[0]
+ MOV V13.S[1], V14.S[0]
+ B 5b
+
+92:
+ EXT V13.16B, V13.16B, V13.16B, #13
+ MOV V13.D[1], V14.D[0]
+ MOV V13.S[1], V14.S[0]
+ MOV V13.B[3], V14.B[0]
+ B 5b
+
+93:
+ MOV V15.H[0], V13.H[7]
+ MOV V13.16B, V14.16B
+ MOV V13.H[0], V15.H[0]
+ B 5b
+
+94:
+ MOV V15.B[0], V13.B[15]
+ MOV V13.16B, V14.16B
+ MOV V13.B[0], V15.B[0]
+ B 5b
+
+95:
+ LDR Q13,=0x0
+ B 5b // _128_done
+
+ /* _exact_16_left */
+10:
+ LD1 { V13.2D }, [X1], #0x10
+
+ REV64 V13.16B, V13.16B
+ EXT V13.16B, V13.16B, V13.16B, #8
+ EOR V13.16B, V13.16B, V10.16B
+ B 5b // _128_done
+
+ /* _only_less_than_4 */
+13: CMP X2, #3
+ MOVI D14, #0
+ B.LT 17f //_only_less_than_3
+
+ LDR S13, [X1], #4
+ MOV V13.B[15], V13.B[0]
+ MOV V13.B[14], V13.B[1]
+ MOV V13.B[13], V13.B[2]
+ MOV V13.S[0], V13.S[1]
+
+ EOR V13.16B, V13.16B, V10.16B
+
+ EXT V13.16B, V13.16B, V13.16B, #5
+
+ MOV V13.S[3], V14.S[0]
+ MOV V13.B[11], V14.B[0]
+
+ B 7b // _barrett
+ /* _only_less_than_3 */
+17:
+ CMP X2, #2
+ B.LT 18f // _only_less_than_2
+
+ LDR H13, [X1], #2
+ MOV V13.B[15], V13.B[0]
+ MOV V13.B[14], V13.B[1]
+ MOV V13.H[0], V13.H[1]
+
+ EOR V13.16B, V13.16B, V10.16B
+
+ EXT V13.16B, V13.16B, V13.16B, #6
+ MOV V13.S[3], V14.S[0]
+ MOV V13.H[5], V14.H[0]
+
+ B 7b // _barrett
+
+ /* _only_less_than_2 */
+18:
+ LDRB W7, [X1], #1
+ LDR Q13, = 0x0
+ MOV V13.B[15], W7
+
+ EOR V13.16B, V13.16B, V10.16B
+
+ EXT V13.16B, V13.16B, V13.16B, #7
+ MOV V13.S[3], V14.S[0]
+ MOV V13.H[5], V14.H[0]
+ MOV V13.B[9], V14.B[0]
+
+ B 7b // _barrett
diff --git a/arch/arm64/crypto/crct10dif-neon_glue.c b/arch/arm64/crypto/crct10dif-neon_glue.c
new file mode 100644
index 0000000..a6d8c5c
--- /dev/null
+++ b/arch/arm64/crypto/crct10dif-neon_glue.c
@@ -0,0 +1,115 @@
+/*
+ * Copyright (c) 2016-2017 Hisilicon Limited.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+
+#include <linux/types.h>
+#include <linux/module.h>
+#include <linux/crc-t10dif.h>
+#include <crypto/internal/hash.h>
+#include <linux/init.h>
+#include <linux/string.h>
+#include <linux/kernel.h>
+
+asmlinkage __u16 crc_t10dif_neon(__u16 crc, const unsigned char *buf,
+ size_t len);
+
+struct chksum_desc_ctx {
+ __u16 crc;
+};
+
+/*
+ * Steps through buffer one byte at at time, calculates reflected
+ * crc using table.
+ */
+
+static int chksum_init(struct shash_desc *desc)
+{
+ struct chksum_desc_ctx *ctx = shash_desc_ctx(desc);
+
+ ctx->crc = 0;
+
+ return 0;
+}
+
+static int chksum_update(struct shash_desc *desc, const u8 *data,
+ unsigned int length)
+{
+ struct chksum_desc_ctx *ctx = shash_desc_ctx(desc);
+
+ ctx->crc = crc_t10dif_neon(ctx->crc, data, length);
+ return 0;
+}
+
+static int chksum_final(struct shash_desc *desc, u8 *out)
+{
+ struct chksum_desc_ctx *ctx = shash_desc_ctx(desc);
+
+ *(__u16 *)out = ctx->crc;
+ return 0;
+}
+
+static int __chksum_finup(__u16 *crcp, const u8 *data, unsigned int len,
+ u8 *out)
+{
+ *(__u16 *)out = crc_t10dif_neon(*crcp, data, len);
+ return 0;
+}
+
+static int chksum_finup(struct shash_desc *desc, const u8 *data,
+ unsigned int len, u8 *out)
+{
+ struct chksum_desc_ctx *ctx = shash_desc_ctx(desc);
+
+ return __chksum_finup(&ctx->crc, data, len, out);
+}
+
+static int chksum_digest(struct shash_desc *desc, const u8 *data,
+ unsigned int length, u8 *out)
+{
+ struct chksum_desc_ctx *ctx = shash_desc_ctx(desc);
+
+ return __chksum_finup(&ctx->crc, data, length, out);
+}
+
+static struct shash_alg alg = {
+ .digestsize = CRC_T10DIF_DIGEST_SIZE,
+ .init = chksum_init,
+ .update = chksum_update,
+ .final = chksum_final,
+ .finup = chksum_finup,
+ .digest = chksum_digest,
+ .descsize = sizeof(struct chksum_desc_ctx),
+ .base = {
+ .cra_name = "crct10dif",
+ .cra_driver_name = "crct10dif-neon",
+ .cra_priority = 200,
+ .cra_blocksize = CRC_T10DIF_BLOCK_SIZE,
+ .cra_module = THIS_MODULE,
+ }
+};
+
+static int __init crct10dif_arm64_mod_init(void)
+{
+ return crypto_register_shash(&alg);
+}
+
+static void __exit crct10dif_arm64_mod_fini(void)
+{
+ crypto_unregister_shash(&alg);
+}
+
+module_init(crct10dif_arm64_mod_init);
+module_exit(crct10dif_arm64_mod_fini);
+
+MODULE_AUTHOR("YueHaibing <yuehaibing@huawei.com>");
+MODULE_DESCRIPTION("T10 DIF CRC calculation accelerated with ARM64 NEON instruction.");
+MODULE_LICENSE("GPL");
+
+MODULE_ALIAS_CRYPTO("crct10dif");
+MODULE_ALIAS_CRYPTO("crct10dif-neon");
--
2.7.0
^ permalink raw reply related
* [RFC PATCH 11/11] ARM: Allow ARCH_MULTIPLATFORM to be selected for NOMMU
From: Arnd Bergmann @ 2016-11-22 10:17 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1479806768-39911-12-git-send-email-vladimir.murzin@arm.com>
On Tuesday, November 22, 2016 9:26:08 AM CET Vladimir Murzin wrote:
> With this patch applied potentially any platform can be built in NOMMU
> configurations if CONFIG_EXPERT is selected. However, there is no
> guaranty that platform can successfully run such Image. So the main
> motivation behind of this patch:
> - bring build coverage for NOMMU configurations
> - allow known working NOMMU platforms (like R-class) to be used
> - pave a way to add support for single address space (aka 1:1 mapping)
> for MMU platforms, so they can be usable in NOMMU configurations
>
> Cc: Hartley Sweeten <hsweeten@visionengravers.com>
> Cc: Ryan Mallon <rmallon@gmail.com>
> Cc: Tony Lindgren <tony@atomide.com>
> Cc: Thierry Reding <thierry.reding@gmail.com>
> Cc: Russell King <linux@armlinux.org.uk>
> Signed-off-by: Vladimir Murzin <vladimir.murzin@arm.com>
I'd have to give this a spin with my randconfig build setup, I'd
rather not introduce build regressions. Have you tried an
allmodconfig build with CONFIG_MMU disabled?
Can you provide a git tree that I can try pulling in?
Another question is what architecture levels and what platforms
we want to support without MMU. The only ARMv4/v5 platform we
still have that can actually use NOMMU cores is Integrator
with its ARM7TDMI, ARM920T and ARM966E core tiles (and possibly
others I couldn't immediately find). Do we actually care about
them any more now that all the NOMMU world is ARMv7-M? Are
there any benefits in running an ARM920T or ARM926E core
with MMU disabled, and does this work with your patches?
If not, we could limit it to ARMv7-A/R and possibly ARMv6.
Depending on how the build tests go, a per-platform opt-in
might be easier than having an opt-out for things that
don't work.
Arnd
^ permalink raw reply
* [PATCH v2] mfd: twl-core: make driver DT only
From: Nicolae Rosia @ 2016-11-22 10:21 UTC (permalink / raw)
To: linux-arm-kernel
All users are DT-only and it makes no sense to keep
unused code which also prevents further cleanups.
Signed-off-by: Nicolae Rosia <Nicolae_Rosia@mentor.com>
---
Changes in v2:
Increased audience in CC list
drivers/mfd/Kconfig | 1 +
drivers/mfd/twl-core.c | 395 ++-----------------------------------------------
2 files changed, 10 insertions(+), 386 deletions(-)
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index c6df644..c180f8b 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -1333,6 +1333,7 @@ config MFD_TPS80031
config TWL4030_CORE
bool "TI TWL4030/TWL5030/TWL6030/TPS659x0 Support"
depends on I2C=y
+ depends on OF
select IRQ_DOMAIN
select REGMAP_I2C
help
diff --git a/drivers/mfd/twl-core.c b/drivers/mfd/twl-core.c
index c64615d..2025326 100644
--- a/drivers/mfd/twl-core.c
+++ b/drivers/mfd/twl-core.c
@@ -13,6 +13,9 @@
* Code cleanup and modifications to IRQ handler.
* by syed khasim <x0khasim@ti.com>
*
+ * Code cleanup and modifications:
+ * Copyright (C) 2016 Nicolae Rosia <nicolae.rosia@gmail.com>
+ *
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
@@ -604,376 +607,6 @@ int twl_get_hfclk_rate(void)
}
EXPORT_SYMBOL_GPL(twl_get_hfclk_rate);
-static struct device *
-add_numbered_child(unsigned mod_no, const char *name, int num,
- void *pdata, unsigned pdata_len,
- bool can_wakeup, int irq0, int irq1)
-{
- struct platform_device *pdev;
- struct twl_client *twl;
- int status, sid;
-
- if (unlikely(mod_no >= twl_get_last_module())) {
- pr_err("%s: invalid module number %d\n", DRIVER_NAME, mod_no);
- return ERR_PTR(-EPERM);
- }
- sid = twl_priv->twl_map[mod_no].sid;
- twl = &twl_priv->twl_modules[sid];
-
- pdev = platform_device_alloc(name, num);
- if (!pdev)
- return ERR_PTR(-ENOMEM);
-
- pdev->dev.parent = &twl->client->dev;
-
- if (pdata) {
- status = platform_device_add_data(pdev, pdata, pdata_len);
- if (status < 0) {
- dev_dbg(&pdev->dev, "can't add platform_data\n");
- goto put_device;
- }
- }
-
- if (irq0) {
- struct resource r[2] = {
- { .start = irq0, .flags = IORESOURCE_IRQ, },
- { .start = irq1, .flags = IORESOURCE_IRQ, },
- };
-
- status = platform_device_add_resources(pdev, r, irq1 ? 2 : 1);
- if (status < 0) {
- dev_dbg(&pdev->dev, "can't add irqs\n");
- goto put_device;
- }
- }
-
- status = platform_device_add(pdev);
- if (status)
- goto put_device;
-
- device_init_wakeup(&pdev->dev, can_wakeup);
-
- return &pdev->dev;
-
-put_device:
- platform_device_put(pdev);
- dev_err(&twl->client->dev, "failed to add device %s\n", name);
- return ERR_PTR(status);
-}
-
-static inline struct device *add_child(unsigned mod_no, const char *name,
- void *pdata, unsigned pdata_len,
- bool can_wakeup, int irq0, int irq1)
-{
- return add_numbered_child(mod_no, name, -1, pdata, pdata_len,
- can_wakeup, irq0, irq1);
-}
-
-static struct device *
-add_regulator_linked(int num, struct regulator_init_data *pdata,
- struct regulator_consumer_supply *consumers,
- unsigned num_consumers, unsigned long features)
-{
- struct twl_regulator_driver_data drv_data;
-
- /* regulator framework demands init_data ... */
- if (!pdata)
- return NULL;
-
- if (consumers) {
- pdata->consumer_supplies = consumers;
- pdata->num_consumer_supplies = num_consumers;
- }
-
- if (pdata->driver_data) {
- /* If we have existing drv_data, just add the flags */
- struct twl_regulator_driver_data *tmp;
- tmp = pdata->driver_data;
- tmp->features |= features;
- } else {
- /* add new driver data struct, used only during init */
- drv_data.features = features;
- drv_data.set_voltage = NULL;
- drv_data.get_voltage = NULL;
- drv_data.data = NULL;
- pdata->driver_data = &drv_data;
- }
-
- /* NOTE: we currently ignore regulator IRQs, e.g. for short circuits */
- return add_numbered_child(TWL_MODULE_PM_MASTER, "twl_reg", num,
- pdata, sizeof(*pdata), false, 0, 0);
-}
-
-static struct device *
-add_regulator(int num, struct regulator_init_data *pdata,
- unsigned long features)
-{
- return add_regulator_linked(num, pdata, NULL, 0, features);
-}
-
-/*
- * NOTE: We know the first 8 IRQs after pdata->base_irq are
- * for the PIH, and the next are for the PWR_INT SIH, since
- * that's how twl_init_irq() sets things up.
- */
-
-static int
-add_children(struct twl4030_platform_data *pdata, unsigned irq_base,
- unsigned long features)
-{
- struct device *child;
-
- if (IS_ENABLED(CONFIG_GPIO_TWL4030) && pdata->gpio) {
- child = add_child(TWL4030_MODULE_GPIO, "twl4030_gpio",
- pdata->gpio, sizeof(*pdata->gpio),
- false, irq_base + GPIO_INTR_OFFSET, 0);
- if (IS_ERR(child))
- return PTR_ERR(child);
- }
-
- if (IS_ENABLED(CONFIG_KEYBOARD_TWL4030) && pdata->keypad) {
- child = add_child(TWL4030_MODULE_KEYPAD, "twl4030_keypad",
- pdata->keypad, sizeof(*pdata->keypad),
- true, irq_base + KEYPAD_INTR_OFFSET, 0);
- if (IS_ERR(child))
- return PTR_ERR(child);
- }
-
- if (IS_ENABLED(CONFIG_TWL4030_MADC) && pdata->madc &&
- twl_class_is_4030()) {
- child = add_child(TWL4030_MODULE_MADC, "twl4030_madc",
- pdata->madc, sizeof(*pdata->madc),
- true, irq_base + MADC_INTR_OFFSET, 0);
- if (IS_ERR(child))
- return PTR_ERR(child);
- }
-
- if (IS_ENABLED(CONFIG_RTC_DRV_TWL4030)) {
- /*
- * REVISIT platform_data here currently might expose the
- * "msecure" line ... but for now we just expect board
- * setup to tell the chip "it's always ok to SET_TIME".
- * Eventually, Linux might become more aware of such
- * HW security concerns, and "least privilege".
- */
- child = add_child(TWL_MODULE_RTC, "twl_rtc", NULL, 0,
- true, irq_base + RTC_INTR_OFFSET, 0);
- if (IS_ERR(child))
- return PTR_ERR(child);
- }
-
- if (IS_ENABLED(CONFIG_PWM_TWL)) {
- child = add_child(TWL_MODULE_PWM, "twl-pwm", NULL, 0,
- false, 0, 0);
- if (IS_ERR(child))
- return PTR_ERR(child);
- }
-
- if (IS_ENABLED(CONFIG_PWM_TWL_LED)) {
- child = add_child(TWL_MODULE_LED, "twl-pwmled", NULL, 0,
- false, 0, 0);
- if (IS_ERR(child))
- return PTR_ERR(child);
- }
-
- if (IS_ENABLED(CONFIG_TWL4030_USB) && pdata->usb &&
- twl_class_is_4030()) {
-
- static struct regulator_consumer_supply usb1v5 = {
- .supply = "usb1v5",
- };
- static struct regulator_consumer_supply usb1v8 = {
- .supply = "usb1v8",
- };
- static struct regulator_consumer_supply usb3v1 = {
- .supply = "usb3v1",
- };
-
- /* First add the regulators so that they can be used by transceiver */
- if (IS_ENABLED(CONFIG_REGULATOR_TWL4030)) {
- /* this is a template that gets copied */
- struct regulator_init_data usb_fixed = {
- .constraints.valid_modes_mask =
- REGULATOR_MODE_NORMAL
- | REGULATOR_MODE_STANDBY,
- .constraints.valid_ops_mask =
- REGULATOR_CHANGE_MODE
- | REGULATOR_CHANGE_STATUS,
- };
-
- child = add_regulator_linked(TWL4030_REG_VUSB1V5,
- &usb_fixed, &usb1v5, 1,
- features);
- if (IS_ERR(child))
- return PTR_ERR(child);
-
- child = add_regulator_linked(TWL4030_REG_VUSB1V8,
- &usb_fixed, &usb1v8, 1,
- features);
- if (IS_ERR(child))
- return PTR_ERR(child);
-
- child = add_regulator_linked(TWL4030_REG_VUSB3V1,
- &usb_fixed, &usb3v1, 1,
- features);
- if (IS_ERR(child))
- return PTR_ERR(child);
-
- }
-
- child = add_child(TWL_MODULE_USB, "twl4030_usb",
- pdata->usb, sizeof(*pdata->usb), true,
- /* irq0 = USB_PRES, irq1 = USB */
- irq_base + USB_PRES_INTR_OFFSET,
- irq_base + USB_INTR_OFFSET);
-
- if (IS_ERR(child))
- return PTR_ERR(child);
-
- /* we need to connect regulators to this transceiver */
- if (IS_ENABLED(CONFIG_REGULATOR_TWL4030) && child) {
- usb1v5.dev_name = dev_name(child);
- usb1v8.dev_name = dev_name(child);
- usb3v1.dev_name = dev_name(child);
- }
- }
-
- if (IS_ENABLED(CONFIG_TWL4030_WATCHDOG) && twl_class_is_4030()) {
- child = add_child(TWL_MODULE_PM_RECEIVER, "twl4030_wdt", NULL,
- 0, false, 0, 0);
- if (IS_ERR(child))
- return PTR_ERR(child);
- }
-
- if (IS_ENABLED(CONFIG_INPUT_TWL4030_PWRBUTTON) && twl_class_is_4030()) {
- child = add_child(TWL_MODULE_PM_MASTER, "twl4030_pwrbutton",
- NULL, 0, true, irq_base + 8 + 0, 0);
- if (IS_ERR(child))
- return PTR_ERR(child);
- }
-
- if (IS_ENABLED(CONFIG_MFD_TWL4030_AUDIO) && pdata->audio &&
- twl_class_is_4030()) {
- child = add_child(TWL4030_MODULE_AUDIO_VOICE, "twl4030-audio",
- pdata->audio, sizeof(*pdata->audio),
- false, 0, 0);
- if (IS_ERR(child))
- return PTR_ERR(child);
- }
-
- /* twl4030 regulators */
- if (IS_ENABLED(CONFIG_REGULATOR_TWL4030) && twl_class_is_4030()) {
- child = add_regulator(TWL4030_REG_VPLL1, pdata->vpll1,
- features);
- if (IS_ERR(child))
- return PTR_ERR(child);
-
- child = add_regulator(TWL4030_REG_VIO, pdata->vio,
- features);
- if (IS_ERR(child))
- return PTR_ERR(child);
-
- child = add_regulator(TWL4030_REG_VDD1, pdata->vdd1,
- features);
- if (IS_ERR(child))
- return PTR_ERR(child);
-
- child = add_regulator(TWL4030_REG_VDD2, pdata->vdd2,
- features);
- if (IS_ERR(child))
- return PTR_ERR(child);
-
- child = add_regulator(TWL4030_REG_VMMC1, pdata->vmmc1,
- features);
- if (IS_ERR(child))
- return PTR_ERR(child);
-
- child = add_regulator(TWL4030_REG_VDAC, pdata->vdac,
- features);
- if (IS_ERR(child))
- return PTR_ERR(child);
-
- child = add_regulator((features & TWL4030_VAUX2)
- ? TWL4030_REG_VAUX2_4030
- : TWL4030_REG_VAUX2,
- pdata->vaux2, features);
- if (IS_ERR(child))
- return PTR_ERR(child);
-
- child = add_regulator(TWL4030_REG_VINTANA1, pdata->vintana1,
- features);
- if (IS_ERR(child))
- return PTR_ERR(child);
-
- child = add_regulator(TWL4030_REG_VINTANA2, pdata->vintana2,
- features);
- if (IS_ERR(child))
- return PTR_ERR(child);
-
- child = add_regulator(TWL4030_REG_VINTDIG, pdata->vintdig,
- features);
- if (IS_ERR(child))
- return PTR_ERR(child);
- }
-
- /* maybe add LDOs that are omitted on cost-reduced parts */
- if (IS_ENABLED(CONFIG_REGULATOR_TWL4030) && !(features & TPS_SUBSET)
- && twl_class_is_4030()) {
- child = add_regulator(TWL4030_REG_VPLL2, pdata->vpll2,
- features);
- if (IS_ERR(child))
- return PTR_ERR(child);
-
- child = add_regulator(TWL4030_REG_VMMC2, pdata->vmmc2,
- features);
- if (IS_ERR(child))
- return PTR_ERR(child);
-
- child = add_regulator(TWL4030_REG_VSIM, pdata->vsim,
- features);
- if (IS_ERR(child))
- return PTR_ERR(child);
-
- child = add_regulator(TWL4030_REG_VAUX1, pdata->vaux1,
- features);
- if (IS_ERR(child))
- return PTR_ERR(child);
-
- child = add_regulator(TWL4030_REG_VAUX3, pdata->vaux3,
- features);
- if (IS_ERR(child))
- return PTR_ERR(child);
-
- child = add_regulator(TWL4030_REG_VAUX4, pdata->vaux4,
- features);
- if (IS_ERR(child))
- return PTR_ERR(child);
- }
-
- if (IS_ENABLED(CONFIG_CHARGER_TWL4030) && pdata->bci &&
- !(features & (TPS_SUBSET | TWL5031))) {
- child = add_child(TWL_MODULE_MAIN_CHARGE, "twl4030_bci",
- pdata->bci, sizeof(*pdata->bci), false,
- /* irq0 = CHG_PRES, irq1 = BCI */
- irq_base + BCI_PRES_INTR_OFFSET,
- irq_base + BCI_INTR_OFFSET);
- if (IS_ERR(child))
- return PTR_ERR(child);
- }
-
- if (IS_ENABLED(CONFIG_TWL4030_POWER) && pdata->power) {
- child = add_child(TWL_MODULE_PM_MASTER, "twl4030_power",
- pdata->power, sizeof(*pdata->power), false,
- 0, 0);
- if (IS_ERR(child))
- return PTR_ERR(child);
- }
-
- return 0;
-}
-
-/*----------------------------------------------------------------------*/
-
/*
* These three functions initialize the on-chip clock framework,
* letting it generate the right frequencies for USB, MADC, and
@@ -1000,8 +633,7 @@ static inline int __init unprotect_pm_master(void)
return e;
}
-static void clocks_init(struct device *dev,
- struct twl4030_clock_init_data *clock)
+static void clocks_init(struct device *dev)
{
int e = 0;
struct clk *osc;
@@ -1031,8 +663,6 @@ static void clocks_init(struct device *dev,
}
ctrl |= HIGH_PERF_SQ;
- if (clock && clock->ck32k_lowpwr_enable)
- ctrl |= CK32K_LOWPWR_EN;
e |= unprotect_pm_master();
/* effect->MADC+USB ck en */
@@ -1080,7 +710,6 @@ static struct of_dev_auxdata twl_auxdata_lookup[] = {
static int
twl_probe(struct i2c_client *client, const struct i2c_device_id *id)
{
- struct twl4030_platform_data *pdata = dev_get_platdata(&client->dev);
struct device_node *node = client->dev.of_node;
struct platform_device *pdev;
const struct regmap_config *twl_regmap_config;
@@ -1088,8 +717,8 @@ twl_probe(struct i2c_client *client, const struct i2c_device_id *id)
int status;
unsigned i, num_slaves;
- if (!node && !pdata) {
- dev_err(&client->dev, "no platform data\n");
+ if (!node) {
+ dev_err(&client->dev, "no DT info\n");
return -EINVAL;
}
@@ -1177,7 +806,7 @@ twl_probe(struct i2c_client *client, const struct i2c_device_id *id)
twl_priv->ready = true;
/* setup clock framework */
- clocks_init(&pdev->dev, pdata ? pdata->clock : NULL);
+ clocks_init(&pdev->dev);
/* read TWL IDCODE Register */
if (twl_class_is_4030()) {
@@ -1225,14 +854,8 @@ twl_probe(struct i2c_client *client, const struct i2c_device_id *id)
TWL4030_DCDC_GLOBAL_CFG);
}
- if (node) {
- if (pdata)
- twl_auxdata_lookup[0].platform_data = pdata->gpio;
- status = of_platform_populate(node, NULL, twl_auxdata_lookup,
- &client->dev);
- } else {
- status = add_children(pdata, irq_base, id->driver_data);
- }
+ status = of_platform_populate(node, NULL, twl_auxdata_lookup,
+ &client->dev);
fail:
if (status < 0)
--
2.5.5
^ permalink raw reply related
* [PATCH 1/3] ARM: davinci: hawk: fix mmc card detect gpio
From: Sekhar Nori @ 2016-11-22 10:21 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CAKXjFTMW7p-TAehV_eTd4nDtC3gvNmcg-e9tLmv4LSX1LEXnhw@mail.gmail.com>
On Tuesday 22 November 2016 03:40 PM, Axel Haslam wrote:
> On Tue, Nov 22, 2016 at 10:53 AM, Sekhar Nori <nsekhar@ti.com> wrote:
>> On Monday 21 November 2016 09:45 PM, Axel Haslam wrote:
>>> The card detect gpio on the hawk board is gpio4_0 and not gpio3_12
>>>
>>> Signed-off-by: Axel Haslam <ahaslam@baylibre.com>
>>
>> The LCDK and HawkBoard are different boards. The HawkBoard schematic
>> from eLinux.org page is broken, but looking for it on the net, I found
>> one and the MMC/SD CD pin in that schematic is indeed connected to GPIO3_12.
>>
>> So I believe the original code is correct.
>
> mmm, ok, the lcdk is booted using the hawk board file,
I think this is just a coincidence. The LCDK came after the hawkboard as
its replacement, and I guess there was some effort to derive out of
hawkboard design. But they are not 100% software compatible, like you
are discovering now.
> so we should differentiate the two boards?
Yes.
> or should we just live with inconsistencies on the lcdk?
Not sure what you mean by "live with inconsistencies on the lcdk". The
two boards need to be treated as close cousins, but independent boards.
Thanks,
Sekhar
^ permalink raw reply
* [PATCH 1/6] reset: hisilicon: add reset core
From: Philipp Zabel @ 2016-11-22 10:22 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1479800961-6249-2-git-send-email-zhangfei.gao@linaro.org>
Hi Zhangfei,
Am Dienstag, den 22.11.2016, 15:49 +0800 schrieb Zhangfei Gao:
> reset.c will be shared by hisilicon chips like hi3660 and hi6220
>
> Signed-off-by: Zhangfei Gao <zhangfei.gao@linaro.org>
> ---
> drivers/reset/Makefile | 2 +-
> drivers/reset/hisilicon/Makefile | 1 +
> drivers/reset/hisilicon/reset.c | 108 +++++++++++++++++++++++++++++++++++++++
> drivers/reset/hisilicon/reset.h | 37 ++++++++++++++
> 4 files changed, 147 insertions(+), 1 deletion(-)
> create mode 100644 drivers/reset/hisilicon/reset.c
> create mode 100644 drivers/reset/hisilicon/reset.h
>
> diff --git a/drivers/reset/Makefile b/drivers/reset/Makefile
> index bbe7026..7e3dc4e 100644
> --- a/drivers/reset/Makefile
> +++ b/drivers/reset/Makefile
> @@ -1,8 +1,8 @@
> obj-y += core.o
> -obj-y += hisilicon/
> obj-$(CONFIG_ARCH_STI) += sti/
> obj-$(CONFIG_RESET_ATH79) += reset-ath79.o
> obj-$(CONFIG_RESET_BERLIN) += reset-berlin.o
> +obj-$(CONFIG_ARCH_HISI) += hisilicon/
> obj-$(CONFIG_RESET_LPC18XX) += reset-lpc18xx.o
> obj-$(CONFIG_RESET_MESON) += reset-meson.o
> obj-$(CONFIG_RESET_OXNAS) += reset-oxnas.o
> diff --git a/drivers/reset/hisilicon/Makefile b/drivers/reset/hisilicon/Makefile
> index c932f86..df511f5 100644
> --- a/drivers/reset/hisilicon/Makefile
> +++ b/drivers/reset/hisilicon/Makefile
> @@ -1 +1,2 @@
> +obj-y += reset.o
> obj-$(CONFIG_COMMON_RESET_HI6220) += hi6220_reset.o
> diff --git a/drivers/reset/hisilicon/reset.c b/drivers/reset/hisilicon/reset.c
> new file mode 100644
> index 0000000..c4971c9
> --- /dev/null
> +++ b/drivers/reset/hisilicon/reset.c
> @@ -0,0 +1,108 @@
> +/*
> + * Copyright (c) 2016-2017 Linaro Ltd.
> + * Copyright (c) 2016-2017 HiSilicon Technologies Co., Ltd.
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; either version 2 of the License, or
> + * (at your option) any later version.
> + */
> +#include <linux/kernel.h>
> +#include <linux/platform_device.h>
> +#include <linux/module.h>
> +#include <linux/err.h>
> +#include <linux/types.h>
> +#include <linux/of_device.h>
> +#include <linux/mfd/syscon.h>
> +
> +#include "reset.h"
> +
> +struct hisi_reset_controller {
> + struct reset_controller_dev rst;
> + const struct hisi_reset_channel_data *channels;
> + struct regmap *map;
> +};
> +
> +#define to_hisi_reset_controller(_rst) \
> + container_of(_rst, struct hisi_reset_controller, rst)
> +
> +static int hisi_reset_program_hw(struct reset_controller_dev *rcdev,
> + unsigned long idx, bool assert)
> +{
> + struct hisi_reset_controller *rc = to_hisi_reset_controller(rcdev);
> + const struct hisi_reset_channel_data *ch;
> +
> + if (idx >= rcdev->nr_resets)
> + return -EINVAL;
> +
> + ch = &rc->channels[idx];
> +
> + if (assert)
> + return regmap_write(rc->map, ch->enable.reg,
> + GENMASK(ch->enable.msb, ch->enable.lsb));
> + else
> + return regmap_write(rc->map, ch->disable.reg,
> + GENMASK(ch->disable.msb, ch->disable.lsb));
These fields are always 1-bit wide and you are not using the
regmap_field functions to access them, so I'd suggest to remove the
struct reg_field indirection and overhead and just write
if (assert)
return regmap_write(rc->map, ch->enable_reg, ch->bit);
else
return regmap_write(rc->map, ch->disable_reg, ch->bit);
here.
> +}
> +
> +static int hisi_reset_assert(struct reset_controller_dev *rcdev,
> + unsigned long idx)
> +{
> + return hisi_reset_program_hw(rcdev, idx, true);
> +}
> +
> +static int hisi_reset_deassert(struct reset_controller_dev *rcdev,
> + unsigned long idx)
> +{
> + return hisi_reset_program_hw(rcdev, idx, false);
> +}
> +
> +static int hisi_reset_dev(struct reset_controller_dev *rcdev,
> + unsigned long idx)
> +{
> + int err;
> +
> + err = hisi_reset_assert(rcdev, idx);
> + if (err)
> + return err;
> +
> + return hisi_reset_deassert(rcdev, idx);
> +}
> +
> +static struct reset_control_ops hisi_reset_ops = {
> + .reset = hisi_reset_dev,
> + .assert = hisi_reset_assert,
> + .deassert = hisi_reset_deassert,
> +};
> +
> +int hisi_reset_probe(struct platform_device *pdev)
> +{
> + struct hisi_reset_controller *rc;
> + struct device_node *np = pdev->dev.of_node;
> + struct hisi_reset_controller_data *d;
> + struct device *dev = &pdev->dev;
> + const struct of_device_id *match;
> +
> + match = of_match_device(dev->driver->of_match_table, dev);
> + if (!match || !match->data)
> + return -EINVAL;
> +
> + d = (struct hisi_reset_controller_data *)match->data;
> + rc = devm_kzalloc(dev, sizeof(*rc), GFP_KERNEL);
> + if (!rc)
> + return -ENOMEM;
> +
> + rc->map = syscon_regmap_lookup_by_phandle(np, "hisi,rst-syscon");
> + if (IS_ERR(rc->map)) {
> + dev_err(dev, "failed to get hisi,rst-syscon\n");
> + return PTR_ERR(rc->map);
> + }
> +
> + rc->rst.ops = &hisi_reset_ops,
> + rc->rst.of_node = np;
> + rc->rst.nr_resets = d->nr_channels;
> + rc->channels = d->channels;
> +
> + return reset_controller_register(&rc->rst);
> +}
> +EXPORT_SYMBOL_GPL(hisi_reset_probe);
> diff --git a/drivers/reset/hisilicon/reset.h b/drivers/reset/hisilicon/reset.h
> new file mode 100644
> index 0000000..77259ee
> --- /dev/null
> +++ b/drivers/reset/hisilicon/reset.h
> @@ -0,0 +1,37 @@
> +/*
> + * Copyright (c) 2016-2017 Linaro Ltd.
> + * Copyright (c) 2016-2017 HiSilicon Technologies Co., Ltd.
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; either version 2 of the License, or
> + * (at your option) any later version.
> + */
> +
> +#ifndef __HISILICON_RESET_H
> +#define __HISILICON_RESET_H
> +
> +#include <linux/device.h>
> +#include <linux/regmap.h>
> +#include <linux/reset-controller.h>
> +
> +/* reset separated register offset is 0x4 */
> +#define HISI_RST_SEP(off, bit) \
> + { .enable = REG_FIELD(off, bit, bit), \
> + .disable = REG_FIELD(off + 0x4, bit, bit), \
> + .status = REG_FIELD(off + 0x8, bit, bit), }
> +
> +struct hisi_reset_channel_data {
> + struct reg_field enable;
> + struct reg_field disable;
> + struct reg_field status;
> +};
Are you expecting the bits to be at different positions in the
enable/disable/status registers? How about just
#define HISI_RST_SEP(off, _bit) \
{ .enable_reg = (off), \
.disable_reg = (off) + 0x4, \
.status_reg = (off) + 0x8, \
.bit = (_bit), }
struct hisi_reset_channel_data {
unsigned int enable_reg;
unsigned int disable_reg;
unsigned int status_reg;
unsigned int bit;
};
as those struct reg_field are not accessed via regmap_field_* functions
anyway.
> +
> +struct hisi_reset_controller_data {
> + int nr_channels;
> + const struct hisi_reset_channel_data *channels;
> +};
> +
> +int hisi_reset_probe(struct platform_device *pdev);
> +
> +#endif /* __HISILICON_RESET_H */
regards
Philipp
^ permalink raw reply
* [PATCH 1/6] reset: hisilicon: add reset core
From: Philipp Zabel @ 2016-11-22 10:22 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1479800961-6249-2-git-send-email-zhangfei.gao@linaro.org>
Hi Zhangfei,
Am Dienstag, den 22.11.2016, 15:49 +0800 schrieb Zhangfei Gao:
> reset.c will be shared by hisilicon chips like hi3660 and hi6220
>
> Signed-off-by: Zhangfei Gao <zhangfei.gao@linaro.org>
> ---
> drivers/reset/Makefile | 2 +-
> drivers/reset/hisilicon/Makefile | 1 +
> drivers/reset/hisilicon/reset.c | 108 +++++++++++++++++++++++++++++++++++++++
> drivers/reset/hisilicon/reset.h | 37 ++++++++++++++
> 4 files changed, 147 insertions(+), 1 deletion(-)
> create mode 100644 drivers/reset/hisilicon/reset.c
> create mode 100644 drivers/reset/hisilicon/reset.h
>
> diff --git a/drivers/reset/Makefile b/drivers/reset/Makefile
> index bbe7026..7e3dc4e 100644
> --- a/drivers/reset/Makefile
> +++ b/drivers/reset/Makefile
> @@ -1,8 +1,8 @@
> obj-y += core.o
> -obj-y += hisilicon/
> obj-$(CONFIG_ARCH_STI) += sti/
> obj-$(CONFIG_RESET_ATH79) += reset-ath79.o
> obj-$(CONFIG_RESET_BERLIN) += reset-berlin.o
> +obj-$(CONFIG_ARCH_HISI) += hisilicon/
> obj-$(CONFIG_RESET_LPC18XX) += reset-lpc18xx.o
> obj-$(CONFIG_RESET_MESON) += reset-meson.o
> obj-$(CONFIG_RESET_OXNAS) += reset-oxnas.o
> diff --git a/drivers/reset/hisilicon/Makefile b/drivers/reset/hisilicon/Makefile
> index c932f86..df511f5 100644
> --- a/drivers/reset/hisilicon/Makefile
> +++ b/drivers/reset/hisilicon/Makefile
> @@ -1 +1,2 @@
> +obj-y += reset.o
> obj-$(CONFIG_COMMON_RESET_HI6220) += hi6220_reset.o
> diff --git a/drivers/reset/hisilicon/reset.c b/drivers/reset/hisilicon/reset.c
> new file mode 100644
> index 0000000..c4971c9
> --- /dev/null
> +++ b/drivers/reset/hisilicon/reset.c
> @@ -0,0 +1,108 @@
> +/*
> + * Copyright (c) 2016-2017 Linaro Ltd.
> + * Copyright (c) 2016-2017 HiSilicon Technologies Co., Ltd.
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; either version 2 of the License, or
> + * (at your option) any later version.
> + */
> +#include <linux/kernel.h>
> +#include <linux/platform_device.h>
> +#include <linux/module.h>
> +#include <linux/err.h>
> +#include <linux/types.h>
> +#include <linux/of_device.h>
> +#include <linux/mfd/syscon.h>
> +
> +#include "reset.h"
> +
> +struct hisi_reset_controller {
> + struct reset_controller_dev rst;
> + const struct hisi_reset_channel_data *channels;
> + struct regmap *map;
> +};
> +
> +#define to_hisi_reset_controller(_rst) \
> + container_of(_rst, struct hisi_reset_controller, rst)
> +
> +static int hisi_reset_program_hw(struct reset_controller_dev *rcdev,
> + unsigned long idx, bool assert)
> +{
> + struct hisi_reset_controller *rc = to_hisi_reset_controller(rcdev);
> + const struct hisi_reset_channel_data *ch;
> +
> + if (idx >= rcdev->nr_resets)
> + return -EINVAL;
> +
> + ch = &rc->channels[idx];
> +
> + if (assert)
> + return regmap_write(rc->map, ch->enable.reg,
> + GENMASK(ch->enable.msb, ch->enable.lsb));
> + else
> + return regmap_write(rc->map, ch->disable.reg,
> + GENMASK(ch->disable.msb, ch->disable.lsb));
These fields are always 1-bit wide and you are not using the
regmap_field functions to access them, so I'd suggest to remove the
struct reg_field indirection and overhead and just write
if (assert)
return regmap_write(rc->map, ch->enable_reg, ch->bit);
else
return regmap_write(rc->map, ch->disable_reg, ch->bit);
here.
> +}
> +
> +static int hisi_reset_assert(struct reset_controller_dev *rcdev,
> + unsigned long idx)
> +{
> + return hisi_reset_program_hw(rcdev, idx, true);
> +}
> +
> +static int hisi_reset_deassert(struct reset_controller_dev *rcdev,
> + unsigned long idx)
> +{
> + return hisi_reset_program_hw(rcdev, idx, false);
> +}
> +
> +static int hisi_reset_dev(struct reset_controller_dev *rcdev,
> + unsigned long idx)
> +{
> + int err;
> +
> + err = hisi_reset_assert(rcdev, idx);
> + if (err)
> + return err;
> +
> + return hisi_reset_deassert(rcdev, idx);
> +}
> +
> +static struct reset_control_ops hisi_reset_ops = {
> + .reset = hisi_reset_dev,
> + .assert = hisi_reset_assert,
> + .deassert = hisi_reset_deassert,
> +};
> +
> +int hisi_reset_probe(struct platform_device *pdev)
> +{
> + struct hisi_reset_controller *rc;
> + struct device_node *np = pdev->dev.of_node;
> + struct hisi_reset_controller_data *d;
> + struct device *dev = &pdev->dev;
> + const struct of_device_id *match;
> +
> + match = of_match_device(dev->driver->of_match_table, dev);
> + if (!match || !match->data)
> + return -EINVAL;
> +
> + d = (struct hisi_reset_controller_data *)match->data;
> + rc = devm_kzalloc(dev, sizeof(*rc), GFP_KERNEL);
> + if (!rc)
> + return -ENOMEM;
> +
> + rc->map = syscon_regmap_lookup_by_phandle(np, "hisi,rst-syscon");
> + if (IS_ERR(rc->map)) {
> + dev_err(dev, "failed to get hisi,rst-syscon\n");
> + return PTR_ERR(rc->map);
> + }
> +
> + rc->rst.ops = &hisi_reset_ops,
> + rc->rst.of_node = np;
> + rc->rst.nr_resets = d->nr_channels;
> + rc->channels = d->channels;
> +
> + return reset_controller_register(&rc->rst);
> +}
> +EXPORT_SYMBOL_GPL(hisi_reset_probe);
> diff --git a/drivers/reset/hisilicon/reset.h b/drivers/reset/hisilicon/reset.h
> new file mode 100644
> index 0000000..77259ee
> --- /dev/null
> +++ b/drivers/reset/hisilicon/reset.h
> @@ -0,0 +1,37 @@
> +/*
> + * Copyright (c) 2016-2017 Linaro Ltd.
> + * Copyright (c) 2016-2017 HiSilicon Technologies Co., Ltd.
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; either version 2 of the License, or
> + * (at your option) any later version.
> + */
> +
> +#ifndef __HISILICON_RESET_H
> +#define __HISILICON_RESET_H
> +
> +#include <linux/device.h>
> +#include <linux/regmap.h>
> +#include <linux/reset-controller.h>
> +
> +/* reset separated register offset is 0x4 */
> +#define HISI_RST_SEP(off, bit) \
> + { .enable = REG_FIELD(off, bit, bit), \
> + .disable = REG_FIELD(off + 0x4, bit, bit), \
> + .status = REG_FIELD(off + 0x8, bit, bit), }
> +
> +struct hisi_reset_channel_data {
> + struct reg_field enable;
> + struct reg_field disable;
> + struct reg_field status;
> +};
Are you expecting the bits to be at different positions in the
enable/disable/status registers? How about just
#define HISI_RST_SEP(off, _bit) \
{ .enable_reg = (off), \
.disable_reg = (off) + 0x4, \
.status_reg = (off) + 0x8, \
.bit = (_bit), }
struct hisi_reset_channel_data {
unsigned int enable_reg;
unsigned int disable_reg;
unsigned int status_reg;
unsigned int bit;
};
as those struct reg_field are not accessed via regmap_field_* functions
anyway.
> +
> +struct hisi_reset_controller_data {
> + int nr_channels;
> + const struct hisi_reset_channel_data *channels;
> +};
> +
> +int hisi_reset_probe(struct platform_device *pdev);
> +
> +#endif /* __HISILICON_RESET_H */
regards
Philipp
^ permalink raw reply
* [PATCH 3/6] reset: hisilicon: add reset-hi3660
From: Philipp Zabel @ 2016-11-22 10:22 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <3166877.sQekoU5ezv@wuerfel>
Am Dienstag, den 22.11.2016, 10:42 +0100 schrieb Arnd Bergmann:
> On Tuesday, November 22, 2016 5:34:05 PM CET zhangfei wrote:
> > On 2016?11?22? 16:50, Arnd Bergmann wrote:
> > > On Tuesday, November 22, 2016 3:49:18 PM CET Zhangfei Gao wrote:
> > >> +static const struct hisi_reset_channel_data hi3660_iomcu_rst[] = {
> > >> + [HI3660_RST_I2C0] = HISI_RST_SEP(0x20, 3),
> > >> + [HI3660_RST_I2C1] = HISI_RST_SEP(0x20, 4),
> > >> + [HI3660_RST_I2C2] = HISI_RST_SEP(0x20, 5),
> > >> + [HI3660_RST_I2C6] = HISI_RST_SEP(0x20, 27),
> > >> +};
> > >> +
> > >> +static struct hisi_reset_controller_data hi3660_iomcu_controller = {
> > >> + .nr_channels = ARRAY_SIZE(hi3660_iomcu_rst),
> > >> + .channels = hi3660_iomcu_rst,
> > >> +};
> > >> +
> > >> +static const struct hisi_reset_channel_data hi3660_crgctrl_rst[] = {
> > >> + [HI3660_RST_I2C3] = HISI_RST_SEP(0x78, 7),
> > >> + [HI3660_RST_I2C4] = HISI_RST_SEP(0x78, 27),
> > >> + [HI3660_RST_I2C7] = HISI_RST_SEP(0x60, 14),
> > >> + [HI3660_RST_SD] = HISI_RST_SEP(0x90, 18),
> > >> + [HI3660_RST_SDIO] = HISI_RST_SEP(0x90, 20),
> > >> + [HI3660_RST_UFS] = HISI_RST_SEP(0x84, 12),
> > >> + [HI3660_RST_UFS_ASSERT] = HISI_RST_SEP(0x84, 7),
> > >> + [HI3660_RST_PCIE_SYS] = HISI_RST_SEP(0x84, 26),
> > >> + [HI3660_RST_PCIE_PHY] = HISI_RST_SEP(0x84, 27),
> > >> + [HI3660_RST_PCIE_BUS] = HISI_RST_SEP(0x84, 31),
> > >> + [HI3660_RST_USB3OTG_PHY] = HISI_RST_SEP(0x90, 3),
> > >> + [HI3660_RST_USB3OTG] = HISI_RST_SEP(0x90, 5),
> > >> + [HI3660_RST_USB3OTG_32K] = HISI_RST_SEP(0x90, 6),
> > >> + [HI3660_RST_USB3OTG_AHB] = HISI_RST_SEP(0x90, 7),
> > >> + [HI3660_RST_USB3OTG_MUX] = HISI_RST_SEP(0x90, 8),
> > >> +};
> > > I think you can avoid the trap of the ABI incompatibility if
> > > you just define those as in the binding as tuples, using #reset-cells=2.
> > >
> > > In particular for the first set, it seems really silly to redefine
> > > the numbers when there is just a simple integer number.
> >
> > Could you clarify more, still not understand.
> > The number is index of the arrays, and the index will be used in dts.
> > The arrays lists the registers offset and bit shift.
> > For example:
> >
> > [HI3660_RST_I2C0] = HISI_RST_SEP(0x20, 3), means register offset : 0x20, and bit shift = 3.
> >
> > And Documentation/devicetree/bindings/reset/reset.txt
> > Required properties:
> > #reset-cells: Number of cells in a reset specifier; Typically 0 for nodes
> > with a single reset output and 1 for nodes with multiple
> > reset outputs.
This is just a suggestion, for reset controllers where the reset lines
can reasonably be enumerated by a single integer. If there is a good
reason to use more complicated bindings, more cells can be used.
That being said, I dislike having to spread register/bit information
throughout the device trees at the consumer/phandle sites, if the
register/bit information absolutely has to be put into the device tree,
I'd prefer a binding similar to ti-syscon, where it's all in one place.
> You can easily enumerate the registers that contain reset bits here,
> so just use one cell for the register and another one for the index.
Changing the reset cells is an incompatible change, and this is not a
straight forward register/bit mapping in hardware either. There are
currently three registers involved: enable (+0x0), disable (+0x4), and
status (+0x8). Also, what if in the future one of these reset bits have
to be handled inverted (as just happened for hi3519)?
regards
Philipp
^ permalink raw reply
* [PATCH 3/3] ARM: davinci: hawk: use gpio descriptor for card detect
From: Sekhar Nori @ 2016-11-22 10:26 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161121161541.27048-4-ahaslam@baylibre.com>
On Monday 21 November 2016 09:45 PM, Axel Haslam wrote:
> Currently the mmc driver is polling the gpio to know if the
> card was removed.
>
> By using a gpio descriptor instead of the platform callbacks, the
> driver will be able to register the gpio with the mmc core with API's
> designed for this purpose.
>
> This has the advantage that an irq will be registered,
> and polling is no longer needed. Also, platform callbacks can be removed.
>
> Signed-off-by: Axel Haslam <ahaslam@baylibre.com>
This patch looks good, provided it is not based of 1/3 and 2/3. There
are other boards in mach-davinci using the card detect and wp callbacks.
And some like board-dm365-evm.c have those pins routed through a CPLD.
So I guess there is more work to be done before platform callbacks can
completely be removed from MMC/SD driver. But the closer we get, the
better it is :)
Thanks,
Sekhar
^ permalink raw reply
* [PATCH] ARM: dts: da850: specify max width for display node
From: Tomi Valkeinen @ 2016-11-22 10:27 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1479807775-28283-1-git-send-email-bgolaszewski@baylibre.com>
On 22/11/16 11:42, Bartosz Golaszewski wrote:
> It has been determined that the highest resolution supported correctly
> by LCDC rev1 is 800x600 on da850 due to memory bandwidth constraints.
>
> Set the max_width property in da850.dtsi to 800.
>
> Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
> ---
> arch/arm/boot/dts/da850.dtsi | 1 +
> 1 file changed, 1 insertion(+)
>
> diff --git a/arch/arm/boot/dts/da850.dtsi b/arch/arm/boot/dts/da850.dtsi
> index 36066fa..0876238 100644
> --- a/arch/arm/boot/dts/da850.dtsi
> +++ b/arch/arm/boot/dts/da850.dtsi
> @@ -441,6 +441,7 @@
> compatible = "ti,da850-tilcdc";
> reg = <0x213000 0x1000>;
> interrupts = <52>;
> + max-width = <800>;
> status = "disabled";
> };
> };
>
Does 1024x768 at 10 work?
The max-width should be the hardware's maximum supported width, not used
for bandwidth. tilcdc has max-bandwidth property for that.
Tomi
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: OpenPGP digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20161122/6e711402/attachment.sig>
^ permalink raw reply
* [PATCH] ARM: dts: da850: specify max width for display node
From: Bartosz Golaszewski @ 2016-11-22 10:30 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <77c993f3-1b5f-94cf-c4bc-8a30148e0a4d@ti.com>
2016-11-22 11:27 GMT+01:00 Tomi Valkeinen <tomi.valkeinen@ti.com>:
> On 22/11/16 11:42, Bartosz Golaszewski wrote:
>> It has been determined that the highest resolution supported correctly
>> by LCDC rev1 is 800x600 on da850 due to memory bandwidth constraints.
>>
>> Set the max_width property in da850.dtsi to 800.
>>
>> Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
>> ---
>> arch/arm/boot/dts/da850.dtsi | 1 +
>> 1 file changed, 1 insertion(+)
>>
>> diff --git a/arch/arm/boot/dts/da850.dtsi b/arch/arm/boot/dts/da850.dtsi
>> index 36066fa..0876238 100644
>> --- a/arch/arm/boot/dts/da850.dtsi
>> +++ b/arch/arm/boot/dts/da850.dtsi
>> @@ -441,6 +441,7 @@
>> compatible = "ti,da850-tilcdc";
>> reg = <0x213000 0x1000>;
>> interrupts = <52>;
>> + max-width = <800>;
>> status = "disabled";
>> };
>> };
>>
>
> Does 1024x768 at 10 work?
>
> The max-width should be the hardware's maximum supported width, not used
> for bandwidth. tilcdc has max-bandwidth property for that.
>
> Tomi
>
Eeek I misread Jyri's answer.
Will fix that in v2.
Thanks,
Bartosz
^ permalink raw reply
* [RESEND PATCH 1/3] ARM: davinci: da830: Handle vbus with a regulator
From: Sekhar Nori @ 2016-11-22 10:35 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161121165349.29128-2-ahaslam@baylibre.com>
On Monday 21 November 2016 10:23 PM, Axel Haslam wrote:
> static __init void da830_evm_usb_init(void)
> {
> @@ -145,23 +123,13 @@ static __init void da830_evm_usb_init(void)
> return;
> }
>
> - ret = gpio_request(ON_BD_USB_DRV, "ON_BD_USB_DRV");
> - if (ret) {
> - pr_err("%s: failed to request GPIO for USB 1.1 port power control: %d\n",
> - __func__, ret);
> - return;
> - }
> - gpio_direction_output(ON_BD_USB_DRV, 0);
> + gpiod_add_lookup_table(&usb11_gpios_table);
>
> - ret = gpio_request(ON_BD_USB_OVC, "ON_BD_USB_OVC");
> - if (ret) {
> - pr_err("%s: failed to request GPIO for USB 1.1 port over-current indicator: %d\n",
> - __func__, ret);
> - return;
> - }
> - gpio_direction_input(ON_BD_USB_OVC);
> + ret = platform_device_register(&da8xx_usb11_regulator);
> + if (ret)
> + pr_warn("fail to add ohci regulator\n");
Can you follow the same style as used in other error/warning messages in
this function (adding a function name prefix, printing of error code).
Thanks,
Sekhar
^ permalink raw reply
* [RESEND PATCH 2/3] ARM: davinci: hawk: Remove vbus and over current gpios
From: Sekhar Nori @ 2016-11-22 10:37 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161121165349.29128-3-ahaslam@baylibre.com>
On Monday 21 November 2016 10:23 PM, Axel Haslam wrote:
> The hawk board VBUS is fixed to a 5v source, and the over
> current pin is actually not connected to the SoC.
>
> Do not reseve these gpios for OHCI as they are not related
> to usb.
>
> Signed-off-by: Axel Haslam <ahaslam@baylibre.com>
As discussed over the MMC/SD patches, this patch should be based off the
hawkboard schematic, not the LCDK schematic.
Thanks,
Sekhar
^ permalink raw reply
* [PATCH 0/3] ARM: da8xx: fix section mismatch in new drivers
From: Bartosz Golaszewski @ 2016-11-22 10:41 UTC (permalink / raw)
To: linux-arm-kernel
Sekhar noticed there's a section mismatch in the da8xx-mstpri and
da8xx-ddrctl drivers. This is caused by calling
of_flat_dt_get_machine_name() which has an __init annotation.
This series addresses this issue by introducing a new function that
allows to retrieve the compatible property of the root node and
using it instead of of_flat_dt_get_machine_name() in the new drivers.
Bartosz Golaszewski (3):
of: base: add support to get machine compatible string
bus: da8xx-mstpri: drop the call to of_flat_dt_get_machine_name()
memory: da8xx-ddrctl: drop the call to of_flat_dt_get_machine_name()
drivers/bus/da8xx-mstpri.c | 2 +-
drivers/memory/da8xx-ddrctl.c | 2 +-
drivers/of/base.c | 22 ++++++++++++++++++++++
include/linux/of.h | 6 ++++++
4 files changed, 30 insertions(+), 2 deletions(-)
--
2.9.3
^ permalink raw reply
* [PATCH 1/3] of: base: add support to get machine compatible string
From: Bartosz Golaszewski @ 2016-11-22 10:41 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1479811311-3080-1-git-send-email-bgolaszewski@baylibre.com>
Add a function allowing to retrieve the compatible string of the root
node of the device tree.
Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
---
drivers/of/base.c | 22 ++++++++++++++++++++++
include/linux/of.h | 6 ++++++
2 files changed, 28 insertions(+)
diff --git a/drivers/of/base.c b/drivers/of/base.c
index a0bccb5..bbfe5e9 100644
--- a/drivers/of/base.c
+++ b/drivers/of/base.c
@@ -546,6 +546,28 @@ int of_machine_is_compatible(const char *compat)
EXPORT_SYMBOL(of_machine_is_compatible);
/**
+ * of_machine_get_compatible - Get the compatible property of the root node
+ *
+ * Returns a NULL-terminated string containing the compatible if it could
+ * be found, NULL otherwise.
+ */
+const char *of_machine_get_compatible(void)
+{
+ struct device_node *root;
+ const char *compatible;
+ int ret = -1;
+
+ root = of_find_node_by_path("/");
+ if (root) {
+ ret = of_property_read_string(root, "compatible", &compatible);
+ of_node_put(root);
+ }
+
+ return ret ? NULL : compatible;
+}
+EXPORT_SYMBOL(of_machine_get_compatible);
+
+/**
* __of_device_is_available - check if a device is available for use
*
* @device: Node to check for availability, with locks already held
diff --git a/include/linux/of.h b/include/linux/of.h
index 299aeb1..664b734 100644
--- a/include/linux/of.h
+++ b/include/linux/of.h
@@ -367,6 +367,7 @@ extern int of_alias_get_id(struct device_node *np, const char *stem);
extern int of_alias_get_highest_id(const char *stem);
extern int of_machine_is_compatible(const char *compat);
+extern const char *of_machine_get_compatible(void);
extern int of_add_property(struct device_node *np, struct property *prop);
extern int of_remove_property(struct device_node *np, struct property *prop);
@@ -788,6 +789,11 @@ static inline int of_machine_is_compatible(const char *compat)
return 0;
}
+static inline const char *of_machine_get_compatible(void)
+{
+ return NULL;
+}
+
static inline bool of_console_check(const struct device_node *dn, const char *name, int index)
{
return false;
--
2.9.3
^ permalink raw reply related
* [PATCH 2/3] bus: da8xx-mstpri: drop the call to of_flat_dt_get_machine_name()
From: Bartosz Golaszewski @ 2016-11-22 10:41 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1479811311-3080-1-git-send-email-bgolaszewski@baylibre.com>
In order to avoid a section mismatch use of_machine_get_compatible()
instead of of_flat_dt_get_machine_name() when printing the error
message.
Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
---
drivers/bus/da8xx-mstpri.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/bus/da8xx-mstpri.c b/drivers/bus/da8xx-mstpri.c
index 85f0b53..41cbbe6 100644
--- a/drivers/bus/da8xx-mstpri.c
+++ b/drivers/bus/da8xx-mstpri.c
@@ -227,7 +227,7 @@ static int da8xx_mstpri_probe(struct platform_device *pdev)
prio_list = da8xx_mstpri_get_board_prio();
if (!prio_list) {
dev_err(dev, "no master priotities defined for board '%s'\n",
- of_flat_dt_get_machine_name());
+ of_machine_get_compatible());
return -EINVAL;
}
--
2.9.3
^ permalink raw reply related
* [PATCH 3/3] memory: da8xx-ddrctl: drop the call to of_flat_dt_get_machine_name()
From: Bartosz Golaszewski @ 2016-11-22 10:41 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1479811311-3080-1-git-send-email-bgolaszewski@baylibre.com>
In order to avoid a section mismatch use of_machine_get_compatible()
instead of of_flat_dt_get_machine_name() when printing the error
message.
Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
---
drivers/memory/da8xx-ddrctl.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/memory/da8xx-ddrctl.c b/drivers/memory/da8xx-ddrctl.c
index a20e7bb..179f505 100644
--- a/drivers/memory/da8xx-ddrctl.c
+++ b/drivers/memory/da8xx-ddrctl.c
@@ -118,7 +118,7 @@ static int da8xx_ddrctl_probe(struct platform_device *pdev)
setting = da8xx_ddrctl_get_board_settings();
if (!setting) {
dev_err(dev, "no settings for board '%s'\n",
- of_flat_dt_get_machine_name());
+ of_machine_get_compatible());
return -EINVAL;
}
--
2.9.3
^ permalink raw reply related
* [RESEND PATCH 3/3] ARM: davinci: remove ohci platform usage
From: Sekhar Nori @ 2016-11-22 10:42 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161121165349.29128-4-ahaslam@baylibre.com>
On Monday 21 November 2016 10:23 PM, Axel Haslam wrote:
> As all users of ohci platform data have been converted
> to use a regulator, we dont need to pass platform
> data to register the ohci device anymore.
>
> Signed-off-by: Axel Haslam <ahaslam@baylibre.com>
This looks good to me.
Thanks,
Sekhar
^ permalink raw reply
* [PATCH v2] mfd: twl-core: make driver DT only
From: Baruch Siach @ 2016-11-22 10:45 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1479810090-12183-1-git-send-email-Nicolae_Rosia@mentor.com>
Hi Nicolae,
On Tue, Nov 22, 2016 at 12:21:30PM +0200, Nicolae Rosia wrote:
> All users are DT-only and it makes no sense to keep
> unused code which also prevents further cleanups.
>
> Signed-off-by: Nicolae Rosia <Nicolae_Rosia@mentor.com>
> ---
> Changes in v2:
> Increased audience in CC list
>
> drivers/mfd/Kconfig | 1 +
> drivers/mfd/twl-core.c | 395 ++-----------------------------------------------
> 2 files changed, 10 insertions(+), 386 deletions(-)
[...]
> @@ -1080,7 +710,6 @@ static struct of_dev_auxdata twl_auxdata_lookup[] = {
> static int
> twl_probe(struct i2c_client *client, const struct i2c_device_id *id)
> {
> - struct twl4030_platform_data *pdata = dev_get_platdata(&client->dev);
Can struct twl4030_platform_data declaration be removed now from
include/linux/i2c/twl.h?
baruch
--
http://baruch.siach.name/blog/ ~. .~ Tk Open Systems
=}------------------------------------------------ooO--U--Ooo------------{=
- baruch at tkos.co.il - tel: +972.52.368.4656, http://www.tkos.co.il -
^ permalink raw reply
* [PATCH 8/9] mtd: nand: mxc: implement onfi get/set features
From: Sascha Hauer @ 2016-11-22 10:52 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161121145643.7804e28f@bbrezillon>
Hi Boris,
On Mon, Nov 21, 2016 at 02:56:43PM +0100, Boris Brezillon wrote:
> Hi Sascha,
>
> On Thu, 15 Sep 2016 10:32:52 +0200
> Sascha Hauer <s.hauer@pengutronix.de> wrote:
>
> > To be able to support different ONFI timing modes we have to implement
> > the onfi_set_features and onfi_get_features. Tested on an i.MX25 SoC.
> >
> > Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
> > ---
> > drivers/mtd/nand/mxc_nand.c | 53 +++++++++++++++++++++++++++++++++++++++++++++
> > 1 file changed, 53 insertions(+)
> >
> > diff --git a/drivers/mtd/nand/mxc_nand.c b/drivers/mtd/nand/mxc_nand.c
> > index 5173fad..1db8299 100644
> > --- a/drivers/mtd/nand/mxc_nand.c
> > +++ b/drivers/mtd/nand/mxc_nand.c
> > @@ -1239,6 +1239,57 @@ static void mxc_nand_command(struct mtd_info *mtd, unsigned command,
> > }
> > }
> >
> > +static int mxc_nand_onfi_set_features(struct mtd_info *mtd, struct nand_chip *chip,
> > + int addr, uint8_t *subfeature_param)
> > +{
> > + struct nand_chip *nand_chip = mtd_to_nand(mtd);
> > + struct mxc_nand_host *host = nand_get_controller_data(nand_chip);
> > + int i;
> > +
> > + if (!chip->onfi_version ||
> > + !(le16_to_cpu(chip->onfi_params.opt_cmd)
> > + & ONFI_OPT_CMD_SET_GET_FEATURES))
> > + return -EINVAL;
> > +
> > + host->buf_start = 0;
> > +
> > + for (i = 0; i < ONFI_SUBFEATURE_PARAM_LEN; ++i)
> > + chip->write_byte(mtd, subfeature_param[i]);
> > +
> > + memcpy32_toio(host->main_area0, host->data_buf, mtd->writesize);
> > + host->devtype_data->send_cmd(host, NAND_CMD_SET_FEATURES, false);
> > + mxc_do_addr_cycle(mtd, addr, -1);
> > + host->devtype_data->send_page(mtd, NFC_INPUT);
>
> I've been working with an mx27 board embedding a NAND device lately,
> and had a closer look at the NAND controller IP.
> With this IP, you're not able to send only 4 bytes of data, and I'm
> sure sure what you're doing here (sending a full page of data) works
> for a SET_FEATURE command.
>
> Do you have a way to test it (my NAND is not ONFI compliant)? By test
> it, I mean, set a timing mode using SET_FEATURE and check if the new
> mode has been applied using GET_FEATURE.
I have an i.MX27 board with ONFI flash, but this one does not have the
ONFI_OPT_CMD_SET_GET_FEATURES bit set, so I can't test it there.
However, I can confirm that it works on an i.MX25. With the attached
patch applied on vanilla v4.9-rc5 I get:
GET FEATURES. chip->onfi_timing_mode_default: 4
timing before: 0x00
timing after: 0x04
Sascha
-------------------------8<-------------------------------
>From 38e45851a796ba47e25c72ebc58e358c70e18275 Mon Sep 17 00:00:00 2001
From: Sascha Hauer <s.hauer@pengutronix.de>
Date: Tue, 22 Nov 2016 11:48:36 +0100
Subject: [PATCH] wip
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
drivers/mtd/nand/nand_base.c | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
index 3bde96a..5b5be2b 100644
--- a/drivers/mtd/nand/nand_base.c
+++ b/drivers/mtd/nand/nand_base.c
@@ -1017,12 +1017,24 @@ static int nand_setup_data_interface(struct nand_chip *chip)
u8 tmode_param[ONFI_SUBFEATURE_PARAM_LEN] = {
chip->onfi_timing_mode_default,
};
+ u8 rmode_param[ONFI_SUBFEATURE_PARAM_LEN] = {};
+
+ printk("GET FEATURES. chip->onfi_timing_mode_default: %d\n", chip->onfi_timing_mode_default);
+ ret = chip->onfi_get_features(mtd, chip, ONFI_FEATURE_ADDR_TIMING_MODE, rmode_param);
+ if (ret)
+ goto err;
+ printk("timing before: 0x%02x\n", rmode_param[0]);
ret = chip->onfi_set_features(mtd, chip,
ONFI_FEATURE_ADDR_TIMING_MODE,
tmode_param);
if (ret)
goto err;
+
+ ret = chip->onfi_get_features(mtd, chip, ONFI_FEATURE_ADDR_TIMING_MODE, rmode_param);
+ if (ret)
+ goto err;
+ printk("timing after: 0x%02x\n", rmode_param[0]);
}
ret = chip->setup_data_interface(mtd, chip->data_interface, false);
--
2.10.2
--
Pengutronix e.K. | |
Industrial Linux Solutions | http://www.pengutronix.de/ |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox