* Re: [PATCH v5 net-next 3/3] rds: Extend RDS API for IPv6 support
From: santosh.shilimkar @ 2018-07-24 4:16 UTC (permalink / raw)
To: Ka-Cheong Poon, netdev; +Cc: davem, rds-devel, sowmini.varadhan
In-Reply-To: <cbb2d34e7b627f8a89f3d774aee585c6945e048f.1532404047.git.ka-cheong.poon@oracle.com>
On 7/23/18 8:51 PM, Ka-Cheong Poon wrote:
> There are many data structures (RDS socket options) used by RDS apps
> which use a 32 bit integer to store IP address. To support IPv6,
> struct in6_addr needs to be used. To ensure backward compatibility, a
> new data structure is introduced for each of those data structures
> which use a 32 bit integer to represent an IP address. And new socket
> options are introduced to use those new structures. This means that
> existing apps should work without a problem with the new RDS module.
> For apps which want to use IPv6, those new data structures and socket
> options can be used. IPv4 mapped address is used to represent IPv4
> address in the new data structures.
>
> v4: Revert changes to SO_RDS_TRANSPORT
>
> Signed-off-by: Ka-Cheong Poon<ka-cheong.poon@oracle.com>
> ---
Acked-by: Santosh Shilimkar <santosh.shilimkar@oracle.com>
^ permalink raw reply
* Re: [PATCH v5 net-next 2/3] rds: Enable RDS IPv6 support
From: santosh.shilimkar @ 2018-07-24 4:16 UTC (permalink / raw)
To: Ka-Cheong Poon, netdev; +Cc: davem, rds-devel, sowmini.varadhan
In-Reply-To: <5ed088681a8508278fd3f5a7ec8eee0179034f12.1532404047.git.ka-cheong.poon@oracle.com>
On 7/23/18 8:51 PM, Ka-Cheong Poon wrote:
> This patch enables RDS to use IPv6 addresses. For RDS/TCP, the
> listener is now an IPv6 endpoint which accepts both IPv4 and IPv6
> connection requests. RDS/RDMA/IB uses a private data (struct
> rds_ib_connect_private) exchange between endpoints at RDS connection
> establishment time to support RDMA. This private data exchange uses a
> 32 bit integer to represent an IP address. This needs to be changed in
> order to support IPv6. A new private data struct
> rds6_ib_connect_private is introduced to handle this. To ensure
> backward compatibility, an IPv6 capable RDS stack uses another RDMA
> listener port (RDS_CM_PORT) to accept IPv6 connection. And it
> continues to use the original RDS_PORT for IPv4 RDS connections. When
> it needs to communicate with an IPv6 peer, it uses the RDS_CM_PORT to
> send the connection set up request.
>
> v5: Fixed syntax problem (David Miller).
>
> v4: Changed port history comments in rds.h (Sowmini Varadhan).
>
> v3: Added support to set up IPv4 connection using mapped address
> (David Miller).
> Added support to set up connection between link local and non-link
> addresses.
> Various review comments from Santosh Shilimkar and Sowmini Varadhan.
>
> v2: Fixed bound and peer address scope mismatched issue.
> Added back rds_connect() IPv6 changes.
>
> Signed-off-by: Ka-Cheong Poon<ka-cheong.poon@oracle.com>
> ---
Acked-by: Santosh Shilimkar <santosh.shilimkar@oracle.com>
^ permalink raw reply
* Re: [PATCH v5 net-next 1/3] rds: Changing IP address internal representation to struct in6_addr
From: santosh.shilimkar @ 2018-07-24 4:15 UTC (permalink / raw)
To: Ka-Cheong Poon, netdev; +Cc: davem, rds-devel, sowmini.varadhan
In-Reply-To: <fb4069712ff1eca2988a002defa5d1b917f6853b.1532404047.git.ka-cheong.poon@oracle.com>
On 7/23/18 8:51 PM, Ka-Cheong Poon wrote:
> This patch changes the internal representation of an IP address to use
> struct in6_addr. IPv4 address is stored as an IPv4 mapped address.
> All the functions which take an IP address as argument are also
> changed to use struct in6_addr. But RDS socket layer is not modified
> such that it still does not accept IPv6 address from an application.
> And RDS layer does not accept nor initiate IPv6 connections.
>
> v2: Fixed sparse warnings.
>
> Signed-off-by: Ka-Cheong Poon<ka-cheong.poon@oracle.com>
> ---
Acked-by: Santosh Shilimkar <santosh.shilimkar@oracle.com>
^ permalink raw reply
* Re: [PATCH 0/4] drm_audio_component support for AMD/ATI HDMI codecs
From: Takashi Iwai @ 2018-07-24 5:19 UTC (permalink / raw)
To: Alex Deucher
Cc: alsa-devel-K7yf7f+aM1XWsZ/bQMPhNw, Maling list - DRI developers,
amd-gfx list
In-Reply-To: <CADnq5_MJf-+Xp5177oTf1M2z1ytrGXM1CYG_fyoh7+WQ5bPAPQ-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
On Mon, 23 Jul 2018 22:53:08 +0200,
Alex Deucher wrote:
>
> On Mon, Jul 23, 2018 at 10:50 AM, Takashi Iwai <tiwai@suse.de> wrote:
> > Hi,
> >
> > this is a patch set to add the support of drm_audio_component for
> > AMD/ATI HDMI codecs. With the drm_audio_component, the HDMI/DP audio
> > hotplug and ELD read-out can be achieved directly without the hardware
> > access. The best point by that is that it makes the hotplug
> > notification working even during runtime suspend.
> >
> > The support is totally optional and dynamic, hence it still works even
> > if either HD-audio or DRM side isn't patched, and it'll fall back to
> > the existing method.
>
> I'm still getting my head around how the new callbacks work so bear
> with me. It seems like we'd want to set the ELD and report whether
> the display is attached in when we detect the displays or fetch the
> EDID rather than at modeset time when we enable the audio stream.
Basically the callbacks are just replacements of the existing
mechanism with the direct calls.
In the traditional model, from GPU to HD-audio, we trigger a hotplug
event via writing a dedicated GPU register. In HD-audio side, it's
transmitted as an unsolicited event via HD-audio bus, and HD-audio
driver receives it. And for passing ELD, we write some bytes to GPU
registers in DRM driver. These are read by HD-audio driver in hotplug
handler after receiving the event.
In the callback model, GPU calls audio_ops.pin_eld_notify() with the
pin index. This callback is set by HD-audio. Then HD-audio reads
back ELD bytes in return by calling ops.get_eld() with the given pin
index. This callback is set by DRM.
For registration and de-registration, DRM gives the component bind /
unbind to set / clear its ops.
thanks,
Takashi
>
> Alex
>
>
> >
> > The current patch supports only radeon and a part of amdgpu; the DC
> > support isn't included yet.
> >
> >
> > Takashi
> >
> > ===
> >
> > Takashi Iwai (4):
> > ALSA: hda/hdmi: Use single mutex unlock in error paths
> > ALSA: hda/hdmi: Allow audio component for AMD/ATI HDMI
> > drm/radeon: Add audio component support
> > drm/amdgpu: Add audio component support
> >
> > drivers/gpu/drm/Kconfig | 2 +
> > drivers/gpu/drm/amd/amdgpu/Makefile | 2 +-
> > drivers/gpu/drm/amd/amdgpu/amdgpu.h | 4 +
> > drivers/gpu/drm/amd/amdgpu/amdgpu_audio.c | 97 ++++++++++
> > drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h | 3 +
> > drivers/gpu/drm/amd/amdgpu/dce_v10_0.c | 6 +
> > drivers/gpu/drm/amd/amdgpu/dce_v11_0.c | 6 +
> > drivers/gpu/drm/amd/amdgpu/dce_v6_0.c | 6 +
> > drivers/gpu/drm/amd/amdgpu/dce_v8_0.c | 6 +
> > drivers/gpu/drm/radeon/radeon.h | 3 +
> > drivers/gpu/drm/radeon/radeon_audio.c | 79 ++++++++
> > sound/pci/hda/patch_hdmi.c | 209 +++++++++++++++++-----
> > 12 files changed, 374 insertions(+), 49 deletions(-)
> > create mode 100644 drivers/gpu/drm/amd/amdgpu/amdgpu_audio.c
> >
> > --
> > 2.18.0
> >
> > _______________________________________________
> > amd-gfx mailing list
> > amd-gfx@lists.freedesktop.org
> > https://lists.freedesktop.org/mailman/listinfo/amd-gfx
>
_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx
^ permalink raw reply
* Re: [PATCH v3.1 0/4] arm64: kexec,kdump: fix boot failures on acpi-only system
From: Bhupesh Sharma @ 2018-07-24 5:19 UTC (permalink / raw)
To: Will Deacon
Cc: Mark Rutland, Lorenzo Pieralisi, Graeme Gregory, Al Stone,
Ard Biesheuvel, Catalin Marinas, Baicar, Tyler,
Kexec Mailing List, Linux Kernel Mailing List, AKASHI Takahiro,
James Morse, Hanjun Guo, Sudeep Holla, Dave Young,
linux-arm-kernel
In-Reply-To: <20180723133527.GA9450@arm.com>
Hi Will,
On Mon, Jul 23, 2018 at 7:05 PM, Will Deacon <will.deacon@arm.com> wrote:
> On Tue, Jul 17, 2018 at 02:12:23PM +0900, AKASHI Takahiro wrote:
>> On Fri, Jul 13, 2018 at 07:49:45AM +0200, Ard Biesheuvel wrote:
>> > On 13 July 2018 at 02:34, AKASHI Takahiro <takahiro.akashi@linaro.org> wrote:
>> > > On Thu, Jul 12, 2018 at 05:49:19PM +0100, Will Deacon wrote:
>> > >> Hi Akashi,
>> > >>
>> > >> On Tue, Jul 10, 2018 at 08:42:25AM +0900, AKASHI Takahiro wrote:
>> > >> > This patch series is a set of bug fixes to address kexec/kdump
>> > >> > failures which are sometimes observed on ACPI-only system and reported
>> > >> > in LAK-ML before.
>> > >>
>> > >> I tried picking this up, along with Ard's fixup, but I'm seeing a build
>> > >> failure for allmodconfig:
>> > >>
>> > >> arch/arm64/kernel/acpi.o: In function `__acpi_get_mem_attribute':
>> > >> acpi.c:(.text+0x60): undefined reference to `efi_mem_attributes'
>> > >>
>> > >> I didn't investigate further. Please can you fix this?
>> > >
>> > > Because CONFIG_ACPI is on and CONFIG_EFI is off.
>> > >
>> > > This can happen in allmodconfig as CONFIG_EFI depends on
>> > > !CONFIG_CPU_BIG_ENDIAN, which is actually on in this case.
>> > >
>> >
>> > Allowing both CONFIG_ACPI and CONFIG_CPU_BIG_ENDIAN to be configured
>> > makes no sense at all. Things will surely break if you start using BE
>> > memory accesses while parsing ACPI tables.
>> >
>> > Allowing CONFIG_ACPI without CONFIG_EFI makes no sense either, since
>> > on arm64, the only way to find the ACPI tables is through a UEFI
>> > configuration table.
>>
>>
>> Do you agree to this?
>
> Yes; please post a new series which resolves these dependencies and includes
> Ard's fixup from before.
I see that Akashi has already posted a v4 here with the suggested fixes:
https://lkml.org/lkml/2018/7/22/321
Thanks,
Bhupesh
_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec
^ permalink raw reply
* Re: [PATCH v3.1 0/4] arm64: kexec,kdump: fix boot failures on acpi-only system
From: Bhupesh Sharma @ 2018-07-24 5:19 UTC (permalink / raw)
To: Will Deacon
Cc: AKASHI Takahiro, Ard Biesheuvel, Catalin Marinas, Baicar, Tyler,
Dave Young, James Morse, Mark Rutland, Al Stone, Graeme Gregory,
Hanjun Guo, Lorenzo Pieralisi, Sudeep Holla, linux-arm-kernel,
Linux Kernel Mailing List, Kexec Mailing List
In-Reply-To: <20180723133527.GA9450@arm.com>
Hi Will,
On Mon, Jul 23, 2018 at 7:05 PM, Will Deacon <will.deacon@arm.com> wrote:
> On Tue, Jul 17, 2018 at 02:12:23PM +0900, AKASHI Takahiro wrote:
>> On Fri, Jul 13, 2018 at 07:49:45AM +0200, Ard Biesheuvel wrote:
>> > On 13 July 2018 at 02:34, AKASHI Takahiro <takahiro.akashi@linaro.org> wrote:
>> > > On Thu, Jul 12, 2018 at 05:49:19PM +0100, Will Deacon wrote:
>> > >> Hi Akashi,
>> > >>
>> > >> On Tue, Jul 10, 2018 at 08:42:25AM +0900, AKASHI Takahiro wrote:
>> > >> > This patch series is a set of bug fixes to address kexec/kdump
>> > >> > failures which are sometimes observed on ACPI-only system and reported
>> > >> > in LAK-ML before.
>> > >>
>> > >> I tried picking this up, along with Ard's fixup, but I'm seeing a build
>> > >> failure for allmodconfig:
>> > >>
>> > >> arch/arm64/kernel/acpi.o: In function `__acpi_get_mem_attribute':
>> > >> acpi.c:(.text+0x60): undefined reference to `efi_mem_attributes'
>> > >>
>> > >> I didn't investigate further. Please can you fix this?
>> > >
>> > > Because CONFIG_ACPI is on and CONFIG_EFI is off.
>> > >
>> > > This can happen in allmodconfig as CONFIG_EFI depends on
>> > > !CONFIG_CPU_BIG_ENDIAN, which is actually on in this case.
>> > >
>> >
>> > Allowing both CONFIG_ACPI and CONFIG_CPU_BIG_ENDIAN to be configured
>> > makes no sense at all. Things will surely break if you start using BE
>> > memory accesses while parsing ACPI tables.
>> >
>> > Allowing CONFIG_ACPI without CONFIG_EFI makes no sense either, since
>> > on arm64, the only way to find the ACPI tables is through a UEFI
>> > configuration table.
>>
>>
>> Do you agree to this?
>
> Yes; please post a new series which resolves these dependencies and includes
> Ard's fixup from before.
I see that Akashi has already posted a v4 here with the suggested fixes:
https://lkml.org/lkml/2018/7/22/321
Thanks,
Bhupesh
^ permalink raw reply
* [PATCH v3.1 0/4] arm64: kexec,kdump: fix boot failures on acpi-only system
From: Bhupesh Sharma @ 2018-07-24 5:19 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180723133527.GA9450@arm.com>
Hi Will,
On Mon, Jul 23, 2018 at 7:05 PM, Will Deacon <will.deacon@arm.com> wrote:
> On Tue, Jul 17, 2018 at 02:12:23PM +0900, AKASHI Takahiro wrote:
>> On Fri, Jul 13, 2018 at 07:49:45AM +0200, Ard Biesheuvel wrote:
>> > On 13 July 2018 at 02:34, AKASHI Takahiro <takahiro.akashi@linaro.org> wrote:
>> > > On Thu, Jul 12, 2018 at 05:49:19PM +0100, Will Deacon wrote:
>> > >> Hi Akashi,
>> > >>
>> > >> On Tue, Jul 10, 2018 at 08:42:25AM +0900, AKASHI Takahiro wrote:
>> > >> > This patch series is a set of bug fixes to address kexec/kdump
>> > >> > failures which are sometimes observed on ACPI-only system and reported
>> > >> > in LAK-ML before.
>> > >>
>> > >> I tried picking this up, along with Ard's fixup, but I'm seeing a build
>> > >> failure for allmodconfig:
>> > >>
>> > >> arch/arm64/kernel/acpi.o: In function `__acpi_get_mem_attribute':
>> > >> acpi.c:(.text+0x60): undefined reference to `efi_mem_attributes'
>> > >>
>> > >> I didn't investigate further. Please can you fix this?
>> > >
>> > > Because CONFIG_ACPI is on and CONFIG_EFI is off.
>> > >
>> > > This can happen in allmodconfig as CONFIG_EFI depends on
>> > > !CONFIG_CPU_BIG_ENDIAN, which is actually on in this case.
>> > >
>> >
>> > Allowing both CONFIG_ACPI and CONFIG_CPU_BIG_ENDIAN to be configured
>> > makes no sense at all. Things will surely break if you start using BE
>> > memory accesses while parsing ACPI tables.
>> >
>> > Allowing CONFIG_ACPI without CONFIG_EFI makes no sense either, since
>> > on arm64, the only way to find the ACPI tables is through a UEFI
>> > configuration table.
>>
>>
>> Do you agree to this?
>
> Yes; please post a new series which resolves these dependencies and includes
> Ard's fixup from before.
I see that Akashi has already posted a v4 here with the suggested fixes:
https://lkml.org/lkml/2018/7/22/321
Thanks,
Bhupesh
^ permalink raw reply
* Re: [PATCH 1/2] arm64: Get 'info->page_offset' from PT_LOAD segments to support KASLR boot cases
From: Bhupesh Sharma @ 2018-07-24 5:17 UTC (permalink / raw)
To: Kazuhito Hagio; +Cc: Bhupesh SHARMA, kexec mailing list
In-Reply-To: <4AE2DC15AC0B8543882A74EA0D43DBEC035590BC@BPXM09GP.gisp.nec.co.jp>
Hi Kazu,
On Mon, Jul 23, 2018 at 10:15 PM, Kazuhito Hagio <k-hagio@ab.jp.nec.com> wrote:
> Hi Bhupesh,
>
> On 7/22/2018 3:44 AM, Bhupesh Sharma wrote:
>> Hello Kazu,
>>
>> Many thanks for your review comments.
>>
>> On Sat, Jul 21, 2018 at 3:18 AM, Kazuhito Hagio <k-hagio@ab.jp.nec.com> wrote:
>>>
>>> On 7/19/2018 1:43 AM, Bhupesh Sharma wrote:
>>>> The existing methodology to obtain 'info->page_offset' from reading
>>>> _stext symbol (from kallsyms) doesn't work well in KASLR boot cases on
>>>> arm64 machines as the PAGE_OFFSET (or the virtual address which
>>>> indicates the start of the linear region) can be randomized as well
>>>> on basis of the kaslr-seed.
>>>>
>>>> Since the value of PAGE_OFFSET inside the kernel is randomized in such
>>>> cases and there is no existing mechanism of conveying this value from
>>>> kernel-space to user-space, so we can use the method used by archs like
>>>> x86_64 to generate the 'info->page_offset' value from the PT_LOAD
>>>> segments by subtracting the phy_addr from virt_addr of a PT_LOAD
>>>> segment.
>>>>
>>>> This approach works fine both with KASLR and non-KASLR boot cases.
>>>>
>>>> I tested this on my qualcomm-amberwing board. Here are some logs from
>>>> the KASLR boot cases:
>>>>
>>>> - Verify that the EFI firmware supports 'kaslr-seed':
>>>>
>>>> chosen {
>>>> kaslr-seed = <0x0 0x0>;
>>>> <..snip..>
>>>> };
>>>>
>>>> - Verify that '--mem-usage' works well after this fix as well (I used
>>>> kernel 4.18.0-rc4+ for my checks):
>>>>
>>>> The kernel version is not supported.
>>>> The makedumpfile operation may be incomplete.
>>>>
>>>> TYPE PAGES EXCLUDABLE DESCRIPTION
>>>> ----------------------------------------------------------------------
>>>> ZERO 4396 yes Pages filled
>>>> with zero
>>>> NON_PRI_CACHE 27859 yes Cache pages
>>>> without private flag
>>>> PRI_CACHE 18490 yes Cache pages with
>>>> private flag
>>>> USER 2728 yes User process
>>>> pages
>>>> FREE 1465848 yes Free pages
>>>> KERN_DATA 18537 no Dumpable kernel
>>>> data
>>>>
>>>> page size: 65536
>>>> Total pages on system: 1537858
>>>> Total size on system: 100785061888 Byte
>>>>
>>>> Signed-off-by: Bhupesh Sharma <bhsharma@redhat.com>
>>>> ---
>>>> arch/arm64.c | 23 ++++++++++++++++++-----
>>>> common.h | 1 +
>>>> makedumpfile.h | 1 +
>>>> 3 files changed, 20 insertions(+), 5 deletions(-)
>>>>
>>>> diff --git a/arch/arm64.c b/arch/arm64.c
>>>> index 2fd3e1874376..9e8c77c76935 100644
>>>> --- a/arch/arm64.c
>>>> +++ b/arch/arm64.c
>>>> @@ -265,6 +265,9 @@ get_xen_info_arm64(void)
>>>> int
>>>> get_versiondep_info_arm64(void)
>>>> {
>>>> + int i;
>>>> + unsigned long long phys_start;
>>>> + unsigned long long virt_start;
>>>> ulong _stext;
>>>>
>>>> _stext = get_stext_symbol();
>>>> @@ -289,12 +292,22 @@ get_versiondep_info_arm64(void)
>>>> return FALSE;
>>>> }
>>>>
>>>
>>>> - info->page_offset = (0xffffffffffffffffUL) << (va_bits - 1);
>>>> -
>>>> - DEBUG_MSG("page_offset=%lx, va_bits=%d\n", info->page_offset,
>>>> - va_bits);
>>>
>>> According to makedumpfile commit 4944f93484 ("x86_64: Calculate page_offset
>>> in case of re-filtering/sadump/virsh dump"), in case of re-filtering,
>>> we don't have any PT_LOAD. So, with this patch, we cannot re-filter
>>> dump file on arm64 system?
>>>
>>> If we cannot, is it better to leave the above behind the following
>>> pt_load section for re-filtering non-KASLR dump?
>>>
>>>> + if (get_num_pt_loads()) {
>>>> + for (i = 0;
>>>> + get_pt_load(i, &phys_start, NULL, &virt_start, NULL);
>>>> + i++) {
>>>> + if (virt_start != NOT_KV_ADDR
>>>> + && virt_start < __START_KERNEL_map
>>>> + && phys_start != NOT_PADDR && phys_start != NOT_PADDR_ARM64) {
>>>> + info->page_offset = virt_start - phys_start;
>>>> + DEBUG_MSG("info->page_offset: %lx, VA_BITS: %d\n",
>>>> + info->page_offset, va_bits);
>>>> + return TRUE;
>>>> + }
>>>> + }
>>>> + }
>>>
>>> I'll adjust some indents for readability.
>>>
>>>>
>>>> - return TRUE;
>>>> + return FALSE;
>>>> }
>>>>
>>>> /*
>>>> diff --git a/common.h b/common.h
>>>> index 6e2f657a79c7..a8181777dbb7 100644
>>>> --- a/common.h
>>>> +++ b/common.h
>>>> @@ -48,6 +48,7 @@
>>>> #define NOT_MEMMAP_ADDR (0x0)
>>>> #define NOT_KV_ADDR (0x0)
>>>> #define NOT_PADDR (ULONGLONG_MAX)
>>>
>>>> +#define NOT_PADDR_ARM64 (0x0000000010a80000UL)
>>>
>>> I think that this should not be in common.h, because it's not for
>>> arch-specific definitions, so I'll move it to makedumpfile.h.
>>>
>>>> #define BADADDR ((ulong)(-1))
>>>>
>>>> #endif /* COMMON_H */
>>>> diff --git a/makedumpfile.h b/makedumpfile.h
>>>> index 5ff94b8e4ac6..5297279f0f3b 100644
>>>> --- a/makedumpfile.h
>>>> +++ b/makedumpfile.h
>>>> @@ -2020,6 +2020,7 @@ struct domain_list {
>>>> #define MFNS_PER_FRAME (info->page_size / sizeof(unsigned long))
>>>>
>>>> #ifdef __aarch64__
>>>> +#define __START_KERNEL_map (0xffffffff80000000UL)
>>>
>>> This #ifdef here is for the definitions related to Xen extraction.
>>> I'll move it to the same place as the above.
>>>
>>>> unsigned long long kvtop_xen_arm64(unsigned long kvaddr);
>>>> #define kvtop_xen(X) kvtop_xen_arm64(X)
>>>> #endif /* aarch64 */
>>>>
>>>
>>> I attached a patch that was applied my suggestions.
>>> How about it?
>>
>> I agree. The patch looks good with the suggested changes.
>> Please go ahead and feel free to apply the modified patch.
>
> OK, I'll apply it.
>
> With respect to the 2/2 patch, I'm waiting for the kernel patch
> to be merged.
>
> If need be, I can apply the 1/2 patch separately from the 2/2 patch,
> because I think they are not directly connected with each other.
Sure, I think we can handle 2/2 patch when it's kernel part is
reviewed properly by the arm64 kernel maintainer(s). We can apply 1/2
patch in the meanwhile.
> p.s. it seems that I cannot send emails to gmail for now,
> so dropped your gmail address. sorry for the inconvenience.
Sure, I use the gmail address just as a backup to read/answer upstream
replies once I am out of office (as it is easier to access on my
phone).
Thanks,
Bhupesh
>>
>> Thanks a lot for your help.
>> Regards,
>> Bhupesh
>>
_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec
^ permalink raw reply
* Re: [PATCH v6 5/5] mailbox: Add support for i.MX7D messaging unit
From: Oleksij Rempel @ 2018-07-24 5:14 UTC (permalink / raw)
To: Lucas Stach, Shawn Guo, Fabio Estevam, Rob Herring, Mark Rutland,
A.s. Dong, Vladimir Zapolskiy
Cc: kernel, devicetree, dl-linux-imx, linux-arm-kernel
In-Reply-To: <1532366380.3163.109.camel@pengutronix.de>
[-- Attachment #1.1.1: Type: text/plain, Size: 11316 bytes --]
Hi Lucas,
here is more detailed response:
On 23.07.2018 19:19, Lucas Stach wrote:
> Am Sonntag, den 22.07.2018, 08:39 +0200 schrieb Oleksij Rempel:
>> The Mailbox controller is able to send messages (up to 4 32 bit words)
>> between the endpoints.
>>
>> This driver was tested using the mailbox-test driver sending messages
>> between the Cortex-A7 and the Cortex-M4.
>>
>>> Reviewed-by: Dong Aisheng <aisheng.dong@nxp.com>
>>> Signed-off-by: Oleksij Rempel <o.rempel@pengutronix.de>
>> ---
>> drivers/mailbox/Kconfig | 6 +
>> drivers/mailbox/Makefile | 2 +
>> drivers/mailbox/imx-mailbox.c | 273 ++++++++++++++++++++++++++++++++++
>> 3 files changed, 281 insertions(+)
>> create mode 100644 drivers/mailbox/imx-mailbox.c
>>
>> diff --git a/drivers/mailbox/Kconfig b/drivers/mailbox/Kconfig
>> index a2bb27446dce..79060ddc380d 100644
>> --- a/drivers/mailbox/Kconfig
>> +++ b/drivers/mailbox/Kconfig
>> @@ -15,6 +15,12 @@ config ARM_MHU
>>> The controller has 3 mailbox channels, the last of which can be
>>> used in Secure mode only.
>>
>> +config IMX_MBOX
>>> + tristate "i.MX Mailbox"
>>> + depends on ARCH_MXC || COMPILE_TEST
>>> + help
>>> + Mailbox implementation for i.MX Messaging Unit (MU).
>> +
>> config PLATFORM_MHU
>>> tristate "Platform MHU Mailbox"
>>> depends on OF
>> diff --git a/drivers/mailbox/Makefile b/drivers/mailbox/Makefile
>> index cc23c3a43fcd..ba2fe1b6dd62 100644
>> --- a/drivers/mailbox/Makefile
>> +++ b/drivers/mailbox/Makefile
>>> @@ -7,6 +7,8 @@ obj-$(CONFIG_MAILBOX_TEST) += mailbox-test.o
>>
>>> obj-$(CONFIG_ARM_MHU) += arm_mhu.o
>>
>>> +obj-$(CONFIG_IMX_MBOX) += imx-mailbox.o
>> +
>>> obj-$(CONFIG_PLATFORM_MHU) += platform_mhu.o
>>
>>> obj-$(CONFIG_PL320_MBOX) += pl320-ipc.o
>> diff --git a/drivers/mailbox/imx-mailbox.c b/drivers/mailbox/imx-mailbox.c
>> new file mode 100644
>> index 000000000000..29cf2876db01
>> --- /dev/null
>> +++ b/drivers/mailbox/imx-mailbox.c
>> @@ -0,0 +1,273 @@
>> +// SPDX-License-Identifier: GPL-2.0
>> +/*
>> + * Copyright (c) 2018 Pengutronix, Oleksij Rempel <o.rempel@pengutronix.de>
>> + */
>> +
>> +#include <linux/clk.h>
>> +#include <linux/interrupt.h>
>> +#include <linux/io.h>
>> +#include <linux/kernel.h>
>> +#include <linux/mailbox_controller.h>
>> +#include <linux/module.h>
>> +#include <linux/of_device.h>
>> +
>> +/* Transmit Register */
>>> +#define IMX_MU_xTRn(x) (0x00 + 4 * (x))
>> +/* Receive Register */
>>> +#define IMX_MU_xRRn(x) (0x10 + 4 * (x))
>> +/* Status Register */
>>> +#define IMX_MU_xSR 0x20
>>> +#define IMX_MU_xSR_TEn(x) BIT(20 + (3 - (x)))
>>> +#define IMX_MU_xSR_RFn(x) BIT(24 + (3 - (x)))
>>> +#define IMX_MU_xSR_BRDIP BIT(9)
>> +
>> +/* Control Register */
>>> +#define IMX_MU_xCR 0x24
>> +/* Transmit Interrupt Enable */
>>> +#define IMX_MU_xCR_TIEn(x) BIT(20 + (3 - (x)))
>> +/* Receive Interrupt Enable */
>>> +#define IMX_MU_xCR_RIEn(x) BIT(24 + (3 - (x)))
>> +
>>> +#define IMX_MU_CHANS 4u
>> +
>> +struct imx_mu_con_priv {
>>>> + int irq;
>>>> + unsigned int idx;
>>>> + char *irq_desc;
>> +};
>> +
>> +struct imx_mu_priv {
>>>> + struct device *dev;
>>>> + void __iomem *base;
>> +
>>>> + struct mbox_controller mbox;
>>>> + struct mbox_chan mbox_chans[IMX_MU_CHANS];
>> +
>>> + struct imx_mu_con_priv con_priv[IMX_MU_CHANS];
>>>> + struct clk *clk;
>> +
>>>> + bool side_b;
>> +};
>> +
>> +static struct imx_mu_priv *to_imx_mu_priv(struct mbox_controller *mbox)
>> +{
>>> + return container_of(mbox, struct imx_mu_priv, mbox);
>> +}
>> +
>> +static void imx_mu_write(struct imx_mu_priv *priv, u32 val, u32 offs)
>> +{
>> + iowrite32(val, priv->base + offs);
>
> This driver is never going to be used on a device with port based IO,
> so iowrite doesn't make much sense here, just use writel. Same comment
> applies to the below read function.
As before I don't really understand the difference. I took some time for
learning and here are my findings:
- historical background of ioread/iowrite functions. What I can find is
this LWN article: https://lwn.net/Articles/102232/ . The main point
seems to be "The first of these is a new __iomem annotation used to mark
pointers to I/O memory" ... " As with __user, the __iomem marker serves
a documentation role in the kernel code;"
In modern kernel the difference between ioread32 and readl seems to be
completely disappeared.
with this LWN article (2016):
https://lwn.net/Articles/698014/
the readl and reade32 are always in the same group..
If there is some documentation which will say why I should use readl()
instead of ioread32() i would really love to read it.
> Also, given that those functions are not really shortening the code in
> the user they may also be removed completely IMHO.
Wrong assumption.. I use this functions for tracing. It is just to easy
to add two trace points... From technical perspective I don't see any
advantage or disadvantage of having this functions.
If it is my personal preference, then I decide to keep it.
>> +}
>> +
>> +static u32 imx_mu_read(struct imx_mu_priv *priv, u32 offs)
>> +{
>>> + return ioread32(priv->base + offs);
>> +}
>> +
>> +static u32 imx_mu_rmw(struct imx_mu_priv *priv, u32 offs, u32 set, u32 clr)
>> +{
>>> + u32 val;
>> +
>>> + val = imx_mu_read(priv, offs);
>>> + val &= ~clr;
>>> + val |= set;
>>> + imx_mu_write(priv, val, offs);
>> +
>>> + return val;
>> +}
>> +
>> +static irqreturn_t imx_mu_isr(int irq, void *p)
>> +{
>>> + struct mbox_chan *chan = p;
>>> + struct imx_mu_priv *priv = to_imx_mu_priv(chan->mbox);
>>> + struct imx_mu_con_priv *cp = chan->con_priv;
>>> + u32 val, ctrl, dat;
>> +
>>> + ctrl = imx_mu_read(priv, IMX_MU_xCR);
>>> + val = imx_mu_read(priv, IMX_MU_xSR);
>>> + val &= IMX_MU_xSR_TEn(cp->idx) | IMX_MU_xSR_RFn(cp->idx);
>>> + val &= ctrl & (IMX_MU_xCR_TIEn(cp->idx) | IMX_MU_xCR_RIEn(cp->idx));
>>> + if (!val)
>>> + return IRQ_NONE;
>> +
>>> + if (val & IMX_MU_xSR_TEn(cp->idx)) {
>>> + imx_mu_rmw(priv, IMX_MU_xCR, 0, IMX_MU_xCR_TIEn(cp->idx));
>>> + mbox_chan_txdone(chan, 0);
>>> + }
>> +
>>> + if (val & IMX_MU_xSR_RFn(cp->idx)) {
>>> + dat = imx_mu_read(priv, IMX_MU_xRRn(cp->idx));
>>> + mbox_chan_received_data(chan, (void *)&dat);
>>> + }
>> +
>>> + return IRQ_HANDLED;
>> +}
>> +
>> +static bool imx_mu_last_tx_done(struct mbox_chan *chan)
>> +{
>>> + struct imx_mu_priv *priv = to_imx_mu_priv(chan->mbox);
>>> + struct imx_mu_con_priv *cp = chan->con_priv;
>>> + u32 val;
>> +
>>> + val = imx_mu_read(priv, IMX_MU_xSR);
>>> + /* test if transmit register is empty */
>> + return val & IMX_MU_xSR_TEn(cp->idx);
>
> I guess
> "return imx_mu_read(priv, IMX_MU_xSR) & IMX_MU_xSR_TEn(cp->idx);" is
> shorter and equally well understood.
So, previous comment was saying, "those functions are not really
shortening the code"
I would apply same comment: "those .. are not really shortening the code".
Do we really need to make review of "personal coding style
preferences".. which are not against kernel coding style in 6. review
round...?!
For example:
kernel coding style is pink... in this case we are talking about
difference between lavender pink and carnation pink.
>> +}
>> +
>> +static int imx_mu_send_data(struct mbox_chan *chan, void *data)
>> +{
>>> + struct imx_mu_priv *priv = to_imx_mu_priv(chan->mbox);
>>> + struct imx_mu_con_priv *cp = chan->con_priv;
>>> + u32 *arg = data;
>> +
>>> + if (!imx_mu_last_tx_done(chan))
>>> + return -EBUSY;
>> +
>>> + imx_mu_write(priv, *arg, IMX_MU_xTRn(cp->idx));
>> + imx_mu_rmw(priv, IMX_MU_xCR, IMX_MU_xSR_TEn(cp->idx), 0);
>
> In multi-channel mode this RMW cycle needs some kind of locking. As
> this register is also changed from the irq handler, this probably needs
> to be a irqsave spinlock.
Thank you, i need to fix it.
>> +
>>> + return 0;
>> +}
>> +
>> +static int imx_mu_startup(struct mbox_chan *chan)
>> +{
>>> + struct imx_mu_priv *priv = to_imx_mu_priv(chan->mbox);
>>> + struct imx_mu_con_priv *cp = chan->con_priv;
>>> + int ret;
>> +
>>> + cp->irq_desc = devm_kasprintf(priv->dev, GFP_KERNEL, "imx_mu_chan[%i]",
>>> + cp->idx);
>>> + if (!cp->irq_desc)
>>> + return -ENOMEM;
>> +
>>> + ret = devm_request_irq(priv->dev, cp->irq, imx_mu_isr,
>> + IRQF_SHARED, cp->irq_desc, chan);
>
> Using the devm_ variants of those functions doesn't make sense when the
> resources aren't tied to the device lifetime. As you are tearing them
> down manually in imx_mu_shutdown anyways, just use the raw variants of
> those functions.
I have nothing against it.
>> + if (ret) {
>>> + dev_err(priv->dev,
>>> + "Unable to acquire IRQ %d\n", cp->irq);
>>> + return ret;
>>> + }
>> +
>>> + imx_mu_rmw(priv, IMX_MU_xCR, IMX_MU_xCR_RIEn(cp->idx), 0);
>> +
>>> + return 0;
>> +}
>> +
>> +static void imx_mu_shutdown(struct mbox_chan *chan)
>> +{
>>> + struct imx_mu_priv *priv = to_imx_mu_priv(chan->mbox);
>>> + struct imx_mu_con_priv *cp = chan->con_priv;
>> +
>>> + imx_mu_rmw(priv, IMX_MU_xCR, 0,
>>> + IMX_MU_xCR_TIEn(cp->idx) | IMX_MU_xCR_RIEn(cp->idx));
>> +
>>> + devm_free_irq(priv->dev, cp->irq, chan);
>>> + devm_kfree(priv->dev, cp->irq_desc);
>> +}
>> +
>> +static const struct mbox_chan_ops imx_mu_ops = {
>>> + .send_data = imx_mu_send_data,
>>> + .startup = imx_mu_startup,
>>> + .shutdown = imx_mu_shutdown,
>> +};
>> +
>> +static void imx_mu_init_generic(struct imx_mu_priv *priv)
>> +{
>>> + if (priv->side_b)
>>> + return;
>> +
>>> + /* Set default MU configuration */
>>> + imx_mu_write(priv, 0, IMX_MU_xCR);
>> +}
>> +
>> +static int imx_mu_probe(struct platform_device *pdev)
>> +{
>>> + struct device *dev = &pdev->dev;
>>> + struct device_node *np = dev->of_node;
>>> + struct resource *iomem;
>>> + struct imx_mu_priv *priv;
>>> + unsigned int i;
>>> + int irq, ret;
>> +
>>> + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
>>> + if (!priv)
>>> + return -ENOMEM;
>> +
>>> + priv->dev = dev;
>> +
>>> + iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
>>> + priv->base = devm_ioremap_resource(&pdev->dev, iomem);
>>> + if (IS_ERR(priv->base))
>>> + return PTR_ERR(priv->base);
>> +
>>> + irq = platform_get_irq(pdev, 0);
>>> + if (irq < 0)
>>> + return irq;
>> +
>>> + priv->clk = devm_clk_get(dev, NULL);
>>> + if (IS_ERR(priv->clk)) {
>>> + if (PTR_ERR(priv->clk) != -ENOENT)
>>> + return PTR_ERR(priv->clk);
>> +
>>> + priv->clk = NULL;
>>> + }
>> +
>>> + ret = clk_prepare_enable(priv->clk);
>>> + if (ret) {
>>> + dev_err(dev, "Failed to enable clock\n");
>>> + return ret;
>>> + }
>> +
>>> + for (i = 0; i < IMX_MU_CHANS; i++) {
>>> + struct imx_mu_con_priv *cp = &priv->con_priv[i];
>> +
>>> + cp->idx = i;
>>> + cp->irq = irq;
>>> + priv->mbox_chans[i].con_priv = cp;
>>> + }
>> +
>>> + if (of_property_read_bool(np, "fsl,mu-side-b"))
>> + priv->side_b = true;
>
> No need for the if clause here. Just assign the return value from
> of_property_read_bool to priv->side_b.
ok.
Thank you for a review!
[-- Attachment #1.2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 488 bytes --]
[-- Attachment #2: Type: text/plain, Size: 176 bytes --]
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* [PATCH v6 5/5] mailbox: Add support for i.MX7D messaging unit
From: Oleksij Rempel @ 2018-07-24 5:14 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1532366380.3163.109.camel@pengutronix.de>
Hi Lucas,
here is more detailed response:
On 23.07.2018 19:19, Lucas Stach wrote:
> Am Sonntag, den 22.07.2018, 08:39 +0200 schrieb Oleksij Rempel:
>> The Mailbox controller is able to send messages (up to 4 32 bit words)
>> between the endpoints.
>>
>> This driver was tested using the mailbox-test driver sending messages
>> between the Cortex-A7 and the Cortex-M4.
>>
>>> Reviewed-by: Dong Aisheng <aisheng.dong@nxp.com>
>>> Signed-off-by: Oleksij Rempel <o.rempel@pengutronix.de>
>> ---
>> ?drivers/mailbox/Kconfig???????|???6 +
>> ?drivers/mailbox/Makefile??????|???2 +
>> ?drivers/mailbox/imx-mailbox.c | 273 ++++++++++++++++++++++++++++++++++
>> ?3 files changed, 281 insertions(+)
>> ?create mode 100644 drivers/mailbox/imx-mailbox.c
>>
>> diff --git a/drivers/mailbox/Kconfig b/drivers/mailbox/Kconfig
>> index a2bb27446dce..79060ddc380d 100644
>> --- a/drivers/mailbox/Kconfig
>> +++ b/drivers/mailbox/Kconfig
>> @@ -15,6 +15,12 @@ config ARM_MHU
>>> ? ??The controller has 3 mailbox channels, the last of which can be
>>> ? ??used in Secure mode only.
>> ?
>> +config IMX_MBOX
>>> + tristate "i.MX Mailbox"
>>> + depends on ARCH_MXC || COMPILE_TEST
>>> + help
>>> + ??Mailbox implementation for i.MX Messaging Unit (MU).
>> +
>> ?config PLATFORM_MHU
>>> ? tristate "Platform MHU Mailbox"
>>> ? depends on OF
>> diff --git a/drivers/mailbox/Makefile b/drivers/mailbox/Makefile
>> index cc23c3a43fcd..ba2fe1b6dd62 100644
>> --- a/drivers/mailbox/Makefile
>> +++ b/drivers/mailbox/Makefile
>>> @@ -7,6 +7,8 @@ obj-$(CONFIG_MAILBOX_TEST) += mailbox-test.o
>> ?
>>> ?obj-$(CONFIG_ARM_MHU) += arm_mhu.o
>> ?
>>> +obj-$(CONFIG_IMX_MBOX) += imx-mailbox.o
>> +
>>> ?obj-$(CONFIG_PLATFORM_MHU) += platform_mhu.o
>> ?
>>> ?obj-$(CONFIG_PL320_MBOX) += pl320-ipc.o
>> diff --git a/drivers/mailbox/imx-mailbox.c b/drivers/mailbox/imx-mailbox.c
>> new file mode 100644
>> index 000000000000..29cf2876db01
>> --- /dev/null
>> +++ b/drivers/mailbox/imx-mailbox.c
>> @@ -0,0 +1,273 @@
>> +// SPDX-License-Identifier: GPL-2.0
>> +/*
>> + * Copyright (c) 2018 Pengutronix, Oleksij Rempel <o.rempel@pengutronix.de>
>> + */
>> +
>> +#include <linux/clk.h>
>> +#include <linux/interrupt.h>
>> +#include <linux/io.h>
>> +#include <linux/kernel.h>
>> +#include <linux/mailbox_controller.h>
>> +#include <linux/module.h>
>> +#include <linux/of_device.h>
>> +
>> +/* Transmit Register */
>>> +#define IMX_MU_xTRn(x) (0x00 + 4 * (x))
>> +/* Receive Register */
>>> +#define IMX_MU_xRRn(x) (0x10 + 4 * (x))
>> +/* Status Register */
>>> +#define IMX_MU_xSR 0x20
>>> +#define IMX_MU_xSR_TEn(x) BIT(20 + (3 - (x)))
>>> +#define IMX_MU_xSR_RFn(x) BIT(24 + (3 - (x)))
>>> +#define IMX_MU_xSR_BRDIP BIT(9)
>> +
>> +/* Control Register */
>>> +#define IMX_MU_xCR 0x24
>> +/* Transmit Interrupt Enable */
>>> +#define IMX_MU_xCR_TIEn(x) BIT(20 + (3 - (x)))
>> +/* Receive Interrupt Enable */
>>> +#define IMX_MU_xCR_RIEn(x) BIT(24 + (3 - (x)))
>> +
>>> +#define IMX_MU_CHANS 4u
>> +
>> +struct imx_mu_con_priv {
>>>> + int irq;
>>>> + unsigned int idx;
>>>> + char *irq_desc;
>> +};
>> +
>> +struct imx_mu_priv {
>>>> + struct device *dev;
>>>> + void __iomem *base;
>> +
>>>> + struct mbox_controller mbox;
>>>> + struct mbox_chan mbox_chans[IMX_MU_CHANS];
>> +
>>> + struct imx_mu_con_priv??con_priv[IMX_MU_CHANS];
>>>> + struct clk *clk;
>> +
>>>> + bool side_b;
>> +};
>> +
>> +static struct imx_mu_priv *to_imx_mu_priv(struct mbox_controller *mbox)
>> +{
>>> + return container_of(mbox, struct imx_mu_priv, mbox);
>> +}
>> +
>> +static void imx_mu_write(struct imx_mu_priv *priv, u32 val, u32 offs)
>> +{
>> + iowrite32(val, priv->base + offs);
>
> This driver is never going to be used on a device with port based IO,
> so iowrite doesn't make much sense here, just use writel. Same comment
> applies to the below read function.
As before I don't really understand the difference. I took some time for
learning and here are my findings:
- historical background of ioread/iowrite functions. What I can find is
this LWN article: https://lwn.net/Articles/102232/ . The main point
seems to be "The first of these is a new __iomem annotation used to mark
pointers to I/O memory" ... " As with __user, the __iomem marker serves
a documentation role in the kernel code;"
In modern kernel the difference between ioread32 and readl seems to be
completely disappeared.
with this LWN article (2016):
https://lwn.net/Articles/698014/
the readl and reade32 are always in the same group..
If there is some documentation which will say why I should use readl()
instead of ioread32() i would really love to read it.
> Also, given that those functions are not really shortening the code in
> the user they may also be removed completely IMHO.
Wrong assumption.. I use this functions for tracing. It is just to easy
to add two trace points... From technical perspective I don't see any
advantage or disadvantage of having this functions.
If it is my personal preference, then I decide to keep it.
>> +}
>> +
>> +static u32 imx_mu_read(struct imx_mu_priv *priv, u32 offs)
>> +{
>>> + return ioread32(priv->base + offs);
>> +}
>> +
>> +static u32 imx_mu_rmw(struct imx_mu_priv *priv, u32 offs, u32 set, u32 clr)
>> +{
>>> + u32 val;
>> +
>>> + val = imx_mu_read(priv, offs);
>>> + val &= ~clr;
>>> + val |= set;
>>> + imx_mu_write(priv, val, offs);
>> +
>>> + return val;
>> +}
>> +
>> +static irqreturn_t imx_mu_isr(int irq, void *p)
>> +{
>>> + struct mbox_chan *chan = p;
>>> + struct imx_mu_priv *priv = to_imx_mu_priv(chan->mbox);
>>> + struct imx_mu_con_priv *cp = chan->con_priv;
>>> + u32 val, ctrl, dat;
>> +
>>> + ctrl = imx_mu_read(priv, IMX_MU_xCR);
>>> + val = imx_mu_read(priv, IMX_MU_xSR);
>>> + val &= IMX_MU_xSR_TEn(cp->idx) | IMX_MU_xSR_RFn(cp->idx);
>>> + val &= ctrl & (IMX_MU_xCR_TIEn(cp->idx) | IMX_MU_xCR_RIEn(cp->idx));
>>> + if (!val)
>>> + return IRQ_NONE;
>> +
>>> + if (val & IMX_MU_xSR_TEn(cp->idx)) {
>>> + imx_mu_rmw(priv, IMX_MU_xCR, 0, IMX_MU_xCR_TIEn(cp->idx));
>>> + mbox_chan_txdone(chan, 0);
>>> + }
>> +
>>> + if (val & IMX_MU_xSR_RFn(cp->idx)) {
>>> + dat = imx_mu_read(priv, IMX_MU_xRRn(cp->idx));
>>> + mbox_chan_received_data(chan, (void *)&dat);
>>> + }
>> +
>>> + return IRQ_HANDLED;
>> +}
>> +
>> +static bool imx_mu_last_tx_done(struct mbox_chan *chan)
>> +{
>>> + struct imx_mu_priv *priv = to_imx_mu_priv(chan->mbox);
>>> + struct imx_mu_con_priv *cp = chan->con_priv;
>>> + u32 val;
>> +
>>> + val = imx_mu_read(priv, IMX_MU_xSR);
>>> + /* test if transmit register is empty */
>> + return val & IMX_MU_xSR_TEn(cp->idx);
>
> I guess
> "return imx_mu_read(priv, IMX_MU_xSR) & IMX_MU_xSR_TEn(cp->idx);" is
> shorter and equally well understood.
So, previous comment was saying, "those functions are not really
shortening the code"
I would apply same comment: "those .. are not really shortening the code".
Do we really need to make review of "personal coding style
preferences".. which are not against kernel coding style in 6. review
round...?!
For example:
kernel coding style is pink... in this case we are talking about
difference between lavender pink and carnation pink.
>> +}
>> +
>> +static int imx_mu_send_data(struct mbox_chan *chan, void *data)
>> +{
>>> + struct imx_mu_priv *priv = to_imx_mu_priv(chan->mbox);
>>> + struct imx_mu_con_priv *cp = chan->con_priv;
>>> + u32 *arg = data;
>> +
>>> + if (!imx_mu_last_tx_done(chan))
>>> + return -EBUSY;
>> +
>>> + imx_mu_write(priv, *arg, IMX_MU_xTRn(cp->idx));
>> + imx_mu_rmw(priv, IMX_MU_xCR, IMX_MU_xSR_TEn(cp->idx), 0);
>
> In multi-channel mode this RMW cycle needs some kind of locking. As
> this register is also changed from the irq handler, this probably needs
> to be a irqsave spinlock.
Thank you, i need to fix it.
>> +
>>> + return 0;
>> +}
>> +
>> +static int imx_mu_startup(struct mbox_chan *chan)
>> +{
>>> + struct imx_mu_priv *priv = to_imx_mu_priv(chan->mbox);
>>> + struct imx_mu_con_priv *cp = chan->con_priv;
>>> + int ret;
>> +
>>> + cp->irq_desc = devm_kasprintf(priv->dev, GFP_KERNEL, "imx_mu_chan[%i]",
>>> + ??????cp->idx);
>>> + if (!cp->irq_desc)
>>> + return -ENOMEM;
>> +
>>> + ret = devm_request_irq(priv->dev, cp->irq, imx_mu_isr,
>> + ???????IRQF_SHARED, cp->irq_desc, chan);
>
> Using the devm_ variants of those functions doesn't make sense when the
> resources aren't tied to the device lifetime. As you are tearing them
> down manually in imx_mu_shutdown anyways, just use the raw variants of
> those functions.
I have nothing against it.
>> + if (ret) {
>>> + dev_err(priv->dev,
>>> + "Unable to acquire IRQ %d\n", cp->irq);
>>> + return ret;
>>> + }
>> +
>>> + imx_mu_rmw(priv, IMX_MU_xCR, IMX_MU_xCR_RIEn(cp->idx), 0);
>> +
>>> + return 0;
>> +}
>> +
>> +static void imx_mu_shutdown(struct mbox_chan *chan)
>> +{
>>> + struct imx_mu_priv *priv = to_imx_mu_priv(chan->mbox);
>>> + struct imx_mu_con_priv *cp = chan->con_priv;
>> +
>>> + imx_mu_rmw(priv, IMX_MU_xCR, 0,
>>> + ???IMX_MU_xCR_TIEn(cp->idx) | IMX_MU_xCR_RIEn(cp->idx));
>> +
>>> + devm_free_irq(priv->dev, cp->irq, chan);
>>> + devm_kfree(priv->dev, cp->irq_desc);
>> +}
>> +
>> +static const struct mbox_chan_ops imx_mu_ops = {
>>> + .send_data = imx_mu_send_data,
>>> + .startup = imx_mu_startup,
>>> + .shutdown = imx_mu_shutdown,
>> +};
>> +
>> +static void imx_mu_init_generic(struct imx_mu_priv *priv)
>> +{
>>> + if (priv->side_b)
>>> + return;
>> +
>>> + /* Set default MU configuration */
>>> + imx_mu_write(priv, 0, IMX_MU_xCR);
>> +}
>> +
>> +static int imx_mu_probe(struct platform_device *pdev)
>> +{
>>> + struct device *dev = &pdev->dev;
>>> + struct device_node *np = dev->of_node;
>>> + struct resource *iomem;
>>> + struct imx_mu_priv *priv;
>>> + unsigned int i;
>>> + int irq, ret;
>> +
>>> + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
>>> + if (!priv)
>>> + return -ENOMEM;
>> +
>>> + priv->dev = dev;
>> +
>>> + iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
>>> + priv->base = devm_ioremap_resource(&pdev->dev, iomem);
>>> + if (IS_ERR(priv->base))
>>> + return PTR_ERR(priv->base);
>> +
>>> + irq = platform_get_irq(pdev, 0);
>>> + if (irq < 0)
>>> + return irq;
>> +
>>> + priv->clk = devm_clk_get(dev, NULL);
>>> + if (IS_ERR(priv->clk)) {
>>> + if (PTR_ERR(priv->clk) != -ENOENT)
>>> + return PTR_ERR(priv->clk);
>> +
>>> + priv->clk = NULL;
>>> + }
>> +
>>> + ret = clk_prepare_enable(priv->clk);
>>> + if (ret) {
>>> + dev_err(dev, "Failed to enable clock\n");
>>> + return ret;
>>> + }
>> +
>>> + for (i = 0; i < IMX_MU_CHANS; i++) {
>>> + struct imx_mu_con_priv *cp = &priv->con_priv[i];
>> +
>>> + cp->idx = i;
>>> + cp->irq = irq;
>>> + priv->mbox_chans[i].con_priv = cp;
>>> + }
>> +
>>> + if (of_property_read_bool(np, "fsl,mu-side-b"))
>> + priv->side_b = true;
>
> No need for the if clause here. Just assign the return value from
> of_property_read_bool to priv->side_b.
ok.
Thank you for a review!
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 488 bytes
Desc: OpenPGP digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20180724/8a7ff5f5/attachment-0001.sig>
^ permalink raw reply
* Re: KASAN: use-after-free Read in link_path_walk
From: DaeRyong Jeong @ 2018-07-24 4:08 UTC (permalink / raw)
To: viro; +Cc: linux-fsdevel, LKML, Byoungyoung Lee, Kyungtae Kim, bammanag
In-Reply-To: <20180724034542.GA19283@dragonet>
I think that below two crashes are also related to the same race issue.
KASAN: use-after-free Read in nd_jump_root, found in v4.17-rc1
KASAN: use-after-free in set_root, found in v4.18-rc3
==================================================================
BUG: KASAN: use-after-free in nd_jump_root+0x69/0x160 fs/namei.c:852
Read of size 8 at addr ffff8801eb677e58 by task syz-executor0/20521
CPU: 0 PID: 20521 Comm: syz-executor0 Not tainted 4.17.0-rc1 #1
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS
rel-1.8.2-0-g33fbe13 by qemu-project.org 04/01/2014
Call Trace:
__dump_stack lib/dump_stack.c:77 [inline]
dump_stack+0x166/0x21c lib/dump_stack.c:113
print_address_description+0x73/0x250 mm/kasan/report.c:256
kasan_report_error mm/kasan/report.c:354 [inline]
kasan_report+0x23f/0x360 mm/kasan/report.c:412
check_memory_region_inline mm/kasan/kasan.c:260 [inline]
__asan_load8+0x54/0x90 mm/kasan/kasan.c:699
nd_jump_root+0x69/0x160 fs/namei.c:852
path_init+0x9ca/0x1190 fs/namei.c:2165
path_openat+0x140/0x2040 fs/namei.c:3495
do_filp_open+0x175/0x230 fs/namei.c:3535
do_sys_open+0x3c7/0x4a0 fs/open.c:1093
__do_sys_openat fs/open.c:1120 [inline]
__se_sys_openat fs/open.c:1114 [inline]
__x64_sys_openat+0x59/0x70 fs/open.c:1114
do_syscall_64+0x15f/0x4a0 arch/x86/entry/common.c:287
entry_SYSCALL_64_after_hwframe+0x49/0xbe
RIP: 0033:0x456419
RSP: 002b:00007fb317cd2b28 EFLAGS: 00000246 ORIG_RAX: 0000000000000101
RAX: ffffffffffffffda RBX: 000000000072bee0 RCX: 0000000000456419
RDX: 0000000000000101 RSI: 00000000200001c0 RDI: ffffffffffffff9c
RBP: 0000000000000497 R08: 0000000000000000 R09: 0000000000000000
R10: 0000000000000000 R11: 0000000000000246 R12: 00007fb317cd36d4
R13: 00000000ffffffff R14: 00000000006fbec8 R15: 0000000000000000
Allocated by task 20521:
save_stack+0x43/0xd0 mm/kasan/kasan.c:448
set_track mm/kasan/kasan.c:460 [inline]
kasan_kmalloc+0xae/0xe0 mm/kasan/kasan.c:553
kasan_slab_alloc+0x12/0x20 mm/kasan/kasan.c:490
kmem_cache_alloc+0x12e/0x760 mm/slab.c:3554
__d_alloc+0xc0/0x6e0 fs/dcache.c:1638
d_alloc_anon fs/dcache.c:1742 [inline]
d_make_root+0x2d/0x70 fs/dcache.c:1934
devpts_fill_super+0x23b/0x500 fs/devpts/inode.c:482
mount_nodev+0x59/0xd0 fs/super.c:1211
devpts_mount+0x2c/0x40 fs/devpts/inode.c:509
mount_fs+0x50/0x200 fs/super.c:1268
vfs_kern_mount.part.26+0xbc/0x2c0 fs/namespace.c:1037
vfs_kern_mount fs/namespace.c:2514 [inline]
do_new_mount fs/namespace.c:2517 [inline]
do_mount+0xb82/0x1bb0 fs/namespace.c:2847
ksys_mount+0xab/0x120 fs/namespace.c:3063
__do_sys_mount fs/namespace.c:3077 [inline]
__se_sys_mount fs/namespace.c:3074 [inline]
__x64_sys_mount+0x67/0x80 fs/namespace.c:3074
do_syscall_64+0x15f/0x4a0 arch/x86/entry/common.c:287
entry_SYSCALL_64_after_hwframe+0x49/0xbe
Freed by task 20522:
save_stack+0x43/0xd0 mm/kasan/kasan.c:448
set_track mm/kasan/kasan.c:460 [inline]
__kasan_slab_free+0x11a/0x170 mm/kasan/kasan.c:521
kasan_slab_free+0xe/0x10 mm/kasan/kasan.c:528
__cache_free mm/slab.c:3498 [inline]
kmem_cache_free+0x83/0x2a0 mm/slab.c:3756
__d_free fs/dcache.c:257 [inline]
dentry_free+0x8c/0xe0 fs/dcache.c:347
__dentry_kill+0x3d6/0x440 fs/dcache.c:582
dentry_kill+0x8f/0x320 fs/dcache.c:686
dput.part.22+0x430/0x4e0 fs/dcache.c:850
dput fs/dcache.c:830 [inline]
do_one_tree+0x43/0x50 fs/dcache.c:1523
shrink_dcache_for_umount+0xa5/0x1c0 fs/dcache.c:1537
generic_shutdown_super+0xb0/0x330 fs/super.c:425
kill_anon_super fs/super.c:1037 [inline]
kill_litter_super+0x48/0x60 fs/super.c:1047
devpts_kill_sb+0x49/0x50 fs/devpts/inode.c:519
deactivate_locked_super+0x71/0xb0 fs/super.c:313
deactivate_super+0x10f/0x150 fs/super.c:344
cleanup_mnt+0x6b/0xc0 fs/namespace.c:1173
__cleanup_mnt+0x16/0x20 fs/namespace.c:1180
task_work_run+0x152/0x1b0 kernel/task_work.c:113
tracehook_notify_resume include/linux/tracehook.h:191 [inline]
exit_to_usermode_loop+0x262/0x270 arch/x86/entry/common.c:166
prepare_exit_to_usermode arch/x86/entry/common.c:196 [inline]
syscall_return_slowpath arch/x86/entry/common.c:265 [inline]
do_syscall_64+0x473/0x4a0 arch/x86/entry/common.c:290
entry_SYSCALL_64_after_hwframe+0x49/0xbe
The buggy address belongs to the object at ffff8801eb677e00
which belongs to the cache dentry(17:syz0) of size 288
The buggy address is located 88 bytes inside of
288-byte region [ffff8801eb677e00, ffff8801eb677f20)
The buggy address belongs to the page:
page:ffffea0007ad9dc0 count:1 mapcount:0 mapping:ffff8801eb677040 index:0x0
flags: 0x2fffc0000000100(slab)
raw: 02fffc0000000100 ffff8801eb677040 0000000000000000 000000010000000b
raw: ffffea0007b9d2a0 ffffea0007b9ed20 ffff8801ef225300 ffff8801ed0249c0
page dumped because: kasan: bad access detected
page->mem_cgroup:ffff8801ed0249c0
Memory state around the buggy address:
ffff8801eb677d00: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
ffff8801eb677d80: fb fb fb fb fb fb fb fb fc fc fc fc fc fc fc fc
>ffff8801eb677e00: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
^
ffff8801eb677e80: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
ffff8801eb677f00: fb fb fb fb fc fc fc fc fc fc fc fc fc fc fc fc
==================================================================
==================================================================
BUG: KASAN: use-after-free in __read_once_size
include/linux/compiler.h:188 [inline]
BUG: KASAN: use-after-free in __read_seqcount_begin
include/linux/seqlock.h:113 [inline]
BUG: KASAN: use-after-free in set_root+0x252/0x3f0 fs/namei.c:820
Read of size 4 at addr ffff88019e5d4b88 by task syz-executor0/30297
CPU: 1 PID: 30297 Comm: syz-executor0 Not tainted 4.18.0-rc3 #1
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS
rel-1.8.2-0-g33fbe13 by qemu-project.org 04/01/2014
Call Trace:
__dump_stack lib/dump_stack.c:77 [inline]
dump_stack+0x16e/0x22c lib/dump_stack.c:113
print_address_description+0x73/0x250 mm/kasan/report.c:256
kasan_report_error mm/kasan/report.c:354 [inline]
kasan_report+0x259/0x380 mm/kasan/report.c:412
check_memory_region_inline mm/kasan/kasan.c:260 [inline]
__asan_load4+0x78/0x80 mm/kasan/kasan.c:698
__read_once_size include/linux/compiler.h:188 [inline]
__read_seqcount_begin include/linux/seqlock.h:113 [inline]
set_root+0x252/0x3f0 fs/namei.c:820
path_init+0x9dd/0x11b0 fs/namei.c:2164
path_openat+0x147/0x1fb0 fs/namei.c:3534
do_filp_open+0x181/0x250 fs/namei.c:3574
do_sys_open+0x3da/0x4b0 fs/open.c:1101
__do_sys_openat fs/open.c:1128 [inline]
__se_sys_openat fs/open.c:1122 [inline]
__x64_sys_openat+0x59/0x70 fs/open.c:1122
do_syscall_64+0x167/0x4b0 arch/x86/entry/common.c:290
entry_SYSCALL_64_after_hwframe+0x49/0xbe
RIP: 0033:0x456469
Code: 1d ba fb ff c3 66 2e 0f 1f 84 00 00 00 00 00 66 90 48 89 f8 48
89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d
01 f0 ff ff 0f 83 eb b9 fb ff c3 66 2e 0f 1f 84 00 00 00 00
RSP: 002b:00007f5e06564b28 EFLAGS: 00000246 ORIG_RAX: 0000000000000101
RAX: ffffffffffffffda RBX: 000000000072bfa0 RCX: 0000000000456469
RDX: 0000000000000080 RSI: 0000000020000140 RDI: ffffffffffffff9c
RBP: 00000000000004e4 R08: 0000000000000000 R09: 0000000000000000
R10: 0000000000000000 R11: 0000000000000246 R12: 00007f5e065656d4
R13: 00000000ffffffff R14: 00000000006fc600 R15: 0000000000000000
Allocated by task 30296:
save_stack+0x43/0xd0 mm/kasan/kasan.c:448
set_track mm/kasan/kasan.c:460 [inline]
kasan_kmalloc+0xae/0xe0 mm/kasan/kasan.c:553
kasan_slab_alloc+0x12/0x20 mm/kasan/kasan.c:490
kmem_cache_alloc+0x12e/0x750 mm/slab.c:3554
__d_alloc+0xc2/0x720 fs/dcache.c:1616
d_alloc_anon fs/dcache.c:1720 [inline]
d_make_root+0x2d/0x70 fs/dcache.c:1934
devpts_fill_super+0x23b/0x500 fs/devpts/inode.c:482
mount_nodev+0x59/0xd0 fs/super.c:1220
devpts_mount+0x2c/0x40 fs/devpts/inode.c:509
mount_fs+0x50/0x200 fs/super.c:1277
vfs_kern_mount.part.26+0xc4/0x2d0 fs/namespace.c:1037
vfs_kern_mount fs/namespace.c:2515 [inline]
do_new_mount fs/namespace.c:2518 [inline]
do_mount+0xbd7/0x1c90 fs/namespace.c:2848
ksys_mount+0xab/0x120 fs/namespace.c:3064
__do_sys_mount fs/namespace.c:3078 [inline]
__se_sys_mount fs/namespace.c:3075 [inline]
__x64_sys_mount+0x67/0x80 fs/namespace.c:3075
do_syscall_64+0x167/0x4b0 arch/x86/entry/common.c:290
entry_SYSCALL_64_after_hwframe+0x49/0xbe
Freed by task 30296:
save_stack+0x43/0xd0 mm/kasan/kasan.c:448
set_track mm/kasan/kasan.c:460 [inline]
__kasan_slab_free+0x11a/0x170 mm/kasan/kasan.c:521
kasan_slab_free+0xe/0x10 mm/kasan/kasan.c:528
__cache_free mm/slab.c:3498 [inline]
kmem_cache_free+0x83/0x2a0 mm/slab.c:3756
__d_free fs/dcache.c:257 [inline]
dentry_free+0x8c/0xe0 fs/dcache.c:347
__dentry_kill+0x3fe/0x470 fs/dcache.c:582
dentry_kill+0x8f/0x320 fs/dcache.c:687
dput+0x450/0x4e0 fs/dcache.c:848
do_one_tree+0x37/0x40 fs/dcache.c:1531
shrink_dcache_for_umount+0xad/0x1d0 fs/dcache.c:1545
generic_shutdown_super+0xb8/0x340 fs/super.c:438
kill_anon_super fs/super.c:1046 [inline]
kill_litter_super+0x48/0x60 fs/super.c:1056
devpts_kill_sb+0x49/0x50 fs/devpts/inode.c:519
deactivate_locked_super+0x71/0xb0 fs/super.c:326
deactivate_super+0x11d/0x160 fs/super.c:357
cleanup_mnt+0x6b/0xc0 fs/namespace.c:1174
__cleanup_mnt+0x16/0x20 fs/namespace.c:1181
task_work_run+0x15a/0x1c0 kernel/task_work.c:113
tracehook_notify_resume include/linux/tracehook.h:192 [inline]
exit_to_usermode_loop+0x2a3/0x2b0 arch/x86/entry/common.c:166
prepare_exit_to_usermode arch/x86/entry/common.c:197 [inline]
syscall_return_slowpath arch/x86/entry/common.c:268 [inline]
do_syscall_64+0x485/0x4b0 arch/x86/entry/common.c:293
entry_SYSCALL_64_after_hwframe+0x49/0xbe
The buggy address belongs to the object at ffff88019e5d4b80
which belongs to the cache dentry(17:syz0) of size 288
The buggy address is located 8 bytes inside of
288-byte region [ffff88019e5d4b80, ffff88019e5d4ca0)
The buggy address belongs to the page:
page:ffffea0006797500 count:1 mapcount:0 mapping:ffff8801ec05d7c0 index:0x0
flags: 0x2fffc0000000100(slab)
raw: 02fffc0000000100 ffffea0006796148 ffffea00067cd648 ffff8801ec05d7c0
raw: 0000000000000000 ffff88019e5d4080 000000010000000b ffff8801dc63e8c0
page dumped because: kasan: bad access detected
page->mem_cgroup:ffff8801dc63e8c0
Memory state around the buggy address:
ffff88019e5d4a80: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
ffff88019e5d4b00: fb fb fb fb fb fb fb fb fc fc fc fc fc fc fc fc
>ffff88019e5d4b80: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
^
ffff88019e5d4c00: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
ffff88019e5d4c80: fb fb fb fb fc fc fc fc fc fc fc fc fb fb fb fb
==================================================================
On Tue, Jul 24, 2018 at 12:45 PM, Dae R. Jeong <threeearcat@gmail.com> wrote:
> Reporting the crash: KASAN: use-after-free Read in link_path_walk
>
> This crash has been found in v4.17-rc1 using RaceFuzzer (a modified
> version of Syzkaller), which we describe more at the end of this
> report. Our analysis shows that the race occurs when invoking two
> syscalls concurrently, open() and chroot().
>
> Diagnosis:
> We think that it is possible that link_path_walk() dereferences a
> freed pointer when cleanup_mnt() is executed between path_init() and
> link_path_walk().
>
> Since I'm not an expert on a file system and don't fully understand
> the crash, please see a executed program and a crash log below in
> case that my understanding is wrong.
>
>
> Executed Program:
> Thread0 Thread1
> mkdir("./file0")
> |--------------------------|
> | mount("./file0", "./file0", "devpts", 0x0, "")
> | |
> openat(AT_FDCWD, chroot("./file0")
> "/dev/vcs", 0x200, 0x0) umount("./file0", 0x2)
>
> openat(), chroot(), umount() syscalls are executed after mount() syscall.
> We think a race occurs between openat() and chroot() because RaceFuzzer
> executed openat() and chroot() concurrently.
>
>
> (Possible) Thread interleaving:
> CPU0 (path_openat) CPU1 (cleanup_mnt)
> ===== =====
> s = path_init(nd, flags);
> if (IS_ERR(s)) {
> put_filp(file);
> return ERR_CAST(s);
> }
>
> deactivate_super(mnt->mnt.mnt_sb);
>
> while (!(error = link_path_walk(s, nd)) &&
>
> // (in link_path_walk())
> struct dentry *parent = nd->path.dentry;
> nd->flags &= ~LOOKUP_JUMPED;
> if (unlikely(parent->d_flags & DCACHE_OP_HASH)) { // UAF occured
>
>
> Crash log:
> ==================================================================
> BUG: KASAN: use-after-free in link_path_walk+0x46e/0xcd0 fs/namei.c:2061
> Read of size 4 at addr ffff8801cbe6cb80 by task syz-executor0/28699
>
> CPU: 0 PID: 28699 Comm: syz-executor0 Not tainted 4.17.0-rc1 #1
> Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.8.2-0-g33fbe13 by qemu-project.org 04/01/2014
> Call Trace:
> __dump_stack lib/dump_stack.c:77 [inline]
> dump_stack+0x166/0x21c lib/dump_stack.c:113
> print_address_description+0x73/0x250 mm/kasan/report.c:256
> kasan_report_error mm/kasan/report.c:354 [inline]
> kasan_report+0x23f/0x360 mm/kasan/report.c:412
> check_memory_region_inline mm/kasan/kasan.c:260 [inline]
> __asan_load4+0x78/0x80 mm/kasan/kasan.c:698
> link_path_walk+0x46e/0xcd0 fs/namei.c:2061
> path_openat+0x23c/0x2040 fs/namei.c:3500
> do_filp_open+0x175/0x230 fs/namei.c:3535
> do_sys_open+0x3c7/0x4a0 fs/open.c:1093
> __do_sys_open fs/open.c:1111 [inline]
> __se_sys_open fs/open.c:1106 [inline]
> __x64_sys_open+0x4c/0x60 fs/open.c:1106
> do_syscall_64+0x15f/0x4a0 arch/x86/entry/common.c:287
> entry_SYSCALL_64_after_hwframe+0x49/0xbe
> RIP: 0033:0x410601
> RSP: 002b:00007f7345489660 EFLAGS: 00000293 ORIG_RAX: 0000000000000002
> RAX: ffffffffffffffda RBX: cccccccccccccccd RCX: 0000000000410601
> RDX: 0000000000000000 RSI: 0000000000010180 RDI: 00007f7345489710
> RBP: 00000000000006e1 R08: 236573756f6d2f74 R09: 0000000000000000
> R10: 00000000200004c0 R11: 0000000000000293 R12: 00007f734548a6d4
> R13: 00000000ffffffff R14: 00000000006ff5b8 R15: 0000000000000000
>
> Allocated by task 28699:
> save_stack+0x43/0xd0 mm/kasan/kasan.c:448
> set_track mm/kasan/kasan.c:460 [inline]
> kasan_kmalloc+0xae/0xe0 mm/kasan/kasan.c:553
> kasan_slab_alloc+0x12/0x20 mm/kasan/kasan.c:490
> kmem_cache_alloc+0x12e/0x760 mm/slab.c:3554
> __d_alloc+0xc0/0x6e0 fs/dcache.c:1638
> d_alloc_anon fs/dcache.c:1742 [inline]
> d_make_root+0x2d/0x70 fs/dcache.c:1934
> devpts_fill_super+0x23b/0x500 fs/devpts/inode.c:482
> mount_nodev+0x59/0xd0 fs/super.c:1211
> devpts_mount+0x2c/0x40 fs/devpts/inode.c:509
> mount_fs+0x50/0x200 fs/super.c:1268
> vfs_kern_mount.part.26+0xbc/0x2c0 fs/namespace.c:1037
> vfs_kern_mount fs/namespace.c:2514 [inline]
> do_new_mount fs/namespace.c:2517 [inline]
> do_mount+0xb82/0x1bb0 fs/namespace.c:2847
> ksys_mount+0xab/0x120 fs/namespace.c:3063
> __do_sys_mount fs/namespace.c:3077 [inline]
> __se_sys_mount fs/namespace.c:3074 [inline]
> __x64_sys_mount+0x67/0x80 fs/namespace.c:3074
> do_syscall_64+0x15f/0x4a0 arch/x86/entry/common.c:287
> entry_SYSCALL_64_after_hwframe+0x49/0xbe
>
> Freed by task 28700:
> save_stack+0x43/0xd0 mm/kasan/kasan.c:448
> set_track mm/kasan/kasan.c:460 [inline]
> __kasan_slab_free+0x11a/0x170 mm/kasan/kasan.c:521
> kasan_slab_free+0xe/0x10 mm/kasan/kasan.c:528
> __cache_free mm/slab.c:3498 [inline]
> kmem_cache_free+0x83/0x2a0 mm/slab.c:3756
> __d_free fs/dcache.c:257 [inline]
> dentry_free+0x8c/0xe0 fs/dcache.c:347
> __dentry_kill+0x3d6/0x440 fs/dcache.c:582
> dentry_kill+0x8f/0x320 fs/dcache.c:686
> dput.part.22+0x430/0x4e0 fs/dcache.c:850
> dput fs/dcache.c:830 [inline]
> do_one_tree+0x43/0x50 fs/dcache.c:1523
> shrink_dcache_for_umount+0xa5/0x1c0 fs/dcache.c:1537
> generic_shutdown_super+0xb0/0x330 fs/super.c:425
> kill_anon_super fs/super.c:1037 [inline]
> kill_litter_super+0x48/0x60 fs/super.c:1047
> devpts_kill_sb+0x49/0x50 fs/devpts/inode.c:519
> deactivate_locked_super+0x71/0xb0 fs/super.c:313
> deactivate_super+0x10f/0x150 fs/super.c:344
> cleanup_mnt+0x6b/0xc0 fs/namespace.c:1173
> __cleanup_mnt+0x16/0x20 fs/namespace.c:1180
> task_work_run+0x152/0x1b0 kernel/task_work.c:113
> tracehook_notify_resume include/linux/tracehook.h:191 [inline]
> exit_to_usermode_loop+0x262/0x270 arch/x86/entry/common.c:166
> prepare_exit_to_usermode arch/x86/entry/common.c:196 [inline]
> syscall_return_slowpath arch/x86/entry/common.c:265 [inline]
> do_syscall_64+0x473/0x4a0 arch/x86/entry/common.c:290
> entry_SYSCALL_64_after_hwframe+0x49/0xbe
>
> The buggy address belongs to the object at ffff8801cbe6cb80
> which belongs to the cache dentry(17:syz0) of size 288
> The buggy address is located 0 bytes inside of
> 288-byte region [ffff8801cbe6cb80, ffff8801cbe6cca0)
> The buggy address belongs to the page:
> page:ffffea00072f9b00 count:1 mapcount:0 mapping:ffff8801cbe6c080 index:0x0
> flags: 0x2fffc0000000100(slab)
> raw: 02fffc0000000100 ffff8801cbe6c080 0000000000000000 000000010000000b
> raw: ffffea00072f8ca0 ffffea00072f8da0 ffff8801dc812c80 ffff8801de41a740
> page dumped because: kasan: bad access detected
> page->mem_cgroup:ffff8801de41a740
>
> Memory state around the buggy address:
> ffff8801cbe6ca80: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
> ffff8801cbe6cb00: fb fb fb fb fb fb fb fb fc fc fc fc fc fc fc fc
>>ffff8801cbe6cb80: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
> ^
> ffff8801cbe6cc00: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
> ffff8801cbe6cc80: fb fb fb fb fc fc fc fc fc fc fc fc fb fb fb fb
> ==================================================================
>
>
> = About RaceFuzzer
>
> RaceFuzzer is a customized version of Syzkaller, specifically tailored
> to find race condition bugs in the Linux kernel. While we leverage
> many different technique, the notable feature of RaceFuzzer is in
> leveraging a custom hypervisor (QEMU/KVM) to interleave the
> scheduling. In particular, we modified the hypervisor to intentionally
> stall a per-core execution, which is similar to supporting per-core
> breakpoint functionality. This allows RaceFuzzer to force the kernel
> to deterministically trigger racy condition (which may rarely happen
> in practice due to randomness in scheduling).
>
> RaceFuzzer's C repro always pinpoints two racy syscalls. Since C
> repro's scheduling synchronization should be performed at the user
> space, its reproducibility is limited (reproduction may take from 1
> second to 10 minutes (or even more), depending on a bug). This is
> because, while RaceFuzzer precisely interleaves the scheduling at the
> kernel's instruction level when finding this bug, C repro cannot fully
> utilize such a feature. Please disregard all code related to
> "should_hypercall" in the C repro, as this is only for our debugging
> purposes using our own hypervisor.
^ permalink raw reply
* [U-Boot] [PATCH 2/3] rockchip: add support for veyron-speedy (ASUS Chromebook C201)
From: Marty E. Plummer @ 2018-07-24 5:12 UTC (permalink / raw)
To: u-boot
In-Reply-To: <5B7BE192-291F-48F6-9247-D9BC37B4AFE6@theobroma-systems.com>
On Fri, Jul 13, 2018 at 12:31:49PM +0200, Dr. Philipp Tomsich wrote:
>
> > On 7 May 2018, at 02:20, Marty E. Plummer <hanetzer@startmail.com> wrote:
> >
> > On Mon, May 07, 2018 at 12:12:54AM +0200, klaus.goger at theobroma-systems.com <mailto:klaus.goger@theobroma-systems.com> wrote:
> >>
> >>> On 06.05.2018, at 16:25, Marty E. Plummer <hanetzer@startmail.com> wrote:
> >>>
> >>> This adds support for the ASUS C201, a RK3288-based clamshell
> >>> device. The device tree comes from linus's linux tree at
> >>> 87ef12027b9b1dd0e0b12cf311fbcb19f9d92539. The SDRAM parameters
> >>> are for 4GB Samsung LPDDR3, decoded from coreboot's
> >>> src/mainboard/google/veyron/sdram_inf/sdram-lpddr3-samsung-4GB.inc
> >>>
> >>> Signed-off-by: Marty E. Plummer <hanetzer@startmail.com>
> >>> ---
> >>> arch/arm/dts/Makefile | 1 +
> >>> arch/arm/dts/rk3288-veyron-speedy.dts | 189 ++++++++++++++++++++++
> >>> arch/arm/mach-rockchip/rk3288-board-spl.c | 3 +-
> >>> arch/arm/mach-rockchip/rk3288/Kconfig | 11 ++
> >>> board/google/veyron/Kconfig | 16 ++
> >>> configs/chromebook_speedy_defconfig | 96 +++++++++++
> >>> 6 files changed, 315 insertions(+), 1 deletion(-)
> >>> create mode 100644 arch/arm/dts/rk3288-veyron-speedy.dts
> >>> create mode 100644 configs/chromebook_speedy_defconfig
> >>>
> >>> diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile
> >>> index ac7667b1e8..ee04d9bedd 100644
> >>> --- a/arch/arm/dts/Makefile
> >>> +++ b/arch/arm/dts/Makefile
> >>> @@ -42,6 +42,7 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += \
> >>> rk3288-veyron-jerry.dtb \
> >>> rk3288-veyron-mickey.dtb \
> >>> rk3288-veyron-minnie.dtb \
> >>> + rk3288-veyron-speedy.dtb \
> >>> rk3288-vyasa.dtb \
> >>> rk3328-evb.dtb \
> >>> rk3368-lion.dtb \
> >>> diff --git a/arch/arm/dts/rk3288-veyron-speedy.dts b/arch/arm/dts/rk3288-veyron-speedy.dts
> >>> new file mode 100644
> >>> index 0000000000..d5383cef0d
> >>> --- /dev/null
> >>> +++ b/arch/arm/dts/rk3288-veyron-speedy.dts
> >>
> >> This file looks quite different then the one I see on kernel.org with that revision id. So you are sure you
> >> imported that one?
> > Dafuq... it seems I borked something up in doing the patch juggling to
> > turn my single-commit mess of a patch (you know, the 'get the thing to
> > work branch') into a good patch series I messed up on this one.
> >>
> >>> @@ -0,0 +1,189 @@
> >>> +/*
> >>> + * Google Veyron Speedy Rev 1+ board device tree source
> >>> + *
> >>> + * Copyright 2015 Google, Inc
> >>> + *
> >>> + * SPDX-License-Identifier: GPL-2.0
> >>
> >> This file is dual licensed upstream, keep it that way.
> >> The comment will claim it's a X11 license but the license text below
> >> is actually MIT so you may want to use the MIT SPDX tag for that.
> >>
> > Yeah, I was listening in on the convo on irc. So, even though it 'says'
> > its GPL/X11, the actual license text is MIT, so I should use that tag?
> > Its not my code, obviously, so I have no dog in that race anyways.
> >>> + */
> >>> +
> >>> +/dts-v1/;
> >>> +#include "rk3288-veyron-chromebook.dtsi"
> >>> +#include "cros-ec-sbs.dtsi"
> >>> +
> >>> +/ {
> >>> + model = "Google Speedy";
> >>> + compatible = "google,veyron-speedy-rev9", "google,veyron-speedy-rev8",
> >>> + "google,veyron-speedy-rev7", "google,veyron-speedy-rev6",
> >>> + "google,veyron-speedy-rev5", "google,veyron-speedy-rev4",
> >>> + "google,veyron-speedy-rev3", "google,veyron-speedy-rev2",
> >>> + "google,veyron-speedy", "google,veyron", "rockchip,rk3288";
> >>> +
> >>> + chosen {
> >>> + stdout-path = &uart2;
> >>> + };
> >>> +
> >>> + panel_regulator: panel-regulator {
> >>> + compatible = "regulator-fixed";
> >>> + enable-active-high;
> >>> + gpio = <&gpio7 RK_PB6 GPIO_ACTIVE_HIGH>;
> >>> + pinctrl-names = "default";
> >>> + pinctrl-0 = <&lcd_enable_h>;
> >>> + regulator-name = "panel_regulator";
> >>> + startup-delay-us = <100000>;
> >>> + vin-supply = <&vcc33_sys>;
> >>> + };
> >>> +
> >>> + vcc18_lcd: vcc18-lcd {
> >>> + compatible = "regulator-fixed";
> >>> + enable-active-high;
> >>> + gpio = <&gpio2 RK_PB5 GPIO_ACTIVE_HIGH>;
> >>> + pinctrl-names = "default";
> >>> + pinctrl-0 = <&avdd_1v8_disp_en>;
> >>> + regulator-name = "vcc18_lcd";
> >>> + regulator-always-on;
> >>> + regulator-boot-on;
> >>> + vin-supply = <&vcc18_wl>;
> >>> + };
> >>> +
> >>> + backlight_regulator: backlight-regulator {
> >>> + compatible = "regulator-fixed";
> >>> + enable-active-high;
> >>> + gpio = <&gpio2 RK_PB4 GPIO_ACTIVE_HIGH>;
> >>> + pinctrl-names = "default";
> >>> + pinctrl-0 = <&bl_pwr_en>;
> >>> + regulator-name = "backlight_regulator";
> >>> + vin-supply = <&vcc33_sys>;
> >>> + startup-delay-us = <15000>;
> >>> + };
> >>> +};
> >>> +
> >>> +&dmc {
> >>> + rockchip,pctl-timing = <0x215 0xc8 0x0 0x35 0x26 0x2 0x70 0x2000d
> >>> + 0x6 0x0 0x8 0x4 0x17 0x24 0xd 0x6
> >>> + 0x4 0x8 0x4 0x76 0x4 0x0 0x30 0x0
> >>> + 0x1 0x2 0x2 0x4 0x0 0x0 0xc0 0x4
> >>> + 0x8 0x1f4>;
> >>> + rockchip,phy-timing = <0x48d7dd93 0x187008d8 0x121076
> >>> + 0x0 0xc3 0x6 0x1>;
> >>> + rockchip,sdram-params = <0x20D266A4 0x5B6 6 533000000 6 13 0>;
> >>> +};
> >>
> >> Not sure if this should go into a separate dtsi. One of the maintainer will have
> >> a preferred way I think, so lets see what they will add.
> >>
> > Yeah, that is possible. However, here I just followed the example of
> > rk3288-veyron-jerry.dtsi, which I (perhaps wrongly) assume can come in
> > other memory size variants.
>
> Having a “-u-boot.dtsi” is the current practice (counting 85 such files as of today).
> We should follow this model here as well for any new devices we add.
>
Fair. So what should go into the -u-boot.dtsi file? everything not
standard to the imported dts/dtsi from linux?
> >>> +&gpio_keys {
> >>> + power {
> >>> + gpios = <&gpio0 RK_PA5 GPIO_ACTIVE_LOW>;
> >>> + };
> >>> +};
> >>> +
> >>> +&backlight {
> >>> + power-supply = <&backlight_regulator>;
> >>> +};
> >>> +
> >>> +&panel {
> >>> + power-supply = <&panel_regulator>;
> >>> +};
> >>> +
> >>> +&rk808 {
> >>> + pinctrl-names = "default";
> >>> + pinctrl-0 = <&pmic_int_l>;
> >>> +};
> >>> +
> >>> +&sdmmc {
> >>> + pinctrl-names = "default";
> >>> + pinctrl-0 = <&sdmmc_clk &sdmmc_cmd &sdmmc_cd_disabled &sdmmc_cd_gpio
> >>> + &sdmmc_bus4>;
> >>> + disable-wp;
> >>> +};
> >>> +
> >>> +&vcc_5v {
> >>> + enable-active-high;
> >>> + gpio = <&gpio7 RK_PC5 GPIO_ACTIVE_HIGH>;
> >>> + pinctrl-names = "default";
> >>> + pinctrl-0 = <&drv_5v>;
> >>> +};
> >>> +
> >>> +&vcc50_hdmi {
> >>> + enable-active-high;
> >>> + gpio = <&gpio5 RK_PC3 GPIO_ACTIVE_HIGH>;
> >>> + pinctrl-names = "default";
> >>> + pinctrl-0 = <&vcc50_hdmi_en>;
> >>> +};
> >>> +
> >>> +&edp {
> >>> + pinctrl-names = "default";
> >>> + pinctrl-0 = <&edp_hpd>;
> >>> +};
> >>> +
> >>> +&pinctrl {
> >>> + backlight {
> >>> + bl_pwr_en: bl_pwr_en {
> >>> + rockchip,pins = <2 12 RK_FUNC_GPIO &pcfg_pull_none>;
> >>> + };
> >>> + };
> >>> +
> >>> + buck-5v {
> >>> + drv_5v: drv-5v {
> >>> + rockchip,pins = <7 21 RK_FUNC_GPIO &pcfg_pull_none>;
> >>> + };
> >>> + };
> >>> +
> >>> + edp {
> >>> + edp_hpd: edp_hpd {
> >>> + rockchip,pins = <7 11 RK_FUNC_2 &pcfg_pull_down>;
> >>> + };
> >>> + };
> >>> +
> >>> + emmc {
> >>> + /* Make sure eMMC is not in reset */
> >>> + emmc_deassert_reset: emmc-deassert-reset {
> >>> + rockchip,pins = <2 9 RK_FUNC_GPIO &pcfg_pull_none>;
> >>> + };
> >>> + };
> >>> +
> >>> + hdmi {
> >>> + vcc50_hdmi_en: vcc50-hdmi-en {
> >>> + rockchip,pins = <5 19 RK_FUNC_GPIO &pcfg_pull_none>;
> >>> + };
> >>> + };
> >>> +
> >>> + lcd {
> >>> + lcd_enable_h: lcd-en {
> >>> + rockchip,pins = <7 14 RK_FUNC_GPIO &pcfg_pull_none>;
> >>> + };
> >>> +
> >>> + avdd_1v8_disp_en: avdd-1v8-disp-en {
> >>> + rockchip,pins = <2 13 RK_FUNC_GPIO &pcfg_pull_none>;
> >>> + };
> >>> + };
> >>> +
> >>> + pmic {
> >>> + dvs_1: dvs-1 {
> >>> + rockchip,pins = <7 12 RK_FUNC_GPIO &pcfg_pull_down>;
> >>> + };
> >>> +
> >>> + dvs_2: dvs-2 {
> >>> + rockchip,pins = <7 15 RK_FUNC_GPIO &pcfg_pull_down>;
> >>> + };
> >>> + };
> >>> +};
> >>> +
> >>> +&i2c4 {
> >>> + status = "okay";
> >>> +
> >>> + pinctrl-names = "default";
> >>> + pinctrl-0 = <&i2c4_xfer>;
> >>> +
> >>> + trackpad at 15 {
> >>> + compatible = "elan,i2c_touchpad";
> >>> + interrupt-parent = <&gpio7>;
> >>> + interrupts = <3 IRQ_TYPE_EDGE_FALLING>;
> >>> + /*
> >>> + * Remove the inherited pinctrl settings to avoid clashing
> >>> + * with bus-wide ones.
> >>> + */
> >>> + /delete-property/pinctrl-names;
> >>> + /delete-property/pinctrl-0;
> >>> + reg = <0x15>;
> >>> + vcc-supply = <&vcc33_io>;
> >>> + wakeup-source;
> >>> + };
> >>> +};
> >>> diff --git a/arch/arm/mach-rockchip/rk3288-board-spl.c b/arch/arm/mach-rockchip/rk3288-board-spl.c
> >>> index f3ea624277..9ae4802647 100644
> >>> --- a/arch/arm/mach-rockchip/rk3288-board-spl.c
> >>> +++ b/arch/arm/mach-rockchip/rk3288-board-spl.c
> >>> @@ -72,7 +72,8 @@ u32 spl_boot_device(void)
> >>> fallback:
> >>> #elif defined(CONFIG_TARGET_CHROMEBOOK_JERRY) || \
> >>> defined(CONFIG_TARGET_CHROMEBIT_MICKEY) || \
> >>> - defined(CONFIG_TARGET_CHROMEBOOK_MINNIE)
> >>> + defined(CONFIG_TARGET_CHROMEBOOK_MINNIE) || \
> >>> + defined(CONFIG_TARGET_CHROMEBOOK_SPEEDY)
> >>> return BOOT_DEVICE_SPI;
> >>> #endif
> >>> return BOOT_DEVICE_MMC1;
> >>> diff --git a/arch/arm/mach-rockchip/rk3288/Kconfig b/arch/arm/mach-rockchip/rk3288/Kconfig
> >>> index 6beb26fd7a..8d1d37895d 100644
> >>> --- a/arch/arm/mach-rockchip/rk3288/Kconfig
> >>> +++ b/arch/arm/mach-rockchip/rk3288/Kconfig
> >>> @@ -30,6 +30,17 @@ config TARGET_CHROMEBOOK_MINNIE
> >>> functions. It includes 2 or 4GB of SDRAM and 16 or 32GB of
> >>> internal MMC. The product name is ASUS Chromebook Flip.
> >>>
> >>> +config TARGET_CHROMEBOOK_SPEEDY
> >>> + bool "Google/Rockchip Veyron-Speedy Chromebook"
> >>> + select BOARD_LATE_INIT
> >>> + help
> >>> + Speedy is a RK3288-based clamshell device with 2 USB 2.0 ports,
> >>> + micro HDMI, an 11.6 inch display, micro-SD card,
> >>> + HD camera, touchpad, wifi and Bluetooth. It includes a Chrome OS
> >>> + EC (Cortex-M3) to provide access to the keyboard and battery
> >>> + functions. It includes 2 or 4GB of SDRAM and 16GB of internal MMC.
> >>> + The product name is Asus Chromebook C201PA.
> >>> +
> >>> config TARGET_EVB_RK3288
> >>> bool "Evb-RK3288"
> >>> select BOARD_LATE_INIT
> >>> diff --git a/board/google/veyron/Kconfig b/board/google/veyron/Kconfig
> >>> index 770e9aad28..7f55d78dac 100644
> >>> --- a/board/google/veyron/Kconfig
> >>> +++ b/board/google/veyron/Kconfig
> >>> @@ -45,3 +45,19 @@ config BOARD_SPECIFIC_OPTIONS # dummy
> >>> def_bool y
> >>>
> >>> endif
> >>> +
> >>> +if TARGET_CHROMEBOOK_SPEEDY
> >>> +
> >>> +config SYS_BOARD
> >>> + default "veyron"
> >>> +
> >>> +config SYS_VENDOR
> >>> + default "google"
> >>> +
> >>> +config SYS_CONFIG_NAME
> >>> + default "veyron"
> >>> +
> >>> +config BOARD_SPECIFIC_OPTIONS # dummy
> >>> + def_bool y
> >>> +
> >>> +endif
> >>> diff --git a/configs/chromebook_speedy_defconfig b/configs/chromebook_speedy_defconfig
> >>> new file mode 100644
> >>> index 0000000000..8789b56f37
> >>> --- /dev/null
> >>> +++ b/configs/chromebook_speedy_defconfig
> >>> @@ -0,0 +1,96 @@
> >>> +CONFIG_ARM=y
> >>> +CONFIG_ARCH_ROCKCHIP=y
> >>> +CONFIG_SYS_TEXT_BASE=0x00100000
> >>> +CONFIG_SYS_MALLOC_F_LEN=0x2000
> >>> +CONFIG_ROCKCHIP_RK3288=y
> >>> +# CONFIG_SPL_MMC_SUPPORT is not set
> >>> +CONFIG_TARGET_CHROMEBOOK_SPEEDY=y
> >>> +CONFIG_SPL_SPI_FLASH_SUPPORT=y
> >>> +CONFIG_SPL_SPI_SUPPORT=y
> >>> +CONFIG_SPL_STACK_R_ADDR=0x80000
> >>> +CONFIG_DEFAULT_DEVICE_TREE="rk3288-veyron-speedy"
> >>> +CONFIG_DEBUG_UART=y
> >>> +# CONFIG_ANDROID_BOOT_IMAGE is not set
> >>> +CONFIG_SILENT_CONSOLE=y
> >>> +# CONFIG_DISPLAY_CPUINFO is not set
> >>> +CONFIG_DISPLAY_BOARDINFO_LATE=y
> >>> +CONFIG_BOARD_EARLY_INIT_F=y
> >>> +CONFIG_SPL_STACK_R=y
> >>> +CONFIG_SPL_STACK_R_MALLOC_SIMPLE_LEN=0x2000
> >>> +CONFIG_SPL_SPI_LOAD=y
> >>> +CONFIG_FASTBOOT_FLASH=y
> >>> +CONFIG_FASTBOOT_FLASH_MMC_DEV=0
> >>> +CONFIG_CMD_GPIO=y
> >>> +CONFIG_CMD_GPT=y
> >>> +CONFIG_CMD_I2C=y
> >>> +CONFIG_CMD_MMC=y
> >>> +CONFIG_CMD_SF=y
> >>> +CONFIG_CMD_SF_TEST=y
> >>> +CONFIG_CMD_SPI=y
> >>> +CONFIG_CMD_USB=y
> >>> +# CONFIG_CMD_SETEXPR is not set
> >>> +CONFIG_CMD_CACHE=y
> >>> +CONFIG_CMD_TIME=y
> >>> +CONFIG_CMD_PMIC=y
> >>> +CONFIG_CMD_REGULATOR=y
> >>> +# CONFIG_SPL_DOS_PARTITION is not set
> >>> +# CONFIG_SPL_EFI_PARTITION is not set
> >>> +CONFIG_SPL_PARTITION_UUIDS=y
> >>> +CONFIG_SPL_OF_CONTROL=y
> >>> +CONFIG_OF_SPL_REMOVE_PROPS="pinctrl-0 pinctrl-names clock-names interrupt-parent assigned-clocks assigned-clock-rates assigned-clock-parents"
> >>> +CONFIG_SPL_OF_PLATDATA=y
> >>> +CONFIG_REGMAP=y
> >>> +CONFIG_SPL_REGMAP=y
> >>> +CONFIG_SYSCON=y
> >>> +CONFIG_SPL_SYSCON=y
> >>> +# CONFIG_SPL_SIMPLE_BUS is not set
> >>> +CONFIG_CLK=y
> >>> +CONFIG_SPL_CLK=y
> >>> +CONFIG_ROCKCHIP_GPIO=y
> >>> +CONFIG_I2C_CROS_EC_TUNNEL=y
> >>> +CONFIG_SYS_I2C_ROCKCHIP=y
> >>> +CONFIG_I2C_MUX=y
> >>> +CONFIG_DM_KEYBOARD=y
> >>> +CONFIG_CROS_EC_KEYB=y
> >>> +CONFIG_CROS_EC=y
> >>> +CONFIG_CROS_EC_SPI=y
> >>> +CONFIG_PWRSEQ=y
> >>> +CONFIG_MMC_DW=y
> >>> +CONFIG_MMC_DW_ROCKCHIP=y
> >>> +CONFIG_PINCTRL=y
> >>> +CONFIG_SPL_PINCTRL=y
> >>> +# CONFIG_SPL_PINCTRL_FULL is not set
> >>> +CONFIG_PINCTRL_ROCKCHIP_RK3288=y
> >>> +CONFIG_DM_PMIC=y
> >>> +# CONFIG_SPL_PMIC_CHILDREN is not set
> >>> +CONFIG_PMIC_RK8XX=y
> >>> +CONFIG_DM_REGULATOR_FIXED=y
> >>> +CONFIG_REGULATOR_RK8XX=y
> >>> +CONFIG_PWM_ROCKCHIP=y
> >>> +CONFIG_RAM=y
> >>> +CONFIG_SPL_RAM=y
> >>> +CONFIG_DEBUG_UART_BASE=0xff690000
> >>> +CONFIG_DEBUG_UART_CLOCK=24000000
> >>> +CONFIG_DEBUG_UART_SHIFT=2
> >>> +CONFIG_SYS_NS16550=y
> >>> +CONFIG_ROCKCHIP_SERIAL=y
> >>> +CONFIG_ROCKCHIP_SPI=y
> >>> +CONFIG_SYSRESET=y
> >>> +CONFIG_USB=y
> >>> +CONFIG_ROCKCHIP_USB2_PHY=y
> >>> +CONFIG_USB_STORAGE=y
> >>> +CONFIG_USB_GADGET=y
> >>> +CONFIG_USB_GADGET_MANUFACTURER="Rockchip"
> >>> +CONFIG_USB_GADGET_VENDOR_NUM=0x2207
> >>> +CONFIG_USB_GADGET_PRODUCT_NUM=0x320a
> >>> +CONFIG_USB_GADGET_DWC2_OTG=y
> >>> +CONFIG_USB_FUNCTION_MASS_STORAGE=y
> >>> +CONFIG_DM_VIDEO=y
> >>> +CONFIG_DISPLAY=y
> >>> +CONFIG_VIDEO_ROCKCHIP=y
> >>> +CONFIG_DISPLAY_ROCKCHIP_EDP=y
> >>> +CONFIG_DISPLAY_ROCKCHIP_HDMI=y
> >>> +CONFIG_USE_TINY_PRINTF=y
> >>> +CONFIG_CMD_DHRYSTONE=y
> >>> +CONFIG_ERRNO_STR=y
> >>> +# CONFIG_SPL_OF_LIBFDT is not set
> >>> --
> >>> 2.17.0
> >>>
> >>> _______________________________________________
> >>> U-Boot mailing list
> >>> U-Boot at lists.denx.de
> >>> https://lists.denx.de/listinfo/u-boot
> >>
> > _______________________________________________
> > U-Boot mailing list
> > U-Boot at lists.denx.de
> > https://lists.denx.de/listinfo/u-boot
>
^ permalink raw reply
* [PATCH] xfsprogs: remove generated scrub files under clean target
From: Eric Sandeen @ 2018-07-24 4:06 UTC (permalink / raw)
To: linux-xfs
Signed-off-by: Eric Sandeen <sandeen@redhat.com>
---
diff --git a/scrub/Makefile b/scrub/Makefile
index d9ab148..acebecc 100644
--- a/scrub/Makefile
+++ b/scrub/Makefile
@@ -97,6 +97,8 @@ ifeq ($(HAVE_HDIO_GETGEO),yes)
LCFLAGS += -DHAVE_HDIO_GETGEO
endif
+LDIRT = $(XFS_SCRUB_ALL_PROG) *.service *.cron
+
default: depend $(LTCOMMAND) $(XFS_SCRUB_ALL_PROG) $(OPTIONAL_TARGETS)
xfs_scrub_all: xfs_scrub_all.in
^ permalink raw reply related
* Re: [PATCH v5 net-next 0/3] rds: IPv6 support
From: David Miller @ 2018-07-24 4:06 UTC (permalink / raw)
To: ka-cheong.poon; +Cc: netdev, santosh.shilimkar, rds-devel, sowmini.varadhan
In-Reply-To: <cover.1532404047.git.ka-cheong.poon@oracle.com>
Hello,
Since you have not fundamentally changed the code, just made
a build failure fix, would you please retain the ACKs that the
previous version received?
I either have to apply this as-is without the ACKs, or wait and
see if that person does the ACKs again for you.
Thank you.
^ permalink raw reply
* [linux-4.14 test] 125509: regressions - trouble: broken/fail/pass
From: osstest service owner @ 2018-07-24 5:10 UTC (permalink / raw)
To: xen-devel, osstest-admin
flight 125509 linux-4.14 real [real]
http://logs.test-lab.xenproject.org/osstest/logs/125509/
Regressions :-(
Tests which did not succeed and are blocking,
including tests which could not be run:
test-armhf-armhf-xl-credit2 <job status> broken
test-armhf-armhf-xl-credit2 4 host-install(4) broken REGR. vs. 125175
test-amd64-amd64-xl-qemuu-debianhvm-amd64-shadow 10 debian-hvm-install fail REGR. vs. 125175
test-amd64-amd64-xl-qemuu-debianhvm-amd64-xsm 10 debian-hvm-install fail REGR. vs. 125175
test-amd64-i386-qemut-rhel6hvm-amd 10 redhat-install fail REGR. vs. 125175
test-amd64-amd64-xl-pvhv2-amd 10 debian-install fail REGR. vs. 125175
test-amd64-amd64-xl-pvshim 10 debian-install fail REGR. vs. 125175
test-amd64-i386-xl 10 debian-install fail REGR. vs. 125175
Tests which did not succeed, but are not blocking:
test-amd64-i386-xl-qemuu-dmrestrict-amd64-dmrestrict 10 debian-hvm-install fail never pass
test-amd64-amd64-xl-qemuu-dmrestrict-amd64-dmrestrict 10 debian-hvm-install fail never pass
test-amd64-i386-libvirt 13 migrate-support-check fail never pass
test-amd64-i386-libvirt-xsm 13 migrate-support-check fail never pass
test-amd64-amd64-libvirt-xsm 13 migrate-support-check fail never pass
test-amd64-i386-xl-pvshim 12 guest-start fail never pass
test-amd64-amd64-libvirt 13 migrate-support-check fail never pass
test-arm64-arm64-xl 13 migrate-support-check fail never pass
test-arm64-arm64-xl 14 saverestore-support-check fail never pass
test-arm64-arm64-libvirt-xsm 13 migrate-support-check fail never pass
test-arm64-arm64-libvirt-xsm 14 saverestore-support-check fail never pass
test-arm64-arm64-xl-credit2 13 migrate-support-check fail never pass
test-arm64-arm64-xl-credit2 14 saverestore-support-check fail never pass
test-arm64-arm64-xl-xsm 13 migrate-support-check fail never pass
test-arm64-arm64-xl-xsm 14 saverestore-support-check fail never pass
test-amd64-amd64-libvirt-qemuu-debianhvm-amd64-xsm 11 migrate-support-check fail never pass
test-amd64-i386-libvirt-qemuu-debianhvm-amd64-xsm 11 migrate-support-check fail never pass
test-armhf-armhf-xl-arndale 13 migrate-support-check fail never pass
test-armhf-armhf-xl-arndale 14 saverestore-support-check fail never pass
test-amd64-amd64-qemuu-nested-amd 17 debian-hvm-install/l1/l2 fail never pass
test-amd64-amd64-libvirt-vhd 12 migrate-support-check fail never pass
test-armhf-armhf-xl 13 migrate-support-check fail never pass
test-armhf-armhf-xl-multivcpu 13 migrate-support-check fail never pass
test-armhf-armhf-xl-multivcpu 14 saverestore-support-check fail never pass
test-armhf-armhf-xl 14 saverestore-support-check fail never pass
test-armhf-armhf-xl-rtds 13 migrate-support-check fail never pass
test-armhf-armhf-xl-rtds 14 saverestore-support-check fail never pass
test-armhf-armhf-libvirt 13 migrate-support-check fail never pass
test-armhf-armhf-libvirt 14 saverestore-support-check fail never pass
test-armhf-armhf-xl-cubietruck 13 migrate-support-check fail never pass
test-armhf-armhf-xl-cubietruck 14 saverestore-support-check fail never pass
test-amd64-i386-xl-qemut-win7-amd64 17 guest-stop fail never pass
test-amd64-amd64-xl-qemuu-ws16-amd64 17 guest-stop fail never pass
test-amd64-amd64-xl-qemuu-win7-amd64 17 guest-stop fail never pass
test-amd64-i386-xl-qemuu-win7-amd64 17 guest-stop fail never pass
test-armhf-armhf-libvirt-raw 12 migrate-support-check fail never pass
test-armhf-armhf-libvirt-raw 13 saverestore-support-check fail never pass
test-amd64-amd64-xl-qemut-win7-amd64 17 guest-stop fail never pass
test-amd64-i386-xl-qemuu-ws16-amd64 17 guest-stop fail never pass
test-amd64-amd64-xl-qemut-ws16-amd64 17 guest-stop fail never pass
test-amd64-i386-xl-qemut-ws16-amd64 17 guest-stop fail never pass
test-armhf-armhf-xl-vhd 12 migrate-support-check fail never pass
test-armhf-armhf-xl-vhd 13 saverestore-support-check fail never pass
test-amd64-i386-xl-qemut-win10-i386 10 windows-install fail never pass
test-amd64-amd64-xl-qemut-win10-i386 10 windows-install fail never pass
test-amd64-amd64-xl-qemuu-win10-i386 10 windows-install fail never pass
test-amd64-i386-xl-qemuu-win10-i386 10 windows-install fail never pass
version targeted for testing:
linux ecc160ece609498c946e73710e5c7c54c62b966a
baseline version:
linux 1e92e813554a93741666e9f378a83d70405b9076
Last test of basis 125175 2018-07-15 08:04:36 Z 8 days
Failing since 125270 2018-07-17 10:10:13 Z 6 days 5 attempts
Testing same since 125509 2018-07-22 20:11:58 Z 1 days 1 attempts
------------------------------------------------------------
People who touched revisions under test:
Alan Jenkins <alan.christopher.jenkins@gmail.com>
Aleksander Morgado <aleksander@aleksander.es>
Alex Chen <alex.chen@huawei.com>
Alex Vesker <valex@mellanox.com>
Amit Pundir <amit.pundir@linaro.org>
Andreas Schwab <schwab@linux-m68k.org>
Andrew Morton <akpm@linux-foundation.org>
Anna Schumaker <Anna.Schumaker@Netapp.com>
Antoine Tenart <antoine.tenart@bootlin.com>
Ard Biesheuvel <ard.biesheuvel@linaro.org>
Artem Bityutskiy <artem.bityutskiy@intel.com>
Bhadram Varka <vbhadram@nvidia.com>
Bjorn Helgaas <bhelgaas@google.com>
Bjørn Mork <bjorn@mork.no>
Boris Brezillon <boris.brezillon@bootlin.com>
Catalin Marinas <catalin.marinas@arm.com>
Changwei Ge <ge.changwei@h3c.com>
Chris Wilson <chris@chris-wilson.co.uk>
Christian Borntraeger <borntraeger@de.ibm.com>
Christian Brauner <christian.brauner@ubuntu.com>
Christian Lamparter <chunkeey@googlemail.com>
Christoffer Dall <cdall@linaro.org>
Christoffer Dall <christoffer.dall@arm.com>
Christoffer Dall <christoffer.dall@linaro.org>
Christoph Hellwig <hch@lst.de>
Chuck Lever <chuck.lever@oracle.com>
Claudio Imbrenda <imbrenda@linux.vnet.ibm.com>
Damien Le Moal <damien.lemoal@wdc.com>
Dan Carpenter <dan.carpenter@oracle.com>
Dave Watson <davejwatson@fb.com>
David Ahern <dsahern@gmail.com>
David S. Miller <davem@davemloft.net>
David Sterba <dsterba@suse.com>
David Woodhouse <dwmw2@infradead.org>
Dennis Dalessandro <dennis.dalessandro@intel.com>
Dexuan Cui <decui@microsoft.com>
Diego Viola <diego.viola@gmail.com>
Doron Roberts-Kedes <doronrk@fb.com>
Eli Cohen <eli@mellanox.com>
Eli Cohen <eli@melloanox.com>
Eric Biggers <ebiggers@google.com>
Eric Dumazet <edumazet@google.com>
Evgeny Kapun <abacabadabacaba@gmail.com> # 8723DE
Filipe Manana <fdmanana@suse.com>
Florian Westphal <fw@strlen.de>
Floris Bos <bos@je-eigen-domein.nl>
Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Gustavo A. R. Silva <gustavo@embeddedor.com>
H. Peter Anvin <hpa@linux.intel.com>
Haiyang Zhang <haiyangz@microsoft.com>
Hans de Goede <hdegoede@redhat.com>
Harini Katakam <harini.katakam@xilinx.com>
Herbert Xu <herbert@gondor.apana.org.au>
Hui Wang <hui.wang@canonical.com>
Ian Kent <raven@themaw.net>
Ilpo Järvinen <ilpo.jarvinen@helsinki.fi>
Ingo Molnar <mingo@kernel.org>
Jaegeuk Kim <jaegeuk@kernel.org>
Jaehoon Chung <jh80.chung@samsung.com>
James Morse <james.morse@arm.com>
Jan Kara <jack@suse.cz>
Jann Horn <jannh@google.com>
Jason Gunthorpe <jgg@mellanox.com>
Jason Wang <jasowang@redhat.com>
Jens Axboe <axboe@kernel.dk>
Jesper Dangaard Brouer <brouer@redhat.com>
Jian-Hong Pan <jian-hong@endlessm.com>
Jiri Benc <jbenc@redhat.com>
Jiri Slaby <jslaby@suse.cz>
Joel Fernandes (Google) <joel@joelfernandes.org>
Johan Hovold <johan@kernel.org>
Jon Hunter <jonathanh@nvidia.com>
Jonas Gorski <jonas.gorski@gmail.com>
Jordan Glover <Golden_Miller83@protonmail.ch>
Juergen Gross <jgross@suse.com>
Kai Chieh Chuang <kaichieh.chuang@mediatek.com>
KaiChieh Chuang <kaichieh.chuang@mediatek.com>
Kalle Valo <kvalo@codeaurora.org>
Kashyap Desai <kashyap.desai@broadcom.com>
Kees Cook <keescook@chromium.org>
Keith Busch <keith.busch@intel.com>
Kevin Darbyshire-Bryant <ldir@darbyshire-bryant.me.uk>
Konstantin Khlebnikov <khlebnikov@yandex-team.ru>
Leon Romanovsky <leonro@mellanox.com>
Linus Torvalds <torvalds@linux-foundation.org>
Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Marc Zyngier <marc.zyngier@arm.com>
Mark Brown <broonie@kernel.org>
Martin K. Petersen <martin.petersen@oracle.com>
Masahiro Yamada <yamada.masahiro@socionext.com>
Mathias Nyman <mathias.nyman@linux.intel.com>
Mauro Carvalho Chehab <mchehab@s-opensource.com>
Michael J. Ruhl <michael.j.ruhl@intel.com>
Michal Hocko <mhocko@suse.com>
Michal Kalderon <Michal.Kalderon@cavium.com>
Ming Lei <ming.lei@redhat.com>
Murray McAllister <murray.mcallister@insomniasec.com>
Nadav Amit <namit@vmware.com>
Neal Cardwell <ncardwell@google.com>
Nick Desaulniers <ndesaulniers@google.com>
Nico Sneck <snecknico@gmail.com>
Nicolas Ferre <nicolas.ferre@microchip.com>
Oleg Nesterov <oleg@redhat.com>
Olli Salonen <olli.salonen@iki.fi>
Or Gerlitz <ogerlitz@mellanox.com>
Oscar Salvador <osalvador@suse.de>
Pablo Neira Ayuso <pablo@netfilter.org>
Paul Burton <paul.burton@mips.com>
Paul Menzel <pmenzel@molgen.mpg.de>
Peter Zijlstra (Intel) <peterz@infradead.org>
Peter Zijlstra <peterz@infradead.org>
Ping-Ke Shih <pkshih@realtek.com>
Prashanth Prakash <pprakash@codeaurora.org>
Qing Xia <xiaqing17@hisilicon.com>
Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Randy Dunlap <rdunlap@infradead.org>
Renato Westphal <renato@opensourcerouting.org>
Richard Weinberger <richard@nod.at>
Sabrina Dubroca <sd@queasysnail.net>
Saeed Mahameed <saeedm@mellanox.com>
Santosh Shilimkar <santosh.shilimkar@oracle.com>
Scott Bauer <scott.bauer@intel.com>
Sean Young <sean@mess.org>
Sedat Dilek <sedat.dilek@gmail.com>
Serge Semin <fancer.lancer@gmail.com>
Shay Agroskin <shayag@mellanox.com>
Shivam Kakkar <shivam543@gmail.com> # 8723BE on 4.18-rc1
Shivasharan S <shivasharan.srikanteshwara@broadcom.com>
Stefan Agner <stefan@agner.ch>
Stefan Haberland <sth@linux.vnet.ibm.com>
Stefan Wahren <stefan.wahren@i2se.com>
Stephan Mueller <smueller@chronox.de>
Stephen Hemminger <sthemmin@microsoft.com>
Steve Wise <swise@opengridcomputing.com>
Steven Rostedt (VMware) <rostedt@goodmis.org>
Sudarsana Reddy Kalluru <Sudarsana.Kalluru@cavium.com>
Sudip Mukherjee <sudipm.mukherjee@gmail.com>
Takashi Iwai <tiwai@suse.de>
Tejun Heo <tj@kernel.org>
Tetsuo Handa <penguin-kernel@i-love.sakura.ne.jp>
Theodore Ts'o <tytso@mit.edu>
Thierry Reding <treding@nvidia.com>
Thomas Gleixner <tglx@linutronix.de>
Tomas Bortoli <tomasbortoli@gmail.com>
Ulf Hansson <ulf.hansson@linaro.org>
Vlastimil Babka <vbabka@suse.cz>
Will Deacon <will.deacon@arm.com>
Willem de Bruijn <willemb@google.com>
Wolfram Sang <wsa@the-dreams.de>
x00270170 <xiaqing17@hisilicon.com>
Xin Long <lucien.xin@gmail.com>
Yandong Zhao <yandong77520@gmail.com>
Yuchung Cheng <ycheng@google.com>
jobs:
build-amd64-xsm pass
build-arm64-xsm pass
build-i386-xsm pass
build-amd64 pass
build-arm64 pass
build-armhf pass
build-i386 pass
build-amd64-libvirt pass
build-arm64-libvirt pass
build-armhf-libvirt pass
build-i386-libvirt pass
build-amd64-pvops pass
build-arm64-pvops pass
build-armhf-pvops pass
build-i386-pvops pass
build-amd64-rumprun pass
build-i386-rumprun pass
test-amd64-amd64-xl pass
test-arm64-arm64-xl pass
test-armhf-armhf-xl pass
test-amd64-i386-xl fail
test-amd64-amd64-xl-qemut-debianhvm-amd64-xsm pass
test-amd64-i386-xl-qemut-debianhvm-amd64-xsm pass
test-amd64-amd64-libvirt-qemuu-debianhvm-amd64-xsm pass
test-amd64-i386-libvirt-qemuu-debianhvm-amd64-xsm pass
test-amd64-amd64-xl-qemuu-debianhvm-amd64-xsm fail
test-amd64-i386-xl-qemuu-debianhvm-amd64-xsm pass
test-amd64-amd64-xl-qemut-stubdom-debianhvm-amd64-xsm pass
test-amd64-i386-xl-qemut-stubdom-debianhvm-amd64-xsm pass
test-amd64-amd64-libvirt-xsm pass
test-arm64-arm64-libvirt-xsm pass
test-amd64-i386-libvirt-xsm pass
test-amd64-amd64-xl-xsm pass
test-arm64-arm64-xl-xsm pass
test-amd64-i386-xl-xsm pass
test-amd64-amd64-qemuu-nested-amd fail
test-amd64-amd64-xl-pvhv2-amd fail
test-amd64-i386-qemut-rhel6hvm-amd fail
test-amd64-i386-qemuu-rhel6hvm-amd pass
test-amd64-amd64-xl-qemut-debianhvm-amd64 pass
test-amd64-i386-xl-qemut-debianhvm-amd64 pass
test-amd64-amd64-xl-qemuu-debianhvm-amd64 pass
test-amd64-i386-xl-qemuu-debianhvm-amd64 pass
test-amd64-i386-freebsd10-amd64 pass
test-amd64-amd64-xl-qemuu-ovmf-amd64 pass
test-amd64-i386-xl-qemuu-ovmf-amd64 pass
test-amd64-amd64-rumprun-amd64 pass
test-amd64-amd64-xl-qemut-win7-amd64 fail
test-amd64-i386-xl-qemut-win7-amd64 fail
test-amd64-amd64-xl-qemuu-win7-amd64 fail
test-amd64-i386-xl-qemuu-win7-amd64 fail
test-amd64-amd64-xl-qemut-ws16-amd64 fail
test-amd64-i386-xl-qemut-ws16-amd64 fail
test-amd64-amd64-xl-qemuu-ws16-amd64 fail
test-amd64-i386-xl-qemuu-ws16-amd64 fail
test-armhf-armhf-xl-arndale pass
test-amd64-amd64-xl-credit2 pass
test-arm64-arm64-xl-credit2 pass
test-armhf-armhf-xl-credit2 broken
test-armhf-armhf-xl-cubietruck pass
test-amd64-amd64-xl-qemuu-dmrestrict-amd64-dmrestrict fail
test-amd64-i386-xl-qemuu-dmrestrict-amd64-dmrestrict fail
test-amd64-amd64-examine pass
test-arm64-arm64-examine pass
test-armhf-armhf-examine pass
test-amd64-i386-examine pass
test-amd64-i386-freebsd10-i386 pass
test-amd64-i386-rumprun-i386 pass
test-amd64-amd64-xl-qemut-win10-i386 fail
test-amd64-i386-xl-qemut-win10-i386 fail
test-amd64-amd64-xl-qemuu-win10-i386 fail
test-amd64-i386-xl-qemuu-win10-i386 fail
test-amd64-amd64-qemuu-nested-intel pass
test-amd64-amd64-xl-pvhv2-intel pass
test-amd64-i386-qemut-rhel6hvm-intel pass
test-amd64-i386-qemuu-rhel6hvm-intel pass
test-amd64-amd64-libvirt pass
test-armhf-armhf-libvirt pass
test-amd64-i386-libvirt pass
test-amd64-amd64-xl-multivcpu pass
test-armhf-armhf-xl-multivcpu pass
test-amd64-amd64-pair pass
test-amd64-i386-pair pass
test-amd64-amd64-libvirt-pair pass
test-amd64-i386-libvirt-pair pass
test-amd64-amd64-amd64-pvgrub pass
test-amd64-amd64-i386-pvgrub pass
test-amd64-amd64-xl-pvshim fail
test-amd64-i386-xl-pvshim fail
test-amd64-amd64-pygrub pass
test-amd64-amd64-xl-qcow2 pass
test-armhf-armhf-libvirt-raw pass
test-amd64-i386-xl-raw pass
test-amd64-amd64-xl-rtds pass
test-armhf-armhf-xl-rtds pass
test-amd64-amd64-xl-qemuu-debianhvm-amd64-shadow fail
test-amd64-i386-xl-qemuu-debianhvm-amd64-shadow pass
test-amd64-amd64-xl-shadow pass
test-amd64-i386-xl-shadow pass
test-amd64-amd64-libvirt-vhd pass
test-armhf-armhf-xl-vhd pass
------------------------------------------------------------
sg-report-flight on osstest.test-lab.xenproject.org
logs: /home/logs/logs
images: /home/logs/images
Logs, config files, etc. are available at
http://logs.test-lab.xenproject.org/osstest/logs
Explanation of these reports, and of osstest in general, is at
http://xenbits.xen.org/gitweb/?p=osstest.git;a=blob;f=README.email;hb=master
http://xenbits.xen.org/gitweb/?p=osstest.git;a=blob;f=README;hb=master
Test harness code can be found at
http://xenbits.xen.org/gitweb?p=osstest.git;a=summary
broken-job test-armhf-armhf-xl-credit2 broken
broken-step test-armhf-armhf-xl-credit2 host-install(4)
Not pushing.
(No revision log; it would be 4657 lines long.)
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel
^ permalink raw reply
* Re: [PATCH v3 bpf-next 6/8] xdp: Add a flag for disabling napi_direct of xdp_return_frame in xdp_mem_info
From: Toshiaki Makita @ 2018-07-24 4:02 UTC (permalink / raw)
To: Jakub Kicinski
Cc: Toshiaki Makita, netdev, Alexei Starovoitov, Daniel Borkmann,
Jesper Dangaard Brouer
In-Reply-To: <20180723203814.009d661d@cakuba.netronome.com>
On 2018/07/24 12:38, Jakub Kicinski wrote:
> On Tue, 24 Jul 2018 11:43:11 +0900, Toshiaki Makita wrote:
>> On 2018/07/24 10:22, Jakub Kicinski wrote:
>>> On Mon, 23 Jul 2018 00:13:06 +0900, Toshiaki Makita wrote:
>>>> From: Toshiaki Makita <makita.toshiaki@lab.ntt.co.jp>
>>>>
>>>> We need some mechanism to disable napi_direct on calling
>>>> xdp_return_frame_rx_napi() from some context.
>>>> When veth gets support of XDP_REDIRECT, it will redirects packets which
>>>> are redirected from other devices. On redirection veth will reuse
>>>> xdp_mem_info of the redirection source device to make return_frame work.
>>>> But in this case .ndo_xdp_xmit() called from veth redirection uses
>>>> xdp_mem_info which is not guarded by NAPI, because the .ndo_xdp_xmit is
>>>> not called directly from the rxq which owns the xdp_mem_info.
>>>>
>>>> This approach introduces a flag in xdp_mem_info to indicate that
>>>> napi_direct should be disabled even when _rx_napi variant is used.
>>>>
>>>> Signed-off-by: Toshiaki Makita <makita.toshiaki@lab.ntt.co.jp>
>>>
>>> To be clear - you will modify flags of the original source device if it
>>> ever redirected a frame to a software device like veth? Seems a bit
>>> heavy handed. The xdp_return_frame_rx_napi() is only really used on
>>> error paths, but still.. Also as you note the original NAPI can run
>>> concurrently with your veth dest one, but also with NAPIs of other veth
>>> devices, so the non-atomic xdp.rxq->mem.flags |= XDP_MEM_RF_NO_DIRECT;
>>> makes me worried.
>>
>> xdp_mem_info is copied in xdp_frame in convert_to_xdp_frame() so the
>> field is local to the frame. Changing flags affects only the frame.
>> xdp.rxq is local to NAPI thread, so no worries about atomicity.
>
> Ah, right! mem_info used to be just 8B, now it would be 12B.
> Alternatively we could perhaps add this info to struct redirect_info,
> through xdp_do_redirect() to avoid the per-frame cost. I'm not sure
> that's better.
OK, let me check if this works.
--
Toshiaki Makita
^ permalink raw reply
* [PATCH 4/5] fsi: Add cfam char devices
From: Benjamin Herrenschmidt @ 2018-07-24 5:05 UTC (permalink / raw)
To: openbmc
Cc: Joel Stanley, linux-aspeed, Andrew Jeffery, Eddie James,
Linux Kernel Mailing List, Benjamin Herrenschmidt
In-Reply-To: <20180724050519.31920-1-benh@kernel.crashing.org>
This aims to deprecate the "raw" sysfs file used for directly
accessing the CFAM and instead use a char device like the
other sub drivers.
Since it reworks the slave creation code and adds a cfam device
type, we also use the opportunity to convert the attributes
to attribute groups and add a couple more.
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
---
drivers/fsi/fsi-core.c | 264 +++++++++++++++++++++++++++++++++--------
1 file changed, 213 insertions(+), 51 deletions(-)
diff --git a/drivers/fsi/fsi-core.c b/drivers/fsi/fsi-core.c
index faa1760a5a40..dea5bd48acc5 100644
--- a/drivers/fsi/fsi-core.c
+++ b/drivers/fsi/fsi-core.c
@@ -11,6 +11,11 @@
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
+ *
+ * TODO:
+ * - Rework topology
+ * - s/chip_id/chip_loc
+ * - s/cfam/chip (cfam_id -> chip_id etc...)
*/
#include <linux/crc4.h>
@@ -21,6 +26,9 @@
#include <linux/of.h>
#include <linux/slab.h>
#include <linux/bitops.h>
+#include <linux/cdev.h>
+#include <linux/fs.h>
+#include <linux/uaccess.h>
#include "fsi-master.h"
@@ -78,8 +86,11 @@ static DEFINE_IDA(master_ida);
struct fsi_slave {
struct device dev;
struct fsi_master *master;
- int id;
- int link;
+ struct cdev cdev;
+ int cdev_idx;
+ int id; /* FSI address */
+ int link; /* FSI link# */
+ u32 cfam_id;
int chip_id;
uint32_t size; /* size of slave address space */
u8 t_send_delay;
@@ -607,29 +618,6 @@ static const struct bin_attribute fsi_slave_raw_attr = {
.write = fsi_slave_sysfs_raw_write,
};
-static ssize_t fsi_slave_sysfs_term_write(struct file *file,
- struct kobject *kobj, struct bin_attribute *attr,
- char *buf, loff_t off, size_t count)
-{
- struct fsi_slave *slave = to_fsi_slave(kobj_to_dev(kobj));
- struct fsi_master *master = slave->master;
-
- if (!master->term)
- return -ENODEV;
-
- master->term(master, slave->link, slave->id);
- return count;
-}
-
-static const struct bin_attribute fsi_slave_term_attr = {
- .attr = {
- .name = "term",
- .mode = 0200,
- },
- .size = 0,
- .write = fsi_slave_sysfs_term_write,
-};
-
static void fsi_slave_release(struct device *dev)
{
struct fsi_slave *slave = to_fsi_slave(dev);
@@ -682,6 +670,127 @@ static struct device_node *fsi_slave_find_of_node(struct fsi_master *master,
return NULL;
}
+static ssize_t cfam_read(struct file *filep, char __user *buf, size_t count,
+ loff_t *offset)
+{
+ struct fsi_slave *slave = filep->private_data;
+ size_t total_len, read_len;
+ loff_t off = *offset;
+ ssize_t rc;
+
+ if (off < 0)
+ return -EINVAL;
+
+ if (off > 0xffffffff || count > 0xffffffff || off + count > 0xffffffff)
+ return -EINVAL;
+
+ for (total_len = 0; total_len < count; total_len += read_len) {
+ __be32 data;
+
+ read_len = min_t(size_t, count, 4);
+ read_len -= off & 0x3;
+
+ rc = fsi_slave_read(slave, off, &data, read_len);
+ if (rc)
+ goto fail;
+ rc = copy_to_user(buf + total_len, &data, read_len);
+ if (rc) {
+ rc = -EFAULT;
+ goto fail;
+ }
+ off += read_len;
+ }
+ rc = count;
+ fail:
+ *offset = off;
+ return count;
+}
+
+static ssize_t cfam_write(struct file *filep, const char __user *buf,
+ size_t count, loff_t *offset)
+{
+ struct fsi_slave *slave = filep->private_data;
+ size_t total_len, write_len;
+ loff_t off = *offset;
+ ssize_t rc;
+
+
+ if (off < 0)
+ return -EINVAL;
+
+ if (off > 0xffffffff || count > 0xffffffff || off + count > 0xffffffff)
+ return -EINVAL;
+
+ for (total_len = 0; total_len < count; total_len += write_len) {
+ __be32 data;
+
+ write_len = min_t(size_t, count, 4);
+ write_len -= off & 0x3;
+
+ rc = copy_from_user(&data, buf + total_len, write_len);
+ if (rc) {
+ rc = -EFAULT;
+ goto fail;
+ }
+ rc = fsi_slave_write(slave, off, &data, write_len);
+ if (rc)
+ goto fail;
+ off += write_len;
+ }
+ rc = count;
+ fail:
+ *offset = off;
+ return count;
+}
+
+static loff_t cfam_llseek(struct file *file, loff_t offset, int whence)
+{
+ switch (whence) {
+ case SEEK_CUR:
+ break;
+ case SEEK_SET:
+ file->f_pos = offset;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return offset;
+}
+
+static int cfam_open(struct inode *inode, struct file *file)
+{
+ struct fsi_slave *slave = container_of(inode->i_cdev, struct fsi_slave, cdev);
+
+ file->private_data = slave;
+
+ return 0;
+}
+
+static const struct file_operations cfam_fops = {
+ .owner = THIS_MODULE,
+ .open = cfam_open,
+ .llseek = cfam_llseek,
+ .read = cfam_read,
+ .write = cfam_write,
+};
+
+static ssize_t send_term_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct fsi_slave *slave = to_fsi_slave(dev);
+ struct fsi_master *master = slave->master;
+
+ if (!master->term)
+ return -ENODEV;
+
+ master->term(master, slave->link, slave->id);
+ return count;
+}
+
+static DEVICE_ATTR_WO(send_term);
+
static ssize_t slave_send_echo_show(struct device *dev,
struct device_attribute *attr,
char *buf)
@@ -737,6 +846,52 @@ static ssize_t chip_id_show(struct device *dev,
static DEVICE_ATTR_RO(chip_id);
+static ssize_t cfam_id_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct fsi_slave *slave = to_fsi_slave(dev);
+
+ return sprintf(buf, "0x%x\n", slave->cfam_id);
+}
+
+static DEVICE_ATTR_RO(cfam_id);
+
+static struct attribute *cfam_attr[] = {
+ &dev_attr_send_echo_delays.attr,
+ &dev_attr_chip_id.attr,
+ &dev_attr_cfam_id.attr,
+ &dev_attr_send_term.attr,
+ NULL,
+};
+
+static const struct attribute_group cfam_attr_group = {
+ .attrs = cfam_attr,
+};
+
+static const struct attribute_group *cfam_attr_groups[] = {
+ &cfam_attr_group,
+ NULL,
+};
+
+static char *cfam_devnode(struct device *dev, umode_t *mode,
+ kuid_t *uid, kgid_t *gid)
+{
+ struct fsi_slave *slave = to_fsi_slave(dev);
+
+#ifdef CONFIG_FSI_NEW_DEV_NODE
+ return kasprintf(GFP_KERNEL, "fsi/cfam%d", slave->cdev_idx);
+#else
+ return kasprintf(GFP_KERNEL, "cfam%d", slave->cdev_idx);
+#endif
+}
+
+static const struct device_type cfam_type = {
+ .name = "cfam",
+ .devnode = cfam_devnode,
+ .groups = cfam_attr_groups
+};
+
static char *fsi_cdev_devnode(struct device *dev, umode_t *mode,
kuid_t *uid, kgid_t *gid)
{
@@ -808,7 +963,7 @@ EXPORT_SYMBOL_GPL(fsi_free_minor);
static int fsi_slave_init(struct fsi_master *master, int link, uint8_t id)
{
- uint32_t chip_id;
+ uint32_t cfam_id;
struct fsi_slave *slave;
uint8_t crc;
__be32 data, llmode;
@@ -826,17 +981,17 @@ static int fsi_slave_init(struct fsi_master *master, int link, uint8_t id)
link, id, rc);
return -ENODEV;
}
- chip_id = be32_to_cpu(data);
+ cfam_id = be32_to_cpu(data);
- crc = crc4(0, chip_id, 32);
+ crc = crc4(0, cfam_id, 32);
if (crc) {
- dev_warn(&master->dev, "slave %02x:%02x invalid chip id CRC!\n",
+ dev_warn(&master->dev, "slave %02x:%02x invalid cfam id CRC!\n",
link, id);
return -EIO;
}
dev_dbg(&master->dev, "fsi: found chip %08x at %02x:%02x:%02x\n",
- chip_id, master->idx, link, id);
+ cfam_id, master->idx, link, id);
/* If we're behind a master that doesn't provide a self-running bus
* clock, put the slave into async mode
@@ -859,10 +1014,14 @@ static int fsi_slave_init(struct fsi_master *master, int link, uint8_t id)
if (!slave)
return -ENOMEM;
- slave->master = master;
+ dev_set_name(&slave->dev, "slave@%02x:%02x", link, id);
+ slave->dev.type = &cfam_type;
slave->dev.parent = &master->dev;
slave->dev.of_node = fsi_slave_find_of_node(master, link, id);
slave->dev.release = fsi_slave_release;
+ device_initialize(&slave->dev);
+ slave->cfam_id = cfam_id;
+ slave->master = master;
slave->link = link;
slave->id = id;
slave->size = FSI_SLAVE_SIZE_23b;
@@ -877,6 +1036,21 @@ static int fsi_slave_init(struct fsi_master *master, int link, uint8_t id)
slave->chip_id = prop;
}
+
+ /* Allocate a minor in the FSI space */
+ rc = __fsi_get_new_minor(slave, fsi_dev_cfam, &slave->dev.devt,
+ &slave->cdev_idx);
+ if (rc)
+ goto err_free;
+
+ /* Create chardev for userspace access */
+ cdev_init(&slave->cdev, &cfam_fops);
+ rc = cdev_device_add(&slave->cdev, &slave->dev);
+ if (rc) {
+ dev_err(&slave->dev, "Error %d creating slave device\n", rc);
+ goto err_free;
+ }
+
rc = fsi_slave_set_smode(slave);
if (rc) {
dev_warn(&master->dev,
@@ -890,30 +1064,11 @@ static int fsi_slave_init(struct fsi_master *master, int link, uint8_t id)
slave->t_send_delay,
slave->t_echo_delay);
- dev_set_name(&slave->dev, "slave@%02x:%02x", link, id);
- rc = device_register(&slave->dev);
- if (rc < 0) {
- dev_warn(&master->dev, "failed to create slave device: %d\n",
- rc);
- put_device(&slave->dev);
- return rc;
- }
-
+ /* Legacy raw file -> to be removed */
rc = device_create_bin_file(&slave->dev, &fsi_slave_raw_attr);
if (rc)
dev_warn(&slave->dev, "failed to create raw attr: %d\n", rc);
- rc = device_create_bin_file(&slave->dev, &fsi_slave_term_attr);
- if (rc)
- dev_warn(&slave->dev, "failed to create term attr: %d\n", rc);
-
- rc = device_create_file(&slave->dev, &dev_attr_send_echo_delays);
- if (rc)
- dev_warn(&slave->dev, "failed to create delay attr: %d\n", rc);
-
- rc = device_create_file(&slave->dev, &dev_attr_chip_id);
- if (rc)
- dev_warn(&slave->dev, "failed to create chip id: %d\n", rc);
rc = fsi_slave_scan(slave);
if (rc)
@@ -921,6 +1076,10 @@ static int fsi_slave_init(struct fsi_master *master, int link, uint8_t id)
rc);
return rc;
+
+ err_free:
+ put_device(&slave->dev);
+ return rc;
}
/* FSI master support */
@@ -1029,7 +1188,10 @@ static int fsi_slave_remove_device(struct device *dev, void *arg)
static int fsi_master_remove_slave(struct device *dev, void *arg)
{
+ struct fsi_slave *slave = to_fsi_slave(dev);
+
device_for_each_child(dev, NULL, fsi_slave_remove_device);
+ cdev_device_del(&slave->cdev, &slave->dev);
put_device(dev);
return 0;
}
--
2.17.1
^ permalink raw reply related
* [PATCH 2/5] fsi: sbefifo: Convert to use the new chardev
From: Benjamin Herrenschmidt @ 2018-07-24 5:05 UTC (permalink / raw)
To: openbmc
Cc: Joel Stanley, linux-aspeed, Andrew Jeffery, Eddie James,
Linux Kernel Mailing List, Benjamin Herrenschmidt
In-Reply-To: <20180724050519.31920-1-benh@kernel.crashing.org>
This converts FSI sbefifo to use the new fsi-core controlled
chardev allocator and use a real cdev instead of a miscdev.
One side effect is to fix the object lifetime by removing
the use of devm_kzalloc() for something that contains kobjects,
and using proper reference counting.
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
---
drivers/fsi/fsi-sbefifo.c | 84 +++++++++++++++++++++++++--------------
1 file changed, 55 insertions(+), 29 deletions(-)
diff --git a/drivers/fsi/fsi-sbefifo.c b/drivers/fsi/fsi-sbefifo.c
index 33a5d9a43a07..8a185f53c9d8 100644
--- a/drivers/fsi/fsi-sbefifo.c
+++ b/drivers/fsi/fsi-sbefifo.c
@@ -17,9 +17,8 @@
#include <linux/fs.h>
#include <linux/fsi.h>
#include <linux/fsi-sbefifo.h>
-#include <linux/idr.h>
#include <linux/kernel.h>
-#include <linux/miscdevice.h>
+#include <linux/cdev.h>
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/of.h>
@@ -118,11 +117,11 @@ struct sbefifo {
uint32_t magic;
#define SBEFIFO_MAGIC 0x53424546 /* "SBEF" */
struct fsi_device *fsi_dev;
- struct miscdevice mdev;
+ struct device dev;
+ struct cdev cdev;
struct mutex lock;
- char name[32];
- int idx;
bool broken;
+ bool dead;
bool async_ffdc;
};
@@ -133,9 +132,9 @@ struct sbefifo_user {
size_t pending_len;
};
-static DEFINE_IDA(sbefifo_ida);
static DEFINE_MUTEX(sbefifo_ffdc_mutex);
+
static void __sbefifo_dump_ffdc(struct device *dev, const __be32 *ffdc,
size_t ffdc_sz, bool internal)
{
@@ -667,6 +666,9 @@ static int __sbefifo_submit(struct sbefifo *sbefifo,
struct device *dev = &sbefifo->fsi_dev->dev;
int rc;
+ if (sbefifo->dead)
+ return -ENODEV;
+
if (cmd_len < 2 || be32_to_cpu(command[0]) != cmd_len) {
dev_vdbg(dev, "Invalid command len %zd (header: %d)\n",
cmd_len, be32_to_cpu(command[0]));
@@ -751,8 +753,7 @@ EXPORT_SYMBOL_GPL(sbefifo_submit);
*/
static int sbefifo_user_open(struct inode *inode, struct file *file)
{
- struct sbefifo *sbefifo = container_of(file->private_data,
- struct sbefifo, mdev);
+ struct sbefifo *sbefifo = container_of(inode->i_cdev, struct sbefifo, cdev);
struct sbefifo_user *user;
user = kzalloc(sizeof(struct sbefifo_user), GFP_KERNEL);
@@ -889,6 +890,14 @@ static const struct file_operations sbefifo_fops = {
.release = sbefifo_user_release,
};
+static void sbefifo_free(struct device *dev)
+{
+ struct sbefifo *sbefifo = container_of(dev, struct sbefifo, dev);
+
+ put_device(&sbefifo->fsi_dev->dev);
+ kfree(sbefifo);
+}
+
/*
* Probe/remove
*/
@@ -900,15 +909,23 @@ static int sbefifo_probe(struct device *dev)
struct device_node *np;
struct platform_device *child;
char child_name[32];
- int rc, child_idx = 0;
+ int rc, didx, child_idx = 0;
dev_dbg(dev, "Found sbefifo device\n");
- sbefifo = devm_kzalloc(dev, sizeof(*sbefifo), GFP_KERNEL);
+ sbefifo = kzalloc(sizeof(*sbefifo), GFP_KERNEL);
if (!sbefifo)
return -ENOMEM;
+
+ /* Grab a reference to the device (parent of our cdev), we'll drop it later */
+ if (!get_device(dev)) {
+ return -ENODEV;
+ kfree(sbefifo);
+ }
+
sbefifo->magic = SBEFIFO_MAGIC;
sbefifo->fsi_dev = fsi_dev;
+ dev_set_drvdata(dev, sbefifo);
mutex_init(&sbefifo->lock);
/*
@@ -919,28 +936,30 @@ static int sbefifo_probe(struct device *dev)
if (rc && rc != -ESHUTDOWN)
dev_err(dev, "Initial HW cleanup failed, will retry later\n");
- sbefifo->idx = ida_simple_get(&sbefifo_ida, 1, INT_MAX, GFP_KERNEL);
- snprintf(sbefifo->name, sizeof(sbefifo->name), "sbefifo%d",
- sbefifo->idx);
+ /* Create chardev for userspace access */
+ sbefifo->dev.type = &fsi_cdev_type;
+ sbefifo->dev.parent = dev;
+ sbefifo->dev.release = sbefifo_free;
+ device_initialize(&sbefifo->dev);
- dev_set_drvdata(dev, sbefifo);
+ /* Allocate a minor in the FSI space */
+ rc = fsi_get_new_minor(fsi_dev, fsi_dev_sbefifo, &sbefifo->dev.devt, &didx);
+ if (rc)
+ goto err;
- /* Create misc chardev for userspace access */
- sbefifo->mdev.minor = MISC_DYNAMIC_MINOR;
- sbefifo->mdev.fops = &sbefifo_fops;
- sbefifo->mdev.name = sbefifo->name;
- sbefifo->mdev.parent = dev;
- rc = misc_register(&sbefifo->mdev);
+ dev_set_name(&sbefifo->dev, "sbefifo%d", didx);
+ cdev_init(&sbefifo->cdev, &sbefifo_fops);
+ rc = cdev_device_add(&sbefifo->cdev, &sbefifo->dev);
if (rc) {
- dev_err(dev, "Failed to register miscdevice: %d\n", rc);
- ida_simple_remove(&sbefifo_ida, sbefifo->idx);
- return rc;
+ dev_err(dev, "Error %d creating char device %s\n",
+ rc, dev_name(&sbefifo->dev));
+ goto err_free_minor;
}
/* Create platform devs for dts child nodes (occ, etc) */
for_each_available_child_of_node(dev->of_node, np) {
snprintf(child_name, sizeof(child_name), "%s-dev%d",
- sbefifo->name, child_idx++);
+ dev_name(&sbefifo->dev), child_idx++);
child = of_platform_device_create(np, child_name, dev);
if (!child)
dev_warn(dev, "failed to create child %s dev\n",
@@ -948,6 +967,11 @@ static int sbefifo_probe(struct device *dev)
}
return 0;
+ err_free_minor:
+ fsi_free_minor(sbefifo->dev.devt);
+ err:
+ put_device(&sbefifo->dev);
+ return rc;
}
static int sbefifo_unregister_child(struct device *dev, void *data)
@@ -967,10 +991,14 @@ static int sbefifo_remove(struct device *dev)
dev_dbg(dev, "Removing sbefifo device...\n");
- misc_deregister(&sbefifo->mdev);
- device_for_each_child(dev, NULL, sbefifo_unregister_child);
+ mutex_lock(&sbefifo->lock);
+ sbefifo->dead = true;
+ mutex_unlock(&sbefifo->lock);
- ida_simple_remove(&sbefifo_ida, sbefifo->idx);
+ cdev_device_del(&sbefifo->cdev, &sbefifo->dev);
+ fsi_free_minor(sbefifo->dev.devt);
+ device_for_each_child(dev, NULL, sbefifo_unregister_child);
+ put_device(&sbefifo->dev);
return 0;
}
@@ -1001,8 +1029,6 @@ static int sbefifo_init(void)
static void sbefifo_exit(void)
{
fsi_driver_unregister(&sbefifo_drv);
-
- ida_destroy(&sbefifo_ida);
}
module_init(sbefifo_init);
--
2.17.1
^ permalink raw reply related
* [PATCH 1/5] fsi: Add new central chardev support
From: Benjamin Herrenschmidt @ 2018-07-24 5:05 UTC (permalink / raw)
To: openbmc
Cc: Joel Stanley, linux-aspeed, Andrew Jeffery, Eddie James,
Linux Kernel Mailing List, Benjamin Herrenschmidt
In-Reply-To: <20180724050519.31920-1-benh@kernel.crashing.org>
The various FSI devices (sbefifo, occ, scom, more to come)
currently use misc devices.
This is problematic as the minor device space for misc is
limited and there can be a lot of them. Also it limits our
ability to move them to a dedicated /dev/fsi directory or
to be smart about device naming and numbering.
It also means we have IDAs on every single of these drivers
This creates a common fsi "device_type" for the optional
/dev/fsi grouping and a dev_t allocator for all FSI devices.
"Legacy" devices get to use a backward compatible numbering
scheme (as long as chip id <16 and there's only one copy
of a given unit type per chip).
A single major number and a single IDA are shared for all
FSI devices.
This doesn't convert the FSI device drivers to use the new
scheme yet, they will be converted individually.
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
---
drivers/fsi/Kconfig | 15 +++++++
drivers/fsi/fsi-core.c | 95 +++++++++++++++++++++++++++++++++++++++++-
include/linux/fsi.h | 12 +++++-
3 files changed, 119 insertions(+), 3 deletions(-)
diff --git a/drivers/fsi/Kconfig b/drivers/fsi/Kconfig
index 8d82b1e60514..af3a20dd5aa4 100644
--- a/drivers/fsi/Kconfig
+++ b/drivers/fsi/Kconfig
@@ -12,6 +12,21 @@ menuconfig FSI
if FSI
+config FSI_NEW_DEV_NODE
+ bool "Create '/dev/fsi' directory for char devices"
+ default n
+ ---help---
+ This option causes char devices created for FSI devices to be
+ located under a common /dev/fsi/ directory. Set to N unless your
+ userspace has been updated to handle the new location.
+
+ Additionally, it also causes the char device names to be offset
+ by one so that chip 0 will have /dev/scom1 and chip1 /dev/scom2
+ to match old userspace expectations.
+
+ New userspace will use udev rules to generate predictable access
+ symlinks in /dev/fsi/by-path when this option is enabled.
+
config FSI_MASTER_GPIO
tristate "GPIO-based FSI master"
depends on GPIOLIB
diff --git a/drivers/fsi/fsi-core.c b/drivers/fsi/fsi-core.c
index eab6c5c4990e..faa1760a5a40 100644
--- a/drivers/fsi/fsi-core.c
+++ b/drivers/fsi/fsi-core.c
@@ -92,6 +92,13 @@ struct fsi_slave {
static const int slave_retries = 2;
static int discard_errors;
+static dev_t fsi_base_dev;
+static DEFINE_IDA(fsi_minor_ida);
+#define FSI_CHAR_MAX_DEVICES 0x1000
+
+/* Legacy /dev numbering: 4 devices per chip, 16 chips */
+#define FSI_CHAR_LEGACY_TOP 64
+
static int fsi_master_read(struct fsi_master *master, int link,
uint8_t slave_id, uint32_t addr, void *val, size_t size);
static int fsi_master_write(struct fsi_master *master, int link,
@@ -627,6 +634,7 @@ static void fsi_slave_release(struct device *dev)
{
struct fsi_slave *slave = to_fsi_slave(dev);
+ fsi_free_minor(slave->dev.devt);
of_node_put(dev->of_node);
kfree(slave);
}
@@ -729,6 +737,75 @@ static ssize_t chip_id_show(struct device *dev,
static DEVICE_ATTR_RO(chip_id);
+static char *fsi_cdev_devnode(struct device *dev, umode_t *mode,
+ kuid_t *uid, kgid_t *gid)
+{
+#ifdef CONFIG_FSI_NEW_DEV_NODE
+ return kasprintf(GFP_KERNEL, "fsi/%s", dev_name(dev));
+#else
+ return kasprintf(GFP_KERNEL, "%s", dev_name(dev));
+#endif
+}
+
+const struct device_type fsi_cdev_type = {
+ .name = "fsi-cdev",
+ .devnode = fsi_cdev_devnode,
+};
+EXPORT_SYMBOL_GPL(fsi_cdev_type);
+
+/* Backward compatible /dev/ numbering in "old style" mode */
+static int fsi_adjust_index(int index)
+{
+#ifdef CONFIG_FSI_NEW_DEV_NODE
+ return index;
+#else
+ return index + 1;
+#endif
+}
+
+static int __fsi_get_new_minor(struct fsi_slave *slave, enum fsi_dev_type type,
+ dev_t *out_dev, int *out_index)
+{
+ int cid = slave->chip_id;
+ int id;
+
+ /* Check if we qualify for legacy numbering */
+ if (cid >= 0 && cid < 16 && type < 4) {
+ /* Try reserving the legacy number */
+ id = (cid << 4) | type;
+ id = ida_simple_get(&fsi_minor_ida, id, id + 1, GFP_KERNEL);
+ if (id >= 0) {
+ *out_index = fsi_adjust_index(cid);
+ *out_dev = fsi_base_dev + id;
+ return 0;
+ }
+ /* Other failure */
+ if (id != -ENOSPC)
+ return id;
+ /* Fallback to non-legacy allocation */
+ }
+ id = ida_simple_get(&fsi_minor_ida, FSI_CHAR_LEGACY_TOP,
+ FSI_CHAR_MAX_DEVICES, GFP_KERNEL);
+ if (id < 0)
+ return id;
+ *out_index = fsi_adjust_index(id);
+ *out_dev = fsi_base_dev + id;
+ return 0;
+}
+
+int fsi_get_new_minor(struct fsi_device *fdev, enum fsi_dev_type type,
+ dev_t *out_dev, int *out_index)
+{
+ return __fsi_get_new_minor(fdev->slave, type, out_dev, out_index);
+}
+EXPORT_SYMBOL_GPL(fsi_get_new_minor);
+
+void fsi_free_minor(dev_t dev)
+{
+ ida_simple_remove(&fsi_minor_ida, MINOR(dev));
+}
+EXPORT_SYMBOL_GPL(fsi_free_minor);
+
static int fsi_slave_init(struct fsi_master *master, int link, uint8_t id)
{
uint32_t chip_id;
@@ -953,7 +1030,7 @@ static int fsi_slave_remove_device(struct device *dev, void *arg)
static int fsi_master_remove_slave(struct device *dev, void *arg)
{
device_for_each_child(dev, NULL, fsi_slave_remove_device);
- device_unregister(dev);
+ put_device(dev);
return 0;
}
@@ -1091,13 +1168,27 @@ EXPORT_SYMBOL_GPL(fsi_bus_type);
static int __init fsi_init(void)
{
- return bus_register(&fsi_bus_type);
+ int rc;
+
+ rc = alloc_chrdev_region(&fsi_base_dev, 0, FSI_CHAR_MAX_DEVICES, "fsi");
+ if (rc)
+ return rc;
+ rc = bus_register(&fsi_bus_type);
+ if (rc)
+ goto fail_bus;
+ return 0;
+
+ fail_bus:
+ unregister_chrdev_region(fsi_base_dev, FSI_CHAR_MAX_DEVICES);
+ return rc;
}
postcore_initcall(fsi_init);
static void fsi_exit(void)
{
bus_unregister(&fsi_bus_type);
+ unregister_chrdev_region(fsi_base_dev, FSI_CHAR_MAX_DEVICES);
+ ida_destroy(&fsi_minor_ida);
}
module_exit(fsi_exit);
module_param(discard_errors, int, 0664);
diff --git a/include/linux/fsi.h b/include/linux/fsi.h
index 141fd38d061f..ec3be0d5b786 100644
--- a/include/linux/fsi.h
+++ b/include/linux/fsi.h
@@ -76,8 +76,18 @@ extern int fsi_slave_read(struct fsi_slave *slave, uint32_t addr,
extern int fsi_slave_write(struct fsi_slave *slave, uint32_t addr,
const void *val, size_t size);
+extern struct bus_type fsi_bus_type;
+extern const struct device_type fsi_cdev_type;
+enum fsi_dev_type {
+ fsi_dev_cfam,
+ fsi_dev_sbefifo,
+ fsi_dev_scom,
+ fsi_dev_occ
+};
-extern struct bus_type fsi_bus_type;
+extern int fsi_get_new_minor(struct fsi_device *fdev, enum fsi_dev_type type,
+ dev_t *out_dev, int *out_index);
+extern void fsi_free_minor(dev_t dev);
#endif /* LINUX_FSI_H */
--
2.17.1
^ permalink raw reply related
* [PATCH 3/5] fsi: scom: Convert to use the new chardev
From: Benjamin Herrenschmidt @ 2018-07-24 5:05 UTC (permalink / raw)
To: openbmc
Cc: Joel Stanley, linux-aspeed, Andrew Jeffery, Eddie James,
Linux Kernel Mailing List, Benjamin Herrenschmidt
In-Reply-To: <20180724050519.31920-1-benh@kernel.crashing.org>
This converts FSI scom to use the new fsi-core controlled
chardev allocator and use a real cdev instead of a miscdev.
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
---
drivers/fsi/fsi-scom.c | 130 +++++++++++++++++++++++++----------------
1 file changed, 80 insertions(+), 50 deletions(-)
diff --git a/drivers/fsi/fsi-scom.c b/drivers/fsi/fsi-scom.c
index 39c74351f1bf..0f303a700f69 100644
--- a/drivers/fsi/fsi-scom.c
+++ b/drivers/fsi/fsi-scom.c
@@ -20,9 +20,8 @@
#include <linux/fs.h>
#include <linux/uaccess.h>
#include <linux/slab.h>
-#include <linux/miscdevice.h>
+#include <linux/cdev.h>
#include <linux/list.h>
-#include <linux/idr.h>
#include <uapi/linux/fsi.h>
@@ -77,18 +76,12 @@
struct scom_device {
struct list_head link;
struct fsi_device *fsi_dev;
- struct miscdevice mdev;
+ struct device dev;
+ struct cdev cdev;
struct mutex lock;
- char name[32];
- int idx;
+ bool dead;
};
-#define to_scom_dev(x) container_of((x), struct scom_device, mdev)
-
-static struct list_head scom_devices;
-
-static DEFINE_IDA(scom_ida);
-
static int __put_scom(struct scom_device *scom_dev, uint64_t value,
uint32_t addr, uint32_t *status)
{
@@ -374,9 +367,7 @@ static int get_scom(struct scom_device *scom, uint64_t *value,
static ssize_t scom_read(struct file *filep, char __user *buf, size_t len,
loff_t *offset)
{
- struct miscdevice *mdev =
- (struct miscdevice *)filep->private_data;
- struct scom_device *scom = to_scom_dev(mdev);
+ struct scom_device *scom = filep->private_data;
struct device *dev = &scom->fsi_dev->dev;
uint64_t val;
int rc;
@@ -385,7 +376,10 @@ static ssize_t scom_read(struct file *filep, char __user *buf, size_t len,
return -EINVAL;
mutex_lock(&scom->lock);
- rc = get_scom(scom, &val, *offset);
+ if (scom->dead)
+ rc = -ENODEV;
+ else
+ rc = get_scom(scom, &val, *offset);
mutex_unlock(&scom->lock);
if (rc) {
dev_dbg(dev, "get_scom fail:%d\n", rc);
@@ -403,8 +397,7 @@ static ssize_t scom_write(struct file *filep, const char __user *buf,
size_t len, loff_t *offset)
{
int rc;
- struct miscdevice *mdev = filep->private_data;
- struct scom_device *scom = to_scom_dev(mdev);
+ struct scom_device *scom = filep->private_data;
struct device *dev = &scom->fsi_dev->dev;
uint64_t val;
@@ -418,7 +411,10 @@ static ssize_t scom_write(struct file *filep, const char __user *buf,
}
mutex_lock(&scom->lock);
- rc = put_scom(scom, val, *offset);
+ if (scom->dead)
+ rc = -ENODEV;
+ else
+ rc = put_scom(scom, val, *offset);
mutex_unlock(&scom->lock);
if (rc) {
dev_dbg(dev, "put_scom failed with:%d\n", rc);
@@ -532,12 +528,15 @@ static int scom_check(struct scom_device *scom, void __user *argp)
static long scom_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
- struct miscdevice *mdev = file->private_data;
- struct scom_device *scom = to_scom_dev(mdev);
+ struct scom_device *scom = file->private_data;
void __user *argp = (void __user *)arg;
int rc = -ENOTTY;
mutex_lock(&scom->lock);
+ if (scom->dead) {
+ mutex_unlock(&scom->lock);
+ return -ENODEV;
+ }
switch(cmd) {
case FSI_SCOM_CHECK:
rc = scom_check(scom, argp);
@@ -556,48 +555,88 @@ static long scom_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
return rc;
}
+static int scom_open(struct inode *inode, struct file *file)
+{
+ struct scom_device *scom = container_of(inode->i_cdev, struct scom_device, cdev);
+
+ file->private_data = scom;
+
+ return 0;
+}
+
static const struct file_operations scom_fops = {
.owner = THIS_MODULE,
+ .open = scom_open,
.llseek = scom_llseek,
.read = scom_read,
.write = scom_write,
.unlocked_ioctl = scom_ioctl,
};
+static void scom_free(struct device *dev)
+{
+ struct scom_device *scom = container_of(dev, struct scom_device, dev);
+
+ put_device(&scom->fsi_dev->dev);
+ kfree(scom);
+}
+
static int scom_probe(struct device *dev)
{
struct fsi_device *fsi_dev = to_fsi_dev(dev);
struct scom_device *scom;
+ int rc, didx;
- scom = devm_kzalloc(dev, sizeof(*scom), GFP_KERNEL);
+ scom = kzalloc(sizeof(*scom), GFP_KERNEL);
if (!scom)
return -ENOMEM;
-
+ dev_set_drvdata(dev, scom);
mutex_init(&scom->lock);
- scom->idx = ida_simple_get(&scom_ida, 1, INT_MAX, GFP_KERNEL);
- snprintf(scom->name, sizeof(scom->name), "scom%d", scom->idx);
- scom->fsi_dev = fsi_dev;
- scom->mdev.minor = MISC_DYNAMIC_MINOR;
- scom->mdev.fops = &scom_fops;
- scom->mdev.name = scom->name;
- scom->mdev.parent = dev;
- list_add(&scom->link, &scom_devices);
-
- return misc_register(&scom->mdev);
+
+ /* Grab a reference to the device (parent of our cdev), we'll drop it later */
+ if (!get_device(dev)) {
+ kfree(scom);
+ return -ENODEV;
+ }
+
+ /* Create chardev for userspace access */
+ scom->dev.type = &fsi_cdev_type;
+ scom->dev.parent = dev;
+ scom->dev.release = scom_free;
+ device_initialize(&scom->dev);
+
+ /* Allocate a minor in the FSI space */
+ rc = fsi_get_new_minor(fsi_dev, fsi_dev_scom, &scom->dev.devt, &didx);
+ if (rc)
+ goto err;
+
+ dev_set_name(&scom->dev, "scom%d", didx);
+ cdev_init(&scom->cdev, &scom_fops);
+ rc = cdev_device_add(&scom->cdev, &scom->dev);
+ if (rc) {
+ dev_err(dev, "Error %d creating char device %s\n",
+ rc, dev_name(&scom->dev));
+ goto err_free_minor;
+ }
+
+ return 0;
+ err_free_minor:
+ fsi_free_minor(scom->dev.devt);
+ err:
+ put_device(&scom->dev);
+ return rc;
}
static int scom_remove(struct device *dev)
{
- struct scom_device *scom, *scom_tmp;
- struct fsi_device *fsi_dev = to_fsi_dev(dev);
+ struct scom_device *scom = dev_get_drvdata(dev);
- list_for_each_entry_safe(scom, scom_tmp, &scom_devices, link) {
- if (scom->fsi_dev == fsi_dev) {
- list_del(&scom->link);
- ida_simple_remove(&scom_ida, scom->idx);
- misc_deregister(&scom->mdev);
- }
- }
+ mutex_lock(&scom->lock);
+ scom->dead = true;
+ mutex_unlock(&scom->lock);
+ cdev_device_del(&scom->cdev, &scom->dev);
+ fsi_free_minor(scom->dev.devt);
+ put_device(&scom->dev);
return 0;
}
@@ -622,20 +661,11 @@ static struct fsi_driver scom_drv = {
static int scom_init(void)
{
- INIT_LIST_HEAD(&scom_devices);
return fsi_driver_register(&scom_drv);
}
static void scom_exit(void)
{
- struct list_head *pos;
- struct scom_device *scom;
-
- list_for_each(pos, &scom_devices) {
- scom = list_entry(pos, struct scom_device, link);
- misc_deregister(&scom->mdev);
- devm_kfree(&scom->fsi_dev->dev, scom);
- }
fsi_driver_unregister(&scom_drv);
}
--
2.17.1
^ permalink raw reply related
* [PATCH 0/5] fsi: Convert misc devs to proper chardevs and more
From: Benjamin Herrenschmidt @ 2018-07-24 5:05 UTC (permalink / raw)
To: openbmc
Cc: Joel Stanley, linux-aspeed, Andrew Jeffery, Eddie James,
Linux Kernel Mailing List
This converts the various FSI devices from misc dev to chardev,
as there can potentially be too much of them for misc devs limited
minors, and because there are some lifetime issues with the current
support.
This provide a common infrastructure to allocate an FSI major and
distribute minors in a way that keeps it compatible with existing
userspace. A new representation grouping FSI devices under a
/dev/fsi directory is optinally provided, which will work in
conjunction with new udev scripts aimed at providing fixed ID
based symlinks.
A side effect of those conversions is to fix some object lifetime
issues caused by a mixup between devm_kzalloc and proper object
lifetime.
This series also adds a /dev{/fsi}/cfamN chardev for raw CFAM
access that will superseed the existing "raw" sysfs file.
Finally there's also a locking fix to avoid horrible mixups if
the "rescan" file is poked while a rescan is already in progress.
^ permalink raw reply
* [PATCH 5/5] fsi: Prevent multiple concurrent rescans
From: Benjamin Herrenschmidt @ 2018-07-24 5:05 UTC (permalink / raw)
To: linux-aspeed
In-Reply-To: <20180724050519.31920-1-benh@kernel.crashing.org>
The bus scanning process isn't terribly good at parallel attempts
at rescanning the same bus. Let's have a per-master mutex protecting
the scanning process.
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
---
drivers/fsi/fsi-core.c | 16 ++++++++++++++--
drivers/fsi/fsi-master.h | 2 ++
2 files changed, 16 insertions(+), 2 deletions(-)
diff --git a/drivers/fsi/fsi-core.c b/drivers/fsi/fsi-core.c
index dea5bd48acc5..2c31563fdcae 100644
--- a/drivers/fsi/fsi-core.c
+++ b/drivers/fsi/fsi-core.c
@@ -1203,8 +1203,14 @@ static void fsi_master_unscan(struct fsi_master *master)
int fsi_master_rescan(struct fsi_master *master)
{
+ int rc;
+
+ mutex_lock(&master->scan_lock);
fsi_master_unscan(master);
- return fsi_master_scan(master);
+ rc = fsi_master_scan(master);
+ mutex_unlock(&master->scan_lock);
+
+ return rc;
}
EXPORT_SYMBOL_GPL(fsi_master_rescan);
@@ -1240,6 +1246,7 @@ int fsi_master_register(struct fsi_master *master)
int rc;
struct device_node *np;
+ mutex_init(&master->scan_lock);
master->idx = ida_simple_get(&master_ida, 0, INT_MAX, GFP_KERNEL);
dev_set_name(&master->dev, "fsi%d", master->idx);
@@ -1264,8 +1271,11 @@ int fsi_master_register(struct fsi_master *master)
}
np = dev_of_node(&master->dev);
- if (!of_property_read_bool(np, "no-scan-on-init"))
+ if (!of_property_read_bool(np, "no-scan-on-init")) {
+ mutex_lock(&master->scan_lock);
fsi_master_scan(master);
+ mutex_unlock(&master->scan_lock);
+ }
return 0;
}
@@ -1278,7 +1288,9 @@ void fsi_master_unregister(struct fsi_master *master)
master->idx = -1;
}
+ mutex_lock(&master->scan_lock);
fsi_master_unscan(master);
+ mutex_unlock(&master->scan_lock);
device_unregister(&master->dev);
}
EXPORT_SYMBOL_GPL(fsi_master_unregister);
diff --git a/drivers/fsi/fsi-master.h b/drivers/fsi/fsi-master.h
index f653f75da7be..040a7d4cf717 100644
--- a/drivers/fsi/fsi-master.h
+++ b/drivers/fsi/fsi-master.h
@@ -18,6 +18,7 @@
#define DRIVERS_FSI_MASTER_H
#include <linux/device.h>
+#include <linux/mutex.h>
/* Various protocol delays */
#define FSI_ECHO_DELAY_CLOCKS 16 /* Number clocks for echo delay */
@@ -59,6 +60,7 @@ struct fsi_master {
int idx;
int n_links;
int flags;
+ struct mutex scan_lock;
int (*read)(struct fsi_master *, int link, uint8_t id,
uint32_t addr, void *val, size_t size);
int (*write)(struct fsi_master *, int link, uint8_t id,
--
2.17.1
^ permalink raw reply related
* [PATCH 4/5] fsi: Add cfam char devices
From: Benjamin Herrenschmidt @ 2018-07-24 5:05 UTC (permalink / raw)
To: linux-aspeed
In-Reply-To: <20180724050519.31920-1-benh@kernel.crashing.org>
This aims to deprecate the "raw" sysfs file used for directly
accessing the CFAM and instead use a char device like the
other sub drivers.
Since it reworks the slave creation code and adds a cfam device
type, we also use the opportunity to convert the attributes
to attribute groups and add a couple more.
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
---
drivers/fsi/fsi-core.c | 264 +++++++++++++++++++++++++++++++++--------
1 file changed, 213 insertions(+), 51 deletions(-)
diff --git a/drivers/fsi/fsi-core.c b/drivers/fsi/fsi-core.c
index faa1760a5a40..dea5bd48acc5 100644
--- a/drivers/fsi/fsi-core.c
+++ b/drivers/fsi/fsi-core.c
@@ -11,6 +11,11 @@
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
+ *
+ * TODO:
+ * - Rework topology
+ * - s/chip_id/chip_loc
+ * - s/cfam/chip (cfam_id -> chip_id etc...)
*/
#include <linux/crc4.h>
@@ -21,6 +26,9 @@
#include <linux/of.h>
#include <linux/slab.h>
#include <linux/bitops.h>
+#include <linux/cdev.h>
+#include <linux/fs.h>
+#include <linux/uaccess.h>
#include "fsi-master.h"
@@ -78,8 +86,11 @@ static DEFINE_IDA(master_ida);
struct fsi_slave {
struct device dev;
struct fsi_master *master;
- int id;
- int link;
+ struct cdev cdev;
+ int cdev_idx;
+ int id; /* FSI address */
+ int link; /* FSI link# */
+ u32 cfam_id;
int chip_id;
uint32_t size; /* size of slave address space */
u8 t_send_delay;
@@ -607,29 +618,6 @@ static const struct bin_attribute fsi_slave_raw_attr = {
.write = fsi_slave_sysfs_raw_write,
};
-static ssize_t fsi_slave_sysfs_term_write(struct file *file,
- struct kobject *kobj, struct bin_attribute *attr,
- char *buf, loff_t off, size_t count)
-{
- struct fsi_slave *slave = to_fsi_slave(kobj_to_dev(kobj));
- struct fsi_master *master = slave->master;
-
- if (!master->term)
- return -ENODEV;
-
- master->term(master, slave->link, slave->id);
- return count;
-}
-
-static const struct bin_attribute fsi_slave_term_attr = {
- .attr = {
- .name = "term",
- .mode = 0200,
- },
- .size = 0,
- .write = fsi_slave_sysfs_term_write,
-};
-
static void fsi_slave_release(struct device *dev)
{
struct fsi_slave *slave = to_fsi_slave(dev);
@@ -682,6 +670,127 @@ static struct device_node *fsi_slave_find_of_node(struct fsi_master *master,
return NULL;
}
+static ssize_t cfam_read(struct file *filep, char __user *buf, size_t count,
+ loff_t *offset)
+{
+ struct fsi_slave *slave = filep->private_data;
+ size_t total_len, read_len;
+ loff_t off = *offset;
+ ssize_t rc;
+
+ if (off < 0)
+ return -EINVAL;
+
+ if (off > 0xffffffff || count > 0xffffffff || off + count > 0xffffffff)
+ return -EINVAL;
+
+ for (total_len = 0; total_len < count; total_len += read_len) {
+ __be32 data;
+
+ read_len = min_t(size_t, count, 4);
+ read_len -= off & 0x3;
+
+ rc = fsi_slave_read(slave, off, &data, read_len);
+ if (rc)
+ goto fail;
+ rc = copy_to_user(buf + total_len, &data, read_len);
+ if (rc) {
+ rc = -EFAULT;
+ goto fail;
+ }
+ off += read_len;
+ }
+ rc = count;
+ fail:
+ *offset = off;
+ return count;
+}
+
+static ssize_t cfam_write(struct file *filep, const char __user *buf,
+ size_t count, loff_t *offset)
+{
+ struct fsi_slave *slave = filep->private_data;
+ size_t total_len, write_len;
+ loff_t off = *offset;
+ ssize_t rc;
+
+
+ if (off < 0)
+ return -EINVAL;
+
+ if (off > 0xffffffff || count > 0xffffffff || off + count > 0xffffffff)
+ return -EINVAL;
+
+ for (total_len = 0; total_len < count; total_len += write_len) {
+ __be32 data;
+
+ write_len = min_t(size_t, count, 4);
+ write_len -= off & 0x3;
+
+ rc = copy_from_user(&data, buf + total_len, write_len);
+ if (rc) {
+ rc = -EFAULT;
+ goto fail;
+ }
+ rc = fsi_slave_write(slave, off, &data, write_len);
+ if (rc)
+ goto fail;
+ off += write_len;
+ }
+ rc = count;
+ fail:
+ *offset = off;
+ return count;
+}
+
+static loff_t cfam_llseek(struct file *file, loff_t offset, int whence)
+{
+ switch (whence) {
+ case SEEK_CUR:
+ break;
+ case SEEK_SET:
+ file->f_pos = offset;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return offset;
+}
+
+static int cfam_open(struct inode *inode, struct file *file)
+{
+ struct fsi_slave *slave = container_of(inode->i_cdev, struct fsi_slave, cdev);
+
+ file->private_data = slave;
+
+ return 0;
+}
+
+static const struct file_operations cfam_fops = {
+ .owner = THIS_MODULE,
+ .open = cfam_open,
+ .llseek = cfam_llseek,
+ .read = cfam_read,
+ .write = cfam_write,
+};
+
+static ssize_t send_term_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct fsi_slave *slave = to_fsi_slave(dev);
+ struct fsi_master *master = slave->master;
+
+ if (!master->term)
+ return -ENODEV;
+
+ master->term(master, slave->link, slave->id);
+ return count;
+}
+
+static DEVICE_ATTR_WO(send_term);
+
static ssize_t slave_send_echo_show(struct device *dev,
struct device_attribute *attr,
char *buf)
@@ -737,6 +846,52 @@ static ssize_t chip_id_show(struct device *dev,
static DEVICE_ATTR_RO(chip_id);
+static ssize_t cfam_id_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct fsi_slave *slave = to_fsi_slave(dev);
+
+ return sprintf(buf, "0x%x\n", slave->cfam_id);
+}
+
+static DEVICE_ATTR_RO(cfam_id);
+
+static struct attribute *cfam_attr[] = {
+ &dev_attr_send_echo_delays.attr,
+ &dev_attr_chip_id.attr,
+ &dev_attr_cfam_id.attr,
+ &dev_attr_send_term.attr,
+ NULL,
+};
+
+static const struct attribute_group cfam_attr_group = {
+ .attrs = cfam_attr,
+};
+
+static const struct attribute_group *cfam_attr_groups[] = {
+ &cfam_attr_group,
+ NULL,
+};
+
+static char *cfam_devnode(struct device *dev, umode_t *mode,
+ kuid_t *uid, kgid_t *gid)
+{
+ struct fsi_slave *slave = to_fsi_slave(dev);
+
+#ifdef CONFIG_FSI_NEW_DEV_NODE
+ return kasprintf(GFP_KERNEL, "fsi/cfam%d", slave->cdev_idx);
+#else
+ return kasprintf(GFP_KERNEL, "cfam%d", slave->cdev_idx);
+#endif
+}
+
+static const struct device_type cfam_type = {
+ .name = "cfam",
+ .devnode = cfam_devnode,
+ .groups = cfam_attr_groups
+};
+
static char *fsi_cdev_devnode(struct device *dev, umode_t *mode,
kuid_t *uid, kgid_t *gid)
{
@@ -808,7 +963,7 @@ EXPORT_SYMBOL_GPL(fsi_free_minor);
static int fsi_slave_init(struct fsi_master *master, int link, uint8_t id)
{
- uint32_t chip_id;
+ uint32_t cfam_id;
struct fsi_slave *slave;
uint8_t crc;
__be32 data, llmode;
@@ -826,17 +981,17 @@ static int fsi_slave_init(struct fsi_master *master, int link, uint8_t id)
link, id, rc);
return -ENODEV;
}
- chip_id = be32_to_cpu(data);
+ cfam_id = be32_to_cpu(data);
- crc = crc4(0, chip_id, 32);
+ crc = crc4(0, cfam_id, 32);
if (crc) {
- dev_warn(&master->dev, "slave %02x:%02x invalid chip id CRC!\n",
+ dev_warn(&master->dev, "slave %02x:%02x invalid cfam id CRC!\n",
link, id);
return -EIO;
}
dev_dbg(&master->dev, "fsi: found chip %08x at %02x:%02x:%02x\n",
- chip_id, master->idx, link, id);
+ cfam_id, master->idx, link, id);
/* If we're behind a master that doesn't provide a self-running bus
* clock, put the slave into async mode
@@ -859,10 +1014,14 @@ static int fsi_slave_init(struct fsi_master *master, int link, uint8_t id)
if (!slave)
return -ENOMEM;
- slave->master = master;
+ dev_set_name(&slave->dev, "slave@%02x:%02x", link, id);
+ slave->dev.type = &cfam_type;
slave->dev.parent = &master->dev;
slave->dev.of_node = fsi_slave_find_of_node(master, link, id);
slave->dev.release = fsi_slave_release;
+ device_initialize(&slave->dev);
+ slave->cfam_id = cfam_id;
+ slave->master = master;
slave->link = link;
slave->id = id;
slave->size = FSI_SLAVE_SIZE_23b;
@@ -877,6 +1036,21 @@ static int fsi_slave_init(struct fsi_master *master, int link, uint8_t id)
slave->chip_id = prop;
}
+
+ /* Allocate a minor in the FSI space */
+ rc = __fsi_get_new_minor(slave, fsi_dev_cfam, &slave->dev.devt,
+ &slave->cdev_idx);
+ if (rc)
+ goto err_free;
+
+ /* Create chardev for userspace access */
+ cdev_init(&slave->cdev, &cfam_fops);
+ rc = cdev_device_add(&slave->cdev, &slave->dev);
+ if (rc) {
+ dev_err(&slave->dev, "Error %d creating slave device\n", rc);
+ goto err_free;
+ }
+
rc = fsi_slave_set_smode(slave);
if (rc) {
dev_warn(&master->dev,
@@ -890,30 +1064,11 @@ static int fsi_slave_init(struct fsi_master *master, int link, uint8_t id)
slave->t_send_delay,
slave->t_echo_delay);
- dev_set_name(&slave->dev, "slave@%02x:%02x", link, id);
- rc = device_register(&slave->dev);
- if (rc < 0) {
- dev_warn(&master->dev, "failed to create slave device: %d\n",
- rc);
- put_device(&slave->dev);
- return rc;
- }
-
+ /* Legacy raw file -> to be removed */
rc = device_create_bin_file(&slave->dev, &fsi_slave_raw_attr);
if (rc)
dev_warn(&slave->dev, "failed to create raw attr: %d\n", rc);
- rc = device_create_bin_file(&slave->dev, &fsi_slave_term_attr);
- if (rc)
- dev_warn(&slave->dev, "failed to create term attr: %d\n", rc);
-
- rc = device_create_file(&slave->dev, &dev_attr_send_echo_delays);
- if (rc)
- dev_warn(&slave->dev, "failed to create delay attr: %d\n", rc);
-
- rc = device_create_file(&slave->dev, &dev_attr_chip_id);
- if (rc)
- dev_warn(&slave->dev, "failed to create chip id: %d\n", rc);
rc = fsi_slave_scan(slave);
if (rc)
@@ -921,6 +1076,10 @@ static int fsi_slave_init(struct fsi_master *master, int link, uint8_t id)
rc);
return rc;
+
+ err_free:
+ put_device(&slave->dev);
+ return rc;
}
/* FSI master support */
@@ -1029,7 +1188,10 @@ static int fsi_slave_remove_device(struct device *dev, void *arg)
static int fsi_master_remove_slave(struct device *dev, void *arg)
{
+ struct fsi_slave *slave = to_fsi_slave(dev);
+
device_for_each_child(dev, NULL, fsi_slave_remove_device);
+ cdev_device_del(&slave->cdev, &slave->dev);
put_device(dev);
return 0;
}
--
2.17.1
^ permalink raw reply related
* [PATCH 3/5] fsi: scom: Convert to use the new chardev
From: Benjamin Herrenschmidt @ 2018-07-24 5:05 UTC (permalink / raw)
To: linux-aspeed
In-Reply-To: <20180724050519.31920-1-benh@kernel.crashing.org>
This converts FSI scom to use the new fsi-core controlled
chardev allocator and use a real cdev instead of a miscdev.
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
---
drivers/fsi/fsi-scom.c | 130 +++++++++++++++++++++++++----------------
1 file changed, 80 insertions(+), 50 deletions(-)
diff --git a/drivers/fsi/fsi-scom.c b/drivers/fsi/fsi-scom.c
index 39c74351f1bf..0f303a700f69 100644
--- a/drivers/fsi/fsi-scom.c
+++ b/drivers/fsi/fsi-scom.c
@@ -20,9 +20,8 @@
#include <linux/fs.h>
#include <linux/uaccess.h>
#include <linux/slab.h>
-#include <linux/miscdevice.h>
+#include <linux/cdev.h>
#include <linux/list.h>
-#include <linux/idr.h>
#include <uapi/linux/fsi.h>
@@ -77,18 +76,12 @@
struct scom_device {
struct list_head link;
struct fsi_device *fsi_dev;
- struct miscdevice mdev;
+ struct device dev;
+ struct cdev cdev;
struct mutex lock;
- char name[32];
- int idx;
+ bool dead;
};
-#define to_scom_dev(x) container_of((x), struct scom_device, mdev)
-
-static struct list_head scom_devices;
-
-static DEFINE_IDA(scom_ida);
-
static int __put_scom(struct scom_device *scom_dev, uint64_t value,
uint32_t addr, uint32_t *status)
{
@@ -374,9 +367,7 @@ static int get_scom(struct scom_device *scom, uint64_t *value,
static ssize_t scom_read(struct file *filep, char __user *buf, size_t len,
loff_t *offset)
{
- struct miscdevice *mdev =
- (struct miscdevice *)filep->private_data;
- struct scom_device *scom = to_scom_dev(mdev);
+ struct scom_device *scom = filep->private_data;
struct device *dev = &scom->fsi_dev->dev;
uint64_t val;
int rc;
@@ -385,7 +376,10 @@ static ssize_t scom_read(struct file *filep, char __user *buf, size_t len,
return -EINVAL;
mutex_lock(&scom->lock);
- rc = get_scom(scom, &val, *offset);
+ if (scom->dead)
+ rc = -ENODEV;
+ else
+ rc = get_scom(scom, &val, *offset);
mutex_unlock(&scom->lock);
if (rc) {
dev_dbg(dev, "get_scom fail:%d\n", rc);
@@ -403,8 +397,7 @@ static ssize_t scom_write(struct file *filep, const char __user *buf,
size_t len, loff_t *offset)
{
int rc;
- struct miscdevice *mdev = filep->private_data;
- struct scom_device *scom = to_scom_dev(mdev);
+ struct scom_device *scom = filep->private_data;
struct device *dev = &scom->fsi_dev->dev;
uint64_t val;
@@ -418,7 +411,10 @@ static ssize_t scom_write(struct file *filep, const char __user *buf,
}
mutex_lock(&scom->lock);
- rc = put_scom(scom, val, *offset);
+ if (scom->dead)
+ rc = -ENODEV;
+ else
+ rc = put_scom(scom, val, *offset);
mutex_unlock(&scom->lock);
if (rc) {
dev_dbg(dev, "put_scom failed with:%d\n", rc);
@@ -532,12 +528,15 @@ static int scom_check(struct scom_device *scom, void __user *argp)
static long scom_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
- struct miscdevice *mdev = file->private_data;
- struct scom_device *scom = to_scom_dev(mdev);
+ struct scom_device *scom = file->private_data;
void __user *argp = (void __user *)arg;
int rc = -ENOTTY;
mutex_lock(&scom->lock);
+ if (scom->dead) {
+ mutex_unlock(&scom->lock);
+ return -ENODEV;
+ }
switch(cmd) {
case FSI_SCOM_CHECK:
rc = scom_check(scom, argp);
@@ -556,48 +555,88 @@ static long scom_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
return rc;
}
+static int scom_open(struct inode *inode, struct file *file)
+{
+ struct scom_device *scom = container_of(inode->i_cdev, struct scom_device, cdev);
+
+ file->private_data = scom;
+
+ return 0;
+}
+
static const struct file_operations scom_fops = {
.owner = THIS_MODULE,
+ .open = scom_open,
.llseek = scom_llseek,
.read = scom_read,
.write = scom_write,
.unlocked_ioctl = scom_ioctl,
};
+static void scom_free(struct device *dev)
+{
+ struct scom_device *scom = container_of(dev, struct scom_device, dev);
+
+ put_device(&scom->fsi_dev->dev);
+ kfree(scom);
+}
+
static int scom_probe(struct device *dev)
{
struct fsi_device *fsi_dev = to_fsi_dev(dev);
struct scom_device *scom;
+ int rc, didx;
- scom = devm_kzalloc(dev, sizeof(*scom), GFP_KERNEL);
+ scom = kzalloc(sizeof(*scom), GFP_KERNEL);
if (!scom)
return -ENOMEM;
-
+ dev_set_drvdata(dev, scom);
mutex_init(&scom->lock);
- scom->idx = ida_simple_get(&scom_ida, 1, INT_MAX, GFP_KERNEL);
- snprintf(scom->name, sizeof(scom->name), "scom%d", scom->idx);
- scom->fsi_dev = fsi_dev;
- scom->mdev.minor = MISC_DYNAMIC_MINOR;
- scom->mdev.fops = &scom_fops;
- scom->mdev.name = scom->name;
- scom->mdev.parent = dev;
- list_add(&scom->link, &scom_devices);
-
- return misc_register(&scom->mdev);
+
+ /* Grab a reference to the device (parent of our cdev), we'll drop it later */
+ if (!get_device(dev)) {
+ kfree(scom);
+ return -ENODEV;
+ }
+
+ /* Create chardev for userspace access */
+ scom->dev.type = &fsi_cdev_type;
+ scom->dev.parent = dev;
+ scom->dev.release = scom_free;
+ device_initialize(&scom->dev);
+
+ /* Allocate a minor in the FSI space */
+ rc = fsi_get_new_minor(fsi_dev, fsi_dev_scom, &scom->dev.devt, &didx);
+ if (rc)
+ goto err;
+
+ dev_set_name(&scom->dev, "scom%d", didx);
+ cdev_init(&scom->cdev, &scom_fops);
+ rc = cdev_device_add(&scom->cdev, &scom->dev);
+ if (rc) {
+ dev_err(dev, "Error %d creating char device %s\n",
+ rc, dev_name(&scom->dev));
+ goto err_free_minor;
+ }
+
+ return 0;
+ err_free_minor:
+ fsi_free_minor(scom->dev.devt);
+ err:
+ put_device(&scom->dev);
+ return rc;
}
static int scom_remove(struct device *dev)
{
- struct scom_device *scom, *scom_tmp;
- struct fsi_device *fsi_dev = to_fsi_dev(dev);
+ struct scom_device *scom = dev_get_drvdata(dev);
- list_for_each_entry_safe(scom, scom_tmp, &scom_devices, link) {
- if (scom->fsi_dev == fsi_dev) {
- list_del(&scom->link);
- ida_simple_remove(&scom_ida, scom->idx);
- misc_deregister(&scom->mdev);
- }
- }
+ mutex_lock(&scom->lock);
+ scom->dead = true;
+ mutex_unlock(&scom->lock);
+ cdev_device_del(&scom->cdev, &scom->dev);
+ fsi_free_minor(scom->dev.devt);
+ put_device(&scom->dev);
return 0;
}
@@ -622,20 +661,11 @@ static struct fsi_driver scom_drv = {
static int scom_init(void)
{
- INIT_LIST_HEAD(&scom_devices);
return fsi_driver_register(&scom_drv);
}
static void scom_exit(void)
{
- struct list_head *pos;
- struct scom_device *scom;
-
- list_for_each(pos, &scom_devices) {
- scom = list_entry(pos, struct scom_device, link);
- misc_deregister(&scom->mdev);
- devm_kfree(&scom->fsi_dev->dev, scom);
- }
fsi_driver_unregister(&scom_drv);
}
--
2.17.1
^ permalink raw reply related
* [PATCH 2/5] fsi: sbefifo: Convert to use the new chardev
From: Benjamin Herrenschmidt @ 2018-07-24 5:05 UTC (permalink / raw)
To: linux-aspeed
In-Reply-To: <20180724050519.31920-1-benh@kernel.crashing.org>
This converts FSI sbefifo to use the new fsi-core controlled
chardev allocator and use a real cdev instead of a miscdev.
One side effect is to fix the object lifetime by removing
the use of devm_kzalloc() for something that contains kobjects,
and using proper reference counting.
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
---
drivers/fsi/fsi-sbefifo.c | 84 +++++++++++++++++++++++++--------------
1 file changed, 55 insertions(+), 29 deletions(-)
diff --git a/drivers/fsi/fsi-sbefifo.c b/drivers/fsi/fsi-sbefifo.c
index 33a5d9a43a07..8a185f53c9d8 100644
--- a/drivers/fsi/fsi-sbefifo.c
+++ b/drivers/fsi/fsi-sbefifo.c
@@ -17,9 +17,8 @@
#include <linux/fs.h>
#include <linux/fsi.h>
#include <linux/fsi-sbefifo.h>
-#include <linux/idr.h>
#include <linux/kernel.h>
-#include <linux/miscdevice.h>
+#include <linux/cdev.h>
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/of.h>
@@ -118,11 +117,11 @@ struct sbefifo {
uint32_t magic;
#define SBEFIFO_MAGIC 0x53424546 /* "SBEF" */
struct fsi_device *fsi_dev;
- struct miscdevice mdev;
+ struct device dev;
+ struct cdev cdev;
struct mutex lock;
- char name[32];
- int idx;
bool broken;
+ bool dead;
bool async_ffdc;
};
@@ -133,9 +132,9 @@ struct sbefifo_user {
size_t pending_len;
};
-static DEFINE_IDA(sbefifo_ida);
static DEFINE_MUTEX(sbefifo_ffdc_mutex);
+
static void __sbefifo_dump_ffdc(struct device *dev, const __be32 *ffdc,
size_t ffdc_sz, bool internal)
{
@@ -667,6 +666,9 @@ static int __sbefifo_submit(struct sbefifo *sbefifo,
struct device *dev = &sbefifo->fsi_dev->dev;
int rc;
+ if (sbefifo->dead)
+ return -ENODEV;
+
if (cmd_len < 2 || be32_to_cpu(command[0]) != cmd_len) {
dev_vdbg(dev, "Invalid command len %zd (header: %d)\n",
cmd_len, be32_to_cpu(command[0]));
@@ -751,8 +753,7 @@ EXPORT_SYMBOL_GPL(sbefifo_submit);
*/
static int sbefifo_user_open(struct inode *inode, struct file *file)
{
- struct sbefifo *sbefifo = container_of(file->private_data,
- struct sbefifo, mdev);
+ struct sbefifo *sbefifo = container_of(inode->i_cdev, struct sbefifo, cdev);
struct sbefifo_user *user;
user = kzalloc(sizeof(struct sbefifo_user), GFP_KERNEL);
@@ -889,6 +890,14 @@ static const struct file_operations sbefifo_fops = {
.release = sbefifo_user_release,
};
+static void sbefifo_free(struct device *dev)
+{
+ struct sbefifo *sbefifo = container_of(dev, struct sbefifo, dev);
+
+ put_device(&sbefifo->fsi_dev->dev);
+ kfree(sbefifo);
+}
+
/*
* Probe/remove
*/
@@ -900,15 +909,23 @@ static int sbefifo_probe(struct device *dev)
struct device_node *np;
struct platform_device *child;
char child_name[32];
- int rc, child_idx = 0;
+ int rc, didx, child_idx = 0;
dev_dbg(dev, "Found sbefifo device\n");
- sbefifo = devm_kzalloc(dev, sizeof(*sbefifo), GFP_KERNEL);
+ sbefifo = kzalloc(sizeof(*sbefifo), GFP_KERNEL);
if (!sbefifo)
return -ENOMEM;
+
+ /* Grab a reference to the device (parent of our cdev), we'll drop it later */
+ if (!get_device(dev)) {
+ return -ENODEV;
+ kfree(sbefifo);
+ }
+
sbefifo->magic = SBEFIFO_MAGIC;
sbefifo->fsi_dev = fsi_dev;
+ dev_set_drvdata(dev, sbefifo);
mutex_init(&sbefifo->lock);
/*
@@ -919,28 +936,30 @@ static int sbefifo_probe(struct device *dev)
if (rc && rc != -ESHUTDOWN)
dev_err(dev, "Initial HW cleanup failed, will retry later\n");
- sbefifo->idx = ida_simple_get(&sbefifo_ida, 1, INT_MAX, GFP_KERNEL);
- snprintf(sbefifo->name, sizeof(sbefifo->name), "sbefifo%d",
- sbefifo->idx);
+ /* Create chardev for userspace access */
+ sbefifo->dev.type = &fsi_cdev_type;
+ sbefifo->dev.parent = dev;
+ sbefifo->dev.release = sbefifo_free;
+ device_initialize(&sbefifo->dev);
- dev_set_drvdata(dev, sbefifo);
+ /* Allocate a minor in the FSI space */
+ rc = fsi_get_new_minor(fsi_dev, fsi_dev_sbefifo, &sbefifo->dev.devt, &didx);
+ if (rc)
+ goto err;
- /* Create misc chardev for userspace access */
- sbefifo->mdev.minor = MISC_DYNAMIC_MINOR;
- sbefifo->mdev.fops = &sbefifo_fops;
- sbefifo->mdev.name = sbefifo->name;
- sbefifo->mdev.parent = dev;
- rc = misc_register(&sbefifo->mdev);
+ dev_set_name(&sbefifo->dev, "sbefifo%d", didx);
+ cdev_init(&sbefifo->cdev, &sbefifo_fops);
+ rc = cdev_device_add(&sbefifo->cdev, &sbefifo->dev);
if (rc) {
- dev_err(dev, "Failed to register miscdevice: %d\n", rc);
- ida_simple_remove(&sbefifo_ida, sbefifo->idx);
- return rc;
+ dev_err(dev, "Error %d creating char device %s\n",
+ rc, dev_name(&sbefifo->dev));
+ goto err_free_minor;
}
/* Create platform devs for dts child nodes (occ, etc) */
for_each_available_child_of_node(dev->of_node, np) {
snprintf(child_name, sizeof(child_name), "%s-dev%d",
- sbefifo->name, child_idx++);
+ dev_name(&sbefifo->dev), child_idx++);
child = of_platform_device_create(np, child_name, dev);
if (!child)
dev_warn(dev, "failed to create child %s dev\n",
@@ -948,6 +967,11 @@ static int sbefifo_probe(struct device *dev)
}
return 0;
+ err_free_minor:
+ fsi_free_minor(sbefifo->dev.devt);
+ err:
+ put_device(&sbefifo->dev);
+ return rc;
}
static int sbefifo_unregister_child(struct device *dev, void *data)
@@ -967,10 +991,14 @@ static int sbefifo_remove(struct device *dev)
dev_dbg(dev, "Removing sbefifo device...\n");
- misc_deregister(&sbefifo->mdev);
- device_for_each_child(dev, NULL, sbefifo_unregister_child);
+ mutex_lock(&sbefifo->lock);
+ sbefifo->dead = true;
+ mutex_unlock(&sbefifo->lock);
- ida_simple_remove(&sbefifo_ida, sbefifo->idx);
+ cdev_device_del(&sbefifo->cdev, &sbefifo->dev);
+ fsi_free_minor(sbefifo->dev.devt);
+ device_for_each_child(dev, NULL, sbefifo_unregister_child);
+ put_device(&sbefifo->dev);
return 0;
}
@@ -1001,8 +1029,6 @@ static int sbefifo_init(void)
static void sbefifo_exit(void)
{
fsi_driver_unregister(&sbefifo_drv);
-
- ida_destroy(&sbefifo_ida);
}
module_init(sbefifo_init);
--
2.17.1
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.