Re: [PATCH v6 2/3] PCI/AER: Disable AER interrupt on suspend

2023-08-08 Thread Kai-Heng Feng
On Fri, Jul 21, 2023 at 11:58 AM Kai-Heng Feng
 wrote:
>
> On Tue, Jul 18, 2023 at 7:17 PM Bjorn Helgaas  wrote:
> >
> > [+cc Rafael]
> >
> > On Fri, May 12, 2023 at 08:00:13AM +0800, Kai-Heng Feng wrote:
> > > PCIe services that share an IRQ with PME, such as AER or DPC, may cause a
> > > spurious wakeup on system suspend. To prevent this, disable the AER 
> > > interrupt
> > > notification during the system suspend process.
> >
> > I see that in this particular BZ dmesg log, PME, AER, and DPC do share
> > the same IRQ, but I don't think this is true in general.
> >
> > Root Ports usually use MSI or MSI-X.  PME and hotplug events use the
> > Interrupt Message Number in the PCIe Capability, but AER uses the one
> > in the AER Root Error Status register, and DPC uses the one in the DPC
> > Capability register.  Those potentially correspond to three distinct
> > MSI/MSI-X vectors.
> >
> > I think this probably has nothing to do with the IRQ being *shared*,
> > but just that putting the downstream component into D3cold, where the
> > link state is L3, may cause the upstream component to log and signal a
> > link-related error as the link goes completely down.
>
> That's quite likely a better explanation than my wording.
> Assuming AER IRQ and PME IRQ are not shared, does system get woken up
> by AER IRQ?
>
> >
> > I don't think D0-D3hot should be relevant here because in all those
> > states, the link should be active because the downstream config space
> > remains accessible.  So I'm not sure if it's possible, but I wonder if
> > there's a more targeted place we could do this, e.g., in the path that
> > puts downstream devices in D3cold.
>
> Let me try to work on this.

We are seeing another case where the issue happens on D3hot [0].
So I wonder if it's possible to disable AER unconditionally?

[0] https://bugzilla.kernel.org/show_bug.cgi?id=216295#c3

>
> Kai-Heng
>
> >
> > > As Per PCIe Base Spec 5.0, section 5.2, titled "Link State Power 
> > > Management",
> > > TLP and DLLP transmission are disabled for a Link in L2/L3 Ready (D3hot), 
> > > L2
> > > (D3cold with aux power) and L3 (D3cold) states. So disabling the AER
> > > notification during suspend and re-enabling them during the resume process
> > > should not affect the basic functionality.
> > >
> > > Link: https://bugzilla.kernel.org/show_bug.cgi?id=216295
> > > Reviewed-by: Mika Westerberg 
> > > Signed-off-by: Kai-Heng Feng 
> > > ---
> > > v6:
> > > v5:
> > >  - Wording.
> > >
> > > v4:
> > > v3:
> > >  - No change.
> > >
> > > v2:
> > >  - Only disable AER IRQ.
> > >  - No more check on PME IRQ#.
> > >  - Use helper.
> > >
> > >  drivers/pci/pcie/aer.c | 22 ++
> > >  1 file changed, 22 insertions(+)
> > >
> > > diff --git a/drivers/pci/pcie/aer.c b/drivers/pci/pcie/aer.c
> > > index 1420e1f27105..9c07fdbeb52d 100644
> > > --- a/drivers/pci/pcie/aer.c
> > > +++ b/drivers/pci/pcie/aer.c
> > > @@ -1356,6 +1356,26 @@ static int aer_probe(struct pcie_device *dev)
> > >   return 0;
> > >  }
> > >
> > > +static int aer_suspend(struct pcie_device *dev)
> > > +{
> > > + struct aer_rpc *rpc = get_service_data(dev);
> > > + struct pci_dev *pdev = rpc->rpd;
> > > +
> > > + aer_disable_irq(pdev);
> > > +
> > > + return 0;
> > > +}
> > > +
> > > +static int aer_resume(struct pcie_device *dev)
> > > +{
> > > + struct aer_rpc *rpc = get_service_data(dev);
> > > + struct pci_dev *pdev = rpc->rpd;
> > > +
> > > + aer_enable_irq(pdev);
> > > +
> > > + return 0;
> > > +}
> > > +
> > >  /**
> > >   * aer_root_reset - reset Root Port hierarchy, RCEC, or RCiEP
> > >   * @dev: pointer to Root Port, RCEC, or RCiEP
> > > @@ -1420,6 +1440,8 @@ static struct pcie_port_service_driver aerdriver = {
> > >   .service= PCIE_PORT_SERVICE_AER,
> > >
> > >   .probe  = aer_probe,
> > > + .suspend= aer_suspend,
> > > + .resume = aer_resume,
> > >   .remove = aer_remove,
> > >  };
> > >
> > > --
> > > 2.34.1
> > >


Re: [PATCH v2] powerpc: Use shared font data

2023-08-08 Thread Dr. David Alan Gilbert
* Randy Dunlap (rdun...@infradead.org) wrote:
> 
> 
> On 8/8/23 10:28, Dr. David Alan Gilbert wrote:
> > * Randy Dunlap (rdun...@infradead.org) wrote:
> >> Hi--
> >>
> >> On 8/6/23 18:07, li...@treblig.org wrote:
> >>> From: "Dr. David Alan Gilbert" 
> >>>
> >>> PowerPC has a 'btext' font used for the console which is almost identical
> >>> to the shared font_sun8x16, so use it rather than duplicating the data.
> >>>
> >>> They were actually identical until about a decade ago when
> >>>commit bcfbeecea11c ("drivers: console: font_: Change a glyph from
> >>> "broken bar" to "vertical line"")
> >>>
> >>> which changed the | in the shared font to be a solid
> >>> bar rather than a broken bar.  That's the only difference.
> >>>
> >>> This was originally spotted by PMD which noticed that sparc does
> >>> the same thing with the same data, and they also share a bunch
> >>> of functions to manipulate the data.  I've previously posted a near
> >>> identical patch for sparc.
> >>>
> >>> One difference I notice in PowerPC is that there are a bunch of compile
> >>> options for the .c files for the early code to avoid a bunch of security
> >>> compilation features;  it's not clear to me if this is a problem for
> >>> this font data.
> >>>
> >>> Tested very lightly with a boot without FS in qemu.
> >>>
> >>> v2
> >>>   Added 'select FONT_SUPPORT' (to stop modconfig causing the font to be
> >>>linked into a module rather than the main kernel)
> >>>   Added 'select FONTS' to satisfy requirements in lib/fonts
> >>>
> >>> Signed-off-by: Dr. David Alan Gilbert 
> >>> ---
> >>>  arch/powerpc/Kconfig.debug  |   3 +
> >>>  arch/powerpc/kernel/btext.c | 360 +---
> >>>  2 files changed, 9 insertions(+), 354 deletions(-)
> >>>
> >>> diff --git a/arch/powerpc/Kconfig.debug b/arch/powerpc/Kconfig.debug
> >>> index 2a54fadbeaf51..521c4baf30e88 100644
> >>> --- a/arch/powerpc/Kconfig.debug
> >>> +++ b/arch/powerpc/Kconfig.debug
> >>> @@ -147,6 +147,9 @@ config BDI_SWITCH
> >>>  config BOOTX_TEXT
> >>>   bool "Support for early boot text console (BootX or OpenFirmware only)"
> >>>   depends on PPC_BOOK3S
> >>> + select FONT_SUN8x16
> >>> + select FONT_SUPPORT
> >>> + select FONTS
> >>>   help
> >>> Say Y here to see progress messages from the boot firmware in text
> >>> mode. Requires either BootX or Open Firmware.
> >>
> >> kconfig tells me:
> >>
> >> WARNING: unmet direct dependencies detected for FONTS
> >>   Depends on [n]: FONT_SUPPORT [=y] && (FRAMEBUFFER_CONSOLE [=n] || 
> >> STI_CONSOLE [=n])
> >>   Selected by [y]:
> >>   - BOOTX_TEXT [=y] && PPC_BOOK3S [=y]
> >>
> >> WARNING: unmet direct dependencies detected for FONT_SUN8x16
> >>   Depends on [n]: FONT_SUPPORT [=y] && FRAMEBUFFER_CONSOLE [=n] && (!SPARC 
> >> && FONTS [=y] || SPARC)
> >>   Selected by [y]:
> >>   - BOOTX_TEXT [=y] && PPC_BOOK3S [=y]
> >>
> >> because FONTS depends on FRAMEBUFFER_CONSOLE || STI_CONSOLE and neither of 
> >> those is set.
> > 
> > I'm not getting the warnings in the v2, with a few configs; what command
> > are using?
> > 
> 
> My 'make' build target is either pp32_randconfig or ppc64_randconfig.
> I see kconfig warnings in > 50% of the randconfigs. (small sample size,
> around 20)

Thanks, that triggers it for me; I'll have a discussion with it

Dave

> 
> > I'm tempted to change the FONT_SUN8x16 dependency line to have
> > SPARC||BOOTX_TEXT or SPARC||POWERPC  and drop the 'select FONTS' I
> > added.
> > 
> > Dave
> > 
> >>
> >> -- 
> >> ~Randy
> 
> -- 
> ~Randy
-- 
 -Open up your eyes, open up your mind, open up your code ---   
/ Dr. David Alan Gilbert|   Running GNU/Linux   | Happy  \ 
\dave @ treblig.org |   | In Hex /
 \ _|_ http://www.treblig.org   |___/


Re: [PATCH net-next v2 00/10] net: fs_enet: Driver cleanup

2023-08-08 Thread patchwork-bot+netdevbpf
Hello:

This series was applied to netdev/net-next.git (main)
by Jakub Kicinski :

On Fri,  4 Aug 2023 15:30:10 +0200 you wrote:
> Over the years, platform and driver initialisation have evolved into
> more generic ways, and driver or platform specific stuff has gone
> away, leaving stale objects behind.
> 
> This series aims at cleaning all that up for fs_enet ethernet driver.
> 
> Changes in v2:
> - Remove a trailing whitespace in the old struct moved in patch 7.
> - Include powerpc people and list that I forgot when sending v1
> (and Rob as expected by Patchwork for patch 6, not sure why)
> 
> [...]

Here is the summary with links:
  - [net-next,v2,01/10] net: fs_enet: Remove set but not used variable
https://git.kernel.org/netdev/net-next/c/78d3902795f0
  - [net-next,v2,02/10] net: fs_enet: Fix address space and base types 
mismatches
https://git.kernel.org/netdev/net-next/c/ae9e78a9dc88
  - [net-next,v2,03/10] net: fs_enet: Remove fs_get_id()
https://git.kernel.org/netdev/net-next/c/26bbbef8ff40
  - [net-next,v2,04/10] net: fs_enet: Remove unused fields in fs_platform_info 
struct
https://git.kernel.org/netdev/net-next/c/caaf482e2654
  - [net-next,v2,05/10] net: fs_enet: Remove has_phy field in fs_platform_info 
struct
https://git.kernel.org/netdev/net-next/c/9359a48c65a3
  - [net-next,v2,06/10] net: fs_enet: Remove stale prototypes from fsl_soc.c
https://git.kernel.org/netdev/net-next/c/62e106c802c5
  - [net-next,v2,07/10] net: fs_enet: Move struct fs_platform_info into 
fs_enet.h
https://git.kernel.org/netdev/net-next/c/7a76918371fe
  - [net-next,v2,08/10] net: fs_enet: Don't include fs_enet_pd.h when not needed
https://git.kernel.org/netdev/net-next/c/33deffc9f19f
  - [net-next,v2,09/10] net: fs_enet: Remove linux/fs_enet_pd.h
https://git.kernel.org/netdev/net-next/c/7149b38dc7cb
  - [net-next,v2,10/10] net: fs_enet: Use cpm_muram_xxx() functions instead of 
cpm_dpxxx() macros
https://git.kernel.org/netdev/net-next/c/5e6cb39a256d

You are awesome, thank you!
-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html




Re: [RFC PATCH v11 12/29] KVM: Add KVM_CREATE_GUEST_MEMFD ioctl() for guest-specific backing memory

2023-08-08 Thread Sean Christopherson
On Mon, Aug 07, 2023, Ackerley Tng wrote:
> I’d like to propose an alternative to the refcounting approach between
> the gmem file and associated kvm, where we think of KVM’s memslots as
> users of the gmem file.
> 
> Instead of having the gmem file pin the VM (i.e. take a refcount on
> kvm), we could let memslot take a refcount on the gmem file when the
> memslots are configured.
> 
> Here’s a POC patch that flips the refcounting (and modified selftests in
> the next commit):
> https://github.com/googleprodkernel/linux-cc/commit/7f487b029b89b9f3e9b094a721bc0772f3c8c797
> 
> One side effect of having the gmem file pin the VM is that now the gmem
> file becomes sort of a false handle on the VM:
> 
> + Closing the file destroys the file pointers in the VM and invalidates
>   the pointers

Yeah, this is less than ideal.  But, it's also how things operate today.  KVM
doesn't hold references to VMAs or files, e.g. if userspace munmap()s memory,
any and all SPTEs pointing at the memory are zapped.  The only difference with
gmem is that KVM needs to explicitly invalidate file pointers, instead of that
happening behind the scenes (no more VMAs to find).  Again, I agree the 
resulting
code is more complex than I would prefer, but from a userspace perspective I
don't see this as problematic.

> + Keeping the file open keeps the VM around in the kernel even though
>   the VM fd may already be closed.

That is perfectly ok.  There is plenty of prior art, as well as plenty of ways
for userspace to shoot itself in the foot.  E.g. open a stats fd for a vCPU and
the VM and all its vCPUs will be kept alive.  And conceptually it's sound,
anything created in the scope of a VM _should_ pin the VM.

> I feel that memslots form a natural way of managing usage of the gmem
> file. When a memslot is created, it is using the file; hence we take a
> refcount on the gmem file, and as memslots are removed, we drop
> refcounts on the gmem file.

Yes and no.  It's definitely more natural *if* the goal is to allow guest_memfd
memory to exist without being attached to a VM.  But I'm not at all convinced
that we want to allow that, or that it has desirable properties.  With TDX and
SNP in particuarly, I'm pretty sure that allowing memory to outlive the VM is
very underisable (more below).

> The KVM pointer is shared among all the bindings in gmem’s xarray, and we can
> enforce that a gmem file is used only with one VM:
> 
> + When binding a memslot to the file, if a kvm pointer exists, it must
>   be the same kvm as the one in this binding
> + When the binding to the last memslot is removed from a file, NULL the
>   kvm pointer.

Nullifying the KVM pointer isn't sufficient, because without additional actions
userspace could extract data from a VM by deleting its memslots and then binding
the guest_memfd to an attacker controlled VM.  Or more likely with TDX and SNP,
induce badness by coercing KVM into mapping memory into a guest with the wrong
ASID/HKID.

I can think of three ways to handle that:

  (a) prevent a different VM from *ever* binding to the gmem instance
  (b) free/zero physical pages when unbinding
  (c) free/zero when binding to a different VM

Option (a) is easy, but that pretty much defeats the purpose of decopuling
guest_memfd from a VM.

Option (b) isn't hard to implement, but it screws up the lifecycle of the 
memory,
e.g. would require memory when a memslot is deleted.  That isn't necessarily a
deal-breaker, but it runs counter to how KVM memlots currently operate.  
Memslots
are basically just weird page tables, e.g. deleting a memslot doesn't have any
impact on the underlying data in memory.  TDX throws a wrench in this as 
removing
a page from the Secure EPT is effectively destructive to the data (can't be 
mapped
back in to the VM without zeroing the data), but IMO that's an oddity with TDX 
and
not necessarily something we want to carry over to other VM types.

There would also be performance implications (probably a non-issue in practice),
and weirdness if/when we get to sharing, linking and/or mmap()ing gmem.  E.g. 
what
should happen if the last memslot (binding) is deleted, but there outstanding 
userspace
mappings?

Option (c) is better from a lifecycle perspective, but it adds its own flavor of
complexity, e.g. the performant way to reclaim TDX memory requires the TDMR
(effectively the VM pointer), and so a deferred relcaim doesn't really work for
TDX.  And I'm pretty sure it *can't* work for SNP, because RMP entries must not
outlive the VM; KVM can't reuse an ASID if there are pages assigned to that ASID
in the RMP, i.e. until all memory belonging to the VM has been fully freed.

> Could binding gmem files not on creation, but at memslot configuration
> time be sufficient and simpler?

After working through the flows, I think binding on-demand would simplify the
refcounting (stating the obvious), but complicate the lifecycle of the memory as
well as the contract between KVM and userspace, and would break 

Re: [PATCH -next] ASoC: imx-audio-rpmsg: Remove redundant initialization owner in imx_audio_rpmsg_driver

2023-08-08 Thread Mark Brown
On Tue, 08 Aug 2023 10:17:28 +0800, Li Zetao wrote:
> The module_rpmsg_driver() will set "THIS_MODULE" to driver.owner when
> register a rpmsg_driver driver, so it is redundant initialization to set
> driver.owner in the statement. Remove it for clean code.
> 
> 

Applied to

   https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git for-next

Thanks!

[1/1] ASoC: imx-audio-rpmsg: Remove redundant initialization owner in 
imx_audio_rpmsg_driver
  commit: 8e5c4a9fc47ab6d8e1d9cf6c1f11c90675c1d968

All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.

You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.

If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.

Please add any relevant lists and maintainers to the CCs when replying
to this mail.

Thanks,
Mark



Re: [PATCH v2] powerpc: Use shared font data

2023-08-08 Thread Randy Dunlap



On 8/8/23 10:28, Dr. David Alan Gilbert wrote:
> * Randy Dunlap (rdun...@infradead.org) wrote:
>> Hi--
>>
>> On 8/6/23 18:07, li...@treblig.org wrote:
>>> From: "Dr. David Alan Gilbert" 
>>>
>>> PowerPC has a 'btext' font used for the console which is almost identical
>>> to the shared font_sun8x16, so use it rather than duplicating the data.
>>>
>>> They were actually identical until about a decade ago when
>>>commit bcfbeecea11c ("drivers: console: font_: Change a glyph from
>>> "broken bar" to "vertical line"")
>>>
>>> which changed the | in the shared font to be a solid
>>> bar rather than a broken bar.  That's the only difference.
>>>
>>> This was originally spotted by PMD which noticed that sparc does
>>> the same thing with the same data, and they also share a bunch
>>> of functions to manipulate the data.  I've previously posted a near
>>> identical patch for sparc.
>>>
>>> One difference I notice in PowerPC is that there are a bunch of compile
>>> options for the .c files for the early code to avoid a bunch of security
>>> compilation features;  it's not clear to me if this is a problem for
>>> this font data.
>>>
>>> Tested very lightly with a boot without FS in qemu.
>>>
>>> v2
>>>   Added 'select FONT_SUPPORT' (to stop modconfig causing the font to be
>>>linked into a module rather than the main kernel)
>>>   Added 'select FONTS' to satisfy requirements in lib/fonts
>>>
>>> Signed-off-by: Dr. David Alan Gilbert 
>>> ---
>>>  arch/powerpc/Kconfig.debug  |   3 +
>>>  arch/powerpc/kernel/btext.c | 360 +---
>>>  2 files changed, 9 insertions(+), 354 deletions(-)
>>>
>>> diff --git a/arch/powerpc/Kconfig.debug b/arch/powerpc/Kconfig.debug
>>> index 2a54fadbeaf51..521c4baf30e88 100644
>>> --- a/arch/powerpc/Kconfig.debug
>>> +++ b/arch/powerpc/Kconfig.debug
>>> @@ -147,6 +147,9 @@ config BDI_SWITCH
>>>  config BOOTX_TEXT
>>> bool "Support for early boot text console (BootX or OpenFirmware only)"
>>> depends on PPC_BOOK3S
>>> +   select FONT_SUN8x16
>>> +   select FONT_SUPPORT
>>> +   select FONTS
>>> help
>>>   Say Y here to see progress messages from the boot firmware in text
>>>   mode. Requires either BootX or Open Firmware.
>>
>> kconfig tells me:
>>
>> WARNING: unmet direct dependencies detected for FONTS
>>   Depends on [n]: FONT_SUPPORT [=y] && (FRAMEBUFFER_CONSOLE [=n] || 
>> STI_CONSOLE [=n])
>>   Selected by [y]:
>>   - BOOTX_TEXT [=y] && PPC_BOOK3S [=y]
>>
>> WARNING: unmet direct dependencies detected for FONT_SUN8x16
>>   Depends on [n]: FONT_SUPPORT [=y] && FRAMEBUFFER_CONSOLE [=n] && (!SPARC 
>> && FONTS [=y] || SPARC)
>>   Selected by [y]:
>>   - BOOTX_TEXT [=y] && PPC_BOOK3S [=y]
>>
>> because FONTS depends on FRAMEBUFFER_CONSOLE || STI_CONSOLE and neither of 
>> those is set.
> 
> I'm not getting the warnings in the v2, with a few configs; what command
> are using?
> 

My 'make' build target is either pp32_randconfig or ppc64_randconfig.
I see kconfig warnings in > 50% of the randconfigs. (small sample size,
around 20)


> I'm tempted to change the FONT_SUN8x16 dependency line to have
> SPARC||BOOTX_TEXT or SPARC||POWERPC  and drop the 'select FONTS' I
> added.
> 
> Dave
> 
>>
>> -- 
>> ~Randy

-- 
~Randy


Re: [PATCH -next] net/ps3_gelic_net: Use ether_addr_to_u64() to convert ethernet address

2023-08-08 Thread Geoff Levand
Hi,

On 8/8/23 04:40, Li Zetao wrote:
> Use ether_addr_to_u64() to convert an Ethernet address into a u64 value,
> instead of directly calculating, as this is exactly what
> this function does.
> 
> Signed-off-by: Li Zetao 
> ---
>  drivers/net/ethernet/toshiba/ps3_gelic_net.c | 8 +---
>  1 file changed, 1 insertion(+), 7 deletions(-)

I tested this on PS3 and it seems to be working OK.
Thanks for your contribution.

Tested-by: Geoff Levand 



Re: [PATCH v2] powerpc: Use shared font data

2023-08-08 Thread Dr. David Alan Gilbert
* Randy Dunlap (rdun...@infradead.org) wrote:
> Hi--
> 
> On 8/6/23 18:07, li...@treblig.org wrote:
> > From: "Dr. David Alan Gilbert" 
> > 
> > PowerPC has a 'btext' font used for the console which is almost identical
> > to the shared font_sun8x16, so use it rather than duplicating the data.
> > 
> > They were actually identical until about a decade ago when
> >commit bcfbeecea11c ("drivers: console: font_: Change a glyph from
> > "broken bar" to "vertical line"")
> > 
> > which changed the | in the shared font to be a solid
> > bar rather than a broken bar.  That's the only difference.
> > 
> > This was originally spotted by PMD which noticed that sparc does
> > the same thing with the same data, and they also share a bunch
> > of functions to manipulate the data.  I've previously posted a near
> > identical patch for sparc.
> > 
> > One difference I notice in PowerPC is that there are a bunch of compile
> > options for the .c files for the early code to avoid a bunch of security
> > compilation features;  it's not clear to me if this is a problem for
> > this font data.
> > 
> > Tested very lightly with a boot without FS in qemu.
> > 
> > v2
> >   Added 'select FONT_SUPPORT' (to stop modconfig causing the font to be
> >linked into a module rather than the main kernel)
> >   Added 'select FONTS' to satisfy requirements in lib/fonts
> > 
> > Signed-off-by: Dr. David Alan Gilbert 
> > ---
> >  arch/powerpc/Kconfig.debug  |   3 +
> >  arch/powerpc/kernel/btext.c | 360 +---
> >  2 files changed, 9 insertions(+), 354 deletions(-)
> > 
> > diff --git a/arch/powerpc/Kconfig.debug b/arch/powerpc/Kconfig.debug
> > index 2a54fadbeaf51..521c4baf30e88 100644
> > --- a/arch/powerpc/Kconfig.debug
> > +++ b/arch/powerpc/Kconfig.debug
> > @@ -147,6 +147,9 @@ config BDI_SWITCH
> >  config BOOTX_TEXT
> > bool "Support for early boot text console (BootX or OpenFirmware only)"
> > depends on PPC_BOOK3S
> > +   select FONT_SUN8x16
> > +   select FONT_SUPPORT
> > +   select FONTS
> > help
> >   Say Y here to see progress messages from the boot firmware in text
> >   mode. Requires either BootX or Open Firmware.
> 
> kconfig tells me:
> 
> WARNING: unmet direct dependencies detected for FONTS
>   Depends on [n]: FONT_SUPPORT [=y] && (FRAMEBUFFER_CONSOLE [=n] || 
> STI_CONSOLE [=n])
>   Selected by [y]:
>   - BOOTX_TEXT [=y] && PPC_BOOK3S [=y]
> 
> WARNING: unmet direct dependencies detected for FONT_SUN8x16
>   Depends on [n]: FONT_SUPPORT [=y] && FRAMEBUFFER_CONSOLE [=n] && (!SPARC && 
> FONTS [=y] || SPARC)
>   Selected by [y]:
>   - BOOTX_TEXT [=y] && PPC_BOOK3S [=y]
> 
> because FONTS depends on FRAMEBUFFER_CONSOLE || STI_CONSOLE and neither of 
> those is set.

I'm not getting the warnings in the v2, with a few configs; what command
are using?

I'm tempted to change the FONT_SUN8x16 dependency line to have
SPARC||BOOTX_TEXT or SPARC||POWERPC  and drop the 'select FONTS' I
added.

Dave

> 
> -- 
> ~Randy
-- 
 -Open up your eyes, open up your mind, open up your code ---   
/ Dr. David Alan Gilbert|   Running GNU/Linux   | Happy  \ 
\dave @ treblig.org |   | In Hex /
 \ _|_ http://www.treblig.org   |___/


Re: [PATCH v2] powerpc: Use shared font data

2023-08-08 Thread Randy Dunlap
Hi--

On 8/6/23 18:07, li...@treblig.org wrote:
> From: "Dr. David Alan Gilbert" 
> 
> PowerPC has a 'btext' font used for the console which is almost identical
> to the shared font_sun8x16, so use it rather than duplicating the data.
> 
> They were actually identical until about a decade ago when
>commit bcfbeecea11c ("drivers: console: font_: Change a glyph from
> "broken bar" to "vertical line"")
> 
> which changed the | in the shared font to be a solid
> bar rather than a broken bar.  That's the only difference.
> 
> This was originally spotted by PMD which noticed that sparc does
> the same thing with the same data, and they also share a bunch
> of functions to manipulate the data.  I've previously posted a near
> identical patch for sparc.
> 
> One difference I notice in PowerPC is that there are a bunch of compile
> options for the .c files for the early code to avoid a bunch of security
> compilation features;  it's not clear to me if this is a problem for
> this font data.
> 
> Tested very lightly with a boot without FS in qemu.
> 
> v2
>   Added 'select FONT_SUPPORT' (to stop modconfig causing the font to be
>linked into a module rather than the main kernel)
>   Added 'select FONTS' to satisfy requirements in lib/fonts
> 
> Signed-off-by: Dr. David Alan Gilbert 
> ---
>  arch/powerpc/Kconfig.debug  |   3 +
>  arch/powerpc/kernel/btext.c | 360 +---
>  2 files changed, 9 insertions(+), 354 deletions(-)
> 
> diff --git a/arch/powerpc/Kconfig.debug b/arch/powerpc/Kconfig.debug
> index 2a54fadbeaf51..521c4baf30e88 100644
> --- a/arch/powerpc/Kconfig.debug
> +++ b/arch/powerpc/Kconfig.debug
> @@ -147,6 +147,9 @@ config BDI_SWITCH
>  config BOOTX_TEXT
>   bool "Support for early boot text console (BootX or OpenFirmware only)"
>   depends on PPC_BOOK3S
> + select FONT_SUN8x16
> + select FONT_SUPPORT
> + select FONTS
>   help
> Say Y here to see progress messages from the boot firmware in text
> mode. Requires either BootX or Open Firmware.

kconfig tells me:

WARNING: unmet direct dependencies detected for FONTS
  Depends on [n]: FONT_SUPPORT [=y] && (FRAMEBUFFER_CONSOLE [=n] || STI_CONSOLE 
[=n])
  Selected by [y]:
  - BOOTX_TEXT [=y] && PPC_BOOK3S [=y]

WARNING: unmet direct dependencies detected for FONT_SUN8x16
  Depends on [n]: FONT_SUPPORT [=y] && FRAMEBUFFER_CONSOLE [=n] && (!SPARC && 
FONTS [=y] || SPARC)
  Selected by [y]:
  - BOOTX_TEXT [=y] && PPC_BOOK3S [=y]

because FONTS depends on FRAMEBUFFER_CONSOLE || STI_CONSOLE and neither of 
those is set.


-- 
~Randy


Re: [PATCH v2 1/2] PCI: Add pci_find_next_dvsec_capability to find next Designated VSEC

2023-08-08 Thread Bjorn Helgaas
Don't re-post just for this, but if you do repost, add "()" after the
function name in the subject line, as you did for the 2/2 patch.

On Tue, Aug 08, 2023 at 12:08:57PM +0800, Xiongfeng Wang wrote:
> Some devices may have several DVSEC (Designated Vendor-Specific Extended
> Capability) entries with the same DVSEC ID. Add
> pci_find_next_dvsec_capability() to find them all.


[PATCH -next] net/ps3_gelic_net: Use ether_addr_to_u64() to convert ethernet address

2023-08-08 Thread Li Zetao
Use ether_addr_to_u64() to convert an Ethernet address into a u64 value,
instead of directly calculating, as this is exactly what
this function does.

Signed-off-by: Li Zetao 
---
 drivers/net/ethernet/toshiba/ps3_gelic_net.c | 8 +---
 1 file changed, 1 insertion(+), 7 deletions(-)

diff --git a/drivers/net/ethernet/toshiba/ps3_gelic_net.c 
b/drivers/net/ethernet/toshiba/ps3_gelic_net.c
index 9d535ae59626..77a02819e412 100644
--- a/drivers/net/ethernet/toshiba/ps3_gelic_net.c
+++ b/drivers/net/ethernet/toshiba/ps3_gelic_net.c
@@ -596,7 +596,6 @@ void gelic_net_set_multi(struct net_device *netdev)
struct gelic_card *card = netdev_card(netdev);
struct netdev_hw_addr *ha;
unsigned int i;
-   uint8_t *p;
u64 addr;
int status;
 
@@ -629,12 +628,7 @@ void gelic_net_set_multi(struct net_device *netdev)
 
/* set multicast addresses */
netdev_for_each_mc_addr(ha, netdev) {
-   addr = 0;
-   p = ha->addr;
-   for (i = 0; i < ETH_ALEN; i++) {
-   addr <<= 8;
-   addr |= *p++;
-   }
+   addr = ether_addr_to_u64(ha->addr);
status = lv1_net_add_multicast_address(bus_id(card),
   dev_id(card),
   addr, 0);
-- 
2.34.1



[PATCH v8 5/6] powerpc/book3s64/memhotplug: Enable memmap on memory for radix

2023-08-08 Thread Aneesh Kumar K.V
Radix vmemmap mapping can map things correctly at the PMD level or PTE
level based on different device boundary checks. Hence we skip the
restrictions w.r.t vmemmap size to be multiple of PMD_SIZE. This also
makes the feature widely useful because to use PMD_SIZE vmemmap area we
require a memory block size of 2GiB

We can also use MHP_RESERVE_PAGES_MEMMAP_ON_MEMORY to that the feature
can work with a memory block size of 256MB. Using altmap.reserve feature
to align things correctly at pageblock granularity. We can end up
losing some pages in memory with this. For ex: with a 256MiB memory block
size, we require 4 pages to map vmemmap pages, In order to align things
correctly we end up adding a reserve of 28 pages. ie, for every 4096
pages 28 pages get reserved.

Reviewed-by: David Hildenbrand 
Signed-off-by: Aneesh Kumar K.V 
---
 arch/powerpc/Kconfig  |  1 +
 arch/powerpc/include/asm/pgtable.h| 21 +++
 .../platforms/pseries/hotplug-memory.c|  2 +-
 3 files changed, 23 insertions(+), 1 deletion(-)

diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index d0497d13f5b4..938294c996dc 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -157,6 +157,7 @@ config PPC
select ARCH_HAS_UBSAN_SANITIZE_ALL
select ARCH_HAVE_NMI_SAFE_CMPXCHG
select ARCH_KEEP_MEMBLOCK
+   select ARCH_MHP_MEMMAP_ON_MEMORY_ENABLE if PPC_RADIX_MMU
select ARCH_MIGHT_HAVE_PC_PARPORT
select ARCH_MIGHT_HAVE_PC_SERIO
select ARCH_OPTIONAL_KERNEL_RWX if ARCH_HAS_STRICT_KERNEL_RWX
diff --git a/arch/powerpc/include/asm/pgtable.h 
b/arch/powerpc/include/asm/pgtable.h
index a4893b17705a..33464e6d6431 100644
--- a/arch/powerpc/include/asm/pgtable.h
+++ b/arch/powerpc/include/asm/pgtable.h
@@ -161,6 +161,27 @@ static inline pgtable_t pmd_pgtable(pmd_t pmd)
 int __meminit vmemmap_populated(unsigned long vmemmap_addr, int 
vmemmap_map_size);
 bool altmap_cross_boundary(struct vmem_altmap *altmap, unsigned long start,
   unsigned long page_size);
+/*
+ * mm/memory_hotplug.c:mhp_supports_memmap_on_memory goes into details
+ * some of the restrictions. We don't check for PMD_SIZE because our
+ * vmemmap allocation code can fallback correctly. The pageblock
+ * alignment requirement is met using altmap->reserve blocks.
+ */
+#define arch_supports_memmap_on_memory arch_supports_memmap_on_memory
+static inline bool arch_supports_memmap_on_memory(unsigned long vmemmap_size)
+{
+   if (!radix_enabled())
+   return false;
+   /*
+* With 4K page size and 2M PMD_SIZE, we can align
+* things better with memory block size value
+* starting from 128MB. Hence align things with PMD_SIZE.
+*/
+   if (IS_ENABLED(CONFIG_PPC_4K_PAGES))
+   return IS_ALIGNED(vmemmap_size, PMD_SIZE);
+   return true;
+}
+
 #endif /* CONFIG_PPC64 */
 
 #endif /* __ASSEMBLY__ */
diff --git a/arch/powerpc/platforms/pseries/hotplug-memory.c 
b/arch/powerpc/platforms/pseries/hotplug-memory.c
index 9c62c2c3b3d0..4f3d6a2f9065 100644
--- a/arch/powerpc/platforms/pseries/hotplug-memory.c
+++ b/arch/powerpc/platforms/pseries/hotplug-memory.c
@@ -637,7 +637,7 @@ static int dlpar_add_lmb(struct drmem_lmb *lmb)
nid = first_online_node;
 
/* Add the memory */
-   rc = __add_memory(nid, lmb->base_addr, block_sz, MHP_NONE);
+   rc = __add_memory(nid, lmb->base_addr, block_sz, MHP_MEMMAP_ON_MEMORY);
if (rc) {
invalidate_lmb_associativity_index(lmb);
return rc;
-- 
2.41.0



[PATCH v8 6/6] mm/memory_hotplug: Embed vmem_altmap details in memory block

2023-08-08 Thread Aneesh Kumar K.V
With memmap on memory, some architecture needs more details w.r.t altmap
such as base_pfn, end_pfn, etc to unmap vmemmap memory. Instead of
computing them again when we remove a memory block, embed vmem_altmap
details in struct memory_block if we are using memmap on memory block
feature.

Acked-by: Michal Hocko 
Acked-by: David Hildenbrand 
Signed-off-by: Aneesh Kumar K.V 
---
 drivers/base/memory.c  | 27 +
 include/linux/memory.h |  8 ++-
 mm/memory_hotplug.c| 54 ++
 3 files changed, 52 insertions(+), 37 deletions(-)

diff --git a/drivers/base/memory.c b/drivers/base/memory.c
index b456ac213610..8191709c9ad2 100644
--- a/drivers/base/memory.c
+++ b/drivers/base/memory.c
@@ -105,7 +105,8 @@ EXPORT_SYMBOL(unregister_memory_notifier);
 static void memory_block_release(struct device *dev)
 {
struct memory_block *mem = to_memory_block(dev);
-
+   /* Verify that the altmap is freed */
+   WARN_ON(mem->altmap);
kfree(mem);
 }
 
@@ -183,7 +184,7 @@ static int memory_block_online(struct memory_block *mem)
 {
unsigned long start_pfn = section_nr_to_pfn(mem->start_section_nr);
unsigned long nr_pages = PAGES_PER_SECTION * sections_per_block;
-   unsigned long nr_vmemmap_pages = mem->nr_vmemmap_pages;
+   unsigned long nr_vmemmap_pages = 0;
struct zone *zone;
int ret;
 
@@ -200,6 +201,9 @@ static int memory_block_online(struct memory_block *mem)
 * stage helps to keep accounting easier to follow - e.g vmemmaps
 * belong to the same zone as the memory they backed.
 */
+   if (mem->altmap)
+   nr_vmemmap_pages = mem->altmap->free;
+
if (nr_vmemmap_pages) {
ret = mhp_init_memmap_on_memory(start_pfn, nr_vmemmap_pages, 
zone);
if (ret)
@@ -230,7 +234,7 @@ static int memory_block_offline(struct memory_block *mem)
 {
unsigned long start_pfn = section_nr_to_pfn(mem->start_section_nr);
unsigned long nr_pages = PAGES_PER_SECTION * sections_per_block;
-   unsigned long nr_vmemmap_pages = mem->nr_vmemmap_pages;
+   unsigned long nr_vmemmap_pages = 0;
int ret;
 
if (!mem->zone)
@@ -240,6 +244,9 @@ static int memory_block_offline(struct memory_block *mem)
 * Unaccount before offlining, such that unpopulated zone and kthreads
 * can properly be torn down in offline_pages().
 */
+   if (mem->altmap)
+   nr_vmemmap_pages = mem->altmap->free;
+
if (nr_vmemmap_pages)
adjust_present_page_count(pfn_to_page(start_pfn), mem->group,
  -nr_vmemmap_pages);
@@ -726,7 +733,7 @@ void memory_block_add_nid(struct memory_block *mem, int nid,
 #endif
 
 static int add_memory_block(unsigned long block_id, unsigned long state,
-   unsigned long nr_vmemmap_pages,
+   struct vmem_altmap *altmap,
struct memory_group *group)
 {
struct memory_block *mem;
@@ -744,7 +751,7 @@ static int add_memory_block(unsigned long block_id, 
unsigned long state,
mem->start_section_nr = block_id * sections_per_block;
mem->state = state;
mem->nid = NUMA_NO_NODE;
-   mem->nr_vmemmap_pages = nr_vmemmap_pages;
+   mem->altmap = altmap;
INIT_LIST_HEAD(>group_next);
 
 #ifndef CONFIG_NUMA
@@ -783,14 +790,14 @@ static int __init add_boot_memory_block(unsigned long 
base_section_nr)
if (section_count == 0)
return 0;
return add_memory_block(memory_block_id(base_section_nr),
-   MEM_ONLINE, 0,  NULL);
+   MEM_ONLINE, NULL,  NULL);
 }
 
 static int add_hotplug_memory_block(unsigned long block_id,
-   unsigned long nr_vmemmap_pages,
+   struct vmem_altmap *altmap,
struct memory_group *group)
 {
-   return add_memory_block(block_id, MEM_OFFLINE, nr_vmemmap_pages, group);
+   return add_memory_block(block_id, MEM_OFFLINE, altmap, group);
 }
 
 static void remove_memory_block(struct memory_block *memory)
@@ -818,7 +825,7 @@ static void remove_memory_block(struct memory_block *memory)
  * Called under device_hotplug_lock.
  */
 int create_memory_block_devices(unsigned long start, unsigned long size,
-   unsigned long vmemmap_pages,
+   struct vmem_altmap *altmap,
struct memory_group *group)
 {
const unsigned long start_block_id = pfn_to_block_id(PFN_DOWN(start));
@@ -832,7 +839,7 @@ int create_memory_block_devices(unsigned long start, 
unsigned long size,
return -EINVAL;
 
for (block_id = start_block_id; block_id != end_block_id; block_id++) {
-   ret = add_hotplug_memory_block(block_id, 

[PATCH v8 4/6] mm/memory_hotplug: Support memmap_on_memory when memmap is not aligned to pageblocks

2023-08-08 Thread Aneesh Kumar K.V
Currently, memmap_on_memory feature is only supported with memory block
sizes that result in vmemmap pages covering full page blocks. This is
because memory onlining/offlining code requires applicable ranges to be
pageblock-aligned, for example, to set the migratetypes properly.

This patch helps to lift that restriction by reserving more pages than
required for vmemmap space. This helps the start address to be page
block aligned with different memory block sizes. Using this facility
implies the kernel will be reserving some pages for every memoryblock.
This allows the memmap on memory feature to be widely useful with
different memory block size values.

For ex: with 64K page size and 256MiB memory block size, we require 4
pages to map vmemmap pages, To align things correctly we end up adding a
reserve of 28 pages. ie, for every 4096 pages 28 pages get reserved.

Acked-by: Michal Hocko 
Acked-by: David Hildenbrand 
Signed-off-by: Aneesh Kumar K.V 
---
 .../admin-guide/mm/memory-hotplug.rst |  12 ++
 mm/memory_hotplug.c   | 120 +++---
 2 files changed, 113 insertions(+), 19 deletions(-)

diff --git a/Documentation/admin-guide/mm/memory-hotplug.rst 
b/Documentation/admin-guide/mm/memory-hotplug.rst
index bd77841041af..2994958c7ce8 100644
--- a/Documentation/admin-guide/mm/memory-hotplug.rst
+++ b/Documentation/admin-guide/mm/memory-hotplug.rst
@@ -433,6 +433,18 @@ The following module parameters are currently defined:
 memory in a way that huge pages in bigger
 granularity cannot be formed on hotplugged
 memory.
+
+With value "force" it could result in memory
+wastage due to memmap size limitations. For
+example, if the memmap for a memory block
+requires 1 MiB, but the pageblock size is 2
+MiB, 1 MiB of hotplugged memory will be wasted.
+Note that there are still cases where the
+feature cannot be enforced: for example, if the
+memmap is smaller than a single page, or if the
+architecture does not support the forced mode
+in all configurations.
+
 ``online_policy``   read-write: Set the basic policy used for
 automatic zone selection when onlining memory
 blocks without specifying a target zone.
diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c
index 746cb7c08c64..76b813991bdc 100644
--- a/mm/memory_hotplug.c
+++ b/mm/memory_hotplug.c
@@ -41,17 +41,83 @@
 #include "internal.h"
 #include "shuffle.h"
 
+enum {
+   MEMMAP_ON_MEMORY_DISABLE = 0,
+   MEMMAP_ON_MEMORY_ENABLE,
+   MEMMAP_ON_MEMORY_FORCE,
+};
+
+static int memmap_mode __read_mostly = MEMMAP_ON_MEMORY_DISABLE;
+
+static inline unsigned long memory_block_memmap_size(void)
+{
+   return PHYS_PFN(memory_block_size_bytes()) * sizeof(struct page);
+}
+
+static inline unsigned long memory_block_memmap_on_memory_pages(void)
+{
+   unsigned long nr_pages = PFN_UP(memory_block_memmap_size());
+
+   /*
+* In "forced" memmap_on_memory mode, we add extra pages to align the
+* vmemmap size to cover full pageblocks. That way, we can add memory
+* even if the vmemmap size is not properly aligned, however, we might 
waste
+* memory.
+*/
+   if (memmap_mode == MEMMAP_ON_MEMORY_FORCE)
+   return pageblock_align(nr_pages);
+   return nr_pages;
+}
+
 #ifdef CONFIG_MHP_MEMMAP_ON_MEMORY
 /*
  * memory_hotplug.memmap_on_memory parameter
  */
-static bool memmap_on_memory __ro_after_init;
-module_param(memmap_on_memory, bool, 0444);
-MODULE_PARM_DESC(memmap_on_memory, "Enable memmap on memory for memory 
hotplug");
+static int set_memmap_mode(const char *val, const struct kernel_param *kp)
+{
+   int ret, mode;
+   bool enabled;
+
+   if (sysfs_streq(val, "force") ||  sysfs_streq(val, "FORCE")) {
+   mode = MEMMAP_ON_MEMORY_FORCE;
+   } else {
+   ret = kstrtobool(val, );
+   if (ret < 0)
+   return ret;
+   if (enabled)
+   mode = MEMMAP_ON_MEMORY_ENABLE;
+   else
+   mode = MEMMAP_ON_MEMORY_DISABLE;
+   }
+   *((int *)kp->arg) = mode;
+   if (mode == MEMMAP_ON_MEMORY_FORCE) {
+   unsigned long memmap_pages = 
memory_block_memmap_on_memory_pages();
+
+   pr_info_once("Memory hotplug will waste %ld pages in each 
memory block\n",
+memmap_pages - PFN_UP(memory_block_memmap_size()));
+   }
+   return 0;
+}
+
+static int get_memmap_mode(char *buffer, const 

[PATCH v8 3/6] mm/memory_hotplug: Allow architecture to override memmap on memory support check

2023-08-08 Thread Aneesh Kumar K.V
Some architectures would want different restrictions. Hence add an
architecture-specific override.

The PMD_SIZE check is moved there.

Acked-by: Michal Hocko 
Acked-by: David Hildenbrand 
Signed-off-by: Aneesh Kumar K.V 
---
 mm/memory_hotplug.c | 24 
 1 file changed, 20 insertions(+), 4 deletions(-)

diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c
index eca32ccd45cc..746cb7c08c64 100644
--- a/mm/memory_hotplug.c
+++ b/mm/memory_hotplug.c
@@ -1247,10 +1247,26 @@ static int online_memory_block(struct memory_block 
*mem, void *arg)
return device_online(>dev);
 }
 
+static inline unsigned long memory_block_memmap_size(void)
+{
+   return PHYS_PFN(memory_block_size_bytes()) * sizeof(struct page);
+}
+
+#ifndef arch_supports_memmap_on_memory
+static inline bool arch_supports_memmap_on_memory(unsigned long vmemmap_size)
+{
+   /*
+* As default, we want the vmemmap to span a complete PMD such that we
+* can map the vmemmap using a single PMD if supported by the
+* architecture.
+*/
+   return IS_ALIGNED(vmemmap_size, PMD_SIZE);
+}
+#endif
+
 static bool mhp_supports_memmap_on_memory(unsigned long size)
 {
-   unsigned long nr_vmemmap_pages = size / PAGE_SIZE;
-   unsigned long vmemmap_size = nr_vmemmap_pages * sizeof(struct page);
+   unsigned long vmemmap_size = memory_block_memmap_size();
unsigned long remaining_size = size - vmemmap_size;
 
/*
@@ -1281,8 +1297,8 @@ static bool mhp_supports_memmap_on_memory(unsigned long 
size)
 */
return mhp_memmap_on_memory() &&
   size == memory_block_size_bytes() &&
-  IS_ALIGNED(vmemmap_size, PMD_SIZE) &&
-  IS_ALIGNED(remaining_size, (pageblock_nr_pages << PAGE_SHIFT));
+  IS_ALIGNED(remaining_size, (pageblock_nr_pages << PAGE_SHIFT)) &&
+  arch_supports_memmap_on_memory(vmemmap_size);
 }
 
 /*
-- 
2.41.0



[PATCH v8 2/6] mm/memory_hotplug: Allow memmap on memory hotplug request to fallback

2023-08-08 Thread Aneesh Kumar K.V
If not supported, fallback to not using memap on memmory. This avoids
the need for callers to do the fallback.

Acked-by: Michal Hocko 
Acked-by: David Hildenbrand 
Signed-off-by: Aneesh Kumar K.V 
---
 drivers/acpi/acpi_memhotplug.c |  3 +--
 include/linux/memory_hotplug.h |  3 ++-
 mm/memory_hotplug.c| 13 ++---
 3 files changed, 9 insertions(+), 10 deletions(-)

diff --git a/drivers/acpi/acpi_memhotplug.c b/drivers/acpi/acpi_memhotplug.c
index 24f662d8bd39..d0c1a71007d0 100644
--- a/drivers/acpi/acpi_memhotplug.c
+++ b/drivers/acpi/acpi_memhotplug.c
@@ -211,8 +211,7 @@ static int acpi_memory_enable_device(struct 
acpi_memory_device *mem_device)
if (!info->length)
continue;
 
-   if (mhp_supports_memmap_on_memory(info->length))
-   mhp_flags |= MHP_MEMMAP_ON_MEMORY;
+   mhp_flags |= MHP_MEMMAP_ON_MEMORY;
result = __add_memory(mgid, info->start_addr, info->length,
  mhp_flags);
 
diff --git a/include/linux/memory_hotplug.h b/include/linux/memory_hotplug.h
index 013c69753c91..7d2076583494 100644
--- a/include/linux/memory_hotplug.h
+++ b/include/linux/memory_hotplug.h
@@ -97,6 +97,8 @@ typedef int __bitwise mhp_t;
  * To do so, we will use the beginning of the hot-added range to build
  * the page tables for the memmap array that describes the entire range.
  * Only selected architectures support it with SPARSE_VMEMMAP.
+ * This is only a hint, the core kernel can decide to not do this based on
+ * different alignment checks.
  */
 #define MHP_MEMMAP_ON_MEMORY   ((__force mhp_t)BIT(1))
 /*
@@ -354,7 +356,6 @@ extern struct zone *zone_for_pfn_range(int online_type, int 
nid,
 extern int arch_create_linear_mapping(int nid, u64 start, u64 size,
  struct mhp_params *params);
 void arch_remove_linear_mapping(u64 start, u64 size);
-extern bool mhp_supports_memmap_on_memory(unsigned long size);
 #endif /* CONFIG_MEMORY_HOTPLUG */
 
 #endif /* __LINUX_MEMORY_HOTPLUG_H */
diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c
index 7cfd13c91568..eca32ccd45cc 100644
--- a/mm/memory_hotplug.c
+++ b/mm/memory_hotplug.c
@@ -1247,7 +1247,7 @@ static int online_memory_block(struct memory_block *mem, 
void *arg)
return device_online(>dev);
 }
 
-bool mhp_supports_memmap_on_memory(unsigned long size)
+static bool mhp_supports_memmap_on_memory(unsigned long size)
 {
unsigned long nr_vmemmap_pages = size / PAGE_SIZE;
unsigned long vmemmap_size = nr_vmemmap_pages * sizeof(struct page);
@@ -1339,13 +1339,12 @@ int __ref add_memory_resource(int nid, struct resource 
*res, mhp_t mhp_flags)
 * Self hosted memmap array
 */
if (mhp_flags & MHP_MEMMAP_ON_MEMORY) {
-   if (!mhp_supports_memmap_on_memory(size)) {
-   ret = -EINVAL;
-   goto error;
+   if (mhp_supports_memmap_on_memory(size)) {
+   mhp_altmap.free = PHYS_PFN(size);
+   mhp_altmap.base_pfn = PHYS_PFN(start);
+   params.altmap = _altmap;
}
-   mhp_altmap.free = PHYS_PFN(size);
-   mhp_altmap.base_pfn = PHYS_PFN(start);
-   params.altmap = _altmap;
+   /* fallback to not using altmap  */
}
 
/* call arch's memory hotadd */
-- 
2.41.0



[PATCH v8 1/6] mm/memory_hotplug: Simplify ARCH_MHP_MEMMAP_ON_MEMORY_ENABLE kconfig

2023-08-08 Thread Aneesh Kumar K.V
Instead of adding menu entry with all supported architectures, add
mm/Kconfig variable and select the same from supported architectures.

No functional change in this patch.

Acked-by: Michal Hocko 
Acked-by: David Hildenbrand 
Signed-off-by: Aneesh Kumar K.V 
---
 arch/arm64/Kconfig | 4 +---
 arch/x86/Kconfig   | 4 +---
 mm/Kconfig | 3 +++
 3 files changed, 5 insertions(+), 6 deletions(-)

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index b1573257a4d6..0f749cfab8e6 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -78,6 +78,7 @@ config ARM64
select ARCH_INLINE_SPIN_UNLOCK_IRQ if !PREEMPTION
select ARCH_INLINE_SPIN_UNLOCK_IRQRESTORE if !PREEMPTION
select ARCH_KEEP_MEMBLOCK
+   select ARCH_MHP_MEMMAP_ON_MEMORY_ENABLE
select ARCH_USE_CMPXCHG_LOCKREF
select ARCH_USE_GNU_PROPERTY
select ARCH_USE_MEMTEST
@@ -347,9 +348,6 @@ config GENERIC_CSUM
 config GENERIC_CALIBRATE_DELAY
def_bool y
 
-config ARCH_MHP_MEMMAP_ON_MEMORY_ENABLE
-   def_bool y
-
 config SMP
def_bool y
 
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 78224aa76409..d0258e92a8af 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -102,6 +102,7 @@ config X86
select ARCH_HAS_DEBUG_WX
select ARCH_HAS_ZONE_DMA_SET if EXPERT
select ARCH_HAVE_NMI_SAFE_CMPXCHG
+   select ARCH_MHP_MEMMAP_ON_MEMORY_ENABLE
select ARCH_MIGHT_HAVE_ACPI_PDC if ACPI
select ARCH_MIGHT_HAVE_PC_PARPORT
select ARCH_MIGHT_HAVE_PC_SERIO
@@ -2610,9 +2611,6 @@ config ARCH_HAS_ADD_PAGES
def_bool y
depends on ARCH_ENABLE_MEMORY_HOTPLUG
 
-config ARCH_MHP_MEMMAP_ON_MEMORY_ENABLE
-   def_bool y
-
 menu "Power management and ACPI options"
 
 config ARCH_HIBERNATION_HEADER
diff --git a/mm/Kconfig b/mm/Kconfig
index 5fe49c030961..721dc88423c7 100644
--- a/mm/Kconfig
+++ b/mm/Kconfig
@@ -571,6 +571,9 @@ config MHP_MEMMAP_ON_MEMORY
 
 endif # MEMORY_HOTPLUG
 
+config ARCH_MHP_MEMMAP_ON_MEMORY_ENABLE
+   bool
+
 # Heavily threaded applications may benefit from splitting the mm-wide
 # page_table_lock, so that faults on different parts of the user address
 # space can be handled with less contention: split it at this NR_CPUS.
-- 
2.41.0



[PATCH v8 0/6] Add support for memmap on memory feature on ppc64

2023-08-08 Thread Aneesh Kumar K.V
This patch series update memmap on memory feature to fall back to
memmap allocation outside the memory block if the alignment rules are
not met. This makes the feature more useful on architectures like
ppc64 where alignment rules are different with 64K page size.

This patch series is dependent on dax vmemmap optimization series
posted here
https://lore.kernel.org/linux-mm/20230718022934.90447-1-aneesh.ku...@linux.ibm.com/

Changes from v7:
* Drop patch 7 because we are still discussing a runtime update of this
feature is useful.

Changes from v6:
* Update comments in the code
* Update commit message for patch 7

Changes from v5:
* Update commit message
* Move memory alloc/free to the callers in patch 6
* Address review feedback w.r.t patch 4

Changes from v4:
* Use altmap.free instead of altmap.reserve
* Address review feedback

Changes from v3:
* Extend the module parameter memmap_on_memory to force allocation even
  though we can waste hotplug memory.

Changes from v2:
* Rebase to latest linus tree
* Redo the series based on review feedback. Multiple changes to the patchset.

Changes from v1:
* update the memblock to store vmemmap_altmap details. This is required
so that when we remove the memory we can find the altmap details which
is needed on some architectures.
* rebase to latest linus tree


Aneesh Kumar K.V (6):
  mm/memory_hotplug: Simplify ARCH_MHP_MEMMAP_ON_MEMORY_ENABLE kconfig
  mm/memory_hotplug: Allow memmap on memory hotplug request to fallback
  mm/memory_hotplug: Allow architecture to override memmap on memory
support check
  mm/memory_hotplug: Support memmap_on_memory when memmap is not aligned
to pageblocks
  powerpc/book3s64/memhotplug: Enable memmap on memory for radix
  mm/memory_hotplug: Embed vmem_altmap details in memory block

 .../admin-guide/mm/memory-hotplug.rst |  12 ++
 arch/arm64/Kconfig|   4 +-
 arch/powerpc/Kconfig  |   1 +
 arch/powerpc/include/asm/pgtable.h|  21 ++
 .../platforms/pseries/hotplug-memory.c|   2 +-
 arch/x86/Kconfig  |   4 +-
 drivers/acpi/acpi_memhotplug.c|   3 +-
 drivers/base/memory.c |  27 ++-
 include/linux/memory.h|   8 +-
 include/linux/memory_hotplug.h|   3 +-
 mm/Kconfig|   3 +
 mm/memory_hotplug.c   | 185 ++
 12 files changed, 209 insertions(+), 64 deletions(-)

-- 
2.41.0



Re: [PATCH v2 26/28] ASoC: codecs: Add support for the framer codec

2023-08-08 Thread Herve Codina
On Tue, 8 Aug 2023 08:26:16 +
Christophe Leroy  wrote:

> Le 26/07/2023 à 17:02, Herve Codina a écrit :
> > The framer codec interracts with a framer.
> > It allows to use some of the framer timeslots as audio channels to
> > transport audio data over the framer E1/T1/J1 lines.
> > It also reports line carrier detection events through the ALSA jack
> > detection feature.
> > 
> > Signed-off-by: Herve Codina   
> 
> Reviewed-by: Christophe Leroy 
> 
> See below
> 
> > +static int framer_dai_hw_rule_channels_by_format(struct snd_soc_dai *dai,
> > +struct snd_pcm_hw_params 
> > *params,
> > +unsigned int nb_ts)
> > +{
> > +   struct snd_interval *c = hw_param_interval(params, 
> > SNDRV_PCM_HW_PARAM_CHANNELS);
> > +   snd_pcm_format_t format = params_format(params);
> > +   struct snd_interval ch = {0};
> > +
> > +   switch (snd_pcm_format_physical_width(format)) {
> > +   case 8:
> > +   ch.max = nb_ts;
> > +   break;
> > +   case 16:
> > +   ch.max = nb_ts / 2;
> > +   break;
> > +   case 32:
> > +   ch.max = nb_ts / 4;
> > +   break;
> > +   case 64:
> > +   ch.max = nb_ts / 8;
> > +   break;
> > +   default:
> > +   dev_err(dai->dev, "format physical width %u not supported\n",
> > +   snd_pcm_format_physical_width(format));
> > +   return -EINVAL;
> > +   }  
> 
> What about
> 
>   width = snd_pcm_format_physical_width(format);
> 
>   if (width == 8 || width == 16 || width == 32 || width == 64) {
>   ch.max = nb_ts * 8 / width;
>   } else {
>   dev_err(dai->dev, "format physical width %u not supported\n", 
> width);
>   return -EINVAL;
>   }
> 

Yes, indeed.
Will be changed in the next iteration.

Regards,
Hervé


Re: [PATCH v2 24/28] pinctrl: Add support for the Lantic PEF2256 pinmux

2023-08-08 Thread Linus Walleij
On Mon, Aug 7, 2023 at 3:10 PM Mark Brown  wrote:
> On Mon, Aug 07, 2023 at 03:05:15PM +0200, Linus Walleij wrote:
> > On Wed, Jul 26, 2023 at 5:04 PM Herve Codina  
> > wrote:
>
> > > +#include "linux/bitfield.h"
>
> > Really? I don't think there is such a file there.
>
> > Do you mean  and does this even compile?
>
> #include "" means "try the local directory first then fall back to
> system includes" so it'll work, it picks up extra stuff on top of what
> <> does.  There's a stylistic issue though.

Wow that's a neat trick, I learn something new every day!

But we probably wanna be sure to get the system include.

Yours,
Linus Walleij


Re: [PATCH v2 22/28] mfd: core: Ensure disabled devices are skiped without aborting

2023-08-08 Thread Herve Codina
On Tue, 8 Aug 2023 08:13:27 +
Christophe Leroy  wrote:

> Le 26/07/2023 à 17:02, Herve Codina a écrit :
> > The loop searching for a matching device based on its compatible
> > string is aborted when a matching disabled device is found.
> > This abort avoid to add devices as soon as one disabled device
> > is found.  
> 
> s/avoid/prevents/

Yes, will be changed.

> 
> > 
> > Continue searching for an other device instead of aborting on the
> > first disabled one fixes the issue.
> > 
> > Fixes: 22380b65dc70 ("mfd: mfd-core: Ensure disabled devices are ignored 
> > without error")
> > Signed-off-by: Herve Codina   
> 
> Reviewed-by: Christophe Leroy 
> 



Re: [PATCH v2 28/28] net: wan: fsl_qmc_hdlc: Add framer support

2023-08-08 Thread Christophe Leroy


Le 26/07/2023 à 17:02, Herve Codina a écrit :
> Add framer support in the fsl_qmc_hdlc driver in order to be able to
> signal carrier changes to the network stack based on the framer status
> Also use this framer to provide information related to the E1/T1 line
> interface on IF_GET_IFACE and configure the line interface according to
> IF_IFACE_{E1,T1} information.
> 
> Signed-off-by: Herve Codina 

Reviewed-by: Christophe Leroy 

> ---
>   drivers/net/wan/fsl_qmc_hdlc.c | 239 -
>   1 file changed, 235 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/net/wan/fsl_qmc_hdlc.c b/drivers/net/wan/fsl_qmc_hdlc.c
> index c449edf0a35e..a873071fa5ca 100644
> --- a/drivers/net/wan/fsl_qmc_hdlc.c
> +++ b/drivers/net/wan/fsl_qmc_hdlc.c
> @@ -8,6 +8,7 @@
>*/
>   
>   #include 
> +#include 
>   #include 
>   #include 
>   #include 
> @@ -27,6 +28,9 @@ struct qmc_hdlc {
>   struct device *dev;
>   struct qmc_chan *qmc_chan;
>   struct net_device *netdev;
> + struct framer *framer;
> + spinlock_t carrier_lock; /* Protect carrier detection */
> + struct notifier_block nb;
>   bool is_crc32;
>   spinlock_t tx_lock; /* Protect tx descriptors */
>   struct qmc_hdlc_desc tx_descs[8];
> @@ -40,6 +44,195 @@ static inline struct qmc_hdlc *netdev_to_qmc_hdlc(struct 
> net_device *netdev)
>   return (struct qmc_hdlc *)dev_to_hdlc(netdev)->priv;
>   }
>   
> +static int qmc_hdlc_framer_set_carrier(struct qmc_hdlc *qmc_hdlc)
> +{
> + struct framer_status framer_status;
> + unsigned long flags;
> + int ret;
> +
> + if (!qmc_hdlc->framer)
> + return 0;
> +
> + spin_lock_irqsave(_hdlc->carrier_lock, flags);
> +
> + ret = framer_get_status(qmc_hdlc->framer, _status);
> + if (ret) {
> + dev_err(qmc_hdlc->dev, "get framer status failed (%d)\n", ret);
> + goto end;
> + }
> + if (framer_status.link_is_on)
> + netif_carrier_on(qmc_hdlc->netdev);
> + else
> + netif_carrier_off(qmc_hdlc->netdev);
> +
> +end:
> + spin_unlock_irqrestore(_hdlc->carrier_lock, flags);
> + return ret;
> +}
> +
> +static int qmc_hdlc_framer_notifier(struct notifier_block *nb, unsigned long 
> action,
> + void *data)
> +{
> + struct qmc_hdlc *qmc_hdlc = container_of(nb, struct qmc_hdlc, nb);
> + int ret;
> +
> + if (action != FRAMER_EVENT_STATUS)
> + return NOTIFY_DONE;
> +
> + ret = qmc_hdlc_framer_set_carrier(qmc_hdlc);
> + return ret ? NOTIFY_DONE : NOTIFY_OK;
> +}
> +
> +static int qmc_hdlc_framer_start(struct qmc_hdlc *qmc_hdlc)
> +{
> + struct framer_status framer_status;
> + int ret;
> +
> + if (!qmc_hdlc->framer)
> + return 0;
> +
> + ret = framer_power_on(qmc_hdlc->framer);
> + if (ret) {
> + dev_err(qmc_hdlc->dev, "framer power-on failed (%d)\n", ret);
> + return ret;
> + }
> +
> + /* Be sure that get_status is supported */
> + ret = framer_get_status(qmc_hdlc->framer, _status);
> + if (ret) {
> + dev_err(qmc_hdlc->dev, "get framer status failed (%d)\n", ret);
> + goto framer_power_off;
> + }
> +
> + qmc_hdlc->nb.notifier_call = qmc_hdlc_framer_notifier;
> + ret = framer_notifier_register(qmc_hdlc->framer, _hdlc->nb);
> + if (ret) {
> + dev_err(qmc_hdlc->dev, "framer notifier register failed 
> (%d)\n", ret);
> + goto framer_power_off;
> + }
> +
> + return 0;
> +
> +framer_power_off:
> + framer_power_off(qmc_hdlc->framer);
> + return ret;
> +}
> +
> +static void qmc_hdlc_framer_stop(struct qmc_hdlc *qmc_hdlc)
> +{
> + if (!qmc_hdlc->framer)
> + return;
> +
> + framer_notifier_unregister(qmc_hdlc->framer, _hdlc->nb);
> + framer_power_off(qmc_hdlc->framer);
> +}
> +
> +static int qmc_hdlc_framer_set_iface(struct qmc_hdlc *qmc_hdlc, int if_iface,
> +  const te1_settings *te1)
> +{
> + struct framer_config config;
> + int ret;
> +
> + if (!qmc_hdlc->framer)
> + return 0;
> +
> + ret = framer_get_config(qmc_hdlc->framer, );
> + if (ret)
> + return ret;
> +
> + switch (if_iface) {
> + case IF_IFACE_E1:
> + config.iface = FRAMER_IFACE_E1;
> + break;
> + case IF_IFACE_T1:
> + config.iface = FRAMER_IFACE_T1;
> + break;
> + default:
> + return -EINVAL;
> + }
> +
> + switch (te1->clock_type) {
> + case CLOCK_DEFAULT:
> + /* Keep current value */
> + break;
> + case CLOCK_EXT:
> + config.clock_type = FRAMER_CLOCK_EXT;
> + break;
> + case CLOCK_INT:
> + config.clock_type = FRAMER_CLOCK_INT;
> + break;
> + default:
> + return -EINVAL;
> + }
> + config.line_clock_rate = te1->clock_rate;

Re: [PATCH v2 26/28] ASoC: codecs: Add support for the framer codec

2023-08-08 Thread Christophe Leroy


Le 26/07/2023 à 17:02, Herve Codina a écrit :
> The framer codec interracts with a framer.
> It allows to use some of the framer timeslots as audio channels to
> transport audio data over the framer E1/T1/J1 lines.
> It also reports line carrier detection events through the ALSA jack
> detection feature.
> 
> Signed-off-by: Herve Codina 

Reviewed-by: Christophe Leroy 

See below

> +static int framer_dai_hw_rule_channels_by_format(struct snd_soc_dai *dai,
> +  struct snd_pcm_hw_params 
> *params,
> +  unsigned int nb_ts)
> +{
> + struct snd_interval *c = hw_param_interval(params, 
> SNDRV_PCM_HW_PARAM_CHANNELS);
> + snd_pcm_format_t format = params_format(params);
> + struct snd_interval ch = {0};
> +
> + switch (snd_pcm_format_physical_width(format)) {
> + case 8:
> + ch.max = nb_ts;
> + break;
> + case 16:
> + ch.max = nb_ts / 2;
> + break;
> + case 32:
> + ch.max = nb_ts / 4;
> + break;
> + case 64:
> + ch.max = nb_ts / 8;
> + break;
> + default:
> + dev_err(dai->dev, "format physical width %u not supported\n",
> + snd_pcm_format_physical_width(format));
> + return -EINVAL;
> + }

What about

width = snd_pcm_format_physical_width(format);

if (width == 8 || width == 16 || width == 32 || width == 64) {
ch.max = nb_ts * 8 / width;
} else {
dev_err(dai->dev, "format physical width %u not supported\n", 
width);
return -EINVAL;
}



Re: [PATCH v2 25/28] MAINTAINERS: Add the Lantiq PEF2256 driver entry

2023-08-08 Thread Christophe Leroy


Le 26/07/2023 à 17:02, Herve Codina a écrit :
> After contributing the driver, add myself as the maintainer for the
> Lantiq PEF2256 driver.
> 
> Signed-off-by: Herve Codina 

Reviewed-by: Christophe Leroy 

> ---
>   MAINTAINERS | 9 +
>   1 file changed, 9 insertions(+)
> 
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 14041d90f9c8..07a7d9fca3c4 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -11776,6 +11776,15 @@ S:   Maintained
>   F:  arch/mips/lantiq
>   F:  drivers/soc/lantiq
>   
> +LANTIQ PEF2256 DRIVER
> +M:   Herve Codina 
> +S:   Maintained
> +F:   Documentation/devicetree/bindings/net/lantiq,pef2256.yaml
> +F:   drivers/net/wan/framer/pef2256/
> +F:   drivers/pinctrl/pinctrl-pef2256-regs.h
> +F:   drivers/pinctrl/pinctrl-pef2256.c
> +F:   include/linux/framer/pef2256.h
> +
>   LASI 53c700 driver for PARISC
>   M:  "James E.J. Bottomley" 
>   L:  linux-s...@vger.kernel.org


Re: [PATCH v2 24/28] pinctrl: Add support for the Lantic PEF2256 pinmux

2023-08-08 Thread Christophe Leroy


Le 26/07/2023 à 17:02, Herve Codina a écrit :
> The Lantiq PEF2256 is a framer and line interface component designed to
> fulfill all required interfacing between an analog E1/T1/J1 line and the
> digital PCM system highway/H.100 bus.
> 
> This pinmux support handles the pin muxing part (pins RP(A..D) and pins
> XP(A..D)) of the PEF2256.
> 
> Signed-off-by: Herve Codina 

Reviewed-by: Christophe Leroy 

> ---
>   drivers/pinctrl/Kconfig|  14 ++
>   drivers/pinctrl/Makefile   |   1 +
>   drivers/pinctrl/pinctrl-pef2256-regs.h |  65 ++
>   drivers/pinctrl/pinctrl-pef2256.c  | 310 +
>   4 files changed, 390 insertions(+)
>   create mode 100644 drivers/pinctrl/pinctrl-pef2256-regs.h
>   create mode 100644 drivers/pinctrl/pinctrl-pef2256.c
> 
> diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig
> index 57d57af1f624..a3aa96b59c97 100644
> --- a/drivers/pinctrl/Kconfig
> +++ b/drivers/pinctrl/Kconfig
> @@ -377,6 +377,20 @@ config PINCTRL_PALMAS
> open drain configuration for the Palmas series devices like
> TPS65913, TPS80036 etc.
>   
> +config PINCTRL_PEF2256
> + tristate "Lantiq PEF2256 (FALC56) pin controller driver"
> + depends on OF && FRAMER_PEF2256
> + select PINMUX
> + select GENERIC_PINCONF
> + help
> +   This option enables the pin controller support for the Lantiq PEF2256
> +   framer, also known as FALC56.
> +
> +   If unsure, say N.
> +
> +   To compile this driver as a module, choose M here: the
> +   module will be called pinctrl-pef2256.
> +
>   config PINCTRL_PIC32
>   bool "Microchip PIC32 pin controller driver"
>   depends on OF
> diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile
> index 482b391b5deb..8f211f7671a8 100644
> --- a/drivers/pinctrl/Makefile
> +++ b/drivers/pinctrl/Makefile
> @@ -40,6 +40,7 @@ obj-$(CONFIG_PINCTRL_MLXBF3)+= pinctrl-mlxbf3.o
>   obj-$(CONFIG_PINCTRL_OCELOT)+= pinctrl-ocelot.o
>   obj-$(CONFIG_PINCTRL_OXNAS) += pinctrl-oxnas.o
>   obj-$(CONFIG_PINCTRL_PALMAS)+= pinctrl-palmas.o
> +obj-$(CONFIG_PINCTRL_PEF2256)+= pinctrl-pef2256.o
>   obj-$(CONFIG_PINCTRL_PIC32) += pinctrl-pic32.o
>   obj-$(CONFIG_PINCTRL_PISTACHIO) += pinctrl-pistachio.o
>   obj-$(CONFIG_PINCTRL_RK805) += pinctrl-rk805.o
> diff --git a/drivers/pinctrl/pinctrl-pef2256-regs.h 
> b/drivers/pinctrl/pinctrl-pef2256-regs.h
> new file mode 100644
> index ..586d94007e24
> --- /dev/null
> +++ b/drivers/pinctrl/pinctrl-pef2256-regs.h
> @@ -0,0 +1,65 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +/*
> + * PEF2256 pinctrl registers definition
> + *
> + * Copyright 2023 CS GROUP France
> + *
> + * Author: Herve Codina 
> + */
> +#ifndef __PEF2256_PINCTRL_REGS_H__
> +#define __PEF2256_PINCTRL_REGS_H__
> +
> +#include "linux/bitfield.h"
> +
> +/* Port Configuration 1..4 */
> +#define PEF2256_PC10x80
> +#define PEF2256_PC20x81
> +#define PEF2256_PC30x82
> +#define PEF2256_PC40x83
> +#define PEF2256_12_PC_RPC_MASK GENMASK(6, 4)
> +#define PEF2256_12_PC_RPC_SYPR 
> FIELD_PREP_CONST(PEF2256_12_PC_RPC_MASK, 0x0)
> +#define PEF2256_12_PC_RPC_RFM  
> FIELD_PREP_CONST(PEF2256_12_PC_RPC_MASK, 0x1)
> +#define PEF2256_12_PC_RPC_RFMB 
> FIELD_PREP_CONST(PEF2256_12_PC_RPC_MASK, 0x2)
> +#define PEF2256_12_PC_RPC_RSIGM
> FIELD_PREP_CONST(PEF2256_12_PC_RPC_MASK, 0x3)
> +#define PEF2256_12_PC_RPC_RSIG 
> FIELD_PREP_CONST(PEF2256_12_PC_RPC_MASK, 0x4)
> +#define PEF2256_12_PC_RPC_DLR  
> FIELD_PREP_CONST(PEF2256_12_PC_RPC_MASK, 0x5)
> +#define PEF2256_12_PC_RPC_FREEZE  FIELD_PREP_CONST(PEF2256_12_PC_RPC_MASK, 
> 0x6)
> +#define PEF2256_12_PC_RPC_RFSP 
> FIELD_PREP_CONST(PEF2256_12_PC_RPC_MASK, 0x7)
> +#define PEF2256_12_PC_XPC_MASKGENMASK(4, 0)
> +#define PEF2256_12_PC_XPC_SYPX 
> FIELD_PREP_CONST(PEF2256_12_PC_XPC_MASK, 0x0)
> +#define PEF2256_12_PC_XPC_XFMS 
> FIELD_PREP_CONST(PEF2256_12_PC_XPC_MASK, 0x1)
> +#define PEF2256_12_PC_XPC_XSIG 
> FIELD_PREP_CONST(PEF2256_12_PC_XPC_MASK, 0x2)
> +#define PEF2256_12_PC_XPC_TCLK 
> FIELD_PREP_CONST(PEF2256_12_PC_XPC_MASK, 0x3)
> +#define PEF2256_12_PC_XPC_XMFB 
> FIELD_PREP_CONST(PEF2256_12_PC_XPC_MASK, 0x4)
> +#define PEF2256_12_PC_XPC_XSIGM
> FIELD_PREP_CONST(PEF2256_12_PC_XPC_MASK, 0x5)
> +#define PEF2256_12_PC_XPC_DLX  
> FIELD_PREP_CONST(PEF2256_12_PC_XPC_MASK, 0x6)
> +#define PEF2256_12_PC_XPC_XCLK 
> FIELD_PREP_CONST(PEF2256_12_PC_XPC_MASK, 0x7)
> +#define PEF2256_12_PC_XPC_XLT  
> FIELD_PREP_CONST(PEF2256_12_PC_XPC_MASK, 0x8)
> +#define PEF2256_2X_PC_RPC_MASK GENMASK(7, 4)
> +#define PEF2256_2X_PC_RPC_SYPR 
> FIELD_PREP_CONST(PEF2256_2X_PC_RPC_MASK, 0x0)
> +#define PEF2256_2X_PC_RPC_RFM  
> FIELD_PREP_CONST(PEF2256_2X_PC_RPC_MASK, 0x1)
> +#define PEF2256_2X_PC_RPC_RFMB

Re: [PATCH v2 23/28] net: wan: framer: Add support for the Lantiq PEF2256 framer

2023-08-08 Thread Christophe Leroy


Le 26/07/2023 à 17:02, Herve Codina a écrit :
> The Lantiq PEF2256 is a framer and line interface component designed to
> fulfill all required interfacing between an analog E1/T1/J1 line and the
> digital PCM system highway/H.100 bus.
> 
> Signed-off-by: Herve Codina 

Reviewed-by: Christophe Leroy 

> ---
>   drivers/net/wan/framer/Kconfig|  16 +
>   drivers/net/wan/framer/Makefile   |   1 +
>   drivers/net/wan/framer/pef2256/Makefile   |   8 +
>   drivers/net/wan/framer/pef2256/pef2256-regs.h | 250 +
>   drivers/net/wan/framer/pef2256/pef2256.c  | 880 ++
>   include/linux/framer/pef2256.h|  31 +
>   6 files changed, 1186 insertions(+)
>   create mode 100644 drivers/net/wan/framer/pef2256/Makefile
>   create mode 100644 drivers/net/wan/framer/pef2256/pef2256-regs.h
>   create mode 100644 drivers/net/wan/framer/pef2256/pef2256.c
>   create mode 100644 include/linux/framer/pef2256.h
> 
> diff --git a/drivers/net/wan/framer/Kconfig b/drivers/net/wan/framer/Kconfig
> index 96ef1e7ba8eb..ba43d7f162a2 100644
> --- a/drivers/net/wan/framer/Kconfig
> +++ b/drivers/net/wan/framer/Kconfig
> @@ -16,4 +16,20 @@ config GENERIC_FRAMER
> framework and framer users can obtain reference to the framer.
> All the users of this framework should select this config.
>   
> +config FRAMER_PEF2256
> + tristate "Lantiq PEF2256"
> + depends on OF
> + select GENERIC_FRAMER
> + select MFD_CORE
> + select REGMAP_MMIO
> + help
> +   Enable support for the Lantiq PEF2256 (FALC56) framer.
> +   The PEF2256 is a framer and line interface between analog E1/T1/J1
> +   line and a digital PCM bus.
> +
> +   If unsure, say N.
> +
> +   To compile this driver as a module, choose M here: the
> +   module will be called framer-pef2256.
> +
>   endmenu
> diff --git a/drivers/net/wan/framer/Makefile b/drivers/net/wan/framer/Makefile
> index 78dbd8e563d0..3403f2b14534 100644
> --- a/drivers/net/wan/framer/Makefile
> +++ b/drivers/net/wan/framer/Makefile
> @@ -4,3 +4,4 @@
>   #
>   
>   obj-$(CONFIG_GENERIC_FRAMER)+= framer-core.o
> +obj-$(CONFIG_FRAMER_PEF2256) += pef2256/
> diff --git a/drivers/net/wan/framer/pef2256/Makefile 
> b/drivers/net/wan/framer/pef2256/Makefile
> new file mode 100644
> index ..f4d1208dd8a4
> --- /dev/null
> +++ b/drivers/net/wan/framer/pef2256/Makefile
> @@ -0,0 +1,8 @@
> +# SPDX-License-Identifier: GPL-2.0
> +#
> +# Makefile for the pef2256 driver.
> +#
> +
> +obj-$(CONFIG_FRAMER_PEF2256) += framer-pef2256.o
> +
> +framer-pef2256-objs  := pef2256.o
> diff --git a/drivers/net/wan/framer/pef2256/pef2256-regs.h 
> b/drivers/net/wan/framer/pef2256/pef2256-regs.h
> new file mode 100644
> index ..5d3183c91714
> --- /dev/null
> +++ b/drivers/net/wan/framer/pef2256/pef2256-regs.h
> @@ -0,0 +1,250 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +/*
> + * PEF2256 registers definition
> + *
> + * Copyright 2023 CS GROUP France
> + *
> + * Author: Herve Codina 
> + */
> +#ifndef __PEF2256_REGS_H__
> +#define __PEF2256_REGS_H__
> +
> +#include "linux/bitfield.h"
> +
> +/* Command Register */
> +#define PEF2256_CMDR 0x02
> +#define PEF2256_CMDR_RRESBIT(6)
> +#define PEF2256_CMDR_XRESBIT(4)
> +#define PEF2256_CMDR_SRESBIT(0)
> +
> +/* Interrupt Mask Register 0..5 */
> +#define PEF2256_IMR0 0x14
> +#define PEF2256_IMR1 0x15
> +#define PEF2256_IMR2 0x16
> +#define PEF2256_IMR3 0x17
> +#define PEF2256_IMR4 0x18
> +#define PEF2256_IMR5 0x19
> +
> +/* Framer Mode Register 0 */
> +#define PEF2256_FMR0 0x1C
> +#define PEF2256_FMR0_XC_MASK GENMASK(7, 6)
> +#define PEF2256_FMR0_XC_NRZ  FIELD_PREP_CONST(PEF2256_FMR0_XC_MASK, 0x0)
> +#define PEF2256_FMR0_XC_CMI  FIELD_PREP_CONST(PEF2256_FMR0_XC_MASK, 0x1)
> +#define PEF2256_FMR0_XC_AMI  FIELD_PREP_CONST(PEF2256_FMR0_XC_MASK, 0x2)
> +#define PEF2256_FMR0_XC_HDB3 FIELD_PREP_CONST(PEF2256_FMR0_XC_MASK, 0x3)
> +#define PEF2256_FMR0_RC_MASK GENMASK(5, 4)
> +#define PEF2256_FMR0_RC_NRZ  FIELD_PREP_CONST(PEF2256_FMR0_RC_MASK, 0x0)
> +#define PEF2256_FMR0_RC_CMI  FIELD_PREP_CONST(PEF2256_FMR0_RC_MASK, 0x1)
> +#define PEF2256_FMR0_RC_AMI  FIELD_PREP_CONST(PEF2256_FMR0_RC_MASK, 0x2)
> +#define PEF2256_FMR0_RC_HDB3 FIELD_PREP_CONST(PEF2256_FMR0_RC_MASK, 0x3)
> +
> +/* Framer Mode Register 1 */
> +#define PEF2256_FMR1 0x1D
> +#define PEF2256_FMR1_XFS BIT(3)
> +#define PEF2256_FMR1_ECM BIT(2)
> +/* SSD is defined on 2 bits. The other bit is on SIC1 register */
> +#define PEF2256_FMR1_SSD_MASKGENMASK(1, 1)
> +#define PEF2256_FMR1_SSD_2048FIELD_PREP_CONST(PEF2256_FMR1_SSD_MASK, 
> 0x0)
> +#define PEF2256_FMR1_SSD_4096FIELD_PREP_CONST(PEF2256_FMR1_SSD_MASK, 
> 0x1)
> +#define PEF2256_FMR1_SSD_8192FIELD_PREP_CONST(PEF2256_FMR1_SSD_MASK, 
> 0x0)
> +#define PEF2256_FMR1_SSD_16384   

Re: [PATCH v2 22/28] mfd: core: Ensure disabled devices are skiped without aborting

2023-08-08 Thread Christophe Leroy


Le 26/07/2023 à 17:02, Herve Codina a écrit :
> The loop searching for a matching device based on its compatible
> string is aborted when a matching disabled device is found.
> This abort avoid to add devices as soon as one disabled device
> is found.

s/avoid/prevents/

> 
> Continue searching for an other device instead of aborting on the
> first disabled one fixes the issue.
> 
> Fixes: 22380b65dc70 ("mfd: mfd-core: Ensure disabled devices are ignored 
> without error")
> Signed-off-by: Herve Codina 

Reviewed-by: Christophe Leroy 

> ---
>   drivers/mfd/mfd-core.c | 18 +-
>   1 file changed, 13 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/mfd/mfd-core.c b/drivers/mfd/mfd-core.c
> index 0ed7c0d7784e..bcc26e64639a 100644
> --- a/drivers/mfd/mfd-core.c
> +++ b/drivers/mfd/mfd-core.c
> @@ -146,6 +146,7 @@ static int mfd_add_device(struct device *parent, int id,
>   struct platform_device *pdev;
>   struct device_node *np = NULL;
>   struct mfd_of_node_entry *of_entry, *tmp;
> + bool disabled;
>   int ret = -ENOMEM;
>   int platform_id;
>   int r;
> @@ -181,13 +182,13 @@ static int mfd_add_device(struct device *parent, int id,
>   goto fail_res;
>   
>   if (IS_ENABLED(CONFIG_OF) && parent->of_node && cell->of_compatible) {
> + disabled = false;
>   for_each_child_of_node(parent->of_node, np) {
>   if (of_device_is_compatible(np, cell->of_compatible)) {
> - /* Ignore 'disabled' devices error free */
> + /* Skip 'disabled' devices */
>   if (!of_device_is_available(np)) {
> - of_node_put(np);
> - ret = 0;
> - goto fail_alias;
> + disabled = true;
> + continue;
>   }
>   
>   ret = mfd_match_of_node_to_dev(pdev, np, cell);
> @@ -197,10 +198,17 @@ static int mfd_add_device(struct device *parent, int id,
>   if (ret)
>   goto fail_alias;
>   
> - break;
> + goto match;
>   }
>   }
>   
> + if (disabled) {
> + /* Ignore 'disabled' devices error free */
> + ret = 0;
> + goto fail_alias;
> + }
> +
> +match:
>   if (!pdev->dev.of_node)
>   pr_warn("%s: Failed to locate of_node [id: %d]\n",
>   cell->name, platform_id);


Re: [PATCH v2 20/28] net: wan: Add framer framework support

2023-08-08 Thread Christophe Leroy


Le 26/07/2023 à 17:02, Herve Codina a écrit :
> A framer is a component in charge of an E1/T1 line interface.
> Connected usually to a TDM bus, it converts TDM frames to/from E1/T1
> frames. It also provides information related to the E1/T1 line.
> 
> The framer framework provides a set of APIs for the framer drivers
> (framer provider) to create/destroy a framer and APIs for the framer
> users (framer consumer) to obtain a reference to the framer, and
> use the framer.
> 
> This basic implementation provides a framer abstraction for:
>   - power on/off the framer
>   - get the framer status (line state)
>   - be notified on framer status changes
>   - get/set the framer configuration
> 
> Signed-off-by: Herve Codina 

Reviewed-by: Christophe Leroy 

> ---
>   drivers/net/wan/Kconfig|   2 +
>   drivers/net/wan/Makefile   |   2 +
>   drivers/net/wan/framer/Kconfig |  19 +
>   drivers/net/wan/framer/Makefile|   6 +
>   drivers/net/wan/framer/framer-core.c   | 935 +
>   include/linux/framer/framer-provider.h | 194 +
>   include/linux/framer/framer.h  | 215 ++
>   7 files changed, 1373 insertions(+)
>   create mode 100644 drivers/net/wan/framer/Kconfig
>   create mode 100644 drivers/net/wan/framer/Makefile
>   create mode 100644 drivers/net/wan/framer/framer-core.c
>   create mode 100644 include/linux/framer/framer-provider.h
>   create mode 100644 include/linux/framer/framer.h
> 
> diff --git a/drivers/net/wan/Kconfig b/drivers/net/wan/Kconfig
> index 8de99f4b647b..31ab2136cdf1 100644
> --- a/drivers/net/wan/Kconfig
> +++ b/drivers/net/wan/Kconfig
> @@ -95,6 +95,8 @@ config HDLC_X25
>   comment "X.25/LAPB support is disabled"
>   depends on HDLC && (LAPB!=m || HDLC!=m) && LAPB!=y
>   
> +source "drivers/net/wan/framer/Kconfig"
> +
>   config PCI200SYN
>   tristate "Goramo PCI200SYN support"
>   depends on HDLC && PCI
> diff --git a/drivers/net/wan/Makefile b/drivers/net/wan/Makefile
> index f338f4830626..00e9b7ee1e01 100644
> --- a/drivers/net/wan/Makefile
> +++ b/drivers/net/wan/Makefile
> @@ -14,6 +14,8 @@ obj-$(CONFIG_HDLC_FR)   += hdlc_fr.o
>   obj-$(CONFIG_HDLC_PPP)  += hdlc_ppp.o
>   obj-$(CONFIG_HDLC_X25)  += hdlc_x25.o
>   
> +obj-y+= framer/
> +
>   obj-$(CONFIG_FARSYNC)   += farsync.o
>   
>   obj-$(CONFIG_LAPBETHER) += lapbether.o
> diff --git a/drivers/net/wan/framer/Kconfig b/drivers/net/wan/framer/Kconfig
> new file mode 100644
> index ..96ef1e7ba8eb
> --- /dev/null
> +++ b/drivers/net/wan/framer/Kconfig
> @@ -0,0 +1,19 @@
> +# SPDX-License-Identifier: GPL-2.0-only
> +#
> +# FRAMER
> +#
> +
> +menu "Framer Subsystem"
> +
> +config GENERIC_FRAMER
> + bool "Framer Core"
> + help
> +   Generic Framer support.
> +
> +   This framework is designed to provide a generic interface for framer
> +   devices present in the kernel. This layer will have the generic
> +   API by which framer drivers can create framer using the framer
> +   framework and framer users can obtain reference to the framer.
> +   All the users of this framework should select this config.
> +
> +endmenu
> diff --git a/drivers/net/wan/framer/Makefile b/drivers/net/wan/framer/Makefile
> new file mode 100644
> index ..78dbd8e563d0
> --- /dev/null
> +++ b/drivers/net/wan/framer/Makefile
> @@ -0,0 +1,6 @@
> +# SPDX-License-Identifier: GPL-2.0
> +#
> +# Makefile for the framer drivers.
> +#
> +
> +obj-$(CONFIG_GENERIC_FRAMER) += framer-core.o
> diff --git a/drivers/net/wan/framer/framer-core.c 
> b/drivers/net/wan/framer/framer-core.c
> new file mode 100644
> index ..ef93b7d74fd1
> --- /dev/null
> +++ b/drivers/net/wan/framer/framer-core.c
> @@ -0,0 +1,935 @@
> +// SPDX-License-Identifier: GPL-2.0-or-later
> +/*
> + * Generic Framer framework.
> + *
> + * Copyright 2023 CS GROUP France
> + *
> + * Author: Herve Codina 
> + */
> +
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +
> +static struct class *framer_class;
> +static DEFINE_MUTEX(framer_provider_mutex);
> +static LIST_HEAD(framer_provider_list);
> +static DEFINE_IDA(framer_ida);
> +
> +#define dev_to_framer(a) (container_of((a), struct framer, dev))
> +
> +int framer_pm_runtime_get(struct framer *framer)
> +{
> + int ret;
> +
> + if (!framer)
> + return 0;
> +
> + if (!pm_runtime_enabled(>dev))
> + return -EOPNOTSUPP;
> +
> + ret = pm_runtime_get(>dev);
> + if (ret < 0 && ret != -EINPROGRESS)
> + pm_runtime_put_noidle(>dev);
> +
> + return ret;
> +}
> +EXPORT_SYMBOL_GPL(framer_pm_runtime_get);
> +
> +int framer_pm_runtime_get_sync(struct framer *framer)
> +{
> + int ret;
> +
> + if (!framer)
> + return 0;
> +
> + if 

Re: [PATCH v2 19/28] wan: qmc_hdlc: Add runtime timeslots changes support

2023-08-08 Thread Christophe Leroy


Le 26/07/2023 à 17:02, Herve Codina a écrit :
> QMC channels support runtime timeslots changes but nothing is done at
> the QMC HDLC driver to handle these changes.
> 
> Use existing IFACE ioctl in order to configure the timeslots to use.
> 
> Signed-off-by: Herve Codina 

Reviewed-by: Christophe Leroy 

> ---
>   drivers/net/wan/fsl_qmc_hdlc.c | 169 -
>   1 file changed, 168 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/net/wan/fsl_qmc_hdlc.c b/drivers/net/wan/fsl_qmc_hdlc.c
> index b4ebae963d39..c449edf0a35e 100644
> --- a/drivers/net/wan/fsl_qmc_hdlc.c
> +++ b/drivers/net/wan/fsl_qmc_hdlc.c
> @@ -32,6 +32,7 @@ struct qmc_hdlc {
>   struct qmc_hdlc_desc tx_descs[8];
>   unsigned int tx_out;
>   struct qmc_hdlc_desc rx_descs[4];
> + u32 slot_map;
>   };
>   
>   static inline struct qmc_hdlc *netdev_to_qmc_hdlc(struct net_device *netdev)
> @@ -202,6 +203,162 @@ static netdev_tx_t qmc_hdlc_xmit(struct sk_buff *skb, 
> struct net_device *netdev)
>   return NETDEV_TX_OK;
>   }
>   
> +static int qmc_hdlc_xlate_slot_map(struct qmc_hdlc *qmc_hdlc,
> +u32 slot_map, struct qmc_chan_ts_info 
> *ts_info)
> +{
> + u64 ts_mask_avail;
> + unsigned int bit;
> + unsigned int i;
> + u64 ts_mask;
> + u64 map = 0;
> +
> + /* Tx and Rx masks must be identical */
> + if (ts_info->rx_ts_mask_avail != ts_info->tx_ts_mask_avail) {
> + dev_err(qmc_hdlc->dev, "tx and rx available timeslots mismatch 
> (0x%llx, 0x%llx)\n",
> + ts_info->rx_ts_mask_avail, ts_info->tx_ts_mask_avail);
> + return -EINVAL;
> + }
> +
> + ts_mask_avail = ts_info->rx_ts_mask_avail;
> + ts_mask = 0;
> + map = slot_map;
> + bit = 0;
> + for (i = 0; i < 64; i++) {
> + if (ts_mask_avail & BIT_ULL(i)) {
> + if (map & BIT_ULL(bit))
> + ts_mask |= BIT_ULL(i);
> + bit++;
> + }
> + }
> +
> + if (hweight64(ts_mask) != hweight64(map)) {
> + dev_err(qmc_hdlc->dev, "Cannot translate timeslots 0x%llx -> 
> (0x%llx,0x%llx)\n",
> + map, ts_mask_avail, ts_mask);
> + return -EINVAL;
> + }
> +
> + ts_info->tx_ts_mask = ts_mask;
> + ts_info->rx_ts_mask = ts_mask;
> + return 0;
> +}
> +
> +static int qmc_hdlc_xlate_ts_info(struct qmc_hdlc *qmc_hdlc,
> +   const struct qmc_chan_ts_info *ts_info, u32 
> *slot_map)
> +{
> + u64 ts_mask_avail;
> + unsigned int bit;
> + unsigned int i;
> + u64 ts_mask;
> + u64 map = 0;
> +
> + /* Tx and Rx masks must be identical */
> + if (ts_info->rx_ts_mask_avail != ts_info->tx_ts_mask_avail) {
> + dev_err(qmc_hdlc->dev, "tx and rx available timeslots mismatch 
> (0x%llx, 0x%llx)\n",
> + ts_info->rx_ts_mask_avail, ts_info->tx_ts_mask_avail);
> + return -EINVAL;
> + }
> + if (ts_info->rx_ts_mask != ts_info->tx_ts_mask) {
> + dev_err(qmc_hdlc->dev, "tx and rx timeslots mismatch (0x%llx, 
> 0x%llx)\n",
> + ts_info->rx_ts_mask, ts_info->tx_ts_mask);
> + return -EINVAL;
> + }
> +
> + ts_mask_avail = ts_info->rx_ts_mask_avail;
> + ts_mask = ts_info->rx_ts_mask;
> + map = 0;
> + bit = 0;
> + for (i = 0; i < 64; i++) {
> + if (ts_mask_avail & BIT_ULL(i)) {
> + if (ts_mask & BIT_ULL(i))
> + map |= BIT_ULL(bit);
> + bit++;
> + }
> + }
> +
> + if (hweight64(ts_mask) != hweight64(map)) {
> + dev_err(qmc_hdlc->dev, "Cannot translate timeslots 
> (0x%llx,0x%llx) -> 0x%llx\n",
> + ts_mask_avail, ts_mask, map);
> + return -EINVAL;
> + }
> +
> + if (map >= BIT_ULL(32)) {
> + dev_err(qmc_hdlc->dev, "Slot map out of 32bit (0x%llx,0x%llx) 
> -> 0x%llx\n",
> + ts_mask_avail, ts_mask, map);
> + return -EINVAL;
> + }
> +
> + *slot_map = map;
> + return 0;
> +}
> +
> +static int qmc_hdlc_set_iface(struct qmc_hdlc *qmc_hdlc, int if_iface, const 
> te1_settings *te1)
> +{
> + struct qmc_chan_ts_info ts_info;
> + int ret;
> +
> + ret = qmc_chan_get_ts_info(qmc_hdlc->qmc_chan, _info);
> + if (ret) {
> + dev_err(qmc_hdlc->dev, "get QMC channel ts info failed %d\n", 
> ret);
> + return ret;
> + }
> + ret = qmc_hdlc_xlate_slot_map(qmc_hdlc, te1->slot_map, _info);
> + if (ret)
> + return ret;
> +
> + ret = qmc_chan_set_ts_info(qmc_hdlc->qmc_chan, _info);
> + if (ret) {
> + dev_err(qmc_hdlc->dev, "set QMC channel ts info failed %d\n", 
> ret);
> + return ret;
> + }
> +
> + qmc_hdlc->slot_map = te1->slot_map;
> +
> + return 0;
> +}
> +
> +static int 

Re: [PATCH v2 18/28] soc: fsl: cpm1: qmc: Introduce functions to change timeslots at runtime

2023-08-08 Thread Christophe Leroy


Le 26/07/2023 à 17:02, Herve Codina a écrit :
> Introduce qmc_chan_{get,set}_ts_info() function to allow timeslots
> modification at runtime.
> 
> The modification is provided using qmc_chan_set_ts_info() and will be
> applied on next qmc_chan_start().
> qmc_chan_set_ts_info() must be called with the channel rx and/or tx
> stopped.
> 
> Signed-off-by: Herve Codina 

Reviewed-by: Christophe Leroy 

> ---
>   drivers/soc/fsl/qe/qmc.c | 51 
>   include/soc/fsl/qe/qmc.h | 10 
>   2 files changed, 61 insertions(+)
> 
> diff --git a/drivers/soc/fsl/qe/qmc.c b/drivers/soc/fsl/qe/qmc.c
> index b1883b9d2bae..e3953bc07b1f 100644
> --- a/drivers/soc/fsl/qe/qmc.c
> +++ b/drivers/soc/fsl/qe/qmc.c
> @@ -290,6 +290,57 @@ int qmc_chan_get_info(struct qmc_chan *chan, struct 
> qmc_chan_info *info)
>   }
>   EXPORT_SYMBOL(qmc_chan_get_info);
>   
> +int qmc_chan_get_ts_info(struct qmc_chan *chan, struct qmc_chan_ts_info 
> *ts_info)
> +{
> + unsigned long flags;
> +
> + spin_lock_irqsave(>ts_lock, flags);
> +
> + ts_info->rx_ts_mask_avail = chan->rx_ts_mask_avail;
> + ts_info->tx_ts_mask_avail = chan->tx_ts_mask_avail;
> + ts_info->rx_ts_mask = chan->rx_ts_mask;
> + ts_info->tx_ts_mask = chan->tx_ts_mask;
> +
> + spin_unlock_irqrestore(>ts_lock, flags);
> +
> + return 0;
> +}
> +EXPORT_SYMBOL(qmc_chan_get_ts_info);
> +
> +int qmc_chan_set_ts_info(struct qmc_chan *chan, const struct 
> qmc_chan_ts_info *ts_info)
> +{
> + unsigned long flags;
> + int ret;
> +
> + /* Only a subset of available timeslots is allowed */
> + if ((ts_info->rx_ts_mask & chan->rx_ts_mask_avail) != 
> ts_info->rx_ts_mask)
> + return -EINVAL;
> + if ((ts_info->tx_ts_mask & chan->tx_ts_mask_avail) != 
> ts_info->tx_ts_mask)
> + return -EINVAL;
> +
> + /* In case of common rx/tx table, rx/tx masks must be identical */
> + if (chan->qmc->is_tsa_64rxtx) {
> + if (ts_info->rx_ts_mask != ts_info->tx_ts_mask)
> + return -EINVAL;
> + }
> +
> + spin_lock_irqsave(>ts_lock, flags);
> +
> + if ((chan->tx_ts_mask != ts_info->tx_ts_mask && !chan->is_tx_stopped) ||
> + (chan->rx_ts_mask != ts_info->rx_ts_mask && !chan->is_rx_stopped)) {
> + dev_err(chan->qmc->dev, "Channel rx and/or tx not stopped\n");
> + ret = -EBUSY;
> + } else {
> + chan->tx_ts_mask = ts_info->tx_ts_mask;
> + chan->rx_ts_mask = ts_info->rx_ts_mask;
> + ret = 0;
> + }
> + spin_unlock_irqrestore(>ts_lock, flags);
> +
> + return ret;
> +}
> +EXPORT_SYMBOL(qmc_chan_set_ts_info);
> +
>   int qmc_chan_set_param(struct qmc_chan *chan, const struct qmc_chan_param 
> *param)
>   {
>   if (param->mode != chan->mode)
> diff --git a/include/soc/fsl/qe/qmc.h b/include/soc/fsl/qe/qmc.h
> index 6f1d6cebc9fe..802c161636bd 100644
> --- a/include/soc/fsl/qe/qmc.h
> +++ b/include/soc/fsl/qe/qmc.h
> @@ -38,6 +38,16 @@ struct qmc_chan_info {
>   
>   int qmc_chan_get_info(struct qmc_chan *chan, struct qmc_chan_info *info);
>   
> +struct qmc_chan_ts_info {
> + u64 rx_ts_mask_avail;
> + u64 tx_ts_mask_avail;
> + u64 rx_ts_mask;
> + u64 tx_ts_mask;
> +};
> +
> +int qmc_chan_get_ts_info(struct qmc_chan *chan, struct qmc_chan_ts_info 
> *ts_info);
> +int qmc_chan_set_ts_info(struct qmc_chan *chan, const struct 
> qmc_chan_ts_info *ts_info);
> +
>   struct qmc_chan_param {
>   enum qmc_mode mode;
>   union {


Re: [PATCH v2 17/28] soc: fsl: cpm1: qmc: Remove timeslots handling from setup_chan()

2023-08-08 Thread Christophe Leroy


Le 26/07/2023 à 17:02, Herve Codina a écrit :
> Timeslots setting is done at channel start() and stop().
> There is no more need to do that during setup_chan().
> 
> Simply remove timeslot setting from setup_chan().
> 
> Signed-off-by: Herve Codina 

Reviewed-by: Christophe Leroy 

> ---
>   drivers/soc/fsl/qe/qmc.c | 28 
>   1 file changed, 28 deletions(-)
> 
> diff --git a/drivers/soc/fsl/qe/qmc.c b/drivers/soc/fsl/qe/qmc.c
> index 258a34641551..b1883b9d2bae 100644
> --- a/drivers/soc/fsl/qe/qmc.c
> +++ b/drivers/soc/fsl/qe/qmc.c
> @@ -723,30 +723,6 @@ static int qmc_chan_setup_tsa_rx(struct qmc_chan *chan, 
> bool enable)
>   return qmc_chan_setup_tsa_32rx(chan, , enable);
>   }
>   
> -static int qmc_chan_setup_tsa(struct qmc_chan *chan, bool enable)
> -{
> - struct tsa_serial_info info;
> - int ret;
> -
> - /* Retrieve info from the TSA related serial */
> - ret = tsa_serial_get_info(chan->qmc->tsa_serial, );
> - if (ret)
> - return ret;
> -
> - /*
> -  * Setup one common 64 entries table or two 32 entries (one for Tx
> -  * and one for Tx) according to assigned TS numbers.
> -  */
> - if (chan->qmc->is_tsa_64rxtx)
> - return qmc_chan_setup_tsa_64rxtx(chan, , enable);
> -
> - ret = qmc_chan_setup_tsa_32rx(chan, , enable);
> - if (ret)
> - return ret;
> -
> - return qmc_chan_setup_tsa_32tx(chan, , enable);
> -}
> -
>   static int qmc_chan_command(struct qmc_chan *chan, u8 qmc_opcode)
>   {
>   return cpm_command(chan->id << 2, (qmc_opcode << 4) | 0x0E);
> @@ -1323,10 +1299,6 @@ static int qmc_setup_chan(struct qmc *qmc, struct 
> qmc_chan *chan)
>   
>   chan->qmc = qmc;
>   
> - ret = qmc_chan_setup_tsa(chan, true);
> - if (ret)
> - return ret;
> -
>   /* Set channel specific parameter base address */
>   chan->s_param = qmc->dpram + (chan->id * 64);
>   /* 16 bd per channel (8 rx and 8 tx) */


Re: [PATCH v2 16/28] soc: fsl: cpm1: qmc: Handle timeslot entries at channel start() and stop()

2023-08-08 Thread Christophe Leroy


Le 26/07/2023 à 17:02, Herve Codina a écrit :
> In order to support runtime timeslot route changes, enable the
> channel timeslot entries at channel start() and disable them at
> channel stop().
> 
> Signed-off-by: Herve Codina 

Reviewed-by: Christophe Leroy 

> ---
>   drivers/soc/fsl/qe/qmc.c | 175 ---
>   1 file changed, 163 insertions(+), 12 deletions(-)
> 
> diff --git a/drivers/soc/fsl/qe/qmc.c b/drivers/soc/fsl/qe/qmc.c
> index dc113463fbc7..258a34641551 100644
> --- a/drivers/soc/fsl/qe/qmc.c
> +++ b/drivers/soc/fsl/qe/qmc.c
> @@ -177,6 +177,7 @@ struct qmc_chan {
>   struct qmc *qmc;
>   void __iomem *s_param;
>   enum qmc_mode mode;
> + spinlock_t  ts_lock; /* Protect timeslots */
>   u64 tx_ts_mask_avail;
>   u64 tx_ts_mask;
>   u64 rx_ts_mask_avail;
> @@ -265,6 +266,7 @@ static inline void qmc_setbits32(void __iomem *addr, u32 
> set)
>   int qmc_chan_get_info(struct qmc_chan *chan, struct qmc_chan_info *info)
>   {
>   struct tsa_serial_info tsa_info;
> + unsigned long flags;
>   int ret;
>   
>   /* Retrieve info from the TSA related serial */
> @@ -272,6 +274,8 @@ int qmc_chan_get_info(struct qmc_chan *chan, struct 
> qmc_chan_info *info)
>   if (ret)
>   return ret;
>   
> + spin_lock_irqsave(>ts_lock, flags);
> +
>   info->mode = chan->mode;
>   info->rx_fs_rate = tsa_info.rx_fs_rate;
>   info->rx_bit_rate = tsa_info.rx_bit_rate;
> @@ -280,6 +284,8 @@ int qmc_chan_get_info(struct qmc_chan *chan, struct 
> qmc_chan_info *info)
>   info->tx_bit_rate = tsa_info.tx_bit_rate;
>   info->nb_rx_ts = hweight64(chan->rx_ts_mask);
>   
> + spin_unlock_irqrestore(>ts_lock, flags);
> +
>   return 0;
>   }
>   EXPORT_SYMBOL(qmc_chan_get_info);
> @@ -683,6 +689,40 @@ static int qmc_chan_setup_tsa_32tx(struct qmc_chan 
> *chan, const struct tsa_seria
>   return 0;
>   }
>   
> +static int qmc_chan_setup_tsa_tx(struct qmc_chan *chan, bool enable)
> +{
> + struct tsa_serial_info info;
> + int ret;
> +
> + /* Retrieve info from the TSA related serial */
> + ret = tsa_serial_get_info(chan->qmc->tsa_serial, );
> + if (ret)
> + return ret;
> +
> + /* Setup entries */
> + if (chan->qmc->is_tsa_64rxtx)
> + return qmc_chan_setup_tsa_64rxtx(chan, , enable);
> +
> + return qmc_chan_setup_tsa_32tx(chan, , enable);
> +}
> +
> +static int qmc_chan_setup_tsa_rx(struct qmc_chan *chan, bool enable)
> +{
> + struct tsa_serial_info info;
> + int ret;
> +
> + /* Retrieve info from the TSA related serial */
> + ret = tsa_serial_get_info(chan->qmc->tsa_serial, );
> + if (ret)
> + return ret;
> +
> + /* Setup entries */
> + if (chan->qmc->is_tsa_64rxtx)
> + return qmc_chan_setup_tsa_64rxtx(chan, , enable);
> +
> + return qmc_chan_setup_tsa_32rx(chan, , enable);
> +}
> +
>   static int qmc_chan_setup_tsa(struct qmc_chan *chan, bool enable)
>   {
>   struct tsa_serial_info info;
> @@ -719,6 +759,12 @@ static int qmc_chan_stop_rx(struct qmc_chan *chan)
>   
>   spin_lock_irqsave(>rx_lock, flags);
>   
> + if (chan->is_rx_stopped) {
> + /* The channel is already stopped -> simply return ok */
> + ret = 0;
> + goto end;
> + }
> +
>   /* Send STOP RECEIVE command */
>   ret = qmc_chan_command(chan, 0x0);
>   if (ret) {
> @@ -729,6 +775,15 @@ static int qmc_chan_stop_rx(struct qmc_chan *chan)
>   
>   chan->is_rx_stopped = true;
>   
> + if (!chan->qmc->is_tsa_64rxtx || chan->is_tx_stopped) {
> + ret = qmc_chan_setup_tsa_rx(chan, false);
> + if (ret) {
> + dev_err(chan->qmc->dev, "chan %u: Disable tsa entries 
> failed (%d)\n",
> + chan->id, ret);
> + goto end;
> + }
> + }
> +
>   end:
>   spin_unlock_irqrestore(>rx_lock, flags);
>   return ret;
> @@ -741,6 +796,12 @@ static int qmc_chan_stop_tx(struct qmc_chan *chan)
>   
>   spin_lock_irqsave(>tx_lock, flags);
>   
> + if (chan->is_tx_stopped) {
> + /* The channel is already stopped -> simply return ok */
> + ret = 0;
> + goto end;
> + }
> +
>   /* Send STOP TRANSMIT command */
>   ret = qmc_chan_command(chan, 0x1);
>   if (ret) {
> @@ -751,37 +812,82 @@ static int qmc_chan_stop_tx(struct qmc_chan *chan)
>   
>   chan->is_tx_stopped = true;
>   
> + if (!chan->qmc->is_tsa_64rxtx || chan->is_rx_stopped) {
> + ret = qmc_chan_setup_tsa_tx(chan, false);
> + if (ret) {
> + dev_err(chan->qmc->dev, "chan %u: Disable tsa entries 
> failed (%d)\n",
> + chan->id, ret);
> + goto end;
> + }
> + }
> +
>   end:
>   spin_unlock_irqrestore(>tx_lock, flags);
>   return ret;
> 

Re: [PATCH v2 15/28] soc: fsl: cpm1: qmc: Introduce is_tsa_64rxtx flag

2023-08-08 Thread Christophe Leroy


Le 26/07/2023 à 17:02, Herve Codina a écrit :
> In order to support runtime timeslot route changes, some operations will
> be different according the routing table used (common Rx and Tx table or
> one table for Rx and one for Tx).
> 
> The is_tsa_64rxtx flag is introduced to avoid extra computation to
> determine the table format each time we need it.
> It is set once at initialization.
> 
> Signed-off-by: Herve Codina 

Reviewed-by: Christophe Leroy 

> ---
>   drivers/soc/fsl/qe/qmc.c | 5 -
>   1 file changed, 4 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/soc/fsl/qe/qmc.c b/drivers/soc/fsl/qe/qmc.c
> index c8ddd2a54bee..dc113463fbc7 100644
> --- a/drivers/soc/fsl/qe/qmc.c
> +++ b/drivers/soc/fsl/qe/qmc.c
> @@ -216,6 +216,7 @@ struct qmc {
>   u16 __iomem *int_curr;
>   dma_addr_t int_dma_addr;
>   size_t int_size;
> + bool is_tsa_64rxtx;
>   struct list_head chan_head;
>   struct qmc_chan *chans[64];
>   };
> @@ -696,7 +697,7 @@ static int qmc_chan_setup_tsa(struct qmc_chan *chan, bool 
> enable)
>* Setup one common 64 entries table or two 32 entries (one for Tx
>* and one for Tx) according to assigned TS numbers.
>*/
> - if (info.nb_tx_ts > 32 || info.nb_rx_ts > 32)
> + if (chan->qmc->is_tsa_64rxtx)
>   return qmc_chan_setup_tsa_64rxtx(chan, , enable);
>   
>   ret = qmc_chan_setup_tsa_32rx(chan, , enable);
> @@ -1053,6 +1054,7 @@ static int qmc_init_tsa_64rxtx(struct qmc *qmc, const 
> struct tsa_serial_info *in
>* Everything was previously checked, Tx and Rx related stuffs are
>* identical -> Used Rx related stuff to build the table
>*/
> + qmc->is_tsa_64rxtx = true;
>   
>   /* Invalidate all entries */
>   for (i = 0; i < 64; i++)
> @@ -1081,6 +1083,7 @@ static int qmc_init_tsa_32rx_32tx(struct qmc *qmc, 
> const struct tsa_serial_info
>* Use a Tx 32 entries table and a Rx 32 entries table.
>* Everything was previously checked.
>*/
> + qmc->is_tsa_64rxtx = false;
>   
>   /* Invalidate all entries */
>   for (i = 0; i < 32; i++) {


Re: [PATCH v2 14/28] soc: fsl: cpm1: qmc: Split Tx and Rx TSA entries setup

2023-08-08 Thread Christophe Leroy


Le 26/07/2023 à 17:02, Herve Codina a écrit :
> The Tx and Rx entries for a given channel are set in one function.
> 
> In order to modify Rx entries and Tx entries independently of one other,
> split this function in one for the Rx part and one for the Tx part.
> 
> Signed-off-by: Herve Codina 

Reviewed-by: Christophe Leroy 

> ---
>   drivers/soc/fsl/qe/qmc.c | 49 
>   1 file changed, 35 insertions(+), 14 deletions(-)
> 
> diff --git a/drivers/soc/fsl/qe/qmc.c b/drivers/soc/fsl/qe/qmc.c
> index 146eebc12737..c8ddd2a54bee 100644
> --- a/drivers/soc/fsl/qe/qmc.c
> +++ b/drivers/soc/fsl/qe/qmc.c
> @@ -610,14 +610,14 @@ static int qmc_chan_setup_tsa_64rxtx(struct qmc_chan 
> *chan, const struct tsa_ser
>   return 0;
>   }
>   
> -static int qmc_chan_setup_tsa_32rx_32tx(struct qmc_chan *chan, const struct 
> tsa_serial_info *info,
> - bool enable)
> +static int qmc_chan_setup_tsa_32rx(struct qmc_chan *chan, const struct 
> tsa_serial_info *info,
> +bool enable)
>   {
>   unsigned int i;
>   u16 curr;
>   u16 val;
>   
> - /* Use a Tx 32 entries table and a Rx 32 entries table */
> + /* Use a Rx 32 entries table */
>   
>   val = QMC_TSA_VALID | QMC_TSA_MASK | QMC_TSA_CHANNEL(chan->id);
>   
> @@ -633,6 +633,30 @@ static int qmc_chan_setup_tsa_32rx_32tx(struct qmc_chan 
> *chan, const struct tsa_
>   return -EBUSY;
>   }
>   }
> +
> + /* Set entries based on Rx stuff */
> + for (i = 0; i < info->nb_rx_ts; i++) {
> + if (!(chan->rx_ts_mask & (((u64)1) << i)))
> + continue;
> +
> + qmc_clrsetbits16(chan->qmc->scc_pram + QMC_GBL_TSATRX + (i * 2),
> +  ~QMC_TSA_WRAP, enable ? val : 0x);
> + }
> +
> + return 0;
> +}
> +
> +static int qmc_chan_setup_tsa_32tx(struct qmc_chan *chan, const struct 
> tsa_serial_info *info,
> +bool enable)
> +{
> + unsigned int i;
> + u16 curr;
> + u16 val;
> +
> + /* Use a Tx 32 entries table */
> +
> + val = QMC_TSA_VALID | QMC_TSA_MASK | QMC_TSA_CHANNEL(chan->id);
> +
>   /* Check entries based on Tx stuff */
>   for (i = 0; i < info->nb_tx_ts; i++) {
>   if (!(chan->tx_ts_mask & (((u64)1) << i)))
> @@ -646,14 +670,6 @@ static int qmc_chan_setup_tsa_32rx_32tx(struct qmc_chan 
> *chan, const struct tsa_
>   }
>   }
>   
> - /* Set entries based on Rx stuff */
> - for (i = 0; i < info->nb_rx_ts; i++) {
> - if (!(chan->rx_ts_mask & (((u64)1) << i)))
> - continue;
> -
> - qmc_clrsetbits16(chan->qmc->scc_pram + QMC_GBL_TSATRX + (i * 2),
> -  ~QMC_TSA_WRAP, enable ? val : 0x);
> - }
>   /* Set entries based on Tx stuff */
>   for (i = 0; i < info->nb_tx_ts; i++) {
>   if (!(chan->tx_ts_mask & (((u64)1) << i)))
> @@ -680,9 +696,14 @@ static int qmc_chan_setup_tsa(struct qmc_chan *chan, 
> bool enable)
>* Setup one common 64 entries table or two 32 entries (one for Tx
>* and one for Tx) according to assigned TS numbers.
>*/
> - return ((info.nb_tx_ts > 32) || (info.nb_rx_ts > 32)) ?
> - qmc_chan_setup_tsa_64rxtx(chan, , enable) :
> - qmc_chan_setup_tsa_32rx_32tx(chan, , enable);
> + if (info.nb_tx_ts > 32 || info.nb_rx_ts > 32)
> + return qmc_chan_setup_tsa_64rxtx(chan, , enable);
> +
> + ret = qmc_chan_setup_tsa_32rx(chan, , enable);
> + if (ret)
> + return ret;
> +
> + return qmc_chan_setup_tsa_32tx(chan, , enable);
>   }
>   
>   static int qmc_chan_command(struct qmc_chan *chan, u8 qmc_opcode)


Re: [PATCH v2 13/28] soc: fsl: cpm1: qmc: Add support for disabling channel TSA entries

2023-08-08 Thread Christophe Leroy


Le 26/07/2023 à 17:02, Herve Codina a écrit :
> In order to allow runtime timeslot route changes, disabling channel TSA
> entries needs to be supported.
> 
> Add support for this new feature.
> 
> Signed-off-by: Herve Codina 

Reviewed-by: Christophe Leroy 

> ---
>   drivers/soc/fsl/qe/qmc.c | 20 +++-
>   1 file changed, 11 insertions(+), 9 deletions(-)
> 
> diff --git a/drivers/soc/fsl/qe/qmc.c b/drivers/soc/fsl/qe/qmc.c
> index 82405915f2a4..146eebc12737 100644
> --- a/drivers/soc/fsl/qe/qmc.c
> +++ b/drivers/soc/fsl/qe/qmc.c
> @@ -567,7 +567,8 @@ static void qmc_chan_read_done(struct qmc_chan *chan)
>   spin_unlock_irqrestore(>rx_lock, flags);
>   }
>   
> -static int qmc_chan_setup_tsa_64rxtx(struct qmc_chan *chan, const struct 
> tsa_serial_info *info)
> +static int qmc_chan_setup_tsa_64rxtx(struct qmc_chan *chan, const struct 
> tsa_serial_info *info,
> +  bool enable)
>   {
>   unsigned int i;
>   u16 curr;
> @@ -603,13 +604,14 @@ static int qmc_chan_setup_tsa_64rxtx(struct qmc_chan 
> *chan, const struct tsa_ser
>   continue;
>   
>   qmc_clrsetbits16(chan->qmc->scc_pram + QMC_GBL_TSATRX + (i * 2),
> -  ~QMC_TSA_WRAP, val);
> +  ~QMC_TSA_WRAP, enable ? val : 0x);
>   }
>   
>   return 0;
>   }
>   
> -static int qmc_chan_setup_tsa_32rx_32tx(struct qmc_chan *chan, const struct 
> tsa_serial_info *info)
> +static int qmc_chan_setup_tsa_32rx_32tx(struct qmc_chan *chan, const struct 
> tsa_serial_info *info,
> + bool enable)
>   {
>   unsigned int i;
>   u16 curr;
> @@ -650,7 +652,7 @@ static int qmc_chan_setup_tsa_32rx_32tx(struct qmc_chan 
> *chan, const struct tsa_
>   continue;
>   
>   qmc_clrsetbits16(chan->qmc->scc_pram + QMC_GBL_TSATRX + (i * 2),
> -  ~QMC_TSA_WRAP, val);
> +  ~QMC_TSA_WRAP, enable ? val : 0x);
>   }
>   /* Set entries based on Tx stuff */
>   for (i = 0; i < info->nb_tx_ts; i++) {
> @@ -658,13 +660,13 @@ static int qmc_chan_setup_tsa_32rx_32tx(struct qmc_chan 
> *chan, const struct tsa_
>   continue;
>   
>   qmc_clrsetbits16(chan->qmc->scc_pram + QMC_GBL_TSATTX + (i * 2),
> -  ~QMC_TSA_WRAP, val);
> +  ~QMC_TSA_WRAP, enable ? val : 0x);
>   }
>   
>   return 0;
>   }
>   
> -static int qmc_chan_setup_tsa(struct qmc_chan *chan)
> +static int qmc_chan_setup_tsa(struct qmc_chan *chan, bool enable)
>   {
>   struct tsa_serial_info info;
>   int ret;
> @@ -679,8 +681,8 @@ static int qmc_chan_setup_tsa(struct qmc_chan *chan)
>* and one for Tx) according to assigned TS numbers.
>*/
>   return ((info.nb_tx_ts > 32) || (info.nb_rx_ts > 32)) ?
> - qmc_chan_setup_tsa_64rxtx(chan, ) :
> - qmc_chan_setup_tsa_32rx_32tx(chan, );
> + qmc_chan_setup_tsa_64rxtx(chan, , enable) :
> + qmc_chan_setup_tsa_32rx_32tx(chan, , enable);
>   }
>   
>   static int qmc_chan_command(struct qmc_chan *chan, u8 qmc_opcode)
> @@ -1146,7 +1148,7 @@ static int qmc_setup_chan(struct qmc *qmc, struct 
> qmc_chan *chan)
>   
>   chan->qmc = qmc;
>   
> - ret = qmc_chan_setup_tsa(chan);
> + ret = qmc_chan_setup_tsa(chan, true);
>   if (ret)
>   return ret;
>   


Re: [PATCH v2 12/28] soc: fsl: cpm1: qmc: Check available timeslots in qmc_check_chans()

2023-08-08 Thread Christophe Leroy


Le 26/07/2023 à 17:02, Herve Codina a écrit :
> The timeslots checked in qmc_check_chans() are the timeslots used.
> With the introduction of the available timeslots, the used timeslots
> are a subset of the available timeslots. The timeslots checked during
> the qmc_check_chans() call should be the available ones.
> 
> Simply update and check the available timeslots instead of the used
> timeslots in qmc_check_chans().
> 
> Signed-off-by: Herve Codina 


Reviewed-by: Christophe Leroy 


> ---
>   drivers/soc/fsl/qe/qmc.c | 8 
>   1 file changed, 4 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/soc/fsl/qe/qmc.c b/drivers/soc/fsl/qe/qmc.c
> index 33761c39aee1..82405915f2a4 100644
> --- a/drivers/soc/fsl/qe/qmc.c
> +++ b/drivers/soc/fsl/qe/qmc.c
> @@ -914,13 +914,13 @@ static int qmc_check_chans(struct qmc *qmc)
>   rx_ts_assigned_mask = info.nb_rx_ts == 64 ? U64_MAX : (((u64)1) << 
> info.nb_rx_ts) - 1;
>   
>   list_for_each_entry(chan, >chan_head, list) {
> - if (chan->tx_ts_mask > tx_ts_assigned_mask) {
> - dev_err(qmc->dev, "chan %u uses TSA unassigned Tx 
> TS\n", chan->id);
> + if (chan->tx_ts_mask_avail > tx_ts_assigned_mask) {
> + dev_err(qmc->dev, "chan %u can use TSA unassigned Tx 
> TS\n", chan->id);
>   return -EINVAL;
>   }
>   
> - if (chan->rx_ts_mask > rx_ts_assigned_mask) {
> - dev_err(qmc->dev, "chan %u uses TSA unassigned Rx 
> TS\n", chan->id);
> + if (chan->rx_ts_mask_avail > rx_ts_assigned_mask) {
> + dev_err(qmc->dev, "chan %u can use TSA unassigned Rx 
> TS\n", chan->id);
>   return -EINVAL;
>   }
>   }


Re: [PATCH v2 11/28] soc: fsl: cpm1: qmc: Remove no more needed checks from qmc_check_chans()

2023-08-08 Thread Christophe Leroy


Le 26/07/2023 à 17:02, Herve Codina a écrit :
> The newly introduced qmc_chan_setup_tsa* functions check that the
> channel entries are not already used.
> These checks are also performed by qmc_check_chans() and are no more
> needed.
> 
> Remove them from qmc_check_chans().
> 
> Signed-off-by: Herve Codina 

Reviewed-by: Christophe Leroy 

> ---
>   drivers/soc/fsl/qe/qmc.c | 20 
>   1 file changed, 20 deletions(-)
> 
> diff --git a/drivers/soc/fsl/qe/qmc.c b/drivers/soc/fsl/qe/qmc.c
> index c5552a0b5b19..33761c39aee1 100644
> --- a/drivers/soc/fsl/qe/qmc.c
> +++ b/drivers/soc/fsl/qe/qmc.c
> @@ -884,10 +884,7 @@ EXPORT_SYMBOL(qmc_chan_reset);
>   static int qmc_check_chans(struct qmc *qmc)
>   {
>   struct tsa_serial_info info;
> - bool is_one_table = false;
>   struct qmc_chan *chan;
> - u64 tx_ts_mask = 0;
> - u64 rx_ts_mask = 0;
>   u64 tx_ts_assigned_mask;
>   u64 rx_ts_assigned_mask;
>   int ret;
> @@ -911,7 +908,6 @@ static int qmc_check_chans(struct qmc *qmc)
>   dev_err(qmc->dev, "Number of TSA Tx/Rx TS assigned are 
> not equal\n");
>   return -EINVAL;
>   }
> - is_one_table = true;
>   }
>   
>   tx_ts_assigned_mask = info.nb_tx_ts == 64 ? U64_MAX : (((u64)1) << 
> info.nb_tx_ts) - 1;
> @@ -922,27 +918,11 @@ static int qmc_check_chans(struct qmc *qmc)
>   dev_err(qmc->dev, "chan %u uses TSA unassigned Tx 
> TS\n", chan->id);
>   return -EINVAL;
>   }
> - if (tx_ts_mask & chan->tx_ts_mask) {
> - dev_err(qmc->dev, "chan %u uses an already used Tx 
> TS\n", chan->id);
> - return -EINVAL;
> - }
>   
>   if (chan->rx_ts_mask > rx_ts_assigned_mask) {
>   dev_err(qmc->dev, "chan %u uses TSA unassigned Rx 
> TS\n", chan->id);
>   return -EINVAL;
>   }
> - if (rx_ts_mask & chan->rx_ts_mask) {
> - dev_err(qmc->dev, "chan %u uses an already used Rx 
> TS\n", chan->id);
> - return -EINVAL;
> - }
> -
> - if (is_one_table && (chan->tx_ts_mask != chan->rx_ts_mask)) {
> - dev_err(qmc->dev, "chan %u uses different Rx and Tx 
> TS\n", chan->id);
> - return -EINVAL;
> - }
> -
> - tx_ts_mask |= chan->tx_ts_mask;
> - rx_ts_mask |= chan->rx_ts_mask;
>   }
>   
>   return 0;


Re: [PATCH v2 10/28] soc: fsl: cpm1: qmc: Introduce qmc_chan_setup_tsa*

2023-08-08 Thread Christophe Leroy


Le 26/07/2023 à 17:02, Herve Codina a écrit :
> Introduce the qmc_chan_setup_tsa* functions to setup entries related
> to the given channel.
> Use them during QMC channels setup.
> 
> Signed-off-by: Herve Codina 

Reviewed-by: Christophe Leroy 

> ---
>   drivers/soc/fsl/qe/qmc.c | 161 ++-
>   1 file changed, 125 insertions(+), 36 deletions(-)
> 
> diff --git a/drivers/soc/fsl/qe/qmc.c b/drivers/soc/fsl/qe/qmc.c
> index 64a11f5c6f85..c5552a0b5b19 100644
> --- a/drivers/soc/fsl/qe/qmc.c
> +++ b/drivers/soc/fsl/qe/qmc.c
> @@ -240,6 +240,11 @@ static inline void qmc_clrbits16(void __iomem *addr, u16 
> clr)
>   qmc_write16(addr, qmc_read16(addr) & ~clr);
>   }
>   
> +static inline void qmc_clrsetbits16(void __iomem *addr, u16 clr, u16 set)
> +{
> + qmc_write16(addr, (qmc_read16(addr) & ~clr) | set);
> +}
> +
>   static inline void qmc_write32(void __iomem *addr, u32 val)
>   {
>   iowrite32be(val, addr);
> @@ -562,6 +567,122 @@ static void qmc_chan_read_done(struct qmc_chan *chan)
>   spin_unlock_irqrestore(>rx_lock, flags);
>   }
>   
> +static int qmc_chan_setup_tsa_64rxtx(struct qmc_chan *chan, const struct 
> tsa_serial_info *info)
> +{
> + unsigned int i;
> + u16 curr;
> + u16 val;
> +
> + /*
> +  * Use a common Tx/Rx 64 entries table.
> +  * Tx and Rx related stuffs must be identical
> +  */
> + if (chan->tx_ts_mask != chan->rx_ts_mask) {
> + dev_err(chan->qmc->dev, "chan %u uses different Rx and Tx 
> TS\n", chan->id);
> + return -EINVAL;
> + }
> +
> + val = QMC_TSA_VALID | QMC_TSA_MASK | QMC_TSA_CHANNEL(chan->id);
> +
> + /* Check entries based on Rx stuff*/
> + for (i = 0; i < info->nb_rx_ts; i++) {
> + if (!(chan->rx_ts_mask & (((u64)1) << i)))
> + continue;
> +
> + curr = qmc_read16(chan->qmc->scc_pram + QMC_GBL_TSATRX + (i * 
> 2));
> + if (curr & QMC_TSA_VALID && (curr & ~QMC_TSA_WRAP) != val) {
> + dev_err(chan->qmc->dev, "chan %u TxRx entry %d already 
> used\n",
> + chan->id, i);
> + return -EBUSY;
> + }
> + }
> +
> + /* Set entries based on Rx stuff*/
> + for (i = 0; i < info->nb_rx_ts; i++) {
> + if (!(chan->rx_ts_mask & (((u64)1) << i)))
> + continue;
> +
> + qmc_clrsetbits16(chan->qmc->scc_pram + QMC_GBL_TSATRX + (i * 2),
> +  ~QMC_TSA_WRAP, val);
> + }
> +
> + return 0;
> +}
> +
> +static int qmc_chan_setup_tsa_32rx_32tx(struct qmc_chan *chan, const struct 
> tsa_serial_info *info)
> +{
> + unsigned int i;
> + u16 curr;
> + u16 val;
> +
> + /* Use a Tx 32 entries table and a Rx 32 entries table */
> +
> + val = QMC_TSA_VALID | QMC_TSA_MASK | QMC_TSA_CHANNEL(chan->id);
> +
> + /* Check entries based on Rx stuff */
> + for (i = 0; i < info->nb_rx_ts; i++) {
> + if (!(chan->rx_ts_mask & (((u64)1) << i)))
> + continue;
> +
> + curr = qmc_read16(chan->qmc->scc_pram + QMC_GBL_TSATRX + (i * 
> 2));
> + if (curr & QMC_TSA_VALID && (curr & ~QMC_TSA_WRAP) != val) {
> + dev_err(chan->qmc->dev, "chan %u Rx entry %d already 
> used\n",
> + chan->id, i);
> + return -EBUSY;
> + }
> + }
> + /* Check entries based on Tx stuff */
> + for (i = 0; i < info->nb_tx_ts; i++) {
> + if (!(chan->tx_ts_mask & (((u64)1) << i)))
> + continue;
> +
> + curr = qmc_read16(chan->qmc->scc_pram + QMC_GBL_TSATTX + (i * 
> 2));
> + if (curr & QMC_TSA_VALID && (curr & ~QMC_TSA_WRAP) != val) {
> + dev_err(chan->qmc->dev, "chan %u Tx entry %d already 
> used\n",
> + chan->id, i);
> + return -EBUSY;
> + }
> + }
> +
> + /* Set entries based on Rx stuff */
> + for (i = 0; i < info->nb_rx_ts; i++) {
> + if (!(chan->rx_ts_mask & (((u64)1) << i)))
> + continue;
> +
> + qmc_clrsetbits16(chan->qmc->scc_pram + QMC_GBL_TSATRX + (i * 2),
> +  ~QMC_TSA_WRAP, val);
> + }
> + /* Set entries based on Tx stuff */
> + for (i = 0; i < info->nb_tx_ts; i++) {
> + if (!(chan->tx_ts_mask & (((u64)1) << i)))
> + continue;
> +
> + qmc_clrsetbits16(chan->qmc->scc_pram + QMC_GBL_TSATTX + (i * 2),
> +  ~QMC_TSA_WRAP, val);
> + }
> +
> + return 0;
> +}
> +
> +static int qmc_chan_setup_tsa(struct qmc_chan *chan)
> +{
> + struct tsa_serial_info info;
> + int ret;
> +
> + /* Retrieve info from the TSA related serial */
> + ret = tsa_serial_get_info(chan->qmc->tsa_serial, );
> + if (ret)
> + return 

Re: [PATCH v2 09/28] soc: fsl: cpm1: qmc: Rename qmc_setup_tsa* to qmc_init_tsa*

2023-08-08 Thread Christophe Leroy


Le 26/07/2023 à 17:02, Herve Codina a écrit :
> qmc_setup_tsa* are called once at initialisation.
> They initialize the QMC TSA table.
> In order to introduce setup function later on for dynamic timeslots
> management, rename the function to avoid later confusion.
> 
> Signed-off-by: Herve Codina 

Reviewed-by: Christophe Leroy 

> ---
>   drivers/soc/fsl/qe/qmc.c | 16 
>   1 file changed, 8 insertions(+), 8 deletions(-)
> 
> diff --git a/drivers/soc/fsl/qe/qmc.c b/drivers/soc/fsl/qe/qmc.c
> index 21ad7e79e7bd..64a11f5c6f85 100644
> --- a/drivers/soc/fsl/qe/qmc.c
> +++ b/drivers/soc/fsl/qe/qmc.c
> @@ -919,7 +919,7 @@ static int qmc_of_parse_chans(struct qmc *qmc, struct 
> device_node *np)
>   return qmc_check_chans(qmc);
>   }
>   
> -static int qmc_setup_tsa_64rxtx(struct qmc *qmc, const struct 
> tsa_serial_info *info)
> +static int qmc_init_tsa_64rxtx(struct qmc *qmc, const struct tsa_serial_info 
> *info)
>   {
>   struct qmc_chan *chan;
>   unsigned int i;
> @@ -961,7 +961,7 @@ static int qmc_setup_tsa_64rxtx(struct qmc *qmc, const 
> struct tsa_serial_info *i
>   return 0;
>   }
>   
> -static int qmc_setup_tsa_32rx_32tx(struct qmc *qmc, const struct 
> tsa_serial_info *info)
> +static int qmc_init_tsa_32rx_32tx(struct qmc *qmc, const struct 
> tsa_serial_info *info)
>   {
>   struct qmc_chan *chan;
>   unsigned int i;
> @@ -1019,7 +1019,7 @@ static int qmc_setup_tsa_32rx_32tx(struct qmc *qmc, 
> const struct tsa_serial_info
>   return 0;
>   }
>   
> -static int qmc_setup_tsa(struct qmc *qmc)
> +static int qmc_init_tsa(struct qmc *qmc)
>   {
>   struct tsa_serial_info info;
>   int ret;
> @@ -1030,12 +1030,12 @@ static int qmc_setup_tsa(struct qmc *qmc)
>   return ret;
>   
>   /*
> -  * Setup one common 64 entries table or two 32 entries (one for Tx and
> -  * one for Tx) according to assigned TS numbers.
> +  * Initialize one common 64 entries table or two 32 entries (one for Tx
> +  * and one for Tx) according to assigned TS numbers.
>*/
>   return ((info.nb_tx_ts > 32) || (info.nb_rx_ts > 32)) ?
> - qmc_setup_tsa_64rxtx(qmc, ) :
> - qmc_setup_tsa_32rx_32tx(qmc, );
> + qmc_init_tsa_64rxtx(qmc, ) :
> + qmc_init_tsa_32rx_32tx(qmc, );
>   }
>   
>   static int qmc_setup_chan_trnsync(struct qmc *qmc, struct qmc_chan *chan)
> @@ -1391,7 +1391,7 @@ static int qmc_probe(struct platform_device *pdev)
>   qmc_write32(qmc->scc_pram + QMC_GBL_C_MASK32, 0xDEBB20E3);
>   qmc_write16(qmc->scc_pram + QMC_GBL_C_MASK16, 0xF0B8);
>   
> - ret = qmc_setup_tsa(qmc);
> + ret = qmc_init_tsa(qmc);
>   if (ret)
>   goto err_tsa_serial_disconnect;
>   


Re: [PATCH v2 08/28] soc: fsl: cpm1: qmc: Introduce available timeslots masks

2023-08-08 Thread Christophe Leroy


Le 26/07/2023 à 17:02, Herve Codina a écrit :
> Available timeslots masks define timeslots available for the related
> channel. These timeslots are defined by the QMC binding.
> 
> Timeslots used are initialized to available timeslots but can be a
> subset of available timeslots.
> This prepares the dynamic timeslots management (ie. changing timeslots
> at runtime).
> 
> Signed-off-by: Herve Codina 

Reviewed-by: Christophe Leroy 

> ---
>   drivers/soc/fsl/qe/qmc.c | 8 ++--
>   1 file changed, 6 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/soc/fsl/qe/qmc.c b/drivers/soc/fsl/qe/qmc.c
> index 2d2a9d88ba6c..21ad7e79e7bd 100644
> --- a/drivers/soc/fsl/qe/qmc.c
> +++ b/drivers/soc/fsl/qe/qmc.c
> @@ -177,7 +177,9 @@ struct qmc_chan {
>   struct qmc *qmc;
>   void __iomem *s_param;
>   enum qmc_mode mode;
> + u64 tx_ts_mask_avail;
>   u64 tx_ts_mask;
> + u64 rx_ts_mask_avail;
>   u64 rx_ts_mask;
>   bool is_reverse_data;
>   
> @@ -875,7 +877,8 @@ static int qmc_of_parse_chans(struct qmc *qmc, struct 
> device_node *np)
>   of_node_put(chan_np);
>   return ret;
>   }
> - chan->tx_ts_mask = ts_mask;
> + chan->tx_ts_mask_avail = ts_mask;
> + chan->tx_ts_mask = chan->tx_ts_mask_avail;
>   
>   ret = of_property_read_u64(chan_np, "fsl,rx-ts-mask", _mask);
>   if (ret) {
> @@ -884,7 +887,8 @@ static int qmc_of_parse_chans(struct qmc *qmc, struct 
> device_node *np)
>   of_node_put(chan_np);
>   return ret;
>   }
> - chan->rx_ts_mask = ts_mask;
> + chan->rx_ts_mask_avail = ts_mask;
> + chan->rx_ts_mask = chan->rx_ts_mask_avail;
>   
>   mode = "transparent";
>   ret = of_property_read_string(chan_np, "fsl,operational-mode", 
> );


Re: [PATCH v2 06/28] net: wan: Add support for QMC HDLC

2023-08-08 Thread Christophe Leroy


Le 26/07/2023 à 17:02, Herve Codina a écrit :
> The QMC HDLC driver provides support for HDLC using the QMC (QUICC
> Multichannel Controller) to transfer the HDLC data.
> 
> Signed-off-by: Herve Codina 


Reviewed-by: Christophe Leroy 

> diff --git a/drivers/net/wan/fsl_qmc_hdlc.c b/drivers/net/wan/fsl_qmc_hdlc.c
> new file mode 100644
> index ..b4ebae963d39
> --- /dev/null
> +++ b/drivers/net/wan/fsl_qmc_hdlc.c

> +
> +static inline struct qmc_hdlc *netdev_to_qmc_hdlc(struct net_device *netdev)
> +{
> + return (struct qmc_hdlc *)dev_to_hdlc(netdev)->priv;

->priv is void* so no cast should be necessary.



Re: [PATCH v7 7/7] mm/memory_hotplug: Enable runtime update of memmap_on_memory parameter

2023-08-08 Thread David Hildenbrand

On 08.08.23 08:29, Aneesh Kumar K V wrote:

On 8/8/23 12:05 AM, David Hildenbrand wrote:

On 07.08.23 14:41, David Hildenbrand wrote:

On 07.08.23 14:27, Michal Hocko wrote:

On Sat 05-08-23 19:54:23, Aneesh Kumar K V wrote:
[...]

Do you see a need for firmware-managed memory to be hotplugged in with
different memory block sizes?


In short. Yes. Slightly longer, a fixed size memory block semantic is
just standing in the way and I would even argue it is actively harmful.
Just have a look at ridicously small memory blocks on ppc. I do
understand that it makes some sense to be aligned to the memory model
(so sparsmem section aligned). In an ideal world, memory hotplug v2
interface (if we ever go that path) should be physical memory range based.


Yes, we discussed that a couple of times already (and so far nobody
cared to implement any of that).

Small memory block sizes are very beneficial for use cases like PPC
dlar, virtio-mem, hyperv-balloon, ... essentially in most virtual
environments where you might want to add/remove memory in very small
granularity. I don't see that changing any time soon. Rather the opposite.

Small memory block sizes are suboptimal for large machines where you
might never end up removing such memory (boot memory), or when dealing
with devices that can only be removed in one piece (DIMM/kmem). We
already have memory groups in place to model that.

For the latter it might be beneficial to have memory blocks of larger
size that correspond to the physical memory ranges. That might also make
a memmap (re-)configuration easier.

Not sure if that is standing in any way or is harmful, though.



Just because I thought of something right now, I'll share it, maybe it makes 
sense.

Assume when we get add_memory*(MHP_MEMMAP_ON_MEMORY) and it is enabled by the 
admin:

1) We create a single altmap at the beginning of the memory

2) We create the existing fixed-size memory block devices, but flag them
    to be part of a single "altmap" unit.

3) Whenever we trigger offlining of a single such memory block, we
    offline *all* memory blocks belonging to that altmap, essentially
    using a single offline_pages() call and updating all memory block
    states accordingly.

4) Whenever we trigger onlining of a single such memory block, we
    online *all* memory blocks belonging to that altmap, using a single
    online_pages() call.

5) We fail remove_memory() if it doesn't cover the same (altmap) range.

So we can avoid having a memory block v2 (and all that comes with that ...) for 
now and still get that altmap stuff sorted out. As that altmap behavior can be 
controlled by the admin, we should be fine for now.

I think all memory notifiers should already be able to handle bigger 
granularity, but it would be easy to check. Some internal things might require 
a bit of tweaking.



We can look at the possibility of using the altmap space reserved for a 
namespace (via option -M dev) for allocating struct page memory even with 
dax/kmem.


Right, an alternative would also be for the caller to pass in the 
altmap. Individual memory blocks can then get onlined/offlined as is.


One issue might be, how to get that altmap considered online memory 
(e.g., pfn_to_online_page(), kdump, ...). Right now, the altmap always 
falls into an online section once the memory block is online, so 
pfn_to_online_page() and especially online_section() holds as soon as 
the altmap has reasonable content -- when the memory block is online and 
initialized the memmap. Maybe that can be worked around, just pointing 
it out.


--
Cheers,

David / dhildenb



Re: [PATCH v2 04/28] soc: fsl: cpm1: qmc: Extend the API to provide Rx status

2023-08-08 Thread Christophe Leroy


Le 26/07/2023 à 17:02, Herve Codina a écrit :
> In HDLC mode, some status flags related to the data read transfer can be
> set by the hardware and need to be known by a QMC consumer for further
> analysis.
> 
> Extend the API in order to provide these transfer status flags at the
> read complete() call.
> 
> In TRANSPARENT mode, these flags have no meaning. Keep only one read
> complete() API and update the consumers working in transparent mode.
> In this case, the newly introduced flags parameter is simply unused.
> 
> Signed-off-by: Herve Codina 

Reviewed-by: Christophe Leroy 

> ---
>   drivers/soc/fsl/qe/qmc.c  | 29 +
>   include/soc/fsl/qe/qmc.h  | 15 ++-
>   sound/soc/fsl/fsl_qmc_audio.c |  2 +-
>   3 files changed, 40 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/soc/fsl/qe/qmc.c b/drivers/soc/fsl/qe/qmc.c
> index 8dc73cc1a83b..2d2a9d88ba6c 100644
> --- a/drivers/soc/fsl/qe/qmc.c
> +++ b/drivers/soc/fsl/qe/qmc.c
> @@ -166,7 +166,7 @@
>   struct qmc_xfer_desc {
>   union {
>   void (*tx_complete)(void *context);
> - void (*rx_complete)(void *context, size_t length);
> + void (*rx_complete)(void *context, size_t length, unsigned int 
> flags);
>   };
>   void *context;
>   };
> @@ -421,7 +421,8 @@ static void qmc_chan_write_done(struct qmc_chan *chan)
>   }
>   
>   int qmc_chan_read_submit(struct qmc_chan *chan, dma_addr_t addr, size_t 
> length,
> -  void (*complete)(void *context, size_t length), void 
> *context)
> +  void (*complete)(void *context, size_t length, 
> unsigned int flags),
> +  void *context)
>   {
>   struct qmc_xfer_desc *xfer_desc;
>   unsigned long flags;
> @@ -454,6 +455,10 @@ int qmc_chan_read_submit(struct qmc_chan *chan, 
> dma_addr_t addr, size_t length,
>   xfer_desc->rx_complete = complete;
>   xfer_desc->context = context;
>   
> + /* Clear previous status flags */
> + ctrl &= ~(QMC_BD_RX_L | QMC_BD_RX_F | QMC_BD_RX_LG | QMC_BD_RX_NO |
> +   QMC_BD_RX_AB | QMC_BD_RX_CR);
> +
>   /* Activate the descriptor */
>   ctrl |= (QMC_BD_RX_E | QMC_BD_RX_UB);
>   wmb(); /* Be sure to flush data before descriptor activation */
> @@ -485,7 +490,7 @@ EXPORT_SYMBOL(qmc_chan_read_submit);
>   
>   static void qmc_chan_read_done(struct qmc_chan *chan)
>   {
> - void (*complete)(void *context, size_t size);
> + void (*complete)(void *context, size_t size, unsigned int flags);
>   struct qmc_xfer_desc *xfer_desc;
>   unsigned long flags;
>   cbd_t __iomem *bd;
> @@ -527,7 +532,23 @@ static void qmc_chan_read_done(struct qmc_chan *chan)
>   
>   if (complete) {
>   spin_unlock_irqrestore(>rx_lock, flags);
> - complete(context, datalen);
> +
> + /*
> +  * Avoid conversion between internal hardware flags and
> +  * the software API flags.
> +  * -> Be sure that the software API flags are consistent
> +  *with the hardware flags
> +  */
> + BUILD_BUG_ON(QMC_RX_FLAG_HDLC_LAST  != QMC_BD_RX_L);
> + BUILD_BUG_ON(QMC_RX_FLAG_HDLC_FIRST != QMC_BD_RX_F);
> + BUILD_BUG_ON(QMC_RX_FLAG_HDLC_OVF   != QMC_BD_RX_LG);
> + BUILD_BUG_ON(QMC_RX_FLAG_HDLC_UNA   != QMC_BD_RX_NO);
> + BUILD_BUG_ON(QMC_RX_FLAG_HDLC_ABORT != QMC_BD_RX_AB);
> + BUILD_BUG_ON(QMC_RX_FLAG_HDLC_CRC   != QMC_BD_RX_CR);
> +
> + complete(context, datalen,
> +  ctrl & (QMC_BD_RX_L | QMC_BD_RX_F | 
> QMC_BD_RX_LG |
> +  QMC_BD_RX_NO | QMC_BD_RX_AB | 
> QMC_BD_RX_CR));
>   spin_lock_irqsave(>rx_lock, flags);
>   }
>   
> diff --git a/include/soc/fsl/qe/qmc.h b/include/soc/fsl/qe/qmc.h
> index 3c61a50d2ae2..6f1d6cebc9fe 100644
> --- a/include/soc/fsl/qe/qmc.h
> +++ b/include/soc/fsl/qe/qmc.h
> @@ -9,6 +9,7 @@
>   #ifndef __SOC_FSL_QMC_H__
>   #define __SOC_FSL_QMC_H__
>   
> +#include 
>   #include 
>   
>   struct device_node;
> @@ -56,8 +57,20 @@ int qmc_chan_set_param(struct qmc_chan *chan, const struct 
> qmc_chan_param *param
>   int qmc_chan_write_submit(struct qmc_chan *chan, dma_addr_t addr, size_t 
> length,
> void (*complete)(void *context), void *context);
>   
> +/* Flags available (ORed) for read complete() flags parameter in HDLC mode.
> + * No flags are available in transparent mode and the read complete() flags
> + * parameter has no meaning in transparent mode.
> + */
> +#define QMC_RX_FLAG_HDLC_LASTBIT(11) /* Last in frame */
> +#define QMC_RX_FLAG_HDLC_FIRST   BIT(10) /* First in frame */
> +#define QMC_RX_FLAG_HDLC_OVF BIT(5)  /* Data overflow */
> 

Re: [PATCH v2 03/28] soc: fsl: cpm1: qmc: Fix rx channel reset

2023-08-08 Thread Christophe Leroy


Le 26/07/2023 à 17:01, Herve Codina a écrit :
> The qmc_chan_reset_rx() set the is_rx_stopped flag. This leads to an
> inconsistent state in the following sequence.
>  qmc_chan_stop()
>  qmc_chan_reset()
> Indeed, after the qmc_chan_reset() call, the channel must still be
> stopped. Only a qmc_chan_start() call can move the channel from stopped
> state to started state.
> 
> Fix the issue removing the is_rx_stopped flag setting from
> qmc_chan_reset()
> 
> Fixes: 3178d58e0b97 ("soc: fsl: cpm1: Add support for QMC")
> Signed-off-by: Herve Codina 

Reviewed-by: Christophe Leroy 

> ---
>   drivers/soc/fsl/qe/qmc.c | 1 -
>   1 file changed, 1 deletion(-)
> 
> diff --git a/drivers/soc/fsl/qe/qmc.c b/drivers/soc/fsl/qe/qmc.c
> index 7ad0d77f1740..8dc73cc1a83b 100644
> --- a/drivers/soc/fsl/qe/qmc.c
> +++ b/drivers/soc/fsl/qe/qmc.c
> @@ -685,7 +685,6 @@ static void qmc_chan_reset_rx(struct qmc_chan *chan)
>   qmc_read16(chan->s_param + QMC_SPE_RBASE));
>   
>   chan->rx_pending = 0;
> - chan->is_rx_stopped = false;
>   
>   spin_unlock_irqrestore(>rx_lock, flags);
>   }


Re: [PATCH v2 02/28] soc: fsl: cpm1: qmc: Fix __iomem addresses declaration

2023-08-08 Thread Christophe Leroy


Le 26/07/2023 à 17:01, Herve Codina a écrit :
> Running sparse (make C=1) on qmc.c raises a lot of warning such as:
>...
>warning: incorrect type in assignment (different address spaces)
>   expected struct cpm_buf_desc [usertype] *[noderef] __iomem bd
>   got struct cpm_buf_desc [noderef] [usertype] __iomem *txbd_free
>...
> 
> Indeed, some variable were declared 'type *__iomem var' instead of
> 'type __iomem *var'.
> 
> Use the correct declaration to remove these warnings.
> 
> Fixes: 3178d58e0b97 ("soc: fsl: cpm1: Add support for QMC")
> Signed-off-by: Herve Codina 

Reviewed-by: Christophe Leroy 

> ---
>   drivers/soc/fsl/qe/qmc.c | 34 +-
>   1 file changed, 17 insertions(+), 17 deletions(-)
> 
> diff --git a/drivers/soc/fsl/qe/qmc.c b/drivers/soc/fsl/qe/qmc.c
> index b3c292c9a14e..7ad0d77f1740 100644
> --- a/drivers/soc/fsl/qe/qmc.c
> +++ b/drivers/soc/fsl/qe/qmc.c
> @@ -175,7 +175,7 @@ struct qmc_chan {
>   struct list_head list;
>   unsigned int id;
>   struct qmc *qmc;
> - void *__iomem s_param;
> + void __iomem *s_param;
>   enum qmc_mode mode;
>   u64 tx_ts_mask;
>   u64 rx_ts_mask;
> @@ -203,9 +203,9 @@ struct qmc_chan {
>   struct qmc {
>   struct device *dev;
>   struct tsa_serial *tsa_serial;
> - void *__iomem scc_regs;
> - void *__iomem scc_pram;
> - void *__iomem dpram;
> + void __iomem *scc_regs;
> + void __iomem *scc_pram;
> + void __iomem *dpram;
>   u16 scc_pram_offset;
>   cbd_t __iomem *bd_table;
>   dma_addr_t bd_dma_addr;
> @@ -218,37 +218,37 @@ struct qmc {
>   struct qmc_chan *chans[64];
>   };
>   
> -static inline void qmc_write16(void *__iomem addr, u16 val)
> +static inline void qmc_write16(void __iomem *addr, u16 val)
>   {
>   iowrite16be(val, addr);
>   }
>   
> -static inline u16 qmc_read16(void *__iomem addr)
> +static inline u16 qmc_read16(void __iomem *addr)
>   {
>   return ioread16be(addr);
>   }
>   
> -static inline void qmc_setbits16(void *__iomem addr, u16 set)
> +static inline void qmc_setbits16(void __iomem *addr, u16 set)
>   {
>   qmc_write16(addr, qmc_read16(addr) | set);
>   }
>   
> -static inline void qmc_clrbits16(void *__iomem addr, u16 clr)
> +static inline void qmc_clrbits16(void __iomem *addr, u16 clr)
>   {
>   qmc_write16(addr, qmc_read16(addr) & ~clr);
>   }
>   
> -static inline void qmc_write32(void *__iomem addr, u32 val)
> +static inline void qmc_write32(void __iomem *addr, u32 val)
>   {
>   iowrite32be(val, addr);
>   }
>   
> -static inline u32 qmc_read32(void *__iomem addr)
> +static inline u32 qmc_read32(void __iomem *addr)
>   {
>   return ioread32be(addr);
>   }
>   
> -static inline void qmc_setbits32(void *__iomem addr, u32 set)
> +static inline void qmc_setbits32(void __iomem *addr, u32 set)
>   {
>   qmc_write32(addr, qmc_read32(addr) | set);
>   }
> @@ -318,7 +318,7 @@ int qmc_chan_write_submit(struct qmc_chan *chan, 
> dma_addr_t addr, size_t length,
>   {
>   struct qmc_xfer_desc *xfer_desc;
>   unsigned long flags;
> - cbd_t *__iomem bd;
> + cbd_t __iomem *bd;
>   u16 ctrl;
>   int ret;
>   
> @@ -374,7 +374,7 @@ static void qmc_chan_write_done(struct qmc_chan *chan)
>   void (*complete)(void *context);
>   unsigned long flags;
>   void *context;
> - cbd_t *__iomem bd;
> + cbd_t __iomem *bd;
>   u16 ctrl;
>   
>   /*
> @@ -425,7 +425,7 @@ int qmc_chan_read_submit(struct qmc_chan *chan, 
> dma_addr_t addr, size_t length,
>   {
>   struct qmc_xfer_desc *xfer_desc;
>   unsigned long flags;
> - cbd_t *__iomem bd;
> + cbd_t __iomem *bd;
>   u16 ctrl;
>   int ret;
>   
> @@ -488,7 +488,7 @@ static void qmc_chan_read_done(struct qmc_chan *chan)
>   void (*complete)(void *context, size_t size);
>   struct qmc_xfer_desc *xfer_desc;
>   unsigned long flags;
> - cbd_t *__iomem bd;
> + cbd_t __iomem *bd;
>   void *context;
>   u16 datalen;
>   u16 ctrl;
> @@ -663,7 +663,7 @@ static void qmc_chan_reset_rx(struct qmc_chan *chan)
>   {
>   struct qmc_xfer_desc *xfer_desc;
>   unsigned long flags;
> - cbd_t *__iomem bd;
> + cbd_t __iomem *bd;
>   u16 ctrl;
>   
>   spin_lock_irqsave(>rx_lock, flags);
> @@ -694,7 +694,7 @@ static void qmc_chan_reset_tx(struct qmc_chan *chan)
>   {
>   struct qmc_xfer_desc *xfer_desc;
>   unsigned long flags;
> - cbd_t *__iomem bd;
> + cbd_t __iomem *bd;
>   u16 ctrl;
>   
>   spin_lock_irqsave(>tx_lock, flags);


Re: [PATCH v2 01/28] soc: fsl: cpm1: tsa: Fix __iomem addresses declaration

2023-08-08 Thread Christophe Leroy


Le 26/07/2023 à 17:01, Herve Codina a écrit :
> Running sparse (make C=1) on tsa.c raises a lot of warning such as:
>--- 8< ---
>warning: incorrect type in assignment (different address spaces)
>   expected void *[noderef] si_regs
>   got void [noderef] __iomem *
>--- 8< ---
> 
> Indeed, some variable were declared 'type *__iomem var' instead of
> 'type __iomem *var'.
> 
> Use the correct declaration to remove these warnings.
> 
> Fixes: 1d4ba0b81c1c ("soc: fsl: cpm1: Add support for TSA")
> Signed-off-by: Herve Codina 

Reviewed-by: Christophe Leroy 

> ---
>   drivers/soc/fsl/qe/tsa.c | 22 +++---
>   1 file changed, 11 insertions(+), 11 deletions(-)
> 
> diff --git a/drivers/soc/fsl/qe/tsa.c b/drivers/soc/fsl/qe/tsa.c
> index 3646153117b3..e0527b9efd05 100644
> --- a/drivers/soc/fsl/qe/tsa.c
> +++ b/drivers/soc/fsl/qe/tsa.c
> @@ -98,9 +98,9 @@
>   #define TSA_SIRP0x10
>   
>   struct tsa_entries_area {
> - void *__iomem entries_start;
> - void *__iomem entries_next;
> - void *__iomem last_entry;
> + void __iomem *entries_start;
> + void __iomem *entries_next;
> + void __iomem *last_entry;
>   };
>   
>   struct tsa_tdm {
> @@ -117,8 +117,8 @@ struct tsa_tdm {
>   
>   struct tsa {
>   struct device *dev;
> - void *__iomem si_regs;
> - void *__iomem si_ram;
> + void __iomem *si_regs;
> + void __iomem *si_ram;
>   resource_size_t si_ram_sz;
>   spinlock_t  lock;
>   int tdms; /* TSA_TDMx ORed */
> @@ -135,27 +135,27 @@ static inline struct tsa *tsa_serial_get_tsa(struct 
> tsa_serial *tsa_serial)
>   return container_of(tsa_serial, struct tsa, serials[tsa_serial->id]);
>   }
>   
> -static inline void tsa_write32(void *__iomem addr, u32 val)
> +static inline void tsa_write32(void __iomem *addr, u32 val)
>   {
>   iowrite32be(val, addr);
>   }
>   
> -static inline void tsa_write8(void *__iomem addr, u32 val)
> +static inline void tsa_write8(void __iomem *addr, u32 val)
>   {
>   iowrite8(val, addr);
>   }
>   
> -static inline u32 tsa_read32(void *__iomem addr)
> +static inline u32 tsa_read32(void __iomem *addr)
>   {
>   return ioread32be(addr);
>   }
>   
> -static inline void tsa_clrbits32(void *__iomem addr, u32 clr)
> +static inline void tsa_clrbits32(void __iomem *addr, u32 clr)
>   {
>   tsa_write32(addr, tsa_read32(addr) & ~clr);
>   }
>   
> -static inline void tsa_clrsetbits32(void *__iomem addr, u32 clr, u32 set)
> +static inline void tsa_clrsetbits32(void __iomem *addr, u32 clr, u32 set)
>   {
>   tsa_write32(addr, (tsa_read32(addr) & ~clr) | set);
>   }
> @@ -313,7 +313,7 @@ static u32 tsa_serial_id2csel(struct tsa *tsa, u32 
> serial_id)
>   static int tsa_add_entry(struct tsa *tsa, struct tsa_entries_area *area,
>u32 count, u32 serial_id)
>   {
> - void *__iomem addr;
> + void __iomem *addr;
>   u32 left;
>   u32 val;
>   u32 cnt;


Re: [PATCH v7 7/7] mm/memory_hotplug: Enable runtime update of memmap_on_memory parameter

2023-08-08 Thread Aneesh Kumar K V
On 8/8/23 12:05 AM, David Hildenbrand wrote:
> On 07.08.23 14:41, David Hildenbrand wrote:
>> On 07.08.23 14:27, Michal Hocko wrote:
>>> On Sat 05-08-23 19:54:23, Aneesh Kumar K V wrote:
>>> [...]
 Do you see a need for firmware-managed memory to be hotplugged in with
 different memory block sizes?
>>>
>>> In short. Yes. Slightly longer, a fixed size memory block semantic is
>>> just standing in the way and I would even argue it is actively harmful.
>>> Just have a look at ridicously small memory blocks on ppc. I do
>>> understand that it makes some sense to be aligned to the memory model
>>> (so sparsmem section aligned). In an ideal world, memory hotplug v2
>>> interface (if we ever go that path) should be physical memory range based.
>>
>> Yes, we discussed that a couple of times already (and so far nobody
>> cared to implement any of that).
>>
>> Small memory block sizes are very beneficial for use cases like PPC
>> dlar, virtio-mem, hyperv-balloon, ... essentially in most virtual
>> environments where you might want to add/remove memory in very small
>> granularity. I don't see that changing any time soon. Rather the opposite.
>>
>> Small memory block sizes are suboptimal for large machines where you
>> might never end up removing such memory (boot memory), or when dealing
>> with devices that can only be removed in one piece (DIMM/kmem). We
>> already have memory groups in place to model that.
>>
>> For the latter it might be beneficial to have memory blocks of larger
>> size that correspond to the physical memory ranges. That might also make
>> a memmap (re-)configuration easier.
>>
>> Not sure if that is standing in any way or is harmful, though.
>>
> 
> Just because I thought of something right now, I'll share it, maybe it makes 
> sense.
> 
> Assume when we get add_memory*(MHP_MEMMAP_ON_MEMORY) and it is enabled by the 
> admin:
> 
> 1) We create a single altmap at the beginning of the memory
> 
> 2) We create the existing fixed-size memory block devices, but flag them
>    to be part of a single "altmap" unit.
> 
> 3) Whenever we trigger offlining of a single such memory block, we
>    offline *all* memory blocks belonging to that altmap, essentially
>    using a single offline_pages() call and updating all memory block
>    states accordingly.
> 
> 4) Whenever we trigger onlining of a single such memory block, we
>    online *all* memory blocks belonging to that altmap, using a single
>    online_pages() call.
> 
> 5) We fail remove_memory() if it doesn't cover the same (altmap) range.
> 
> So we can avoid having a memory block v2 (and all that comes with that ...) 
> for now and still get that altmap stuff sorted out. As that altmap behavior 
> can be controlled by the admin, we should be fine for now.
> 
> I think all memory notifiers should already be able to handle bigger 
> granularity, but it would be easy to check. Some internal things might 
> require a bit of tweaking.
> 

We can look at the possibility of using the altmap space reserved for a 
namespace (via option -M dev) for allocating struct page memory even with 
dax/kmem. 

-aneesh



Re: [PATCH v7 7/7] mm/memory_hotplug: Enable runtime update of memmap_on_memory parameter

2023-08-08 Thread Aneesh Kumar K V
On 8/8/23 12:05 AM, David Hildenbrand wrote:
> On 07.08.23 14:41, David Hildenbrand wrote:
>> On 07.08.23 14:27, Michal Hocko wrote:
>>> On Sat 05-08-23 19:54:23, Aneesh Kumar K V wrote:
>>> [...]
 Do you see a need for firmware-managed memory to be hotplugged in with
 different memory block sizes?
>>>
>>> In short. Yes. Slightly longer, a fixed size memory block semantic is
>>> just standing in the way and I would even argue it is actively harmful.
>>> Just have a look at ridicously small memory blocks on ppc. I do
>>> understand that it makes some sense to be aligned to the memory model
>>> (so sparsmem section aligned). In an ideal world, memory hotplug v2
>>> interface (if we ever go that path) should be physical memory range based.
>>
>> Yes, we discussed that a couple of times already (and so far nobody
>> cared to implement any of that).
>>
>> Small memory block sizes are very beneficial for use cases like PPC
>> dlar, virtio-mem, hyperv-balloon, ... essentially in most virtual
>> environments where you might want to add/remove memory in very small
>> granularity. I don't see that changing any time soon. Rather the opposite.
>>
>> Small memory block sizes are suboptimal for large machines where you
>> might never end up removing such memory (boot memory), or when dealing
>> with devices that can only be removed in one piece (DIMM/kmem). We
>> already have memory groups in place to model that.
>>
>> For the latter it might be beneficial to have memory blocks of larger
>> size that correspond to the physical memory ranges. That might also make
>> a memmap (re-)configuration easier.
>>
>> Not sure if that is standing in any way or is harmful, though.
>>
> 
> Just because I thought of something right now, I'll share it, maybe it makes 
> sense.
> 
> Assume when we get add_memory*(MHP_MEMMAP_ON_MEMORY) and it is enabled by the 
> admin:
> 
> 1) We create a single altmap at the beginning of the memory
> 
> 2) We create the existing fixed-size memory block devices, but flag them
>    to be part of a single "altmap" unit.
> 
> 3) Whenever we trigger offlining of a single such memory block, we
>    offline *all* memory blocks belonging to that altmap, essentially
>    using a single offline_pages() call and updating all memory block
>    states accordingly.
> 
> 4) Whenever we trigger onlining of a single such memory block, we
>    online *all* memory blocks belonging to that altmap, using a single
>    online_pages() call.
> 
> 5) We fail remove_memory() if it doesn't cover the same (altmap) range.
> 
> So we can avoid having a memory block v2 (and all that comes with that ...) 
> for now and still get that altmap stuff sorted out. As that altmap behavior 
> can be controlled by the admin, we should be fine for now.
> 
> I think all memory notifiers should already be able to handle bigger 
> granularity, but it would be easy to check. Some internal things might 
> require a bit of tweaking.
> 
> Just a thought.
> 


W.r.t enabling memmap_on_memory for ppc64, I guess I will drop patch 7 and 
resend the series so that Andrew can pick rest of the patches? 

-aneesh





[PATCH v1 5/6] powerpc/8xx: Remove immr_map() and immr_unmap()

2023-08-08 Thread Christophe Leroy
Since commit fb533d0c5a97 ("[POWERPC] 8xx: Infrastructure code cleanup.")
immr_map() is just returning mpc8xxx_immr pointer and immr_unmap()
do nothing.

We already have parts of code that use mpc8xxx_immr directly so get rid
of immr_map() and immr_unmap() by using mpc8xxx_immr directly. And avoid
going through local pointers that hide the pointed structure.

Signed-off-by: Christophe Leroy 
---
 arch/powerpc/include/asm/fs_pd.h|  8 ---
 arch/powerpc/platforms/8xx/cpm1.c   | 10 ++--
 arch/powerpc/platforms/8xx/m8xx_setup.c | 66 +++--
 3 files changed, 22 insertions(+), 62 deletions(-)

diff --git a/arch/powerpc/include/asm/fs_pd.h b/arch/powerpc/include/asm/fs_pd.h
index d251a55de8b0..82f0e528e21c 100644
--- a/arch/powerpc/include/asm/fs_pd.h
+++ b/arch/powerpc/include/asm/fs_pd.h
@@ -22,14 +22,6 @@
 #define cpm2_unmap(addr) do {} while(0)
 #endif
 
-#ifdef CONFIG_PPC_8xx
-#include 
-
-#define immr_map(member) (_immr->member)
-#define immr_map_size(member, size) (_immr->member)
-#define immr_unmap(addr) do {} while (0)
-#endif
-
 static inline int uart_baudrate(void)
 {
 return get_baudrate();
diff --git a/arch/powerpc/platforms/8xx/cpm1.c 
b/arch/powerpc/platforms/8xx/cpm1.c
index 34ab29966c8b..ebb5f6a27dbf 100644
--- a/arch/powerpc/platforms/8xx/cpm1.c
+++ b/arch/powerpc/platforms/8xx/cpm1.c
@@ -41,7 +41,7 @@
 #include 
 #include 
 
-#include 
+#include 
 
 #ifdef CONFIG_8xx_GPIO
 #include 
@@ -54,8 +54,6 @@ immap_t __iomem *mpc8xx_immr = (void __iomem *)VIRT_IMMR_BASE;
 
 void __init cpm_reset(void)
 {
-   sysconf8xx_t __iomem *siu_conf;
-
cpmp = _immr->im_cpm;
 
 #ifndef CONFIG_PPC_EARLY_DEBUG_CPM
@@ -77,12 +75,10 @@ void __init cpm_reset(void)
 * manual recommends it.
 * Bit 25, FAM can also be set to use FEC aggressive mode (860T).
 */
-   siu_conf = immr_map(im_siu_conf);
if ((mfspr(SPRN_IMMR) & 0x) == 0x0900) /* MPC885 */
-   out_be32(_conf->sc_sdcr, 0x40);
+   out_be32(_immr->im_siu_conf.sc_sdcr, 0x40);
else
-   out_be32(_conf->sc_sdcr, 1);
-   immr_unmap(siu_conf);
+   out_be32(_immr->im_siu_conf.sc_sdcr, 1);
 }
 
 static DEFINE_SPINLOCK(cmd_lock);
diff --git a/arch/powerpc/platforms/8xx/m8xx_setup.c 
b/arch/powerpc/platforms/8xx/m8xx_setup.c
index 24f358f86d16..3c5c4e08b6a9 100644
--- a/arch/powerpc/platforms/8xx/m8xx_setup.c
+++ b/arch/powerpc/platforms/8xx/m8xx_setup.c
@@ -22,7 +22,6 @@
 
 #include 
 #include 
-#include 
 #include 
 
 #include "pic.h"
@@ -41,14 +40,11 @@ static irqreturn_t timebase_interrupt(int irq, void *dev)
 void __init __attribute__ ((weak))
 init_internal_rtc(void)
 {
-   sit8xx_t __iomem *sys_tmr = immr_map(im_sit);
-
/* Disable the RTC one second and alarm interrupts. */
-   clrbits16(_tmr->sit_rtcsc, (RTCSC_SIE | RTCSC_ALE));
+   clrbits16(_immr->im_sit.sit_rtcsc, (RTCSC_SIE | RTCSC_ALE));
 
/* Enable the RTC */
-   setbits16(_tmr->sit_rtcsc, (RTCSC_RTF | RTCSC_RTE));
-   immr_unmap(sys_tmr);
+   setbits16(_immr->im_sit.sit_rtcsc, (RTCSC_RTF | RTCSC_RTE));
 }
 
 static int __init get_freq(char *name, unsigned long *val)
@@ -80,23 +76,14 @@ static int __init get_freq(char *name, unsigned long *val)
 void __init mpc8xx_calibrate_decr(void)
 {
struct device_node *cpu;
-   cark8xx_t __iomem *clk_r1;
-   car8xx_t __iomem *clk_r2;
-   sitk8xx_t __iomem *sys_tmr1;
-   sit8xx_t __iomem *sys_tmr2;
int irq, virq;
 
-   clk_r1 = immr_map(im_clkrstk);
-
/* Unlock the SCCR. */
-   out_be32(_r1->cark_sccrk, ~KAPWR_KEY);
-   out_be32(_r1->cark_sccrk, KAPWR_KEY);
-   immr_unmap(clk_r1);
+   out_be32(_immr->im_clkrstk.cark_sccrk, ~KAPWR_KEY);
+   out_be32(_immr->im_clkrstk.cark_sccrk, KAPWR_KEY);
 
/* Force all 8xx processors to use divide by 16 processor clock. */
-   clk_r2 = immr_map(im_clkrst);
-   setbits32(_r2->car_sccr, 0x0200);
-   immr_unmap(clk_r2);
+   setbits32(_immr->im_clkrst.car_sccr, 0x0200);
 
/* Processor frequency is MHz.
 */
@@ -123,14 +110,12 @@ void __init mpc8xx_calibrate_decr(void)
 * we guarantee the registers are locked, then we unlock them
 * for our use.
 */
-   sys_tmr1 = immr_map(im_sitk);
-   out_be32(_tmr1->sitk_tbscrk, ~KAPWR_KEY);
-   out_be32(_tmr1->sitk_rtcsck, ~KAPWR_KEY);
-   out_be32(_tmr1->sitk_tbk, ~KAPWR_KEY);
-   out_be32(_tmr1->sitk_tbscrk, KAPWR_KEY);
-   out_be32(_tmr1->sitk_rtcsck, KAPWR_KEY);
-   out_be32(_tmr1->sitk_tbk, KAPWR_KEY);
-   immr_unmap(sys_tmr1);
+   out_be32(_immr->im_sitk.sitk_tbscrk, ~KAPWR_KEY);
+   out_be32(_immr->im_sitk.sitk_rtcsck, ~KAPWR_KEY);
+   out_be32(_immr->im_sitk.sitk_tbk, ~KAPWR_KEY);
+   out_be32(_immr->im_sitk.sitk_tbscrk, KAPWR_KEY);
+   out_be32(_immr->im_sitk.sitk_rtcsck, KAPWR_KEY);
+   out_be32(_immr->im_sitk.sitk_tbk, 

[PATCH v1 6/6] powerpc/cpm2: Remove cpm2_map() and cpm2_unmap()

2023-08-08 Thread Christophe Leroy
Since commit 449012daa92a ("[POWERPC] cpm2: Infrastructure code
cleanup.") cpm2_map() is just returning cpm2_immr pointer and
cpm2_unmap() does nothing.

We already have parts of code that use cpm2_immr directly so get rid
of cpm2_map() and cpm2_unmap() by using cpm2_immr directly. And avoid
going through local pointers that hide the pointed structure.

Signed-off-by: Christophe Leroy 
---
 arch/powerpc/include/asm/fs_pd.h |  8 
 arch/powerpc/sysdev/cpm2.c   | 32 +++-
 arch/powerpc/sysdev/cpm2_pic.c   |  3 +--
 3 files changed, 12 insertions(+), 31 deletions(-)

diff --git a/arch/powerpc/include/asm/fs_pd.h b/arch/powerpc/include/asm/fs_pd.h
index 82f0e528e21c..d530f68b4eef 100644
--- a/arch/powerpc/include/asm/fs_pd.h
+++ b/arch/powerpc/include/asm/fs_pd.h
@@ -14,14 +14,6 @@
 #include 
 #include 
 
-#ifdef CONFIG_CPM2
-#include 
-
-#define cpm2_map(member) (_immr->member)
-#define cpm2_map_size(member, size) (_immr->member)
-#define cpm2_unmap(addr) do {} while(0)
-#endif
-
 static inline int uart_baudrate(void)
 {
 return get_baudrate();
diff --git a/arch/powerpc/sysdev/cpm2.c b/arch/powerpc/sysdev/cpm2.c
index a92691193314..14cc5ea936c0 100644
--- a/arch/powerpc/sysdev/cpm2.c
+++ b/arch/powerpc/sysdev/cpm2.c
@@ -40,7 +40,6 @@
 #include 
 #include 
 #include 
-#include 
 
 #include 
 
@@ -118,9 +117,9 @@ void __cpm2_setbrg(uint brg, uint rate, uint clk, int 
div16, int src)
/* This is good enough to get SMCs running.
*/
if (brg < 4) {
-   bp = cpm2_map_size(im_brgc1, 16);
+   bp = _immr->im_brgc1;
} else {
-   bp = cpm2_map_size(im_brgc5, 16);
+   bp = _immr->im_brgc5;
brg -= 4;
}
bp += brg;
@@ -130,7 +129,6 @@ void __cpm2_setbrg(uint brg, uint rate, uint clk, int 
div16, int src)
val |= CPM_BRG_DIV16;
 
out_be32(bp, val);
-   cpm2_unmap(bp);
 }
 EXPORT_SYMBOL(__cpm2_setbrg);
 
@@ -139,7 +137,6 @@ int __init cpm2_clk_setup(enum cpm_clk_target target, int 
clock, int mode)
int ret = 0;
int shift;
int i, bits = 0;
-   cpmux_t __iomem *im_cpmux;
u32 __iomem *reg;
u32 mask = 7;
 
@@ -202,35 +199,33 @@ int __init cpm2_clk_setup(enum cpm_clk_target target, int 
clock, int mode)
{CPM_CLK_SCC4, CPM_CLK8, 7},
};
 
-   im_cpmux = cpm2_map(im_cpmux);
-
switch (target) {
case CPM_CLK_SCC1:
-   reg = _cpmux->cmx_scr;
+   reg = _immr->im_cpmux.cmx_scr;
shift = 24;
break;
case CPM_CLK_SCC2:
-   reg = _cpmux->cmx_scr;
+   reg = _immr->im_cpmux.cmx_scr;
shift = 16;
break;
case CPM_CLK_SCC3:
-   reg = _cpmux->cmx_scr;
+   reg = _immr->im_cpmux.cmx_scr;
shift = 8;
break;
case CPM_CLK_SCC4:
-   reg = _cpmux->cmx_scr;
+   reg = _immr->im_cpmux.cmx_scr;
shift = 0;
break;
case CPM_CLK_FCC1:
-   reg = _cpmux->cmx_fcr;
+   reg = _immr->im_cpmux.cmx_fcr;
shift = 24;
break;
case CPM_CLK_FCC2:
-   reg = _cpmux->cmx_fcr;
+   reg = _immr->im_cpmux.cmx_fcr;
shift = 16;
break;
case CPM_CLK_FCC3:
-   reg = _cpmux->cmx_fcr;
+   reg = _immr->im_cpmux.cmx_fcr;
shift = 8;
break;
default:
@@ -260,7 +255,6 @@ int __init cpm2_clk_setup(enum cpm_clk_target target, int 
clock, int mode)
 
out_be32(reg, (in_be32(reg) & ~mask) | bits);
 
-   cpm2_unmap(im_cpmux);
return ret;
 }
 
@@ -269,7 +263,6 @@ int __init cpm2_smc_clk_setup(enum cpm_clk_target target, 
int clock)
int ret = 0;
int shift;
int i, bits = 0;
-   cpmux_t __iomem *im_cpmux;
u8 __iomem *reg;
u8 mask = 3;
 
@@ -284,16 +277,14 @@ int __init cpm2_smc_clk_setup(enum cpm_clk_target target, 
int clock)
{CPM_CLK_SMC2, CPM_CLK15, 3},
};
 
-   im_cpmux = cpm2_map(im_cpmux);
-
switch (target) {
case CPM_CLK_SMC1:
-   reg = _cpmux->cmx_smr;
+   reg = _immr->im_cpmux.cmx_smr;
mask = 3;
shift = 4;
break;
case CPM_CLK_SMC2:
-   reg = _cpmux->cmx_smr;
+   reg = _immr->im_cpmux.cmx_smr;
mask = 3;
shift = 0;
break;
@@ -316,7 +307,6 @@ int __init cpm2_smc_clk_setup(enum cpm_clk_target target, 
int clock)
 
out_8(reg, (in_8(reg) & ~mask) | bits);
 
-   cpm2_unmap(im_cpmux);
return ret;
 }
 
diff --git a/arch/powerpc/sysdev/cpm2_pic.c b/arch/powerpc/sysdev/cpm2_pic.c
index d6c1359ae89d..e14493685fe8 100644
--- 

[PATCH v1 4/6] powerpc: Remove CONFIG_PCI_8260

2023-08-08 Thread Christophe Leroy
CONFIG_PCI_8260 is not used anymore, remove it.

Signed-off-by: Christophe Leroy 
---
 arch/powerpc/Kconfig| 6 --
 arch/powerpc/platforms/82xx/Kconfig | 1 +
 2 files changed, 1 insertion(+), 6 deletions(-)

diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index 0b1172cbeccb..c157be9547c5 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -1144,12 +1144,6 @@ config FSL_GTM
help
  Freescale General-purpose Timers support
 
-config PCI_8260
-   bool
-   depends on PCI && 8260
-   select PPC_INDIRECT_PCI
-   default y
-
 config FSL_RIO
bool "Freescale Embedded SRIO Controller support"
depends on RAPIDIO = y && HAVE_RAPIDIO
diff --git a/arch/powerpc/platforms/82xx/Kconfig 
b/arch/powerpc/platforms/82xx/Kconfig
index 4eb372bdab70..58e58b4f6a12 100644
--- a/arch/powerpc/platforms/82xx/Kconfig
+++ b/arch/powerpc/platforms/82xx/Kconfig
@@ -32,6 +32,7 @@ config 8260
bool
depends on PPC_BOOK3S_32
select CPM2
+   select PPC_INDIRECT_PCI if PCI
help
  The MPC8260 is a typical embedded CPU made by Freescale.  Selecting
  this option means that you wish to build a kernel for a machine with
-- 
2.41.0



[PATCH v1 3/6] powerpc/include: Remove mpc8260.h and m82xx_pci.h

2023-08-08 Thread Christophe Leroy
SIU_INT_IRQ1 is not used anywhere and __IO_BASE is defined in
asm/io.h

Remove m82xx_pci.h

Then the only thing remaining in mpc8260.h is MPC82XX_BCR_PLDP

Move MPC82XX_BCR_PLDP into asm/cpm2.h then remove mpc8260.h

Signed-off-by: Christophe Leroy 
---
 arch/powerpc/include/asm/cpm2.h   |  3 +++
 arch/powerpc/include/asm/fs_pd.h  |  4 
 arch/powerpc/include/asm/mpc8260.h| 22 ---
 arch/powerpc/platforms/82xx/ep8248e.c |  1 -
 arch/powerpc/platforms/82xx/km82xx.c  |  1 -
 arch/powerpc/platforms/82xx/m82xx_pci.h   | 14 
 arch/powerpc/sysdev/cpm2.c|  1 -
 arch/powerpc/sysdev/cpm2_pic.c|  1 -
 .../net/ethernet/freescale/fs_enet/mac-fcc.c  |  1 -
 9 files changed, 3 insertions(+), 45 deletions(-)
 delete mode 100644 arch/powerpc/include/asm/mpc8260.h
 delete mode 100644 arch/powerpc/platforms/82xx/m82xx_pci.h

diff --git a/arch/powerpc/include/asm/cpm2.h b/arch/powerpc/include/asm/cpm2.h
index 9ee192a6c5d7..249d43cc6427 100644
--- a/arch/powerpc/include/asm/cpm2.h
+++ b/arch/powerpc/include/asm/cpm2.h
@@ -1080,6 +1080,9 @@ typedef struct im_idma {
 #define FCC2_MEM_OFFSET FCC_MEM_OFFSET(1)
 #define FCC3_MEM_OFFSET FCC_MEM_OFFSET(2)
 
+/* Pipeline Maximum Depth */
+#define MPC82XX_BCR_PLDP 0x0080
+
 /* Clocks and GRG's */
 
 enum cpm_clk_dir {
diff --git a/arch/powerpc/include/asm/fs_pd.h b/arch/powerpc/include/asm/fs_pd.h
index 2b2b52b7451d..d251a55de8b0 100644
--- a/arch/powerpc/include/asm/fs_pd.h
+++ b/arch/powerpc/include/asm/fs_pd.h
@@ -17,10 +17,6 @@
 #ifdef CONFIG_CPM2
 #include 
 
-#if defined(CONFIG_8260)
-#include 
-#endif
-
 #define cpm2_map(member) (_immr->member)
 #define cpm2_map_size(member, size) (_immr->member)
 #define cpm2_unmap(addr) do {} while(0)
diff --git a/arch/powerpc/include/asm/mpc8260.h 
b/arch/powerpc/include/asm/mpc8260.h
deleted file mode 100644
index 155114bbd1a2..
--- a/arch/powerpc/include/asm/mpc8260.h
+++ /dev/null
@@ -1,22 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Since there are many different boards and no standard configuration,
- * we have a unique include file for each.  Rather than change every
- * file that has to include MPC8260 configuration, they all include
- * this one and the configuration switching is done here.
- */
-#ifdef __KERNEL__
-#ifndef __ASM_POWERPC_MPC8260_H__
-#define __ASM_POWERPC_MPC8260_H__
-
-#define MPC82XX_BCR_PLDP 0x0080 /* Pipeline Maximum Depth */
-
-#ifdef CONFIG_8260
-
-#ifdef CONFIG_PCI_8260
-#include 
-#endif
-
-#endif /* CONFIG_8260 */
-#endif /* !__ASM_POWERPC_MPC8260_H__ */
-#endif /* __KERNEL__ */
diff --git a/arch/powerpc/platforms/82xx/ep8248e.c 
b/arch/powerpc/platforms/82xx/ep8248e.c
index 4bfa1a95e155..3dc65ce1f175 100644
--- a/arch/powerpc/platforms/82xx/ep8248e.c
+++ b/arch/powerpc/platforms/82xx/ep8248e.c
@@ -20,7 +20,6 @@
 #include 
 #include 
 #include 
-#include 
 
 #include 
 #include 
diff --git a/arch/powerpc/platforms/82xx/km82xx.c 
b/arch/powerpc/platforms/82xx/km82xx.c
index 51c9bfd97592..c86da3f2b74b 100644
--- a/arch/powerpc/platforms/82xx/km82xx.c
+++ b/arch/powerpc/platforms/82xx/km82xx.c
@@ -19,7 +19,6 @@
 #include 
 #include 
 #include 
-#include 
 
 #include 
 #include 
diff --git a/arch/powerpc/platforms/82xx/m82xx_pci.h 
b/arch/powerpc/platforms/82xx/m82xx_pci.h
deleted file mode 100644
index d07c4d7606f6..
--- a/arch/powerpc/platforms/82xx/m82xx_pci.h
+++ /dev/null
@@ -1,14 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-#ifndef _PPC_KERNEL_M82XX_PCI_H
-#define _PPC_KERNEL_M82XX_PCI_H
-
-/*
- */
-
-#define SIU_INT_IRQ1   ((uint)0x13 + CPM_IRQ_OFFSET)
-
-#ifndef _IO_BASE
-#define _IO_BASE isa_io_base
-#endif
-
-#endif /* _PPC_KERNEL_M8260_PCI_H */
diff --git a/arch/powerpc/sysdev/cpm2.c b/arch/powerpc/sysdev/cpm2.c
index 915f4d3991c3..a92691193314 100644
--- a/arch/powerpc/sysdev/cpm2.c
+++ b/arch/powerpc/sysdev/cpm2.c
@@ -37,7 +37,6 @@
 
 #include 
 #include 
-#include 
 #include 
 #include 
 #include 
diff --git a/arch/powerpc/sysdev/cpm2_pic.c b/arch/powerpc/sysdev/cpm2_pic.c
index cb9ba4ef557a..d6c1359ae89d 100644
--- a/arch/powerpc/sysdev/cpm2_pic.c
+++ b/arch/powerpc/sysdev/cpm2_pic.c
@@ -33,7 +33,6 @@
 #include 
 
 #include 
-#include 
 #include 
 #include 
 
diff --git a/drivers/net/ethernet/freescale/fs_enet/mac-fcc.c 
b/drivers/net/ethernet/freescale/fs_enet/mac-fcc.c
index b47490be872c..c9491b6e8708 100644
--- a/drivers/net/ethernet/freescale/fs_enet/mac-fcc.c
+++ b/drivers/net/ethernet/freescale/fs_enet/mac-fcc.c
@@ -38,7 +38,6 @@
 #include 
 
 #include 
-#include 
 #include 
 
 #include 
-- 
2.41.0



[PATCH v1 2/6] powerpc/include: Declare mpc8xx_immr in 8xx_immap.h

2023-08-08 Thread Christophe Leroy
Do the same as for cmp2_immr : declare it at the same place
as its type immap_t, that is in 8xx_immap.h instead of fs_pd.h

Signed-off-by: Christophe Leroy 
---
 arch/powerpc/include/asm/8xx_immap.h | 2 ++
 arch/powerpc/include/asm/fs_pd.h | 2 --
 arch/powerpc/platforms/8xx/adder875.c| 2 +-
 arch/powerpc/platforms/8xx/mpc86xads_setup.c | 1 -
 arch/powerpc/platforms/8xx/mpc885ads_setup.c | 1 -
 5 files changed, 3 insertions(+), 5 deletions(-)

diff --git a/arch/powerpc/include/asm/8xx_immap.h 
b/arch/powerpc/include/asm/8xx_immap.h
index bdf0563ba423..f9cac46a95cb 100644
--- a/arch/powerpc/include/asm/8xx_immap.h
+++ b/arch/powerpc/include/asm/8xx_immap.h
@@ -560,5 +560,7 @@ typedef struct immap {
cpm8xx_tim_cpm; /* Communication processor */
 } immap_t;
 
+extern immap_t __iomem *mpc8xx_immr;
+
 #endif /* __IMMAP_8XX__ */
 #endif /* __KERNEL__ */
diff --git a/arch/powerpc/include/asm/fs_pd.h b/arch/powerpc/include/asm/fs_pd.h
index 8def56ec05c6..2b2b52b7451d 100644
--- a/arch/powerpc/include/asm/fs_pd.h
+++ b/arch/powerpc/include/asm/fs_pd.h
@@ -29,8 +29,6 @@
 #ifdef CONFIG_PPC_8xx
 #include 
 
-extern immap_t __iomem *mpc8xx_immr;
-
 #define immr_map(member) (_immr->member)
 #define immr_map_size(member, size) (_immr->member)
 #define immr_unmap(addr) do {} while (0)
diff --git a/arch/powerpc/platforms/8xx/adder875.c 
b/arch/powerpc/platforms/8xx/adder875.c
index 7e83eb6746f4..ae72c574eb7e 100644
--- a/arch/powerpc/platforms/8xx/adder875.c
+++ b/arch/powerpc/platforms/8xx/adder875.c
@@ -13,7 +13,7 @@
 #include 
 #include 
 #include 
-#include 
+#include 
 #include 
 
 #include "mpc8xx.h"
diff --git a/arch/powerpc/platforms/8xx/mpc86xads_setup.c 
b/arch/powerpc/platforms/8xx/mpc86xads_setup.c
index 11b3d1116db1..e4192c0a3c0c 100644
--- a/arch/powerpc/platforms/8xx/mpc86xads_setup.c
+++ b/arch/powerpc/platforms/8xx/mpc86xads_setup.c
@@ -24,7 +24,6 @@
 #include 
 #include 
 #include 
-#include 
 #include 
 
 #include "mpc86xads.h"
diff --git a/arch/powerpc/platforms/8xx/mpc885ads_setup.c 
b/arch/powerpc/platforms/8xx/mpc885ads_setup.c
index 2fc7cacbcd96..eb4e54ba417f 100644
--- a/arch/powerpc/platforms/8xx/mpc885ads_setup.c
+++ b/arch/powerpc/platforms/8xx/mpc885ads_setup.c
@@ -37,7 +37,6 @@
 #include 
 #include 
 #include 
-#include 
 #include 
 
 #include "mpc885ads.h"
-- 
2.41.0



[PATCH v1 1/6] powerpc/include: Remove unneeded #include

2023-08-08 Thread Christophe Leroy
tqm8xx_setup.c and fs_enet.h don't use any items provided by fs_pd.h

Remove unneeded #include 

Signed-off-by: Christophe Leroy 
---
 arch/powerpc/platforms/8xx/tqm8xx_setup.c| 1 -
 drivers/net/ethernet/freescale/fs_enet/fs_enet.h | 1 -
 2 files changed, 2 deletions(-)

diff --git a/arch/powerpc/platforms/8xx/tqm8xx_setup.c 
b/arch/powerpc/platforms/8xx/tqm8xx_setup.c
index 7d8eb50bb9cd..c422262ba27b 100644
--- a/arch/powerpc/platforms/8xx/tqm8xx_setup.c
+++ b/arch/powerpc/platforms/8xx/tqm8xx_setup.c
@@ -39,7 +39,6 @@
 #include 
 #include 
 #include 
-#include 
 #include 
 
 #include "mpc8xx.h"
diff --git a/drivers/net/ethernet/freescale/fs_enet/fs_enet.h 
b/drivers/net/ethernet/freescale/fs_enet/fs_enet.h
index cb419aef8d1b..aad96cb2ab4e 100644
--- a/drivers/net/ethernet/freescale/fs_enet/fs_enet.h
+++ b/drivers/net/ethernet/freescale/fs_enet/fs_enet.h
@@ -10,7 +10,6 @@
 #include 
 
 #include 
-#include 
 
 #ifdef CONFIG_CPM1
 #include 
-- 
2.41.0