Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * DOC: Cadence GEM PCI wrapper.
0004  *
0005  * Copyright (C) 2016 Cadence Design Systems - https://www.cadence.com
0006  *
0007  * Authors: Rafal Ozieblo <rafalo@cadence.com>
0008  *      Bartosz Folta <bfolta@cadence.com>
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     /* enable pci device */
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     /* set up resources */
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     /* set up macb platform data */
0059     memset(&plat_data, 0, sizeof(plat_data));
0060 
0061     /* initialize clocks */
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     /* set up platform device info */
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     /* register platform device */
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");