brintos

brintos / linux-shallow public Read only

0
0
Text · 3.3 KiB · fc4f5ae Raw
134 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 * DOC: Cadence GEM PCI wrapper.4 *5 * Copyright (C) 2016 Cadence Design Systems - https://www.cadence.com6 *7 * Authors: Rafal Ozieblo <rafalo@cadence.com>8 *	    Bartosz Folta <bfolta@cadence.com>9 */10 11#include <linux/clk.h>12#include <linux/clk-provider.h>13#include <linux/etherdevice.h>14#include <linux/module.h>15#include <linux/pci.h>16#include <linux/platform_device.h>17#include "macb.h"18 19#define PCI_DRIVER_NAME "macb_pci"20#define PLAT_DRIVER_NAME "macb"21 22#define PCI_DEVICE_ID_CDNS_MACB 0xe00723 24#define GEM_PCLK_RATE 5000000025#define GEM_HCLK_RATE 5000000026 27static int macb_probe(struct pci_dev *pdev, const struct pci_device_id *id)28{29	int err;30	struct platform_device *plat_dev;31	struct platform_device_info plat_info;32	struct macb_platform_data plat_data;33	struct resource res[2];34 35	/* enable pci device */36	err = pcim_enable_device(pdev);37	if (err < 0) {38		dev_err(&pdev->dev, "Enabling PCI device has failed: %d", err);39		return err;40	}41 42	pci_set_master(pdev);43 44	/* set up resources */45	memset(res, 0x00, sizeof(struct resource) * ARRAY_SIZE(res));46	res[0].start = pci_resource_start(pdev, 0);47	res[0].end = pci_resource_end(pdev, 0);48	res[0].name = PCI_DRIVER_NAME;49	res[0].flags = IORESOURCE_MEM;50	res[1].start = pci_irq_vector(pdev, 0);51	res[1].name = PCI_DRIVER_NAME;52	res[1].flags = IORESOURCE_IRQ;53 54	dev_info(&pdev->dev, "EMAC physical base addr: %pa\n",55		 &res[0].start);56 57	/* set up macb platform data */58	memset(&plat_data, 0, sizeof(plat_data));59 60	/* initialize clocks */61	plat_data.pclk = clk_register_fixed_rate(&pdev->dev, "pclk", NULL, 0,62						 GEM_PCLK_RATE);63	if (IS_ERR(plat_data.pclk)) {64		err = PTR_ERR(plat_data.pclk);65		goto err_pclk_register;66	}67 68	plat_data.hclk = clk_register_fixed_rate(&pdev->dev, "hclk", NULL, 0,69						 GEM_HCLK_RATE);70	if (IS_ERR(plat_data.hclk)) {71		err = PTR_ERR(plat_data.hclk);72		goto err_hclk_register;73	}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 87	/* register platform device */88	plat_dev = platform_device_register_full(&plat_info);89	if (IS_ERR(plat_dev)) {90		err = PTR_ERR(plat_dev);91		goto err_plat_dev_register;92	}93 94	pci_set_drvdata(pdev, plat_dev);95 96	return 0;97 98err_plat_dev_register:99	clk_unregister(plat_data.hclk);100 101err_hclk_register:102	clk_unregister(plat_data.pclk);103 104err_pclk_register:105	return err;106}107 108static void macb_remove(struct pci_dev *pdev)109{110	struct platform_device *plat_dev = pci_get_drvdata(pdev);111	struct macb_platform_data *plat_data = dev_get_platdata(&plat_dev->dev);112 113	clk_unregister(plat_data->pclk);114	clk_unregister(plat_data->hclk);115	platform_device_unregister(plat_dev);116}117 118static const struct pci_device_id dev_id_table[] = {119	{ PCI_VDEVICE(CDNS, PCI_DEVICE_ID_CDNS_MACB) },120	{ 0, }121};122 123static struct pci_driver macb_pci_driver = {124	.name     = PCI_DRIVER_NAME,125	.id_table = dev_id_table,126	.probe    = macb_probe,127	.remove	  = macb_remove,128};129 130module_pci_driver(macb_pci_driver);131MODULE_DEVICE_TABLE(pci, dev_id_table);132MODULE_LICENSE("GPL");133MODULE_DESCRIPTION("Cadence NIC PCI wrapper");134