imx-aipstz.c 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * Copyright 2025 NXP
  4. */
  5. #include <linux/module.h>
  6. #include <linux/of.h>
  7. #include <linux/of_platform.h>
  8. #include <linux/platform_device.h>
  9. #include <linux/pm_runtime.h>
  10. #include <linux/regmap.h>
  11. #define IMX_AIPSTZ_MPR0 0x0
  12. struct imx_aipstz_config {
  13. u32 mpr0;
  14. };
  15. struct imx_aipstz_data {
  16. void __iomem *base;
  17. const struct imx_aipstz_config *default_cfg;
  18. };
  19. static void imx_aipstz_apply_default(struct imx_aipstz_data *data)
  20. {
  21. writel(data->default_cfg->mpr0, data->base + IMX_AIPSTZ_MPR0);
  22. }
  23. static const struct of_device_id imx_aipstz_match_table[] = {
  24. { .compatible = "simple-bus", },
  25. { }
  26. };
  27. static int imx_aipstz_probe(struct platform_device *pdev)
  28. {
  29. struct imx_aipstz_data *data;
  30. data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
  31. if (!data)
  32. return dev_err_probe(&pdev->dev, -ENOMEM,
  33. "failed to allocate data memory\n");
  34. data->base = devm_platform_get_and_ioremap_resource(pdev, 0, NULL);
  35. if (IS_ERR(data->base))
  36. return dev_err_probe(&pdev->dev, -ENOMEM,
  37. "failed to get/ioremap AC memory\n");
  38. data->default_cfg = of_device_get_match_data(&pdev->dev);
  39. imx_aipstz_apply_default(data);
  40. dev_set_drvdata(&pdev->dev, data);
  41. pm_runtime_set_active(&pdev->dev);
  42. devm_pm_runtime_enable(&pdev->dev);
  43. return of_platform_populate(pdev->dev.of_node, imx_aipstz_match_table,
  44. NULL, &pdev->dev);
  45. }
  46. static void imx_aipstz_remove(struct platform_device *pdev)
  47. {
  48. of_platform_depopulate(&pdev->dev);
  49. }
  50. static int imx_aipstz_runtime_resume(struct device *dev)
  51. {
  52. struct imx_aipstz_data *data = dev_get_drvdata(dev);
  53. /* restore potentially lost configuration during domain power-off */
  54. imx_aipstz_apply_default(data);
  55. return 0;
  56. }
  57. static const struct dev_pm_ops imx_aipstz_pm_ops = {
  58. RUNTIME_PM_OPS(NULL, imx_aipstz_runtime_resume, NULL)
  59. SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, pm_runtime_force_resume)
  60. };
  61. /*
  62. * following configuration is equivalent to:
  63. * masters 0-7 => trusted for R/W + use AHB's HPROT[1] to det. privilege
  64. */
  65. static const struct imx_aipstz_config imx8mp_aipstz_default_cfg = {
  66. .mpr0 = 0x77777777,
  67. };
  68. static const struct of_device_id imx_aipstz_of_ids[] = {
  69. { .compatible = "fsl,imx8mp-aipstz", .data = &imx8mp_aipstz_default_cfg },
  70. { }
  71. };
  72. MODULE_DEVICE_TABLE(of, imx_aipstz_of_ids);
  73. static struct platform_driver imx_aipstz_of_driver = {
  74. .probe = imx_aipstz_probe,
  75. .remove = imx_aipstz_remove,
  76. .driver = {
  77. .name = "imx-aipstz",
  78. .of_match_table = imx_aipstz_of_ids,
  79. .pm = pm_ptr(&imx_aipstz_pm_ops),
  80. },
  81. };
  82. module_platform_driver(imx_aipstz_of_driver);
  83. MODULE_LICENSE("GPL");
  84. MODULE_DESCRIPTION("IMX secure AHB to IP Slave bus (AIPSTZ) bridge driver");
  85. MODULE_AUTHOR("Laurentiu Mihalcea <laurentiu.mihalcea@nxp.com>");