1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Microchip PolarFire SoC (MPFS) system controller driver 4 * 5 * Copyright (c) 2020-2021 Microchip Corporation. All rights reserved. 6 * 7 * Author: Conor Dooley <conor.dooley@microchip.com> 8 * 9 */ 10 11 #include <linux/slab.h> 12 #include <linux/kref.h> 13 #include <linux/module.h> 14 #include <linux/jiffies.h> 15 #include <linux/mtd/mtd.h> 16 #include <linux/spi/spi.h> 17 #include <linux/interrupt.h> 18 #include <linux/of.h> 19 #include <linux/mailbox_client.h> 20 #include <linux/platform_device.h> 21 #include <soc/microchip/mpfs.h> 22 23 /* 24 * This timeout must be long, as some services (example: image authentication) 25 * take significant time to complete 26 */ 27 #define MPFS_SYS_CTRL_TIMEOUT_MS 30000 28 29 static DEFINE_MUTEX(transaction_lock); 30 31 struct mpfs_sys_controller { 32 struct mbox_client client; 33 struct mbox_chan *chan; 34 struct completion c; 35 struct mtd_info *flash; 36 struct kref consumers; 37 }; 38 39 int mpfs_blocking_transaction(struct mpfs_sys_controller *sys_controller, struct mpfs_mss_msg *msg) 40 { 41 unsigned long timeout = msecs_to_jiffies(MPFS_SYS_CTRL_TIMEOUT_MS); 42 int ret; 43 44 ret = mutex_lock_interruptible(&transaction_lock); 45 if (ret) 46 return ret; 47 48 reinit_completion(&sys_controller->c); 49 50 ret = mbox_send_message(sys_controller->chan, msg); 51 if (ret < 0) { 52 dev_warn(sys_controller->client.dev, "MPFS sys controller service timeout\n"); 53 goto out; 54 } 55 56 /* 57 * Unfortunately, the system controller will only deliver an interrupt 58 * if a service succeeds. mbox_send_message() will block until the busy 59 * flag is gone. If the busy flag is gone but no interrupt has arrived 60 * to trigger the rx callback then the service can be deemed to have 61 * failed. 62 * The caller can then interrogate msg::response::resp_status to 63 * determine the cause of the failure. 64 * mbox_send_message() returns positive integers in the success path, so 65 * ret needs to be cleared if we do get an interrupt. 66 */ 67 if (!wait_for_completion_timeout(&sys_controller->c, timeout)) { 68 ret = -EBADMSG; 69 dev_warn(sys_controller->client.dev, 70 "MPFS sys controller service failed with status: %d\n", 71 msg->response->resp_status); 72 } else { 73 ret = 0; 74 } 75 76 out: 77 mutex_unlock(&transaction_lock); 78 79 return ret; 80 } 81 EXPORT_SYMBOL(mpfs_blocking_transaction); 82 83 static void mpfs_sys_controller_rx_callback(struct mbox_client *client, void *msg) 84 { 85 struct mpfs_sys_controller *sys_controller = 86 container_of(client, struct mpfs_sys_controller, client); 87 88 complete(&sys_controller->c); 89 } 90 91 static void mpfs_sys_controller_delete(struct kref *kref) 92 { 93 struct mpfs_sys_controller *sys_controller = 94 container_of(kref, struct mpfs_sys_controller, consumers); 95 96 mbox_free_channel(sys_controller->chan); 97 kfree(sys_controller); 98 } 99 100 static void mpfs_sys_controller_put(void *data) 101 { 102 struct mpfs_sys_controller *sys_controller = data; 103 104 kref_put(&sys_controller->consumers, mpfs_sys_controller_delete); 105 } 106 107 struct mtd_info *mpfs_sys_controller_get_flash(struct mpfs_sys_controller *mpfs_client) 108 { 109 return mpfs_client->flash; 110 } 111 EXPORT_SYMBOL(mpfs_sys_controller_get_flash); 112 113 static struct platform_device subdevs[] = { 114 { 115 .name = "mpfs-rng", 116 .id = -1, 117 }, 118 { 119 .name = "mpfs-generic-service", 120 .id = -1, 121 } 122 }; 123 124 static int mpfs_sys_controller_probe(struct platform_device *pdev) 125 { 126 struct device *dev = &pdev->dev; 127 struct mpfs_sys_controller *sys_controller; 128 struct device_node *np; 129 int i, ret; 130 131 sys_controller = kzalloc(sizeof(*sys_controller), GFP_KERNEL); 132 if (!sys_controller) 133 return -ENOMEM; 134 135 np = of_parse_phandle(dev->of_node, "microchip,bitstream-flash", 0); 136 if (!np) 137 goto no_flash; 138 139 sys_controller->flash = of_get_mtd_device_by_node(np); 140 of_node_put(np); 141 if (IS_ERR(sys_controller->flash)) 142 return dev_err_probe(dev, PTR_ERR(sys_controller->flash), "Failed to get flash\n"); 143 144 no_flash: 145 sys_controller->client.dev = dev; 146 sys_controller->client.rx_callback = mpfs_sys_controller_rx_callback; 147 sys_controller->client.tx_block = 1U; 148 sys_controller->client.tx_tout = msecs_to_jiffies(MPFS_SYS_CTRL_TIMEOUT_MS); 149 150 sys_controller->chan = mbox_request_channel(&sys_controller->client, 0); 151 if (IS_ERR(sys_controller->chan)) { 152 ret = dev_err_probe(dev, PTR_ERR(sys_controller->chan), 153 "Failed to get mbox channel\n"); 154 kfree(sys_controller); 155 return ret; 156 } 157 158 init_completion(&sys_controller->c); 159 kref_init(&sys_controller->consumers); 160 161 platform_set_drvdata(pdev, sys_controller); 162 163 dev_info(&pdev->dev, "Registered MPFS system controller\n"); 164 165 for (i = 0; i < ARRAY_SIZE(subdevs); i++) { 166 subdevs[i].dev.parent = dev; 167 if (platform_device_register(&subdevs[i])) 168 dev_warn(dev, "Error registering sub device %s\n", subdevs[i].name); 169 } 170 171 return 0; 172 } 173 174 static void mpfs_sys_controller_remove(struct platform_device *pdev) 175 { 176 struct mpfs_sys_controller *sys_controller = platform_get_drvdata(pdev); 177 178 mpfs_sys_controller_put(sys_controller); 179 } 180 181 static const struct of_device_id mpfs_sys_controller_of_match[] = { 182 {.compatible = "microchip,mpfs-sys-controller", }, 183 {}, 184 }; 185 MODULE_DEVICE_TABLE(of, mpfs_sys_controller_of_match); 186 187 struct mpfs_sys_controller *mpfs_sys_controller_get(struct device *dev) 188 { 189 const struct of_device_id *match; 190 struct mpfs_sys_controller *sys_controller; 191 int ret; 192 193 if (!dev->parent) 194 goto err_no_device; 195 196 match = of_match_node(mpfs_sys_controller_of_match, dev->parent->of_node); 197 of_node_put(dev->parent->of_node); 198 if (!match) 199 goto err_no_device; 200 201 sys_controller = dev_get_drvdata(dev->parent); 202 if (!sys_controller) 203 goto err_bad_device; 204 205 if (!kref_get_unless_zero(&sys_controller->consumers)) 206 goto err_bad_device; 207 208 ret = devm_add_action_or_reset(dev, mpfs_sys_controller_put, sys_controller); 209 if (ret) 210 return ERR_PTR(ret); 211 212 return sys_controller; 213 214 err_no_device: 215 dev_dbg(dev, "Parent device was not an MPFS system controller\n"); 216 return ERR_PTR(-ENODEV); 217 218 err_bad_device: 219 dev_dbg(dev, "MPFS system controller found but could not register as a sub device\n"); 220 return ERR_PTR(-EPROBE_DEFER); 221 } 222 EXPORT_SYMBOL(mpfs_sys_controller_get); 223 224 static struct platform_driver mpfs_sys_controller_driver = { 225 .driver = { 226 .name = "mpfs-sys-controller", 227 .of_match_table = mpfs_sys_controller_of_match, 228 }, 229 .probe = mpfs_sys_controller_probe, 230 .remove_new = mpfs_sys_controller_remove, 231 }; 232 module_platform_driver(mpfs_sys_controller_driver); 233 234 MODULE_LICENSE("GPL v2"); 235 MODULE_AUTHOR("Conor Dooley <conor.dooley@microchip.com>"); 236 MODULE_DESCRIPTION("MPFS system controller driver"); 237