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, "MPFS sys controller service failed\n"); 70 } else { 71 ret = 0; 72 } 73 74 out: 75 mutex_unlock(&transaction_lock); 76 77 return ret; 78 } 79 EXPORT_SYMBOL(mpfs_blocking_transaction); 80 81 static void mpfs_sys_controller_rx_callback(struct mbox_client *client, void *msg) 82 { 83 struct mpfs_sys_controller *sys_controller = 84 container_of(client, struct mpfs_sys_controller, client); 85 86 complete(&sys_controller->c); 87 } 88 89 static void mpfs_sys_controller_delete(struct kref *kref) 90 { 91 struct mpfs_sys_controller *sys_controller = 92 container_of(kref, struct mpfs_sys_controller, consumers); 93 94 mbox_free_channel(sys_controller->chan); 95 kfree(sys_controller); 96 } 97 98 static void mpfs_sys_controller_put(void *data) 99 { 100 struct mpfs_sys_controller *sys_controller = data; 101 102 kref_put(&sys_controller->consumers, mpfs_sys_controller_delete); 103 } 104 105 struct mtd_info *mpfs_sys_controller_get_flash(struct mpfs_sys_controller *mpfs_client) 106 { 107 return mpfs_client->flash; 108 } 109 EXPORT_SYMBOL(mpfs_sys_controller_get_flash); 110 111 static struct platform_device subdevs[] = { 112 { 113 .name = "mpfs-rng", 114 .id = -1, 115 }, 116 { 117 .name = "mpfs-generic-service", 118 .id = -1, 119 } 120 }; 121 122 static int mpfs_sys_controller_probe(struct platform_device *pdev) 123 { 124 struct device *dev = &pdev->dev; 125 struct mpfs_sys_controller *sys_controller; 126 struct device_node *np; 127 int i, ret; 128 129 sys_controller = kzalloc(sizeof(*sys_controller), GFP_KERNEL); 130 if (!sys_controller) 131 return -ENOMEM; 132 133 np = of_parse_phandle(dev->of_node, "microchip,bitstream-flash", 0); 134 if (!np) 135 goto no_flash; 136 137 sys_controller->flash = of_get_mtd_device_by_node(np); 138 of_node_put(np); 139 if (IS_ERR(sys_controller->flash)) 140 return dev_err_probe(dev, PTR_ERR(sys_controller->flash), "Failed to get flash\n"); 141 142 no_flash: 143 sys_controller->client.dev = dev; 144 sys_controller->client.rx_callback = mpfs_sys_controller_rx_callback; 145 sys_controller->client.tx_block = 1U; 146 sys_controller->client.tx_tout = msecs_to_jiffies(MPFS_SYS_CTRL_TIMEOUT_MS); 147 148 sys_controller->chan = mbox_request_channel(&sys_controller->client, 0); 149 if (IS_ERR(sys_controller->chan)) { 150 ret = dev_err_probe(dev, PTR_ERR(sys_controller->chan), 151 "Failed to get mbox channel\n"); 152 kfree(sys_controller); 153 return ret; 154 } 155 156 init_completion(&sys_controller->c); 157 kref_init(&sys_controller->consumers); 158 159 platform_set_drvdata(pdev, sys_controller); 160 161 dev_info(&pdev->dev, "Registered MPFS system controller\n"); 162 163 for (i = 0; i < ARRAY_SIZE(subdevs); i++) { 164 subdevs[i].dev.parent = dev; 165 if (platform_device_register(&subdevs[i])) 166 dev_warn(dev, "Error registering sub device %s\n", subdevs[i].name); 167 } 168 169 return 0; 170 } 171 172 static void mpfs_sys_controller_remove(struct platform_device *pdev) 173 { 174 struct mpfs_sys_controller *sys_controller = platform_get_drvdata(pdev); 175 176 mpfs_sys_controller_put(sys_controller); 177 } 178 179 static const struct of_device_id mpfs_sys_controller_of_match[] = { 180 {.compatible = "microchip,mpfs-sys-controller", }, 181 {}, 182 }; 183 MODULE_DEVICE_TABLE(of, mpfs_sys_controller_of_match); 184 185 struct mpfs_sys_controller *mpfs_sys_controller_get(struct device *dev) 186 { 187 const struct of_device_id *match; 188 struct mpfs_sys_controller *sys_controller; 189 int ret; 190 191 if (!dev->parent) 192 goto err_no_device; 193 194 match = of_match_node(mpfs_sys_controller_of_match, dev->parent->of_node); 195 of_node_put(dev->parent->of_node); 196 if (!match) 197 goto err_no_device; 198 199 sys_controller = dev_get_drvdata(dev->parent); 200 if (!sys_controller) 201 goto err_bad_device; 202 203 if (!kref_get_unless_zero(&sys_controller->consumers)) 204 goto err_bad_device; 205 206 ret = devm_add_action_or_reset(dev, mpfs_sys_controller_put, sys_controller); 207 if (ret) 208 return ERR_PTR(ret); 209 210 return sys_controller; 211 212 err_no_device: 213 dev_dbg(dev, "Parent device was not an MPFS system controller\n"); 214 return ERR_PTR(-ENODEV); 215 216 err_bad_device: 217 dev_dbg(dev, "MPFS system controller found but could not register as a sub device\n"); 218 return ERR_PTR(-EPROBE_DEFER); 219 } 220 EXPORT_SYMBOL(mpfs_sys_controller_get); 221 222 static struct platform_driver mpfs_sys_controller_driver = { 223 .driver = { 224 .name = "mpfs-sys-controller", 225 .of_match_table = mpfs_sys_controller_of_match, 226 }, 227 .probe = mpfs_sys_controller_probe, 228 .remove_new = mpfs_sys_controller_remove, 229 }; 230 module_platform_driver(mpfs_sys_controller_driver); 231 232 MODULE_LICENSE("GPL v2"); 233 MODULE_AUTHOR("Conor Dooley <conor.dooley@microchip.com>"); 234 MODULE_DESCRIPTION("MPFS system controller driver"); 235