* Re: [PATCH v3 1/5] ARM: dts: rockchip: move rk3288-veryon display settings into a separate file
From: Heiko Stuebner @ 2019-07-25 20:45 UTC (permalink / raw)
To: Matthias Kaehlcke
Cc: Rob Herring, Mark Rutland, devicetree, linux-arm-kernel,
linux-rockchip, linux-kernel
In-Reply-To: <20190725162642.250709-2-mka@chromium.org>
Am Donnerstag, 25. Juli 2019, 18:26:38 CEST schrieb Matthias Kaehlcke:
> The chromebook .dtsi file contains common settings for veyron
> Chromebooks with eDP displays. Some veyron devices with a display
> aren't Chromebooks (e.g. 'tiger' aka 'AOpen Chromebase Mini'), move
> display related bits from the chromebook .dtsi into a separate file
> to avoid redundant DT settings.
>
> The new file is included from the chromebook .dtsi and can be
> included by non-Chromebook devices with a display.
>
> Signed-off-by: Matthias Kaehlcke <mka@chromium.org>
applied for 5.4
Thanks
Heiko
^ permalink raw reply
* Re: [PATCH] ARM: dts: rockchip: Limit WiFi TX power on rk3288-veyron-jerry
From: Heiko Stuebner @ 2019-07-25 20:23 UTC (permalink / raw)
To: Matthias Kaehlcke
Cc: Rob Herring, Mark Rutland, linux-arm-kernel, linux-rockchip,
devicetree, linux-kernel, Douglas Anderson
In-Reply-To: <20190723225258.93058-1-mka@chromium.org>
Am Mittwoch, 24. Juli 2019, 00:52:58 CEST schrieb Matthias Kaehlcke:
> The downstream Chrome OS 3.14 kernel for jerry limits WiFi TX power
> through calibration data in the device tree [1]. Add a DT node for
> the WiFi chip and use the downstream calibration data.
>
> Not all calibration data entries have the length specified in the
> binding (Documentation/devicetree/bindings/net/wireless/marvell-8xxx.txt),
> however this is the data used by the downstream ('official') kernel
> and the binding mentions that "the length can vary between hw
> versions".
>
> [1] https://crrev.com/c/271237
>
> Signed-off-by: Matthias Kaehlcke <mka@chromium.org>
> ---
> arch/arm/boot/dts/rk3288-veyron-jerry.dts | 147 ++++++++++++++++++++++
> 1 file changed, 147 insertions(+)
>
> diff --git a/arch/arm/boot/dts/rk3288-veyron-jerry.dts b/arch/arm/boot/dts/rk3288-veyron-jerry.dts
> index b1613af83d5d..2d0d5a4603ba 100644
> --- a/arch/arm/boot/dts/rk3288-veyron-jerry.dts
> +++ b/arch/arm/boot/dts/rk3288-veyron-jerry.dts
> @@ -82,6 +82,153 @@
> };
> };
>
> +&sdio0 {
added #address-cells = <1> and #size-cells = <0> here
as it was creating dtc warnings due to the reg=1 below
> + mwifiex: wifi@1 {
> + compatible = "marvell,sd8897";
> + reg = <1>;
> + status = "okay";
dropped status ... okay is the default and the wifi node only was
added to this board, not before.
and applied for 5.4
Thanks
Heiko
^ permalink raw reply
* Re: [PATCH v9 04/18] kunit: test: add kunit_stream a std::stream like logger
From: Brendan Higgins @ 2019-07-25 20:21 UTC (permalink / raw)
To: Petr Mladek
Cc: Stephen Boyd, Jeff Dike, Kevin Hilman, Logan Gunthorpe,
Michael Ellerman, Daniel Vetter, Amir Goldstein, Frank Rowand,
Steven Rostedt, Kees Cook, David Rientjes, kunit-dev,
Kieran Bingham, Peter Zijlstra, Randy Dunlap, Joel Stanley,
Luis Chamberlain, Rob Herring, shuah, wfg, Greg KH
In-Reply-To: <20190724073125.xyzfywctrcvg6fmh@pathway.suse.cz>
On Wed, Jul 24, 2019 at 12:31 AM Petr Mladek <pmladek@suse.com> wrote:
>
> On Mon 2019-07-22 16:54:10, Stephen Boyd wrote:
> > Quoting Brendan Higgins (2019-07-22 15:30:49)
> > > On Mon, Jul 22, 2019 at 1:03 PM Stephen Boyd <sboyd@kernel.org> wrote:
> > > >
> > > >
> > > > What's the calling context of the assertions and expectations? I still
> > > > don't like the fact that string stream needs to allocate buffers and
> > > > throw them into a list somewhere because the calling context matters
> > > > there.
> > >
> > > The calling context is the same as before, which is anywhere.
> >
> > Ok. That's concerning then.
> >
> > >
> > > > I'd prefer we just wrote directly to the console/log via printk
> > > > instead. That way things are simple because we use the existing
> > > > buffering path of printk, but maybe there's some benefit to the string
> > > > stream that I don't see? Right now it looks like it builds a string and
> > > > then dumps it to printk so I'm sort of lost what the benefit is over
> > > > just writing directly with printk.
> > >
> > > It's just buffering it so the whole string gets printed uninterrupted.
> > > If we were to print out piecemeal to printk, couldn't we have another
> > > call to printk come in causing it to garble the KUnit message we are
> > > in the middle of printing?
> >
> > Yes, printing piecemeal by calling printk many times could lead to
> > interleaving of messages if something else comes in such as an interrupt
> > printing something. Printk has some support to hold "records" but I'm
> > not sure how that would work here because KERN_CONT talks about only
> > being used early on in boot code. I haven't looked at printk in detail
> > though so maybe I'm all wrong and KERN_CONT just works?
>
> KERN_CONT does not guarantee that the message will get printed
> together. The pieces get interleaved with messages printed in
> parallel.
>
> Note that KERN_CONT was originally really meant to be used only during
> boot. It was later used more widely and ended in the best effort category.
>
> There were several attempts to make it more reliable. But it was
> always either too complicated or error prone or both.
>
> You need to use your own buffering if you rely want perfect output.
> The question is if it is really worth the complexity. Also note that
> any buffering reduces the chance that the messages will reach
> the console.
Seems like that settles it then. Thanks!
> BTW: There is a work in progress on a lockless printk ring buffer.
> It will make printk() more secure regarding deadlocks. But it might
> make transparent handling of continuous lines even more tricky.
>
> I guess that local buffering, before calling printk(), will be
> even more important then. Well, it might really force us to create
> an API for it.
Cool! Can you CC me on that discussion?
> > Can printk be called once with whatever is in the struct? Otherwise if
> > this is about making printk into a structured log then maybe printk
> > isn't the proper solution anyway. Maybe a dev interface should be used
> > instead that can handle starting and stopping tests (via ioctl) in
> > addition to reading test results, records, etc. with read() and a
> > clearing of the records. Then the seqfile API works naturally. All of
> > this is a bit premature, but it looks like you're going down the path of
> > making something akin to ftrace that stores binary formatted
> > assertion/expectation records in a lockless ring buffer that then
> > formats those records when the user asks for them.
>
> IMHO, ftrace postpones the text formatting primary because it does not
> not want to slow down the traced code more than necessary. It is yet
> another layer and there should be some strong reason for it.
Noted. Yeah, I would prefer avoiding printing out the info at a separate time.
> > I can imagine someone wanting to write unit tests that check conditions
> > from a simulated hardirq context via irq works (a driver mock
> > framework?), so this doesn't seem far off.
>
> Note that stroring the messages into the printk log is basically safe in any
> context. It uses temporary per-CPU buffers for recursive messages and
> in NMI. The only problem is panic() when some CPU gets stuck with the
> lock taken. This will get solved by the lockless ringbuffer. Also
> the temporary buffers will not be necessary any longer.
Sure, I think Stephen's concern is all the supporting code that is
involved. Not printk specifically. It just means a lot more of KUnit
has to be IRQ safe.
> Much bigger problems are with consoles. There are many of them. It
> means a lot of code and more locks involved, including scheduler
> locks. Note that console lock is a semaphore.
That shouldn't affect us though, right? As long as we continue to use
the printk interface?
^ permalink raw reply
* Re: [v4 1/6] dt-bindings: media: Document bindings for DW MIPI CSI-2 Host
From: Sakari Ailus @ 2019-07-25 20:02 UTC (permalink / raw)
To: Luis de Oliveira
Cc: mchehab@kernel.org, davem@davemloft.net,
gregkh@linuxfoundation.org, Jonathan.Cameron@huawei.com,
robh@kernel.org, nicolas.ferre@microchip.com,
paulmck@linux.ibm.com, mark.rutland@arm.com, kishon@ti.com,
devicetree@vger.kernel.org, linux-media@vger.kernel.org,
linux-kernel@vger.kernel.org, Joao.Pinto@synopsys.com
In-Reply-To: <MN2PR12MB371026A6547B449EEC0439B1CBF00@MN2PR12MB3710.namprd12.prod.outlook.com>
Hi Luis,
On Wed, Jul 10, 2019 at 10:20:55AM +0000, Luis de Oliveira wrote:
> Hi Sakari,
>
> From: Sakari Ailus <sakari.ailus@iki.fi>
> Date: Tue, Jul 09, 2019 at 19:25:00
>
> > Hi Luis,
> >
> > On Mon, Jul 08, 2019 at 03:21:50PM +0000, Luis de Oliveira wrote:
> > > Hi Sakari,
> > >
> > > Thank you for your feedback.
> > > I have my comments inline.
> > >
> > > From: Sakari Ailus <sakari.ailus@iki.fi>
> > > Date: Fri, Jun 28, 2019 at 15:13:26
> > >
> > > > Hi Luis,
> > > >
> > > > Thank you for the patchset.
> > > >
> > > > On Tue, Jun 11, 2019 at 09:20:50PM +0200, Luis Oliveira wrote:
> > > > > From: Luis Oliveira <lolivei@synopsys.com>
> > > > >
> > > > > Add bindings for Synopsys DesignWare MIPI CSI-2 host.
> > > > >
> > > > > Signed-off-by: Luis Oliveira <lolivei@synopsys.com>
> > > > > ---
> > > > > Changelog
> > > > > v3-v4
> > > > > - remove "plat" from the block name @rob @laurent
> > > > > - remove "phy-names" when single-entry @rob
> > > > > - remove "snps,output-type" -> went to the driver config @laurent
> > > > >
> > > > > .../devicetree/bindings/media/snps,dw-csi.txt | 41 ++++++++++++++++++++++
> > > > > 1 file changed, 41 insertions(+)
> > > > > create mode 100644 Documentation/devicetree/bindings/media/snps,dw-csi.txt
> > > > >
> > > > > diff --git a/Documentation/devicetree/bindings/media/snps,dw-csi.txt b/Documentation/devicetree/bindings/media/snps,dw-csi.txt
> > > > > new file mode 100644
> > > > > index 0000000..613b7f9
> > > > > --- /dev/null
> > > > > +++ b/Documentation/devicetree/bindings/media/snps,dw-csi.txt
> > > > > @@ -0,0 +1,41 @@
> > > > > +Synopsys DesignWare CSI-2 Host controller
> > > > > +
> > > > > +Description
> > > > > +-----------
> > > > > +
> > > > > +This HW block is used to receive image coming from an MIPI CSI-2 compatible
> > > > > +camera.
> > > > > +
> > > > > +Required properties:
> > > > > +- compatible : shall be "snps,dw-csi"
> > > > > +- reg : physical base address and size of the device memory
> > > > > + mapped registers;
> > > > > +- interrupts : DW CSI-2 Host interrupts
> > > > > +- phys : List of one PHY specifier (as defined in
> > > > > + Documentation/devicetree/bindings/phy/phy-bindings.txt).
> > > > > + This PHY is a MIPI DPHY working in RX mode.
> > > > > +- resets : Reference to a reset controller (optional)
> > > > > +
> > > > > +The per-board settings:
> > > > > + - port sub-node describing a single endpoint connected to the camera as
> > > > > + described in video-interfaces.txt[1].
> > > >
> > > > Which endpoint properties in video-interfaces.txt are relevant for the
> > > > hardware? Which values may they have?
> > > >
> > >
> > > Currently I'm using only two properties "data-lanes" and "bus-width", but
> > > I have plans to add blanking info also.
> > > I will add more info.
> >
> > Isn't blanking defined by what the transmitter seneds? Or do you have
> > hardware limitations on the receiver side?
> >
>
> When we use this IP in prototyping we configure blanking at the receiver
> side.
> Some cameras don't have blanking configuration capabilities so we
> configure it on the RX side.
I haven't come across a CSI-2 connected camera without some kind of
blanking configuration capabilities. Even if there was one, you couldn't
configure blanking from the receiver side.
Please document that the data-lanes property is required, and which values
are possible.
>
> > I've only heard of one such case before, and it was a very old parallel
> > receiver.
> >
> > If you have a CSI-2 receiver, bus-width isn't relevant --- it's for paralle
> > interfaces only. Please add data-lanes to required endpoint properties.
> >
>
> I used bus-width property in the Synopsys IPI (Image Pixel Interface)
> that enables direct video stream access.
> This interface is an output that can be 16-bit or 48-bit, that's why I
> used bus-width property.
Does this device write the image data to system memory, or is it another
device? If there's another one, then you should probably have another port
to describe that connection.
--
Kind regards,
Sakari Ailus
^ permalink raw reply
* [PATCH 4/4] ARM64: dts: amlogic: adds crypto hardware node
From: Corentin Labbe @ 2019-07-25 19:42 UTC (permalink / raw)
To: davem, herbert, khilman, mark.rutland, robh+dt
Cc: devicetree, linux-amlogic, linux-arm-kernel, linux-crypto,
linux-kernel, baylibre-upstreaming, Corentin Labbe
In-Reply-To: <1564083776-20540-1-git-send-email-clabbe@baylibre.com>
This patch adds the GXL crypto hardware node for all GXL SoCs.
Signed-off-by: Corentin Labbe <clabbe@baylibre.com>
---
arch/arm64/boot/dts/amlogic/meson-gxl.dtsi | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi
index c959456bacc6..fdcda12a7113 100644
--- a/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi
@@ -36,6 +36,17 @@
phys = <&usb3_phy>, <&usb2_phy0>, <&usb2_phy1>;
};
};
+
+ crypto: crypto@c883e000 {
+ compatible = "amlogic,gxl-crypto";
+ reg = <0x0 0xc883e000 0x0 0x36>;
+ interrupts = <GIC_SPI 188 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 189 IRQ_TYPE_EDGE_RISING>;
+ clocks = <&clkc CLKID_BLKMV>;
+ clock-names = "blkmv";
+ status = "okay";
+ };
+
};
};
--
2.21.0
^ permalink raw reply related
* [PATCH 3/4] MAINTAINERS: Add myself as maintainer of amlogic crypto
From: Corentin Labbe @ 2019-07-25 19:42 UTC (permalink / raw)
To: davem, herbert, khilman, mark.rutland, robh+dt
Cc: devicetree, linux-amlogic, linux-arm-kernel, linux-crypto,
linux-kernel, baylibre-upstreaming, Corentin Labbe
In-Reply-To: <1564083776-20540-1-git-send-email-clabbe@baylibre.com>
I will maintain the amlogic crypto driver.
Signed-off-by: Corentin Labbe <clabbe@baylibre.com>
---
MAINTAINERS | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/MAINTAINERS b/MAINTAINERS
index 93d6cae3274d..48e7fd110688 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1450,6 +1450,13 @@ F: drivers/mmc/host/meson*
F: drivers/soc/amlogic/
N: meson
+ARM/Amlogic Meson SoC Crypto Drivers
+M: Corentin Labbe <clabbe@baylibre.com>
+L: linux-crypto@vger.kernel.org
+S: Maintained
+F: drivers/crypto/amlogic/
+F: Documentation/devicetree/bindings/crypto/amlogic*
+
ARM/Amlogic Meson SoC Sound Drivers
M: Jerome Brunet <jbrunet@baylibre.com>
L: alsa-devel@alsa-project.org (moderated for non-subscribers)
--
2.21.0
^ permalink raw reply related
* [PATCH 2/4] crypto: amlogic: Add crypto accelerator for amlogic GXL
From: Corentin Labbe @ 2019-07-25 19:42 UTC (permalink / raw)
To: davem, herbert, khilman, mark.rutland, robh+dt
Cc: devicetree, linux-amlogic, linux-arm-kernel, linux-crypto,
linux-kernel, baylibre-upstreaming, Corentin Labbe
In-Reply-To: <1564083776-20540-1-git-send-email-clabbe@baylibre.com>
This patch adds support for the amlogic GXL cryptographic offloader present
on GXL SoCs.
This driver supports AES cipher in CBC/ECB mode.
Signed-off-by: Corentin Labbe <clabbe@baylibre.com>
---
drivers/crypto/Kconfig | 2 +
drivers/crypto/Makefile | 1 +
drivers/crypto/amlogic/Kconfig | 24 ++
drivers/crypto/amlogic/Makefile | 2 +
drivers/crypto/amlogic/amlogic-cipher.c | 358 ++++++++++++++++++++++++
drivers/crypto/amlogic/amlogic-core.c | 326 +++++++++++++++++++++
drivers/crypto/amlogic/amlogic.h | 172 ++++++++++++
7 files changed, 885 insertions(+)
create mode 100644 drivers/crypto/amlogic/Kconfig
create mode 100644 drivers/crypto/amlogic/Makefile
create mode 100644 drivers/crypto/amlogic/amlogic-cipher.c
create mode 100644 drivers/crypto/amlogic/amlogic-core.c
create mode 100644 drivers/crypto/amlogic/amlogic.h
diff --git a/drivers/crypto/Kconfig b/drivers/crypto/Kconfig
index 8fd5352c6a29..51679c077ced 100644
--- a/drivers/crypto/Kconfig
+++ b/drivers/crypto/Kconfig
@@ -787,4 +787,6 @@ config CRYPTO_DEV_CCREE
source "drivers/crypto/hisilicon/Kconfig"
+source "drivers/crypto/amlogic/Kconfig"
+
endif # CRYPTO_HW
diff --git a/drivers/crypto/Makefile b/drivers/crypto/Makefile
index 90d60eff5ecc..1623bd8d20f6 100644
--- a/drivers/crypto/Makefile
+++ b/drivers/crypto/Makefile
@@ -49,3 +49,4 @@ obj-$(CONFIG_CRYPTO_DEV_BCM_SPU) += bcm/
obj-$(CONFIG_CRYPTO_DEV_SAFEXCEL) += inside-secure/
obj-$(CONFIG_CRYPTO_DEV_ARTPEC6) += axis/
obj-y += hisilicon/
+obj-$(CONFIG_CRYPTO_DEV_AMLOGIC_GXL) += amlogic/
diff --git a/drivers/crypto/amlogic/Kconfig b/drivers/crypto/amlogic/Kconfig
new file mode 100644
index 000000000000..9c4bf96afeb3
--- /dev/null
+++ b/drivers/crypto/amlogic/Kconfig
@@ -0,0 +1,24 @@
+config CRYPTO_DEV_AMLOGIC_GXL
+ tristate "Support for amlogic cryptographic offloader"
+ default y if ARCH_MESON
+ select CRYPTO_BLKCIPHER
+ select CRYPTO_ENGINE
+ select CRYPTO_ECB
+ select CRYPTO_CBC
+ select CRYPTO_AES
+ help
+ Select y here for having support for the cryptographic offloader
+ availlable on Amlogic GXL SoC.
+ This hardware handle AES ciphers in ECB/CBC mode.
+
+ To compile this driver as a module, choose M here: the module
+ will be called amlogic-crypto.
+
+config CRYPTO_DEV_AMLOGIC_GXL_DEBUG
+ bool "Enabled amlogic stats"
+ depends on CRYPTO_DEV_AMLOGIC_GXL
+ depends on DEBUG_FS
+ help
+ Say y to enabled amlogic-crypto debug stats.
+ This will create /sys/kernel/debug/gxl-crypto/stats for displaying
+ the number of requests per flow and per algorithm.
diff --git a/drivers/crypto/amlogic/Makefile b/drivers/crypto/amlogic/Makefile
new file mode 100644
index 000000000000..0ec472c5562e
--- /dev/null
+++ b/drivers/crypto/amlogic/Makefile
@@ -0,0 +1,2 @@
+obj-$(CONFIG_CRYPTO_DEV_AMLOGIC_GXL) += amlogic-crypto.o
+amlogic-crypto-y := amlogic-core.o amlogic-cipher.o
diff --git a/drivers/crypto/amlogic/amlogic-cipher.c b/drivers/crypto/amlogic/amlogic-cipher.c
new file mode 100644
index 000000000000..84e65b4e9ba9
--- /dev/null
+++ b/drivers/crypto/amlogic/amlogic-cipher.c
@@ -0,0 +1,358 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * amlogic-cipher.c - hardware cryptographic offloader for Amlogic GXL SoC
+ *
+ * Copyright (C) 2018-2019 Corentin LABBE <clabbe@baylibre.com>
+ *
+ * This file add support for AES cipher with 128,192,256 bits keysize in
+ * CBC and ECB mode.
+ */
+
+#include <linux/crypto.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <crypto/scatterwalk.h>
+#include <linux/scatterlist.h>
+#include <linux/dma-mapping.h>
+#include <crypto/internal/skcipher.h>
+#include "amlogic.h"
+
+static int get_engine_number(struct meson_dev *mc)
+{
+ return atomic_inc_return(&mc->flow) % MAXFLOW;
+}
+
+static int meson_cipher(struct skcipher_request *areq)
+{
+ struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(areq);
+ struct meson_cipher_tfm_ctx *op = crypto_skcipher_ctx(tfm);
+ struct meson_cipher_req_ctx *rctx = skcipher_request_ctx(areq);
+ struct meson_dev *mc = op->mc;
+ struct skcipher_alg *alg = crypto_skcipher_alg(tfm);
+ struct meson_alg_template *algt;
+ int flow = rctx->flow;
+ unsigned int todo, eat, len;
+ struct scatterlist *src_sg = areq->src;
+ struct scatterlist *dst_sg = areq->dst;
+ struct meson_desc *desc;
+ bool need_fallback = false;
+ int nr_sgs, nr_sgd;
+ int i, err = 0;
+ unsigned int keyivlen, ivsize, offset, tloffset;
+ dma_addr_t phykeyiv;
+ void *backup_iv = NULL, *bkeyiv;
+
+ algt = container_of(alg, struct meson_alg_template, alg.skcipher);
+
+ dev_dbg(mc->dev, "%s %s %u %x IV(%u) key=%u flow=%d\n", __func__,
+ crypto_tfm_alg_name(areq->base.tfm),
+ areq->cryptlen,
+ rctx->op_dir, crypto_skcipher_ivsize(tfm),
+ op->keylen, flow);
+
+ if (areq->cryptlen == 0)
+ need_fallback = true;
+
+ if (sg_nents(src_sg) != sg_nents(dst_sg))
+ need_fallback = true;
+
+ /* KEY/IV descriptors use 3 desc */
+ if (sg_nents(src_sg) > MAXDESC - 3 || sg_nents(dst_sg) > MAXDESC - 3)
+ need_fallback = true;
+
+ while (src_sg && dst_sg && !need_fallback) {
+ if ((src_sg->length % 16) != 0)
+ need_fallback = true;
+ if ((dst_sg->length % 16) != 0)
+ need_fallback = true;
+ if (src_sg->length != dst_sg->length)
+ need_fallback = true;
+ if (!IS_ALIGNED(src_sg->offset, sizeof(u32)))
+ need_fallback = true;
+ if (!IS_ALIGNED(dst_sg->offset, sizeof(u32)))
+ need_fallback = true;
+ src_sg = sg_next(src_sg);
+ dst_sg = sg_next(dst_sg);
+ }
+
+#ifdef CONFIG_CRYPTO_DEV_AMLOGIC_GXL_DEBUG
+ algt->stat_req++;
+#endif
+
+ if (need_fallback) {
+ SYNC_SKCIPHER_REQUEST_ON_STACK(req, op->fallback_tfm);
+#ifdef CONFIG_CRYPTO_DEV_AMLOGIC_GXL_DEBUG
+ algt->stat_fb++;
+#endif
+ skcipher_request_set_sync_tfm(req, op->fallback_tfm);
+ skcipher_request_set_callback(req, areq->base.flags, NULL,
+ NULL);
+ skcipher_request_set_crypt(req, areq->src, areq->dst,
+ areq->cryptlen, areq->iv);
+ if (rctx->op_dir == MESON_DECRYPT)
+ err = crypto_skcipher_decrypt(req);
+ else
+ err = crypto_skcipher_encrypt(req);
+ skcipher_request_zero(req);
+ return err;
+ }
+
+ /*
+ * The hardware expect a list of meson_desc structures.
+ * The 2 first structures store key
+ * The third stores IV
+ */
+ bkeyiv = kzalloc(48, GFP_KERNEL | GFP_DMA);
+ if (!bkeyiv)
+ return -ENOMEM;
+
+ memcpy(bkeyiv, op->key, op->keylen);
+ keyivlen = op->keylen;
+
+ ivsize = crypto_skcipher_ivsize(tfm);
+ if (areq->iv && ivsize > 0) {
+ if (ivsize > areq->cryptlen) {
+ dev_err(mc->dev, "invalid ivsize=%d vs len=%d\n", ivsize, areq->cryptlen);
+ return -EINVAL;
+ }
+ memcpy(bkeyiv + 32, areq->iv, ivsize);
+ keyivlen = 48;
+ if (rctx->op_dir == MESON_DECRYPT) {
+ backup_iv = kzalloc(ivsize, GFP_KERNEL);
+ if (!backup_iv) {
+ err = -ENOMEM;
+ goto theend;
+ }
+ offset = areq->cryptlen - ivsize;
+ scatterwalk_map_and_copy(backup_iv, areq->src, offset,
+ ivsize, 0);
+ }
+ }
+ if (keyivlen == 24)
+ keyivlen = 32;
+
+ phykeyiv = dma_map_single(mc->dev, bkeyiv, keyivlen,
+ DMA_TO_DEVICE);
+ if (dma_mapping_error(mc->dev, phykeyiv)) {
+ dev_err(mc->dev, "Cannot DMA MAP KEY IV\n");
+ return -EFAULT;
+ }
+
+ tloffset = 0;
+ eat = 0;
+ i = 0;
+ while (keyivlen > eat) {
+ desc = &mc->chanlist[flow].tl[tloffset];
+ memset(desc, 0, sizeof(struct meson_desc));
+ todo = min(keyivlen - eat, 16u);
+ desc->t_src = phykeyiv + i * 16;
+ desc->t_dst = i * 16;
+ desc->len = 16;
+ desc->mode = MODE_KEY;
+ desc->owner = 1;
+ eat += todo;
+ i++;
+ tloffset++;
+ }
+
+ if (areq->src == areq->dst) {
+ nr_sgs = dma_map_sg(mc->dev, areq->src, sg_nents(areq->src),
+ DMA_BIDIRECTIONAL);
+ if (nr_sgs < 0) {
+ dev_err(mc->dev, "Invalid SG count %d\n", nr_sgs);
+ err = -EINVAL;
+ goto theend;
+ }
+ nr_sgd = nr_sgs;
+ } else {
+ nr_sgs = dma_map_sg(mc->dev, areq->src, sg_nents(areq->src),
+ DMA_TO_DEVICE);
+ if (nr_sgs < 0 || nr_sgs > MAXDESC - 3) {
+ dev_err(mc->dev, "Invalid SG count %d\n", nr_sgs);
+ err = -EINVAL;
+ goto theend;
+ }
+ nr_sgd = dma_map_sg(mc->dev, areq->dst, sg_nents(areq->dst),
+ DMA_FROM_DEVICE);
+ if (nr_sgd < 0 || nr_sgd > MAXDESC - 3) {
+ dev_err(mc->dev, "Invalid SG count %d\n", nr_sgd);
+ err = -EINVAL;
+ goto theend;
+ }
+ }
+
+#ifdef CONFIG_CRYPTO_DEV_AMLOGIC_GXL_DEBUG
+ mc->chanlist[flow].stat_req++;
+#endif
+ src_sg = areq->src;
+ dst_sg = areq->dst;
+ len = areq->cryptlen;
+ while (src_sg) {
+ desc = &mc->chanlist[flow].tl[tloffset];
+ memset(desc, 0, sizeof(struct meson_desc));
+
+ desc->t_src = sg_dma_address(src_sg);
+ desc->t_dst = sg_dma_address(dst_sg);
+ todo = min(len, sg_dma_len(src_sg));
+ desc->owner = 1;
+ desc->len = todo;
+ desc->mode = op->keymode;
+ desc->op_mode = algt->blockmode;
+ desc->enc = rctx->op_dir;
+ len -= todo;
+
+ if (!sg_next(src_sg))
+ desc->eoc = 1;
+ tloffset++;
+ src_sg = sg_next(src_sg);
+ dst_sg = sg_next(dst_sg);
+ }
+
+ reinit_completion(&mc->chanlist[flow].complete);
+ mc->chanlist[flow].status = 0;
+ writel(mc->chanlist[flow].t_phy | 2, mc->base + (flow << 2));
+ wait_for_completion_interruptible_timeout(&mc->chanlist[flow].complete,
+ msecs_to_jiffies(500));
+ if (mc->chanlist[flow].status == 0) {
+ dev_err(mc->dev, "DMA timeout for flow %d\n", flow);
+ err = -EINVAL;
+ }
+
+ dma_unmap_single(mc->dev, phykeyiv, keyivlen, DMA_TO_DEVICE);
+
+ if (areq->src == areq->dst) {
+ dma_unmap_sg(mc->dev, areq->src, nr_sgs, DMA_BIDIRECTIONAL);
+ } else {
+ dma_unmap_sg(mc->dev, areq->src, nr_sgs, DMA_TO_DEVICE);
+ dma_unmap_sg(mc->dev, areq->dst, nr_sgd, DMA_FROM_DEVICE);
+ }
+
+ if (areq->iv && ivsize > 0) {
+ if (rctx->op_dir == MESON_DECRYPT) {
+ memcpy(areq->iv, backup_iv, ivsize);
+ kzfree(backup_iv);
+ } else {
+ scatterwalk_map_and_copy(areq->iv, areq->dst,
+ areq->cryptlen - ivsize,
+ ivsize, 0);
+ }
+ }
+theend:
+ kzfree(bkeyiv);
+
+ return err;
+}
+
+static int handle_cipher_request(struct crypto_engine *engine,
+ void *areq)
+{
+ int err;
+ struct skcipher_request *breq = container_of(areq, struct skcipher_request, base);
+
+ err = meson_cipher(breq);
+ crypto_finalize_skcipher_request(engine, breq, err);
+
+ return 0;
+}
+
+int meson_skdecrypt(struct skcipher_request *areq)
+{
+ struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(areq);
+ struct meson_cipher_tfm_ctx *op = crypto_skcipher_ctx(tfm);
+ struct meson_cipher_req_ctx *rctx = skcipher_request_ctx(areq);
+ int e = get_engine_number(op->mc);
+ struct crypto_engine *engine = op->mc->chanlist[e].engine;
+
+ rctx->op_dir = MESON_DECRYPT;
+ rctx->flow = e;
+
+ return crypto_transfer_skcipher_request_to_engine(engine, areq);
+}
+
+int meson_skencrypt(struct skcipher_request *areq)
+{
+ struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(areq);
+ struct meson_cipher_tfm_ctx *op = crypto_skcipher_ctx(tfm);
+ struct meson_cipher_req_ctx *rctx = skcipher_request_ctx(areq);
+ int e = get_engine_number(op->mc);
+ struct crypto_engine *engine = op->mc->chanlist[e].engine;
+
+ rctx->op_dir = MESON_ENCRYPT;
+ rctx->flow = e;
+
+ return crypto_transfer_skcipher_request_to_engine(engine, areq);
+}
+
+int meson_cipher_init(struct crypto_tfm *tfm)
+{
+ struct meson_cipher_tfm_ctx *op = crypto_tfm_ctx(tfm);
+ struct meson_alg_template *algt;
+ const char *name = crypto_tfm_alg_name(tfm);
+ struct crypto_skcipher *sktfm = __crypto_skcipher_cast(tfm);
+ struct skcipher_alg *alg = crypto_skcipher_alg(sktfm);
+
+ memset(op, 0, sizeof(struct meson_cipher_tfm_ctx));
+
+ algt = container_of(alg, struct meson_alg_template, alg.skcipher);
+ op->mc = algt->mc;
+
+ sktfm->reqsize = sizeof(struct meson_cipher_req_ctx);
+
+ op->fallback_tfm = crypto_alloc_sync_skcipher(name, 0, CRYPTO_ALG_NEED_FALLBACK);
+ if (IS_ERR(op->fallback_tfm)) {
+ dev_err(op->mc->dev, "ERROR: Cannot allocate fallback for %s %ld\n",
+ name, PTR_ERR(op->fallback_tfm));
+ return PTR_ERR(op->fallback_tfm);
+ }
+
+ op->enginectx.op.do_one_request = handle_cipher_request;
+ op->enginectx.op.prepare_request = NULL;
+ op->enginectx.op.unprepare_request = NULL;
+
+ return 0;
+}
+
+void meson_cipher_exit(struct crypto_tfm *tfm)
+{
+ struct meson_cipher_tfm_ctx *op = crypto_tfm_ctx(tfm);
+
+ if (op->key) {
+ memzero_explicit(op->key, op->keylen);
+ kfree(op->key);
+ }
+ crypto_free_sync_skcipher(op->fallback_tfm);
+}
+
+int meson_aes_setkey(struct crypto_skcipher *tfm, const u8 *key,
+ unsigned int keylen)
+{
+ struct meson_cipher_tfm_ctx *op = crypto_skcipher_ctx(tfm);
+ struct meson_dev *mc = op->mc;
+
+ switch (keylen) {
+ case 128 / 8:
+ op->keymode = MODE_AES_128;
+ break;
+ case 192 / 8:
+ op->keymode = MODE_AES_192;
+ break;
+ case 256 / 8:
+ op->keymode = MODE_AES_256;
+ break;
+ default:
+ dev_dbg(mc->dev, "ERROR: Invalid keylen %u\n", keylen);
+ crypto_skcipher_set_flags(tfm, CRYPTO_TFM_RES_BAD_KEY_LEN);
+ return -EINVAL;
+ }
+ if (op->key) {
+ memzero_explicit(op->key, op->keylen);
+ kfree(op->key);
+ }
+ op->keylen = keylen;
+ op->key = kmalloc(keylen, GFP_KERNEL | GFP_DMA);
+ if (!op->key)
+ return -ENOMEM;
+ memcpy(op->key, key, keylen);
+
+ return crypto_sync_skcipher_setkey(op->fallback_tfm, key, keylen);
+}
diff --git a/drivers/crypto/amlogic/amlogic-core.c b/drivers/crypto/amlogic/amlogic-core.c
new file mode 100644
index 000000000000..94f6e5a520bb
--- /dev/null
+++ b/drivers/crypto/amlogic/amlogic-core.c
@@ -0,0 +1,326 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * amlgoic-core.c - hardware cryptographic offloader for Amlogic GXL SoC
+ *
+ * Copyright (C) 2018-2019 Corentin Labbe <clabbe@baylibre.com>
+ *
+ * Core file which registers crypto algorithms supported by the hardware.
+ */
+#include <linux/clk.h>
+#include <linux/crypto.h>
+#include <linux/io.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/reset.h>
+#include <crypto/internal/skcipher.h>
+#include <linux/dma-mapping.h>
+
+#include "amlogic.h"
+
+static irqreturn_t meson_irq_handler(int irq, void *data)
+{
+ struct meson_dev *mc = (struct meson_dev *)data;
+ int flow;
+ u32 p;
+
+ for (flow = 0; flow < MAXFLOW; flow++) {
+ if (mc->irqs[flow] == irq) {
+ p = readl(mc->base + ((0x04 + flow) << 2));
+ if (p) {
+ writel_relaxed(0xF, mc->base + ((0x4 + flow) << 2));
+ mc->chanlist[flow].status = 1;
+ complete(&mc->chanlist[flow].complete);
+ return IRQ_HANDLED;
+ }
+ dev_err(mc->dev, "%s %d Got irq for flow %d but ctrl is empty\n", __func__, irq, flow);
+ }
+ }
+
+ dev_err(mc->dev, "%s %d from unknown irq\n", __func__, irq);
+ return IRQ_HANDLED;
+}
+
+static struct meson_alg_template mc_algs[] = {
+{
+ .type = CRYPTO_ALG_TYPE_SKCIPHER,
+ .blockmode = MESON_OPMODE_CBC,
+ .alg.skcipher = {
+ .base = {
+ .cra_name = "cbc(aes)",
+ .cra_driver_name = "cbc-aes-meson",
+ .cra_priority = 400,
+ .cra_blocksize = AES_BLOCK_SIZE,
+ .cra_flags = CRYPTO_ALG_TYPE_SKCIPHER |
+ CRYPTO_ALG_ASYNC | CRYPTO_ALG_NEED_FALLBACK,
+ .cra_ctxsize = sizeof(struct meson_cipher_tfm_ctx),
+ .cra_module = THIS_MODULE,
+ .cra_alignmask = 0xf,
+ .cra_init = meson_cipher_init,
+ .cra_exit = meson_cipher_exit,
+ },
+ .min_keysize = AES_MIN_KEY_SIZE,
+ .max_keysize = AES_MAX_KEY_SIZE,
+ .ivsize = AES_BLOCK_SIZE,
+ .setkey = meson_aes_setkey,
+ .encrypt = meson_skencrypt,
+ .decrypt = meson_skdecrypt,
+ }
+},
+{
+ .type = CRYPTO_ALG_TYPE_SKCIPHER,
+ .blockmode = MESON_OPMODE_ECB,
+ .alg.skcipher = {
+ .base = {
+ .cra_name = "ecb(aes)",
+ .cra_driver_name = "ecb-aes-meson",
+ .cra_priority = 400,
+ .cra_blocksize = AES_BLOCK_SIZE,
+ .cra_flags = CRYPTO_ALG_TYPE_SKCIPHER |
+ CRYPTO_ALG_ASYNC | CRYPTO_ALG_NEED_FALLBACK,
+ .cra_ctxsize = sizeof(struct meson_cipher_tfm_ctx),
+ .cra_module = THIS_MODULE,
+ .cra_alignmask = 0xf,
+ .cra_init = meson_cipher_init,
+ .cra_exit = meson_cipher_exit,
+ },
+ .min_keysize = AES_MIN_KEY_SIZE,
+ .max_keysize = AES_MAX_KEY_SIZE,
+ .setkey = meson_aes_setkey,
+ .encrypt = meson_skencrypt,
+ .decrypt = meson_skdecrypt,
+ }
+},
+};
+
+#ifdef CONFIG_CRYPTO_DEV_AMLOGIC_GXL_DEBUG
+static int meson_dbgfs_read(struct seq_file *seq, void *v)
+{
+ struct meson_dev *mc = seq->private;
+ int i;
+
+ for (i = 0; i < MAXFLOW; i++)
+ seq_printf(seq, "Channel %d: req %lu\n", i, mc->chanlist[i].stat_req);
+
+ for (i = 0; i < ARRAY_SIZE(mc_algs); i++) {
+ switch (mc_algs[i].type) {
+ case CRYPTO_ALG_TYPE_SKCIPHER:
+ seq_printf(seq, "%s %s %lu %lu\n",
+ mc_algs[i].alg.skcipher.base.cra_driver_name,
+ mc_algs[i].alg.skcipher.base.cra_name,
+ mc_algs[i].stat_req, mc_algs[i].stat_fb);
+ break;
+ }
+ }
+ return 0;
+}
+
+static int meson_dbgfs_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, meson_dbgfs_read, inode->i_private);
+}
+
+static const struct file_operations meson_debugfs_fops = {
+ .owner = THIS_MODULE,
+ .open = meson_dbgfs_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
+#endif
+
+static int meson_crypto_probe(struct platform_device *pdev)
+{
+ struct resource *res;
+ struct meson_dev *mc;
+ int err, i;
+
+ if (!pdev->dev.of_node)
+ return -ENODEV;
+
+ mc = devm_kzalloc(&pdev->dev, sizeof(*mc), GFP_KERNEL);
+ if (!mc)
+ return -ENOMEM;
+
+ mc->dev = &pdev->dev;
+ platform_set_drvdata(pdev, mc);
+
+ dev_info(mc->dev, "GXL crypto driver v1.1\n");
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ mc->base = devm_ioremap_resource(&pdev->dev, res);
+ if (IS_ERR(mc->base)) {
+ err = PTR_ERR(mc->base);
+ dev_err(&pdev->dev, "Cannot request MMIO err=%d\n", err);
+ return err;
+ }
+ mc->busclk = devm_clk_get(&pdev->dev, "blkmv");
+ if (IS_ERR(mc->busclk)) {
+ err = PTR_ERR(mc->busclk);
+ dev_err(&pdev->dev, "Cannot get core clock err=%d\n", err);
+ return err;
+ }
+
+ mc->irqs = devm_kcalloc(mc->dev, MAXFLOW, sizeof(int), GFP_KERNEL);
+ for (i = 0; i < MAXFLOW; i++) {
+ mc->irqs[i] = platform_get_irq(pdev, i);
+ if (mc->irqs[i] < 0) {
+ dev_err(mc->dev, "Cannot get IRQ for flow %d\n", i);
+ return mc->irqs[i];
+ }
+
+ err = devm_request_irq(&pdev->dev, mc->irqs[i], meson_irq_handler, 0,
+ "gxl-crypto", mc);
+ if (err < 0) {
+ dev_err(mc->dev, "Cannot request IRQ for flow %d\n", i);
+ return err;
+ }
+ }
+
+ mc->reset = devm_reset_control_get_optional(&pdev->dev, "ahb");
+ if (IS_ERR(mc->reset)) {
+ if (PTR_ERR(mc->reset) == -EPROBE_DEFER)
+ return PTR_ERR(mc->reset);
+ dev_info(&pdev->dev, "No reset control found\n");
+ mc->reset = NULL;
+ }
+
+ err = clk_prepare_enable(mc->busclk);
+ if (err != 0) {
+ dev_err(&pdev->dev, "Cannot prepare_enable busclk\n");
+ return err;
+ }
+
+ err = reset_control_deassert(mc->reset);
+ if (err) {
+ dev_err(&pdev->dev, "Cannot deassert reset control\n");
+ goto error_clk;
+ }
+
+ mc->chanlist = devm_kcalloc(mc->dev, MAXFLOW,
+ sizeof(struct meson_flow), GFP_KERNEL);
+ if (!mc->chanlist) {
+ err = -ENOMEM;
+ goto error_flow;
+ }
+
+ for (i = 0; i < MAXFLOW; i++) {
+ init_completion(&mc->chanlist[i].complete);
+
+ mc->chanlist[i].engine = crypto_engine_alloc_init(mc->dev, 1);
+ if (!mc->chanlist[i].engine) {
+ dev_err(mc->dev, "Cannot allocate engine\n");
+ i--;
+ goto error_engine;
+ }
+ err = crypto_engine_start(mc->chanlist[i].engine);
+ if (err) {
+ dev_err(mc->dev, "Cannot request engine\n");
+ goto error_engine;
+ }
+ mc->chanlist[i].tl = dma_alloc_coherent(mc->dev,
+ sizeof(struct meson_desc) * MAXDESC,
+ &mc->chanlist[i].t_phy,
+ GFP_KERNEL);
+ if (!mc->chanlist[i].tl) {
+ dev_err(mc->dev, "Cannot get DMA memory for task %d\n",
+ i);
+ err = -ENOMEM;
+ goto error_engine;
+ }
+ }
+
+#ifdef CONFIG_CRYPTO_DEV_AMLOGIC_GXL_DEBUG
+ mc->dbgfs_dir = debugfs_create_dir("gxl-crypto", NULL);
+ debugfs_create_file("stats", 0444, mc->dbgfs_dir, mc, &meson_debugfs_fops);
+#endif
+ for (i = 0; i < ARRAY_SIZE(mc_algs); i++) {
+ mc_algs[i].mc = mc;
+ switch (mc_algs[i].type) {
+ case CRYPTO_ALG_TYPE_SKCIPHER:
+ err = crypto_register_skcipher(&mc_algs[i].alg.skcipher);
+ if (err) {
+ dev_err(mc->dev, "Fail to register %s\n",
+ mc_algs[i].alg.skcipher.base.cra_name);
+ mc_algs[i].mc = NULL;
+ goto error_alg;
+ }
+ break;
+ }
+ }
+
+ return 0;
+error_alg:
+ i--;
+ for (; i >= 0; i--) {
+ switch (mc_algs[i].type) {
+ case CRYPTO_ALG_TYPE_SKCIPHER:
+ if (mc_algs[i].mc)
+ crypto_unregister_skcipher(&mc_algs[i].alg.skcipher);
+ break;
+ }
+ }
+#ifdef CONFIG_CRYPTO_DEV_AMLOGIC_GXL_DEBUG
+ debugfs_remove_recursive(mc->dbgfs_dir);
+#endif
+ i = MAXFLOW;
+error_engine:
+ while (i >= 0) {
+ if (mc->chanlist[i].tl)
+ dma_free_coherent(mc->dev, sizeof(struct meson_desc) * MAXDESC,
+ mc->chanlist[i].tl, mc->chanlist[i].t_phy);
+ i--;
+ }
+error_flow:
+ reset_control_assert(mc->reset);
+error_clk:
+ clk_disable_unprepare(mc->busclk);
+ return err;
+}
+
+static int meson_crypto_remove(struct platform_device *pdev)
+{
+ int i;
+ struct meson_dev *mc = platform_get_drvdata(pdev);
+
+ for (i = 0; i < ARRAY_SIZE(mc_algs); i++) {
+ switch (mc_algs[i].type) {
+ case CRYPTO_ALG_TYPE_SKCIPHER:
+ if (mc_algs[i].mc)
+ crypto_unregister_skcipher(&mc_algs[i].alg.skcipher);
+ break;
+ }
+ }
+
+#ifdef CONFIG_CRYPTO_DEV_AMLOGIC_GXL_DEBUG
+ debugfs_remove_recursive(mc->dbgfs_dir);
+#endif
+
+ reset_control_assert(mc->reset);
+ clk_disable_unprepare(mc->busclk);
+ return 0;
+}
+
+static const struct of_device_id meson_crypto_of_match_table[] = {
+ { .compatible = "amlogic,gxl-crypto", },
+ {}
+};
+MODULE_DEVICE_TABLE(of, meson_crypto_of_match_table);
+
+static struct platform_driver meson_crypto_driver = {
+ .probe = meson_crypto_probe,
+ .remove = meson_crypto_remove,
+ .driver = {
+ .name = "gxl-crypto",
+ .of_match_table = meson_crypto_of_match_table,
+ },
+};
+
+module_platform_driver(meson_crypto_driver);
+
+MODULE_DESCRIPTION("Amlogic GXL cryptographic offloader");
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Corentin Labbe <clabbe@baylibre.com>");
diff --git a/drivers/crypto/amlogic/amlogic.h b/drivers/crypto/amlogic/amlogic.h
new file mode 100644
index 000000000000..23891cc58d7f
--- /dev/null
+++ b/drivers/crypto/amlogic/amlogic.h
@@ -0,0 +1,172 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * amlogic.h - hardware cryptographic offloader for Amlogic SoC
+ *
+ * Copyright (C) 2018-2019 Corentin LABBE <clabbe@baylibre.com>
+ */
+#include <crypto/aes.h>
+#include <crypto/engine.h>
+#include <crypto/skcipher.h>
+#include <linux/debugfs.h>
+#include <linux/crypto.h>
+#include <linux/scatterlist.h>
+
+#define MODE_KEY 1
+#define MODE_AES_128 0x8
+#define MODE_AES_192 0x9
+#define MODE_AES_256 0xa
+
+#define MESON_DECRYPT 0
+#define MESON_ENCRYPT 1
+
+#define MESON_OPMODE_ECB 0
+#define MESON_OPMODE_CBC 1
+
+#define MAXFLOW 2
+
+#define MAXDESC 64
+
+/*
+ * struct meson_desc - Descriptor for DMA operations
+ * Note that without datasheet, some are unknown
+ * @len: length of data to operate
+ * @irq: Ignored by hardware
+ * @eoc: End of descriptor
+ * @loop: Unknown
+ * @mode: Type of algorithm (AES, SHA)
+ * @begin: Unknown
+ * @end: Unknown
+ * @op_mode: Blockmode (CBC, ECB)
+ * @block: Unknown
+ * @error: Unknown
+ * @owner: owner of the descriptor, 1 own by HW
+ * @t_src: Physical address of data to read
+ * @t_dst: Physical address of data to write
+ */
+struct meson_desc {
+ union {
+ u32 t_status;
+ struct {
+ u32 len:17;
+ u32 irq:1;
+ u32 eoc:1;
+ u32 loop:1;
+ u32 mode:4;
+ u32 begin:1;
+ u32 end:1;
+ u32 op_mode:2;
+ u32 enc:1;
+ u32 block:1;
+ u32 error:1;
+ u32 owner:1;
+ };
+ };
+ u32 t_src;
+ u32 t_dst;
+};
+
+/*
+ * struct meson_flow - Information used by each flow
+ * @engine: ptr to the crypto_engine for this flow
+ * @keylen: keylen for this flow operation
+ * @complete: completion for the current task on this flow
+ * @status: set to 1 by interrupt if task is done
+ * @t_phy: Physical address of task
+ * @tl: pointer to the current ce_task for this flow
+ * @stat_req: number of request done by this flow
+ */
+struct meson_flow {
+ struct crypto_engine *engine;
+ struct completion complete;
+ int status;
+ unsigned int keylen;
+ dma_addr_t t_phy;
+ struct meson_desc *tl;
+#ifdef CONFIG_CRYPTO_DEV_AMLOGIC_GXL_DEBUG
+ unsigned long stat_req;
+#endif
+};
+
+/*
+ * struct meson_dev - main container for all this driver information
+ * @base: base address of amlogic-crypto
+ * @busclk: bus clock for amlogic-crypto
+ * @reset: pointer to reset controller
+ * @dev: the platform device
+ * @chanlist: array of all flow
+ * @flow: flow to use in next request
+ * @irqs: IRQ numbers for amlogic-crypto
+ * @dbgfs_dir: Debugfs dentry for statistic directory
+ * @dbgfs_stats: Debugfs dentry for statistic counters
+ */
+struct meson_dev {
+ void __iomem *base;
+ struct clk *busclk;
+ struct reset_control *reset;
+ struct device *dev;
+ struct meson_flow *chanlist;
+ atomic_t flow;
+ int *irqs;
+#ifdef CONFIG_CRYPTO_DEV_AMLOGIC_GXL_DEBUG
+ struct dentry *dbgfs_dir;
+#endif
+};
+
+/*
+ * struct meson_cipher_req_ctx - context for a skcipher request
+ * @op_dir: direction (encrypt vs decrypt) for this request
+ * @flow: the flow to use for this request
+ */
+struct meson_cipher_req_ctx {
+ u32 op_dir;
+ int flow;
+};
+
+/*
+ * struct meson_cipher_tfm_ctx - context for a skcipher TFM
+ * @enginectx: crypto_engine used by this TFM
+ * @key: pointer to key data
+ * @keylen: len of the key
+ * @keymode: The keymode(type and size of key) associated with this TFM
+ * @mc: pointer to the private data of driver handling this TFM
+ * @fallback_tfm: pointer to the fallback TFM
+ */
+struct meson_cipher_tfm_ctx {
+ struct crypto_engine_ctx enginectx;
+ u32 *key;
+ u32 keylen;
+ u32 keymode;
+ struct meson_dev *mc;
+ struct crypto_sync_skcipher *fallback_tfm;
+};
+
+/*
+ * struct meson_alg_template - crypto_alg template
+ * @type: the CRYPTO_ALG_TYPE for this template
+ * @blockmode: the type of block operation
+ * @mc: pointer to the meson_dev structure associated with this template
+ * @alg: one of sub struct must be used
+ * @stat_req: number of request done on this template
+ * @stat_fb: total of all data len done on this template
+ */
+struct meson_alg_template {
+ u32 type;
+ u32 blockmode;
+ union {
+ struct skcipher_alg skcipher;
+ } alg;
+ struct meson_dev *mc;
+#ifdef CONFIG_CRYPTO_DEV_AMLOGIC_GXL_DEBUG
+ unsigned long stat_req;
+ unsigned long stat_fb;
+#endif
+};
+
+int meson_enqueue(struct crypto_async_request *areq, u32 type);
+
+int meson_aes_setkey(struct crypto_skcipher *tfm, const u8 *key,
+ unsigned int keylen);
+int meson_cipher_init(struct crypto_tfm *tfm);
+void meson_cipher_exit(struct crypto_tfm *tfm);
+int meson_skdecrypt(struct skcipher_request *areq);
+int meson_skencrypt(struct skcipher_request *areq);
--
2.21.0
^ permalink raw reply related
* [PATCH 1/4] dt-bindings: crypto: Add DT bindings documentation for amlogic-crypto
From: Corentin Labbe @ 2019-07-25 19:42 UTC (permalink / raw)
To: davem, herbert, khilman, mark.rutland, robh+dt
Cc: devicetree, linux-amlogic, linux-arm-kernel, linux-crypto,
linux-kernel, baylibre-upstreaming, Corentin Labbe
In-Reply-To: <1564083776-20540-1-git-send-email-clabbe@baylibre.com>
This patch adds documentation for Device-Tree bindings for the
Amlogic GXL cryptographic offloader driver.
Signed-off-by: Corentin Labbe <clabbe@baylibre.com>
---
.../bindings/crypto/amlogic-gxl-crypto.yaml | 45 +++++++++++++++++++
1 file changed, 45 insertions(+)
create mode 100644 Documentation/devicetree/bindings/crypto/amlogic-gxl-crypto.yaml
diff --git a/Documentation/devicetree/bindings/crypto/amlogic-gxl-crypto.yaml b/Documentation/devicetree/bindings/crypto/amlogic-gxl-crypto.yaml
new file mode 100644
index 000000000000..41265e57c00b
--- /dev/null
+++ b/Documentation/devicetree/bindings/crypto/amlogic-gxl-crypto.yaml
@@ -0,0 +1,45 @@
+# SPDX-License-Identifier: GPL-2.0
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/crypto/amlogic-gxl-crypto.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Amlogic GXL Cryptographic Offloader
+
+maintainers:
+ - Corentin Labbe <clabbe@baylibre.com>
+
+properties:
+ compatible:
+ oneOf:
+ - const: amlogic,gxl-crypto
+
+ reg:
+ maxItems: 1
+
+ interrupts:
+ maxItems: 1
+
+ clocks:
+ maxItems: 1
+
+ clock-names:
+ const: blkmv
+
+required:
+ - compatible
+ - reg
+ - interrupts
+ - clocks
+ - clock-names
+
+examples:
+ - |
+ crypto: crypto@c883e000 {
+ compatible = "amlogic,gxl-crypto";
+ reg = <0x0 0xc883e000 0x0 0x36>;
+ interrupts = <GIC_SPI 188 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 189 IRQ_TYPE_EDGE_RISING>;
+ clocks = <&clkc CLKID_BLKMV>;
+ clock-names = "blkmv";
+ };
--
2.21.0
^ permalink raw reply related
* [PATCH 0/4] crypto: add amlogic crypto offloader driver
From: Corentin Labbe @ 2019-07-25 19:42 UTC (permalink / raw)
To: davem, herbert, khilman, mark.rutland, robh+dt
Cc: devicetree, linux-amlogic, linux-arm-kernel, linux-crypto,
linux-kernel, baylibre-upstreaming, Corentin Labbe
Hello
This serie adds support for the crypto offloader present on amlogic GXL
SoCs.
Tested on meson-gxl-s905x-khadas-vim and meson-gxl-s905x-libretech-cc
Regards
Corentin Labbe (4):
dt-bindings: crypto: Add DT bindings documentation for amlogic-crypto
crypto: amlogic: Add crypto accelerator for amlogic GXL
MAINTAINERS: Add myself as maintainer of amlogic crypto
ARM64: dts: amlogic: adds crypto hardware node
.../bindings/crypto/amlogic-gxl-crypto.yaml | 45 +++
MAINTAINERS | 7 +
arch/arm64/boot/dts/amlogic/meson-gxl.dtsi | 11 +
drivers/crypto/Kconfig | 2 +
drivers/crypto/Makefile | 1 +
drivers/crypto/amlogic/Kconfig | 24 ++
drivers/crypto/amlogic/Makefile | 2 +
drivers/crypto/amlogic/amlogic-cipher.c | 358 ++++++++++++++++++
drivers/crypto/amlogic/amlogic-core.c | 326 ++++++++++++++++
drivers/crypto/amlogic/amlogic.h | 172 +++++++++
10 files changed, 948 insertions(+)
create mode 100644 Documentation/devicetree/bindings/crypto/amlogic-gxl-crypto.yaml
create mode 100644 drivers/crypto/amlogic/Kconfig
create mode 100644 drivers/crypto/amlogic/Makefile
create mode 100644 drivers/crypto/amlogic/amlogic-cipher.c
create mode 100644 drivers/crypto/amlogic/amlogic-core.c
create mode 100644 drivers/crypto/amlogic/amlogic.h
--
2.21.0
^ permalink raw reply
* Re: [PATCH 1/2] bus: imx-weim: optionally enable burst clock mode
From: Fabio Estevam @ 2019-07-25 19:32 UTC (permalink / raw)
To: Sven Van Asbroeck
Cc: Shawn Guo, NXP Linux Team, Kees Cook, Linux Kernel Mailing List,
moderated list:ARM/FREESCALE IMX / MXC ARM ARCHITECTURE,
Mark Rutland, Sascha Hauer, devicetree, Pengutronix Kernel Team,
Arnd Bergmann
In-Reply-To: <CAGngYiVb_-A4Au749GD6SKi=UqKKBm4yxim8YOCbgVjfz7xtvg@mail.gmail.com>
Hi Sven,
On Thu, Jul 25, 2019 at 11:30 AM Sven Van Asbroeck <thesven73@gmail.com> wrote:
>
> On Fri, Jul 12, 2019 at 4:43 PM Sven Van Asbroeck <thesven73@gmail.com> wrote:
> >
> > To enable burst clock mode, add the fsl,burst-clk-enable
> > property to the weim bus's devicetree node.
> >
>
> Any feedback on this patch, positive or negative?
Looks good to me:
Reviewed-by: Fabio Estevam <festevam@gmail.com>
^ permalink raw reply
* Re: [PATCH net-next 3/3] dt-bindings: net: ethernet: Update mt7622 docs and dts to reflect the new phylink API
From: Andrew Lunn @ 2019-07-25 19:31 UTC (permalink / raw)
To: René van Dorst
Cc: netdev, frank-w, sean.wang, f.fainelli, linux, davem,
matthias.bgg, vivien.didelot, john, linux-mediatek, linux-mips,
robh+dt, devicetree
In-Reply-To: <20190724192411.20639-1-opensource@vdorst.com>
> + gmac0: mac@0 {
> + compatible = "mediatek,eth-mac";
> + reg = <0>;
> + phy-mode = "sgmii";
> +
> + fixed-link {
> + speed = <2500>;
> + full-duplex;
> + pause;
> + };
> + };
Hi René
SGMII and fixed-link is rather odd. Why do you need this combination?
Andrew
^ permalink raw reply
* Re: [PATCH v3 2/7] drivers: Introduce device lookup variants by of_node
From: Wolfram Sang @ 2019-07-25 19:25 UTC (permalink / raw)
To: Suzuki K Poulose
Cc: linux-kernel, gregkh, rafael, linux-arm-kernel, Maarten Lankhorst,
Maxime Ripard, dri-devel, David Airlie, Daniel Vetter, devicetree,
Florian Fainelli, Frank Rowand, Heiko Stuebner, Liam Girdwood,
linux-i2c, linux-rockchip, linux-spi, Mathieu Poirier,
Rob Herring, Srinivas Kandagatla, Takashi Iwai, Alan Tull
In-Reply-To: <20190723221838.12024-3-suzuki.poulose@arm.com>
[-- Attachment #1: Type: text/plain, Size: 1952 bytes --]
On Tue, Jul 23, 2019 at 11:18:33PM +0100, Suzuki K Poulose wrote:
> Introduce wrappers for {bus/driver/class}_find_device() to
> locate devices by its of_node.
>
> Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> Cc: Maxime Ripard <maxime.ripard@bootlin.com>
> Cc: dri-devel@lists.freedesktop.org
> Cc: David Airlie <airlied@linux.ie>
> Cc: Daniel Vetter <daniel@ffwll.ch>
> Cc: devicetree@vger.kernel.org
> Cc: Florian Fainelli <f.fainelli@gmail.com>
> Cc: Frank Rowand <frowand.list@gmail.com>
> Cc: Heiko Stuebner <heiko@sntech.de>
> Cc: Liam Girdwood <lgirdwood@gmail.com>
> Cc: linux-i2c@vger.kernel.org
> Cc: linux-rockchip@lists.infradead.org
> Cc: linux-spi@vger.kernel.org
> Cc: Mathieu Poirier <mathieu.poirier@linaro.org>
> Cc: Rob Herring <robh+dt@kernel.org>
> Cc: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
> Cc: Takashi Iwai <tiwai@suse.com>
> Cc: Wolfram Sang <wsa@the-dreams.de>
> Cc: Alan Tull <atull@kernel.org>
> Cc: Moritz Fischer <mdf@kernel.org>
> Cc: linux-fpga@vger.kernel.org
> Cc: Peter Rosin <peda@axentia.se>
> Cc: Mark Brown <broonie@kernel.org>
> Cc: Florian Fainelli <f.fainelli@gmail.com>
> Cc: Heiner Kallweit <hkallweit1@gmail.com>
> Cc: "David S. Miller" <davem@davemloft.net>
> Cc: Andrew Lunn <andrew@lunn.ch>
> Cc: Liam Girdwood <lgirdwood@gmail.com>
> Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
> Cc: "Rafael J. Wysocki" <rafael@kernel.org>
> Cc: Lee Jones <lee.jones@linaro.org>
> Cc: Thor Thayer <thor.thayer@linux.intel.com>
> Cc: Jiri Slaby <jslaby@suse.com>
> Cc: Mark Brown <broonie@kernel.org>
> Cc: Andrew Lunn <andrew@lunn.ch>
> Cc: Peter Rosin <peda@axentia.se>
> Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>
> ---
> - Dropped the reviewed-by tags from Thor, Mark, Andrew and Peter as the
> patches are mereged, though there are no functional changes.
Acked-by: Wolfram Sang <wsa@the-dreams.de> # I2C part
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ permalink raw reply
* Re: [RFC] dt-bindings: net: phy: Add subnode for LED configuration
From: Matthias Kaehlcke @ 2019-07-25 19:18 UTC (permalink / raw)
To: Andrew Lunn
Cc: David S . Miller, Rob Herring, Mark Rutland, Florian Fainelli,
Heiner Kallweit, netdev, devicetree, linux-kernel,
Douglas Anderson
In-Reply-To: <20190725183441.GL21952@lunn.ch>
On Thu, Jul 25, 2019 at 08:34:41PM +0200, Andrew Lunn wrote:
> > As of now I don't plan to expose the label to userspace by the PHY
> > driver/framework itself.
>
> Great.
>
> With that change, i think this proposed binding is O.K.
Great, thanks for your feedback!
I'll probably post a new version with actual code next week, unless
there is more discussion before I get to it.
^ permalink raw reply
* Re: [RFC] dt-bindings: net: phy: Add subnode for LED configuration
From: Andrew Lunn @ 2019-07-25 18:34 UTC (permalink / raw)
To: Matthias Kaehlcke
Cc: David S . Miller, Rob Herring, Mark Rutland, Florian Fainelli,
Heiner Kallweit, netdev, devicetree, linux-kernel,
Douglas Anderson
In-Reply-To: <20190725175258.GE250418@google.com>
> As of now I don't plan to expose the label to userspace by the PHY
> driver/framework itself.
Great.
With that change, i think this proposed binding is O.K.
Andrew
^ permalink raw reply
* Re: [RFC] dt-bindings: net: phy: Add subnode for LED configuration
From: Matthias Kaehlcke @ 2019-07-25 17:52 UTC (permalink / raw)
To: Andrew Lunn
Cc: David S . Miller, Rob Herring, Mark Rutland, Florian Fainelli,
Heiner Kallweit, netdev, devicetree, linux-kernel,
Douglas Anderson
In-Reply-To: <20190724180430.GB28488@lunn.ch>
Hi Andrew,
On Wed, Jul 24, 2019 at 08:04:30PM +0200, Andrew Lunn wrote:
> On Mon, Jul 22, 2019 at 03:37:41PM -0700, Matthias Kaehlcke wrote:
> > The LED behavior of some Ethernet PHYs is configurable. Add an
> > optional 'leds' subnode with a child node for each LED to be
> > configured. The binding aims to be compatible with the common
> > LED binding (see devicetree/bindings/leds/common.txt).
> >
> > A LED can be configured to be 'on' when a link with a certain speed
> > is active, or to blink on RX/TX activity. For the configuration to
> > be effective it needs to be supported by the hardware and the
> > corresponding PHY driver.
> >
> > Suggested-by: Andrew Lunn <andrew@lunn.ch>
> > Signed-off-by: Matthias Kaehlcke <mka@chromium.org>
> > ---
> > This RFC is a follow up of the discussion on "[PATCH v2 6/7]
> > dt-bindings: net: realtek: Add property to configure LED mode"
> > (https://lore.kernel.org/patchwork/patch/1097185/).
> >
> > For now posting as RFC to get a basic agreement on the bindings
> > before proceding with the implementation in phylib and a specific
> > driver.
> > ---
> > Documentation/devicetree/bindings/net/phy.txt | 33 +++++++++++++++++++
> > 1 file changed, 33 insertions(+)
> >
> > diff --git a/Documentation/devicetree/bindings/net/phy.txt b/Documentation/devicetree/bindings/net/phy.txt
> > index 9b9e5b1765dd..ad495d3abbbb 100644
> > --- a/Documentation/devicetree/bindings/net/phy.txt
> > +++ b/Documentation/devicetree/bindings/net/phy.txt
> > @@ -46,6 +46,25 @@ Optional Properties:
> > Mark the corresponding energy efficient ethernet mode as broken and
> > request the ethernet to stop advertising it.
> >
> > +- leds: A sub-node which is a container of only LED nodes. Each child
> > + node represents a PHY LED.
> > +
> > + Required properties for LED child nodes:
> > + - reg: The ID number of the LED, typically corresponds to a hardware ID.
> > +
> > + Optional properties for child nodes:
> > + - label: The label for this LED. If omitted, the label is taken from the node
> > + name (excluding the unit address). It has to uniquely identify a device,
> > + i.e. no other LED class device can be assigned the same label.
>
> Hi Matthias
>
> I've thought about label a bit more.
>
> > + label = "ethphy0:left:green";
>
> We need to be careful with names here. systemd etc renames
> interfaces. ethphy0 could in fact be connected to enp3s0, or eth0
> might get renamed to eth1, etc. So i think we should avoid things like
> ethphy0.
Agreed, this could be problematic.
> Also, i'm not sure we actually need a label, at least not to
> start with.Do we have any way to expose it to the user?
As of now I don't plan to expose the label to userspace by the PHY
driver/framework itself.
>From my side we can omit the label for now and add it later if needed.
> If we do ever make it part of the generic LED framework, we can then
> use the label. At that point, i would probably combine the label with
> the interface name in a dynamic way to avoid issues like this.
Sounds good.
Thanks
Matthias
^ permalink raw reply
* [PATCH] ARM: dts: aspeed: tiogapass: Move battery sensor
From: Vijay Khemka @ 2019-07-25 17:45 UTC (permalink / raw)
To: Rob Herring, Mark Rutland, Joel Stanley, Andrew Jeffery,
devicetree, linux-arm-kernel, linux-aspeed, linux-kernel
Cc: openbmc @ lists . ozlabs . org, sdasari, vijaykhemka
Moved adc7 hwmon battery sensor to correct label to be read
by single applications for all adc sensors.
Signed-off-by: Vijay Khemka <vijaykhemka@fb.com>
---
arch/arm/boot/dts/aspeed-bmc-facebook-tiogapass.dts | 6 +-----
1 file changed, 1 insertion(+), 5 deletions(-)
diff --git a/arch/arm/boot/dts/aspeed-bmc-facebook-tiogapass.dts b/arch/arm/boot/dts/aspeed-bmc-facebook-tiogapass.dts
index d0c823e8fce5..682f729ea25e 100644
--- a/arch/arm/boot/dts/aspeed-bmc-facebook-tiogapass.dts
+++ b/arch/arm/boot/dts/aspeed-bmc-facebook-tiogapass.dts
@@ -46,13 +46,9 @@
iio-hwmon {
compatible = "iio-hwmon";
io-channels = <&adc 0>, <&adc 1>, <&adc 2>, <&adc 3>,
- <&adc 4>, <&adc 5>, <&adc 6>;
+ <&adc 4>, <&adc 5>, <&adc 6>, <&adc 7>;
};
- iio-hwmon-battery {
- compatible = "iio-hwmon";
- io-channels = <&adc 7>;
- };
};
&fmc {
--
2.17.1
^ permalink raw reply related
* Applied "ASoC: codec2codec: deal with params when necessary" to the asoc tree
From: Mark Brown @ 2019-07-25 17:43 UTC (permalink / raw)
To: Jerome Brunet
Cc: alsa-devel, devicetree, Kevin Hilman, Liam Girdwood,
linux-amlogic, linux-kernel, Mark Brown
In-Reply-To: <20190725165949.29699-4-jbrunet@baylibre.com>
The patch
ASoC: codec2codec: deal with params when necessary
has been applied to the asoc tree at
https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git for-5.4
All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.
You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.
If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.
Please add any relevant lists and maintainers to the CCs when replying
to this mail.
Thanks,
Mark
>From 3dcfb397dad2ad55bf50de3c5d5a57090d35a18a Mon Sep 17 00:00:00 2001
From: Jerome Brunet <jbrunet@baylibre.com>
Date: Thu, 25 Jul 2019 18:59:46 +0200
Subject: [PATCH] ASoC: codec2codec: deal with params when necessary
When there is an event on codec to codec dai_link, we only need to deal
with params if the event is SND_SOC_DAPM_PRE_PMU, when .hw_params() is
called. For the other events, it is useless.
Also, dealing with the codec to codec params just before calling
.hw_params() callbacks give change to either party on the link to alter
params content in .startup(), which might be useful in some cases
Signed-off-by: Jerome Brunet <jbrunet@baylibre.com>
Link: https://lore.kernel.org/r/20190725165949.29699-4-jbrunet@baylibre.com
Signed-off-by: Mark Brown <broonie@kernel.org>
---
sound/soc/soc-dapm.c | 159 +++++++++++++++++++++++++------------------
1 file changed, 92 insertions(+), 67 deletions(-)
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c
index 7db4abd9a0a5..6dcaf9ff6eb5 100644
--- a/sound/soc/soc-dapm.c
+++ b/sound/soc/soc-dapm.c
@@ -3764,25 +3764,59 @@ int snd_soc_dapm_new_controls(struct snd_soc_dapm_context *dapm,
}
EXPORT_SYMBOL_GPL(snd_soc_dapm_new_controls);
-static int snd_soc_dai_link_event(struct snd_soc_dapm_widget *w,
- struct snd_kcontrol *kcontrol, int event)
+static int
+snd_soc_dai_link_event_pre_pmu(struct snd_soc_dapm_widget *w,
+ struct snd_pcm_substream *substream)
{
struct snd_soc_dapm_path *path;
struct snd_soc_dai *source, *sink;
- struct snd_soc_pcm_runtime *rtd = w->priv;
- const struct snd_soc_pcm_stream *config;
- struct snd_pcm_substream substream;
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct snd_pcm_hw_params *params = NULL;
- struct snd_pcm_runtime *runtime = NULL;
+ const struct snd_soc_pcm_stream *config = NULL;
unsigned int fmt;
- int ret = 0;
+ int ret;
- config = rtd->dai_link->params + rtd->params_select;
+ params = kzalloc(sizeof(*params), GFP_KERNEL);
+ if (!params)
+ return -ENOMEM;
- if (WARN_ON(!config) ||
- WARN_ON(list_empty(&w->edges[SND_SOC_DAPM_DIR_OUT]) ||
- list_empty(&w->edges[SND_SOC_DAPM_DIR_IN])))
- return -EINVAL;
+ substream->stream = SNDRV_PCM_STREAM_CAPTURE;
+ snd_soc_dapm_widget_for_each_source_path(w, path) {
+ source = path->source->priv;
+
+ ret = snd_soc_dai_startup(source, substream);
+ if (ret < 0) {
+ dev_err(source->dev,
+ "ASoC: startup() failed: %d\n", ret);
+ goto out;
+ }
+ source->active++;
+ }
+
+ substream->stream = SNDRV_PCM_STREAM_PLAYBACK;
+ snd_soc_dapm_widget_for_each_sink_path(w, path) {
+ sink = path->sink->priv;
+
+ ret = snd_soc_dai_startup(sink, substream);
+ if (ret < 0) {
+ dev_err(sink->dev,
+ "ASoC: startup() failed: %d\n", ret);
+ goto out;
+ }
+ sink->active++;
+ }
+
+ /*
+ * Note: getting the config after .startup() gives a chance to
+ * either party on the link to alter the configuration if
+ * necessary
+ */
+ config = rtd->dai_link->params + rtd->params_select;
+ if (WARN_ON(!config)) {
+ dev_err(w->dapm->dev, "ASoC: link config missing\n");
+ ret = -EINVAL;
+ goto out;
+ }
/* Be a little careful as we don't want to overflow the mask array */
if (config->formats) {
@@ -3790,27 +3824,62 @@ static int snd_soc_dai_link_event(struct snd_soc_dapm_widget *w,
} else {
dev_warn(w->dapm->dev, "ASoC: Invalid format %llx specified\n",
config->formats);
- fmt = 0;
- }
- /* Currently very limited parameter selection */
- params = kzalloc(sizeof(*params), GFP_KERNEL);
- if (!params) {
- ret = -ENOMEM;
+ ret = -EINVAL;
goto out;
}
- snd_mask_set(hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT), fmt);
+ snd_mask_set(hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT), fmt);
hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE)->min =
config->rate_min;
hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE)->max =
config->rate_max;
-
hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS)->min
= config->channels_min;
hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS)->max
= config->channels_max;
+ substream->stream = SNDRV_PCM_STREAM_CAPTURE;
+ snd_soc_dapm_widget_for_each_source_path(w, path) {
+ source = path->source->priv;
+
+ ret = snd_soc_dai_hw_params(source, substream, params);
+ if (ret < 0)
+ goto out;
+
+ dapm_update_dai_unlocked(substream, params, source);
+ }
+
+ substream->stream = SNDRV_PCM_STREAM_PLAYBACK;
+ snd_soc_dapm_widget_for_each_sink_path(w, path) {
+ sink = path->sink->priv;
+
+ ret = snd_soc_dai_hw_params(sink, substream, params);
+ if (ret < 0)
+ goto out;
+
+ dapm_update_dai_unlocked(substream, params, sink);
+ }
+
+out:
+ kfree(params);
+ return 0;
+}
+
+static int snd_soc_dai_link_event(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol, int event)
+{
+ struct snd_soc_dapm_path *path;
+ struct snd_soc_dai *source, *sink;
+ struct snd_soc_pcm_runtime *rtd = w->priv;
+ struct snd_pcm_substream substream;
+ struct snd_pcm_runtime *runtime = NULL;
+ int ret = 0;
+
+ if (WARN_ON(list_empty(&w->edges[SND_SOC_DAPM_DIR_OUT]) ||
+ list_empty(&w->edges[SND_SOC_DAPM_DIR_IN])))
+ return -EINVAL;
+
memset(&substream, 0, sizeof(substream));
/* Allocate a dummy snd_pcm_runtime for startup() and other ops() */
@@ -3824,53 +3893,10 @@ static int snd_soc_dai_link_event(struct snd_soc_dapm_widget *w,
switch (event) {
case SND_SOC_DAPM_PRE_PMU:
- substream.stream = SNDRV_PCM_STREAM_CAPTURE;
- snd_soc_dapm_widget_for_each_source_path(w, path) {
- source = path->source->priv;
-
- ret = snd_soc_dai_startup(source, &substream);
- if (ret < 0) {
- dev_err(source->dev,
- "ASoC: startup() failed: %d\n", ret);
- goto out;
- }
- source->active++;
- }
-
- substream.stream = SNDRV_PCM_STREAM_PLAYBACK;
- snd_soc_dapm_widget_for_each_sink_path(w, path) {
- sink = path->sink->priv;
-
- ret = snd_soc_dai_startup(sink, &substream);
- if (ret < 0) {
- dev_err(sink->dev,
- "ASoC: startup() failed: %d\n", ret);
- goto out;
- }
- sink->active++;
- }
-
- substream.stream = SNDRV_PCM_STREAM_CAPTURE;
- snd_soc_dapm_widget_for_each_source_path(w, path) {
- source = path->source->priv;
-
- ret = snd_soc_dai_hw_params(source, &substream, params);
- if (ret < 0)
- goto out;
-
- dapm_update_dai_unlocked(&substream, params, source);
- }
-
- substream.stream = SNDRV_PCM_STREAM_PLAYBACK;
- snd_soc_dapm_widget_for_each_sink_path(w, path) {
- sink = path->sink->priv;
-
- ret = snd_soc_dai_hw_params(sink, &substream, params);
- if (ret < 0)
- goto out;
+ ret = snd_soc_dai_link_event_pre_pmu(w, &substream);
+ if (ret < 0)
+ goto out;
- dapm_update_dai_unlocked(&substream, params, sink);
- }
break;
case SND_SOC_DAPM_POST_PMU:
@@ -3932,7 +3958,6 @@ static int snd_soc_dai_link_event(struct snd_soc_dapm_widget *w,
out:
kfree(runtime);
- kfree(params);
return ret;
}
--
2.20.1
^ permalink raw reply related
* Applied "ASoC: codec2codec: name link using stream direction" to the asoc tree
From: Mark Brown @ 2019-07-25 17:43 UTC (permalink / raw)
To: Jerome Brunet
Cc: alsa-devel, devicetree, Kevin Hilman, Liam Girdwood,
linux-amlogic, linux-kernel, Mark Brown
In-Reply-To: <20190725165949.29699-3-jbrunet@baylibre.com>
The patch
ASoC: codec2codec: name link using stream direction
has been applied to the asoc tree at
https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git for-5.4
All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.
You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.
If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.
Please add any relevant lists and maintainers to the CCs when replying
to this mail.
Thanks,
Mark
>From 054d65004c6a008dfefbdae4fc1b46a3ad4e94c1 Mon Sep 17 00:00:00 2001
From: Jerome Brunet <jbrunet@baylibre.com>
Date: Thu, 25 Jul 2019 18:59:45 +0200
Subject: [PATCH] ASoC: codec2codec: name link using stream direction
At the moment, codec to codec dai link widgets are named after the
cpu dai and the 1st codec valid on the link. This might be confusing
if there is multiple valid codecs on the link for one stream
direction.
Instead, use the dai link name and the stream direction to name the
the dai link widget
Signed-off-by: Jerome Brunet <jbrunet@baylibre.com>
Link: https://lore.kernel.org/r/20190725165949.29699-3-jbrunet@baylibre.com
Signed-off-by: Mark Brown <broonie@kernel.org>
---
sound/soc/soc-dapm.c | 12 ++++--------
1 file changed, 4 insertions(+), 8 deletions(-)
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c
index 034b31fd2ecb..7db4abd9a0a5 100644
--- a/sound/soc/soc-dapm.c
+++ b/sound/soc/soc-dapm.c
@@ -4056,8 +4056,7 @@ snd_soc_dapm_alloc_kcontrol(struct snd_soc_card *card,
static struct snd_soc_dapm_widget *
snd_soc_dapm_new_dai(struct snd_soc_card *card, struct snd_soc_pcm_runtime *rtd,
- struct snd_soc_dapm_widget *source,
- struct snd_soc_dapm_widget *sink)
+ char *id)
{
struct snd_soc_dapm_widget template;
struct snd_soc_dapm_widget *w;
@@ -4067,7 +4066,7 @@ snd_soc_dapm_new_dai(struct snd_soc_card *card, struct snd_soc_pcm_runtime *rtd,
int ret;
link_name = devm_kasprintf(card->dev, GFP_KERNEL, "%s-%s",
- source->name, sink->name);
+ rtd->dai_link->name, id);
if (!link_name)
return ERR_PTR(-ENOMEM);
@@ -4247,15 +4246,13 @@ static void dapm_connect_dai_link_widgets(struct snd_soc_card *card,
}
for_each_rtd_codec_dai(rtd, i, codec_dai) {
-
/* connect BE DAI playback if widgets are valid */
codec = codec_dai->playback_widget;
if (playback_cpu && codec) {
if (!playback) {
playback = snd_soc_dapm_new_dai(card, rtd,
- playback_cpu,
- codec);
+ "playback");
if (IS_ERR(playback)) {
dev_err(rtd->dev,
"ASoC: Failed to create DAI %s: %ld\n",
@@ -4284,8 +4281,7 @@ static void dapm_connect_dai_link_widgets(struct snd_soc_card *card,
if (codec && capture_cpu) {
if (!capture) {
capture = snd_soc_dapm_new_dai(card, rtd,
- codec,
- capture_cpu);
+ "capture");
if (IS_ERR(capture)) {
dev_err(rtd->dev,
"ASoC: Failed to create DAI %s: %ld\n",
--
2.20.1
^ permalink raw reply related
* Applied "ASoC: codec2codec: run callbacks in order" to the asoc tree
From: Mark Brown @ 2019-07-25 17:43 UTC (permalink / raw)
To: Jerome Brunet
Cc: alsa-devel, devicetree, Kevin Hilman, Liam Girdwood,
linux-amlogic, linux-kernel, Mark Brown
In-Reply-To: <20190725165949.29699-2-jbrunet@baylibre.com>
The patch
ASoC: codec2codec: run callbacks in order
has been applied to the asoc tree at
https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git for-5.4
All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.
You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.
If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.
Please add any relevant lists and maintainers to the CCs when replying
to this mail.
Thanks,
Mark
>From 68c907f10cd816cad2287167a1a1d77914a6d466 Mon Sep 17 00:00:00 2001
From: Jerome Brunet <jbrunet@baylibre.com>
Date: Thu, 25 Jul 2019 18:59:44 +0200
Subject: [PATCH] ASoC: codec2codec: run callbacks in order
When handling dai_link events on codec to codec links, run all .startup()
callbacks on sinks and sources before running any .hw_params(). Same goes
for hw_free() and shutdown(). This is closer to the behavior of regular
dai links
Signed-off-by: Jerome Brunet <jbrunet@baylibre.com>
Link: https://lore.kernel.org/r/20190725165949.29699-2-jbrunet@baylibre.com
Signed-off-by: Mark Brown <broonie@kernel.org>
---
sound/soc/soc-dapm.c | 36 +++++++++++++++++++++++++++---------
1 file changed, 27 insertions(+), 9 deletions(-)
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c
index 1d04612601ad..034b31fd2ecb 100644
--- a/sound/soc/soc-dapm.c
+++ b/sound/soc/soc-dapm.c
@@ -3835,11 +3835,6 @@ static int snd_soc_dai_link_event(struct snd_soc_dapm_widget *w,
goto out;
}
source->active++;
- ret = snd_soc_dai_hw_params(source, &substream, params);
- if (ret < 0)
- goto out;
-
- dapm_update_dai_unlocked(&substream, params, source);
}
substream.stream = SNDRV_PCM_STREAM_PLAYBACK;
@@ -3853,6 +3848,23 @@ static int snd_soc_dai_link_event(struct snd_soc_dapm_widget *w,
goto out;
}
sink->active++;
+ }
+
+ substream.stream = SNDRV_PCM_STREAM_CAPTURE;
+ snd_soc_dapm_widget_for_each_source_path(w, path) {
+ source = path->source->priv;
+
+ ret = snd_soc_dai_hw_params(source, &substream, params);
+ if (ret < 0)
+ goto out;
+
+ dapm_update_dai_unlocked(&substream, params, source);
+ }
+
+ substream.stream = SNDRV_PCM_STREAM_PLAYBACK;
+ snd_soc_dapm_widget_for_each_sink_path(w, path) {
+ sink = path->sink->priv;
+
ret = snd_soc_dai_hw_params(sink, &substream, params);
if (ret < 0)
goto out;
@@ -3889,9 +3901,18 @@ static int snd_soc_dai_link_event(struct snd_soc_dapm_widget *w,
substream.stream = SNDRV_PCM_STREAM_CAPTURE;
snd_soc_dapm_widget_for_each_source_path(w, path) {
source = path->source->priv;
-
snd_soc_dai_hw_free(source, &substream);
+ }
+
+ substream.stream = SNDRV_PCM_STREAM_PLAYBACK;
+ snd_soc_dapm_widget_for_each_sink_path(w, path) {
+ sink = path->sink->priv;
+ snd_soc_dai_hw_free(sink, &substream);
+ }
+ substream.stream = SNDRV_PCM_STREAM_CAPTURE;
+ snd_soc_dapm_widget_for_each_source_path(w, path) {
+ source = path->source->priv;
source->active--;
snd_soc_dai_shutdown(source, &substream);
}
@@ -3899,9 +3920,6 @@ static int snd_soc_dai_link_event(struct snd_soc_dapm_widget *w,
substream.stream = SNDRV_PCM_STREAM_PLAYBACK;
snd_soc_dapm_widget_for_each_sink_path(w, path) {
sink = path->sink->priv;
-
- snd_soc_dai_hw_free(sink, &substream);
-
sink->active--;
snd_soc_dai_shutdown(sink, &substream);
}
--
2.20.1
^ permalink raw reply related
* Re: [PATCH v4 0/5] soc: ti: k3: Allow for exclusive and shared device requests
From: santosh.shilimkar @ 2019-07-25 17:39 UTC (permalink / raw)
To: Lokesh Vutla, Nishanth Menon, Tero Kristo, Santosh Shilimkar,
Rob Herring
Cc: Device Tree Mailing List, Sekhar Nori, Linux ARM Mailing List
In-Reply-To: <20190722050757.29893-1-lokeshvutla@ti.com>
On 7/21/19 10:07 PM, Lokesh Vutla wrote:
> Sysfw provides an option for requesting exclusive access for a
> device using the flags MSG_FLAG_DEVICE_EXCLUSIVE. If this flag is
> not used, the device is meant to be shared across hosts. Once a device
> is requested from a host with this flag set, any request to this
> device from a different host will be nacked by sysfw.
>
> Current tisci firmware and pm drivers always requests for device with
> exclusive permissions set. But this is not be true for certain devices
> that are expcted to be shared across different host contexts.
> So add support for getting the shared or exclusive permissions from DT
> and request firmware accordingly.
>
> Changes since v3: https://patchwork.kernel.org/project/linux-arm-kernel/list/?series=103447
> - Rebased on top of v5.3-rc1
> - Updated power-domain cells for j721e.
> - Mark the console uart as shared in am65x-base-board
> - Added Reviewed-by from Rob
>
> Lokesh Vutla (5):
> firmware: ti_sci: Allow for device shared and exclusive requests
> dt-bindings: ti_sci_pm_domains: Add support for exclusive and shared
> access
> soc: ti: ti_sci_pm_domains: Add support for exclusive and shared
> access
> arm64: dts: ti: k3-am654: Update the power domain cells
> arm64: dts: ti: k3-j721e: Update the power domain cells
>
> .../bindings/soc/ti/sci-pm-domain.txt | 11 ++++-
> MAINTAINERS | 1 +
> arch/arm64/boot/dts/ti/k3-am65-main.dtsi | 44 +++++++++---------
> arch/arm64/boot/dts/ti/k3-am65-mcu.dtsi | 10 ++---
> arch/arm64/boot/dts/ti/k3-am65-wakeup.dtsi | 6 +--
> arch/arm64/boot/dts/ti/k3-am65.dtsi | 1 +
> .../arm64/boot/dts/ti/k3-am654-base-board.dts | 1 +
> .../dts/ti/k3-j721e-common-proc-board.dts | 4 ++
> arch/arm64/boot/dts/ti/k3-j721e-main.dtsi | 20 ++++-----
> .../boot/dts/ti/k3-j721e-mcu-wakeup.dtsi | 6 +--
> arch/arm64/boot/dts/ti/k3-j721e.dtsi | 1 +
> drivers/firmware/ti_sci.c | 45 ++++++++++++++++++-
> drivers/soc/ti/ti_sci_pm_domains.c | 23 +++++++++-
> include/dt-bindings/soc/ti,sci_pm_domain.h | 9 ++++
> include/linux/soc/ti/ti_sci_protocol.h | 3 ++
> 15 files changed, 136 insertions(+), 49 deletions(-)
> create mode 100644 include/dt-bindings/soc/ti,sci_pm_domain.h
>
Please split this patch series so that drivers and arch, dts patches
can be queued by respective trees.
Regards,
Santosh
^ permalink raw reply
* [PATCH v2] arm64: dts: fast models: Remove clcd's max-memory-bandwidth
From: Kevin Brodsky @ 2019-07-25 17:12 UTC (permalink / raw)
To: linux-arm-kernel
Cc: devicetree, Pawel Moll, Ruben Ayrapetyan, Linus Walleij,
Kevin Brodsky, Liviu Dudau, dri-devel, Sudeep Holla, Robin Murphy,
Brian Starkey
It is unclear why max-memory-bandwidth should be set for CLCD on the
fast model. Removing that property allows allocating and using 32bpp
buffers, which may be desirable on certain platforms such as
Android.
Reported-by: Ruben Ayrapetyan <ruben.ayrapetyan@arm.com>
Signed-off-by: Kevin Brodsky <kevin.brodsky@arm.com>
---
Changes in v2:
- Remove the attribute completely instead of increasing its value. It is
optional and there is no clear reason why it should be set at all.
arch/arm64/boot/dts/arm/fvp-base-revc.dts | 8 --------
arch/arm64/boot/dts/arm/rtsm_ve-motherboard.dtsi | 2 --
2 files changed, 10 deletions(-)
diff --git a/arch/arm64/boot/dts/arm/fvp-base-revc.dts b/arch/arm64/boot/dts/arm/fvp-base-revc.dts
index 687707020ec1..62ab0d54ff71 100644
--- a/arch/arm64/boot/dts/arm/fvp-base-revc.dts
+++ b/arch/arm64/boot/dts/arm/fvp-base-revc.dts
@@ -265,13 +265,5 @@
<0 0 42 &gic 0 0 GIC_SPI 42 IRQ_TYPE_LEVEL_HIGH>,
<0 0 43 &gic 0 0 GIC_SPI 43 IRQ_TYPE_LEVEL_HIGH>,
<0 0 44 &gic 0 0 GIC_SPI 44 IRQ_TYPE_LEVEL_HIGH>;
-
- motherboard {
- iofpga@3,00000000 {
- clcd@1f0000 {
- max-memory-bandwidth = <130000000>; /* 16bpp @ 63.5MHz */
- };
- };
- };
};
};
diff --git a/arch/arm64/boot/dts/arm/rtsm_ve-motherboard.dtsi b/arch/arm64/boot/dts/arm/rtsm_ve-motherboard.dtsi
index 454cf6c44c49..03a7bf079c8f 100644
--- a/arch/arm64/boot/dts/arm/rtsm_ve-motherboard.dtsi
+++ b/arch/arm64/boot/dts/arm/rtsm_ve-motherboard.dtsi
@@ -188,8 +188,6 @@
interrupts = <14>;
clocks = <&v2m_oscclk1>, <&v2m_clk24mhz>;
clock-names = "clcdclk", "apb_pclk";
- /* 800x600 16bpp @36MHz works fine */
- max-memory-bandwidth = <54000000>;
memory-region = <&vram>;
port {
--
2.22.0
^ permalink raw reply related
* [PATCH v2 6/6] ASoC: codec2codec: fill some of the runtime stream parameters
From: Jerome Brunet @ 2019-07-25 16:59 UTC (permalink / raw)
To: Mark Brown, Liam Girdwood, Kevin Hilman
Cc: Jerome Brunet, alsa-devel, devicetree, linux-kernel,
linux-amlogic
In-Reply-To: <20190725165949.29699-1-jbrunet@baylibre.com>
Set the information provided struct snd_soc_pcm_stream in the
struct snd_pcm_runtime of the codec to codec link.
Signed-off-by: Jerome Brunet <jbrunet@baylibre.com>
---
sound/soc/soc-dapm.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c
index 3e3b81ae87dd..fadc804be89c 100644
--- a/sound/soc/soc-dapm.c
+++ b/sound/soc/soc-dapm.c
@@ -3872,6 +3872,11 @@ snd_soc_dai_link_event_pre_pmu(struct snd_soc_dapm_widget *w,
dapm_update_dai_unlocked(substream, params, sink);
}
+ runtime->format = params_format(params);
+ runtime->subformat = params_subformat(params);
+ runtime->channels = params_channels(params);
+ runtime->rate = params_rate(params);
+
out:
if (ret < 0)
kfree(runtime);
--
2.21.0
^ permalink raw reply related
* [PATCH v2 5/6] ASoC: codec2codec: remove ephemeral variables
From: Jerome Brunet @ 2019-07-25 16:59 UTC (permalink / raw)
To: Mark Brown, Liam Girdwood, Kevin Hilman
Cc: Jerome Brunet, alsa-devel, devicetree, linux-kernel,
linux-amlogic
In-Reply-To: <20190725165949.29699-1-jbrunet@baylibre.com>
Now that codec to codec links struct snd_soc_pcm_runtime have lasting pcm
and substreams, let's use them. Alsa allocate and keep the
struct snd_pcm_runtime as long as the link is powered.
Signed-off-by: Jerome Brunet <jbrunet@baylibre.com>
---
sound/soc/soc-dapm.c | 72 ++++++++++++++++++++++++++------------------
1 file changed, 42 insertions(+), 30 deletions(-)
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c
index 6dcaf9ff6eb5..3e3b81ae87dd 100644
--- a/sound/soc/soc-dapm.c
+++ b/sound/soc/soc-dapm.c
@@ -3773,6 +3773,7 @@ snd_soc_dai_link_event_pre_pmu(struct snd_soc_dapm_widget *w,
struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct snd_pcm_hw_params *params = NULL;
const struct snd_soc_pcm_stream *config = NULL;
+ struct snd_pcm_runtime *runtime = NULL;
unsigned int fmt;
int ret;
@@ -3780,6 +3781,14 @@ snd_soc_dai_link_event_pre_pmu(struct snd_soc_dapm_widget *w,
if (!params)
return -ENOMEM;
+ runtime = kzalloc(sizeof(*runtime), GFP_KERNEL);
+ if (!runtime) {
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ substream->runtime = runtime;
+
substream->stream = SNDRV_PCM_STREAM_CAPTURE;
snd_soc_dapm_widget_for_each_source_path(w, path) {
source = path->source->priv;
@@ -3806,6 +3815,8 @@ snd_soc_dai_link_event_pre_pmu(struct snd_soc_dapm_widget *w,
sink->active++;
}
+ substream->hw_opened = 1;
+
/*
* Note: getting the config after .startup() gives a chance to
* either party on the link to alter the configuration if
@@ -3862,6 +3873,9 @@ snd_soc_dai_link_event_pre_pmu(struct snd_soc_dapm_widget *w,
}
out:
+ if (ret < 0)
+ kfree(runtime);
+
kfree(params);
return 0;
}
@@ -3871,29 +3885,16 @@ static int snd_soc_dai_link_event(struct snd_soc_dapm_widget *w,
{
struct snd_soc_dapm_path *path;
struct snd_soc_dai *source, *sink;
- struct snd_soc_pcm_runtime *rtd = w->priv;
- struct snd_pcm_substream substream;
- struct snd_pcm_runtime *runtime = NULL;
- int ret = 0;
+ struct snd_pcm_substream *substream = w->priv;
+ int ret = 0, saved_stream = substream->stream;
if (WARN_ON(list_empty(&w->edges[SND_SOC_DAPM_DIR_OUT]) ||
list_empty(&w->edges[SND_SOC_DAPM_DIR_IN])))
return -EINVAL;
- memset(&substream, 0, sizeof(substream));
-
- /* Allocate a dummy snd_pcm_runtime for startup() and other ops() */
- runtime = kzalloc(sizeof(*runtime), GFP_KERNEL);
- if (!runtime) {
- ret = -ENOMEM;
- goto out;
- }
- substream.runtime = runtime;
- substream.private_data = rtd;
-
switch (event) {
case SND_SOC_DAPM_PRE_PMU:
- ret = snd_soc_dai_link_event_pre_pmu(w, &substream);
+ ret = snd_soc_dai_link_event_pre_pmu(w, substream);
if (ret < 0)
goto out;
@@ -3924,40 +3925,45 @@ static int snd_soc_dai_link_event(struct snd_soc_dapm_widget *w,
ret = 0;
}
- substream.stream = SNDRV_PCM_STREAM_CAPTURE;
+ substream->stream = SNDRV_PCM_STREAM_CAPTURE;
snd_soc_dapm_widget_for_each_source_path(w, path) {
source = path->source->priv;
- snd_soc_dai_hw_free(source, &substream);
+ snd_soc_dai_hw_free(source, substream);
}
- substream.stream = SNDRV_PCM_STREAM_PLAYBACK;
+ substream->stream = SNDRV_PCM_STREAM_PLAYBACK;
snd_soc_dapm_widget_for_each_sink_path(w, path) {
sink = path->sink->priv;
- snd_soc_dai_hw_free(sink, &substream);
+ snd_soc_dai_hw_free(sink, substream);
}
- substream.stream = SNDRV_PCM_STREAM_CAPTURE;
+ substream->stream = SNDRV_PCM_STREAM_CAPTURE;
snd_soc_dapm_widget_for_each_source_path(w, path) {
source = path->source->priv;
source->active--;
- snd_soc_dai_shutdown(source, &substream);
+ snd_soc_dai_shutdown(source, substream);
}
- substream.stream = SNDRV_PCM_STREAM_PLAYBACK;
+ substream->stream = SNDRV_PCM_STREAM_PLAYBACK;
snd_soc_dapm_widget_for_each_sink_path(w, path) {
sink = path->sink->priv;
sink->active--;
- snd_soc_dai_shutdown(sink, &substream);
+ snd_soc_dai_shutdown(sink, substream);
}
break;
+ case SND_SOC_DAPM_POST_PMD:
+ kfree(substream->runtime);
+ break;
+
default:
WARN(1, "Unknown event %d\n", event);
ret = -EINVAL;
}
out:
- kfree(runtime);
+ /* Restore the substream direction */
+ substream->stream = saved_stream;
return ret;
}
@@ -4080,9 +4086,11 @@ snd_soc_dapm_alloc_kcontrol(struct snd_soc_card *card,
}
static struct snd_soc_dapm_widget *
-snd_soc_dapm_new_dai(struct snd_soc_card *card, struct snd_soc_pcm_runtime *rtd,
+snd_soc_dapm_new_dai(struct snd_soc_card *card,
+ struct snd_pcm_substream *substream,
char *id)
{
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct snd_soc_dapm_widget template;
struct snd_soc_dapm_widget *w;
const char **w_param_text;
@@ -4101,7 +4109,7 @@ snd_soc_dapm_new_dai(struct snd_soc_card *card, struct snd_soc_pcm_runtime *rtd,
template.name = link_name;
template.event = snd_soc_dai_link_event;
template.event_flags = SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
- SND_SOC_DAPM_PRE_PMD;
+ SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD;
template.kcontrol_news = NULL;
/* allocate memory for control, only in case of multiple configs */
@@ -4136,7 +4144,7 @@ snd_soc_dapm_new_dai(struct snd_soc_card *card, struct snd_soc_pcm_runtime *rtd,
goto outfree_kcontrol_news;
}
- w->priv = rtd;
+ w->priv = substream;
return w;
@@ -4258,6 +4266,8 @@ static void dapm_connect_dai_link_widgets(struct snd_soc_card *card,
struct snd_soc_dai *codec_dai;
struct snd_soc_dapm_widget *playback = NULL, *capture = NULL;
struct snd_soc_dapm_widget *codec, *playback_cpu, *capture_cpu;
+ struct snd_pcm_substream *substream;
+ struct snd_pcm_str *streams = rtd->pcm->streams;
int i;
if (rtd->dai_link->params) {
@@ -4276,7 +4286,8 @@ static void dapm_connect_dai_link_widgets(struct snd_soc_card *card,
if (playback_cpu && codec) {
if (!playback) {
- playback = snd_soc_dapm_new_dai(card, rtd,
+ substream = streams[SNDRV_PCM_STREAM_PLAYBACK].substream;
+ playback = snd_soc_dapm_new_dai(card, substream,
"playback");
if (IS_ERR(playback)) {
dev_err(rtd->dev,
@@ -4305,7 +4316,8 @@ static void dapm_connect_dai_link_widgets(struct snd_soc_card *card,
if (codec && capture_cpu) {
if (!capture) {
- capture = snd_soc_dapm_new_dai(card, rtd,
+ substream = streams[SNDRV_PCM_STREAM_CAPTURE].substream;
+ capture = snd_soc_dapm_new_dai(card, substream,
"capture");
if (IS_ERR(capture)) {
dev_err(rtd->dev,
--
2.21.0
^ permalink raw reply related
* [PATCH v2 4/6] ASoC: create pcm for codec2codec links as well
From: Jerome Brunet @ 2019-07-25 16:59 UTC (permalink / raw)
To: Mark Brown, Liam Girdwood, Kevin Hilman
Cc: Jerome Brunet, alsa-devel, devicetree, linux-kernel,
linux-amlogic
In-Reply-To: <20190725165949.29699-1-jbrunet@baylibre.com>
At the moment, codec to codec links uses an ephemeral variable for
the struct snd_pcm_substream. Also the struct snd_soc_pcm_runtime
does not have real struct snd_pcm.
This might a problem if the functions used by a codec on codec to
codec link expect these structures to exist, and keep on existing
during the life of the codec.
For example, it is the case of the hdmi-codec, which uses
snd_pcm_add_chmap_ctls(). For the controls to works, the pcm and
substream must to exist.
This change is first step, it create pcm (and substreams) for codec
to codec links, in the same way as dpcm backend links.
Signed-off-by: Jerome Brunet <jbrunet@baylibre.com>
---
sound/soc/soc-core.c | 42 ++++++++++++------------------------------
sound/soc/soc-pcm.c | 35 ++++++++++++++++++++++++++++++++---
2 files changed, 44 insertions(+), 33 deletions(-)
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index 7ecfe641ca46..9e8eb93c8a3f 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -447,16 +447,6 @@ static void snd_soc_flush_all_delayed_work(struct snd_soc_card *card)
flush_delayed_work(&rtd->delayed_work);
}
-static void codec2codec_close_delayed_work(struct work_struct *work)
-{
- /*
- * Currently nothing to do for c2c links
- * Since c2c links are internal nodes in the DAPM graph and
- * don't interface with the outside world or application layer
- * we don't have to do any special handling on close.
- */
-}
-
#ifdef CONFIG_PM_SLEEP
/* powers down audio subsystem for suspend */
int snd_soc_suspend(struct device *dev)
@@ -1552,27 +1542,19 @@ static int soc_probe_link_dais(struct snd_soc_card *card,
return ret;
}
- if (!dai_link->params) {
- /* create the pcm */
- ret = soc_new_pcm(rtd, num);
- if (ret < 0) {
- dev_err(card->dev, "ASoC: can't create pcm %s :%d\n",
- dai_link->stream_name, ret);
- return ret;
- }
- ret = soc_link_dai_pcm_new(&cpu_dai, 1, rtd);
- if (ret < 0)
- return ret;
- ret = soc_link_dai_pcm_new(rtd->codec_dais,
- rtd->num_codecs, rtd);
- if (ret < 0)
- return ret;
- } else {
- INIT_DELAYED_WORK(&rtd->delayed_work,
- codec2codec_close_delayed_work);
+ /* create the pcm */
+ ret = soc_new_pcm(rtd, num);
+ if (ret < 0) {
+ dev_err(card->dev, "ASoC: can't create pcm %s :%d\n",
+ dai_link->stream_name, ret);
+ return ret;
}
-
- return 0;
+ ret = soc_link_dai_pcm_new(&cpu_dai, 1, rtd);
+ if (ret < 0)
+ return ret;
+ ret = soc_link_dai_pcm_new(rtd->codec_dais,
+ rtd->num_codecs, rtd);
+ return ret;
}
static int soc_bind_aux_dev(struct snd_soc_card *card, int num)
diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c
index fabeac164a6c..30264bc592f6 100644
--- a/sound/soc/soc-pcm.c
+++ b/sound/soc/soc-pcm.c
@@ -678,6 +678,16 @@ static void close_delayed_work(struct work_struct *work)
mutex_unlock(&rtd->pcm_mutex);
}
+static void codec2codec_close_delayed_work(struct work_struct *work)
+{
+ /*
+ * Currently nothing to do for c2c links
+ * Since c2c links are internal nodes in the DAPM graph and
+ * don't interface with the outside world or application layer
+ * we don't have to do any special handling on close.
+ */
+}
+
/*
* Called by ALSA when a PCM substream is closed. Private data can be
* freed here. The cpu DAI, codec DAI, machine and components are also
@@ -3011,6 +3021,12 @@ int soc_new_pcm(struct snd_soc_pcm_runtime *rtd, int num)
playback = rtd->dai_link->dpcm_playback;
capture = rtd->dai_link->dpcm_capture;
} else {
+ /* Adapt stream for codec2codec links */
+ struct snd_soc_pcm_stream *cpu_capture = rtd->dai_link->params ?
+ &cpu_dai->driver->playback : &cpu_dai->driver->capture;
+ struct snd_soc_pcm_stream *cpu_playback = rtd->dai_link->params ?
+ &cpu_dai->driver->capture : &cpu_dai->driver->playback;
+
for_each_rtd_codec_dai(rtd, i, codec_dai) {
if (snd_soc_dai_stream_valid(codec_dai, SNDRV_PCM_STREAM_PLAYBACK) &&
snd_soc_dai_stream_valid(cpu_dai, SNDRV_PCM_STREAM_PLAYBACK))
@@ -3019,6 +3035,9 @@ int soc_new_pcm(struct snd_soc_pcm_runtime *rtd, int num)
snd_soc_dai_stream_valid(cpu_dai, SNDRV_PCM_STREAM_CAPTURE))
capture = 1;
}
+
+ capture = capture && cpu_capture->channels_min;
+ playback = playback && cpu_playback->channels_min;
}
if (rtd->dai_link->playback_only) {
@@ -3032,7 +3051,13 @@ int soc_new_pcm(struct snd_soc_pcm_runtime *rtd, int num)
}
/* create the PCM */
- if (rtd->dai_link->no_pcm) {
+ if (rtd->dai_link->params) {
+ snprintf(new_name, sizeof(new_name), "codec2codec(%s)",
+ rtd->dai_link->stream_name);
+
+ ret = snd_pcm_new_internal(rtd->card->snd_card, new_name, num,
+ playback, capture, &pcm);
+ } else if (rtd->dai_link->no_pcm) {
snprintf(new_name, sizeof(new_name), "(%s)",
rtd->dai_link->stream_name);
@@ -3059,13 +3084,17 @@ int soc_new_pcm(struct snd_soc_pcm_runtime *rtd, int num)
dev_dbg(rtd->card->dev, "ASoC: registered pcm #%d %s\n",num, new_name);
/* DAPM dai link stream work */
- INIT_DELAYED_WORK(&rtd->delayed_work, close_delayed_work);
+ if (rtd->dai_link->params)
+ INIT_DELAYED_WORK(&rtd->delayed_work,
+ codec2codec_close_delayed_work);
+ else
+ INIT_DELAYED_WORK(&rtd->delayed_work, close_delayed_work);
pcm->nonatomic = rtd->dai_link->nonatomic;
rtd->pcm = pcm;
pcm->private_data = rtd;
- if (rtd->dai_link->no_pcm) {
+ if (rtd->dai_link->no_pcm || rtd->dai_link->params) {
if (playback)
pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream->private_data = rtd;
if (capture)
--
2.21.0
^ permalink raw reply related
* [PATCH v2 3/6] ASoC: codec2codec: deal with params when necessary
From: Jerome Brunet @ 2019-07-25 16:59 UTC (permalink / raw)
To: Mark Brown, Liam Girdwood, Kevin Hilman
Cc: Jerome Brunet, alsa-devel, devicetree, linux-kernel,
linux-amlogic
In-Reply-To: <20190725165949.29699-1-jbrunet@baylibre.com>
When there is an event on codec to codec dai_link, we only need to deal
with params if the event is SND_SOC_DAPM_PRE_PMU, when .hw_params() is
called. For the other events, it is useless.
Also, dealing with the codec to codec params just before calling
.hw_params() callbacks give change to either party on the link to alter
params content in .startup(), which might be useful in some cases
Signed-off-by: Jerome Brunet <jbrunet@baylibre.com>
---
sound/soc/soc-dapm.c | 159 +++++++++++++++++++++++++------------------
1 file changed, 92 insertions(+), 67 deletions(-)
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c
index 7db4abd9a0a5..6dcaf9ff6eb5 100644
--- a/sound/soc/soc-dapm.c
+++ b/sound/soc/soc-dapm.c
@@ -3764,25 +3764,59 @@ int snd_soc_dapm_new_controls(struct snd_soc_dapm_context *dapm,
}
EXPORT_SYMBOL_GPL(snd_soc_dapm_new_controls);
-static int snd_soc_dai_link_event(struct snd_soc_dapm_widget *w,
- struct snd_kcontrol *kcontrol, int event)
+static int
+snd_soc_dai_link_event_pre_pmu(struct snd_soc_dapm_widget *w,
+ struct snd_pcm_substream *substream)
{
struct snd_soc_dapm_path *path;
struct snd_soc_dai *source, *sink;
- struct snd_soc_pcm_runtime *rtd = w->priv;
- const struct snd_soc_pcm_stream *config;
- struct snd_pcm_substream substream;
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct snd_pcm_hw_params *params = NULL;
- struct snd_pcm_runtime *runtime = NULL;
+ const struct snd_soc_pcm_stream *config = NULL;
unsigned int fmt;
- int ret = 0;
+ int ret;
- config = rtd->dai_link->params + rtd->params_select;
+ params = kzalloc(sizeof(*params), GFP_KERNEL);
+ if (!params)
+ return -ENOMEM;
- if (WARN_ON(!config) ||
- WARN_ON(list_empty(&w->edges[SND_SOC_DAPM_DIR_OUT]) ||
- list_empty(&w->edges[SND_SOC_DAPM_DIR_IN])))
- return -EINVAL;
+ substream->stream = SNDRV_PCM_STREAM_CAPTURE;
+ snd_soc_dapm_widget_for_each_source_path(w, path) {
+ source = path->source->priv;
+
+ ret = snd_soc_dai_startup(source, substream);
+ if (ret < 0) {
+ dev_err(source->dev,
+ "ASoC: startup() failed: %d\n", ret);
+ goto out;
+ }
+ source->active++;
+ }
+
+ substream->stream = SNDRV_PCM_STREAM_PLAYBACK;
+ snd_soc_dapm_widget_for_each_sink_path(w, path) {
+ sink = path->sink->priv;
+
+ ret = snd_soc_dai_startup(sink, substream);
+ if (ret < 0) {
+ dev_err(sink->dev,
+ "ASoC: startup() failed: %d\n", ret);
+ goto out;
+ }
+ sink->active++;
+ }
+
+ /*
+ * Note: getting the config after .startup() gives a chance to
+ * either party on the link to alter the configuration if
+ * necessary
+ */
+ config = rtd->dai_link->params + rtd->params_select;
+ if (WARN_ON(!config)) {
+ dev_err(w->dapm->dev, "ASoC: link config missing\n");
+ ret = -EINVAL;
+ goto out;
+ }
/* Be a little careful as we don't want to overflow the mask array */
if (config->formats) {
@@ -3790,27 +3824,62 @@ static int snd_soc_dai_link_event(struct snd_soc_dapm_widget *w,
} else {
dev_warn(w->dapm->dev, "ASoC: Invalid format %llx specified\n",
config->formats);
- fmt = 0;
- }
- /* Currently very limited parameter selection */
- params = kzalloc(sizeof(*params), GFP_KERNEL);
- if (!params) {
- ret = -ENOMEM;
+ ret = -EINVAL;
goto out;
}
- snd_mask_set(hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT), fmt);
+ snd_mask_set(hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT), fmt);
hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE)->min =
config->rate_min;
hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE)->max =
config->rate_max;
-
hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS)->min
= config->channels_min;
hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS)->max
= config->channels_max;
+ substream->stream = SNDRV_PCM_STREAM_CAPTURE;
+ snd_soc_dapm_widget_for_each_source_path(w, path) {
+ source = path->source->priv;
+
+ ret = snd_soc_dai_hw_params(source, substream, params);
+ if (ret < 0)
+ goto out;
+
+ dapm_update_dai_unlocked(substream, params, source);
+ }
+
+ substream->stream = SNDRV_PCM_STREAM_PLAYBACK;
+ snd_soc_dapm_widget_for_each_sink_path(w, path) {
+ sink = path->sink->priv;
+
+ ret = snd_soc_dai_hw_params(sink, substream, params);
+ if (ret < 0)
+ goto out;
+
+ dapm_update_dai_unlocked(substream, params, sink);
+ }
+
+out:
+ kfree(params);
+ return 0;
+}
+
+static int snd_soc_dai_link_event(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol, int event)
+{
+ struct snd_soc_dapm_path *path;
+ struct snd_soc_dai *source, *sink;
+ struct snd_soc_pcm_runtime *rtd = w->priv;
+ struct snd_pcm_substream substream;
+ struct snd_pcm_runtime *runtime = NULL;
+ int ret = 0;
+
+ if (WARN_ON(list_empty(&w->edges[SND_SOC_DAPM_DIR_OUT]) ||
+ list_empty(&w->edges[SND_SOC_DAPM_DIR_IN])))
+ return -EINVAL;
+
memset(&substream, 0, sizeof(substream));
/* Allocate a dummy snd_pcm_runtime for startup() and other ops() */
@@ -3824,53 +3893,10 @@ static int snd_soc_dai_link_event(struct snd_soc_dapm_widget *w,
switch (event) {
case SND_SOC_DAPM_PRE_PMU:
- substream.stream = SNDRV_PCM_STREAM_CAPTURE;
- snd_soc_dapm_widget_for_each_source_path(w, path) {
- source = path->source->priv;
-
- ret = snd_soc_dai_startup(source, &substream);
- if (ret < 0) {
- dev_err(source->dev,
- "ASoC: startup() failed: %d\n", ret);
- goto out;
- }
- source->active++;
- }
-
- substream.stream = SNDRV_PCM_STREAM_PLAYBACK;
- snd_soc_dapm_widget_for_each_sink_path(w, path) {
- sink = path->sink->priv;
-
- ret = snd_soc_dai_startup(sink, &substream);
- if (ret < 0) {
- dev_err(sink->dev,
- "ASoC: startup() failed: %d\n", ret);
- goto out;
- }
- sink->active++;
- }
-
- substream.stream = SNDRV_PCM_STREAM_CAPTURE;
- snd_soc_dapm_widget_for_each_source_path(w, path) {
- source = path->source->priv;
-
- ret = snd_soc_dai_hw_params(source, &substream, params);
- if (ret < 0)
- goto out;
-
- dapm_update_dai_unlocked(&substream, params, source);
- }
-
- substream.stream = SNDRV_PCM_STREAM_PLAYBACK;
- snd_soc_dapm_widget_for_each_sink_path(w, path) {
- sink = path->sink->priv;
-
- ret = snd_soc_dai_hw_params(sink, &substream, params);
- if (ret < 0)
- goto out;
+ ret = snd_soc_dai_link_event_pre_pmu(w, &substream);
+ if (ret < 0)
+ goto out;
- dapm_update_dai_unlocked(&substream, params, sink);
- }
break;
case SND_SOC_DAPM_POST_PMU:
@@ -3932,7 +3958,6 @@ static int snd_soc_dai_link_event(struct snd_soc_dapm_widget *w,
out:
kfree(runtime);
- kfree(params);
return ret;
}
--
2.21.0
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox