ARM SCMI updates for v5.12

Addition of optional interrupt to signal completion of the request when
 using SMC/HVC transport as on some platforms they can return before the
 SCMI request is completed. Apart from that, we just have a minor fix in
 scmi_remove which was found recently as we are now experimenting more on
 SCMI as module. Finally, we are adding Cristian as official reviewer for
 SCMI since he is more involved in active development of new features.
 -----BEGIN PGP SIGNATURE-----
 
 iQIzBAABCAAdFiEEunHlEgbzHrJD3ZPhAEG6vDF+4pgFAmAIakMACgkQAEG6vDF+
 4pjxbA/+Og3HGOwlzk2ul69r25+pYXBnP8Fad0DHPAdJ6kR/5R4QG/pABtTEvbED
 jRWTxHTrXjaMkp+rKl+KkeRj0Z41cKSyIlbrRpZCj8vg9t5i4RfUKAk+5+vbOc1p
 RG6zaNShILyzw/gQwQvk7gDcuz/jrT3Mb+yMAqisXEpmO97qTsXb8DDVdAIne5HW
 7+jLsNWAeaave3igJzje46/nTtHJ6QQnCQVYbzW4AOzO7ACEVNl1iK9etHxoYEsL
 1fRwCVPZBszfwxXzdfV8jJTAoLCJpeOJ3GLpmyhtmAWFT+FLMtQVPyZNtaySji7Q
 phFzum5blX7gnWcBijBTPfOsNxBYOR1ZrMuY7MfGMGSt7LTujoYFCL5po3yWrfWz
 jcNlY6Y7Bu3ntELYMgnJ9nwmfCY6dT6oeeR3SVZ0F18HvJle49RgeIs90y4F/eVa
 sTQWm65MeKGqppj71fYC8B47J6QMVpkyJgufkWV8JovhuHnSkmW5MD6iFJeVY3Iy
 eG8BlfMqx3Bc0qFr25CHDcvgVdJphxn536MRMlfVnCG79oT3Gg3XONY0s5t9b3bd
 gKIXizSCAEbfBweLGproSV7keVN6lz68A/ZmY8F0k1f9YKwtZURDUpd6wg5Z2/4a
 eY0Z3SHF07LAciyiXrq4RXPqkoC9dxhtz5k/phkLlVmhDsFo+VU=
 =42bR
 -----END PGP SIGNATURE-----

Merge tag 'scmi-updates-5.12' of git://git.kernel.org/pub/scm/linux/kernel/git/sudeep.holla/linux into arm/drivers

ARM SCMI updates for v5.12

Addition of optional interrupt to signal completion of the request when
using SMC/HVC transport as on some platforms they can return before the
SCMI request is completed. Apart from that, we just have a minor fix in
scmi_remove which was found recently as we are now experimenting more on
SCMI as module. Finally, we are adding Cristian as official reviewer for
SCMI since he is more involved in active development of new features.

* tag 'scmi-updates-5.12' of git://git.kernel.org/pub/scm/linux/kernel/git/sudeep.holla/linux:
  firmware: arm_scmi: Fix call site of scmi_notification_exit
  MAINTAINERS: Update ARM SCMI entry
  firmware: arm_scmi: Augment SMC/HVC to allow optional interrupt
  dt-bindings: arm: Add optional interrupt to smc/hvc SCMI transport

Link: https://lore.kernel.org/r/20210120174356.cnxopzjjpqo5e3ws@bogus
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
This commit is contained in:
Arnd Bergmann 2021-01-22 15:28:16 +01:00
commit e6babd8dde
4 changed files with 53 additions and 3 deletions

View File

@ -31,6 +31,14 @@ Optional properties:
- mbox-names: shall be "tx" or "rx" depending on mboxes entries.
- interrupts : when using smc or hvc transports, this optional
property indicates that msg completion by the platform is indicated
by an interrupt rather than by the return of the smc call. This
should not be used except when the platform requires such behavior.
- interrupt-names : if "interrupts" is present, interrupt-names must also
be present and have the value "a2p".
See Documentation/devicetree/bindings/mailbox/mailbox.txt for more details
about the generic mailbox controller and client driver bindings.

View File

@ -17208,6 +17208,7 @@ F: drivers/mfd/syscon.c
SYSTEM CONTROL & POWER/MANAGEMENT INTERFACE (SCPI/SCMI) Message Protocol drivers
M: Sudeep Holla <sudeep.holla@arm.com>
R: Cristian Marussi <cristian.marussi@arm.com>
L: linux-arm-kernel@lists.infradead.org
S: Maintained
F: Documentation/devicetree/bindings/arm/arm,sc[mp]i.txt
@ -17215,6 +17216,7 @@ F: drivers/clk/clk-sc[mp]i.c
F: drivers/cpufreq/sc[mp]i-cpufreq.c
F: drivers/firmware/arm_scmi/
F: drivers/firmware/arm_scpi.c
F: drivers/regulator/scmi-regulator.c
F: drivers/reset/reset-scmi.c
F: include/linux/sc[mp]i_protocol.h
F: include/trace/events/scmi.h

View File

@ -848,8 +848,6 @@ static int scmi_remove(struct platform_device *pdev)
struct scmi_info *info = platform_get_drvdata(pdev);
struct idr *idr = &info->tx_idr;
scmi_notification_exit(&info->handle);
mutex_lock(&scmi_list_mutex);
if (info->users)
ret = -EBUSY;
@ -860,6 +858,8 @@ static int scmi_remove(struct platform_device *pdev)
if (ret)
return ret;
scmi_notification_exit(&info->handle);
/* Safe to free channels since no more users */
ret = idr_for_each(idr, info->desc->ops->chan_free, idr);
idr_destroy(&info->tx_idr);

View File

@ -9,9 +9,11 @@
#include <linux/arm-smccc.h>
#include <linux/device.h>
#include <linux/err.h>
#include <linux/interrupt.h>
#include <linux/mutex.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/of_irq.h>
#include <linux/slab.h>
#include "common.h"
@ -23,6 +25,8 @@
* @shmem: Transmit/Receive shared memory area
* @shmem_lock: Lock to protect access to Tx/Rx shared memory area
* @func_id: smc/hvc call function id
* @irq: Optional; employed when platforms indicates msg completion by intr.
* @tx_complete: Optional, employed only when irq is valid.
*/
struct scmi_smc {
@ -30,8 +34,19 @@ struct scmi_smc {
struct scmi_shared_mem __iomem *shmem;
struct mutex shmem_lock;
u32 func_id;
int irq;
struct completion tx_complete;
};
static irqreturn_t smc_msg_done_isr(int irq, void *data)
{
struct scmi_smc *scmi_info = data;
complete(&scmi_info->tx_complete);
return IRQ_HANDLED;
}
static bool smc_chan_available(struct device *dev, int idx)
{
struct device_node *np = of_parse_phandle(dev->of_node, "shmem", 0);
@ -51,7 +66,7 @@ static int smc_chan_setup(struct scmi_chan_info *cinfo, struct device *dev,
struct resource res;
struct device_node *np;
u32 func_id;
int ret;
int ret, irq;
if (!tx)
return -ENODEV;
@ -79,6 +94,24 @@ static int smc_chan_setup(struct scmi_chan_info *cinfo, struct device *dev,
if (ret < 0)
return ret;
/*
* If there is an interrupt named "a2p", then the service and
* completion of a message is signaled by an interrupt rather than by
* the return of the SMC call.
*/
irq = of_irq_get_byname(cdev->of_node, "a2p");
if (irq > 0) {
ret = devm_request_irq(dev, irq, smc_msg_done_isr,
IRQF_NO_SUSPEND,
dev_name(dev), scmi_info);
if (ret) {
dev_err(dev, "failed to setup SCMI smc irq\n");
return ret;
}
init_completion(&scmi_info->tx_complete);
scmi_info->irq = irq;
}
scmi_info->func_id = func_id;
scmi_info->cinfo = cinfo;
mutex_init(&scmi_info->shmem_lock);
@ -110,7 +143,14 @@ static int smc_send_message(struct scmi_chan_info *cinfo,
shmem_tx_prepare(scmi_info->shmem, xfer);
if (scmi_info->irq)
reinit_completion(&scmi_info->tx_complete);
arm_smccc_1_1_invoke(scmi_info->func_id, 0, 0, 0, 0, 0, 0, 0, &res);
if (scmi_info->irq)
wait_for_completion(&scmi_info->tx_complete);
scmi_rx_callback(scmi_info->cinfo, shmem_read_header(scmi_info->shmem));
mutex_unlock(&scmi_info->shmem_lock);