1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Copyright 2025 NXP 4 */ 5 6 #include <linux/firmware/imx/sm.h> 7 #include <linux/module.h> 8 #include <linux/of.h> 9 #include <linux/platform_device.h> 10 #include <linux/scmi_protocol.h> 11 #include <linux/scmi_imx_protocol.h> 12 13 static const struct scmi_imx_lmm_proto_ops *imx_lmm_ops; 14 static struct scmi_protocol_handle *ph; 15 16 int scmi_imx_lmm_info(u32 lmid, struct scmi_imx_lmm_info *info) 17 { 18 if (!ph) 19 return -EPROBE_DEFER; 20 21 if (!info) 22 return -EINVAL; 23 24 return imx_lmm_ops->lmm_info(ph, lmid, info); 25 }; 26 EXPORT_SYMBOL(scmi_imx_lmm_info); 27 28 int scmi_imx_lmm_reset_vector_set(u32 lmid, u32 cpuid, u32 flags, u64 vector) 29 { 30 if (!ph) 31 return -EPROBE_DEFER; 32 33 return imx_lmm_ops->lmm_reset_vector_set(ph, lmid, cpuid, flags, vector); 34 } 35 EXPORT_SYMBOL(scmi_imx_lmm_reset_vector_set); 36 37 int scmi_imx_lmm_operation(u32 lmid, enum scmi_imx_lmm_op op, u32 flags) 38 { 39 if (!ph) 40 return -EPROBE_DEFER; 41 42 switch (op) { 43 case SCMI_IMX_LMM_BOOT: 44 return imx_lmm_ops->lmm_power_boot(ph, lmid, true); 45 case SCMI_IMX_LMM_POWER_ON: 46 return imx_lmm_ops->lmm_power_boot(ph, lmid, false); 47 case SCMI_IMX_LMM_SHUTDOWN: 48 return imx_lmm_ops->lmm_shutdown(ph, lmid, flags); 49 default: 50 break; 51 } 52 53 return -EINVAL; 54 } 55 EXPORT_SYMBOL(scmi_imx_lmm_operation); 56 57 static int scmi_imx_lmm_probe(struct scmi_device *sdev) 58 { 59 const struct scmi_handle *handle = sdev->handle; 60 61 if (!handle) 62 return -ENODEV; 63 64 if (imx_lmm_ops) { 65 dev_err(&sdev->dev, "lmm already initialized\n"); 66 return -EEXIST; 67 } 68 69 imx_lmm_ops = handle->devm_protocol_get(sdev, SCMI_PROTOCOL_IMX_LMM, &ph); 70 if (IS_ERR(imx_lmm_ops)) 71 return PTR_ERR(imx_lmm_ops); 72 73 return 0; 74 } 75 76 static const struct scmi_device_id scmi_id_table[] = { 77 { SCMI_PROTOCOL_IMX_LMM, "imx-lmm" }, 78 { }, 79 }; 80 MODULE_DEVICE_TABLE(scmi, scmi_id_table); 81 82 static struct scmi_driver scmi_imx_lmm_driver = { 83 .name = "scmi-imx-lmm", 84 .probe = scmi_imx_lmm_probe, 85 .id_table = scmi_id_table, 86 }; 87 module_scmi_driver(scmi_imx_lmm_driver); 88 89 MODULE_AUTHOR("Peng Fan <peng.fan@nxp.com>"); 90 MODULE_DESCRIPTION("IMX SM LMM driver"); 91 MODULE_LICENSE("GPL"); 92