macb_pci.c 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. /**
  2. * Cadence GEM PCI wrapper.
  3. *
  4. * Copyright (C) 2016 Cadence Design Systems - http://www.cadence.com
  5. *
  6. * Authors: Rafal Ozieblo <rafalo@cadence.com>
  7. * Bartosz Folta <bfolta@cadence.com>
  8. *
  9. * This program is free software: you can redistribute it and/or modify
  10. * it under the terms of the GNU General Public License version 2 of
  11. * the License as published by the Free Software Foundation.
  12. *
  13. * This program is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU General Public License
  19. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  20. */
  21. #include <linux/clk.h>
  22. #include <linux/clk-provider.h>
  23. #include <linux/etherdevice.h>
  24. #include <linux/module.h>
  25. #include <linux/pci.h>
  26. #include <linux/platform_data/macb.h>
  27. #include <linux/platform_device.h>
  28. #include "macb.h"
  29. #define PCI_DRIVER_NAME "macb_pci"
  30. #define PLAT_DRIVER_NAME "macb"
  31. #define CDNS_VENDOR_ID 0x17cd
  32. #define CDNS_DEVICE_ID 0xe007
  33. #define GEM_PCLK_RATE 50000000
  34. #define GEM_HCLK_RATE 50000000
  35. static int macb_probe(struct pci_dev *pdev, const struct pci_device_id *id)
  36. {
  37. int err;
  38. struct platform_device *plat_dev;
  39. struct platform_device_info plat_info;
  40. struct macb_platform_data plat_data;
  41. struct resource res[2];
  42. /* enable pci device */
  43. err = pcim_enable_device(pdev);
  44. if (err < 0) {
  45. dev_err(&pdev->dev, "Enabling PCI device has failed: %d", err);
  46. return err;
  47. }
  48. pci_set_master(pdev);
  49. /* set up resources */
  50. memset(res, 0x00, sizeof(struct resource) * ARRAY_SIZE(res));
  51. res[0].start = pci_resource_start(pdev, 0);
  52. res[0].end = pci_resource_end(pdev, 0);
  53. res[0].name = PCI_DRIVER_NAME;
  54. res[0].flags = IORESOURCE_MEM;
  55. res[1].start = pci_irq_vector(pdev, 0);
  56. res[1].name = PCI_DRIVER_NAME;
  57. res[1].flags = IORESOURCE_IRQ;
  58. dev_info(&pdev->dev, "EMAC physical base addr: %pa\n",
  59. &res[0].start);
  60. /* set up macb platform data */
  61. memset(&plat_data, 0, sizeof(plat_data));
  62. /* initialize clocks */
  63. plat_data.pclk = clk_register_fixed_rate(&pdev->dev, "pclk", NULL, 0,
  64. GEM_PCLK_RATE);
  65. if (IS_ERR(plat_data.pclk)) {
  66. err = PTR_ERR(plat_data.pclk);
  67. goto err_pclk_register;
  68. }
  69. plat_data.hclk = clk_register_fixed_rate(&pdev->dev, "hclk", NULL, 0,
  70. GEM_HCLK_RATE);
  71. if (IS_ERR(plat_data.hclk)) {
  72. err = PTR_ERR(plat_data.hclk);
  73. goto err_hclk_register;
  74. }
  75. /* set up platform device info */
  76. memset(&plat_info, 0, sizeof(plat_info));
  77. plat_info.parent = &pdev->dev;
  78. plat_info.fwnode = pdev->dev.fwnode;
  79. plat_info.name = PLAT_DRIVER_NAME;
  80. plat_info.id = pdev->devfn;
  81. plat_info.res = res;
  82. plat_info.num_res = ARRAY_SIZE(res);
  83. plat_info.data = &plat_data;
  84. plat_info.size_data = sizeof(plat_data);
  85. plat_info.dma_mask = pdev->dma_mask;
  86. /* register platform device */
  87. plat_dev = platform_device_register_full(&plat_info);
  88. if (IS_ERR(plat_dev)) {
  89. err = PTR_ERR(plat_dev);
  90. goto err_plat_dev_register;
  91. }
  92. pci_set_drvdata(pdev, plat_dev);
  93. return 0;
  94. err_plat_dev_register:
  95. clk_unregister(plat_data.hclk);
  96. err_hclk_register:
  97. clk_unregister(plat_data.pclk);
  98. err_pclk_register:
  99. return err;
  100. }
  101. static void macb_remove(struct pci_dev *pdev)
  102. {
  103. struct platform_device *plat_dev = pci_get_drvdata(pdev);
  104. struct macb_platform_data *plat_data = dev_get_platdata(&plat_dev->dev);
  105. platform_device_unregister(plat_dev);
  106. clk_unregister(plat_data->pclk);
  107. clk_unregister(plat_data->hclk);
  108. }
  109. static const struct pci_device_id dev_id_table[] = {
  110. { PCI_DEVICE(CDNS_VENDOR_ID, CDNS_DEVICE_ID), },
  111. { 0, }
  112. };
  113. static struct pci_driver macb_pci_driver = {
  114. .name = PCI_DRIVER_NAME,
  115. .id_table = dev_id_table,
  116. .probe = macb_probe,
  117. .remove = macb_remove,
  118. };
  119. module_pci_driver(macb_pci_driver);
  120. MODULE_DEVICE_TABLE(pci, dev_id_table);
  121. MODULE_LICENSE("GPL");
  122. MODULE_DESCRIPTION("Cadence NIC PCI wrapper");