Eine aufbereitete Darstellung der Quelle

 
     
 
 
Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 

Benutzer

Quelle  pcie-hisi.c

  Sprache: C
 

// SPDX-License-Identifier: GPL-2.0
/*
 * PCIe host controller driver for HiSilicon SoCs
 *
 * Copyright (C) 2015 HiSilicon Co., Ltd. http://www.hisilicon.com
 *
 * Authors: Zhou Wang <wangzhou1@hisilicon.com>
 *          Dacai Zhu <zhudacai@hisilicon.com>
 *          Gabriele Paoloni <gabriele.paoloni@huawei.com>
 */

#include <linux/interrupt.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/pci.h>
#include <linux/pci-acpi.h>
#include <linux/pci-ecam.h>
#include "../../pci.h"
#include "../pci-host-common.h"

#if defined(CONFIG_PCI_HISI) || (defined(CONFIG_ACPI) && defined(CONFIG_PCI_QUIRKS))

struct hisi_pcie {
 void __iomem *reg_base;
};

static int hisi_pcie_rd_conf(struct pci_bus *bus, u32 devfn, int where,
        int size, u32 *val)
{
 struct pci_config_window *cfg = bus->sysdata;
 int dev = PCI_SLOT(devfn);

 if (bus->number == cfg->busr.start) {
  /* access only one slot on each root port */
  if (dev > 0)
   return PCIBIOS_DEVICE_NOT_FOUND;
  else
   return pci_generic_config_read32(bus, devfn, where,
        size, val);
 }

 return pci_generic_config_read(bus, devfn, where, size, val);
}

static int hisi_pcie_wr_conf(struct pci_bus *bus, u32 devfn,
        int where, int size, u32 val)
{
 struct pci_config_window *cfg = bus->sysdata;
 int dev = PCI_SLOT(devfn);

 if (bus->number == cfg->busr.start) {
  /* access only one slot on each root port */
  if (dev > 0)
   return PCIBIOS_DEVICE_NOT_FOUND;
  else
   return pci_generic_config_write32(bus, devfn, where,
         size, val);
 }

 return pci_generic_config_write(bus, devfn, where, size, val);
}

static void __iomem *hisi_pcie_map_bus(struct pci_bus *bus, unsigned int devfn,
           int where)
{
 struct pci_config_window *cfg = bus->sysdata;
 struct hisi_pcie *pcie = cfg->priv;

 if (bus->number == cfg->busr.start)
  return pcie->reg_base + where;
 else
  return pci_ecam_map_bus(bus, devfn, where);
}

#if defined(CONFIG_ACPI) && defined(CONFIG_PCI_QUIRKS)

static int hisi_pcie_init(struct pci_config_window *cfg)
{
 struct device *dev = cfg->parent;
 struct hisi_pcie *pcie;
 struct acpi_device *adev = to_acpi_device(dev);
 struct acpi_pci_root *root = acpi_driver_data(adev);
 struct resource *res;
 int ret;

 pcie = devm_kzalloc(dev, sizeof(*pcie), GFP_KERNEL);
 if (!pcie)
  return -ENOMEM;

 /*
 * Retrieve RC base and size from a HISI0081 device with _UID
 * matching our segment.
 */

 res = devm_kzalloc(dev, sizeof(*res), GFP_KERNEL);
 if (!res)
  return -ENOMEM;

 ret = acpi_get_rc_resources(dev, "HISI0081", root->segment, res);
 if (ret) {
  dev_err(dev, "can't get rc base address\n");
  return -ENOMEM;
 }

 pcie->reg_base = devm_pci_remap_cfgspace(dev, res->start, resource_size(res));
 if (!pcie->reg_base)
  return -ENOMEM;

 cfg->priv = pcie;
 return 0;
}

const struct pci_ecam_ops hisi_pcie_ops = {
 .init         =  hisi_pcie_init,
 .pci_ops      = {
  .map_bus    = hisi_pcie_map_bus,
  .read       = hisi_pcie_rd_conf,
  .write      = hisi_pcie_wr_conf,
 }
};

#endif

#ifdef CONFIG_PCI_HISI

static int hisi_pcie_platform_init(struct pci_config_window *cfg)
{
 struct device *dev = cfg->parent;
 struct hisi_pcie *pcie;
 struct platform_device *pdev = to_platform_device(dev);
 struct resource *res;

 pcie = devm_kzalloc(dev, sizeof(*pcie), GFP_KERNEL);
 if (!pcie)
  return -ENOMEM;

 res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
 if (!res) {
  dev_err(dev, "missing \"reg[1]\"property\n");
  return -EINVAL;
 }

 pcie->reg_base = devm_pci_remap_cfgspace(dev, res->start, resource_size(res));
 if (!pcie->reg_base)
  return -ENOMEM;

 cfg->priv = pcie;
 return 0;
}

static const struct pci_ecam_ops hisi_pcie_platform_ops = {
 .init         =  hisi_pcie_platform_init,
 .pci_ops      = {
  .map_bus    = hisi_pcie_map_bus,
  .read       = hisi_pcie_rd_conf,
  .write      = hisi_pcie_wr_conf,
 }
};

static const struct of_device_id hisi_pcie_almost_ecam_of_match[] = {
 {
  .compatible =  "hisilicon,hip06-pcie-ecam",
  .data     =  &hisi_pcie_platform_ops,
 },
 {
  .compatible =  "hisilicon,hip07-pcie-ecam",
  .data       =  &hisi_pcie_platform_ops,
 },
 {},
};

static struct platform_driver hisi_pcie_almost_ecam_driver = {
 .probe  = pci_host_common_probe,
 .driver = {
     .name = "hisi-pcie-almost-ecam",
     .of_match_table = hisi_pcie_almost_ecam_of_match,
     .suppress_bind_attrs = true,
 },
};
builtin_platform_driver(hisi_pcie_almost_ecam_driver);

#endif
#endif

Messung V0.5 in Prozent
C=93 H=93 G=92

¤ Dauer der Verarbeitung: 0.1 Sekunden  (vorverarbeitet am  2026-06-05) ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

PVS Prover

Isabelle Prover

NIST Cobol Testsuite

Cephes Mathematical Library

Vienna Development Method

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Open Source Software

     Quellcodebibliothek
     Eigene Quellcodes
     Fremde Quellcodes
     Suchen

Jenseits des Üblichen ....
    

Besucherstatistik

Besucherstatistik

Statistik
#Sources=277311
#Domains=752002