mtk-efuse.c 2.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * Copyright (c) 2015 MediaTek Inc.
  4. * Author: Andrew-CT Chen <andrew-ct.chen@mediatek.com>
  5. */
  6. #include <linux/device.h>
  7. #include <linux/module.h>
  8. #include <linux/mod_devicetable.h>
  9. #include <linux/io.h>
  10. #include <linux/nvmem-provider.h>
  11. #include <linux/platform_device.h>
  12. struct mtk_efuse_priv {
  13. void __iomem *base;
  14. };
  15. static int mtk_reg_read(void *context,
  16. unsigned int reg, void *_val, size_t bytes)
  17. {
  18. struct mtk_efuse_priv *priv = context;
  19. u32 *val = _val;
  20. int i = 0, words = bytes / 4;
  21. while (words--)
  22. *val++ = readl(priv->base + reg + (i++ * 4));
  23. return 0;
  24. }
  25. static int mtk_efuse_probe(struct platform_device *pdev)
  26. {
  27. struct device *dev = &pdev->dev;
  28. struct resource *res;
  29. struct nvmem_device *nvmem;
  30. struct nvmem_config econfig = {};
  31. struct mtk_efuse_priv *priv;
  32. priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
  33. if (!priv)
  34. return -ENOMEM;
  35. res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  36. priv->base = devm_ioremap_resource(dev, res);
  37. if (IS_ERR(priv->base))
  38. return PTR_ERR(priv->base);
  39. econfig.stride = 4;
  40. econfig.word_size = 4;
  41. econfig.reg_read = mtk_reg_read;
  42. econfig.size = resource_size(res);
  43. econfig.priv = priv;
  44. econfig.dev = dev;
  45. nvmem = devm_nvmem_register(dev, &econfig);
  46. return PTR_ERR_OR_ZERO(nvmem);
  47. }
  48. static const struct of_device_id mtk_efuse_of_match[] = {
  49. { .compatible = "mediatek,mt8173-efuse",},
  50. { .compatible = "mediatek,efuse",},
  51. {/* sentinel */},
  52. };
  53. MODULE_DEVICE_TABLE(of, mtk_efuse_of_match);
  54. static struct platform_driver mtk_efuse_driver = {
  55. .probe = mtk_efuse_probe,
  56. .driver = {
  57. .name = "mediatek,efuse",
  58. .of_match_table = mtk_efuse_of_match,
  59. },
  60. };
  61. static int __init mtk_efuse_init(void)
  62. {
  63. int ret;
  64. ret = platform_driver_register(&mtk_efuse_driver);
  65. if (ret) {
  66. pr_err("Failed to register efuse driver\n");
  67. return ret;
  68. }
  69. return 0;
  70. }
  71. static void __exit mtk_efuse_exit(void)
  72. {
  73. return platform_driver_unregister(&mtk_efuse_driver);
  74. }
  75. subsys_initcall(mtk_efuse_init);
  76. module_exit(mtk_efuse_exit);
  77. MODULE_AUTHOR("Andrew-CT Chen <andrew-ct.chen@mediatek.com>");
  78. MODULE_DESCRIPTION("Mediatek EFUSE driver");
  79. MODULE_LICENSE("GPL v2");