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 .name = "mpfs-auto-update", 124 .id = -1, 125 }, 126 }; 127 128 static int mpfs_sys_controller_probe(struct platform_device *pdev) 129 { 130 struct device *dev = &pdev->dev; 131 struct mpfs_sys_controller *sys_controller; 132 struct device_node *np; 133 int i, ret; 134 135 sys_controller = kzalloc(sizeof(*sys_controller), GFP_KERNEL); 136 if (!sys_controller) 137 return -ENOMEM; 138 139 np = of_parse_phandle(dev->of_node, "microchip,bitstream-flash", 0); 140 if (!np) 141 goto no_flash; 142 143 sys_controller->flash = of_get_mtd_device_by_node(np); 144 of_node_put(np); 145 if (IS_ERR(sys_controller->flash)) 146 return dev_err_probe(dev, PTR_ERR(sys_controller->flash), "Failed to get flash\n"); 147 148 no_flash: 149 sys_controller->client.dev = dev; 150 sys_controller->client.rx_callback = mpfs_sys_controller_rx_callback; 151 sys_controller->client.tx_block = 1U; 152 sys_controller->client.tx_tout = msecs_to_jiffies(MPFS_SYS_CTRL_TIMEOUT_MS); 153 154 sys_controller->chan = mbox_request_channel(&sys_controller->client, 0); 155 if (IS_ERR(sys_controller->chan)) { 156 ret = dev_err_probe(dev, PTR_ERR(sys_controller->chan), 157 "Failed to get mbox channel\n"); 158 kfree(sys_controller); 159 return ret; 160 } 161 162 init_completion(&sys_controller->c); 163 kref_init(&sys_controller->consumers); 164 165 platform_set_drvdata(pdev, sys_controller); 166 167 168 for (i = 0; i < ARRAY_SIZE(subdevs); i++) { 169 subdevs[i].dev.parent = dev; 170 if (platform_device_register(&subdevs[i])) 171 dev_warn(dev, "Error registering sub device %s\n", subdevs[i].name); 172 } 173 174 dev_info(&pdev->dev, "Registered MPFS system controller\n"); 175 176 return 0; 177 } 178 179 static void mpfs_sys_controller_remove(struct platform_device *pdev) 180 { 181 struct mpfs_sys_controller *sys_controller = platform_get_drvdata(pdev); 182 183 mpfs_sys_controller_put(sys_controller); 184 } 185 186 static const struct of_device_id mpfs_sys_controller_of_match[] = { 187 {.compatible = "microchip,mpfs-sys-controller", }, 188 {}, 189 }; 190 MODULE_DEVICE_TABLE(of, mpfs_sys_controller_of_match); 191 192 struct mpfs_sys_controller *mpfs_sys_controller_get(struct device *dev) 193 { 194 const struct of_device_id *match; 195 struct mpfs_sys_controller *sys_controller; 196 int ret; 197 198 if (!dev->parent) 199 goto err_no_device; 200 201 match = of_match_node(mpfs_sys_controller_of_match, dev->parent->of_node); 202 of_node_put(dev->parent->of_node); 203 if (!match) 204 goto err_no_device; 205 206 sys_controller = dev_get_drvdata(dev->parent); 207 if (!sys_controller) 208 goto err_bad_device; 209 210 if (!kref_get_unless_zero(&sys_controller->consumers)) 211 goto err_bad_device; 212 213 ret = devm_add_action_or_reset(dev, mpfs_sys_controller_put, sys_controller); 214 if (ret) 215 return ERR_PTR(ret); 216 217 return sys_controller; 218 219 err_no_device: 220 dev_dbg(dev, "Parent device was not an MPFS system controller\n"); 221 return ERR_PTR(-ENODEV); 222 223 err_bad_device: 224 dev_dbg(dev, "MPFS system controller found but could not register as a sub device\n"); 225 return ERR_PTR(-EPROBE_DEFER); 226 } 227 EXPORT_SYMBOL(mpfs_sys_controller_get); 228 229 static struct platform_driver mpfs_sys_controller_driver = { 230 .driver = { 231 .name = "mpfs-sys-controller", 232 .of_match_table = mpfs_sys_controller_of_match, 233 }, 234 .probe = mpfs_sys_controller_probe, 235 .remove = mpfs_sys_controller_remove, 236 }; 237 module_platform_driver(mpfs_sys_controller_driver); 238 239 MODULE_LICENSE("GPL v2"); 240 MODULE_AUTHOR("Conor Dooley <conor.dooley@microchip.com>"); 241 MODULE_DESCRIPTION("MPFS system controller driver"); 242