Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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

Arm SCMI driver updates for v6.11

The main addition this time is the support for platform to agent(p2a
also referred sometimes as notification or Rx) channel completion via
interrupt driven method. Currently, the OSPM agent clears or
acknowledge the receipt of the norification or delayed response by
updating the flags in the shared memory region which the platform is
expected to poll.

On some platforms that are completely interrupt driven, the OSPM
agent is expected to send a response message instead. This change
adds the support for the same.

Other changes include addition of a separate mailing list specific to
SCMI to allow open discussions about the interface itself in addition
to the kernel driver updates and support for system suspend via the
platform noification used on some systems.

* tag 'scmi-updates-6.11' of git://git.kernel.org/pub/scm/linux/kernel/git/sudeep.holla/linux:
firmware: arm_scmi: Add support for platform to agent channel completion
dt-bindings: firmware: arm,scmi: Add support for notification completion channel
firmware: arm_scmi: Add support for system suspend in power control driver
MAINTAINERS: Add mailing list for SCMI drivers

Link: https://lore.kernel.org/r/20240620093924.375244-3-sudeep.holla@arm.com
Signed-off-by: Arnd Bergmann <arnd@arndb.de>

+86 -11
+8 -4
Documentation/devicetree/bindings/firmware/arm,scmi.yaml
··· 72 72 - const: tx 73 73 - const: tx_reply 74 74 - const: rx 75 + - const: rx_reply 75 76 minItems: 2 76 77 77 78 mboxes: 78 79 description: 79 80 List of phandle and mailbox channel specifiers. It should contain 80 - exactly one, two or three mailboxes; the first one or two for transmitting 81 - messages ("tx") and another optional ("rx") for receiving notifications 82 - and delayed responses, if supported by the platform. 81 + exactly one, two, three or four mailboxes; the first one or two for 82 + transmitting messages ("tx") and another optional ("rx") for receiving 83 + notifications and delayed responses, if supported by the platform. 84 + The optional ("rx_reply") is for notifications completion interrupt, 85 + if supported by the platform. 83 86 The number of mailboxes needed for transmitting messages depends on the 84 87 type of channels exposed by the specific underlying mailbox controller; 85 88 one single channel descriptor is enough if such channel is bidirectional, ··· 95 92 2 mbox / 2 shmem => SCMI TX and RX over 2 mailbox bidirectional channels 96 93 2 mbox / 1 shmem => SCMI TX over 2 mailbox unidirectional channels 97 94 3 mbox / 2 shmem => SCMI TX and RX over 3 mailbox unidirectional channels 95 + 4 mbox / 2 shmem => SCMI TX and RX over 4 mailbox unidirectional channels 98 96 Any other combination of mboxes and shmem is invalid. 99 97 minItems: 1 100 - maxItems: 3 98 + maxItems: 4 101 99 102 100 shmem: 103 101 description:
+1
MAINTAINERS
··· 21795 21795 SYSTEM CONTROL & POWER/MANAGEMENT INTERFACE (SCPI/SCMI) Message Protocol drivers 21796 21796 M: Sudeep Holla <sudeep.holla@arm.com> 21797 21797 R: Cristian Marussi <cristian.marussi@arm.com> 21798 + L: arm-scmi@vger.kernel.org 21798 21799 L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) 21799 21800 S: Maintained 21800 21801 F: Documentation/devicetree/bindings/firmware/arm,sc[mp]i.yaml
+1
drivers/firmware/arm_scmi/common.h
··· 326 326 bool shmem_poll_done(struct scmi_shared_mem __iomem *shmem, 327 327 struct scmi_xfer *xfer); 328 328 bool shmem_channel_free(struct scmi_shared_mem __iomem *shmem); 329 + bool shmem_channel_intr_enabled(struct scmi_shared_mem __iomem *shmem); 329 330 330 331 /* declarations for message passing transports */ 331 332 struct scmi_msg_payld;
+51 -6
drivers/firmware/arm_scmi/mailbox.c
··· 21 21 * @cl: Mailbox Client 22 22 * @chan: Transmit/Receive mailbox uni/bi-directional channel 23 23 * @chan_receiver: Optional Receiver mailbox unidirectional channel 24 + * @chan_platform_receiver: Optional Platform Receiver mailbox unidirectional channel 24 25 * @cinfo: SCMI channel info 25 26 * @shmem: Transmit/Receive shared memory area 26 27 */ ··· 29 28 struct mbox_client cl; 30 29 struct mbox_chan *chan; 31 30 struct mbox_chan *chan_receiver; 31 + struct mbox_chan *chan_platform_receiver; 32 32 struct scmi_chan_info *cinfo; 33 33 struct scmi_shared_mem __iomem *shmem; 34 34 }; ··· 93 91 * for replies on the a2p channel. Set as zero if not present. 94 92 * @p2a_chan: A reference to the optional p2a channel. 95 93 * Set as zero if not present. 94 + * @p2a_rx_chan: A reference to the optional p2a completion channel. 95 + * Set as zero if not present. 96 96 * 97 97 * At first, validate the transport configuration as described in terms of 98 98 * 'mboxes' and 'shmem', then determin which mailbox channel indexes are ··· 102 98 * 103 99 * Return: 0 on Success or error 104 100 */ 105 - static int mailbox_chan_validate(struct device *cdev, 106 - int *a2p_rx_chan, int *p2a_chan) 101 + static int mailbox_chan_validate(struct device *cdev, int *a2p_rx_chan, 102 + int *p2a_chan, int *p2a_rx_chan) 107 103 { 108 104 int num_mb, num_sh, ret = 0; 109 105 struct device_node *np = cdev->of_node; ··· 113 109 dev_dbg(cdev, "Found %d mboxes and %d shmems !\n", num_mb, num_sh); 114 110 115 111 /* Bail out if mboxes and shmem descriptors are inconsistent */ 116 - if (num_mb <= 0 || num_sh <= 0 || num_sh > 2 || num_mb > 3 || 117 - (num_mb == 1 && num_sh != 1) || (num_mb == 3 && num_sh != 2)) { 112 + if (num_mb <= 0 || num_sh <= 0 || num_sh > 2 || num_mb > 4 || 113 + (num_mb == 1 && num_sh != 1) || (num_mb == 3 && num_sh != 2) || 114 + (num_mb == 4 && num_sh != 2)) { 118 115 dev_warn(cdev, 119 116 "Invalid channel descriptor for '%s' - mbs:%d shm:%d\n", 120 117 of_node_full_name(np), num_mb, num_sh); ··· 144 139 case 1: 145 140 *a2p_rx_chan = 0; 146 141 *p2a_chan = 0; 142 + *p2a_rx_chan = 0; 147 143 break; 148 144 case 2: 149 145 if (num_sh == 2) { ··· 154 148 *a2p_rx_chan = 1; 155 149 *p2a_chan = 0; 156 150 } 151 + *p2a_rx_chan = 0; 157 152 break; 158 153 case 3: 159 154 *a2p_rx_chan = 1; 160 155 *p2a_chan = 2; 156 + *p2a_rx_chan = 0; 157 + break; 158 + case 4: 159 + *a2p_rx_chan = 1; 160 + *p2a_chan = 2; 161 + *p2a_rx_chan = 3; 161 162 break; 162 163 } 163 164 } ··· 179 166 struct device *cdev = cinfo->dev; 180 167 struct scmi_mailbox *smbox; 181 168 struct device_node *shmem; 182 - int ret, a2p_rx_chan, p2a_chan, idx = tx ? 0 : 1; 169 + int ret, a2p_rx_chan, p2a_chan, p2a_rx_chan, idx = tx ? 0 : 1; 183 170 struct mbox_client *cl; 184 171 resource_size_t size; 185 172 struct resource res; 186 173 187 - ret = mailbox_chan_validate(cdev, &a2p_rx_chan, &p2a_chan); 174 + ret = mailbox_chan_validate(cdev, &a2p_rx_chan, &p2a_chan, &p2a_rx_chan); 188 175 if (ret) 189 176 return ret; 190 177 ··· 242 229 } 243 230 } 244 231 232 + if (!tx && p2a_rx_chan) { 233 + smbox->chan_platform_receiver = mbox_request_channel(cl, p2a_rx_chan); 234 + if (IS_ERR(smbox->chan_platform_receiver)) { 235 + ret = PTR_ERR(smbox->chan_platform_receiver); 236 + if (ret != -EPROBE_DEFER) 237 + dev_err(cdev, "failed to request SCMI P2A Receiver mailbox\n"); 238 + return ret; 239 + } 240 + } 241 + 242 + 245 243 cinfo->transport_info = smbox; 246 244 smbox->cinfo = cinfo; 247 245 ··· 267 243 if (smbox && !IS_ERR(smbox->chan)) { 268 244 mbox_free_channel(smbox->chan); 269 245 mbox_free_channel(smbox->chan_receiver); 246 + mbox_free_channel(smbox->chan_platform_receiver); 270 247 cinfo->transport_info = NULL; 271 248 smbox->chan = NULL; 272 249 smbox->chan_receiver = NULL; 250 + smbox->chan_platform_receiver = NULL; 273 251 smbox->cinfo = NULL; 274 252 } 275 253 ··· 326 300 static void mailbox_clear_channel(struct scmi_chan_info *cinfo) 327 301 { 328 302 struct scmi_mailbox *smbox = cinfo->transport_info; 303 + struct mbox_chan *intr_chan; 304 + int ret; 329 305 330 306 shmem_clear_channel(smbox->shmem); 307 + 308 + if (!shmem_channel_intr_enabled(smbox->shmem)) 309 + return; 310 + 311 + if (smbox->chan_platform_receiver) 312 + intr_chan = smbox->chan_platform_receiver; 313 + else if (smbox->chan) 314 + intr_chan = smbox->chan; 315 + else 316 + return; 317 + 318 + ret = mbox_send_message(intr_chan, NULL); 319 + /* mbox_send_message returns non-negative value on success, so reset */ 320 + if (ret > 0) 321 + ret = 0; 322 + 323 + mbox_client_txdone(intr_chan, ret); 331 324 } 332 325 333 326 static bool
+20 -1
drivers/firmware/arm_scmi/scmi_power_control.c
··· 50 50 #include <linux/reboot.h> 51 51 #include <linux/scmi_protocol.h> 52 52 #include <linux/slab.h> 53 + #include <linux/suspend.h> 53 54 #include <linux/time64.h> 54 55 #include <linux/timer.h> 55 56 #include <linux/types.h> ··· 79 78 * @reboot_nb: A notifier_block optionally used to track reboot progress 80 79 * @forceful_work: A worker used to trigger a forceful transition once a 81 80 * graceful has timed out. 81 + * @suspend_work: A worker used to trigger system suspend 82 82 */ 83 83 struct scmi_syspower_conf { 84 84 struct device *dev; ··· 92 90 struct notifier_block reboot_nb; 93 91 94 92 struct delayed_work forceful_work; 93 + struct work_struct suspend_work; 95 94 }; 96 95 97 96 #define userspace_nb_to_sconf(x) \ ··· 252 249 case SCMI_SYSTEM_WARMRESET: 253 250 orderly_reboot(); 254 251 break; 252 + case SCMI_SYSTEM_SUSPEND: 253 + schedule_work(&sc->suspend_work); 254 + break; 255 255 default: 256 256 break; 257 257 } ··· 283 277 struct scmi_system_power_state_notifier_report *er = data; 284 278 struct scmi_syspower_conf *sc = userspace_nb_to_sconf(nb); 285 279 286 - if (er->system_state >= SCMI_SYSTEM_POWERUP) { 280 + if (er->system_state >= SCMI_SYSTEM_MAX || 281 + er->system_state == SCMI_SYSTEM_POWERUP) { 287 282 dev_err(sc->dev, "Ignoring unsupported system_state: 0x%X\n", 288 283 er->system_state); 289 284 return NOTIFY_DONE; ··· 322 315 return NOTIFY_OK; 323 316 } 324 317 318 + static void scmi_suspend_work_func(struct work_struct *work) 319 + { 320 + struct scmi_syspower_conf *sc = 321 + container_of(work, struct scmi_syspower_conf, suspend_work); 322 + 323 + pm_suspend(PM_SUSPEND_MEM); 324 + 325 + sc->state = SCMI_SYSPOWER_IDLE; 326 + } 327 + 325 328 static int scmi_syspower_probe(struct scmi_device *sdev) 326 329 { 327 330 int ret; ··· 354 337 sc->required_transition = SCMI_SYSTEM_MAX; 355 338 sc->userspace_nb.notifier_call = &scmi_userspace_notifier; 356 339 sc->dev = &sdev->dev; 340 + 341 + INIT_WORK(&sc->suspend_work, scmi_suspend_work_func); 357 342 358 343 return handle->notify_ops->devm_event_notifier_register(sdev, 359 344 SCMI_PROTOCOL_SYSTEM,
+5
drivers/firmware/arm_scmi/shmem.c
··· 128 128 return (ioread32(&shmem->channel_status) & 129 129 SCMI_SHMEM_CHAN_STAT_CHANNEL_FREE); 130 130 } 131 + 132 + bool shmem_channel_intr_enabled(struct scmi_shared_mem __iomem *shmem) 133 + { 134 + return ioread32(&shmem->flags) & SCMI_SHMEM_FLAG_INTR_ENABLED; 135 + }