0001
0002
0003
0004
0005
0006
0007
0008
0009 #include <linux/dma-mapping.h>
0010 #include <linux/kref.h>
0011 #include <linux/mailbox_client.h>
0012 #include <linux/module.h>
0013 #include <linux/of_platform.h>
0014 #include <linux/platform_device.h>
0015 #include <linux/slab.h>
0016 #include <soc/bcm2835/raspberrypi-firmware.h>
0017
0018 #define MBOX_MSG(chan, data28) (((data28) & ~0xf) | ((chan) & 0xf))
0019 #define MBOX_CHAN(msg) ((msg) & 0xf)
0020 #define MBOX_DATA28(msg) ((msg) & ~0xf)
0021 #define MBOX_CHAN_PROPERTY 8
0022
0023 static struct platform_device *rpi_hwmon;
0024 static struct platform_device *rpi_clk;
0025
0026 struct rpi_firmware {
0027 struct mbox_client cl;
0028 struct mbox_chan *chan;
0029 struct completion c;
0030 u32 enabled;
0031
0032 struct kref consumers;
0033 };
0034
0035 static DEFINE_MUTEX(transaction_lock);
0036
0037 static void response_callback(struct mbox_client *cl, void *msg)
0038 {
0039 struct rpi_firmware *fw = container_of(cl, struct rpi_firmware, cl);
0040 complete(&fw->c);
0041 }
0042
0043
0044
0045
0046
0047 static int
0048 rpi_firmware_transaction(struct rpi_firmware *fw, u32 chan, u32 data)
0049 {
0050 u32 message = MBOX_MSG(chan, data);
0051 int ret;
0052
0053 WARN_ON(data & 0xf);
0054
0055 mutex_lock(&transaction_lock);
0056 reinit_completion(&fw->c);
0057 ret = mbox_send_message(fw->chan, &message);
0058 if (ret >= 0) {
0059 if (wait_for_completion_timeout(&fw->c, HZ)) {
0060 ret = 0;
0061 } else {
0062 ret = -ETIMEDOUT;
0063 WARN_ONCE(1, "Firmware transaction timeout");
0064 }
0065 } else {
0066 dev_err(fw->cl.dev, "mbox_send_message returned %d\n", ret);
0067 }
0068 mutex_unlock(&transaction_lock);
0069
0070 return ret;
0071 }
0072
0073
0074
0075
0076
0077
0078
0079
0080
0081
0082
0083
0084
0085
0086
0087 int rpi_firmware_property_list(struct rpi_firmware *fw,
0088 void *data, size_t tag_size)
0089 {
0090 size_t size = tag_size + 12;
0091 u32 *buf;
0092 dma_addr_t bus_addr;
0093 int ret;
0094
0095
0096 if (size & 3)
0097 return -EINVAL;
0098
0099 buf = dma_alloc_coherent(fw->cl.dev, PAGE_ALIGN(size), &bus_addr,
0100 GFP_ATOMIC);
0101 if (!buf)
0102 return -ENOMEM;
0103
0104
0105 WARN_ON(size >= 1024 * 1024);
0106
0107 buf[0] = size;
0108 buf[1] = RPI_FIRMWARE_STATUS_REQUEST;
0109 memcpy(&buf[2], data, tag_size);
0110 buf[size / 4 - 1] = RPI_FIRMWARE_PROPERTY_END;
0111 wmb();
0112
0113 ret = rpi_firmware_transaction(fw, MBOX_CHAN_PROPERTY, bus_addr);
0114
0115 rmb();
0116 memcpy(data, &buf[2], tag_size);
0117 if (ret == 0 && buf[1] != RPI_FIRMWARE_STATUS_SUCCESS) {
0118
0119
0120
0121
0122
0123 dev_err(fw->cl.dev, "Request 0x%08x returned status 0x%08x\n",
0124 buf[2], buf[1]);
0125 ret = -EINVAL;
0126 }
0127
0128 dma_free_coherent(fw->cl.dev, PAGE_ALIGN(size), buf, bus_addr);
0129
0130 return ret;
0131 }
0132 EXPORT_SYMBOL_GPL(rpi_firmware_property_list);
0133
0134
0135
0136
0137
0138
0139
0140
0141
0142
0143
0144
0145
0146
0147
0148 int rpi_firmware_property(struct rpi_firmware *fw,
0149 u32 tag, void *tag_data, size_t buf_size)
0150 {
0151 struct rpi_firmware_property_tag_header *header;
0152 int ret;
0153
0154
0155
0156
0157
0158
0159 void *data = kmalloc(sizeof(*header) + buf_size, GFP_KERNEL);
0160
0161 if (!data)
0162 return -ENOMEM;
0163
0164 header = data;
0165 header->tag = tag;
0166 header->buf_size = buf_size;
0167 header->req_resp_size = 0;
0168 memcpy(data + sizeof(*header), tag_data, buf_size);
0169
0170 ret = rpi_firmware_property_list(fw, data, buf_size + sizeof(*header));
0171
0172 memcpy(tag_data, data + sizeof(*header), buf_size);
0173
0174 kfree(data);
0175
0176 return ret;
0177 }
0178 EXPORT_SYMBOL_GPL(rpi_firmware_property);
0179
0180 static void
0181 rpi_firmware_print_firmware_revision(struct rpi_firmware *fw)
0182 {
0183 time64_t date_and_time;
0184 u32 packet;
0185 int ret = rpi_firmware_property(fw,
0186 RPI_FIRMWARE_GET_FIRMWARE_REVISION,
0187 &packet, sizeof(packet));
0188
0189 if (ret)
0190 return;
0191
0192
0193 date_and_time = packet;
0194 dev_info(fw->cl.dev, "Attached to firmware from %ptT\n", &date_and_time);
0195 }
0196
0197 static void
0198 rpi_register_hwmon_driver(struct device *dev, struct rpi_firmware *fw)
0199 {
0200 u32 packet;
0201 int ret = rpi_firmware_property(fw, RPI_FIRMWARE_GET_THROTTLED,
0202 &packet, sizeof(packet));
0203
0204 if (ret)
0205 return;
0206
0207 rpi_hwmon = platform_device_register_data(dev, "raspberrypi-hwmon",
0208 -1, NULL, 0);
0209 }
0210
0211 static void rpi_register_clk_driver(struct device *dev)
0212 {
0213 struct device_node *firmware;
0214
0215
0216
0217
0218
0219
0220 firmware = of_get_compatible_child(dev->of_node,
0221 "raspberrypi,firmware-clocks");
0222 if (firmware) {
0223 of_node_put(firmware);
0224 return;
0225 }
0226
0227 rpi_clk = platform_device_register_data(dev, "raspberrypi-clk",
0228 -1, NULL, 0);
0229 }
0230
0231 static void rpi_firmware_delete(struct kref *kref)
0232 {
0233 struct rpi_firmware *fw = container_of(kref, struct rpi_firmware,
0234 consumers);
0235
0236 mbox_free_channel(fw->chan);
0237 kfree(fw);
0238 }
0239
0240 void rpi_firmware_put(struct rpi_firmware *fw)
0241 {
0242 kref_put(&fw->consumers, rpi_firmware_delete);
0243 }
0244 EXPORT_SYMBOL_GPL(rpi_firmware_put);
0245
0246 static void devm_rpi_firmware_put(void *data)
0247 {
0248 struct rpi_firmware *fw = data;
0249
0250 rpi_firmware_put(fw);
0251 }
0252
0253 static int rpi_firmware_probe(struct platform_device *pdev)
0254 {
0255 struct device *dev = &pdev->dev;
0256 struct rpi_firmware *fw;
0257
0258
0259
0260
0261
0262 fw = kzalloc(sizeof(*fw), GFP_KERNEL);
0263 if (!fw)
0264 return -ENOMEM;
0265
0266 fw->cl.dev = dev;
0267 fw->cl.rx_callback = response_callback;
0268 fw->cl.tx_block = true;
0269
0270 fw->chan = mbox_request_channel(&fw->cl, 0);
0271 if (IS_ERR(fw->chan)) {
0272 int ret = PTR_ERR(fw->chan);
0273 if (ret != -EPROBE_DEFER)
0274 dev_err(dev, "Failed to get mbox channel: %d\n", ret);
0275 return ret;
0276 }
0277
0278 init_completion(&fw->c);
0279 kref_init(&fw->consumers);
0280
0281 platform_set_drvdata(pdev, fw);
0282
0283 rpi_firmware_print_firmware_revision(fw);
0284 rpi_register_hwmon_driver(dev, fw);
0285 rpi_register_clk_driver(dev);
0286
0287 return 0;
0288 }
0289
0290 static void rpi_firmware_shutdown(struct platform_device *pdev)
0291 {
0292 struct rpi_firmware *fw = platform_get_drvdata(pdev);
0293
0294 if (!fw)
0295 return;
0296
0297 rpi_firmware_property(fw, RPI_FIRMWARE_NOTIFY_REBOOT, NULL, 0);
0298 }
0299
0300 static int rpi_firmware_remove(struct platform_device *pdev)
0301 {
0302 struct rpi_firmware *fw = platform_get_drvdata(pdev);
0303
0304 platform_device_unregister(rpi_hwmon);
0305 rpi_hwmon = NULL;
0306 platform_device_unregister(rpi_clk);
0307 rpi_clk = NULL;
0308
0309 rpi_firmware_put(fw);
0310
0311 return 0;
0312 }
0313
0314
0315
0316
0317
0318
0319
0320
0321
0322 struct rpi_firmware *rpi_firmware_get(struct device_node *firmware_node)
0323 {
0324 struct platform_device *pdev = of_find_device_by_node(firmware_node);
0325 struct rpi_firmware *fw;
0326
0327 if (!pdev)
0328 return NULL;
0329
0330 fw = platform_get_drvdata(pdev);
0331 if (!fw)
0332 goto err_put_device;
0333
0334 if (!kref_get_unless_zero(&fw->consumers))
0335 goto err_put_device;
0336
0337 put_device(&pdev->dev);
0338
0339 return fw;
0340
0341 err_put_device:
0342 put_device(&pdev->dev);
0343 return NULL;
0344 }
0345 EXPORT_SYMBOL_GPL(rpi_firmware_get);
0346
0347
0348
0349
0350
0351
0352
0353 struct rpi_firmware *devm_rpi_firmware_get(struct device *dev,
0354 struct device_node *firmware_node)
0355 {
0356 struct rpi_firmware *fw;
0357
0358 fw = rpi_firmware_get(firmware_node);
0359 if (!fw)
0360 return NULL;
0361
0362 if (devm_add_action_or_reset(dev, devm_rpi_firmware_put, fw))
0363 return NULL;
0364
0365 return fw;
0366 }
0367 EXPORT_SYMBOL_GPL(devm_rpi_firmware_get);
0368
0369 static const struct of_device_id rpi_firmware_of_match[] = {
0370 { .compatible = "raspberrypi,bcm2835-firmware", },
0371 {},
0372 };
0373 MODULE_DEVICE_TABLE(of, rpi_firmware_of_match);
0374
0375 static struct platform_driver rpi_firmware_driver = {
0376 .driver = {
0377 .name = "raspberrypi-firmware",
0378 .of_match_table = rpi_firmware_of_match,
0379 },
0380 .probe = rpi_firmware_probe,
0381 .shutdown = rpi_firmware_shutdown,
0382 .remove = rpi_firmware_remove,
0383 };
0384 module_platform_driver(rpi_firmware_driver);
0385
0386 MODULE_AUTHOR("Eric Anholt <eric@anholt.net>");
0387 MODULE_DESCRIPTION("Raspberry Pi firmware driver");
0388 MODULE_LICENSE("GPL v2");