Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH net-next 1/3] net: sparx5: support 72-bit VCAP actions
From: Daniel Machon @ 2024-04-03 18:41 UTC (permalink / raw)
  To: Lars Povlsen, Steen Hegelund, UNGLinuxDriver, David S. Miller,
	Eric Dumazet, Jakub Kicinski, Paolo Abeni
  Cc: linux-arm-kernel, netdev, linux-kernel, Daniel Machon
In-Reply-To: <20240403-mirror-redirect-actions-v1-0-c8e7c8132c89@microchip.com>

In preparation for supporting tc flower mirred and redirect action,
extend the VCAP API to support 72-bit wide VCAP actions.

Signed-off-by: Daniel Machon <daniel.machon@microchip.com>
---
 drivers/net/ethernet/microchip/vcap/vcap_api.c        | 12 ++++++++++++
 drivers/net/ethernet/microchip/vcap/vcap_api_client.h |  2 ++
 2 files changed, 14 insertions(+)

diff --git a/drivers/net/ethernet/microchip/vcap/vcap_api.c b/drivers/net/ethernet/microchip/vcap/vcap_api.c
index ef980e4e5bc2..80ae5e1708a6 100644
--- a/drivers/net/ethernet/microchip/vcap/vcap_api.c
+++ b/drivers/net/ethernet/microchip/vcap/vcap_api.c
@@ -2907,6 +2907,18 @@ int vcap_rule_add_action_u32(struct vcap_rule *rule,
 }
 EXPORT_SYMBOL_GPL(vcap_rule_add_action_u32);
 
+/* Add a 72 bit action field with value to the rule */
+int vcap_rule_add_action_u72(struct vcap_rule *rule,
+			     enum vcap_action_field action,
+			     struct vcap_u72_action *fieldval)
+{
+	struct vcap_client_actionfield_data data;
+
+	memcpy(&data.u72, fieldval, sizeof(data.u72));
+	return vcap_rule_add_action(rule, action, VCAP_FIELD_U72, &data);
+}
+EXPORT_SYMBOL_GPL(vcap_rule_add_action_u72);
+
 static int vcap_read_counter(struct vcap_rule_internal *ri,
 			     struct vcap_counter *ctr)
 {
diff --git a/drivers/net/ethernet/microchip/vcap/vcap_api_client.h b/drivers/net/ethernet/microchip/vcap/vcap_api_client.h
index 88641508f885..56874f2adbba 100644
--- a/drivers/net/ethernet/microchip/vcap/vcap_api_client.h
+++ b/drivers/net/ethernet/microchip/vcap/vcap_api_client.h
@@ -200,6 +200,8 @@ int vcap_rule_add_action_bit(struct vcap_rule *rule,
 			     enum vcap_action_field action, enum vcap_bit val);
 int vcap_rule_add_action_u32(struct vcap_rule *rule,
 			     enum vcap_action_field action, u32 value);
+int vcap_rule_add_action_u72(struct vcap_rule *rule, enum vcap_action_field action,
+			     struct vcap_u72_action *fieldval);
 
 /* Get number of rules in a vcap instance lookup chain id range */
 int vcap_admin_rule_count(struct vcap_admin *admin, int cid);

-- 
2.34.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related

* [PATCH net-next 2/3] net: sparx5: add support for tc flower mirred action.
From: Daniel Machon @ 2024-04-03 18:41 UTC (permalink / raw)
  To: Lars Povlsen, Steen Hegelund, UNGLinuxDriver, David S. Miller,
	Eric Dumazet, Jakub Kicinski, Paolo Abeni
  Cc: linux-arm-kernel, netdev, linux-kernel, Daniel Machon
In-Reply-To: <20240403-mirror-redirect-actions-v1-0-c8e7c8132c89@microchip.com>

Add support for tc flower mirred action. Two VCAP actions are encoded in
the rule - one for the port mask, and one for the port mask mode. When
the rule is hit, the destination mask is OR'ed with the port mask.

Also add helper to set port forwarding mask.

Signed-off-by: Daniel Machon <daniel.machon@microchip.com>
---
 .../ethernet/microchip/sparx5/sparx5_tc_flower.c   | 43 ++++++++++++++++++++++
 1 file changed, 43 insertions(+)

diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_tc_flower.c b/drivers/net/ethernet/microchip/sparx5/sparx5_tc_flower.c
index 523e0c470894..a86ce1f8f3e5 100644
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_tc_flower.c
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_tc_flower.c
@@ -1004,6 +1004,44 @@ static int sparx5_tc_action_vlan_push(struct vcap_admin *admin,
 	return err;
 }
 
+static void sparx5_tc_flower_set_port_mask(struct vcap_u72_action *ports,
+					   struct net_device *ndev)
+{
+	struct sparx5_port *port = netdev_priv(ndev);
+	int byidx = port->portno / BITS_PER_BYTE;
+	int biidx = port->portno % BITS_PER_BYTE;
+
+	ports->value[byidx] |= BIT(biidx);
+}
+
+static int sparx5_tc_action_mirred(struct vcap_admin *admin,
+				   struct vcap_rule *vrule,
+				   struct flow_cls_offload *fco,
+				   struct flow_action_entry *act)
+{
+	struct vcap_u72_action ports = {0};
+	int err;
+
+	if (admin->vtype != VCAP_TYPE_IS0 && admin->vtype != VCAP_TYPE_IS2) {
+		NL_SET_ERR_MSG_MOD(fco->common.extack,
+				   "Mirror action not supported in this VCAP");
+		return -EOPNOTSUPP;
+	}
+
+	err = vcap_rule_add_action_u32(vrule, VCAP_AF_MASK_MODE,
+				       SPX5_PMM_OR_DSTMASK);
+	if (err)
+		return err;
+
+	sparx5_tc_flower_set_port_mask(&ports, act->dev);
+
+	err = vcap_rule_add_action_u72(vrule, VCAP_AF_PORT_MASK, &ports);
+	if (err)
+		return err;
+
+	return 0;
+}
+
 /* Remove rule keys that may prevent templates from matching a keyset */
 static void sparx5_tc_flower_simplify_rule(struct vcap_admin *admin,
 					   struct vcap_rule *vrule,
@@ -1150,6 +1188,11 @@ static int sparx5_tc_flower_replace(struct net_device *ndev,
 			if (err)
 				goto out;
 			break;
+		case FLOW_ACTION_MIRRED:
+			err = sparx5_tc_action_mirred(admin, vrule, fco, act);
+			if (err)
+				goto out;
+			break;
 		case FLOW_ACTION_ACCEPT:
 			err = sparx5_tc_set_actionset(admin, vrule);
 			if (err)

-- 
2.34.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related

* Re: [PATCH 2/7] arm64: mm: accelerate pagefault when VM_FAULT_BADACCESS
From: Catalin Marinas @ 2024-04-03 18:32 UTC (permalink / raw)
  To: Kefeng Wang
  Cc: akpm, Russell King, Will Deacon, Michael Ellerman,
	Nicholas Piggin, Christophe Leroy, Paul Walmsley, Palmer Dabbelt,
	Albert Ou, Alexander Gordeev, Gerald Schaefer, Dave Hansen,
	Andy Lutomirski, Peter Zijlstra, x86, linux-arm-kernel,
	linuxppc-dev, linux-riscv, linux-s390, surenb
In-Reply-To: <20240402075142.196265-3-wangkefeng.wang@huawei.com>

On Tue, Apr 02, 2024 at 03:51:37PM +0800, Kefeng Wang wrote:
> The vm_flags of vma already checked under per-VMA lock, if it is a
> bad access, directly set fault to VM_FAULT_BADACCESS and handle error,
> no need to lock_mm_and_find_vma() and check vm_flags again, the latency
> time reduce 34% in lmbench 'lat_sig -P 1 prot lat_sig'.
> 
> Signed-off-by: Kefeng Wang <wangkefeng.wang@huawei.com>
> ---
>  arch/arm64/mm/fault.c | 4 +++-
>  1 file changed, 3 insertions(+), 1 deletion(-)
> 
> diff --git a/arch/arm64/mm/fault.c b/arch/arm64/mm/fault.c
> index 9bb9f395351a..405f9aa831bd 100644
> --- a/arch/arm64/mm/fault.c
> +++ b/arch/arm64/mm/fault.c
> @@ -572,7 +572,9 @@ static int __kprobes do_page_fault(unsigned long far, unsigned long esr,
>  
>  	if (!(vma->vm_flags & vm_flags)) {
>  		vma_end_read(vma);
> -		goto lock_mmap;
> +		fault = VM_FAULT_BADACCESS;
> +		count_vm_vma_lock_event(VMA_LOCK_SUCCESS);
> +		goto done;
>  	}
>  	fault = handle_mm_fault(vma, addr, mm_flags | FAULT_FLAG_VMA_LOCK, regs);
>  	if (!(fault & (VM_FAULT_RETRY | VM_FAULT_COMPLETED)))

I think this makes sense. A concurrent modification of vma->vm_flags
(e.g. mprotect()) would do a vma_start_write(), so no need to recheck
again with the mmap lock held.

Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply

* [PATCH v2 2/2] PM / devfreq: exynos: Switch from CONFIG_PM_SLEEP guards to pm_sleep_ptr()
From: Anand Moon @ 2024-04-03 18:15 UTC (permalink / raw)
  To: Chanwoo Choi, MyungJoo Ham, Kyungmin Park, Krzysztof Kozlowski,
	Alim Akhtar
  Cc: Anand Moon, linux-pm, linux-samsung-soc, linux-arm-kernel,
	linux-kernel
In-Reply-To: <20240403181517.5993-1-linux.amoon@gmail.com>

Use the new PM macros for the suspend and resume functions to be
automatically dropped by the compiler when CONFIG_PM_SLEEP are disabled,
without having to use #ifdef guards. If CONFIG_PM_SLEEP unused,
they will simply be discarded by the compiler.

Signed-off-by: Anand Moon <linux.amoon@gmail.com>
---
added __maybe_unused to suspend/resume functions

[0] https://lore.kernel.org/all/20240226183308.4730-1-linux.amoon@gmail.com/
---
 drivers/devfreq/exynos-bus.c | 8 +++-----
 1 file changed, 3 insertions(+), 5 deletions(-)

diff --git a/drivers/devfreq/exynos-bus.c b/drivers/devfreq/exynos-bus.c
index 153340b6685f..09822f8fa209 100644
--- a/drivers/devfreq/exynos-bus.c
+++ b/drivers/devfreq/exynos-bus.c
@@ -454,8 +454,7 @@ static void exynos_bus_shutdown(struct platform_device *pdev)
 	devfreq_suspend_device(bus->devfreq);
 }
 
-#ifdef CONFIG_PM_SLEEP
-static int exynos_bus_resume(struct device *dev)
+static int __maybe_unused exynos_bus_resume(struct device *dev)
 {
 	struct exynos_bus *bus = dev_get_drvdata(dev);
 	int ret;
@@ -469,7 +468,7 @@ static int exynos_bus_resume(struct device *dev)
 	return 0;
 }
 
-static int exynos_bus_suspend(struct device *dev)
+static int __maybe_unused exynos_bus_suspend(struct device *dev)
 {
 	struct exynos_bus *bus = dev_get_drvdata(dev);
 	int ret;
@@ -482,7 +481,6 @@ static int exynos_bus_suspend(struct device *dev)
 
 	return 0;
 }
-#endif
 
 static const struct dev_pm_ops exynos_bus_pm = {
 	SET_SYSTEM_SLEEP_PM_OPS(exynos_bus_suspend, exynos_bus_resume)
@@ -499,7 +497,7 @@ static struct platform_driver exynos_bus_platdrv = {
 	.shutdown	= exynos_bus_shutdown,
 	.driver = {
 		.name	= "exynos-bus",
-		.pm	= &exynos_bus_pm,
+		.pm	= pm_sleep_ptr(&exynos_bus_pm),
 		.of_match_table = exynos_bus_of_match,
 	},
 };
-- 
2.44.0


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related

* [PATCH v2 1/2] PM / devfreq: exynos: Use Use devm_clk_get_enabled() helpers
From: Anand Moon @ 2024-04-03 18:15 UTC (permalink / raw)
  To: Chanwoo Choi, MyungJoo Ham, Kyungmin Park, Krzysztof Kozlowski,
	Alim Akhtar
  Cc: Anand Moon, linux-pm, linux-samsung-soc, linux-arm-kernel,
	linux-kernel

The devm_clk_get_enabled() helpers:
    - call devm_clk_get()
    - call clk_prepare_enable() and register what is needed in order to
     call clk_disable_unprepare() when needed, as a managed resource.

This simplifies the code and avoids the calls to clk_disable_unprepare().

While at it, use dev_err_probe consistently, and use its return value
to return the error code.

Signed-off-by: Anand Moon <linux.amoon@gmail.com>
---
v2: no changes
---
 drivers/devfreq/exynos-bus.c | 21 ++++-----------------
 1 file changed, 4 insertions(+), 17 deletions(-)

diff --git a/drivers/devfreq/exynos-bus.c b/drivers/devfreq/exynos-bus.c
index 245898f1a88e..153340b6685f 100644
--- a/drivers/devfreq/exynos-bus.c
+++ b/drivers/devfreq/exynos-bus.c
@@ -160,7 +160,6 @@ static void exynos_bus_exit(struct device *dev)
 	platform_device_unregister(bus->icc_pdev);
 
 	dev_pm_opp_of_remove_table(dev);
-	clk_disable_unprepare(bus->clk);
 	dev_pm_opp_put_regulators(bus->opp_token);
 }
 
@@ -171,7 +170,6 @@ static void exynos_bus_passive_exit(struct device *dev)
 	platform_device_unregister(bus->icc_pdev);
 
 	dev_pm_opp_of_remove_table(dev);
-	clk_disable_unprepare(bus->clk);
 }
 
 static int exynos_bus_parent_parse_of(struct device_node *np,
@@ -247,23 +245,15 @@ static int exynos_bus_parse_of(struct device_node *np,
 	int ret;
 
 	/* Get the clock to provide each bus with source clock */
-	bus->clk = devm_clk_get(dev, "bus");
-	if (IS_ERR(bus->clk)) {
-		dev_err(dev, "failed to get bus clock\n");
-		return PTR_ERR(bus->clk);
-	}
-
-	ret = clk_prepare_enable(bus->clk);
-	if (ret < 0) {
-		dev_err(dev, "failed to get enable clock\n");
-		return ret;
-	}
+	bus->clk = devm_clk_get_enabled(dev, "bus");
+	if (IS_ERR(bus->clk))
+		return dev_err_probe(dev, PTR_ERR(bus->clk), "failed to get bus clock\n");
 
 	/* Get the freq and voltage from OPP table to scale the bus freq */
 	ret = dev_pm_opp_of_add_table(dev);
 	if (ret < 0) {
 		dev_err(dev, "failed to get OPP table\n");
-		goto err_clk;
+		return ret;
 	}
 
 	rate = clk_get_rate(bus->clk);
@@ -281,8 +271,6 @@ static int exynos_bus_parse_of(struct device_node *np,
 
 err_opp:
 	dev_pm_opp_of_remove_table(dev);
-err_clk:
-	clk_disable_unprepare(bus->clk);
 
 	return ret;
 }
@@ -453,7 +441,6 @@ static int exynos_bus_probe(struct platform_device *pdev)
 
 err:
 	dev_pm_opp_of_remove_table(dev);
-	clk_disable_unprepare(bus->clk);
 err_reg:
 	dev_pm_opp_put_regulators(bus->opp_token);
 
-- 
2.44.0


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related

* Re: [PATCH v4 05/13] mm/arch: Provide pud_pfn() fallback
From: Peter Xu @ 2024-04-03 18:25 UTC (permalink / raw)
  To: Jason Gunthorpe
  Cc: Nathan Chancellor, linux-mm, linux-kernel, Yang Shi,
	Kirill A . Shutemov, Mike Kravetz, John Hubbard, Michael Ellerman,
	Andrew Jones, Muchun Song, linux-riscv, linuxppc-dev,
	Christophe Leroy, Andrew Morton, Christoph Hellwig,
	Lorenzo Stoakes, Matthew Wilcox, Rik van Riel, linux-arm-kernel,
	Andrea Arcangeli, David Hildenbrand, Aneesh Kumar K . V,
	Vlastimil Babka, James Houghton, Mike Rapoport, Axel Rasmussen,
	Huacai Chen, WANG Xuerui, loongarch
In-Reply-To: <20240403120841.GB1723999@nvidia.com>

On Wed, Apr 03, 2024 at 09:08:41AM -0300, Jason Gunthorpe wrote:
> On Tue, Apr 02, 2024 at 07:35:45PM -0400, Peter Xu wrote:
> > On Tue, Apr 02, 2024 at 07:53:20PM -0300, Jason Gunthorpe wrote:
> > > On Tue, Apr 02, 2024 at 06:43:56PM -0400, Peter Xu wrote:
> > > 
> > > > I actually tested this without hitting the issue (even though I didn't
> > > > mention it in the cover letter..).  I re-kicked the build test, it turns
> > > > out my "make alldefconfig" on loongarch will generate a config with both
> > > > HUGETLB=n && THP=n, while arch/loongarch/configs/loongson3_defconfig has
> > > > THP=y (which I assume was the one above build used).  I didn't further
> > > > check how "make alldefconfig" generated the config; a bit surprising that
> > > > it didn't fetch from there.
> > > 
> > > I suspect it is weird compiler variations.. Maybe something is not
> > > being inlined.
> > > 
> > > > (and it also surprises me that this BUILD_BUG can trigger.. I used to try
> > > >  triggering it elsewhere but failed..)
> > > 
> > > As the pud_leaf() == FALSE should result in the BUILD_BUG never being
> > > called and the optimizer removing it.
> > 
> > Good point, for some reason loongarch defined pud_leaf() without defining
> > pud_pfn(), which does look strange.
> > 
> > #define pud_leaf(pud)		((pud_val(pud) & _PAGE_HUGE) != 0)
> > 
> > But I noticed at least MIPS also does it..  Logically I think one arch
> > should define either none of both.
> 
> Wow, this is definately an arch issue. You can't define pud_leaf() and
> not have a pud_pfn(). It makes no sense at all..
> 
> I'd say the BUILD_BUG has done it's job and found an issue, fix it by
> not defining pud_leaf? I don't see any calls to pud_leaf in loongarch
> at least

Yes, that sounds better too to me, however it means we may also risk other
archs that can fail another defconfig build.. and I worry I bring trouble
to multiple such cases.  Fundamentally it's indeed my patch that broke
those builds, so I still sent the change and leave that for arch developers
to decide the best for the archs.

I think if wanted, we can add that BUILD_BUG() back when we're sure no arch
will break with it.  So such changes from arch can still be proposed
alongside of removal of BUILD_BUG() (and I'd guess some other arch will
start to notice such build issue soon if existed.. so it still more or less
has similar effect of a reminder..).

Thanks,

-- 
Peter Xu


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply

* Re: [PATCH 1/7] arm64: mm: cleanup __do_page_fault()
From: Catalin Marinas @ 2024-04-03 18:24 UTC (permalink / raw)
  To: Kefeng Wang
  Cc: akpm, Russell King, Will Deacon, Michael Ellerman,
	Nicholas Piggin, Christophe Leroy, Paul Walmsley, Palmer Dabbelt,
	Albert Ou, Alexander Gordeev, Gerald Schaefer, Dave Hansen,
	Andy Lutomirski, Peter Zijlstra, x86, linux-arm-kernel,
	linuxppc-dev, linux-riscv, linux-s390, surenb
In-Reply-To: <20240402075142.196265-2-wangkefeng.wang@huawei.com>

On Tue, Apr 02, 2024 at 03:51:36PM +0800, Kefeng Wang wrote:
> The __do_page_fault() only check vma->flags and call handle_mm_fault(),
> and only called by do_page_fault(), let's squash it into do_page_fault()
> to cleanup code.
> 
> Signed-off-by: Kefeng Wang <wangkefeng.wang@huawei.com>

Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply

* Re: [PATCH v2 1/2] dt-bindings: mailbox: arm,mhuv3: Add bindings
From: Rob Herring @ 2024-04-03 18:24 UTC (permalink / raw)
  To: Cristian Marussi
  Cc: sudeep.holla, conor+dt, linux-arm-kernel, linux-kernel,
	jassisinghbrar, robh+dt, krzysztof.kozlowski+dt, devicetree
In-Reply-To: <20240403171346.3173843-2-cristian.marussi@arm.com>


On Wed, 03 Apr 2024 18:13:45 +0100, Cristian Marussi wrote:
> Add bindings for the ARM MHUv3 Mailbox controller.
> 
> Signed-off-by: Cristian Marussi <cristian.marussi@arm.com>
> ---
> v1 -> v2
> - clarified extension descriptions around configurability and discoverability
> - removed unused labels from the example
> - using pattern properties to define interrupt-names
> - bumped interrupt maxItems to 74 (allowing uo to 8 channels per extension)
> ---
>  .../bindings/mailbox/arm,mhuv3.yaml           | 217 ++++++++++++++++++
>  1 file changed, 217 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/mailbox/arm,mhuv3.yaml
> 

My bot found errors running 'make DT_CHECKER_FLAGS=-m dt_binding_check'
on your patch (DT_CHECKER_FLAGS is new in v5.13):

yamllint warnings/errors:
./Documentation/devicetree/bindings/mailbox/arm,mhuv3.yaml:86:1: [error] syntax error: found character '\t' that cannot start any token (syntax)

dtschema/dtc warnings/errors:
make[2]: *** Deleting file 'Documentation/devicetree/bindings/mailbox/arm,mhuv3.example.dts'
Documentation/devicetree/bindings/mailbox/arm,mhuv3.yaml:86:1: found a tab character where an indentation space is expected
make[2]: *** [Documentation/devicetree/bindings/Makefile:26: Documentation/devicetree/bindings/mailbox/arm,mhuv3.example.dts] Error 1
make[2]: *** Waiting for unfinished jobs....
./Documentation/devicetree/bindings/mailbox/arm,mhuv3.yaml:86:1: found a tab character where an indentation space is expected
/builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/mailbox/arm,mhuv3.yaml: ignoring, error parsing file
make[1]: *** [/builds/robherring/dt-review-ci/linux/Makefile:1430: dt_binding_check] Error 2
make: *** [Makefile:240: __sub-make] Error 2

doc reference errors (make refcheckdocs):

See https://patchwork.ozlabs.org/project/devicetree-bindings/patch/20240403171346.3173843-2-cristian.marussi@arm.com

The base for the series is generally the latest rc1. A different dependency
should be noted in *this* patch.

If you already ran 'make dt_binding_check' and didn't see the above
error(s), then make sure 'yamllint' is installed and dt-schema is up to
date:

pip3 install dtschema --upgrade

Please check and re-submit after running the above command yourself. Note
that DT_SCHEMA_FILES can be set to your schema file to speed up checking
your schema. However, it must be unset to test all examples with your schema.


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply

* Re: [PATCH v14 01/18] irqchip/sifive-plic: Convert PLIC driver into a platform driver
From: Lad, Prabhakar @ 2024-04-03 18:10 UTC (permalink / raw)
  To: Samuel Holland, Anup Patel
  Cc: Anup Patel, devicetree, Conor Dooley, Geert Uytterhoeven,
	Marc Zyngier, Atish Patra, linux-kernel, Saravana Kannan,
	Björn Töpel, Rob Herring, Palmer Dabbelt,
	Krzysztof Kozlowski, Paul Walmsley, Thomas Gleixner, Frank Rowand,
	linux-riscv, linux-arm-kernel, Andrew Jones
In-Reply-To: <4dbd5daf-d100-4ae2-8bda-c657e23a809e@sifive.com>

Hi Samuel and Anup,

On Wed, Apr 3, 2024 at 5:28 PM Samuel Holland <samuel.holland@sifive.com> wrote:
>
> Hi Prabhakar,
>
> On 2024-04-03 10:49 AM, Lad, Prabhakar wrote:
> > On Wed, Apr 3, 2024 at 3:17 PM Anup Patel <apatel@ventanamicro.com> wrote:
> >>
> >> On Wed, Apr 3, 2024 at 2:01 PM Lad, Prabhakar
> >> <prabhakar.csengg@gmail.com> wrote:
> >>>
> >>> Hi Anup,
> >>>
> >>> On Thu, Feb 22, 2024 at 9:41 AM Anup Patel <apatel@ventanamicro.com> wrote:
> >>>>
> >>>> The PLIC driver does not require very early initialization so convert
> >>>> it into a platform driver.
> >>>>
> >>>> After conversion, the PLIC driver is probed after CPUs are brought-up
> >>>> so setup cpuhp state after context handler of all online CPUs are
> >>>> initialized otherwise PLIC driver crashes for platforms with multiple
> >>>> PLIC instances.
> >>>>
> >>>> Signed-off-by: Anup Patel <apatel@ventanamicro.com>
> >>>> ---
> >>>>  drivers/irqchip/irq-sifive-plic.c | 101 ++++++++++++++++++------------
> >>>>  1 file changed, 61 insertions(+), 40 deletions(-)
> >>>>
> >>> This patch seems to have broken things on RZ/Five SoC, after reverting
> >>> this patch I get to boot it back again on v6.9-rc2. Looks like there
> >>> is some probe order issue after switching to platform driver?
> >>
> >> Yes, this is most likely related to probe ordering based on your DT.
> >>
> >> Can you share the failing boot log and DT ?
> >
> > non working case, https://paste.debian.net/1312947/
>
> Looks like you need to add "keep_bootcon" to your kernel command line to get a
> full log here.
>
Thanks for the pointer, that helped me to get to the root cause.

> > after reverting, https://paste.debian.net/1312948/
> > (attached is the DTB)
>
> I don't see anything suspicious between the "riscv-intc" lines and the "Fixed
> dependency cycle(s)" lines that looks like it would depend on the PLIC IRQ
> domain. Maybe there is some driver that does not handle -EPROBE_DEFER? It's hard
> to tell without the full log from the failure case.
>
The clock required for the PLIC wasnt available during the probe of
this driver. This bug got hidden when the PLIC driver was probed
earlier  in boot where it used an incorrect clock source. Ive created
a patch which adds a missing clock for the PLIC.

Sorry for the noise!

Cheers,
Prabhakar

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply

* Re: [PATCH v2 1/4] arm64: patching: always use fixmap
From: Catalin Marinas @ 2024-04-03 17:52 UTC (permalink / raw)
  To: Mark Rutland
  Cc: linux-kernel, Will Deacon, anil.s.keshavamurthy, aou, davem,
	jarkko, linux-arm-kernel, mhiramat, naveen.n.rao, palmer,
	paul.walmsley
In-Reply-To: <20240403150154.667649-2-mark.rutland@arm.com>

On Wed, Apr 03, 2024 at 04:01:51PM +0100, Mark Rutland wrote:
> For historical reasons, patch_map() won't bother to fixmap non-image
> addresses when CONFIG_STRICT_MODULE_RWX=n, matching the behaviour prior
> to the introduction of CONFIG_STRICT_MODULE_RWX. However, as arm64
> doesn't select CONFIG_ARCH_OPTIONAL_KERNEL_RWX, CONFIG_MODULES implies
> CONFIG_STRICT_MODULE_RWX, so any kernel built with module support will
> use the fixmap for any non-image address.
> 
> Historically we only used patch_map() for the kernel image and modules,
> but these days its also used by BPF and KPROBES to write to read-only
> pages of executable text. Currently these both depend on CONFIG_MODULES,
> but we'd like to change that in subsequent patches, which will require
> using the fixmap regardless of CONFIG_STRICT_MODULE_RWX.
> 
> This patch changes patch_map() to always use the fixmap, and simplifies
> the logic:
> 
> * Use is_image_text() directly in the if-else, rather than using a
>   temporary boolean variable.
> 
> * Use offset_in_page() to get the offset within the mapping.
> 
> * Remove uintaddr and cast the address directly when using
>   is_image_text().
> 
> For kernels built with CONFIG_MODULES=y, there should be no functional
> change as a result of this patch.
> 
> For kernels built with CONFIG_MODULES=n, patch_map() will use the fixmap
> for non-image addresses, but there are no extant users with non-image
> addresses when CONFIG_MODULES=n, and hence there should be no functional
> change as a result of this patch alone.
> 
> Signed-off-by: Mark Rutland <mark.rutland@arm.com>
> Cc: Catalin Marinas <catalin.marinas@arm.com>
> Cc: Will Deacon <will@kernel.org>
> ---
>  arch/arm64/kernel/patching.c | 10 +++-------
>  1 file changed, 3 insertions(+), 7 deletions(-)
> 
> Catalin, Will, this is a prerequisite for the final two patches in the
> series. Are you happy for this go via the tracing tree?

Fine by me.

Acked-by: Catalin Marinas <catalin.marinas@arm.com>

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply

* Re: [PATCH v3 22/25] dt-bindings: media: imx258: Add binding for powerdown-gpio
From: Krzysztof Kozlowski @ 2024-04-03 17:38 UTC (permalink / raw)
  To: git, linux-media
  Cc: dave.stevenson, jacopo.mondi, mchehab, robh,
	krzysztof.kozlowski+dt, conor+dt, shawnguo, s.hauer, kernel,
	festevam, sakari.ailus, devicetree, imx, linux-arm-kernel,
	linux-kernel, pavel, phone-devel, Ondrej Jirman
In-Reply-To: <20240403150355.189229-23-git@luigi311.com>

On 03/04/2024 17:03, git@luigi311.com wrote:
> From: Luis Garcia <git@luigi311.com>
> 
> Add powerdown-gpio binding as it is required for some boards
> 
> Signed-off-by: Ondrej Jirman <megi@xff.cz>
> Signed-off-by: Luis Garcia <git@luigi311.com>
> ---

Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>

Best regards,
Krzysztof


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply

* Re: [PATCH v14 01/18] irqchip/sifive-plic: Convert PLIC driver into a platform driver
From: Anup Patel @ 2024-04-03 17:19 UTC (permalink / raw)
  To: Lad, Prabhakar
  Cc: Anup Patel, Geert Uytterhoeven, Palmer Dabbelt, Paul Walmsley,
	Thomas Gleixner, Rob Herring, Krzysztof Kozlowski, Frank Rowand,
	Conor Dooley, Marc Zyngier, Björn Töpel, Atish Patra,
	Andrew Jones, Sunil V L, Saravana Kannan, linux-riscv,
	linux-arm-kernel, linux-kernel, devicetree
In-Reply-To: <CA+V-a8ser=hDmst6+XSeOWaEoOd+iY3Ys6bYBWDa5UYPfT+Pug@mail.gmail.com>

On Wed, Apr 3, 2024 at 9:19 PM Lad, Prabhakar
<prabhakar.csengg@gmail.com> wrote:
>
> On Wed, Apr 3, 2024 at 3:17 PM Anup Patel <apatel@ventanamicro.com> wrote:
> >
> > On Wed, Apr 3, 2024 at 2:01 PM Lad, Prabhakar
> > <prabhakar.csengg@gmail.com> wrote:
> > >
> > > Hi Anup,
> > >
> > > On Thu, Feb 22, 2024 at 9:41 AM Anup Patel <apatel@ventanamicro.com> wrote:
> > > >
> > > > The PLIC driver does not require very early initialization so convert
> > > > it into a platform driver.
> > > >
> > > > After conversion, the PLIC driver is probed after CPUs are brought-up
> > > > so setup cpuhp state after context handler of all online CPUs are
> > > > initialized otherwise PLIC driver crashes for platforms with multiple
> > > > PLIC instances.
> > > >
> > > > Signed-off-by: Anup Patel <apatel@ventanamicro.com>
> > > > ---
> > > >  drivers/irqchip/irq-sifive-plic.c | 101 ++++++++++++++++++------------
> > > >  1 file changed, 61 insertions(+), 40 deletions(-)
> > > >
> > > This patch seems to have broken things on RZ/Five SoC, after reverting
> > > this patch I get to boot it back again on v6.9-rc2. Looks like there
> > > is some probe order issue after switching to platform driver?
> >
> > Yes, this is most likely related to probe ordering based on your DT.
> >
> > Can you share the failing boot log and DT ?
>
> non working case, https://paste.debian.net/1312947/
> after reverting, https://paste.debian.net/1312948/
> (attached is the DTB)

One potential problem is that
drivers/clocksource/renesas-ostm.c is probed early
using TIMER_OF_DECLARE() but the timer interrupt
is connected to PLIC which is probed late hence the
timer probe will fail.

We have two possible options:
1) Disable OSTM nodes
2) Improve the OSTM driver to probe like a
    regular platform device on RISC-V

Regards,
Anup

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply

* [PATCH v1 0/5] spi: pxa2xx: Cleanup (part 2)
From: Andy Shevchenko @ 2024-04-03 17:06 UTC (permalink / raw)
  To: Andy Shevchenko, linux-arm-kernel, linux-spi, linux-kernel
  Cc: Daniel Mack, Haojian Zhuang, Robert Jarzmik, Mark Brown


Here is the additional cleanup of the driver based on the fact of
the linux/spi/pxa2xx_spi.h being a local (to drivers/spi/) header.
This means it's based on top of "spi: pxa2xx: Drop linux/spi/pxa2xx_spi.h"
(20240327193138.2385910-1-andriy.shevchenko@linux.intel.com).

Andy Shevchenko (5):
  spi: pxa2xx: Move number of CS pins validation out of condition
  spi: pxa2xx: Drop struct pxa2xx_spi_chip
  spi: pxa2xx: Remove DMA parameters from struct chip_data
  spi: pxa2xx: Remove timeout field from struct chip_data
  spi: pxa2xx: Don't provide struct chip_data for others

 drivers/spi/spi-pxa2xx-dma.c | 27 +----------
 drivers/spi/spi-pxa2xx.c     | 92 +++++++++---------------------------
 drivers/spi/spi-pxa2xx.h     | 31 ------------
 3 files changed, 25 insertions(+), 125 deletions(-)

-- 
2.43.0.rc1.1.gbec44491f096


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply

* [PATCH v1 3/5] spi: pxa2xx: Remove DMA parameters from struct chip_data
From: Andy Shevchenko @ 2024-04-03 17:06 UTC (permalink / raw)
  To: Andy Shevchenko, linux-arm-kernel, linux-spi, linux-kernel
  Cc: Daniel Mack, Haojian Zhuang, Robert Jarzmik, Mark Brown
In-Reply-To: <20240403171550.1074644-1-andriy.shevchenko@linux.intel.com>

The DMA related fields are set once and never modified. It effectively
repeats the content of the same fields in struct pxa2xx_spi_controller.
With that, remove DMA parameters from struct chip_data.

Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
---
 drivers/spi/spi-pxa2xx-dma.c | 22 ++------------------
 drivers/spi/spi-pxa2xx.c     | 40 +++++++-----------------------------
 drivers/spi/spi-pxa2xx.h     |  8 --------
 3 files changed, 9 insertions(+), 61 deletions(-)

diff --git a/drivers/spi/spi-pxa2xx-dma.c b/drivers/spi/spi-pxa2xx-dma.c
index d77279c3acd8..08cb6e96ac94 100644
--- a/drivers/spi/spi-pxa2xx-dma.c
+++ b/drivers/spi/spi-pxa2xx-dma.c
@@ -68,8 +68,6 @@ pxa2xx_spi_dma_prepare_one(struct driver_data *drv_data,
 			   enum dma_transfer_direction dir,
 			   struct spi_transfer *xfer)
 {
-	struct chip_data *chip =
-		spi_get_ctldata(drv_data->controller->cur_msg->spi);
 	enum dma_slave_buswidth width;
 	struct dma_slave_config cfg;
 	struct dma_chan *chan;
@@ -94,14 +92,14 @@ pxa2xx_spi_dma_prepare_one(struct driver_data *drv_data,
 	if (dir == DMA_MEM_TO_DEV) {
 		cfg.dst_addr = drv_data->ssp->phys_base + SSDR;
 		cfg.dst_addr_width = width;
-		cfg.dst_maxburst = chip->dma_burst_size;
+		cfg.dst_maxburst = drv_data->controller_info->dma_burst_size;
 
 		sgt = &xfer->tx_sg;
 		chan = drv_data->controller->dma_tx;
 	} else {
 		cfg.src_addr = drv_data->ssp->phys_base + SSDR;
 		cfg.src_addr_width = width;
-		cfg.src_maxburst = chip->dma_burst_size;
+		cfg.src_maxburst = drv_data->controller_info->dma_burst_size;
 
 		sgt = &xfer->rx_sg;
 		chan = drv_data->controller->dma_rx;
@@ -225,19 +223,3 @@ void pxa2xx_spi_dma_release(struct driver_data *drv_data)
 		controller->dma_tx = NULL;
 	}
 }
-
-int pxa2xx_spi_set_dma_burst_and_threshold(struct chip_data *chip,
-					   struct spi_device *spi,
-					   u8 bits_per_word, u32 *burst_code,
-					   u32 *threshold)
-{
-	struct driver_data *drv_data = spi_controller_get_devdata(spi->controller);
-	u32 dma_burst_size = drv_data->controller_info->dma_burst_size;
-
-	/* We use the default the DMA burst size and FIFO thresholds for now */
-	*burst_code = dma_burst_size;
-	*threshold = SSCR1_RxTresh(RX_THRESH_DFLT)
-		   | SSCR1_TxTresh(TX_THRESH_DFLT);
-
-	return 0;
-}
diff --git a/drivers/spi/spi-pxa2xx.c b/drivers/spi/spi-pxa2xx.c
index 00aa33c937bf..3ba0f5816f7f 100644
--- a/drivers/spi/spi-pxa2xx.c
+++ b/drivers/spi/spi-pxa2xx.c
@@ -934,11 +934,11 @@ static bool pxa2xx_spi_can_dma(struct spi_controller *controller,
 			       struct spi_device *spi,
 			       struct spi_transfer *xfer)
 {
-	struct chip_data *chip = spi_get_ctldata(spi);
+	struct driver_data *drv_data = spi_controller_get_devdata(controller);
 
-	return chip->enable_dma &&
+	return drv_data->controller_info->enable_dma &&
 	       xfer->len <= MAX_DMA_LEN &&
-	       xfer->len >= chip->dma_burst_size;
+	       xfer->len >= drv_data->controller_info->dma_burst_size;
 }
 
 static int pxa2xx_spi_transfer_one(struct spi_controller *controller,
@@ -947,9 +947,8 @@ static int pxa2xx_spi_transfer_one(struct spi_controller *controller,
 {
 	struct driver_data *drv_data = spi_controller_get_devdata(controller);
 	struct chip_data *chip = spi_get_ctldata(spi);
-	u32 dma_thresh = chip->dma_threshold;
-	u32 dma_burst = chip->dma_burst_size;
 	u32 change_mask = pxa2xx_spi_get_ssrc1_change_mask(drv_data);
+	u32 dma_thresh;
 	u32 clk_div;
 	u8 bits;
 	u32 speed;
@@ -959,7 +958,7 @@ static int pxa2xx_spi_transfer_one(struct spi_controller *controller,
 	int dma_mapped;
 
 	/* Check if we can DMA this transfer */
-	if (transfer->len > MAX_DMA_LEN && chip->enable_dma) {
+	if (transfer->len > MAX_DMA_LEN && drv_data->controller_info->enable_dma) {
 		/* Warn ... we force this to PIO mode */
 		dev_warn_ratelimited(&spi->dev,
 				     "DMA disabled for transfer length %u greater than %d\n",
@@ -995,19 +994,8 @@ static int pxa2xx_spi_transfer_one(struct spi_controller *controller,
 		drv_data->read = drv_data->rx ? u32_reader : null_reader;
 		drv_data->write = drv_data->tx ? u32_writer : null_writer;
 	}
-	/*
-	 * If bits per word is changed in DMA mode, then must check
-	 * the thresholds and burst also.
-	 */
-	if (chip->enable_dma) {
-		if (pxa2xx_spi_set_dma_burst_and_threshold(chip,
-						spi,
-						bits, &dma_burst,
-						&dma_thresh))
-			dev_warn_ratelimited(&spi->dev,
-					     "DMA burst size reduced to match bits_per_word\n");
-	}
 
+	dma_thresh = SSCR1_RxTresh(RX_THRESH_DFLT) | SSCR1_TxTresh(TX_THRESH_DFLT);
 	dma_mapped = controller->can_dma &&
 		     controller->can_dma(controller, spi, transfer) &&
 		     controller->cur_msg_mapped;
@@ -1213,7 +1201,6 @@ static int setup(struct spi_device *spi)
 		if (!chip)
 			return -ENOMEM;
 
-		chip->enable_dma = drv_data->controller_info->enable_dma;
 		chip->timeout = TIMOUT_DFLT;
 	}
 
@@ -1236,20 +1223,6 @@ static int setup(struct spi_device *spi)
 		chip->lpss_tx_threshold = tx_thres;
 	}
 
-	if (chip->enable_dma) {
-		/* Set up legal burst and threshold for DMA */
-		if (pxa2xx_spi_set_dma_burst_and_threshold(chip, spi,
-						spi->bits_per_word,
-						&chip->dma_burst_size,
-						&chip->dma_threshold)) {
-			dev_warn(&spi->dev,
-				 "in setup: DMA burst size reduced to match bits_per_word\n");
-		}
-		dev_dbg(&spi->dev,
-			"in setup: DMA burst size set to %u\n",
-			chip->dma_burst_size);
-	}
-
 	switch (drv_data->ssp_type) {
 	case QUARK_X1000_SSP:
 		chip->threshold = (QUARK_X1000_SSCR1_RxTresh(rx_thres)
@@ -1439,6 +1412,7 @@ static int pxa2xx_spi_probe(struct platform_device *pdev)
 		if (IS_ERR(platform_info))
 			return dev_err_probe(dev, PTR_ERR(platform_info), "missing platform data\n");
 	}
+	dev_dbg(dev, "DMA burst size set to %u\n", platform_info->dma_burst_size);
 
 	ssp = pxa_ssp_request(pdev->id, pdev->name);
 	if (!ssp)
diff --git a/drivers/spi/spi-pxa2xx.h b/drivers/spi/spi-pxa2xx.h
index ae9c99bc9f6c..10294ef209d9 100644
--- a/drivers/spi/spi-pxa2xx.h
+++ b/drivers/spi/spi-pxa2xx.h
@@ -79,9 +79,6 @@ struct chip_data {
 	u32 cr1;
 	u32 dds_rate;
 	u32 timeout;
-	u8 enable_dma;
-	u32 dma_burst_size;
-	u32 dma_threshold;
 	u32 threshold;
 	u16 lpss_rx_threshold;
 	u16 lpss_tx_threshold;
@@ -142,10 +139,5 @@ extern void pxa2xx_spi_dma_start(struct driver_data *drv_data);
 extern void pxa2xx_spi_dma_stop(struct driver_data *drv_data);
 extern int pxa2xx_spi_dma_setup(struct driver_data *drv_data);
 extern void pxa2xx_spi_dma_release(struct driver_data *drv_data);
-extern int pxa2xx_spi_set_dma_burst_and_threshold(struct chip_data *chip,
-						  struct spi_device *spi,
-						  u8 bits_per_word,
-						  u32 *burst_code,
-						  u32 *threshold);
 
 #endif /* SPI_PXA2XX_H */
-- 
2.43.0.rc1.1.gbec44491f096


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related

* [PATCH v1 4/5] spi: pxa2xx: Remove timeout field from struct chip_data
From: Andy Shevchenko @ 2024-04-03 17:06 UTC (permalink / raw)
  To: Andy Shevchenko, linux-arm-kernel, linux-spi, linux-kernel
  Cc: Daniel Mack, Haojian Zhuang, Robert Jarzmik, Mark Brown
In-Reply-To: <20240403171550.1074644-1-andriy.shevchenko@linux.intel.com>

The timeout field is used only once and assigned to a predefined
constant. Replace all that by using the constant directly.

Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
---
 drivers/spi/spi-pxa2xx.c | 4 +---
 drivers/spi/spi-pxa2xx.h | 1 -
 2 files changed, 1 insertion(+), 4 deletions(-)

diff --git a/drivers/spi/spi-pxa2xx.c b/drivers/spi/spi-pxa2xx.c
index 3ba0f5816f7f..030afb17e606 100644
--- a/drivers/spi/spi-pxa2xx.c
+++ b/drivers/spi/spi-pxa2xx.c
@@ -1058,7 +1058,7 @@ static int pxa2xx_spi_transfer_one(struct spi_controller *controller,
 		pxa_ssp_disable(drv_data->ssp);
 
 	if (!pxa25x_ssp_comp(drv_data))
-		pxa2xx_spi_write(drv_data, SSTO, chip->timeout);
+		pxa2xx_spi_write(drv_data, SSTO, TIMOUT_DFLT);
 
 	/* First set CR1 without interrupt and service enables */
 	pxa2xx_spi_update(drv_data, SSCR1, change_mask, cr1);
@@ -1200,8 +1200,6 @@ static int setup(struct spi_device *spi)
 		chip = kzalloc(sizeof(struct chip_data), GFP_KERNEL);
 		if (!chip)
 			return -ENOMEM;
-
-		chip->timeout = TIMOUT_DFLT;
 	}
 
 	chip->cr1 = 0;
diff --git a/drivers/spi/spi-pxa2xx.h b/drivers/spi/spi-pxa2xx.h
index 10294ef209d9..5f741bb30240 100644
--- a/drivers/spi/spi-pxa2xx.h
+++ b/drivers/spi/spi-pxa2xx.h
@@ -78,7 +78,6 @@ struct driver_data {
 struct chip_data {
 	u32 cr1;
 	u32 dds_rate;
-	u32 timeout;
 	u32 threshold;
 	u16 lpss_rx_threshold;
 	u16 lpss_tx_threshold;
-- 
2.43.0.rc1.1.gbec44491f096


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related

* [PATCH v1 5/5] spi: pxa2xx: Don't provide struct chip_data for others
From: Andy Shevchenko @ 2024-04-03 17:06 UTC (permalink / raw)
  To: Andy Shevchenko, linux-arm-kernel, linux-spi, linux-kernel
  Cc: Daniel Mack, Haojian Zhuang, Robert Jarzmik, Mark Brown
In-Reply-To: <20240403171550.1074644-1-andriy.shevchenko@linux.intel.com>

Now the struct chip_data is local to spi-pxa2xx.c, move
its definition to the C file. This will slightly speed up
a build and also hide badly named data type (too generic).

Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
---
 drivers/spi/spi-pxa2xx.c | 8 ++++++++
 drivers/spi/spi-pxa2xx.h | 8 --------
 2 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/drivers/spi/spi-pxa2xx.c b/drivers/spi/spi-pxa2xx.c
index 030afb17e606..efe76d0c21bb 100644
--- a/drivers/spi/spi-pxa2xx.c
+++ b/drivers/spi/spi-pxa2xx.c
@@ -66,6 +66,14 @@ MODULE_ALIAS("platform:pxa2xx-spi");
 				| CE4100_SSCR1_RFT | CE4100_SSCR1_TFT | SSCR1_MWDS \
 				| SSCR1_SPH | SSCR1_SPO | SSCR1_LBM)
 
+struct chip_data {
+	u32 cr1;
+	u32 dds_rate;
+	u32 threshold;
+	u16 lpss_rx_threshold;
+	u16 lpss_tx_threshold;
+};
+
 #define LPSS_GENERAL_REG_RXTO_HOLDOFF_DISABLE	BIT(24)
 #define LPSS_CS_CONTROL_SW_MODE			BIT(0)
 #define LPSS_CS_CONTROL_CS_HIGH			BIT(1)
diff --git a/drivers/spi/spi-pxa2xx.h b/drivers/spi/spi-pxa2xx.h
index 5f741bb30240..93e1e471e1c6 100644
--- a/drivers/spi/spi-pxa2xx.h
+++ b/drivers/spi/spi-pxa2xx.h
@@ -75,14 +75,6 @@ struct driver_data {
 	struct gpio_desc *gpiod_ready;
 };
 
-struct chip_data {
-	u32 cr1;
-	u32 dds_rate;
-	u32 threshold;
-	u16 lpss_rx_threshold;
-	u16 lpss_tx_threshold;
-};
-
 static inline u32 pxa2xx_spi_read(const struct driver_data *drv_data, u32 reg)
 {
 	return pxa_ssp_read_reg(drv_data->ssp, reg);
-- 
2.43.0.rc1.1.gbec44491f096


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related

* [PATCH v1 1/5] spi: pxa2xx: Move number of CS pins validation out of condition
From: Andy Shevchenko @ 2024-04-03 17:06 UTC (permalink / raw)
  To: Andy Shevchenko, linux-arm-kernel, linux-spi, linux-kernel
  Cc: Daniel Mack, Haojian Zhuang, Robert Jarzmik, Mark Brown
In-Reply-To: <20240403171550.1074644-1-andriy.shevchenko@linux.intel.com>

There is no need to allocate chip_data and then validate number of
CS pins as it will have the same effect. Hence move number of CS pins
validation out of condition in setup().

Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
---
 drivers/spi/spi-pxa2xx.c | 15 +++++++--------
 1 file changed, 7 insertions(+), 8 deletions(-)

diff --git a/drivers/spi/spi-pxa2xx.c b/drivers/spi/spi-pxa2xx.c
index 1348249f8178..cc0e54f8d2c3 100644
--- a/drivers/spi/spi-pxa2xx.c
+++ b/drivers/spi/spi-pxa2xx.c
@@ -1200,6 +1200,13 @@ static int setup(struct spi_device *spi)
 		break;
 	}
 
+	if (drv_data->ssp_type == CE4100_SSP) {
+		if (spi_get_chipselect(spi, 0) > 4) {
+			dev_err(&spi->dev, "failed setup: cs number must not be > 4.\n");
+			return -EINVAL;
+		}
+	}
+
 	/* Only allocate on the first setup */
 	chip = spi_get_ctldata(spi);
 	if (!chip) {
@@ -1207,14 +1214,6 @@ static int setup(struct spi_device *spi)
 		if (!chip)
 			return -ENOMEM;
 
-		if (drv_data->ssp_type == CE4100_SSP) {
-			if (spi_get_chipselect(spi, 0) > 4) {
-				dev_err(&spi->dev,
-					"failed setup: cs number must not be > 4.\n");
-				kfree(chip);
-				return -EINVAL;
-			}
-		}
 		chip->enable_dma = drv_data->controller_info->enable_dma;
 		chip->timeout = TIMOUT_DFLT;
 	}
-- 
2.43.0.rc1.1.gbec44491f096


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related

* [PATCH v1 2/5] spi: pxa2xx: Drop struct pxa2xx_spi_chip
From: Andy Shevchenko @ 2024-04-03 17:06 UTC (permalink / raw)
  To: Andy Shevchenko, linux-arm-kernel, linux-spi, linux-kernel
  Cc: Daniel Mack, Haojian Zhuang, Robert Jarzmik, Mark Brown
In-Reply-To: <20240403171550.1074644-1-andriy.shevchenko@linux.intel.com>

No more users.

Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
---
 drivers/spi/spi-pxa2xx-dma.c |  9 ++-------
 drivers/spi/spi-pxa2xx.c     | 25 -------------------------
 drivers/spi/spi-pxa2xx.h     | 14 --------------
 3 files changed, 2 insertions(+), 46 deletions(-)

diff --git a/drivers/spi/spi-pxa2xx-dma.c b/drivers/spi/spi-pxa2xx-dma.c
index 751cb0f77b62..d77279c3acd8 100644
--- a/drivers/spi/spi-pxa2xx-dma.c
+++ b/drivers/spi/spi-pxa2xx-dma.c
@@ -231,16 +231,11 @@ int pxa2xx_spi_set_dma_burst_and_threshold(struct chip_data *chip,
 					   u8 bits_per_word, u32 *burst_code,
 					   u32 *threshold)
 {
-	struct pxa2xx_spi_chip *chip_info = spi->controller_data;
 	struct driver_data *drv_data = spi_controller_get_devdata(spi->controller);
 	u32 dma_burst_size = drv_data->controller_info->dma_burst_size;
 
-	/*
-	 * If the DMA burst size is given in chip_info we use that,
-	 * otherwise we use the default. Also we use the default FIFO
-	 * thresholds for now.
-	 */
-	*burst_code = chip_info ? chip_info->dma_burst_size : dma_burst_size;
+	/* We use the default the DMA burst size and FIFO thresholds for now */
+	*burst_code = dma_burst_size;
 	*threshold = SSCR1_RxTresh(RX_THRESH_DFLT)
 		   | SSCR1_TxTresh(TX_THRESH_DFLT);
 
diff --git a/drivers/spi/spi-pxa2xx.c b/drivers/spi/spi-pxa2xx.c
index cc0e54f8d2c3..00aa33c937bf 100644
--- a/drivers/spi/spi-pxa2xx.c
+++ b/drivers/spi/spi-pxa2xx.c
@@ -1154,7 +1154,6 @@ static int pxa2xx_spi_unprepare_transfer(struct spi_controller *controller)
 
 static int setup(struct spi_device *spi)
 {
-	struct pxa2xx_spi_chip *chip_info;
 	struct chip_data *chip;
 	const struct lpss_config *config;
 	struct driver_data *drv_data =
@@ -1218,25 +1217,6 @@ static int setup(struct spi_device *spi)
 		chip->timeout = TIMOUT_DFLT;
 	}
 
-	/*
-	 * Protocol drivers may change the chip settings, so...
-	 * if chip_info exists, use it.
-	 */
-	chip_info = spi->controller_data;
-
-	/* chip_info isn't always needed */
-	if (chip_info) {
-		if (chip_info->timeout)
-			chip->timeout = chip_info->timeout;
-		if (chip_info->tx_threshold)
-			tx_thres = chip_info->tx_threshold;
-		if (chip_info->tx_hi_threshold)
-			tx_hi_thres = chip_info->tx_hi_threshold;
-		if (chip_info->rx_threshold)
-			rx_thres = chip_info->rx_threshold;
-		chip->dma_threshold = 0;
-	}
-
 	chip->cr1 = 0;
 	if (spi_controller_is_target(drv_data->controller)) {
 		chip->cr1 |= SSCR1_SCFR;
@@ -1256,11 +1236,6 @@ static int setup(struct spi_device *spi)
 		chip->lpss_tx_threshold = tx_thres;
 	}
 
-	/*
-	 * Set DMA burst and threshold outside of chip_info path so that if
-	 * chip_info goes away after setting chip->enable_dma, the burst and
-	 * threshold can still respond to changes in bits_per_word.
-	 */
 	if (chip->enable_dma) {
 		/* Set up legal burst and threshold for DMA */
 		if (pxa2xx_spi_set_dma_burst_and_threshold(chip, spi,
diff --git a/drivers/spi/spi-pxa2xx.h b/drivers/spi/spi-pxa2xx.h
index f1097c96c50f..ae9c99bc9f6c 100644
--- a/drivers/spi/spi-pxa2xx.h
+++ b/drivers/spi/spi-pxa2xx.h
@@ -35,20 +35,6 @@ struct pxa2xx_spi_controller {
 	struct ssp_device ssp;
 };
 
-/*
- * The controller specific data for SPI target devices
- * (resides in spi_board_info.controller_data),
- * copied to spi_device.platform_data ... mostly for
- * DMA tuning.
- */
-struct pxa2xx_spi_chip {
-	u8 tx_threshold;
-	u8 tx_hi_threshold;
-	u8 rx_threshold;
-	u8 dma_burst_size;
-	u32 timeout;
-};
-
 struct spi_controller;
 struct spi_device;
 struct spi_transfer;
-- 
2.43.0.rc1.1.gbec44491f096


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related

* Re: [PATCH v6 1/1] dt-bindings: net: starfive,jh7110-dwmac: Add StarFive JH8100 support
From: Rob Herring @ 2024-04-03 17:15 UTC (permalink / raw)
  To: Tan Chun Hau
  Cc: Andrew Halaney, Maxime Coquelin, Simon Horman, netdev,
	Ley Foon Tan, David S . Miller, Jakub Kicinski, linux-arm-kernel,
	Jisheng Zhang, Russell King, Emil Renner Berthing, Rob Herring,
	Bartosz Golaszewski, Jee Heng Sia, Paolo Abeni, linux-riscv,
	linux-stm32, Alexandre Torgue, Eric Dumazet, devicetree,
	Uwe Kleine-König, linux-kernel, Conor Dooley,
	Krzysztof Kozlowski
In-Reply-To: <20240403100549.78719-2-chunhau.tan@starfivetech.com>


On Wed, 03 Apr 2024 03:05:49 -0700, Tan Chun Hau wrote:
> Add StarFive JH8100 dwmac support.
> The JH8100 dwmac shares the same driver code as the JH7110 dwmac
> and has only one reset signal.
> 
> Please refer to below:
> 
>   JH8100: reset-names = "stmmaceth";
>   JH7110: reset-names = "stmmaceth", "ahb";
>   JH7100: reset-names = "ahb";
> 
> Example usage of JH8100 in the device tree:
> 
> gmac0: ethernet@16030000 {
>         compatible = "starfive,jh8100-dwmac",
>                      "starfive,jh7110-dwmac",
>                      "snps,dwmac-5.20";
>         ...
> };
> 
> Signed-off-by: Tan Chun Hau <chunhau.tan@starfivetech.com>
> ---
>  .../bindings/net/starfive,jh7110-dwmac.yaml   | 28 +++++++++++++++----
>  1 file changed, 23 insertions(+), 5 deletions(-)
> 

Reviewed-by: Rob Herring <robh@kernel.org>


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply

* [PATCH v2 2/2] mailbox: arm_mhuv3: Add driver
From: Cristian Marussi @ 2024-04-03 17:13 UTC (permalink / raw)
  To: linux-kernel, linux-arm-kernel, devicetree
  Cc: sudeep.holla, cristian.marussi, jassisinghbrar, robh+dt,
	krzysztof.kozlowski+dt, conor+dt
In-Reply-To: <20240403171346.3173843-1-cristian.marussi@arm.com>

Add support for ARM MHUv3 mailbox controller.

Support is limited to the MHUv3 Doorbell extension using only the PBX/MBX
combined interrupts.

Signed-off-by: Cristian Marussi <cristian.marussi@arm.com>
---
v1 -> v2
- fixed checkpatch warnings about side-effects
- fixed sparse errors as reported
  | Reported-by: kernel test robot <lkp@intel.com>
  | Closes: https://lore.kernel.org/oe-kbuild-all/202403290015.tCLXudqC-lkp@intel.com/
---
 MAINTAINERS                 |    9 +
 drivers/mailbox/Kconfig     |   11 +
 drivers/mailbox/Makefile    |    2 +
 drivers/mailbox/arm_mhuv3.c | 1063 +++++++++++++++++++++++++++++++++++
 4 files changed, 1085 insertions(+)
 create mode 100644 drivers/mailbox/arm_mhuv3.c

diff --git a/MAINTAINERS b/MAINTAINERS
index aa3b947fb080..e957b9d9e32a 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -12998,6 +12998,15 @@ F:	Documentation/devicetree/bindings/mailbox/arm,mhuv2.yaml
 F:	drivers/mailbox/arm_mhuv2.c
 F:	include/linux/mailbox/arm_mhuv2_message.h
 
+MAILBOX ARM MHUv3
+M:	Sudeep Holla <sudeep.holla@arm.com>
+M:	Cristian Marussi <cristian.marussi@arm.com>
+L:	linux-kernel@vger.kernel.org
+L:	linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
+S:	Maintained
+F:	Documentation/devicetree/bindings/mailbox/arm,mhuv3.yaml
+F:	drivers/mailbox/arm_mhuv3.c
+
 MAN-PAGES: MANUAL PAGES FOR LINUX -- Sections 2, 3, 4, 5, and 7
 M:	Alejandro Colomar <alx@kernel.org>
 L:	linux-man@vger.kernel.org
diff --git a/drivers/mailbox/Kconfig b/drivers/mailbox/Kconfig
index 42940108a187..d20cdae65cfe 100644
--- a/drivers/mailbox/Kconfig
+++ b/drivers/mailbox/Kconfig
@@ -23,6 +23,17 @@ config ARM_MHU_V2
 	  Say Y here if you want to build the ARM MHUv2 controller driver,
 	  which provides unidirectional mailboxes between processing elements.
 
+config ARM_MHU_V3
+	tristate "ARM MHUv3 Mailbox"
+	depends on ARM64 || COMPILE_TEST
+	help
+	  Say Y here if you want to build the ARM MHUv3 controller driver,
+	  which provides unidirectional mailboxes between processing elements.
+
+	  ARM MHUv3 controllers can implement a varying number of extensions
+	  that provides different means of transports: supported extensions
+	  will be discovered and possibly managed at probe-time.
+
 config IMX_MBOX
 	tristate "i.MX Mailbox"
 	depends on ARCH_MXC || COMPILE_TEST
diff --git a/drivers/mailbox/Makefile b/drivers/mailbox/Makefile
index 18793e6caa2f..5cf2f54debaf 100644
--- a/drivers/mailbox/Makefile
+++ b/drivers/mailbox/Makefile
@@ -9,6 +9,8 @@ obj-$(CONFIG_ARM_MHU)	+= arm_mhu.o arm_mhu_db.o
 
 obj-$(CONFIG_ARM_MHU_V2)	+= arm_mhuv2.o
 
+obj-$(CONFIG_ARM_MHU_V3)	+= arm_mhuv3.o
+
 obj-$(CONFIG_IMX_MBOX)	+= imx-mailbox.o
 
 obj-$(CONFIG_ARMADA_37XX_RWTM_MBOX)	+= armada-37xx-rwtm-mailbox.o
diff --git a/drivers/mailbox/arm_mhuv3.c b/drivers/mailbox/arm_mhuv3.c
new file mode 100644
index 000000000000..e4125568bec0
--- /dev/null
+++ b/drivers/mailbox/arm_mhuv3.c
@@ -0,0 +1,1063 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * ARM Message Handling Unit Version 3 (MHUv3) driver.
+ *
+ * Copyright (C) 2024 ARM Ltd.
+ *
+ * Based on ARM MHUv2 driver.
+ */
+
+#include <linux/device.h>
+#include <linux/interrupt.h>
+#include <linux/mailbox_controller.h>
+#include <linux/module.h>
+#include <linux/of_address.h>
+#include <linux/platform_device.h>
+#include <linux/spinlock.h>
+#include <linux/types.h>
+
+/* ====== MHUv3 Registers ====== */
+
+/* Maximum number of Doorbell channel windows */
+#define MHUV3_DBCW_MAX			128
+/* Number of DBCH combined interrupt status registers */
+#define MHUV3_DBCH_CMB_INT_ST_REG_CNT	4
+#define MHUV3_INVALID_DOORBELL		0xFFFFFFFFUL
+
+/* Number of FFCH combined interrupt status registers */
+#define MHUV3_FFCH_CMB_INT_ST_REG_CNT	2
+
+#define MHUV3_STAT_BYTES		(sizeof(u32))
+#define MHUV3_STAT_BITS			(MHUV3_STAT_BYTES * __CHAR_BIT__)
+
+/* Not a typo ... */
+#define MHUV3_MAJOR_VERSION		2
+
+enum {
+	MHUV3_MBOX_CELL_TYPE,
+	MHUV3_MBOX_CELL_CHWN,
+	MHUV3_MBOX_CELL_PARAM,
+	MHUV3_MBOX_CELLS
+};
+
+/* CTRL_Page */
+
+struct blk_id {
+	u32 blk_id : 4;
+	u32 pad : 28;
+} __packed;
+
+struct feat_spt0 {
+	u32 dbe_spt : 4;
+	u32 fe_spt : 4;
+	u32 fce_spt : 4;
+	u32 tze_spt : 4;
+	u32 rme_spt : 4;
+	u32 rase_spt : 4;
+	u32 pad: 8;
+} __packed;
+
+struct feat_spt1 {
+	u32 auto_op_spt : 4;
+	u32 pad: 28;
+} __packed;
+
+struct dbch_cfg0 {
+	u32 num_dbch : 8;
+	u32 pad: 24;
+} __packed;
+
+struct ffch_cfg0 {
+	u32 num_ffch : 8;
+	u32 x8ba_spt : 1;
+	u32 x16ba_spt : 1;
+	u32 x32ba_spt : 1;
+	u32 x64ba_spt : 1;
+	u32 pad : 4;
+	u32 ffch_depth : 10;
+	u32 pad2 : 6;
+} __packed;
+
+struct fch_cfg0 {
+	u32 num_fch : 10;
+	/* MBX only registers */
+	u32 fcgi_spt : 1;
+	/* ------------------ */
+	u32 num_fcg : 5;
+	u32 num_fch_per_grp : 5;
+	u32 fch_ws : 8;
+	u32 pad : 3;
+} __packed;
+
+struct ctrl {
+	u32 op_req : 1;
+	u32 ch_op_mask : 1;
+	u32 pad : 30;
+} __packed;
+
+struct fch_ctrl {
+	u32 pad : 2;
+	u32 int_en : 1;
+	u32 pad2 : 29;
+} __packed;
+
+struct iidr {
+	u32 implementer : 12;
+	u32 revision : 4;
+	u32 variant : 4;
+	u32 product_id : 12;
+} __packed;
+
+struct aidr {
+	u32 arch_minor_rev : 4;
+	u32 arch_major_rev : 4;
+	u32 pad : 24;
+} __packed;
+
+struct ctrl_page {
+	struct blk_id blk_id;
+	u8 pad[0x10 - 0x4];
+	struct feat_spt0 feat_spt0;
+	struct feat_spt1 feat_spt1;
+	u8 pad1[0x20 - 0x18];
+	struct dbch_cfg0 dbch_cfg0;
+	u8 pad2[0x30 - 0x24];
+	struct ffch_cfg0 ffch_cfg0;
+	u8 pad3[0x40 - 0x34];
+	struct fch_cfg0 fch_cfg0;
+	u8 pad4[0x100 - 0x44];
+	struct ctrl ctrl;
+	/* MBX only registers */
+	u8 pad5[0x140 - 0x104];
+	struct fch_ctrl fch_ctrl;
+	u32 fcg_int_en;
+	u8 pad6[0x400 - 0x148];
+	/* ------------------ */
+	u32 dbch_int_st[MHUV3_DBCH_CMB_INT_ST_REG_CNT];
+	u32 ffch_int_st[MHUV3_FFCH_CMB_INT_ST_REG_CNT];
+	/* MBX only registers */
+	u8 pad7[0x470 - 0x418];
+	u32 fcg_int_st;
+	u8 pad8[0x480 - 0x474];
+	u32 fcg_grp_int_st[32];
+	u8 pad9[0xFC8 - 0x500];
+	/* ------------------ */
+	struct iidr iidr;
+	struct aidr aidr;
+	u32 imp_def_id[12];
+} __packed;
+
+/* DBCW_Page */
+
+struct xbcw_ctrl {
+	u32 comb_en : 1;
+	u32 pad : 31;
+} __packed;
+
+struct pdbcw_int {
+	u32 tfr_ack : 1;
+	u32 pad : 31;
+} __packed;
+
+struct pdbcw_page {
+	u32 st;
+	u8 pad[0xC - 0x4];
+	u32 set;
+	struct pdbcw_int int_st;
+	struct pdbcw_int int_clr;
+	struct pdbcw_int int_en;
+	struct xbcw_ctrl ctrl;
+} __packed;
+
+struct mdbcw_page {
+	u32 st;
+	u32 st_msk;
+	u32 clr;
+	u8 pad[0x10 - 0xC];
+	u32 msk_st;
+	u32 msk_set;
+	u32 msk_clr;
+	struct xbcw_ctrl ctrl;
+} __packed;
+
+struct dummy_page {
+	u8 pad[0x1000];
+} __packed;
+
+struct mhu3_pbx_frame_reg {
+	struct ctrl_page ctrl;
+	struct pdbcw_page dbcw[MHUV3_DBCW_MAX];
+	struct dummy_page ffcw;
+	struct dummy_page fcw;
+	u8 pad[0xF000 - 0x4000];
+	struct dummy_page impdef;
+} __packed;
+
+struct mhu3_mbx_frame_reg {
+	struct ctrl_page ctrl;
+	struct mdbcw_page dbcw[MHUV3_DBCW_MAX];
+	struct dummy_page ffcw;
+	struct dummy_page fcw;
+	u8 pad[0xF000 - 0x4000];
+	struct dummy_page impdef;
+} __packed;
+
+/* Macro for reading a bitfield within a physically mapped packed struct */
+#define readl_relaxed_bitfield(_regptr, _field)				\
+	({								\
+		u32 _rval;						\
+		typeof(_regptr) _rptr = _regptr;			\
+		_rval = readl_relaxed(_rptr);				\
+		((typeof(*_rptr) __force *)(&_rval))->_field;		\
+	})
+
+/* Macro for writing a bitfield within a physically mapped packed struct */
+#define writel_relaxed_bitfield(_value, _regptr, _field)		\
+	({								\
+		u32 _rval;						\
+		typeof(_regptr) _rptr = _regptr;			\
+		_rval = readl_relaxed(_rptr);				\
+		((typeof(*_rptr) __force *)(&_rval))->_field = _value;	\
+		writel_relaxed(_rval, _rptr);				\
+	})
+
+/* ====== MHUv3 data structures ====== */
+
+enum mhuv3_frame {
+	PBX_FRAME,
+	MBX_FRAME
+};
+
+static char *mhuv3_str[] = {
+	"PBX",
+	"MBX"
+};
+
+enum mhuv3_extension_type {
+	FIRST_EXT = 0,
+	DBE_EXT = FIRST_EXT,
+	FCE_EXT,
+	FE_EXT,
+	MAX_EXT
+};
+
+struct mhuv3;
+
+/**
+ * struct mhuv3_protocol_ops - MHUv3 operations
+ *
+ * @rx_startup: Receiver startup callback.
+ * @rx_shutdown: Receiver shutdown callback.
+ * @read_data: Read available Sender in-band LE data (if any).
+ * @rx_complete: Acknowledge data reception to the Sender. Any out-of-band data
+ *		 has to have been already retrieved before calling this.
+ * @tx_startup: Sender startup callback.
+ * @tx_shutdown: Sender shutdown callback.
+ * @last_tx_done: Report back to the Sender if the last transfer has completed.
+ * @send_data: Send data to the receiver.
+ *
+ * Each supported transport protocol provides its own implementation of
+ * these operations.
+ */
+struct mhuv3_protocol_ops {
+	int (*rx_startup)(struct mhuv3 *mhu, struct mbox_chan *chan);
+	void (*rx_shutdown)(struct mhuv3 *mhu, struct mbox_chan *chan);
+	void *(*read_data)(struct mhuv3 *mhu, struct mbox_chan *chan);
+	void (*rx_complete)(struct mhuv3 *mhu, struct mbox_chan *chan);
+	void (*tx_startup)(struct mhuv3 *mhu, struct mbox_chan *chan);
+	void (*tx_shutdown)(struct mhuv3 *mhu, struct mbox_chan *chan);
+	int (*last_tx_done)(struct mhuv3 *mhu, struct mbox_chan *chan);
+	int (*send_data)(struct mhuv3 *mhu, struct mbox_chan *chan, void *arg);
+};
+
+/**
+ * struct mhuv3_mbox_chan_priv - MHUv3 channel private information
+ *
+ * @ch_idx: Channel window index associated to this mailbox channel.
+ * @doorbell: Doorbell bit number within the @ch_idx window.
+ *	      Only relevant to Doorbell transport.
+ * @ops: Transport protocol specific operations for this channel.
+ *
+ * Transport specific data attached to mmailbox channel priv data.
+ */
+struct mhuv3_mbox_chan_priv {
+	u32 ch_idx;
+	u32 doorbell;
+	const struct mhuv3_protocol_ops *ops;
+};
+
+/**
+ * struct mhuv3_extension - MHUv3 extension descriptor
+ *
+ * @type: Type of extension
+ * @max_chans: Max number of channels found for this extension.
+ * @base_ch_idx: First channel number assigned to this extension, picked from
+ *		 the set of all mailbox channels descriptors created.
+ * @mbox_of_xlate: Extension specific helper to parse DT and lookup associated
+ *		   channel from the related 'mboxes' property.
+ * @combined_irq_setup: Extension specific helper to setup the combined irq.
+ * @channels_init: Extension specific helper to initialize channels.
+ * @chan_from_comb_irq_get: Extension specific helper to lookup which channel
+ *			    triggered the combined irq.
+ * @pending_db: Array of per-channel pending doorbells.
+ * @pending_lock: Protect access to pending_db.
+ */
+struct mhuv3_extension {
+	enum mhuv3_extension_type type;
+	unsigned int max_chans;
+	unsigned int base_ch_idx;
+	struct mbox_chan *(*mbox_of_xlate)(struct mhuv3 *mhu,
+					   unsigned int channel,
+					   unsigned int param);
+	void (*combined_irq_setup)(struct mhuv3 *mhu);
+	int (*channels_init)(struct mhuv3 *mhu);
+	struct mbox_chan *(*chan_from_comb_irq_get)(struct mhuv3 *mhu);
+	u32 pending_db[MHUV3_DBCW_MAX];
+	/* Protect access to pending_db */
+	spinlock_t pending_lock;
+};
+
+/**
+ * struct mhuv3 - MHUv3 mailbox controller data
+ *
+ * @frame:	Frame type: MBX_FRAME or PBX_FRAME.
+ * @auto_op_full: Flag to indicate if the MHU supports AutoOp full mode.
+ * @major: MHUv3 controller architectural major version.
+ * @minor: MHUv3 controller architectural minor version.
+ * @tot_chans: The total number of channnels discovered across all extensions.
+ * @cmb_irq: Combined IRQ number if any found defined.
+ * @ctrl: A reference to the MHUv3 control page for this block.
+ * @pbx: Base address of the PBX register mapping region.
+ * @mbx: Base address of the MBX register mapping region.
+ * @ext: Array holding descriptors for any found implemented extension.
+ * @mbox: Mailbox controller belonging to the MHU frame.
+ */
+struct mhuv3 {
+	enum mhuv3_frame frame;
+	bool auto_op_full;
+	unsigned int major;
+	unsigned int minor;
+	unsigned int tot_chans;
+	int cmb_irq;
+	struct ctrl_page __iomem *ctrl;
+	union {
+		struct mhu3_pbx_frame_reg __iomem *pbx;
+		struct mhu3_mbx_frame_reg __iomem *mbx;
+	};
+	struct mhuv3_extension *ext[MAX_EXT];
+	struct mbox_controller mbox;
+};
+
+#define mhu_from_mbox(_mbox) container_of(_mbox, struct mhuv3, mbox)
+
+typedef int (*mhuv3_extension_initializer)(struct mhuv3 *mhu);
+
+/* =================== Doorbell transport protocol operations =============== */
+
+static void mhuv3_doorbell_tx_startup(struct mhuv3 *mhu, struct mbox_chan *chan)
+{
+	struct mhuv3_mbox_chan_priv *priv = chan->con_priv;
+
+	/* Enable Transfer Acknowledgment events */
+	writel_relaxed_bitfield(0x1, &mhu->pbx->dbcw[priv->ch_idx].int_en, tfr_ack);
+}
+
+static void mhuv3_doorbell_tx_shutdown(struct mhuv3 *mhu, struct mbox_chan *chan)
+{
+	unsigned long flags;
+	struct mhuv3_extension *e = mhu->ext[DBE_EXT];
+	struct mhuv3_mbox_chan_priv *priv = chan->con_priv;
+
+	/* Disable Channel Transfer Ack events */
+	writel_relaxed_bitfield(0x0, &mhu->pbx->dbcw[priv->ch_idx].int_en, tfr_ack);
+
+	/* Clear Channel Transfer Ack and pending doorbells */
+	writel_relaxed_bitfield(0x1, &mhu->pbx->dbcw[priv->ch_idx].int_clr, tfr_ack);
+	spin_lock_irqsave(&e->pending_lock, flags);
+	e->pending_db[priv->ch_idx] = 0;
+	spin_unlock_irqrestore(&e->pending_lock, flags);
+}
+
+static int mhuv3_doorbell_rx_startup(struct mhuv3 *mhu, struct mbox_chan *chan)
+{
+	struct mhuv3_mbox_chan_priv *priv = chan->con_priv;
+
+	/* Unmask Channel Transfer events */
+	writel_relaxed(BIT(priv->doorbell), &mhu->mbx->dbcw[priv->ch_idx].msk_clr);
+
+	return 0;
+}
+
+static void mhuv3_doorbell_rx_shutdown(struct mhuv3 *mhu,
+				       struct mbox_chan *chan)
+{
+	struct mhuv3_mbox_chan_priv *priv = chan->con_priv;
+
+	/* Mask Channel Transfer events */
+	writel_relaxed(BIT(priv->doorbell), &mhu->mbx->dbcw[priv->ch_idx].msk_set);
+}
+
+static void mhuv3_doorbell_rx_complete(struct mhuv3 *mhu, struct mbox_chan *chan)
+{
+	struct mhuv3_mbox_chan_priv *priv = chan->con_priv;
+
+	/* Clearing the pending transfer generates the Channel Transfer Ack */
+	writel_relaxed(BIT(priv->doorbell), &mhu->mbx->dbcw[priv->ch_idx].clr);
+}
+
+static int mhuv3_doorbell_last_tx_done(struct mhuv3 *mhu,
+				       struct mbox_chan *chan)
+{
+	int done;
+	struct mhuv3_mbox_chan_priv *priv = chan->con_priv;
+
+	done = !(readl_relaxed(&mhu->pbx->dbcw[priv->ch_idx].st) &
+		 BIT(priv->doorbell));
+	if (done) {
+		unsigned long flags;
+		struct mhuv3_extension *e = mhu->ext[DBE_EXT];
+
+		/* Take care to clear the pending doorbell also when polling */
+		spin_lock_irqsave(&e->pending_lock, flags);
+		e->pending_db[priv->ch_idx] &= ~BIT(priv->doorbell);
+		spin_unlock_irqrestore(&e->pending_lock, flags);
+	}
+
+	return done;
+}
+
+static int mhuv3_doorbell_send_data(struct mhuv3 *mhu, struct mbox_chan *chan,
+				    void *arg)
+{
+	int ret = 0;
+	struct mhuv3_mbox_chan_priv *priv = chan->con_priv;
+	struct mhuv3_extension *e = mhu->ext[DBE_EXT];
+	unsigned long flags;
+
+	spin_lock_irqsave(&e->pending_lock, flags);
+	/* Only one in-flight Transfer is allowed per-doorbell */
+	if (!(e->pending_db[priv->ch_idx] & BIT(priv->doorbell))) {
+		e->pending_db[priv->ch_idx] |= BIT(priv->doorbell);
+		writel_relaxed(BIT(priv->doorbell),
+			       &mhu->pbx->dbcw[priv->ch_idx].set);
+	} else {
+		ret = -EBUSY;
+	}
+	spin_unlock_irqrestore(&e->pending_lock, flags);
+
+	return ret;
+}
+
+static const struct mhuv3_protocol_ops mhuv3_doorbell_ops = {
+	.tx_startup = mhuv3_doorbell_tx_startup,
+	.tx_shutdown = mhuv3_doorbell_tx_shutdown,
+	.rx_startup = mhuv3_doorbell_rx_startup,
+	.rx_shutdown = mhuv3_doorbell_rx_shutdown,
+	.rx_complete = mhuv3_doorbell_rx_complete,
+	.last_tx_done = mhuv3_doorbell_last_tx_done,
+	.send_data = mhuv3_doorbell_send_data,
+};
+
+/* Sender and receiver mailbox ops */
+static bool mhuv3_sender_last_tx_done(struct mbox_chan *chan)
+{
+	struct mhuv3 *mhu = mhu_from_mbox(chan->mbox);
+	struct mhuv3_mbox_chan_priv *priv = chan->con_priv;
+
+	return priv->ops->last_tx_done(mhu, chan);
+}
+
+static int mhuv3_sender_send_data(struct mbox_chan *chan, void *data)
+{
+	struct mhuv3 *mhu = mhu_from_mbox(chan->mbox);
+	struct mhuv3_mbox_chan_priv *priv = chan->con_priv;
+
+	if (!priv->ops->last_tx_done(mhu, chan))
+		return -EBUSY;
+
+	return priv->ops->send_data(mhu, chan, data);
+}
+
+static int mhuv3_sender_startup(struct mbox_chan *chan)
+{
+	struct mhuv3 *mhu = mhu_from_mbox(chan->mbox);
+	struct mhuv3_mbox_chan_priv *priv = chan->con_priv;
+
+	if (priv->ops->tx_startup)
+		priv->ops->tx_startup(mhu, chan);
+
+	return 0;
+}
+
+static void mhuv3_sender_shutdown(struct mbox_chan *chan)
+{
+	struct mhuv3 *mhu = mhu_from_mbox(chan->mbox);
+	struct mhuv3_mbox_chan_priv *priv = chan->con_priv;
+
+	if (priv->ops->tx_shutdown)
+		priv->ops->tx_shutdown(mhu, chan);
+}
+
+static const struct mbox_chan_ops mhuv3_sender_ops = {
+	.send_data = mhuv3_sender_send_data,
+	.startup = mhuv3_sender_startup,
+	.shutdown = mhuv3_sender_shutdown,
+	.last_tx_done = mhuv3_sender_last_tx_done,
+};
+
+static int mhuv3_receiver_startup(struct mbox_chan *chan)
+{
+	struct mhuv3 *mhu = mhu_from_mbox(chan->mbox);
+	struct mhuv3_mbox_chan_priv *priv = chan->con_priv;
+
+	return priv->ops->rx_startup(mhu, chan);
+}
+
+static void mhuv3_receiver_shutdown(struct mbox_chan *chan)
+{
+	struct mhuv3 *mhu = mhu_from_mbox(chan->mbox);
+	struct mhuv3_mbox_chan_priv *priv = chan->con_priv;
+
+	priv->ops->rx_shutdown(mhu, chan);
+}
+
+static int mhuv3_receiver_send_data(struct mbox_chan *chan, void *data)
+{
+	dev_err(chan->mbox->dev,
+		"Trying to transmit on a MBX MHUv3 frame\n");
+	return -EIO;
+}
+
+static bool mhuv3_receiver_last_tx_done(struct mbox_chan *chan)
+{
+	dev_err(chan->mbox->dev, "Trying to Tx poll on a MBX MHUv3 frame\n");
+	return true;
+}
+
+static const struct mbox_chan_ops mhuv3_receiver_ops = {
+	.send_data = mhuv3_receiver_send_data,
+	.startup = mhuv3_receiver_startup,
+	.shutdown = mhuv3_receiver_shutdown,
+	.last_tx_done = mhuv3_receiver_last_tx_done,
+};
+
+static struct mbox_chan *mhuv3_dbe_mbox_of_xlate(struct mhuv3 *mhu,
+						 unsigned int channel,
+						 unsigned int doorbell)
+{
+	struct mbox_controller *mbox = &mhu->mbox;
+	struct mbox_chan *chans = mbox->chans;
+	struct mhuv3_extension *e = mhu->ext[DBE_EXT];
+
+	if (channel >= e->max_chans || doorbell >= MHUV3_STAT_BITS) {
+		dev_err(mbox->dev, "Couldn't xlate to a valid channel (%d: %d)\n",
+			channel, doorbell);
+		return ERR_PTR(-ENODEV);
+	}
+
+	return &chans[e->base_ch_idx + channel * MHUV3_STAT_BITS + doorbell];
+}
+
+static void mhuv3_dbe_combined_irq_setup(struct mhuv3 *mhu)
+{
+	int i;
+	struct mhuv3_extension *e = mhu->ext[DBE_EXT];
+
+	if (mhu->frame == PBX_FRAME) {
+		struct pdbcw_page __iomem *dbcw = mhu->pbx->dbcw;
+
+		for (i = 0; i < e->max_chans; i++) {
+			writel_relaxed_bitfield(0x1, &dbcw[i].int_clr, tfr_ack);
+			writel_relaxed_bitfield(0x0, &dbcw[i].int_en, tfr_ack);
+			writel_relaxed_bitfield(0x1, &dbcw[i].ctrl, comb_en);
+		}
+	} else {
+		struct mdbcw_page __iomem *dbcw = mhu->mbx->dbcw;
+
+		for (i = 0; i < e->max_chans; i++) {
+			writel_relaxed(0xFFFFFFFF, &dbcw[i].clr);
+			writel_relaxed(0xFFFFFFFF, &dbcw[i].msk_set);
+			writel_relaxed_bitfield(0x1, &dbcw[i].ctrl, comb_en);
+		}
+	}
+}
+
+static int mhuv3_dbe_channels_init(struct mhuv3 *mhu)
+{
+	int i;
+	struct mhuv3_extension *e = mhu->ext[DBE_EXT];
+	struct mbox_controller *mbox = &mhu->mbox;
+	struct mbox_chan *chans;
+
+	chans = mbox->chans + mbox->num_chans;
+	e->base_ch_idx = mbox->num_chans;
+	for (i = 0; i < e->max_chans; i++) {
+		int k;
+		struct mhuv3_mbox_chan_priv *priv;
+
+		for (k = 0; k < MHUV3_STAT_BITS; k++) {
+			priv = devm_kmalloc(mbox->dev, sizeof(*priv), GFP_KERNEL);
+			if (!priv)
+				return -ENOMEM;
+
+			priv->ch_idx = i;
+			priv->ops = &mhuv3_doorbell_ops;
+			priv->doorbell = k;
+			chans++->con_priv = priv;
+			mbox->num_chans++;
+		}
+	}
+
+	spin_lock_init(&e->pending_lock);
+
+	return 0;
+}
+
+static struct mbox_chan *mhuv3_dbe_chan_from_comb_irq_get(struct mhuv3 *mhu)
+{
+	int i;
+	struct mhuv3_extension *e = mhu->ext[DBE_EXT];
+	struct device *dev = mhu->mbox.dev;
+
+	for (i = 0; i < MHUV3_DBCH_CMB_INT_ST_REG_CNT; i++) {
+		unsigned int channel, db = MHUV3_INVALID_DOORBELL;
+		u32 cmb_st, st;
+
+		cmb_st = readl_relaxed(&mhu->ctrl->dbch_int_st[i]);
+		if (!cmb_st)
+			continue;
+
+		channel = i * MHUV3_STAT_BITS + __builtin_ctz(cmb_st);
+		if (channel >= e->max_chans) {
+			dev_err(dev, "Invalid %s channel:%d\n",
+				mhuv3_str[mhu->frame], channel);
+			break;
+		}
+
+		if (mhu->frame == PBX_FRAME) {
+			unsigned long flags;
+			u32 active_dbs, fired_dbs;
+
+			st = readl_relaxed_bitfield(&mhu->pbx->dbcw[channel].int_st,
+						    tfr_ack);
+			if (!st) {
+				dev_warn(dev, "Spurios IRQ on %s channel:%d\n",
+					 mhuv3_str[mhu->frame], channel);
+				continue;
+			}
+
+			active_dbs = readl_relaxed(&mhu->pbx->dbcw[channel].st);
+			spin_lock_irqsave(&e->pending_lock, flags);
+			fired_dbs = e->pending_db[channel] & ~active_dbs;
+			if (fired_dbs) {
+				db = __builtin_ctz(fired_dbs);
+				e->pending_db[channel] &= ~BIT(db);
+				fired_dbs &= ~BIT(db);
+			}
+			spin_unlock_irqrestore(&e->pending_lock, flags);
+
+			/* Clear TFR Ack if no more doorbells pending */
+			if (!fired_dbs)
+				writel_relaxed_bitfield(0x1,
+							&mhu->pbx->dbcw[channel].int_clr,
+							tfr_ack);
+		} else {
+			st = readl_relaxed(&mhu->mbx->dbcw[channel].st_msk);
+			if (!st) {
+				dev_warn(dev, "Spurios IRQ on %s channel:%d\n",
+					 mhuv3_str[mhu->frame], channel);
+				continue;
+			}
+			db = __builtin_ctz(st);
+		}
+
+		if (db != MHUV3_INVALID_DOORBELL) {
+			dev_dbg(dev, "Found %s ch[%d]/db[%d]\n",
+				mhuv3_str[mhu->frame], channel, db);
+
+			return &mhu->mbox.chans[channel * MHUV3_STAT_BITS + db];
+		}
+	}
+
+	return ERR_PTR(-EIO);
+}
+
+static int mhuv3_dbe_init(struct mhuv3 *mhu)
+{
+	struct mhuv3_extension *e;
+	struct device *dev = mhu->mbox.dev;
+
+	if (!readl_relaxed_bitfield(&mhu->ctrl->feat_spt0, dbe_spt))
+		return 0;
+
+	dev_dbg(dev, "%s: Initializing DBE Extension.\n", mhuv3_str[mhu->frame]);
+
+	e = devm_kzalloc(dev, sizeof(*e), GFP_KERNEL);
+	if (!e)
+		return -ENOMEM;
+
+	e->type = DBE_EXT;
+	/* Note that, by the spec, the number of channels is (num_dbch + 1) */
+	e->max_chans =
+		readl_relaxed_bitfield(&mhu->ctrl->dbch_cfg0, num_dbch) + 1;
+	e->mbox_of_xlate = mhuv3_dbe_mbox_of_xlate;
+	e->combined_irq_setup = mhuv3_dbe_combined_irq_setup;
+	e->channels_init = mhuv3_dbe_channels_init;
+	e->chan_from_comb_irq_get = mhuv3_dbe_chan_from_comb_irq_get;
+
+	mhu->tot_chans += e->max_chans * MHUV3_STAT_BITS;
+	mhu->ext[DBE_EXT] = e;
+
+	dev_info(dev, "%s: found %d DBE channels.\n",
+		 mhuv3_str[mhu->frame], e->max_chans);
+
+	return 0;
+}
+
+static int mhuv3_fce_init(struct mhuv3 *mhu)
+{
+	struct device *dev = mhu->mbox.dev;
+
+	if (!readl_relaxed_bitfield(&mhu->ctrl->feat_spt0, fce_spt))
+		return 0;
+
+	dev_dbg(dev, "%s: FCE Extension not supported by driver.\n",
+		mhuv3_str[mhu->frame]);
+
+	return 0;
+}
+
+static int mhuv3_fe_init(struct mhuv3 *mhu)
+{
+	struct device *dev = mhu->mbox.dev;
+
+	if (!readl_relaxed_bitfield(&mhu->ctrl->feat_spt0, fe_spt))
+		return 0;
+
+	dev_dbg(dev, "%s: FE Extension not supported by driver.\n",
+		mhuv3_str[mhu->frame]);
+
+	return 0;
+}
+
+static mhuv3_extension_initializer mhuv3_extension_init[MAX_EXT] = {
+	mhuv3_dbe_init,
+	mhuv3_fce_init,
+	mhuv3_fe_init,
+};
+
+static int mhuv3_initialize_channels(struct device *dev, struct mhuv3 *mhu)
+{
+	int i, ret = 0;
+	struct mbox_controller *mbox = &mhu->mbox;
+
+	mbox->chans = devm_kcalloc(dev, mhu->tot_chans,
+				   sizeof(*mbox->chans), GFP_KERNEL);
+	if (!mbox->chans)
+		return -ENOMEM;
+
+	for (i = FIRST_EXT; i < MAX_EXT && !ret; i++)
+		if (mhu->ext[i])
+			ret = mhu->ext[i]->channels_init(mhu);
+
+	return ret;
+}
+
+static struct mbox_chan *mhuv3_mbox_of_xlate(struct mbox_controller *mbox,
+					     const struct of_phandle_args *pa)
+{
+	unsigned int type, channel, param;
+	struct mhuv3 *mhu = mhu_from_mbox(mbox);
+
+	if (pa->args_count != MHUV3_MBOX_CELLS)
+		return ERR_PTR(-EINVAL);
+
+	type = pa->args[MHUV3_MBOX_CELL_TYPE];
+	if (type >= MAX_EXT)
+		return ERR_PTR(-EINVAL);
+
+	channel = pa->args[MHUV3_MBOX_CELL_CHWN];
+	param = pa->args[MHUV3_MBOX_CELL_PARAM];
+
+	return mhu->ext[type]->mbox_of_xlate(mhu, channel, param);
+}
+
+static int mhuv3_frame_init(struct mhuv3 *mhu, void __iomem *regs)
+{
+	int i, ret = 0;
+	struct device *dev = mhu->mbox.dev;
+
+	mhu->ctrl = regs;
+	mhu->frame = readl_relaxed_bitfield(&mhu->ctrl->blk_id, blk_id);
+	if (mhu->frame > MBX_FRAME) {
+		dev_err(dev, "Invalid Frame type- %d\n", mhu->frame);
+		return -EINVAL;
+	}
+
+	mhu->major = readl_relaxed_bitfield(&mhu->ctrl->aidr, arch_major_rev);
+	mhu->minor = readl_relaxed_bitfield(&mhu->ctrl->aidr, arch_minor_rev);
+	if (mhu->major != MHUV3_MAJOR_VERSION) {
+		dev_warn(dev, "Unsupported MHU %s block - major:%d  minor:%d\n",
+			 mhuv3_str[mhu->frame], mhu->major, mhu->minor);
+		return -EINVAL;
+	}
+	mhu->auto_op_full = !!readl_relaxed_bitfield(&mhu->ctrl->feat_spt1,
+						     auto_op_spt);
+	/* Request the PBX/MBX to remain operational */
+	if (mhu->auto_op_full)
+		writel_relaxed_bitfield(0x1, &mhu->ctrl->ctrl, op_req);
+
+	dev_dbg(dev, "Found MHU %s block - major:%d  minor:%d\n",
+		mhuv3_str[mhu->frame], mhu->major, mhu->minor);
+
+	if (mhu->frame == PBX_FRAME)
+		mhu->pbx = regs;
+	else
+		mhu->mbx = regs;
+
+	for (i = FIRST_EXT; i < MAX_EXT && !ret; i++)
+		ret = mhuv3_extension_init[i](mhu);
+
+	return ret;
+}
+
+static irqreturn_t mhuv3_pbx_comb_interrupt(int irq, void *arg)
+{
+	int ret = IRQ_NONE;
+	unsigned int i, found = 0;
+	struct mhuv3 *mhu = arg;
+	struct device *dev = mhu->mbox.dev;
+	struct mbox_chan *chan;
+
+	for (i = FIRST_EXT; i < MAX_EXT; i++) {
+		/* FCE does not participate to the PBX combined */
+		if (i == FCE_EXT || !mhu->ext[i])
+			continue;
+
+		chan = mhu->ext[i]->chan_from_comb_irq_get(mhu);
+		if (!IS_ERR(chan)) {
+			struct mhuv3_mbox_chan_priv *priv = chan->con_priv;
+
+			found++;
+			if (chan->cl) {
+				mbox_chan_txdone(chan, 0);
+				ret = IRQ_HANDLED;
+			} else {
+				dev_warn(dev,
+					 "TX Ack on UNBOUND channel (%u)\n",
+					 priv->ch_idx);
+			}
+		}
+	}
+
+	if (!found)
+		dev_warn_once(dev, "Failed to find channel for the TX interrupt\n");
+
+	return ret;
+}
+
+static irqreturn_t mhuv3_mbx_comb_interrupt(int irq, void *arg)
+{
+	int ret = IRQ_NONE;
+	unsigned int i, found = 0;
+	struct mhuv3 *mhu = arg;
+	struct device *dev = mhu->mbox.dev;
+	struct mbox_chan *chan;
+
+	for (i = FIRST_EXT; i < MAX_EXT; i++) {
+		if (!mhu->ext[i])
+			continue;
+
+		/* Process any extension which could be source of the IRQ */
+		chan = mhu->ext[i]->chan_from_comb_irq_get(mhu);
+		if (!IS_ERR(chan)) {
+			void *data = NULL;
+			struct mhuv3_mbox_chan_priv *priv = chan->con_priv;
+
+			found++;
+			/* Read and acknowledge optional in-band LE data first. */
+			if (priv->ops->read_data)
+				data = priv->ops->read_data(mhu, chan);
+
+			if (chan->cl && !IS_ERR(data)) {
+				mbox_chan_received_data(chan, data);
+				ret = IRQ_HANDLED;
+			} else if (!chan->cl) {
+				dev_warn(dev,
+					 "RX Data on UNBOUND channel (%u)\n",
+					 priv->ch_idx);
+			} else {
+				dev_err(dev, "Failed to read data: %lu\n",
+					PTR_ERR(data));
+			}
+
+			if (!IS_ERR(data))
+				kfree(data);
+
+			/*
+			 * Acknowledge transfer after any possible optional
+			 * out-of-band data has also been retrieved via
+			 * mbox_chan_received_data().
+			 */
+			if (priv->ops->rx_complete)
+				priv->ops->rx_complete(mhu, chan);
+		}
+	}
+
+	if (!found)
+		dev_warn_once(dev, "Failed to find channel for the RX interrupt\n");
+
+	return ret;
+}
+
+static int mhuv3_setup_pbx(struct mhuv3 *mhu)
+{
+	struct device *dev = mhu->mbox.dev;
+
+	mhu->mbox.ops = &mhuv3_sender_ops;
+
+	if (mhu->cmb_irq > 0) {
+		int ret;
+
+		ret = devm_request_threaded_irq(dev, mhu->cmb_irq, NULL,
+						mhuv3_pbx_comb_interrupt,
+						IRQF_ONESHOT, "mhuv3-pbx", mhu);
+		if (!ret) {
+			int i;
+
+			mhu->mbox.txdone_irq = true;
+			mhu->mbox.txdone_poll = false;
+
+			for (i = FIRST_EXT; i < MAX_EXT; i++)
+				if (mhu->ext[i])
+					mhu->ext[i]->combined_irq_setup(mhu);
+
+			dev_dbg(dev, "MHUv3 PBX IRQs initialized.\n");
+
+			return 0;
+		}
+
+		dev_err(dev, "Failed to request PBX IRQ - ret:%d", ret);
+	}
+
+	dev_info(dev, "Using PBX in Tx polling mode.\n");
+	mhu->mbox.txdone_irq = false;
+	mhu->mbox.txdone_poll = true;
+	mhu->mbox.txpoll_period = 1;
+
+	return 0;
+}
+
+static int mhuv3_setup_mbx(struct mhuv3 *mhu)
+{
+	int ret, i;
+	struct device *dev = mhu->mbox.dev;
+
+	mhu->mbox.ops = &mhuv3_receiver_ops;
+
+	if (mhu->cmb_irq <= 0) {
+		dev_err(dev, "Missing MBX combined IRQ !\n");
+		return -EINVAL;
+	}
+
+	ret = devm_request_threaded_irq(dev, mhu->cmb_irq, NULL,
+					mhuv3_mbx_comb_interrupt, IRQF_ONESHOT,
+					"mhuv3-mbx", mhu);
+	if (ret) {
+		dev_err(dev, "Failed to request MBX IRQ - ret:%d\n", ret);
+		return ret;
+	}
+
+	for (i = FIRST_EXT; i < MAX_EXT; i++)
+		if (mhu->ext[i])
+			mhu->ext[i]->combined_irq_setup(mhu);
+
+	dev_dbg(dev, "MHUv3 MBX IRQs initialized.\n");
+
+	return ret;
+}
+
+static int mhuv3_irqs_init(struct mhuv3 *mhu, struct platform_device *pdev)
+{
+	int ret;
+
+	dev_dbg(mhu->mbox.dev, "Initializing %s block.\n", mhuv3_str[mhu->frame]);
+
+	if (mhu->frame == PBX_FRAME) {
+		mhu->cmb_irq = platform_get_irq_byname_optional(pdev, "combined");
+		ret = mhuv3_setup_pbx(mhu);
+	} else {
+		mhu->cmb_irq = platform_get_irq_byname(pdev, "combined");
+		ret = mhuv3_setup_mbx(mhu);
+	}
+
+	return ret;
+}
+
+static int mhuv3_probe(struct platform_device *pdev)
+{
+	int ret;
+	struct mhuv3 *mhu;
+	void __iomem *regs;
+	struct device *dev = &pdev->dev;
+
+	mhu = devm_kzalloc(dev, sizeof(*mhu), GFP_KERNEL);
+	if (!mhu)
+		return -ENOMEM;
+
+	regs = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(regs))
+		return PTR_ERR(regs);
+
+	mhu->mbox.dev = dev;
+	ret = mhuv3_frame_init(mhu, regs);
+	if (ret)
+		return ret;
+
+	ret = mhuv3_irqs_init(mhu, pdev);
+	if (ret)
+		return ret;
+
+	mhu->mbox.of_xlate = mhuv3_mbox_of_xlate;
+	ret = mhuv3_initialize_channels(dev, mhu);
+	if (ret)
+		return ret;
+
+	ret = devm_mbox_controller_register(dev, &mhu->mbox);
+	if (ret)
+		dev_err(dev, "failed to register ARM MHUv3 driver %d\n", ret);
+
+	platform_set_drvdata(pdev, mhu);
+
+	return ret;
+}
+
+static int mhuv3_remove(struct platform_device *pdev)
+{
+	struct mhuv3 *mhu = platform_get_drvdata(pdev);
+
+	if (mhu->auto_op_full)
+		writel_relaxed_bitfield(0x0, &mhu->ctrl->ctrl, op_req);
+
+	return 0;
+}
+
+static const struct of_device_id mhuv3_of_match[] = {
+	{ .compatible = "arm,mhuv3", .data = NULL },
+	{}
+};
+MODULE_DEVICE_TABLE(of, mhuv3_of_match);
+
+static struct platform_driver mhuv3_driver = {
+	.driver = {
+		.name = "arm-mhuv3-mailbox",
+		.of_match_table = mhuv3_of_match,
+	},
+	.probe = mhuv3_probe,
+	.remove = mhuv3_remove,
+};
+module_platform_driver(mhuv3_driver);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("ARM MHUv3 Driver");
+MODULE_AUTHOR("Cristian Marussi <cristian.marussi@arm.com>");
-- 
2.34.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related

* [PATCH v2 1/2] dt-bindings: mailbox: arm,mhuv3: Add bindings
From: Cristian Marussi @ 2024-04-03 17:13 UTC (permalink / raw)
  To: linux-kernel, linux-arm-kernel, devicetree
  Cc: sudeep.holla, cristian.marussi, jassisinghbrar, robh+dt,
	krzysztof.kozlowski+dt, conor+dt
In-Reply-To: <20240403171346.3173843-1-cristian.marussi@arm.com>

Add bindings for the ARM MHUv3 Mailbox controller.

Signed-off-by: Cristian Marussi <cristian.marussi@arm.com>
---
v1 -> v2
- clarified extension descriptions around configurability and discoverability
- removed unused labels from the example
- using pattern properties to define interrupt-names
- bumped interrupt maxItems to 74 (allowing uo to 8 channels per extension)
---
 .../bindings/mailbox/arm,mhuv3.yaml           | 217 ++++++++++++++++++
 1 file changed, 217 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/mailbox/arm,mhuv3.yaml

diff --git a/Documentation/devicetree/bindings/mailbox/arm,mhuv3.yaml b/Documentation/devicetree/bindings/mailbox/arm,mhuv3.yaml
new file mode 100644
index 000000000000..d781045521da
--- /dev/null
+++ b/Documentation/devicetree/bindings/mailbox/arm,mhuv3.yaml
@@ -0,0 +1,217 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/mailbox/arm,mhuv3.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: ARM MHUv3 Mailbox Controller
+
+maintainers:
+  - Sudeep Holla <sudeep.holla@arm.com>
+  - Cristian Marussi <cristian.marussi@arm.com>
+
+description: |
+  The Arm Message Handling Unit (MHU) Version 3 is a mailbox controller that
+  enables unidirectional communications with remote processors through various
+  possible transport protocols.
+  The controller can optionally support a varying number of extensions that, in
+  turn, enable different kinds of transport to be used for communication.
+  Number, type and characteristics of each supported extension can be discovered
+  dynamically at runtime.
+
+  Given the unidirectional nature of the controller, an MHUv3 mailbox controller
+  is composed of a MHU Sender (MHUS) containing a PostBox (PBX) block and a MHU
+  Receiver (MHUR) containing a MailBox (MBX) block, where
+
+   PBX is used to
+      - Configure the MHU
+      - Send Transfers to the Receiver
+      - Optionally receive acknowledgment of a Transfer from the Receiver
+
+   MBX is used to
+      - Configure the MHU
+      - Receive Transfers from the Sender
+      - Optionally acknowledge Transfers sent by the Sender
+
+  Both PBX and MBX need to be present and defined in the DT description if you
+  need to establish a bidirectional communication, since you will have to
+  acquire two distinct unidirectional channels, one for each block.
+
+  As a consequence both blocks needs to be represented separately and specified
+  as distinct DT nodes in order to properly describe their resources.
+
+  Note that, though, thanks to the runtime discoverability, there is no need to
+  identify the type of blocks with distinct compatibles.
+
+  Following are the MHUv3 possible extensions.
+
+  - Doorbell Extension (DBE): DBE defines a type of channel called a Doorbell
+    Channel (DBCH). DBCH enables a single bit Transfer to be sent from the
+    Sender to Receiver. The Transfer indicates that an event has occurred.
+    When DBE is implemented, the number of DBCHs that an implementation of the
+    MHU can support is between 1 and 128, numbered starting from 0 in ascending
+    order and discoverable at run-time.
+    Each DBCH contains 32 individual fields, referred to as flags, each of which
+    can be used independently. It is possible for the Sender to send multiple
+    Transfers at once using a single DBCH, so long as each Transfer uses
+    a different flag in the DBCH.
+    Optionally, data may be transmitted through an out-of-band shared memory
+    region, wherein the MHU Doorbell is used strictly as an interrupt generation
+    mechanism, but this is out of the scope of these bindings.
+
+  - FastChannel Extension (FCE): FCE defines a type of channel called a Fast
+    Channel (FCH). FCH is intended for lower overhead communication between
+    Sender and Receiver at the expense of determinism. An FCH allows the Sender
+    to update the channel value at any time, regardless of whether the previous
+    value has been seen by the Receiver. When the Receiver reads the channel's
+    content it gets the last value written to the channel.
+    FCH is considered lossy in nature, and means that the Sender has no way of
+    knowing if, or when, the Receiver will act on the Transfer.
+    FCHs are expected to behave as RAM which generates interrupts when writes
+    occur to the locations within the RAM.
+    When FCE is implemented, the number of FCHs that an implementation of the
+    MHU can support is between 1-1024, if the FastChannel word-size is 32-bits,
+    or between 1-512, when the FastChannel word-size is 64-bits.
+    FCHs are numbered from 0 in ascending order.
+    Note that the number of FCHs and the word-size are implementation defined,
+    not configurable but discoverable at run-time.
+    Optionally, data may be transmitted through an out-of-band shared memory
+    region, wherein the MHU FastChannel is used as an interrupt generation
+    mechanism which carries also a pointer to such out-of-band data, but this
+    is out of the scope of these bindings.
+
+  - FIFO Extension (FE): FE defines a Channel type called a FIFO Channel (FFCH).
+    FFCH allows a Sender to send
+       - Multiple Transfers to the Receiver without having to wait for the
+	 previous Transfer to be acknowledged by the Receiver, as long as the
+	 FIFO has room for the Transfer.
+       - Transfers which require the Receiver to provide acknowledgment.
+       - Transfers which have in-band payload.
+    In all cases, the data is guaranteed to be observed by the Receiver in the
+    same order which the Sender sent it.
+    When FE is implemented, the number of FFCHs that an implementation of the
+    MHU can support is between 1 and 64, numbered starting from 0 in ascending
+    order. The number of FFCHs, their depth (same for all implemented FFCHs) and
+    the access-granularity are implementation defined, not configurable but
+    discoverable at run-time.
+    Optionally, additional data may be transmitted through an out-of-band shared
+    memory region, wherein the MHU FIFO is used to transmit, in order, a small
+    part of the payload (like a header) and a reference to the shared memory
+    area holding the remaining, bigger, chunk of the payload, but this is out of
+    the scope of these bindings.
+
+properties:
+  compatible:
+    const: arm,mhuv3
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    minItems: 1
+    maxItems: 74
+
+  interrupt-names:
+    description: |
+      The MHUv3 controller generates a number of events some of which are used
+      to generate interrupts; as a consequence it can expose a varying number of
+      optional PBX/MBX interrupts, representing the events generated during the
+      operation of the various transport protocols associated with different
+      extensions. All interrupts of the MHU are level-sensitive.
+      Some of these optional interrupts are defined per-channel, where the
+      number of channels effectively available is implementation defined and
+      run-time discoverable.
+      In the following names are enumerated using patterns, with per-channel
+      interrupts implicitly capped at the maximum channels allowed by the
+      specification for each extension type.
+      For the sake of simplicity maxItems is anyway capped to a most plausible
+      number, assuming way less channels would be implemented than actually
+      possible.
+
+      The only mandatory interrupts on the MHU are:
+        - combined
+        - mbx-fch-xfer-<N> but only if mbx-fcgrp-xfer-<N> is not implemented.
+
+    minItems: 1
+    maxItems: 74
+    items:
+      oneOf:
+        - const: combined
+          description: PBX/MBX Combined interrupt
+        - const: combined-ffch
+          description: PBX/MBX FIFO Combined interrupt
+        - pattern: '^ffch-low-tide-[0-9]+$'
+          description: PBX/MBX FIFO Channel <N> Low Tide interrupt
+        - pattern: '^ffch-high-tide-[0-9]+$'
+          description: PBX/MBX FIFO Channel <N> High Tide interrupt
+        - pattern: '^ffch-flush-[0-9]+$'
+          description: PBX/MBX FIFO Channel <N> Flush interrupt
+        - pattern: '^mbx-dbch-xfer-[0-9]+$'
+          description: MBX Doorbell Channel <N> Transfer interrupt
+        - pattern: '^mbx-fch-xfer-[0-9]+$'
+          description: MBX FastChannel <N> Transfer interrupt
+        - pattern: '^mbx-fchgrp-xfer-[0-9]+$'
+          description: MBX FastChannel <N> Group Transfer interrupt
+        - pattern: '^mbx-ffch-xfer-[0-9]+$'
+          description: MBX FIFO Channel <N> Transfer interrupt
+        - pattern: '^pbx-dbch-xfer-ack-[0-9]+$'
+          description: PBX Doorbell Channel <N> Transfer Ack interrupt
+        - pattern: '^pbx-ffch-xfer-ack-[0-9]+$'
+          description: PBX FIFO Channel <N> Transfer Ack interrupt
+
+  '#mbox-cells':
+    description: |
+      The first argument in the consumers 'mboxes' property represents the
+      extension type, the second is for the channel number while the third
+      depends on extension type.
+
+      Extension type for DBE is 0 and the third parameter represents the
+      doorbell flag number to use.
+      Extension type for FCE is 1, third parameter unused.
+      Extension type for FE is 2, third parameter unused.
+
+      mboxes = <&mhu 0 0 5>; // DBE, Doorbell Channel Window 0, doorbell flag 5.
+      mboxes = <&mhu 0 1 7>; // DBE, Doorbell Channel Window 1, doorbell flag 7.
+      mboxes = <&mhu 1 0 0>; // FCE, FastChannel Window 0.
+      mboxes = <&mhu 1 3 0>; // FCE, FastChannel Window 3.
+      mboxes = <&mhu 2 1 0>; // FE, FIFO Channel Window 1.
+      mboxes = <&mhu 2 7 0>; // FE, FIFO Channel Window 7.
+    const: 3
+
+  clocks:
+    maxItems: 1
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - interrupt-names
+  - '#mbox-cells'
+
+additionalProperties: false
+
+examples:
+  - |
+    soc {
+        #address-cells = <2>;
+        #size-cells = <2>;
+
+        mailbox@2aaa0000 {
+            compatible = "arm,mhuv3";
+            #mbox-cells = <3>;
+            reg = <0 0x2aaa0000 0 0x10000>;
+            clocks = <&clock 0>;
+            interrupt-names = "combined", "pbx-dbch-xfer-ack-1",
+                               "ffch-high-tide-0";
+            interrupts = <0 36 4>, <0 37 4>;
+        };
+
+        mailbox@2ab00000 {
+            compatible = "arm,mhuv3";
+            #mbox-cells = <3>;
+            reg = <0 0x2aab0000 0 0x10000>;
+            clocks = <&clock 0>;
+            interrupt-names = "combined", "mbx-dbch-xfer-1", "ffch-low-tide-0";
+            interrupts = <0 35 4>, <0 38 4>, <0 39 4>;
+        };
+    };
-- 
2.34.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related

* [PATCH v2 0/2] Add initial ARM MHUv3 mailbox support
From: Cristian Marussi @ 2024-04-03 17:13 UTC (permalink / raw)
  To: linux-kernel, linux-arm-kernel, devicetree
  Cc: sudeep.holla, cristian.marussi, jassisinghbrar, robh+dt,
	krzysztof.kozlowski+dt, conor+dt

Hi,

This series adds support for the new ARM Message Handling Unit v3 mailbox
controller [1].

The ARM MHUv3 can optionally support various extensions, enabling the
usage of different transport protocols.

Patch [2/2] adds a platform driver which, as of now, provides support only
for the Doorbell extension using the combined interrupt.

On the other side, bindings in [1/2] are introduced for all the extensions
described by the specification, as long as they are of interest to an
entity running from Normal world, like Linux: as such, Doorbell, FIFO and
FastChannel extensions are documented.

In these regards, note that the ARM MHUv3 controller can optionally
implement a considerable number of interrupts to express a great deal of
events and many of such interrupts are defined as being per-channel: with
the total maximum amount of possibly implemented channels across all
extensions being 1216 (1024+128+64), it would mean *a lot* of
interrupt-names to enumerate in the bindings.

For the sake of simplicity the binding as of now only introduces interrupt
names for a mere 8-channels in the range (0,7) for each per-channel
interrupt type: the idea is to leave open the possibility to add more to
this list of numbered items only when (and if) new real HW appears that
effectively needs more than 8 channels. (like AMBA, where the maximum
number of IRQ was progressively increased when needed, AFAIU).

Based on v6.9-rc1, tested on ARM TCS23 [2]
(TCS23 reference SW stack is still to be made fully publicly available)

Thanks,
Cristian

[1]: https://developer.arm.com/documentation/aes0072/aa/?lang=en
[2]: https://community.arm.com/arm-community-blogs/b/tools-software-ides-blog/posts/total-compute-solutions-platform-software-stack-and-fvp


---
v1 -> v2
 - clarified DT bindings extension descriptions around configurability
   and discoverability
 - removed unused labels from the DT example
 - using pattern properties to define DT interrupt-names
 - bumped DT interrupt maxItems to 74 (allowing uo to 8 channels per extension)
 - fixed checkpatch warnings about side-effects on write/read bitfield macros
 - fixed sparse errors as reported
   | Reported-by: kernel test robot <lkp@intel.com>
   | Closes: https://lore.kernel.org/oe-kbuild-all/202403290015.tCLXudqC-lkp@intel.com/

Cristian Marussi (2):
  dt-bindings: mailbox: arm,mhuv3: Add bindings
  mailbox: arm_mhuv3: Add driver

 .../bindings/mailbox/arm,mhuv3.yaml           |  217 ++++
 MAINTAINERS                                   |    9 +
 drivers/mailbox/Kconfig                       |   11 +
 drivers/mailbox/Makefile                      |    2 +
 drivers/mailbox/arm_mhuv3.c                   | 1063 +++++++++++++++++
 5 files changed, 1302 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/mailbox/arm,mhuv3.yaml
 create mode 100644 drivers/mailbox/arm_mhuv3.c

-- 
2.34.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply

* Re: (subset) [PATCH v2 0/9] spi: pxa2xx: Drop linux/spi/pxa2xx_spi.h
From: Andy Shevchenko @ 2024-04-03 17:13 UTC (permalink / raw)
  To: Mark Brown
  Cc: linux-spi, linux-kernel, linux-arm-kernel, Daniel Mack,
	Haojian Zhuang, Robert Jarzmik, Russell King, Arnd Bergmann
In-Reply-To: <48793ea5-92ca-4529-bad0-35d8c4e3f0c8@sirena.org.uk>

On Wed, Apr 03, 2024 at 04:50:00PM +0100, Mark Brown wrote:
> On Wed, Apr 03, 2024 at 05:41:30PM +0300, Andy Shevchenko wrote:
> 
> > Linus was long time ago against board files. Yet, we have a few old
> > (kinda supported) boards left in the tree. The conversion makes the
> > driver be prepared for the DT conversion when it happens. From maintenance
> > perspective my patch reduced the code under the maintenance, which reduces
> > time spent by both contributors and maintainers on this.
> 
> > AFAIU all what you are moaning about is type checking. Okay, I got
> 
> The type checking is part of it, but it's more a general taste thing
> with using swnodes like this.  You've not actually removed the board
> file and it's hard to get enthusiastic about the change to the board
> file that results, or to see this as a substantial step towards DT
> conversion for the platform given the trivialness of the single
> property here.  As a general thing I don't want to encourage people to
> start randomly converting things to swnode rather than to DT.

Conversion to GPIO lookup tables is also the same in this sense.
But with it in place, the drivers aren't needed to be touched
when the real conversion happens. I agree, that _ideally_ we should
take that shot, but I am not an expert in DT and it will take a lot
for me to get to the shape, besides the fact of the ARM (platform)
specifics, which I'm far from. So, I prefer do step-by-step approach
if one developer can't fulfill the task. I.o.w. perfect is enemy of
good.

> > it, but we have a lot of other places with similar approach done,
> > e.g. GPIO_LOOKUP*() tables that basically gives something unconnected to the
> > driver without any platform data being involved and you seems to be fine with
> > that:
> 
> > $ git log --oneline --no-merges --grep 'Mark Brown' -- arch/ | grep 'GPIO desc'
> 
> > I randomly took this 366f36e2a ("ASoC: wm1250-ev1: Convert to GPIO descriptors").
> 
> > Can you tell how it is different to my proposal?
> 
> The main difference with the GPIO lookup tables is that they are
> structured data specifically for GPIOs rather than the general purpose
> free for all we have with swnode.

Semantically yes, technically they have all the same issues you pointed out
that swnode has.

Nevertheless, I'm about to send a part 2 of cleanup (I decided not mangle
this series, so it will be on top of this) for you to see how we can go
forward.

And thank you for this discussion.

-- 
With Best Regards,
Andy Shevchenko



_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply

* Re: [PATCH v2] dt-bindings: watchdog: aspeed,ast2400-wdt: Convert to DT schema
From: Rob Herring @ 2024-04-03 17:13 UTC (permalink / raw)
  To: Andrew Jeffery
  Cc: wim, linux, krzysztof.kozlowski+dt, conor+dt, joel, zev,
	linux-watchdog, devicetree, linux-arm-kernel, linux-aspeed,
	linux-kernel
In-Reply-To: <20240403020439.418788-1-andrew@codeconstruct.com.au>

On Wed, Apr 03, 2024 at 12:34:39PM +1030, Andrew Jeffery wrote:
> Squash warnings such as:
> 
> ```
> arch/arm/boot/dts/aspeed/aspeed-bmc-facebook-galaxy100.dtb: /ahb/apb@1e600000/watchdog@1e785000: failed to match any schema with compatible: ['aspeed,ast2400-wdt']
> ```
> 
> The schema binding additionally defines the clocks property over the
> prose binding to align with use of the node in the DTS files.
> 
> Signed-off-by: Andrew Jeffery <andrew@codeconstruct.com.au>
> ---
> v2: Address feedback from Rob and Zev
> 
>     - Rob: https://lore.kernel.org/linux-watchdog/20240402180718.GA358505-robh@kernel.org/
>     - Zev: https://lore.kernel.org/linux-watchdog/65722a59-2e94-4616-81e1-835615b0e600@hatter.bewilderbeest.net/
> 
> v1: https://lore.kernel.org/linux-watchdog/20240402120118.282035-1-andrew@codeconstruct.com.au/
> 
>  .../bindings/watchdog/aspeed,ast2400-wdt.yaml | 142 ++++++++++++++++++
>  .../bindings/watchdog/aspeed-wdt.txt          |  73 ---------
>  2 files changed, 142 insertions(+), 73 deletions(-)
>  create mode 100644 Documentation/devicetree/bindings/watchdog/aspeed,ast2400-wdt.yaml
>  delete mode 100644 Documentation/devicetree/bindings/watchdog/aspeed-wdt.txt
> 
> diff --git a/Documentation/devicetree/bindings/watchdog/aspeed,ast2400-wdt.yaml b/Documentation/devicetree/bindings/watchdog/aspeed,ast2400-wdt.yaml
> new file mode 100644
> index 000000000000..be78a9865584
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/watchdog/aspeed,ast2400-wdt.yaml
> @@ -0,0 +1,142 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/watchdog/aspeed,ast2400-wdt.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Aspeed watchdog timer controllers
> +
> +maintainers:
> +  - Andrew Jeffery <andrew@codeconstruct.com.au>
> +
> +properties:
> +  compatible:
> +    enum:
> +      - aspeed,ast2400-wdt
> +      - aspeed,ast2500-wdt
> +      - aspeed,ast2600-wdt
> +
> +  reg:
> +    maxItems: 1
> +
> +  clocks:
> +    maxItems: 1
> +    description: >

You don't need '>' either. I guess it is equivalent here as there are no 
double newlines. Drop these if you respin, otherwise:

Reviewed-by: Rob Herring <robh@kernel.org>

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply

* [PATCH v3 10/10] perf/thunderx2: Avoid placing cpumask on the stack
From: Dawei Li @ 2024-04-03 15:59 UTC (permalink / raw)
  To: will, mark.rutland, yury.norov, linux
  Cc: xueshuai, renyu.zj, yangyicong, jonathan.cameron, andersson,
	konrad.dybcio, linux-arm-kernel, linux-kernel, linux-arm-msm,
	Dawei Li
In-Reply-To: <20240403155950.2068109-1-dawei.li@shingroup.cn>

In general it's preferable to avoid placing cpumasks on the stack, as
for large values of NR_CPUS these can consume significant amounts of
stack space and make stack overflows more likely.

Use cpumask_any_and_but() to avoid the need for a temporary cpumask on
the stack.

Suggested-by: Mark Rutland <mark.rutland@arm.com>
Reviewed-by: Mark Rutland <mark.rutland@arm.com>
Signed-off-by: Dawei Li <dawei.li@shingroup.cn>
---
 drivers/perf/thunderx2_pmu.c | 10 +++-------
 1 file changed, 3 insertions(+), 7 deletions(-)

diff --git a/drivers/perf/thunderx2_pmu.c b/drivers/perf/thunderx2_pmu.c
index e16d10c763de..b3377b662ffc 100644
--- a/drivers/perf/thunderx2_pmu.c
+++ b/drivers/perf/thunderx2_pmu.c
@@ -932,9 +932,8 @@ static int tx2_uncore_pmu_online_cpu(unsigned int cpu,
 static int tx2_uncore_pmu_offline_cpu(unsigned int cpu,
 		struct hlist_node *hpnode)
 {
-	int new_cpu;
 	struct tx2_uncore_pmu *tx2_pmu;
-	struct cpumask cpu_online_mask_temp;
+	unsigned int new_cpu;
 
 	tx2_pmu = hlist_entry_safe(hpnode,
 			struct tx2_uncore_pmu, hpnode);
@@ -945,11 +944,8 @@ static int tx2_uncore_pmu_offline_cpu(unsigned int cpu,
 	if (tx2_pmu->hrtimer_callback)
 		hrtimer_cancel(&tx2_pmu->hrtimer);
 
-	cpumask_copy(&cpu_online_mask_temp, cpu_online_mask);
-	cpumask_clear_cpu(cpu, &cpu_online_mask_temp);
-	new_cpu = cpumask_any_and(
-			cpumask_of_node(tx2_pmu->node),
-			&cpu_online_mask_temp);
+	new_cpu = cpumask_any_and_but(cpumask_of_node(tx2_pmu->node),
+				      cpu_online_mask, cpu);
 
 	tx2_pmu->cpu = new_cpu;
 	if (new_cpu >= nr_cpu_ids)
-- 
2.27.0


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox