0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #include <linux/clk.h>
0012 #include <linux/clk-provider.h>
0013 #include <linux/etherdevice.h>
0014 #include <linux/module.h>
0015 #include <linux/pci.h>
0016 #include <linux/platform_device.h>
0017 #include "macb.h"
0018
0019 #define PCI_DRIVER_NAME "macb_pci"
0020 #define PLAT_DRIVER_NAME "macb"
0021
0022 #define CDNS_VENDOR_ID 0x17cd
0023 #define CDNS_DEVICE_ID 0xe007
0024
0025 #define GEM_PCLK_RATE 50000000
0026 #define GEM_HCLK_RATE 50000000
0027
0028 static int macb_probe(struct pci_dev *pdev, const struct pci_device_id *id)
0029 {
0030 int err;
0031 struct platform_device *plat_dev;
0032 struct platform_device_info plat_info;
0033 struct macb_platform_data plat_data;
0034 struct resource res[2];
0035
0036
0037 err = pcim_enable_device(pdev);
0038 if (err < 0) {
0039 dev_err(&pdev->dev, "Enabling PCI device has failed: %d", err);
0040 return err;
0041 }
0042
0043 pci_set_master(pdev);
0044
0045
0046 memset(res, 0x00, sizeof(struct resource) * ARRAY_SIZE(res));
0047 res[0].start = pci_resource_start(pdev, 0);
0048 res[0].end = pci_resource_end(pdev, 0);
0049 res[0].name = PCI_DRIVER_NAME;
0050 res[0].flags = IORESOURCE_MEM;
0051 res[1].start = pci_irq_vector(pdev, 0);
0052 res[1].name = PCI_DRIVER_NAME;
0053 res[1].flags = IORESOURCE_IRQ;
0054
0055 dev_info(&pdev->dev, "EMAC physical base addr: %pa\n",
0056 &res[0].start);
0057
0058
0059 memset(&plat_data, 0, sizeof(plat_data));
0060
0061
0062 plat_data.pclk = clk_register_fixed_rate(&pdev->dev, "pclk", NULL, 0,
0063 GEM_PCLK_RATE);
0064 if (IS_ERR(plat_data.pclk)) {
0065 err = PTR_ERR(plat_data.pclk);
0066 goto err_pclk_register;
0067 }
0068
0069 plat_data.hclk = clk_register_fixed_rate(&pdev->dev, "hclk", NULL, 0,
0070 GEM_HCLK_RATE);
0071 if (IS_ERR(plat_data.hclk)) {
0072 err = PTR_ERR(plat_data.hclk);
0073 goto err_hclk_register;
0074 }
0075
0076
0077 memset(&plat_info, 0, sizeof(plat_info));
0078 plat_info.parent = &pdev->dev;
0079 plat_info.fwnode = pdev->dev.fwnode;
0080 plat_info.name = PLAT_DRIVER_NAME;
0081 plat_info.id = pdev->devfn;
0082 plat_info.res = res;
0083 plat_info.num_res = ARRAY_SIZE(res);
0084 plat_info.data = &plat_data;
0085 plat_info.size_data = sizeof(plat_data);
0086 plat_info.dma_mask = pdev->dma_mask;
0087
0088
0089 plat_dev = platform_device_register_full(&plat_info);
0090 if (IS_ERR(plat_dev)) {
0091 err = PTR_ERR(plat_dev);
0092 goto err_plat_dev_register;
0093 }
0094
0095 pci_set_drvdata(pdev, plat_dev);
0096
0097 return 0;
0098
0099 err_plat_dev_register:
0100 clk_unregister(plat_data.hclk);
0101
0102 err_hclk_register:
0103 clk_unregister(plat_data.pclk);
0104
0105 err_pclk_register:
0106 return err;
0107 }
0108
0109 static void macb_remove(struct pci_dev *pdev)
0110 {
0111 struct platform_device *plat_dev = pci_get_drvdata(pdev);
0112 struct macb_platform_data *plat_data = dev_get_platdata(&plat_dev->dev);
0113
0114 clk_unregister(plat_data->pclk);
0115 clk_unregister(plat_data->hclk);
0116 platform_device_unregister(plat_dev);
0117 }
0118
0119 static const struct pci_device_id dev_id_table[] = {
0120 { PCI_DEVICE(CDNS_VENDOR_ID, CDNS_DEVICE_ID), },
0121 { 0, }
0122 };
0123
0124 static struct pci_driver macb_pci_driver = {
0125 .name = PCI_DRIVER_NAME,
0126 .id_table = dev_id_table,
0127 .probe = macb_probe,
0128 .remove = macb_remove,
0129 };
0130
0131 module_pci_driver(macb_pci_driver);
0132 MODULE_DEVICE_TABLE(pci, dev_id_table);
0133 MODULE_LICENSE("GPL");
0134 MODULE_DESCRIPTION("Cadence NIC PCI wrapper");