mirror of
https://github.com/Qortal/Brooklyn.git
synced 2025-01-30 14:52:17 +00:00
phase 7
This commit is contained in:
parent
bdb2b1eed6
commit
b9d9e26075
@ -19,8 +19,7 @@
|
||||
#include <linux/clk/clk-conf.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/reset.h>
|
||||
|
||||
#include <asm/irq.h>
|
||||
#include <linux/of_irq.h>
|
||||
|
||||
#define to_amba_driver(d) container_of(d, struct amba_driver, drv)
|
||||
|
||||
@ -135,8 +134,6 @@ static ssize_t name##_show(struct device *_dev, \
|
||||
static DEVICE_ATTR_RO(name)
|
||||
|
||||
amba_attr_func(id, "%08x\n", dev->periphid);
|
||||
amba_attr_func(irq0, "%u\n", dev->irq[0]);
|
||||
amba_attr_func(irq1, "%u\n", dev->irq[1]);
|
||||
amba_attr_func(resource, "\t%016llx\t%016llx\t%016lx\n",
|
||||
(unsigned long long)dev->res.start, (unsigned long long)dev->res.end,
|
||||
dev->res.flags);
|
||||
@ -174,6 +171,28 @@ static int amba_uevent(struct device *dev, struct kobj_uevent_env *env)
|
||||
return retval;
|
||||
}
|
||||
|
||||
static int of_amba_device_decode_irq(struct amba_device *dev)
|
||||
{
|
||||
struct device_node *node = dev->dev.of_node;
|
||||
int i, irq = 0;
|
||||
|
||||
if (IS_ENABLED(CONFIG_OF_IRQ) && node) {
|
||||
/* Decode the IRQs and address ranges */
|
||||
for (i = 0; i < AMBA_NR_IRQS; i++) {
|
||||
irq = of_irq_get(node, i);
|
||||
if (irq < 0) {
|
||||
if (irq == -EPROBE_DEFER)
|
||||
return irq;
|
||||
irq = 0;
|
||||
}
|
||||
|
||||
dev->irq[i] = irq;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* These are the device model conversion veneers; they convert the
|
||||
* device model structures to our more specific structures.
|
||||
@ -186,6 +205,10 @@ static int amba_probe(struct device *dev)
|
||||
int ret;
|
||||
|
||||
do {
|
||||
ret = of_amba_device_decode_irq(pcdev);
|
||||
if (ret)
|
||||
break;
|
||||
|
||||
ret = of_clk_set_defaults(dev->of_node, false);
|
||||
if (ret < 0)
|
||||
break;
|
||||
@ -461,20 +484,9 @@ static int amba_device_try_add(struct amba_device *dev, struct resource *parent)
|
||||
|
||||
skip_probe:
|
||||
ret = device_add(&dev->dev);
|
||||
if (ret)
|
||||
goto err_release;
|
||||
|
||||
if (dev->irq[0])
|
||||
ret = device_create_file(&dev->dev, &dev_attr_irq0);
|
||||
if (ret == 0 && dev->irq[1])
|
||||
ret = device_create_file(&dev->dev, &dev_attr_irq1);
|
||||
if (ret == 0)
|
||||
return ret;
|
||||
|
||||
device_unregister(&dev->dev);
|
||||
|
||||
err_release:
|
||||
release_resource(&dev->res);
|
||||
if (ret)
|
||||
release_resource(&dev->res);
|
||||
err_out:
|
||||
return ret;
|
||||
|
||||
@ -576,78 +588,6 @@ int amba_device_add(struct amba_device *dev, struct resource *parent)
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(amba_device_add);
|
||||
|
||||
static struct amba_device *
|
||||
amba_aphb_device_add(struct device *parent, const char *name,
|
||||
resource_size_t base, size_t size, int irq1, int irq2,
|
||||
void *pdata, unsigned int periphid, u64 dma_mask,
|
||||
struct resource *resbase)
|
||||
{
|
||||
struct amba_device *dev;
|
||||
int ret;
|
||||
|
||||
dev = amba_device_alloc(name, base, size);
|
||||
if (!dev)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
dev->dev.coherent_dma_mask = dma_mask;
|
||||
dev->irq[0] = irq1;
|
||||
dev->irq[1] = irq2;
|
||||
dev->periphid = periphid;
|
||||
dev->dev.platform_data = pdata;
|
||||
dev->dev.parent = parent;
|
||||
|
||||
ret = amba_device_add(dev, resbase);
|
||||
if (ret) {
|
||||
amba_device_put(dev);
|
||||
return ERR_PTR(ret);
|
||||
}
|
||||
|
||||
return dev;
|
||||
}
|
||||
|
||||
struct amba_device *
|
||||
amba_apb_device_add(struct device *parent, const char *name,
|
||||
resource_size_t base, size_t size, int irq1, int irq2,
|
||||
void *pdata, unsigned int periphid)
|
||||
{
|
||||
return amba_aphb_device_add(parent, name, base, size, irq1, irq2, pdata,
|
||||
periphid, 0, &iomem_resource);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(amba_apb_device_add);
|
||||
|
||||
struct amba_device *
|
||||
amba_ahb_device_add(struct device *parent, const char *name,
|
||||
resource_size_t base, size_t size, int irq1, int irq2,
|
||||
void *pdata, unsigned int periphid)
|
||||
{
|
||||
return amba_aphb_device_add(parent, name, base, size, irq1, irq2, pdata,
|
||||
periphid, ~0ULL, &iomem_resource);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(amba_ahb_device_add);
|
||||
|
||||
struct amba_device *
|
||||
amba_apb_device_add_res(struct device *parent, const char *name,
|
||||
resource_size_t base, size_t size, int irq1,
|
||||
int irq2, void *pdata, unsigned int periphid,
|
||||
struct resource *resbase)
|
||||
{
|
||||
return amba_aphb_device_add(parent, name, base, size, irq1, irq2, pdata,
|
||||
periphid, 0, resbase);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(amba_apb_device_add_res);
|
||||
|
||||
struct amba_device *
|
||||
amba_ahb_device_add_res(struct device *parent, const char *name,
|
||||
resource_size_t base, size_t size, int irq1,
|
||||
int irq2, void *pdata, unsigned int periphid,
|
||||
struct resource *resbase)
|
||||
{
|
||||
return amba_aphb_device_add(parent, name, base, size, irq1, irq2, pdata,
|
||||
periphid, ~0ULL, resbase);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(amba_ahb_device_add_res);
|
||||
|
||||
|
||||
static void amba_device_initialize(struct amba_device *dev, const char *name)
|
||||
{
|
||||
device_initialize(&dev->dev);
|
||||
|
@ -588,20 +588,11 @@ static void agp_amd64_remove(struct pci_dev *pdev)
|
||||
agp_bridges_found--;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
#define agp_amd64_suspend NULL
|
||||
|
||||
static int agp_amd64_suspend(struct pci_dev *pdev, pm_message_t state)
|
||||
static int __maybe_unused agp_amd64_resume(struct device *dev)
|
||||
{
|
||||
pci_save_state(pdev);
|
||||
pci_set_power_state(pdev, pci_choose_state(pdev, state));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int agp_amd64_resume(struct pci_dev *pdev)
|
||||
{
|
||||
pci_set_power_state(pdev, PCI_D0);
|
||||
pci_restore_state(pdev);
|
||||
struct pci_dev *pdev = to_pci_dev(dev);
|
||||
|
||||
if (pdev->vendor == PCI_VENDOR_ID_NVIDIA)
|
||||
nforce3_agp_init(pdev);
|
||||
@ -609,8 +600,6 @@ static int agp_amd64_resume(struct pci_dev *pdev)
|
||||
return amd_8151_configure();
|
||||
}
|
||||
|
||||
#endif /* CONFIG_PM */
|
||||
|
||||
static const struct pci_device_id agp_amd64_pci_table[] = {
|
||||
{
|
||||
.class = (PCI_CLASS_BRIDGE_HOST << 8),
|
||||
@ -738,15 +727,14 @@ static const struct pci_device_id agp_amd64_pci_promisc_table[] = {
|
||||
{ }
|
||||
};
|
||||
|
||||
static SIMPLE_DEV_PM_OPS(agp_amd64_pm_ops, agp_amd64_suspend, agp_amd64_resume);
|
||||
|
||||
static struct pci_driver agp_amd64_pci_driver = {
|
||||
.name = "agpgart-amd64",
|
||||
.id_table = agp_amd64_pci_table,
|
||||
.probe = agp_amd64_probe,
|
||||
.remove = agp_amd64_remove,
|
||||
#ifdef CONFIG_PM
|
||||
.suspend = agp_amd64_suspend,
|
||||
.resume = agp_amd64_resume,
|
||||
#endif
|
||||
.driver.pm = &agp_amd64_pm_ops,
|
||||
};
|
||||
|
||||
|
||||
|
@ -20,6 +20,7 @@
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/pagemap.h>
|
||||
#include <linux/agp_backend.h>
|
||||
#include <linux/intel-iommu.h>
|
||||
#include <linux/delay.h>
|
||||
#include <asm/smp.h>
|
||||
#include "agp.h"
|
||||
|
@ -217,26 +217,14 @@ static void agp_sis_remove(struct pci_dev *pdev)
|
||||
agp_put_bridge(bridge);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
#define agp_sis_suspend NULL
|
||||
|
||||
static int agp_sis_suspend(struct pci_dev *pdev, pm_message_t state)
|
||||
static int __maybe_unused agp_sis_resume(
|
||||
__attribute__((unused)) struct device *dev)
|
||||
{
|
||||
pci_save_state(pdev);
|
||||
pci_set_power_state(pdev, pci_choose_state(pdev, state));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int agp_sis_resume(struct pci_dev *pdev)
|
||||
{
|
||||
pci_set_power_state(pdev, PCI_D0);
|
||||
pci_restore_state(pdev);
|
||||
|
||||
return sis_driver.configure();
|
||||
}
|
||||
|
||||
#endif /* CONFIG_PM */
|
||||
|
||||
static const struct pci_device_id agp_sis_pci_table[] = {
|
||||
{
|
||||
.class = (PCI_CLASS_BRIDGE_HOST << 8),
|
||||
@ -419,15 +407,14 @@ static const struct pci_device_id agp_sis_pci_table[] = {
|
||||
|
||||
MODULE_DEVICE_TABLE(pci, agp_sis_pci_table);
|
||||
|
||||
static SIMPLE_DEV_PM_OPS(agp_sis_pm_ops, agp_sis_suspend, agp_sis_resume);
|
||||
|
||||
static struct pci_driver agp_sis_pci_driver = {
|
||||
.name = "agpgart-sis",
|
||||
.id_table = agp_sis_pci_table,
|
||||
.probe = agp_sis_probe,
|
||||
.remove = agp_sis_remove,
|
||||
#ifdef CONFIG_PM
|
||||
.suspend = agp_sis_suspend,
|
||||
.resume = agp_sis_resume,
|
||||
#endif
|
||||
.driver.pm = &agp_sis_pm_ops,
|
||||
};
|
||||
|
||||
static int __init agp_sis_init(void)
|
||||
|
@ -492,22 +492,11 @@ static void agp_via_remove(struct pci_dev *pdev)
|
||||
agp_put_bridge(bridge);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
#define agp_via_suspend NULL
|
||||
|
||||
static int agp_via_suspend(struct pci_dev *pdev, pm_message_t state)
|
||||
static int __maybe_unused agp_via_resume(struct device *dev)
|
||||
{
|
||||
pci_save_state (pdev);
|
||||
pci_set_power_state (pdev, PCI_D3hot);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int agp_via_resume(struct pci_dev *pdev)
|
||||
{
|
||||
struct agp_bridge_data *bridge = pci_get_drvdata(pdev);
|
||||
|
||||
pci_set_power_state (pdev, PCI_D0);
|
||||
pci_restore_state(pdev);
|
||||
struct agp_bridge_data *bridge = dev_get_drvdata(dev);
|
||||
|
||||
if (bridge->driver == &via_agp3_driver)
|
||||
return via_configure_agp3();
|
||||
@ -517,8 +506,6 @@ static int agp_via_resume(struct pci_dev *pdev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_PM */
|
||||
|
||||
/* must be the same order as name table above */
|
||||
static const struct pci_device_id agp_via_pci_table[] = {
|
||||
#define ID(x) \
|
||||
@ -567,16 +554,14 @@ static const struct pci_device_id agp_via_pci_table[] = {
|
||||
|
||||
MODULE_DEVICE_TABLE(pci, agp_via_pci_table);
|
||||
|
||||
static SIMPLE_DEV_PM_OPS(agp_via_pm_ops, agp_via_suspend, agp_via_resume);
|
||||
|
||||
static struct pci_driver agp_via_pci_driver = {
|
||||
.name = "agpgart-via",
|
||||
.id_table = agp_via_pci_table,
|
||||
.probe = agp_via_probe,
|
||||
.remove = agp_via_remove,
|
||||
#ifdef CONFIG_PM
|
||||
.suspend = agp_via_suspend,
|
||||
.resume = agp_via_resume,
|
||||
#endif
|
||||
.driver.pm = &agp_via_pm_ops,
|
||||
};
|
||||
|
||||
|
||||
|
@ -89,8 +89,8 @@ static struct applicom_board {
|
||||
spinlock_t mutex;
|
||||
} apbs[MAX_BOARD];
|
||||
|
||||
static unsigned int irq = 0; /* interrupt number IRQ */
|
||||
static unsigned long mem = 0; /* physical segment of board */
|
||||
static unsigned int irq; /* interrupt number IRQ */
|
||||
static unsigned long mem; /* physical segment of board */
|
||||
|
||||
module_param_hw(irq, uint, irq, 0);
|
||||
MODULE_PARM_DESC(irq, "IRQ of the Applicom board");
|
||||
|
@ -746,26 +746,6 @@ static struct ctl_table hpet_table[] = {
|
||||
{}
|
||||
};
|
||||
|
||||
static struct ctl_table hpet_root[] = {
|
||||
{
|
||||
.procname = "hpet",
|
||||
.maxlen = 0,
|
||||
.mode = 0555,
|
||||
.child = hpet_table,
|
||||
},
|
||||
{}
|
||||
};
|
||||
|
||||
static struct ctl_table dev_root[] = {
|
||||
{
|
||||
.procname = "dev",
|
||||
.maxlen = 0,
|
||||
.mode = 0555,
|
||||
.child = hpet_root,
|
||||
},
|
||||
{}
|
||||
};
|
||||
|
||||
static struct ctl_table_header *sysctl_header;
|
||||
|
||||
/*
|
||||
@ -1061,7 +1041,7 @@ static int __init hpet_init(void)
|
||||
if (result < 0)
|
||||
return -ENODEV;
|
||||
|
||||
sysctl_header = register_sysctl_table(dev_root);
|
||||
sysctl_header = register_sysctl("dev/hpet", hpet_table);
|
||||
|
||||
result = acpi_bus_register_driver(&hpet_acpi_driver);
|
||||
if (result < 0) {
|
||||
|
@ -63,7 +63,7 @@ config HW_RANDOM_AMD
|
||||
|
||||
config HW_RANDOM_ATMEL
|
||||
tristate "Atmel Random Number Generator support"
|
||||
depends on ARCH_AT91 && HAVE_CLK && OF
|
||||
depends on (ARCH_AT91 || COMPILE_TEST) && HAVE_CLK && OF
|
||||
default HW_RANDOM
|
||||
help
|
||||
This driver provides kernel-side support for the Random Number
|
||||
@ -87,7 +87,7 @@ config HW_RANDOM_BA431
|
||||
config HW_RANDOM_BCM2835
|
||||
tristate "Broadcom BCM2835/BCM63xx Random Number Generator support"
|
||||
depends on ARCH_BCM2835 || ARCH_BCM_NSP || ARCH_BCM_5301X || \
|
||||
ARCH_BCM_63XX || BCM63XX || BMIPS_GENERIC
|
||||
ARCH_BCM_63XX || BCM63XX || BMIPS_GENERIC || COMPILE_TEST
|
||||
default HW_RANDOM
|
||||
help
|
||||
This driver provides kernel-side support for the Random Number
|
||||
@ -100,7 +100,7 @@ config HW_RANDOM_BCM2835
|
||||
|
||||
config HW_RANDOM_IPROC_RNG200
|
||||
tristate "Broadcom iProc/STB RNG200 support"
|
||||
depends on ARCH_BCM_IPROC || ARCH_BCM2835 || ARCH_BRCMSTB
|
||||
depends on ARCH_BCM_IPROC || ARCH_BCM2835 || ARCH_BRCMSTB || COMPILE_TEST
|
||||
default HW_RANDOM
|
||||
help
|
||||
This driver provides kernel-side support for the RNG200
|
||||
@ -165,7 +165,7 @@ config HW_RANDOM_IXP4XX
|
||||
|
||||
config HW_RANDOM_OMAP
|
||||
tristate "OMAP Random Number Generator support"
|
||||
depends on ARCH_OMAP16XX || ARCH_OMAP2PLUS || ARCH_MVEBU || ARCH_K3
|
||||
depends on ARCH_OMAP16XX || ARCH_OMAP2PLUS || ARCH_MVEBU || ARCH_K3 || COMPILE_TEST
|
||||
default HW_RANDOM
|
||||
help
|
||||
This driver provides kernel-side support for the Random Number
|
||||
@ -179,7 +179,7 @@ config HW_RANDOM_OMAP
|
||||
|
||||
config HW_RANDOM_OMAP3_ROM
|
||||
tristate "OMAP3 ROM Random Number Generator support"
|
||||
depends on ARCH_OMAP3
|
||||
depends on ARCH_OMAP3 || COMPILE_TEST
|
||||
default HW_RANDOM
|
||||
help
|
||||
This driver provides kernel-side support for the Random Number
|
||||
@ -226,19 +226,6 @@ config HW_RANDOM_VIRTIO
|
||||
To compile this driver as a module, choose M here: the
|
||||
module will be called virtio-rng. If unsure, say N.
|
||||
|
||||
config HW_RANDOM_TX4939
|
||||
tristate "TX4939 Random Number Generator support"
|
||||
depends on SOC_TX4939
|
||||
default HW_RANDOM
|
||||
help
|
||||
This driver provides kernel-side support for the Random Number
|
||||
Generator hardware found on TX4939 SoC.
|
||||
|
||||
To compile this driver as a module, choose M here: the
|
||||
module will be called tx4939-rng.
|
||||
|
||||
If unsure, say Y.
|
||||
|
||||
config HW_RANDOM_MXC_RNGA
|
||||
tristate "Freescale i.MX RNGA Random Number Generator"
|
||||
depends on SOC_IMX31
|
||||
@ -298,7 +285,7 @@ config HW_RANDOM_INGENIC_TRNG
|
||||
|
||||
config HW_RANDOM_NOMADIK
|
||||
tristate "ST-Ericsson Nomadik Random Number Generator support"
|
||||
depends on ARCH_NOMADIK
|
||||
depends on ARCH_NOMADIK || COMPILE_TEST
|
||||
default HW_RANDOM
|
||||
help
|
||||
This driver provides kernel-side support for the Random Number
|
||||
@ -414,7 +401,7 @@ config HW_RANDOM_MESON
|
||||
|
||||
config HW_RANDOM_CAVIUM
|
||||
tristate "Cavium ThunderX Random Number Generator support"
|
||||
depends on HW_RANDOM && PCI && (ARM64 || (COMPILE_TEST && 64BIT))
|
||||
depends on HW_RANDOM && PCI && ARM64
|
||||
default HW_RANDOM
|
||||
help
|
||||
This driver provides kernel-side support for the Random Number
|
||||
@ -538,6 +525,17 @@ config HW_RANDOM_ARM_SMCCC_TRNG
|
||||
To compile this driver as a module, choose M here: the
|
||||
module will be called arm_smccc_trng.
|
||||
|
||||
config HW_RANDOM_CN10K
|
||||
tristate "Marvell CN10K Random Number Generator support"
|
||||
depends on HW_RANDOM && PCI && ARM64
|
||||
default HW_RANDOM
|
||||
help
|
||||
This driver provides support for the True Random Number
|
||||
generator available in Marvell CN10K SoCs.
|
||||
|
||||
To compile this driver as a module, choose M here.
|
||||
The module will be called cn10k_rng. If unsure, say Y.
|
||||
|
||||
endif # HW_RANDOM
|
||||
|
||||
config UML_RANDOM
|
||||
|
@ -20,7 +20,6 @@ obj-$(CONFIG_HW_RANDOM_OMAP) += omap-rng.o
|
||||
obj-$(CONFIG_HW_RANDOM_OMAP3_ROM) += omap3-rom-rng.o
|
||||
obj-$(CONFIG_HW_RANDOM_PASEMI) += pasemi-rng.o
|
||||
obj-$(CONFIG_HW_RANDOM_VIRTIO) += virtio-rng.o
|
||||
obj-$(CONFIG_HW_RANDOM_TX4939) += tx4939-rng.o
|
||||
obj-$(CONFIG_HW_RANDOM_MXC_RNGA) += mxc-rnga.o
|
||||
obj-$(CONFIG_HW_RANDOM_IMX_RNGC) += imx-rngc.o
|
||||
obj-$(CONFIG_HW_RANDOM_INGENIC_RNG) += ingenic-rng.o
|
||||
@ -46,3 +45,4 @@ obj-$(CONFIG_HW_RANDOM_NPCM) += npcm-rng.o
|
||||
obj-$(CONFIG_HW_RANDOM_CCTRNG) += cctrng.o
|
||||
obj-$(CONFIG_HW_RANDOM_XIPHERA) += xiphera-trng.o
|
||||
obj-$(CONFIG_HW_RANDOM_ARM_SMCCC_TRNG) += arm_smccc_trng.o
|
||||
obj-$(CONFIG_HW_RANDOM_CN10K) += cn10k-rng.o
|
||||
|
@ -1,10 +1,7 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Hardware Random Number Generator support for Cavium, Inc.
|
||||
* Thunder processor family.
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU General Public
|
||||
* License. See the file "COPYING" in the main directory of this archive
|
||||
* for more details.
|
||||
* Hardware Random Number Generator support.
|
||||
* Cavium Thunder, Marvell OcteonTx/Tx2 processor families.
|
||||
*
|
||||
* Copyright (C) 2016 Cavium, Inc.
|
||||
*/
|
||||
@ -15,16 +12,146 @@
|
||||
#include <linux/pci.h>
|
||||
#include <linux/pci_ids.h>
|
||||
|
||||
#include <asm/arch_timer.h>
|
||||
|
||||
/* PCI device IDs */
|
||||
#define PCI_DEVID_CAVIUM_RNG_PF 0xA018
|
||||
#define PCI_DEVID_CAVIUM_RNG_VF 0xA033
|
||||
|
||||
#define HEALTH_STATUS_REG 0x38
|
||||
|
||||
/* RST device info */
|
||||
#define PCI_DEVICE_ID_RST_OTX2 0xA085
|
||||
#define RST_BOOT_REG 0x1600ULL
|
||||
#define CLOCK_BASE_RATE 50000000ULL
|
||||
#define MSEC_TO_NSEC(x) (x * 1000000)
|
||||
|
||||
struct cavium_rng {
|
||||
struct hwrng ops;
|
||||
void __iomem *result;
|
||||
void __iomem *pf_regbase;
|
||||
struct pci_dev *pdev;
|
||||
u64 clock_rate;
|
||||
u64 prev_error;
|
||||
u64 prev_time;
|
||||
};
|
||||
|
||||
static inline bool is_octeontx(struct pci_dev *pdev)
|
||||
{
|
||||
if (midr_is_cpu_model_range(read_cpuid_id(), MIDR_THUNDERX_83XX,
|
||||
MIDR_CPU_VAR_REV(0, 0),
|
||||
MIDR_CPU_VAR_REV(3, 0)) ||
|
||||
midr_is_cpu_model_range(read_cpuid_id(), MIDR_THUNDERX_81XX,
|
||||
MIDR_CPU_VAR_REV(0, 0),
|
||||
MIDR_CPU_VAR_REV(3, 0)) ||
|
||||
midr_is_cpu_model_range(read_cpuid_id(), MIDR_THUNDERX,
|
||||
MIDR_CPU_VAR_REV(0, 0),
|
||||
MIDR_CPU_VAR_REV(3, 0)))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static u64 rng_get_coprocessor_clkrate(void)
|
||||
{
|
||||
u64 ret = CLOCK_BASE_RATE * 16; /* Assume 800Mhz as default */
|
||||
struct pci_dev *pdev;
|
||||
void __iomem *base;
|
||||
|
||||
pdev = pci_get_device(PCI_VENDOR_ID_CAVIUM,
|
||||
PCI_DEVICE_ID_RST_OTX2, NULL);
|
||||
if (!pdev)
|
||||
goto error;
|
||||
|
||||
base = pci_ioremap_bar(pdev, 0);
|
||||
if (!base)
|
||||
goto error_put_pdev;
|
||||
|
||||
/* RST: PNR_MUL * 50Mhz gives clockrate */
|
||||
ret = CLOCK_BASE_RATE * ((readq(base + RST_BOOT_REG) >> 33) & 0x3F);
|
||||
|
||||
iounmap(base);
|
||||
|
||||
error_put_pdev:
|
||||
pci_dev_put(pdev);
|
||||
|
||||
error:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int check_rng_health(struct cavium_rng *rng)
|
||||
{
|
||||
u64 cur_err, cur_time;
|
||||
u64 status, cycles;
|
||||
u64 time_elapsed;
|
||||
|
||||
|
||||
/* Skip checking health for OcteonTx */
|
||||
if (!rng->pf_regbase)
|
||||
return 0;
|
||||
|
||||
status = readq(rng->pf_regbase + HEALTH_STATUS_REG);
|
||||
if (status & BIT_ULL(0)) {
|
||||
dev_err(&rng->pdev->dev, "HWRNG: Startup health test failed\n");
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
cycles = status >> 1;
|
||||
if (!cycles)
|
||||
return 0;
|
||||
|
||||
cur_time = arch_timer_read_counter();
|
||||
|
||||
/* RNM_HEALTH_STATUS[CYCLES_SINCE_HEALTH_FAILURE]
|
||||
* Number of coprocessor cycles times 2 since the last failure.
|
||||
* This field doesn't get cleared/updated until another failure.
|
||||
*/
|
||||
cycles = cycles / 2;
|
||||
cur_err = (cycles * 1000000000) / rng->clock_rate; /* In nanosec */
|
||||
|
||||
/* Ignore errors that happenned a long time ago, these
|
||||
* are most likely false positive errors.
|
||||
*/
|
||||
if (cur_err > MSEC_TO_NSEC(10)) {
|
||||
rng->prev_error = 0;
|
||||
rng->prev_time = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (rng->prev_error) {
|
||||
/* Calculate time elapsed since last error
|
||||
* '1' tick of CNTVCT is 10ns, since it runs at 100Mhz.
|
||||
*/
|
||||
time_elapsed = (cur_time - rng->prev_time) * 10;
|
||||
time_elapsed += rng->prev_error;
|
||||
|
||||
/* Check if current error is a new one or the old one itself.
|
||||
* If error is a new one then consider there is a persistent
|
||||
* issue with entropy, declare hardware failure.
|
||||
*/
|
||||
if (cur_err < time_elapsed) {
|
||||
dev_err(&rng->pdev->dev, "HWRNG failure detected\n");
|
||||
rng->prev_error = cur_err;
|
||||
rng->prev_time = cur_time;
|
||||
return -EIO;
|
||||
}
|
||||
}
|
||||
|
||||
rng->prev_error = cur_err;
|
||||
rng->prev_time = cur_time;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Read data from the RNG unit */
|
||||
static int cavium_rng_read(struct hwrng *rng, void *dat, size_t max, bool wait)
|
||||
{
|
||||
struct cavium_rng *p = container_of(rng, struct cavium_rng, ops);
|
||||
unsigned int size = max;
|
||||
int err = 0;
|
||||
|
||||
err = check_rng_health(p);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
while (size >= 8) {
|
||||
*((u64 *)dat) = readq(p->result);
|
||||
@ -39,6 +166,39 @@ static int cavium_rng_read(struct hwrng *rng, void *dat, size_t max, bool wait)
|
||||
return max;
|
||||
}
|
||||
|
||||
static int cavium_map_pf_regs(struct cavium_rng *rng)
|
||||
{
|
||||
struct pci_dev *pdev;
|
||||
|
||||
/* Health status is not supported on 83xx, skip mapping PF CSRs */
|
||||
if (is_octeontx(rng->pdev)) {
|
||||
rng->pf_regbase = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
pdev = pci_get_device(PCI_VENDOR_ID_CAVIUM,
|
||||
PCI_DEVID_CAVIUM_RNG_PF, NULL);
|
||||
if (!pdev) {
|
||||
dev_err(&pdev->dev, "Cannot find RNG PF device\n");
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
rng->pf_regbase = ioremap(pci_resource_start(pdev, 0),
|
||||
pci_resource_len(pdev, 0));
|
||||
if (!rng->pf_regbase) {
|
||||
dev_err(&pdev->dev, "Failed to map PF CSR region\n");
|
||||
pci_dev_put(pdev);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
pci_dev_put(pdev);
|
||||
|
||||
/* Get co-processor clock rate */
|
||||
rng->clock_rate = rng_get_coprocessor_clkrate();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Map Cavium RNG to an HWRNG object */
|
||||
static int cavium_rng_probe_vf(struct pci_dev *pdev,
|
||||
const struct pci_device_id *id)
|
||||
@ -50,6 +210,8 @@ static int cavium_rng_probe_vf(struct pci_dev *pdev,
|
||||
if (!rng)
|
||||
return -ENOMEM;
|
||||
|
||||
rng->pdev = pdev;
|
||||
|
||||
/* Map the RNG result */
|
||||
rng->result = pcim_iomap(pdev, 0, 0);
|
||||
if (!rng->result) {
|
||||
@ -67,6 +229,11 @@ static int cavium_rng_probe_vf(struct pci_dev *pdev,
|
||||
|
||||
pci_set_drvdata(pdev, rng);
|
||||
|
||||
/* Health status is available only at PF, hence map PF registers. */
|
||||
ret = cavium_map_pf_regs(rng);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = devm_hwrng_register(&pdev->dev, &rng->ops);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "Error registering device as HWRNG.\n");
|
||||
@ -76,10 +243,18 @@ static int cavium_rng_probe_vf(struct pci_dev *pdev,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Remove the VF */
|
||||
static void cavium_rng_remove_vf(struct pci_dev *pdev)
|
||||
{
|
||||
struct cavium_rng *rng;
|
||||
|
||||
rng = pci_get_drvdata(pdev);
|
||||
iounmap(rng->pf_regbase);
|
||||
}
|
||||
|
||||
static const struct pci_device_id cavium_rng_vf_id_table[] = {
|
||||
{ PCI_DEVICE(PCI_VENDOR_ID_CAVIUM, 0xa033), 0, 0, 0},
|
||||
{0,},
|
||||
{ PCI_DEVICE(PCI_VENDOR_ID_CAVIUM, PCI_DEVID_CAVIUM_RNG_VF) },
|
||||
{ 0, }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(pci, cavium_rng_vf_id_table);
|
||||
|
||||
@ -87,8 +262,9 @@ static struct pci_driver cavium_rng_vf_driver = {
|
||||
.name = "cavium_rng_vf",
|
||||
.id_table = cavium_rng_vf_id_table,
|
||||
.probe = cavium_rng_probe_vf,
|
||||
.remove = cavium_rng_remove_vf,
|
||||
};
|
||||
module_pci_driver(cavium_rng_vf_driver);
|
||||
|
||||
MODULE_AUTHOR("Omer Khaliq <okhaliq@caviumnetworks.com>");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
|
@ -1,10 +1,7 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Hardware Random Number Generator support for Cavium Inc.
|
||||
* Thunder processor family.
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU General Public
|
||||
* License. See the file "COPYING" in the main directory of this archive
|
||||
* for more details.
|
||||
* Hardware Random Number Generator support.
|
||||
* Cavium Thunder, Marvell OcteonTx/Tx2 processor families.
|
||||
*
|
||||
* Copyright (C) 2016 Cavium, Inc.
|
||||
*/
|
||||
@ -91,4 +88,4 @@ static struct pci_driver cavium_rng_pf_driver = {
|
||||
|
||||
module_pci_driver(cavium_rng_pf_driver);
|
||||
MODULE_AUTHOR("Omer Khaliq <okhaliq@caviumnetworks.com>");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
|
@ -42,13 +42,11 @@ static int ixp4xx_rng_probe(struct platform_device *pdev)
|
||||
{
|
||||
void __iomem * rng_base;
|
||||
struct device *dev = &pdev->dev;
|
||||
struct resource *res;
|
||||
|
||||
if (!cpu_is_ixp46x()) /* includes IXP455 */
|
||||
return -ENOSYS;
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
rng_base = devm_ioremap_resource(dev, res);
|
||||
rng_base = devm_platform_ioremap_resource(pdev, 0);
|
||||
if (IS_ERR(rng_base))
|
||||
return PTR_ERR(rng_base);
|
||||
|
||||
|
@ -54,9 +54,10 @@ static int meson_rng_probe(struct platform_device *pdev)
|
||||
if (IS_ERR(data->base))
|
||||
return PTR_ERR(data->base);
|
||||
|
||||
data->core_clk = devm_clk_get(dev, "core");
|
||||
data->core_clk = devm_clk_get_optional(dev, "core");
|
||||
if (IS_ERR(data->core_clk))
|
||||
data->core_clk = NULL;
|
||||
return dev_err_probe(dev, PTR_ERR(data->core_clk),
|
||||
"Failed to get core clock\n");
|
||||
|
||||
if (data->core_clk) {
|
||||
ret = clk_prepare_enable(data->core_clk);
|
||||
|
@ -111,7 +111,7 @@ static ssize_t trng_counter_show(struct device *dev,
|
||||
#if IS_ENABLED(CONFIG_ARCH_RANDOM)
|
||||
u64 arch_counter = atomic64_read(&s390_arch_random_counter);
|
||||
|
||||
return snprintf(buf, PAGE_SIZE,
|
||||
return sysfs_emit(buf,
|
||||
"trng: %llu\n"
|
||||
"hwrng: %llu\n"
|
||||
"arch: %llu\n"
|
||||
@ -119,7 +119,7 @@ static ssize_t trng_counter_show(struct device *dev,
|
||||
dev_counter, hwrng_counter, arch_counter,
|
||||
dev_counter + hwrng_counter + arch_counter);
|
||||
#else
|
||||
return snprintf(buf, PAGE_SIZE,
|
||||
return sysfs_emit(buf,
|
||||
"trng: %llu\n"
|
||||
"hwrng: %llu\n"
|
||||
"total: %llu\n",
|
||||
|
@ -18,13 +18,20 @@ static DEFINE_IDA(rng_index_ida);
|
||||
struct virtrng_info {
|
||||
struct hwrng hwrng;
|
||||
struct virtqueue *vq;
|
||||
struct completion have_data;
|
||||
char name[25];
|
||||
unsigned int data_avail;
|
||||
int index;
|
||||
bool busy;
|
||||
bool hwrng_register_done;
|
||||
bool hwrng_removed;
|
||||
/* data transfer */
|
||||
struct completion have_data;
|
||||
unsigned int data_avail;
|
||||
unsigned int data_idx;
|
||||
/* minimal size returned by rng_buffer_size() */
|
||||
#if SMP_CACHE_BYTES < 32
|
||||
u8 data[32];
|
||||
#else
|
||||
u8 data[SMP_CACHE_BYTES];
|
||||
#endif
|
||||
};
|
||||
|
||||
static void random_recv_done(struct virtqueue *vq)
|
||||
@ -35,54 +42,88 @@ static void random_recv_done(struct virtqueue *vq)
|
||||
if (!virtqueue_get_buf(vi->vq, &vi->data_avail))
|
||||
return;
|
||||
|
||||
vi->data_idx = 0;
|
||||
|
||||
complete(&vi->have_data);
|
||||
}
|
||||
|
||||
/* The host will fill any buffer we give it with sweet, sweet randomness. */
|
||||
static void register_buffer(struct virtrng_info *vi, u8 *buf, size_t size)
|
||||
static void request_entropy(struct virtrng_info *vi)
|
||||
{
|
||||
struct scatterlist sg;
|
||||
|
||||
sg_init_one(&sg, buf, size);
|
||||
reinit_completion(&vi->have_data);
|
||||
vi->data_avail = 0;
|
||||
vi->data_idx = 0;
|
||||
|
||||
sg_init_one(&sg, vi->data, sizeof(vi->data));
|
||||
|
||||
/* There should always be room for one buffer. */
|
||||
virtqueue_add_inbuf(vi->vq, &sg, 1, buf, GFP_KERNEL);
|
||||
virtqueue_add_inbuf(vi->vq, &sg, 1, vi->data, GFP_KERNEL);
|
||||
|
||||
virtqueue_kick(vi->vq);
|
||||
}
|
||||
|
||||
static unsigned int copy_data(struct virtrng_info *vi, void *buf,
|
||||
unsigned int size)
|
||||
{
|
||||
size = min_t(unsigned int, size, vi->data_avail);
|
||||
memcpy(buf, vi->data + vi->data_idx, size);
|
||||
vi->data_idx += size;
|
||||
vi->data_avail -= size;
|
||||
if (vi->data_avail == 0)
|
||||
request_entropy(vi);
|
||||
return size;
|
||||
}
|
||||
|
||||
static int virtio_read(struct hwrng *rng, void *buf, size_t size, bool wait)
|
||||
{
|
||||
int ret;
|
||||
struct virtrng_info *vi = (struct virtrng_info *)rng->priv;
|
||||
unsigned int chunk;
|
||||
size_t read;
|
||||
|
||||
if (vi->hwrng_removed)
|
||||
return -ENODEV;
|
||||
|
||||
if (!vi->busy) {
|
||||
vi->busy = true;
|
||||
reinit_completion(&vi->have_data);
|
||||
register_buffer(vi, buf, size);
|
||||
read = 0;
|
||||
|
||||
/* copy available data */
|
||||
if (vi->data_avail) {
|
||||
chunk = copy_data(vi, buf, size);
|
||||
size -= chunk;
|
||||
read += chunk;
|
||||
}
|
||||
|
||||
if (!wait)
|
||||
return 0;
|
||||
return read;
|
||||
|
||||
ret = wait_for_completion_killable(&vi->have_data);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
/* We have already copied available entropy,
|
||||
* so either size is 0 or data_avail is 0
|
||||
*/
|
||||
while (size != 0) {
|
||||
/* data_avail is 0 but a request is pending */
|
||||
ret = wait_for_completion_killable(&vi->have_data);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
/* if vi->data_avail is 0, we have been interrupted
|
||||
* by a cleanup, but buffer stays in the queue
|
||||
*/
|
||||
if (vi->data_avail == 0)
|
||||
return read;
|
||||
|
||||
vi->busy = false;
|
||||
chunk = copy_data(vi, buf + read, size);
|
||||
size -= chunk;
|
||||
read += chunk;
|
||||
}
|
||||
|
||||
return vi->data_avail;
|
||||
return read;
|
||||
}
|
||||
|
||||
static void virtio_cleanup(struct hwrng *rng)
|
||||
{
|
||||
struct virtrng_info *vi = (struct virtrng_info *)rng->priv;
|
||||
|
||||
if (vi->busy)
|
||||
wait_for_completion(&vi->have_data);
|
||||
complete(&vi->have_data);
|
||||
}
|
||||
|
||||
static int probe_common(struct virtio_device *vdev)
|
||||
@ -118,6 +159,9 @@ static int probe_common(struct virtio_device *vdev)
|
||||
goto err_find;
|
||||
}
|
||||
|
||||
/* we always have a pending entropy request */
|
||||
request_entropy(vi);
|
||||
|
||||
return 0;
|
||||
|
||||
err_find:
|
||||
@ -133,11 +177,11 @@ static void remove_common(struct virtio_device *vdev)
|
||||
|
||||
vi->hwrng_removed = true;
|
||||
vi->data_avail = 0;
|
||||
vi->data_idx = 0;
|
||||
complete(&vi->have_data);
|
||||
vdev->config->reset(vdev);
|
||||
vi->busy = false;
|
||||
if (vi->hwrng_register_done)
|
||||
hwrng_unregister(&vi->hwrng);
|
||||
virtio_reset_device(vdev);
|
||||
vdev->config->del_vqs(vdev);
|
||||
ida_simple_remove(&rng_index_ida, vi->index);
|
||||
kfree(vi);
|
||||
|
@ -69,12 +69,21 @@ config IPMI_SI
|
||||
|
||||
config IPMI_SSIF
|
||||
tristate 'IPMI SMBus handler (SSIF)'
|
||||
select I2C
|
||||
depends on I2C
|
||||
help
|
||||
Provides a driver for a SMBus interface to a BMC, meaning that you
|
||||
have a driver that must be accessed over an I2C bus instead of a
|
||||
standard interface. This module requires I2C support.
|
||||
|
||||
config IPMI_IPMB
|
||||
tristate 'IPMI IPMB interface'
|
||||
depends on I2C && I2C_SLAVE
|
||||
help
|
||||
Provides a driver for a system running right on the IPMB bus.
|
||||
It supports normal system interface messages to a BMC on the IPMB
|
||||
bus, and it also supports direct messaging on the bus using
|
||||
IPMB direct messages. This module requires I2C support.
|
||||
|
||||
config IPMI_POWERNV
|
||||
depends on PPC_POWERNV
|
||||
tristate 'POWERNV (OPAL firmware) IPMI interface'
|
||||
|
@ -19,6 +19,7 @@ obj-$(CONFIG_IPMI_SI) += ipmi_si.o
|
||||
obj-$(CONFIG_IPMI_DMI_DECODE) += ipmi_dmi.o
|
||||
obj-$(CONFIG_IPMI_PLAT_DATA) += ipmi_plat_data.o
|
||||
obj-$(CONFIG_IPMI_SSIF) += ipmi_ssif.o
|
||||
obj-$(CONFIG_IPMI_IPMB) += ipmi_ipmb.o
|
||||
obj-$(CONFIG_IPMI_POWERNV) += ipmi_powernv.o
|
||||
obj-$(CONFIG_IPMI_WATCHDOG) += ipmi_watchdog.o
|
||||
obj-$(CONFIG_IPMI_POWEROFF) += ipmi_poweroff.o
|
||||
|
@ -8,13 +8,11 @@
|
||||
#include <linux/errno.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/mfd/syscon.h>
|
||||
#include <linux/miscdevice.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/poll.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/timer.h>
|
||||
|
||||
@ -59,8 +57,7 @@
|
||||
struct bt_bmc {
|
||||
struct device dev;
|
||||
struct miscdevice miscdev;
|
||||
struct regmap *map;
|
||||
int offset;
|
||||
void __iomem *base;
|
||||
int irq;
|
||||
wait_queue_head_t queue;
|
||||
struct timer_list poll_timer;
|
||||
@ -69,29 +66,14 @@ struct bt_bmc {
|
||||
|
||||
static atomic_t open_count = ATOMIC_INIT(0);
|
||||
|
||||
static const struct regmap_config bt_regmap_cfg = {
|
||||
.reg_bits = 32,
|
||||
.val_bits = 32,
|
||||
.reg_stride = 4,
|
||||
};
|
||||
|
||||
static u8 bt_inb(struct bt_bmc *bt_bmc, int reg)
|
||||
{
|
||||
uint32_t val = 0;
|
||||
int rc;
|
||||
|
||||
rc = regmap_read(bt_bmc->map, bt_bmc->offset + reg, &val);
|
||||
WARN(rc != 0, "regmap_read() failed: %d\n", rc);
|
||||
|
||||
return rc == 0 ? (u8) val : 0;
|
||||
return readb(bt_bmc->base + reg);
|
||||
}
|
||||
|
||||
static void bt_outb(struct bt_bmc *bt_bmc, u8 data, int reg)
|
||||
{
|
||||
int rc;
|
||||
|
||||
rc = regmap_write(bt_bmc->map, bt_bmc->offset + reg, data);
|
||||
WARN(rc != 0, "regmap_write() failed: %d\n", rc);
|
||||
writeb(data, bt_bmc->base + reg);
|
||||
}
|
||||
|
||||
static void clr_rd_ptr(struct bt_bmc *bt_bmc)
|
||||
@ -376,18 +358,15 @@ static irqreturn_t bt_bmc_irq(int irq, void *arg)
|
||||
{
|
||||
struct bt_bmc *bt_bmc = arg;
|
||||
u32 reg;
|
||||
int rc;
|
||||
|
||||
rc = regmap_read(bt_bmc->map, bt_bmc->offset + BT_CR2, ®);
|
||||
if (rc)
|
||||
return IRQ_NONE;
|
||||
reg = readl(bt_bmc->base + BT_CR2);
|
||||
|
||||
reg &= BT_CR2_IRQ_H2B | BT_CR2_IRQ_HBUSY;
|
||||
if (!reg)
|
||||
return IRQ_NONE;
|
||||
|
||||
/* ack pending IRQs */
|
||||
regmap_write(bt_bmc->map, bt_bmc->offset + BT_CR2, reg);
|
||||
writel(reg, bt_bmc->base + BT_CR2);
|
||||
|
||||
wake_up(&bt_bmc->queue);
|
||||
return IRQ_HANDLED;
|
||||
@ -398,6 +377,7 @@ static int bt_bmc_config_irq(struct bt_bmc *bt_bmc,
|
||||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
int rc;
|
||||
u32 reg;
|
||||
|
||||
bt_bmc->irq = platform_get_irq_optional(pdev, 0);
|
||||
if (bt_bmc->irq < 0)
|
||||
@ -417,11 +397,11 @@ static int bt_bmc_config_irq(struct bt_bmc *bt_bmc,
|
||||
* will be cleared (along with B2H) when we can write the next
|
||||
* message to the BT buffer
|
||||
*/
|
||||
rc = regmap_update_bits(bt_bmc->map, bt_bmc->offset + BT_CR1,
|
||||
(BT_CR1_IRQ_H2B | BT_CR1_IRQ_HBUSY),
|
||||
(BT_CR1_IRQ_H2B | BT_CR1_IRQ_HBUSY));
|
||||
reg = readl(bt_bmc->base + BT_CR1);
|
||||
reg |= BT_CR1_IRQ_H2B | BT_CR1_IRQ_HBUSY;
|
||||
writel(reg, bt_bmc->base + BT_CR1);
|
||||
|
||||
return rc;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int bt_bmc_probe(struct platform_device *pdev)
|
||||
@ -439,25 +419,9 @@ static int bt_bmc_probe(struct platform_device *pdev)
|
||||
|
||||
dev_set_drvdata(&pdev->dev, bt_bmc);
|
||||
|
||||
bt_bmc->map = syscon_node_to_regmap(pdev->dev.parent->of_node);
|
||||
if (IS_ERR(bt_bmc->map)) {
|
||||
void __iomem *base;
|
||||
|
||||
/*
|
||||
* Assume it's not the MFD-based devicetree description, in
|
||||
* which case generate a regmap ourselves
|
||||
*/
|
||||
base = devm_platform_ioremap_resource(pdev, 0);
|
||||
if (IS_ERR(base))
|
||||
return PTR_ERR(base);
|
||||
|
||||
bt_bmc->map = devm_regmap_init_mmio(dev, base, &bt_regmap_cfg);
|
||||
bt_bmc->offset = 0;
|
||||
} else {
|
||||
rc = of_property_read_u32(dev->of_node, "reg", &bt_bmc->offset);
|
||||
if (rc)
|
||||
return rc;
|
||||
}
|
||||
bt_bmc->base = devm_platform_ioremap_resource(pdev, 0);
|
||||
if (IS_ERR(bt_bmc->base))
|
||||
return PTR_ERR(bt_bmc->base);
|
||||
|
||||
mutex_init(&bt_bmc->mutex);
|
||||
init_waitqueue_head(&bt_bmc->queue);
|
||||
@ -483,12 +447,12 @@ static int bt_bmc_probe(struct platform_device *pdev)
|
||||
add_timer(&bt_bmc->poll_timer);
|
||||
}
|
||||
|
||||
regmap_write(bt_bmc->map, bt_bmc->offset + BT_CR0,
|
||||
(BT_IO_BASE << BT_CR0_IO_BASE) |
|
||||
writel((BT_IO_BASE << BT_CR0_IO_BASE) |
|
||||
(BT_IRQ << BT_CR0_IRQ) |
|
||||
BT_CR0_EN_CLR_SLV_RDP |
|
||||
BT_CR0_EN_CLR_SLV_WRP |
|
||||
BT_CR0_ENABLE_IBT);
|
||||
BT_CR0_ENABLE_IBT,
|
||||
bt_bmc->base + BT_CR0);
|
||||
|
||||
clr_b_busy(bt_bmc);
|
||||
|
||||
@ -508,6 +472,7 @@ static int bt_bmc_remove(struct platform_device *pdev)
|
||||
static const struct of_device_id bt_bmc_match[] = {
|
||||
{ .compatible = "aspeed,ast2400-ibt-bmc" },
|
||||
{ .compatible = "aspeed,ast2500-ibt-bmc" },
|
||||
{ .compatible = "aspeed,ast2600-ibt-bmc" },
|
||||
{ },
|
||||
};
|
||||
|
||||
|
@ -247,11 +247,13 @@ static int handle_recv(struct ipmi_file_private *priv,
|
||||
|
||||
if (msg->msg.data_len > 0) {
|
||||
if (rsp->msg.data_len < msg->msg.data_len) {
|
||||
rv2 = -EMSGSIZE;
|
||||
if (trunc)
|
||||
if (trunc) {
|
||||
rv2 = -EMSGSIZE;
|
||||
msg->msg.data_len = rsp->msg.data_len;
|
||||
else
|
||||
} else {
|
||||
rv = -EMSGSIZE;
|
||||
goto recv_putback_on_err;
|
||||
}
|
||||
}
|
||||
|
||||
if (copy_to_user(rsp->msg.data,
|
||||
|
@ -655,6 +655,11 @@ static int is_ipmb_bcast_addr(struct ipmi_addr *addr)
|
||||
return addr->addr_type == IPMI_IPMB_BROADCAST_ADDR_TYPE;
|
||||
}
|
||||
|
||||
static int is_ipmb_direct_addr(struct ipmi_addr *addr)
|
||||
{
|
||||
return addr->addr_type == IPMI_IPMB_DIRECT_ADDR_TYPE;
|
||||
}
|
||||
|
||||
static void free_recv_msg_list(struct list_head *q)
|
||||
{
|
||||
struct ipmi_recv_msg *msg, *msg2;
|
||||
@ -807,6 +812,17 @@ ipmi_addr_equal(struct ipmi_addr *addr1, struct ipmi_addr *addr2)
|
||||
&& (ipmb_addr1->lun == ipmb_addr2->lun));
|
||||
}
|
||||
|
||||
if (is_ipmb_direct_addr(addr1)) {
|
||||
struct ipmi_ipmb_direct_addr *daddr1
|
||||
= (struct ipmi_ipmb_direct_addr *) addr1;
|
||||
struct ipmi_ipmb_direct_addr *daddr2
|
||||
= (struct ipmi_ipmb_direct_addr *) addr2;
|
||||
|
||||
return daddr1->slave_addr == daddr2->slave_addr &&
|
||||
daddr1->rq_lun == daddr2->rq_lun &&
|
||||
daddr1->rs_lun == daddr2->rs_lun;
|
||||
}
|
||||
|
||||
if (is_lan_addr(addr1)) {
|
||||
struct ipmi_lan_addr *lan_addr1
|
||||
= (struct ipmi_lan_addr *) addr1;
|
||||
@ -845,6 +861,23 @@ int ipmi_validate_addr(struct ipmi_addr *addr, int len)
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (is_ipmb_direct_addr(addr)) {
|
||||
struct ipmi_ipmb_direct_addr *daddr = (void *) addr;
|
||||
|
||||
if (addr->channel != 0)
|
||||
return -EINVAL;
|
||||
if (len < sizeof(struct ipmi_ipmb_direct_addr))
|
||||
return -EINVAL;
|
||||
|
||||
if (daddr->slave_addr & 0x01)
|
||||
return -EINVAL;
|
||||
if (daddr->rq_lun >= 4)
|
||||
return -EINVAL;
|
||||
if (daddr->rs_lun >= 4)
|
||||
return -EINVAL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (is_lan_addr(addr)) {
|
||||
if (len < sizeof(struct ipmi_lan_addr))
|
||||
return -EINVAL;
|
||||
@ -864,6 +897,9 @@ unsigned int ipmi_addr_length(int addr_type)
|
||||
|| (addr_type == IPMI_IPMB_BROADCAST_ADDR_TYPE))
|
||||
return sizeof(struct ipmi_ipmb_addr);
|
||||
|
||||
if (addr_type == IPMI_IPMB_DIRECT_ADDR_TYPE)
|
||||
return sizeof(struct ipmi_ipmb_direct_addr);
|
||||
|
||||
if (addr_type == IPMI_LAN_ADDR_TYPE)
|
||||
return sizeof(struct ipmi_lan_addr);
|
||||
|
||||
@ -1712,7 +1748,7 @@ int ipmi_unregister_for_cmd(struct ipmi_user *user,
|
||||
}
|
||||
EXPORT_SYMBOL(ipmi_unregister_for_cmd);
|
||||
|
||||
static unsigned char
|
||||
unsigned char
|
||||
ipmb_checksum(unsigned char *data, int size)
|
||||
{
|
||||
unsigned char csum = 0;
|
||||
@ -1722,6 +1758,7 @@ ipmb_checksum(unsigned char *data, int size)
|
||||
|
||||
return -csum;
|
||||
}
|
||||
EXPORT_SYMBOL(ipmb_checksum);
|
||||
|
||||
static inline void format_ipmb_msg(struct ipmi_smi_msg *smi_msg,
|
||||
struct kernel_ipmi_msg *msg,
|
||||
@ -2053,6 +2090,58 @@ static int i_ipmi_req_ipmb(struct ipmi_smi *intf,
|
||||
return rv;
|
||||
}
|
||||
|
||||
static int i_ipmi_req_ipmb_direct(struct ipmi_smi *intf,
|
||||
struct ipmi_addr *addr,
|
||||
long msgid,
|
||||
struct kernel_ipmi_msg *msg,
|
||||
struct ipmi_smi_msg *smi_msg,
|
||||
struct ipmi_recv_msg *recv_msg,
|
||||
unsigned char source_lun)
|
||||
{
|
||||
struct ipmi_ipmb_direct_addr *daddr;
|
||||
bool is_cmd = !(recv_msg->msg.netfn & 0x1);
|
||||
|
||||
if (!(intf->handlers->flags & IPMI_SMI_CAN_HANDLE_IPMB_DIRECT))
|
||||
return -EAFNOSUPPORT;
|
||||
|
||||
/* Responses must have a completion code. */
|
||||
if (!is_cmd && msg->data_len < 1) {
|
||||
ipmi_inc_stat(intf, sent_invalid_commands);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if ((msg->data_len + 4) > IPMI_MAX_MSG_LENGTH) {
|
||||
ipmi_inc_stat(intf, sent_invalid_commands);
|
||||
return -EMSGSIZE;
|
||||
}
|
||||
|
||||
daddr = (struct ipmi_ipmb_direct_addr *) addr;
|
||||
if (daddr->rq_lun > 3 || daddr->rs_lun > 3) {
|
||||
ipmi_inc_stat(intf, sent_invalid_commands);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
smi_msg->type = IPMI_SMI_MSG_TYPE_IPMB_DIRECT;
|
||||
smi_msg->msgid = msgid;
|
||||
|
||||
if (is_cmd) {
|
||||
smi_msg->data[0] = msg->netfn << 2 | daddr->rs_lun;
|
||||
smi_msg->data[2] = recv_msg->msgid << 2 | daddr->rq_lun;
|
||||
} else {
|
||||
smi_msg->data[0] = msg->netfn << 2 | daddr->rq_lun;
|
||||
smi_msg->data[2] = recv_msg->msgid << 2 | daddr->rs_lun;
|
||||
}
|
||||
smi_msg->data[1] = daddr->slave_addr;
|
||||
smi_msg->data[3] = msg->cmd;
|
||||
|
||||
memcpy(smi_msg->data + 4, msg->data, msg->data_len);
|
||||
smi_msg->data_size = msg->data_len + 4;
|
||||
|
||||
smi_msg->user_data = recv_msg;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int i_ipmi_req_lan(struct ipmi_smi *intf,
|
||||
struct ipmi_addr *addr,
|
||||
long msgid,
|
||||
@ -2242,6 +2331,9 @@ static int i_ipmi_request(struct ipmi_user *user,
|
||||
rv = i_ipmi_req_ipmb(intf, addr, msgid, msg, smi_msg, recv_msg,
|
||||
source_address, source_lun,
|
||||
retries, retry_time_ms);
|
||||
} else if (is_ipmb_direct_addr(addr)) {
|
||||
rv = i_ipmi_req_ipmb_direct(intf, addr, msgid, msg, smi_msg,
|
||||
recv_msg, source_lun);
|
||||
} else if (is_lan_addr(addr)) {
|
||||
rv = i_ipmi_req_lan(intf, addr, msgid, msg, smi_msg, recv_msg,
|
||||
source_lun, retries, retry_time_ms);
|
||||
@ -2371,6 +2463,13 @@ static void bmc_device_id_handler(struct ipmi_smi *intf,
|
||||
return;
|
||||
}
|
||||
|
||||
if (msg->msg.data[0]) {
|
||||
dev_warn(intf->si_dev, "device id fetch failed: 0x%2.2x\n",
|
||||
msg->msg.data[0]);
|
||||
intf->bmc->dyn_id_set = 0;
|
||||
goto out;
|
||||
}
|
||||
|
||||
rv = ipmi_demangle_device_id(msg->msg.netfn, msg->msg.cmd,
|
||||
msg->msg.data, msg->msg.data_len, &intf->bmc->fetch_id);
|
||||
if (rv) {
|
||||
@ -2386,7 +2485,7 @@ static void bmc_device_id_handler(struct ipmi_smi *intf,
|
||||
smp_wmb();
|
||||
intf->bmc->dyn_id_set = 1;
|
||||
}
|
||||
|
||||
out:
|
||||
wake_up(&intf->waitq);
|
||||
}
|
||||
|
||||
@ -2619,7 +2718,7 @@ static ssize_t device_id_show(struct device *dev,
|
||||
if (rv)
|
||||
return rv;
|
||||
|
||||
return snprintf(buf, 10, "%u\n", id.device_id);
|
||||
return sysfs_emit(buf, "%u\n", id.device_id);
|
||||
}
|
||||
static DEVICE_ATTR_RO(device_id);
|
||||
|
||||
@ -2635,7 +2734,7 @@ static ssize_t provides_device_sdrs_show(struct device *dev,
|
||||
if (rv)
|
||||
return rv;
|
||||
|
||||
return snprintf(buf, 10, "%u\n", (id.device_revision & 0x80) >> 7);
|
||||
return sysfs_emit(buf, "%u\n", (id.device_revision & 0x80) >> 7);
|
||||
}
|
||||
static DEVICE_ATTR_RO(provides_device_sdrs);
|
||||
|
||||
@ -2650,7 +2749,7 @@ static ssize_t revision_show(struct device *dev, struct device_attribute *attr,
|
||||
if (rv)
|
||||
return rv;
|
||||
|
||||
return snprintf(buf, 20, "%u\n", id.device_revision & 0x0F);
|
||||
return sysfs_emit(buf, "%u\n", id.device_revision & 0x0F);
|
||||
}
|
||||
static DEVICE_ATTR_RO(revision);
|
||||
|
||||
@ -2666,7 +2765,7 @@ static ssize_t firmware_revision_show(struct device *dev,
|
||||
if (rv)
|
||||
return rv;
|
||||
|
||||
return snprintf(buf, 20, "%u.%x\n", id.firmware_revision_1,
|
||||
return sysfs_emit(buf, "%u.%x\n", id.firmware_revision_1,
|
||||
id.firmware_revision_2);
|
||||
}
|
||||
static DEVICE_ATTR_RO(firmware_revision);
|
||||
@ -2683,7 +2782,7 @@ static ssize_t ipmi_version_show(struct device *dev,
|
||||
if (rv)
|
||||
return rv;
|
||||
|
||||
return snprintf(buf, 20, "%u.%u\n",
|
||||
return sysfs_emit(buf, "%u.%u\n",
|
||||
ipmi_version_major(&id),
|
||||
ipmi_version_minor(&id));
|
||||
}
|
||||
@ -2701,7 +2800,7 @@ static ssize_t add_dev_support_show(struct device *dev,
|
||||
if (rv)
|
||||
return rv;
|
||||
|
||||
return snprintf(buf, 10, "0x%02x\n", id.additional_device_support);
|
||||
return sysfs_emit(buf, "0x%02x\n", id.additional_device_support);
|
||||
}
|
||||
static DEVICE_ATTR(additional_device_support, S_IRUGO, add_dev_support_show,
|
||||
NULL);
|
||||
@ -2718,7 +2817,7 @@ static ssize_t manufacturer_id_show(struct device *dev,
|
||||
if (rv)
|
||||
return rv;
|
||||
|
||||
return snprintf(buf, 20, "0x%6.6x\n", id.manufacturer_id);
|
||||
return sysfs_emit(buf, "0x%6.6x\n", id.manufacturer_id);
|
||||
}
|
||||
static DEVICE_ATTR_RO(manufacturer_id);
|
||||
|
||||
@ -2734,7 +2833,7 @@ static ssize_t product_id_show(struct device *dev,
|
||||
if (rv)
|
||||
return rv;
|
||||
|
||||
return snprintf(buf, 10, "0x%4.4x\n", id.product_id);
|
||||
return sysfs_emit(buf, "0x%4.4x\n", id.product_id);
|
||||
}
|
||||
static DEVICE_ATTR_RO(product_id);
|
||||
|
||||
@ -2750,7 +2849,7 @@ static ssize_t aux_firmware_rev_show(struct device *dev,
|
||||
if (rv)
|
||||
return rv;
|
||||
|
||||
return snprintf(buf, 21, "0x%02x 0x%02x 0x%02x 0x%02x\n",
|
||||
return sysfs_emit(buf, "0x%02x 0x%02x 0x%02x 0x%02x\n",
|
||||
id.aux_firmware_revision[3],
|
||||
id.aux_firmware_revision[2],
|
||||
id.aux_firmware_revision[1],
|
||||
@ -2772,7 +2871,7 @@ static ssize_t guid_show(struct device *dev, struct device_attribute *attr,
|
||||
if (!guid_set)
|
||||
return -ENOENT;
|
||||
|
||||
return snprintf(buf, UUID_STRING_LEN + 1 + 1, "%pUl\n", &guid);
|
||||
return sysfs_emit(buf, "%pUl\n", &guid);
|
||||
}
|
||||
static DEVICE_ATTR_RO(guid);
|
||||
|
||||
@ -3796,6 +3895,125 @@ static int handle_ipmb_get_msg_cmd(struct ipmi_smi *intf,
|
||||
return rv;
|
||||
}
|
||||
|
||||
static int handle_ipmb_direct_rcv_cmd(struct ipmi_smi *intf,
|
||||
struct ipmi_smi_msg *msg)
|
||||
{
|
||||
struct cmd_rcvr *rcvr;
|
||||
int rv = 0;
|
||||
struct ipmi_user *user = NULL;
|
||||
struct ipmi_ipmb_direct_addr *daddr;
|
||||
struct ipmi_recv_msg *recv_msg;
|
||||
unsigned char netfn = msg->rsp[0] >> 2;
|
||||
unsigned char cmd = msg->rsp[3];
|
||||
|
||||
rcu_read_lock();
|
||||
/* We always use channel 0 for direct messages. */
|
||||
rcvr = find_cmd_rcvr(intf, netfn, cmd, 0);
|
||||
if (rcvr) {
|
||||
user = rcvr->user;
|
||||
kref_get(&user->refcount);
|
||||
} else
|
||||
user = NULL;
|
||||
rcu_read_unlock();
|
||||
|
||||
if (user == NULL) {
|
||||
/* We didn't find a user, deliver an error response. */
|
||||
ipmi_inc_stat(intf, unhandled_commands);
|
||||
|
||||
msg->data[0] = (netfn + 1) << 2;
|
||||
msg->data[0] |= msg->rsp[2] & 0x3; /* rqLUN */
|
||||
msg->data[1] = msg->rsp[1]; /* Addr */
|
||||
msg->data[2] = msg->rsp[2] & ~0x3; /* rqSeq */
|
||||
msg->data[2] |= msg->rsp[0] & 0x3; /* rsLUN */
|
||||
msg->data[3] = cmd;
|
||||
msg->data[4] = IPMI_INVALID_CMD_COMPLETION_CODE;
|
||||
msg->data_size = 5;
|
||||
|
||||
rcu_read_lock();
|
||||
if (!intf->in_shutdown) {
|
||||
smi_send(intf, intf->handlers, msg, 0);
|
||||
/*
|
||||
* We used the message, so return the value
|
||||
* that causes it to not be freed or
|
||||
* queued.
|
||||
*/
|
||||
rv = -1;
|
||||
}
|
||||
rcu_read_unlock();
|
||||
} else {
|
||||
recv_msg = ipmi_alloc_recv_msg();
|
||||
if (!recv_msg) {
|
||||
/*
|
||||
* We couldn't allocate memory for the
|
||||
* message, so requeue it for handling
|
||||
* later.
|
||||
*/
|
||||
rv = 1;
|
||||
kref_put(&user->refcount, free_user);
|
||||
} else {
|
||||
/* Extract the source address from the data. */
|
||||
daddr = (struct ipmi_ipmb_direct_addr *)&recv_msg->addr;
|
||||
daddr->addr_type = IPMI_IPMB_DIRECT_ADDR_TYPE;
|
||||
daddr->channel = 0;
|
||||
daddr->slave_addr = msg->rsp[1];
|
||||
daddr->rs_lun = msg->rsp[0] & 3;
|
||||
daddr->rq_lun = msg->rsp[2] & 3;
|
||||
|
||||
/*
|
||||
* Extract the rest of the message information
|
||||
* from the IPMB header.
|
||||
*/
|
||||
recv_msg->user = user;
|
||||
recv_msg->recv_type = IPMI_CMD_RECV_TYPE;
|
||||
recv_msg->msgid = (msg->rsp[2] >> 2);
|
||||
recv_msg->msg.netfn = msg->rsp[0] >> 2;
|
||||
recv_msg->msg.cmd = msg->rsp[3];
|
||||
recv_msg->msg.data = recv_msg->msg_data;
|
||||
|
||||
recv_msg->msg.data_len = msg->rsp_size - 4;
|
||||
memcpy(recv_msg->msg_data, msg->rsp + 4,
|
||||
msg->rsp_size - 4);
|
||||
if (deliver_response(intf, recv_msg))
|
||||
ipmi_inc_stat(intf, unhandled_commands);
|
||||
else
|
||||
ipmi_inc_stat(intf, handled_commands);
|
||||
}
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
static int handle_ipmb_direct_rcv_rsp(struct ipmi_smi *intf,
|
||||
struct ipmi_smi_msg *msg)
|
||||
{
|
||||
struct ipmi_recv_msg *recv_msg;
|
||||
struct ipmi_ipmb_direct_addr *daddr;
|
||||
|
||||
recv_msg = (struct ipmi_recv_msg *) msg->user_data;
|
||||
if (recv_msg == NULL) {
|
||||
dev_warn(intf->si_dev,
|
||||
"IPMI message received with no owner. This could be because of a malformed message, or because of a hardware error. Contact your hardware vendor for assistance.\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
recv_msg->recv_type = IPMI_RESPONSE_RECV_TYPE;
|
||||
recv_msg->msgid = msg->msgid;
|
||||
daddr = (struct ipmi_ipmb_direct_addr *) &recv_msg->addr;
|
||||
daddr->addr_type = IPMI_IPMB_DIRECT_ADDR_TYPE;
|
||||
daddr->channel = 0;
|
||||
daddr->slave_addr = msg->rsp[1];
|
||||
daddr->rq_lun = msg->rsp[0] & 3;
|
||||
daddr->rs_lun = msg->rsp[2] & 3;
|
||||
recv_msg->msg.netfn = msg->rsp[0] >> 2;
|
||||
recv_msg->msg.cmd = msg->rsp[3];
|
||||
memcpy(recv_msg->msg_data, &msg->rsp[4], msg->rsp_size - 4);
|
||||
recv_msg->msg.data = recv_msg->msg_data;
|
||||
recv_msg->msg.data_len = msg->rsp_size - 4;
|
||||
deliver_local_response(intf, recv_msg);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int handle_lan_get_msg_rsp(struct ipmi_smi *intf,
|
||||
struct ipmi_smi_msg *msg)
|
||||
{
|
||||
@ -4221,18 +4439,51 @@ static int handle_bmc_rsp(struct ipmi_smi *intf,
|
||||
static int handle_one_recv_msg(struct ipmi_smi *intf,
|
||||
struct ipmi_smi_msg *msg)
|
||||
{
|
||||
int requeue;
|
||||
int requeue = 0;
|
||||
int chan;
|
||||
unsigned char cc;
|
||||
bool is_cmd = !((msg->rsp[0] >> 2) & 1);
|
||||
|
||||
pr_debug("Recv: %*ph\n", msg->rsp_size, msg->rsp);
|
||||
|
||||
if ((msg->data_size >= 2)
|
||||
if (msg->rsp_size < 2) {
|
||||
/* Message is too small to be correct. */
|
||||
dev_warn(intf->si_dev,
|
||||
"BMC returned too small a message for netfn %x cmd %x, got %d bytes\n",
|
||||
(msg->data[0] >> 2) | 1, msg->data[1], msg->rsp_size);
|
||||
|
||||
return_unspecified:
|
||||
/* Generate an error response for the message. */
|
||||
msg->rsp[0] = msg->data[0] | (1 << 2);
|
||||
msg->rsp[1] = msg->data[1];
|
||||
msg->rsp[2] = IPMI_ERR_UNSPECIFIED;
|
||||
msg->rsp_size = 3;
|
||||
} else if (msg->type == IPMI_SMI_MSG_TYPE_IPMB_DIRECT) {
|
||||
/* commands must have at least 4 bytes, responses 5. */
|
||||
if (is_cmd && (msg->rsp_size < 4)) {
|
||||
ipmi_inc_stat(intf, invalid_commands);
|
||||
goto out;
|
||||
}
|
||||
if (!is_cmd && (msg->rsp_size < 5)) {
|
||||
ipmi_inc_stat(intf, invalid_ipmb_responses);
|
||||
/* Construct a valid error response. */
|
||||
msg->rsp[0] = msg->data[0] & 0xfc; /* NetFN */
|
||||
msg->rsp[0] |= (1 << 2); /* Make it a response */
|
||||
msg->rsp[0] |= msg->data[2] & 3; /* rqLUN */
|
||||
msg->rsp[1] = msg->data[1]; /* Addr */
|
||||
msg->rsp[2] = msg->data[2] & 0xfc; /* rqSeq */
|
||||
msg->rsp[2] |= msg->data[0] & 0x3; /* rsLUN */
|
||||
msg->rsp[3] = msg->data[3]; /* Cmd */
|
||||
msg->rsp[4] = IPMI_ERR_UNSPECIFIED;
|
||||
msg->rsp_size = 5;
|
||||
}
|
||||
} else if ((msg->data_size >= 2)
|
||||
&& (msg->data[0] == (IPMI_NETFN_APP_REQUEST << 2))
|
||||
&& (msg->data[1] == IPMI_SEND_MSG_CMD)
|
||||
&& (msg->user_data == NULL)) {
|
||||
|
||||
if (intf->in_shutdown)
|
||||
goto free_msg;
|
||||
goto out;
|
||||
|
||||
/*
|
||||
* This is the local response to a command send, start
|
||||
@ -4267,21 +4518,6 @@ static int handle_one_recv_msg(struct ipmi_smi *intf,
|
||||
} else
|
||||
/* The message was sent, start the timer. */
|
||||
intf_start_seq_timer(intf, msg->msgid);
|
||||
free_msg:
|
||||
requeue = 0;
|
||||
goto out;
|
||||
|
||||
} else if (msg->rsp_size < 2) {
|
||||
/* Message is too small to be correct. */
|
||||
dev_warn(intf->si_dev,
|
||||
"BMC returned too small a message for netfn %x cmd %x, got %d bytes\n",
|
||||
(msg->data[0] >> 2) | 1, msg->data[1], msg->rsp_size);
|
||||
|
||||
/* Generate an error response for the message. */
|
||||
msg->rsp[0] = msg->data[0] | (1 << 2);
|
||||
msg->rsp[1] = msg->data[1];
|
||||
msg->rsp[2] = IPMI_ERR_UNSPECIFIED;
|
||||
msg->rsp_size = 3;
|
||||
} else if (((msg->rsp[0] >> 2) != ((msg->data[0] >> 2) | 1))
|
||||
|| (msg->rsp[1] != msg->data[1])) {
|
||||
/*
|
||||
@ -4293,39 +4529,46 @@ static int handle_one_recv_msg(struct ipmi_smi *intf,
|
||||
(msg->data[0] >> 2) | 1, msg->data[1],
|
||||
msg->rsp[0] >> 2, msg->rsp[1]);
|
||||
|
||||
/* Generate an error response for the message. */
|
||||
msg->rsp[0] = msg->data[0] | (1 << 2);
|
||||
msg->rsp[1] = msg->data[1];
|
||||
msg->rsp[2] = IPMI_ERR_UNSPECIFIED;
|
||||
msg->rsp_size = 3;
|
||||
goto return_unspecified;
|
||||
}
|
||||
|
||||
if ((msg->rsp[0] == ((IPMI_NETFN_APP_REQUEST|1) << 2))
|
||||
&& (msg->rsp[1] == IPMI_SEND_MSG_CMD)
|
||||
&& (msg->user_data != NULL)) {
|
||||
if (msg->type == IPMI_SMI_MSG_TYPE_IPMB_DIRECT) {
|
||||
if ((msg->data[0] >> 2) & 1) {
|
||||
/* It's a response to a sent response. */
|
||||
chan = 0;
|
||||
cc = msg->rsp[4];
|
||||
goto process_response_response;
|
||||
}
|
||||
if (is_cmd)
|
||||
requeue = handle_ipmb_direct_rcv_cmd(intf, msg);
|
||||
else
|
||||
requeue = handle_ipmb_direct_rcv_rsp(intf, msg);
|
||||
} else if ((msg->rsp[0] == ((IPMI_NETFN_APP_REQUEST|1) << 2))
|
||||
&& (msg->rsp[1] == IPMI_SEND_MSG_CMD)
|
||||
&& (msg->user_data != NULL)) {
|
||||
/*
|
||||
* It's a response to a response we sent. For this we
|
||||
* deliver a send message response to the user.
|
||||
*/
|
||||
struct ipmi_recv_msg *recv_msg = msg->user_data;
|
||||
|
||||
requeue = 0;
|
||||
if (msg->rsp_size < 2)
|
||||
/* Message is too small to be correct. */
|
||||
goto out;
|
||||
struct ipmi_recv_msg *recv_msg;
|
||||
|
||||
chan = msg->data[2] & 0x0f;
|
||||
if (chan >= IPMI_MAX_CHANNELS)
|
||||
/* Invalid channel number */
|
||||
goto out;
|
||||
cc = msg->rsp[2];
|
||||
|
||||
process_response_response:
|
||||
recv_msg = msg->user_data;
|
||||
|
||||
requeue = 0;
|
||||
if (!recv_msg)
|
||||
goto out;
|
||||
|
||||
recv_msg->recv_type = IPMI_RESPONSE_RESPONSE_TYPE;
|
||||
recv_msg->msg.data = recv_msg->msg_data;
|
||||
recv_msg->msg_data[0] = cc;
|
||||
recv_msg->msg.data_len = 1;
|
||||
recv_msg->msg_data[0] = msg->rsp[2];
|
||||
deliver_local_response(intf, recv_msg);
|
||||
} else if ((msg->rsp[0] == ((IPMI_NETFN_APP_REQUEST|1) << 2))
|
||||
&& (msg->rsp[1] == IPMI_GET_MSG_CMD)) {
|
||||
@ -4803,6 +5046,7 @@ struct ipmi_smi_msg *ipmi_alloc_smi_msg(void)
|
||||
if (rv) {
|
||||
rv->done = free_smi_msg;
|
||||
rv->user_data = NULL;
|
||||
rv->type = IPMI_SMI_MSG_TYPE_NORMAL;
|
||||
atomic_inc(&smi_msg_inuse_count);
|
||||
}
|
||||
return rv;
|
||||
|
@ -1603,7 +1603,7 @@ static ssize_t name##_show(struct device *dev, \
|
||||
{ \
|
||||
struct smi_info *smi_info = dev_get_drvdata(dev); \
|
||||
\
|
||||
return snprintf(buf, 10, "%u\n", smi_get_stat(smi_info, name)); \
|
||||
return sysfs_emit(buf, "%u\n", smi_get_stat(smi_info, name)); \
|
||||
} \
|
||||
static DEVICE_ATTR_RO(name)
|
||||
|
||||
@ -1613,7 +1613,7 @@ static ssize_t type_show(struct device *dev,
|
||||
{
|
||||
struct smi_info *smi_info = dev_get_drvdata(dev);
|
||||
|
||||
return snprintf(buf, 10, "%s\n", si_to_str[smi_info->io.si_type]);
|
||||
return sysfs_emit(buf, "%s\n", si_to_str[smi_info->io.si_type]);
|
||||
}
|
||||
static DEVICE_ATTR_RO(type);
|
||||
|
||||
@ -1624,7 +1624,7 @@ static ssize_t interrupts_enabled_show(struct device *dev,
|
||||
struct smi_info *smi_info = dev_get_drvdata(dev);
|
||||
int enabled = smi_info->io.irq && !smi_info->interrupt_disabled;
|
||||
|
||||
return snprintf(buf, 10, "%d\n", enabled);
|
||||
return sysfs_emit(buf, "%d\n", enabled);
|
||||
}
|
||||
static DEVICE_ATTR_RO(interrupts_enabled);
|
||||
|
||||
@ -1646,7 +1646,7 @@ static ssize_t params_show(struct device *dev,
|
||||
{
|
||||
struct smi_info *smi_info = dev_get_drvdata(dev);
|
||||
|
||||
return snprintf(buf, 200,
|
||||
return sysfs_emit(buf,
|
||||
"%s,%s,0x%lx,rsp=%d,rsi=%d,rsh=%d,irq=%d,ipmb=%d\n",
|
||||
si_to_str[smi_info->io.si_type],
|
||||
addr_space_to_str[smi_info->io.addr_space],
|
||||
|
@ -1190,7 +1190,7 @@ static ssize_t ipmi_##name##_show(struct device *dev, \
|
||||
{ \
|
||||
struct ssif_info *ssif_info = dev_get_drvdata(dev); \
|
||||
\
|
||||
return snprintf(buf, 10, "%u\n", ssif_get_stat(ssif_info, name));\
|
||||
return sysfs_emit(buf, "%u\n", ssif_get_stat(ssif_info, name));\
|
||||
} \
|
||||
static DEVICE_ATTR(name, S_IRUGO, ipmi_##name##_show, NULL)
|
||||
|
||||
@ -1198,7 +1198,7 @@ static ssize_t ipmi_type_show(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
return snprintf(buf, 10, "ssif\n");
|
||||
return sysfs_emit(buf, "ssif\n");
|
||||
}
|
||||
static DEVICE_ATTR(type, S_IRUGO, ipmi_type_show, NULL);
|
||||
|
||||
|
@ -495,6 +495,10 @@ static ssize_t read_iter_zero(struct kiocb *iocb, struct iov_iter *iter)
|
||||
written += n;
|
||||
if (signal_pending(current))
|
||||
return written ? written : -ERESTARTSYS;
|
||||
if (!need_resched())
|
||||
continue;
|
||||
if (iocb->ki_flags & IOCB_NOWAIT)
|
||||
return written ? written : -EAGAIN;
|
||||
cond_resched();
|
||||
}
|
||||
return written;
|
||||
@ -696,11 +700,11 @@ static const struct memdev {
|
||||
#ifdef CONFIG_DEVMEM
|
||||
[DEVMEM_MINOR] = { "mem", 0, &mem_fops, FMODE_UNSIGNED_OFFSET },
|
||||
#endif
|
||||
[3] = { "null", 0666, &null_fops, 0 },
|
||||
[3] = { "null", 0666, &null_fops, FMODE_NOWAIT },
|
||||
#ifdef CONFIG_DEVPORT
|
||||
[4] = { "port", 0, &port_fops, 0 },
|
||||
#endif
|
||||
[5] = { "zero", 0666, &zero_fops, 0 },
|
||||
[5] = { "zero", 0666, &zero_fops, FMODE_NOWAIT },
|
||||
[7] = { "full", 0666, &full_fops, 0 },
|
||||
[8] = { "random", 0666, &random_fops, 0 },
|
||||
[9] = { "urandom", 0666, &urandom_fops, 0 },
|
||||
|
@ -116,8 +116,9 @@ struct cm4000_dev {
|
||||
wait_queue_head_t atrq; /* wait for ATR valid */
|
||||
wait_queue_head_t readq; /* used by write to wake blk.read */
|
||||
|
||||
/* warning: do not move this fields.
|
||||
/* warning: do not move this struct group.
|
||||
* initialising to zero depends on it - see ZERO_DEV below. */
|
||||
struct_group(init,
|
||||
unsigned char atr_csum;
|
||||
unsigned char atr_len_retry;
|
||||
unsigned short atr_len;
|
||||
@ -140,12 +141,10 @@ struct cm4000_dev {
|
||||
|
||||
struct timer_list timer; /* used to keep monitor running */
|
||||
int monitor_running;
|
||||
);
|
||||
};
|
||||
|
||||
#define ZERO_DEV(dev) \
|
||||
memset(&dev->atr_csum,0, \
|
||||
sizeof(struct cm4000_dev) - \
|
||||
offsetof(struct cm4000_dev, atr_csum))
|
||||
#define ZERO_DEV(dev) memset(&((dev)->init), 0, sizeof((dev)->init))
|
||||
|
||||
static struct pcmcia_device *dev_table[CM4000_MAX_DEV];
|
||||
static struct class *cmm_class;
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -76,7 +76,7 @@ config TCG_TIS_SPI_CR50
|
||||
|
||||
config TCG_TIS_SYNQUACER
|
||||
tristate "TPM Interface Specification 1.2 Interface / TPM 2.0 FIFO Interface (MMIO - SynQuacer)"
|
||||
depends on ARCH_SYNQUACER
|
||||
depends on ARCH_SYNQUACER || COMPILE_TEST
|
||||
select TCG_TIS_CORE
|
||||
help
|
||||
If you have a TPM security chip that is compliant with the
|
||||
|
@ -61,9 +61,7 @@ enum tis_defaults {
|
||||
};
|
||||
|
||||
/*
|
||||
* clear_interruption clear the pending interrupt.
|
||||
* @param: tpm_dev, the tpm device device.
|
||||
* @return: the interrupt status value.
|
||||
* clear the pending interrupt.
|
||||
*/
|
||||
static u8 clear_interruption(struct st33zp24_dev *tpm_dev)
|
||||
{
|
||||
@ -72,12 +70,10 @@ static u8 clear_interruption(struct st33zp24_dev *tpm_dev)
|
||||
tpm_dev->ops->recv(tpm_dev->phy_id, TPM_INT_STATUS, &interrupt, 1);
|
||||
tpm_dev->ops->send(tpm_dev->phy_id, TPM_INT_STATUS, &interrupt, 1);
|
||||
return interrupt;
|
||||
} /* clear_interruption() */
|
||||
}
|
||||
|
||||
/*
|
||||
* st33zp24_cancel, cancel the current command execution or
|
||||
* set STS to COMMAND READY.
|
||||
* @param: chip, the tpm_chip description as specified in driver/char/tpm/tpm.h
|
||||
* cancel the current command execution or set STS to COMMAND READY.
|
||||
*/
|
||||
static void st33zp24_cancel(struct tpm_chip *chip)
|
||||
{
|
||||
@ -86,12 +82,10 @@ static void st33zp24_cancel(struct tpm_chip *chip)
|
||||
|
||||
data = TPM_STS_COMMAND_READY;
|
||||
tpm_dev->ops->send(tpm_dev->phy_id, TPM_STS, &data, 1);
|
||||
} /* st33zp24_cancel() */
|
||||
}
|
||||
|
||||
/*
|
||||
* st33zp24_status return the TPM_STS register
|
||||
* @param: chip, the tpm chip description
|
||||
* @return: the TPM_STS register value.
|
||||
* return the TPM_STS register
|
||||
*/
|
||||
static u8 st33zp24_status(struct tpm_chip *chip)
|
||||
{
|
||||
@ -100,12 +94,10 @@ static u8 st33zp24_status(struct tpm_chip *chip)
|
||||
|
||||
tpm_dev->ops->recv(tpm_dev->phy_id, TPM_STS, &data, 1);
|
||||
return data;
|
||||
} /* st33zp24_status() */
|
||||
}
|
||||
|
||||
/*
|
||||
* check_locality if the locality is active
|
||||
* @param: chip, the tpm chip description
|
||||
* @return: true if LOCALITY0 is active, otherwise false
|
||||
* if the locality is active
|
||||
*/
|
||||
static bool check_locality(struct tpm_chip *chip)
|
||||
{
|
||||
@ -120,13 +112,8 @@ static bool check_locality(struct tpm_chip *chip)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
} /* check_locality() */
|
||||
}
|
||||
|
||||
/*
|
||||
* request_locality request the TPM locality
|
||||
* @param: chip, the chip description
|
||||
* @return: the active locality or negative value.
|
||||
*/
|
||||
static int request_locality(struct tpm_chip *chip)
|
||||
{
|
||||
struct st33zp24_dev *tpm_dev = dev_get_drvdata(&chip->dev);
|
||||
@ -153,12 +140,8 @@ static int request_locality(struct tpm_chip *chip)
|
||||
|
||||
/* could not get locality */
|
||||
return -EACCES;
|
||||
} /* request_locality() */
|
||||
}
|
||||
|
||||
/*
|
||||
* release_locality release the active locality
|
||||
* @param: chip, the tpm chip description.
|
||||
*/
|
||||
static void release_locality(struct tpm_chip *chip)
|
||||
{
|
||||
struct st33zp24_dev *tpm_dev = dev_get_drvdata(&chip->dev);
|
||||
@ -171,8 +154,6 @@ static void release_locality(struct tpm_chip *chip)
|
||||
|
||||
/*
|
||||
* get_burstcount return the burstcount value
|
||||
* @param: chip, the chip description
|
||||
* return: the burstcount or negative value.
|
||||
*/
|
||||
static int get_burstcount(struct tpm_chip *chip)
|
||||
{
|
||||
@ -200,18 +181,8 @@ static int get_burstcount(struct tpm_chip *chip)
|
||||
msleep(TPM_TIMEOUT);
|
||||
} while (time_before(jiffies, stop));
|
||||
return -EBUSY;
|
||||
} /* get_burstcount() */
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* wait_for_tpm_stat_cond
|
||||
* @param: chip, chip description
|
||||
* @param: mask, expected mask value
|
||||
* @param: check_cancel, does the command expected to be canceled ?
|
||||
* @param: canceled, did we received a cancel request ?
|
||||
* @return: true if status == mask or if the command is canceled.
|
||||
* false in other cases.
|
||||
*/
|
||||
static bool wait_for_tpm_stat_cond(struct tpm_chip *chip, u8 mask,
|
||||
bool check_cancel, bool *canceled)
|
||||
{
|
||||
@ -228,13 +199,7 @@ static bool wait_for_tpm_stat_cond(struct tpm_chip *chip, u8 mask,
|
||||
}
|
||||
|
||||
/*
|
||||
* wait_for_stat wait for a TPM_STS value
|
||||
* @param: chip, the tpm chip description
|
||||
* @param: mask, the value mask to wait
|
||||
* @param: timeout, the timeout
|
||||
* @param: queue, the wait queue.
|
||||
* @param: check_cancel, does the command can be cancelled ?
|
||||
* @return: the tpm status, 0 if success, -ETIME if timeout is reached.
|
||||
* wait for a TPM_STS value
|
||||
*/
|
||||
static int wait_for_stat(struct tpm_chip *chip, u8 mask, unsigned long timeout,
|
||||
wait_queue_head_t *queue, bool check_cancel)
|
||||
@ -292,15 +257,8 @@ static int wait_for_stat(struct tpm_chip *chip, u8 mask, unsigned long timeout,
|
||||
}
|
||||
|
||||
return -ETIME;
|
||||
} /* wait_for_stat() */
|
||||
}
|
||||
|
||||
/*
|
||||
* recv_data receive data
|
||||
* @param: chip, the tpm chip description
|
||||
* @param: buf, the buffer where the data are received
|
||||
* @param: count, the number of data to receive
|
||||
* @return: the number of bytes read from TPM FIFO.
|
||||
*/
|
||||
static int recv_data(struct tpm_chip *chip, u8 *buf, size_t count)
|
||||
{
|
||||
struct st33zp24_dev *tpm_dev = dev_get_drvdata(&chip->dev);
|
||||
@ -325,12 +283,6 @@ static int recv_data(struct tpm_chip *chip, u8 *buf, size_t count)
|
||||
return size;
|
||||
}
|
||||
|
||||
/*
|
||||
* tpm_ioserirq_handler the serirq irq handler
|
||||
* @param: irq, the tpm chip description
|
||||
* @param: dev_id, the description of the chip
|
||||
* @return: the status of the handler.
|
||||
*/
|
||||
static irqreturn_t tpm_ioserirq_handler(int irq, void *dev_id)
|
||||
{
|
||||
struct tpm_chip *chip = dev_id;
|
||||
@ -341,16 +293,10 @@ static irqreturn_t tpm_ioserirq_handler(int irq, void *dev_id)
|
||||
disable_irq_nosync(tpm_dev->irq);
|
||||
|
||||
return IRQ_HANDLED;
|
||||
} /* tpm_ioserirq_handler() */
|
||||
}
|
||||
|
||||
/*
|
||||
* st33zp24_send send TPM commands through the I2C bus.
|
||||
*
|
||||
* @param: chip, the tpm_chip description as specified in driver/char/tpm/tpm.h
|
||||
* @param: buf, the buffer to send.
|
||||
* @param: count, the number of bytes to send.
|
||||
* @return: In case of success the number of bytes sent.
|
||||
* In other case, a < 0 value describing the issue.
|
||||
* send TPM commands through the I2C bus.
|
||||
*/
|
||||
static int st33zp24_send(struct tpm_chip *chip, unsigned char *buf,
|
||||
size_t len)
|
||||
@ -431,14 +377,6 @@ static int st33zp24_send(struct tpm_chip *chip, unsigned char *buf,
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* st33zp24_recv received TPM response through TPM phy.
|
||||
* @param: chip, the tpm_chip description as specified in driver/char/tpm/tpm.h.
|
||||
* @param: buf, the buffer to store datas.
|
||||
* @param: count, the number of bytes to send.
|
||||
* @return: In case of success the number of bytes received.
|
||||
* In other case, a < 0 value describing the issue.
|
||||
*/
|
||||
static int st33zp24_recv(struct tpm_chip *chip, unsigned char *buf,
|
||||
size_t count)
|
||||
{
|
||||
@ -478,12 +416,6 @@ static int st33zp24_recv(struct tpm_chip *chip, unsigned char *buf,
|
||||
return size;
|
||||
}
|
||||
|
||||
/*
|
||||
* st33zp24_req_canceled
|
||||
* @param: chip, the tpm_chip description as specified in driver/char/tpm/tpm.h.
|
||||
* @param: status, the TPM status.
|
||||
* @return: Does TPM ready to compute a new command ? true.
|
||||
*/
|
||||
static bool st33zp24_req_canceled(struct tpm_chip *chip, u8 status)
|
||||
{
|
||||
return (status == TPM_STS_COMMAND_READY);
|
||||
@ -501,11 +433,7 @@ static const struct tpm_class_ops st33zp24_tpm = {
|
||||
};
|
||||
|
||||
/*
|
||||
* st33zp24_probe initialize the TPM device
|
||||
* @param: client, the i2c_client description (TPM I2C description).
|
||||
* @param: id, the i2c_device_id struct.
|
||||
* @return: 0 in case of success.
|
||||
* -1 in other case.
|
||||
* initialize the TPM device
|
||||
*/
|
||||
int st33zp24_probe(void *phy_id, const struct st33zp24_phy_ops *ops,
|
||||
struct device *dev, int irq, int io_lpcpd)
|
||||
@ -583,11 +511,6 @@ int st33zp24_probe(void *phy_id, const struct st33zp24_phy_ops *ops,
|
||||
}
|
||||
EXPORT_SYMBOL(st33zp24_probe);
|
||||
|
||||
/*
|
||||
* st33zp24_remove remove the TPM device
|
||||
* @param: tpm_data, the tpm phy.
|
||||
* @return: 0 in case of success.
|
||||
*/
|
||||
int st33zp24_remove(struct tpm_chip *chip)
|
||||
{
|
||||
tpm_chip_unregister(chip);
|
||||
@ -596,12 +519,6 @@ int st33zp24_remove(struct tpm_chip *chip)
|
||||
EXPORT_SYMBOL(st33zp24_remove);
|
||||
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
/*
|
||||
* st33zp24_pm_suspend suspend the TPM device
|
||||
* @param: tpm_data, the tpm phy.
|
||||
* @param: mesg, the power management message.
|
||||
* @return: 0 in case of success.
|
||||
*/
|
||||
int st33zp24_pm_suspend(struct device *dev)
|
||||
{
|
||||
struct tpm_chip *chip = dev_get_drvdata(dev);
|
||||
@ -615,14 +532,9 @@ int st33zp24_pm_suspend(struct device *dev)
|
||||
ret = tpm_pm_suspend(dev);
|
||||
|
||||
return ret;
|
||||
} /* st33zp24_pm_suspend() */
|
||||
}
|
||||
EXPORT_SYMBOL(st33zp24_pm_suspend);
|
||||
|
||||
/*
|
||||
* st33zp24_pm_resume resume the TPM device
|
||||
* @param: tpm_data, the tpm phy.
|
||||
* @return: 0 in case of success.
|
||||
*/
|
||||
int st33zp24_pm_resume(struct device *dev)
|
||||
{
|
||||
struct tpm_chip *chip = dev_get_drvdata(dev);
|
||||
@ -640,7 +552,7 @@ int st33zp24_pm_resume(struct device *dev)
|
||||
tpm1_do_selftest(chip);
|
||||
}
|
||||
return ret;
|
||||
} /* st33zp24_pm_resume() */
|
||||
}
|
||||
EXPORT_SYMBOL(st33zp24_pm_resume);
|
||||
#endif
|
||||
|
||||
|
@ -274,14 +274,6 @@ static void tpm_dev_release(struct device *dev)
|
||||
kfree(chip);
|
||||
}
|
||||
|
||||
static void tpm_devs_release(struct device *dev)
|
||||
{
|
||||
struct tpm_chip *chip = container_of(dev, struct tpm_chip, devs);
|
||||
|
||||
/* release the master device reference */
|
||||
put_device(&chip->dev);
|
||||
}
|
||||
|
||||
/**
|
||||
* tpm_class_shutdown() - prepare the TPM device for loss of power.
|
||||
* @dev: device to which the chip is associated.
|
||||
@ -344,7 +336,6 @@ struct tpm_chip *tpm_chip_alloc(struct device *pdev,
|
||||
chip->dev_num = rc;
|
||||
|
||||
device_initialize(&chip->dev);
|
||||
device_initialize(&chip->devs);
|
||||
|
||||
chip->dev.class = tpm_class;
|
||||
chip->dev.class->shutdown_pre = tpm_class_shutdown;
|
||||
@ -352,29 +343,12 @@ struct tpm_chip *tpm_chip_alloc(struct device *pdev,
|
||||
chip->dev.parent = pdev;
|
||||
chip->dev.groups = chip->groups;
|
||||
|
||||
chip->devs.parent = pdev;
|
||||
chip->devs.class = tpmrm_class;
|
||||
chip->devs.release = tpm_devs_release;
|
||||
/* get extra reference on main device to hold on
|
||||
* behalf of devs. This holds the chip structure
|
||||
* while cdevs is in use. The corresponding put
|
||||
* is in the tpm_devs_release (TPM2 only)
|
||||
*/
|
||||
if (chip->flags & TPM_CHIP_FLAG_TPM2)
|
||||
get_device(&chip->dev);
|
||||
|
||||
if (chip->dev_num == 0)
|
||||
chip->dev.devt = MKDEV(MISC_MAJOR, TPM_MINOR);
|
||||
else
|
||||
chip->dev.devt = MKDEV(MAJOR(tpm_devt), chip->dev_num);
|
||||
|
||||
chip->devs.devt =
|
||||
MKDEV(MAJOR(tpm_devt), chip->dev_num + TPM_NUM_DEVICES);
|
||||
|
||||
rc = dev_set_name(&chip->dev, "tpm%d", chip->dev_num);
|
||||
if (rc)
|
||||
goto out;
|
||||
rc = dev_set_name(&chip->devs, "tpmrm%d", chip->dev_num);
|
||||
if (rc)
|
||||
goto out;
|
||||
|
||||
@ -382,9 +356,7 @@ struct tpm_chip *tpm_chip_alloc(struct device *pdev,
|
||||
chip->flags |= TPM_CHIP_FLAG_VIRTUAL;
|
||||
|
||||
cdev_init(&chip->cdev, &tpm_fops);
|
||||
cdev_init(&chip->cdevs, &tpmrm_fops);
|
||||
chip->cdev.owner = THIS_MODULE;
|
||||
chip->cdevs.owner = THIS_MODULE;
|
||||
|
||||
rc = tpm2_init_space(&chip->work_space, TPM2_SPACE_BUFFER_SIZE);
|
||||
if (rc) {
|
||||
@ -396,7 +368,6 @@ struct tpm_chip *tpm_chip_alloc(struct device *pdev,
|
||||
return chip;
|
||||
|
||||
out:
|
||||
put_device(&chip->devs);
|
||||
put_device(&chip->dev);
|
||||
return ERR_PTR(rc);
|
||||
}
|
||||
@ -444,15 +415,10 @@ static int tpm_add_char_device(struct tpm_chip *chip)
|
||||
return rc;
|
||||
}
|
||||
|
||||
if (chip->flags & TPM_CHIP_FLAG_TPM2) {
|
||||
rc = cdev_device_add(&chip->cdevs, &chip->devs);
|
||||
if (rc) {
|
||||
dev_err(&chip->devs,
|
||||
"unable to cdev_device_add() %s, major %d, minor %d, err=%d\n",
|
||||
dev_name(&chip->devs), MAJOR(chip->devs.devt),
|
||||
MINOR(chip->devs.devt), rc);
|
||||
return rc;
|
||||
}
|
||||
if (chip->flags & TPM_CHIP_FLAG_TPM2 && !tpm_is_firmware_upgrade(chip)) {
|
||||
rc = tpm_devs_add(chip);
|
||||
if (rc)
|
||||
goto err_del_cdev;
|
||||
}
|
||||
|
||||
/* Make the chip available. */
|
||||
@ -460,6 +426,10 @@ static int tpm_add_char_device(struct tpm_chip *chip)
|
||||
idr_replace(&dev_nums_idr, chip, chip->dev_num);
|
||||
mutex_unlock(&idr_lock);
|
||||
|
||||
return 0;
|
||||
|
||||
err_del_cdev:
|
||||
cdev_device_del(&chip->cdev, &chip->dev);
|
||||
return rc;
|
||||
}
|
||||
|
||||
@ -496,7 +466,8 @@ static void tpm_del_legacy_sysfs(struct tpm_chip *chip)
|
||||
{
|
||||
struct attribute **i;
|
||||
|
||||
if (chip->flags & (TPM_CHIP_FLAG_TPM2 | TPM_CHIP_FLAG_VIRTUAL))
|
||||
if (chip->flags & (TPM_CHIP_FLAG_TPM2 | TPM_CHIP_FLAG_VIRTUAL) ||
|
||||
tpm_is_firmware_upgrade(chip))
|
||||
return;
|
||||
|
||||
sysfs_remove_link(&chip->dev.parent->kobj, "ppi");
|
||||
@ -514,7 +485,8 @@ static int tpm_add_legacy_sysfs(struct tpm_chip *chip)
|
||||
struct attribute **i;
|
||||
int rc;
|
||||
|
||||
if (chip->flags & (TPM_CHIP_FLAG_TPM2 | TPM_CHIP_FLAG_VIRTUAL))
|
||||
if (chip->flags & (TPM_CHIP_FLAG_TPM2 | TPM_CHIP_FLAG_VIRTUAL) ||
|
||||
tpm_is_firmware_upgrade(chip))
|
||||
return 0;
|
||||
|
||||
rc = compat_only_sysfs_link_entry_to_kobj(
|
||||
@ -544,7 +516,7 @@ static int tpm_hwrng_read(struct hwrng *rng, void *data, size_t max, bool wait)
|
||||
|
||||
static int tpm_add_hwrng(struct tpm_chip *chip)
|
||||
{
|
||||
if (!IS_ENABLED(CONFIG_HW_RANDOM_TPM))
|
||||
if (!IS_ENABLED(CONFIG_HW_RANDOM_TPM) || tpm_is_firmware_upgrade(chip))
|
||||
return 0;
|
||||
|
||||
snprintf(chip->hwrng_name, sizeof(chip->hwrng_name),
|
||||
@ -558,6 +530,9 @@ static int tpm_get_pcr_allocation(struct tpm_chip *chip)
|
||||
{
|
||||
int rc;
|
||||
|
||||
if (tpm_is_firmware_upgrade(chip))
|
||||
return 0;
|
||||
|
||||
rc = (chip->flags & TPM_CHIP_FLAG_TPM2) ?
|
||||
tpm2_get_pcr_allocation(chip) :
|
||||
tpm1_get_pcr_allocation(chip);
|
||||
@ -620,7 +595,7 @@ int tpm_chip_register(struct tpm_chip *chip)
|
||||
return 0;
|
||||
|
||||
out_hwrng:
|
||||
if (IS_ENABLED(CONFIG_HW_RANDOM_TPM))
|
||||
if (IS_ENABLED(CONFIG_HW_RANDOM_TPM) && !tpm_is_firmware_upgrade(chip))
|
||||
hwrng_unregister(&chip->hwrng);
|
||||
out_ppi:
|
||||
tpm_bios_log_teardown(chip);
|
||||
@ -645,11 +620,11 @@ EXPORT_SYMBOL_GPL(tpm_chip_register);
|
||||
void tpm_chip_unregister(struct tpm_chip *chip)
|
||||
{
|
||||
tpm_del_legacy_sysfs(chip);
|
||||
if (IS_ENABLED(CONFIG_HW_RANDOM_TPM))
|
||||
if (IS_ENABLED(CONFIG_HW_RANDOM_TPM) && !tpm_is_firmware_upgrade(chip))
|
||||
hwrng_unregister(&chip->hwrng);
|
||||
tpm_bios_log_teardown(chip);
|
||||
if (chip->flags & TPM_CHIP_FLAG_TPM2)
|
||||
cdev_device_del(&chip->cdevs, &chip->devs);
|
||||
if (chip->flags & TPM_CHIP_FLAG_TPM2 && !tpm_is_firmware_upgrade(chip))
|
||||
tpm_devs_remove(chip);
|
||||
tpm_del_char_device(chip);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(tpm_chip_unregister);
|
||||
|
@ -69,7 +69,13 @@ static void tpm_dev_async_work(struct work_struct *work)
|
||||
ret = tpm_dev_transmit(priv->chip, priv->space, priv->data_buffer,
|
||||
sizeof(priv->data_buffer));
|
||||
tpm_put_ops(priv->chip);
|
||||
if (ret > 0) {
|
||||
|
||||
/*
|
||||
* If ret is > 0 then tpm_dev_transmit returned the size of the
|
||||
* response. If ret is < 0 then tpm_dev_transmit failed and
|
||||
* returned an error code.
|
||||
*/
|
||||
if (ret != 0) {
|
||||
priv->response_length = ret;
|
||||
mod_timer(&priv->user_read_timer, jiffies + (120 * HZ));
|
||||
}
|
||||
|
@ -480,6 +480,9 @@ void tpm_sysfs_add_device(struct tpm_chip *chip)
|
||||
|
||||
WARN_ON(chip->groups_cnt != 0);
|
||||
|
||||
if (tpm_is_firmware_upgrade(chip))
|
||||
return;
|
||||
|
||||
if (chip->flags & TPM_CHIP_FLAG_TPM2)
|
||||
chip->groups[chip->groups_cnt++] = &tpm2_dev_group;
|
||||
else
|
||||
|
@ -234,6 +234,8 @@ int tpm2_prepare_space(struct tpm_chip *chip, struct tpm_space *space, u8 *cmd,
|
||||
size_t cmdsiz);
|
||||
int tpm2_commit_space(struct tpm_chip *chip, struct tpm_space *space, void *buf,
|
||||
size_t *bufsiz);
|
||||
int tpm_devs_add(struct tpm_chip *chip);
|
||||
void tpm_devs_remove(struct tpm_chip *chip);
|
||||
|
||||
void tpm_bios_log_setup(struct tpm_chip *chip);
|
||||
void tpm_bios_log_teardown(struct tpm_chip *chip);
|
||||
|
@ -745,6 +745,12 @@ int tpm2_auto_startup(struct tpm_chip *chip)
|
||||
rc = tpm2_get_cc_attrs_tbl(chip);
|
||||
|
||||
out:
|
||||
if (rc == TPM2_RC_UPGRADE) {
|
||||
dev_info(&chip->dev, "TPM in field upgrade mode, requires firmware upgrade\n");
|
||||
chip->flags |= TPM_CHIP_FLAG_FIRMWARE_UPGRADE;
|
||||
rc = 0;
|
||||
}
|
||||
|
||||
if (rc > 0)
|
||||
rc = -ENODEV;
|
||||
return rc;
|
||||
|
@ -58,12 +58,12 @@ int tpm2_init_space(struct tpm_space *space, unsigned int buf_size)
|
||||
|
||||
void tpm2_del_space(struct tpm_chip *chip, struct tpm_space *space)
|
||||
{
|
||||
mutex_lock(&chip->tpm_mutex);
|
||||
if (!tpm_chip_start(chip)) {
|
||||
|
||||
if (tpm_try_get_ops(chip) == 0) {
|
||||
tpm2_flush_sessions(chip, space);
|
||||
tpm_chip_stop(chip);
|
||||
tpm_put_ops(chip);
|
||||
}
|
||||
mutex_unlock(&chip->tpm_mutex);
|
||||
|
||||
kfree(space->context_buf);
|
||||
kfree(space->session_buf);
|
||||
}
|
||||
@ -574,3 +574,68 @@ int tpm2_commit_space(struct tpm_chip *chip, struct tpm_space *space,
|
||||
dev_err(&chip->dev, "%s: error %d\n", __func__, rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
* Put the reference to the main device.
|
||||
*/
|
||||
static void tpm_devs_release(struct device *dev)
|
||||
{
|
||||
struct tpm_chip *chip = container_of(dev, struct tpm_chip, devs);
|
||||
|
||||
/* release the master device reference */
|
||||
put_device(&chip->dev);
|
||||
}
|
||||
|
||||
/*
|
||||
* Remove the device file for exposed TPM spaces and release the device
|
||||
* reference. This may also release the reference to the master device.
|
||||
*/
|
||||
void tpm_devs_remove(struct tpm_chip *chip)
|
||||
{
|
||||
cdev_device_del(&chip->cdevs, &chip->devs);
|
||||
put_device(&chip->devs);
|
||||
}
|
||||
|
||||
/*
|
||||
* Add a device file to expose TPM spaces. Also take a reference to the
|
||||
* main device.
|
||||
*/
|
||||
int tpm_devs_add(struct tpm_chip *chip)
|
||||
{
|
||||
int rc;
|
||||
|
||||
device_initialize(&chip->devs);
|
||||
chip->devs.parent = chip->dev.parent;
|
||||
chip->devs.class = tpmrm_class;
|
||||
|
||||
/*
|
||||
* Get extra reference on main device to hold on behalf of devs.
|
||||
* This holds the chip structure while cdevs is in use. The
|
||||
* corresponding put is in the tpm_devs_release.
|
||||
*/
|
||||
get_device(&chip->dev);
|
||||
chip->devs.release = tpm_devs_release;
|
||||
chip->devs.devt = MKDEV(MAJOR(tpm_devt), chip->dev_num + TPM_NUM_DEVICES);
|
||||
cdev_init(&chip->cdevs, &tpmrm_fops);
|
||||
chip->cdevs.owner = THIS_MODULE;
|
||||
|
||||
rc = dev_set_name(&chip->devs, "tpmrm%d", chip->dev_num);
|
||||
if (rc)
|
||||
goto err_put_devs;
|
||||
|
||||
rc = cdev_device_add(&chip->cdevs, &chip->devs);
|
||||
if (rc) {
|
||||
dev_err(&chip->devs,
|
||||
"unable to cdev_device_add() %s, major %d, minor %d, err=%d\n",
|
||||
dev_name(&chip->devs), MAJOR(chip->devs.devt),
|
||||
MINOR(chip->devs.devt), rc);
|
||||
goto err_put_devs;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
err_put_devs:
|
||||
put_device(&chip->devs);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
@ -628,6 +628,19 @@ static bool tpm_cr50_i2c_req_canceled(struct tpm_chip *chip, u8 status)
|
||||
return status == TPM_STS_COMMAND_READY;
|
||||
}
|
||||
|
||||
static bool tpm_cr50_i2c_is_firmware_power_managed(struct device *dev)
|
||||
{
|
||||
u8 val;
|
||||
int ret;
|
||||
|
||||
/* This flag should default true when the device property is not present */
|
||||
ret = device_property_read_u8(dev, "firmware-power-managed", &val);
|
||||
if (ret)
|
||||
return true;
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
static const struct tpm_class_ops cr50_i2c = {
|
||||
.flags = TPM_OPS_AUTO_STARTUP,
|
||||
.status = &tpm_cr50_i2c_tis_status,
|
||||
@ -686,7 +699,8 @@ static int tpm_cr50_i2c_probe(struct i2c_client *client)
|
||||
|
||||
/* cr50 is a TPM 2.0 chip */
|
||||
chip->flags |= TPM_CHIP_FLAG_TPM2;
|
||||
chip->flags |= TPM_CHIP_FLAG_FIRMWARE_POWER_MANAGED;
|
||||
if (tpm_cr50_i2c_is_firmware_power_managed(dev))
|
||||
chip->flags |= TPM_CHIP_FLAG_FIRMWARE_POWER_MANAGED;
|
||||
|
||||
/* Default timeouts */
|
||||
chip->timeout_a = msecs_to_jiffies(TIS_SHORT_TIMEOUT);
|
||||
|
@ -36,6 +36,9 @@
|
||||
#define TPM_CR50_FW_VER(l) (0x0f90 | ((l) << 12))
|
||||
#define TPM_CR50_MAX_FW_VER_LEN 64
|
||||
|
||||
/* Default quality for hwrng. */
|
||||
#define TPM_CR50_DEFAULT_RNG_QUALITY 700
|
||||
|
||||
struct cr50_spi_phy {
|
||||
struct tpm_tis_spi_phy spi_phy;
|
||||
|
||||
@ -182,6 +185,19 @@ static int cr50_spi_flow_control(struct tpm_tis_spi_phy *phy,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool tpm_cr50_spi_is_firmware_power_managed(struct device *dev)
|
||||
{
|
||||
u8 val;
|
||||
int ret;
|
||||
|
||||
/* This flag should default true when the device property is not present */
|
||||
ret = device_property_read_u8(dev, "firmware-power-managed", &val);
|
||||
if (ret)
|
||||
return true;
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
static int tpm_tis_spi_cr50_transfer(struct tpm_tis_data *data, u32 addr, u16 len,
|
||||
u8 *in, const u8 *out)
|
||||
{
|
||||
@ -264,6 +280,7 @@ int cr50_spi_probe(struct spi_device *spi)
|
||||
phy = &cr50_phy->spi_phy;
|
||||
phy->flow_control = cr50_spi_flow_control;
|
||||
phy->wake_after = jiffies;
|
||||
phy->priv.rng_quality = TPM_CR50_DEFAULT_RNG_QUALITY;
|
||||
init_completion(&phy->ready);
|
||||
|
||||
cr50_phy->access_delay = CR50_NOIRQ_ACCESS_DELAY;
|
||||
@ -305,7 +322,8 @@ int cr50_spi_probe(struct spi_device *spi)
|
||||
cr50_print_fw_version(&phy->priv);
|
||||
|
||||
chip = dev_get_drvdata(&spi->dev);
|
||||
chip->flags |= TPM_CHIP_FLAG_FIRMWARE_POWER_MANAGED;
|
||||
if (tpm_cr50_spi_is_firmware_power_managed(&spi->dev))
|
||||
chip->flags |= TPM_CHIP_FLAG_FIRMWARE_POWER_MANAGED;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -28,6 +28,7 @@
|
||||
#include "../tty/hvc/hvc_console.h"
|
||||
|
||||
#define is_rproc_enabled IS_ENABLED(CONFIG_REMOTEPROC)
|
||||
#define VIRTCONS_MAX_PORTS 0x8000
|
||||
|
||||
/*
|
||||
* This is a global struct for storing common data for all the devices
|
||||
@ -1956,8 +1957,15 @@ static void virtcons_remove(struct virtio_device *vdev)
|
||||
list_del(&portdev->list);
|
||||
spin_unlock_irq(&pdrvdata_lock);
|
||||
|
||||
/* Device is going away, exit any polling for buffers */
|
||||
virtio_break_device(vdev);
|
||||
if (use_multiport(portdev))
|
||||
flush_work(&portdev->control_work);
|
||||
else
|
||||
flush_work(&portdev->config_work);
|
||||
|
||||
/* Disable interrupts for vqs */
|
||||
vdev->config->reset(vdev);
|
||||
virtio_reset_device(vdev);
|
||||
/* Finish up work that's lined up */
|
||||
if (use_multiport(portdev))
|
||||
cancel_work_sync(&portdev->control_work);
|
||||
@ -2036,6 +2044,14 @@ static int virtcons_probe(struct virtio_device *vdev)
|
||||
virtio_cread_feature(vdev, VIRTIO_CONSOLE_F_MULTIPORT,
|
||||
struct virtio_console_config, max_nr_ports,
|
||||
&portdev->max_nr_ports) == 0) {
|
||||
if (portdev->max_nr_ports == 0 ||
|
||||
portdev->max_nr_ports > VIRTCONS_MAX_PORTS) {
|
||||
dev_err(&vdev->dev,
|
||||
"Invalidate max_nr_ports %d",
|
||||
portdev->max_nr_ports);
|
||||
err = -EINVAL;
|
||||
goto free;
|
||||
}
|
||||
multiport = true;
|
||||
}
|
||||
|
||||
@ -2139,7 +2155,7 @@ static int virtcons_freeze(struct virtio_device *vdev)
|
||||
|
||||
portdev = vdev->priv;
|
||||
|
||||
vdev->config->reset(vdev);
|
||||
virtio_reset_device(vdev);
|
||||
|
||||
if (use_multiport(portdev))
|
||||
virtqueue_disable_cb(portdev->c_ivq);
|
||||
|
@ -87,13 +87,8 @@ struct xilly_channel {
|
||||
};
|
||||
|
||||
struct xilly_endpoint {
|
||||
/*
|
||||
* One of pdev and dev is always NULL, and the other is a valid
|
||||
* pointer, depending on the type of device
|
||||
*/
|
||||
struct pci_dev *pdev;
|
||||
struct device *dev;
|
||||
struct xilly_endpoint_hardware *ephw;
|
||||
struct module *owner;
|
||||
|
||||
int dma_using_dac; /* =1 if 64-bit DMA is used, =0 otherwise. */
|
||||
__iomem void *registers;
|
||||
@ -113,25 +108,8 @@ struct xilly_endpoint {
|
||||
unsigned int msg_buf_size;
|
||||
};
|
||||
|
||||
struct xilly_endpoint_hardware {
|
||||
struct module *owner;
|
||||
void (*hw_sync_sgl_for_cpu)(struct xilly_endpoint *,
|
||||
dma_addr_t,
|
||||
size_t,
|
||||
int);
|
||||
void (*hw_sync_sgl_for_device)(struct xilly_endpoint *,
|
||||
dma_addr_t,
|
||||
size_t,
|
||||
int);
|
||||
int (*map_single)(struct xilly_endpoint *,
|
||||
void *,
|
||||
size_t,
|
||||
int,
|
||||
dma_addr_t *);
|
||||
};
|
||||
|
||||
struct xilly_mapping {
|
||||
void *device;
|
||||
struct device *device;
|
||||
dma_addr_t dma_addr;
|
||||
size_t size;
|
||||
int direction;
|
||||
@ -139,10 +117,7 @@ struct xilly_mapping {
|
||||
|
||||
irqreturn_t xillybus_isr(int irq, void *data);
|
||||
|
||||
struct xilly_endpoint *xillybus_init_endpoint(struct pci_dev *pdev,
|
||||
struct device *dev,
|
||||
struct xilly_endpoint_hardware
|
||||
*ephw);
|
||||
struct xilly_endpoint *xillybus_init_endpoint(struct device *dev);
|
||||
|
||||
int xillybus_endpoint_discovery(struct xilly_endpoint *endpoint);
|
||||
|
||||
|
@ -122,10 +122,8 @@ irqreturn_t xillybus_isr(int irq, void *data)
|
||||
buf = ep->msgbuf_addr;
|
||||
buf_size = ep->msg_buf_size/sizeof(u32);
|
||||
|
||||
ep->ephw->hw_sync_sgl_for_cpu(ep,
|
||||
ep->msgbuf_dma_addr,
|
||||
ep->msg_buf_size,
|
||||
DMA_FROM_DEVICE);
|
||||
dma_sync_single_for_cpu(ep->dev, ep->msgbuf_dma_addr,
|
||||
ep->msg_buf_size, DMA_FROM_DEVICE);
|
||||
|
||||
for (i = 0; i < buf_size; i += 2) {
|
||||
if (((buf[i+1] >> 28) & 0xf) != ep->msg_counter) {
|
||||
@ -140,11 +138,10 @@ irqreturn_t xillybus_isr(int irq, void *data)
|
||||
dev_err(ep->dev,
|
||||
"Lost sync with interrupt messages. Stopping.\n");
|
||||
} else {
|
||||
ep->ephw->hw_sync_sgl_for_device(
|
||||
ep,
|
||||
ep->msgbuf_dma_addr,
|
||||
ep->msg_buf_size,
|
||||
DMA_FROM_DEVICE);
|
||||
dma_sync_single_for_device(ep->dev,
|
||||
ep->msgbuf_dma_addr,
|
||||
ep->msg_buf_size,
|
||||
DMA_FROM_DEVICE);
|
||||
|
||||
iowrite32(0x01, /* Message NACK */
|
||||
ep->registers + fpga_msg_ctrl_reg);
|
||||
@ -275,10 +272,8 @@ irqreturn_t xillybus_isr(int irq, void *data)
|
||||
}
|
||||
}
|
||||
|
||||
ep->ephw->hw_sync_sgl_for_device(ep,
|
||||
ep->msgbuf_dma_addr,
|
||||
ep->msg_buf_size,
|
||||
DMA_FROM_DEVICE);
|
||||
dma_sync_single_for_device(ep->dev, ep->msgbuf_dma_addr,
|
||||
ep->msg_buf_size, DMA_FROM_DEVICE);
|
||||
|
||||
ep->msg_counter = (ep->msg_counter + 1) & 0xf;
|
||||
ep->failed_messages = 0;
|
||||
@ -304,6 +299,47 @@ struct xilly_alloc_state {
|
||||
u32 regdirection;
|
||||
};
|
||||
|
||||
static void xilly_unmap(void *ptr)
|
||||
{
|
||||
struct xilly_mapping *data = ptr;
|
||||
|
||||
dma_unmap_single(data->device, data->dma_addr,
|
||||
data->size, data->direction);
|
||||
|
||||
kfree(ptr);
|
||||
}
|
||||
|
||||
static int xilly_map_single(struct xilly_endpoint *ep,
|
||||
void *ptr,
|
||||
size_t size,
|
||||
int direction,
|
||||
dma_addr_t *ret_dma_handle
|
||||
)
|
||||
{
|
||||
dma_addr_t addr;
|
||||
struct xilly_mapping *this;
|
||||
|
||||
this = kzalloc(sizeof(*this), GFP_KERNEL);
|
||||
if (!this)
|
||||
return -ENOMEM;
|
||||
|
||||
addr = dma_map_single(ep->dev, ptr, size, direction);
|
||||
|
||||
if (dma_mapping_error(ep->dev, addr)) {
|
||||
kfree(this);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
this->device = ep->dev;
|
||||
this->dma_addr = addr;
|
||||
this->size = size;
|
||||
this->direction = direction;
|
||||
|
||||
*ret_dma_handle = addr;
|
||||
|
||||
return devm_add_action_or_reset(ep->dev, xilly_unmap, this);
|
||||
}
|
||||
|
||||
static int xilly_get_dma_buffers(struct xilly_endpoint *ep,
|
||||
struct xilly_alloc_state *s,
|
||||
struct xilly_buffer **buffers,
|
||||
@ -355,9 +391,9 @@ static int xilly_get_dma_buffers(struct xilly_endpoint *ep,
|
||||
s->left_of_salami = allocsize;
|
||||
}
|
||||
|
||||
rc = ep->ephw->map_single(ep, s->salami,
|
||||
bytebufsize, s->direction,
|
||||
&dma_addr);
|
||||
rc = xilly_map_single(ep, s->salami,
|
||||
bytebufsize, s->direction,
|
||||
&dma_addr);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
@ -620,11 +656,10 @@ static int xilly_obtain_idt(struct xilly_endpoint *endpoint)
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
endpoint->ephw->hw_sync_sgl_for_cpu(
|
||||
channel->endpoint,
|
||||
channel->wr_buffers[0]->dma_addr,
|
||||
channel->wr_buf_size,
|
||||
DMA_FROM_DEVICE);
|
||||
dma_sync_single_for_cpu(channel->endpoint->dev,
|
||||
channel->wr_buffers[0]->dma_addr,
|
||||
channel->wr_buf_size,
|
||||
DMA_FROM_DEVICE);
|
||||
|
||||
if (channel->wr_buffers[0]->end_offset != endpoint->idtlen) {
|
||||
dev_err(endpoint->dev,
|
||||
@ -735,11 +770,10 @@ static ssize_t xillybus_read(struct file *filp, char __user *userbuf,
|
||||
if (!empty) { /* Go on, now without the spinlock */
|
||||
|
||||
if (bufpos == 0) /* Position zero means it's virgin */
|
||||
channel->endpoint->ephw->hw_sync_sgl_for_cpu(
|
||||
channel->endpoint,
|
||||
channel->wr_buffers[bufidx]->dma_addr,
|
||||
channel->wr_buf_size,
|
||||
DMA_FROM_DEVICE);
|
||||
dma_sync_single_for_cpu(channel->endpoint->dev,
|
||||
channel->wr_buffers[bufidx]->dma_addr,
|
||||
channel->wr_buf_size,
|
||||
DMA_FROM_DEVICE);
|
||||
|
||||
if (copy_to_user(
|
||||
userbuf,
|
||||
@ -751,11 +785,10 @@ static ssize_t xillybus_read(struct file *filp, char __user *userbuf,
|
||||
bytes_done += howmany;
|
||||
|
||||
if (bufferdone) {
|
||||
channel->endpoint->ephw->hw_sync_sgl_for_device(
|
||||
channel->endpoint,
|
||||
channel->wr_buffers[bufidx]->dma_addr,
|
||||
channel->wr_buf_size,
|
||||
DMA_FROM_DEVICE);
|
||||
dma_sync_single_for_device(channel->endpoint->dev,
|
||||
channel->wr_buffers[bufidx]->dma_addr,
|
||||
channel->wr_buf_size,
|
||||
DMA_FROM_DEVICE);
|
||||
|
||||
/*
|
||||
* Tell FPGA the buffer is done with. It's an
|
||||
@ -1055,11 +1088,10 @@ static int xillybus_myflush(struct xilly_channel *channel, long timeout)
|
||||
else
|
||||
channel->rd_host_buf_idx++;
|
||||
|
||||
channel->endpoint->ephw->hw_sync_sgl_for_device(
|
||||
channel->endpoint,
|
||||
channel->rd_buffers[bufidx]->dma_addr,
|
||||
channel->rd_buf_size,
|
||||
DMA_TO_DEVICE);
|
||||
dma_sync_single_for_device(channel->endpoint->dev,
|
||||
channel->rd_buffers[bufidx]->dma_addr,
|
||||
channel->rd_buf_size,
|
||||
DMA_TO_DEVICE);
|
||||
|
||||
mutex_lock(&channel->endpoint->register_mutex);
|
||||
|
||||
@ -1275,11 +1307,10 @@ static ssize_t xillybus_write(struct file *filp, const char __user *userbuf,
|
||||
|
||||
if ((bufpos == 0) || /* Zero means it's virgin */
|
||||
(channel->rd_leftovers[3] != 0)) {
|
||||
channel->endpoint->ephw->hw_sync_sgl_for_cpu(
|
||||
channel->endpoint,
|
||||
channel->rd_buffers[bufidx]->dma_addr,
|
||||
channel->rd_buf_size,
|
||||
DMA_TO_DEVICE);
|
||||
dma_sync_single_for_cpu(channel->endpoint->dev,
|
||||
channel->rd_buffers[bufidx]->dma_addr,
|
||||
channel->rd_buf_size,
|
||||
DMA_TO_DEVICE);
|
||||
|
||||
/* Virgin, but leftovers are due */
|
||||
for (i = 0; i < bufpos; i++)
|
||||
@ -1297,11 +1328,10 @@ static ssize_t xillybus_write(struct file *filp, const char __user *userbuf,
|
||||
bytes_done += howmany;
|
||||
|
||||
if (bufferdone) {
|
||||
channel->endpoint->ephw->hw_sync_sgl_for_device(
|
||||
channel->endpoint,
|
||||
channel->rd_buffers[bufidx]->dma_addr,
|
||||
channel->rd_buf_size,
|
||||
DMA_TO_DEVICE);
|
||||
dma_sync_single_for_device(channel->endpoint->dev,
|
||||
channel->rd_buffers[bufidx]->dma_addr,
|
||||
channel->rd_buf_size,
|
||||
DMA_TO_DEVICE);
|
||||
|
||||
mutex_lock(&channel->endpoint->register_mutex);
|
||||
|
||||
@ -1772,10 +1802,7 @@ static const struct file_operations xillybus_fops = {
|
||||
.poll = xillybus_poll,
|
||||
};
|
||||
|
||||
struct xilly_endpoint *xillybus_init_endpoint(struct pci_dev *pdev,
|
||||
struct device *dev,
|
||||
struct xilly_endpoint_hardware
|
||||
*ephw)
|
||||
struct xilly_endpoint *xillybus_init_endpoint(struct device *dev)
|
||||
{
|
||||
struct xilly_endpoint *endpoint;
|
||||
|
||||
@ -1783,9 +1810,7 @@ struct xilly_endpoint *xillybus_init_endpoint(struct pci_dev *pdev,
|
||||
if (!endpoint)
|
||||
return NULL;
|
||||
|
||||
endpoint->pdev = pdev;
|
||||
endpoint->dev = dev;
|
||||
endpoint->ephw = ephw;
|
||||
endpoint->msg_counter = 0x0b;
|
||||
endpoint->failed_messages = 0;
|
||||
endpoint->fatal_error = 0;
|
||||
@ -1912,7 +1937,7 @@ int xillybus_endpoint_discovery(struct xilly_endpoint *endpoint)
|
||||
goto failed_idt;
|
||||
|
||||
rc = xillybus_init_chrdev(dev, &xillybus_fops,
|
||||
endpoint->ephw->owner, endpoint,
|
||||
endpoint->owner, endpoint,
|
||||
idt_handle.names,
|
||||
idt_handle.names_len,
|
||||
endpoint->num_channels,
|
||||
|
@ -31,102 +31,22 @@ static const struct of_device_id xillybus_of_match[] = {
|
||||
|
||||
MODULE_DEVICE_TABLE(of, xillybus_of_match);
|
||||
|
||||
static void xilly_dma_sync_single_for_cpu_of(struct xilly_endpoint *ep,
|
||||
dma_addr_t dma_handle,
|
||||
size_t size,
|
||||
int direction)
|
||||
{
|
||||
dma_sync_single_for_cpu(ep->dev, dma_handle, size, direction);
|
||||
}
|
||||
|
||||
static void xilly_dma_sync_single_for_device_of(struct xilly_endpoint *ep,
|
||||
dma_addr_t dma_handle,
|
||||
size_t size,
|
||||
int direction)
|
||||
{
|
||||
dma_sync_single_for_device(ep->dev, dma_handle, size, direction);
|
||||
}
|
||||
|
||||
static void xilly_dma_sync_single_nop(struct xilly_endpoint *ep,
|
||||
dma_addr_t dma_handle,
|
||||
size_t size,
|
||||
int direction)
|
||||
{
|
||||
}
|
||||
|
||||
static void xilly_of_unmap(void *ptr)
|
||||
{
|
||||
struct xilly_mapping *data = ptr;
|
||||
|
||||
dma_unmap_single(data->device, data->dma_addr,
|
||||
data->size, data->direction);
|
||||
|
||||
kfree(ptr);
|
||||
}
|
||||
|
||||
static int xilly_map_single_of(struct xilly_endpoint *ep,
|
||||
void *ptr,
|
||||
size_t size,
|
||||
int direction,
|
||||
dma_addr_t *ret_dma_handle
|
||||
)
|
||||
{
|
||||
dma_addr_t addr;
|
||||
struct xilly_mapping *this;
|
||||
|
||||
this = kzalloc(sizeof(*this), GFP_KERNEL);
|
||||
if (!this)
|
||||
return -ENOMEM;
|
||||
|
||||
addr = dma_map_single(ep->dev, ptr, size, direction);
|
||||
|
||||
if (dma_mapping_error(ep->dev, addr)) {
|
||||
kfree(this);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
this->device = ep->dev;
|
||||
this->dma_addr = addr;
|
||||
this->size = size;
|
||||
this->direction = direction;
|
||||
|
||||
*ret_dma_handle = addr;
|
||||
|
||||
return devm_add_action_or_reset(ep->dev, xilly_of_unmap, this);
|
||||
}
|
||||
|
||||
static struct xilly_endpoint_hardware of_hw = {
|
||||
.owner = THIS_MODULE,
|
||||
.hw_sync_sgl_for_cpu = xilly_dma_sync_single_for_cpu_of,
|
||||
.hw_sync_sgl_for_device = xilly_dma_sync_single_for_device_of,
|
||||
.map_single = xilly_map_single_of,
|
||||
};
|
||||
|
||||
static struct xilly_endpoint_hardware of_hw_coherent = {
|
||||
.owner = THIS_MODULE,
|
||||
.hw_sync_sgl_for_cpu = xilly_dma_sync_single_nop,
|
||||
.hw_sync_sgl_for_device = xilly_dma_sync_single_nop,
|
||||
.map_single = xilly_map_single_of,
|
||||
};
|
||||
|
||||
static int xilly_drv_probe(struct platform_device *op)
|
||||
{
|
||||
struct device *dev = &op->dev;
|
||||
struct xilly_endpoint *endpoint;
|
||||
int rc;
|
||||
int irq;
|
||||
struct xilly_endpoint_hardware *ephw = &of_hw;
|
||||
|
||||
if (of_property_read_bool(dev->of_node, "dma-coherent"))
|
||||
ephw = &of_hw_coherent;
|
||||
|
||||
endpoint = xillybus_init_endpoint(NULL, dev, ephw);
|
||||
endpoint = xillybus_init_endpoint(dev);
|
||||
|
||||
if (!endpoint)
|
||||
return -ENOMEM;
|
||||
|
||||
dev_set_drvdata(dev, endpoint);
|
||||
|
||||
endpoint->owner = THIS_MODULE;
|
||||
|
||||
endpoint->registers = devm_platform_ioremap_resource(op, 0);
|
||||
if (IS_ERR(endpoint->registers))
|
||||
return PTR_ERR(endpoint->registers);
|
||||
|
@ -32,110 +32,21 @@ static const struct pci_device_id xillyids[] = {
|
||||
{ /* End: all zeroes */ }
|
||||
};
|
||||
|
||||
static int xilly_pci_direction(int direction)
|
||||
{
|
||||
switch (direction) {
|
||||
case DMA_TO_DEVICE:
|
||||
return PCI_DMA_TODEVICE;
|
||||
case DMA_FROM_DEVICE:
|
||||
return PCI_DMA_FROMDEVICE;
|
||||
default:
|
||||
return PCI_DMA_BIDIRECTIONAL;
|
||||
}
|
||||
}
|
||||
|
||||
static void xilly_dma_sync_single_for_cpu_pci(struct xilly_endpoint *ep,
|
||||
dma_addr_t dma_handle,
|
||||
size_t size,
|
||||
int direction)
|
||||
{
|
||||
pci_dma_sync_single_for_cpu(ep->pdev,
|
||||
dma_handle,
|
||||
size,
|
||||
xilly_pci_direction(direction));
|
||||
}
|
||||
|
||||
static void xilly_dma_sync_single_for_device_pci(struct xilly_endpoint *ep,
|
||||
dma_addr_t dma_handle,
|
||||
size_t size,
|
||||
int direction)
|
||||
{
|
||||
pci_dma_sync_single_for_device(ep->pdev,
|
||||
dma_handle,
|
||||
size,
|
||||
xilly_pci_direction(direction));
|
||||
}
|
||||
|
||||
static void xilly_pci_unmap(void *ptr)
|
||||
{
|
||||
struct xilly_mapping *data = ptr;
|
||||
|
||||
pci_unmap_single(data->device, data->dma_addr,
|
||||
data->size, data->direction);
|
||||
|
||||
kfree(ptr);
|
||||
}
|
||||
|
||||
/*
|
||||
* Map either through the PCI DMA mapper or the non_PCI one. Behind the
|
||||
* scenes exactly the same functions are called with the same parameters,
|
||||
* but that can change.
|
||||
*/
|
||||
|
||||
static int xilly_map_single_pci(struct xilly_endpoint *ep,
|
||||
void *ptr,
|
||||
size_t size,
|
||||
int direction,
|
||||
dma_addr_t *ret_dma_handle
|
||||
)
|
||||
{
|
||||
int pci_direction;
|
||||
dma_addr_t addr;
|
||||
struct xilly_mapping *this;
|
||||
|
||||
this = kzalloc(sizeof(*this), GFP_KERNEL);
|
||||
if (!this)
|
||||
return -ENOMEM;
|
||||
|
||||
pci_direction = xilly_pci_direction(direction);
|
||||
|
||||
addr = pci_map_single(ep->pdev, ptr, size, pci_direction);
|
||||
|
||||
if (pci_dma_mapping_error(ep->pdev, addr)) {
|
||||
kfree(this);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
this->device = ep->pdev;
|
||||
this->dma_addr = addr;
|
||||
this->size = size;
|
||||
this->direction = pci_direction;
|
||||
|
||||
*ret_dma_handle = addr;
|
||||
|
||||
return devm_add_action_or_reset(ep->dev, xilly_pci_unmap, this);
|
||||
}
|
||||
|
||||
static struct xilly_endpoint_hardware pci_hw = {
|
||||
.owner = THIS_MODULE,
|
||||
.hw_sync_sgl_for_cpu = xilly_dma_sync_single_for_cpu_pci,
|
||||
.hw_sync_sgl_for_device = xilly_dma_sync_single_for_device_pci,
|
||||
.map_single = xilly_map_single_pci,
|
||||
};
|
||||
|
||||
static int xilly_probe(struct pci_dev *pdev,
|
||||
const struct pci_device_id *ent)
|
||||
{
|
||||
struct xilly_endpoint *endpoint;
|
||||
int rc;
|
||||
|
||||
endpoint = xillybus_init_endpoint(pdev, &pdev->dev, &pci_hw);
|
||||
endpoint = xillybus_init_endpoint(&pdev->dev);
|
||||
|
||||
if (!endpoint)
|
||||
return -ENOMEM;
|
||||
|
||||
pci_set_drvdata(pdev, endpoint);
|
||||
|
||||
endpoint->owner = THIS_MODULE;
|
||||
|
||||
rc = pcim_enable_device(pdev);
|
||||
if (rc) {
|
||||
dev_err(endpoint->dev,
|
||||
@ -185,9 +96,9 @@ static int xilly_probe(struct pci_dev *pdev,
|
||||
* So go for the 64-bit mask only when failing is the other option.
|
||||
*/
|
||||
|
||||
if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(32))) {
|
||||
if (!dma_set_mask(&pdev->dev, DMA_BIT_MASK(32))) {
|
||||
endpoint->dma_using_dac = 0;
|
||||
} else if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(64))) {
|
||||
} else if (!dma_set_mask(&pdev->dev, DMA_BIT_MASK(64))) {
|
||||
endpoint->dma_using_dac = 1;
|
||||
} else {
|
||||
dev_err(endpoint->dev, "Failed to set DMA mask. Aborting.\n");
|
||||
|
@ -9,8 +9,7 @@
|
||||
|
||||
#include <linux/vmalloc.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
#include "comedidev.h"
|
||||
#include <linux/comedi/comedidev.h>
|
||||
#include "comedi_internal.h"
|
||||
|
||||
#ifdef PAGE_KERNEL_NOCACHE
|
||||
|
@ -23,7 +23,7 @@
|
||||
#include <linux/poll.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/fs.h>
|
||||
#include "comedidev.h"
|
||||
#include <linux/comedi/comedidev.h>
|
||||
#include <linux/cdev.h>
|
||||
|
||||
#include <linux/io.h>
|
||||
|
@ -9,8 +9,7 @@
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/interrupt.h>
|
||||
|
||||
#include "comedi_pci.h"
|
||||
#include <linux/comedi/comedi_pci.h>
|
||||
|
||||
/**
|
||||
* comedi_to_pci_dev() - Return PCI device attached to COMEDI device
|
||||
|
@ -9,8 +9,7 @@
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/kernel.h>
|
||||
|
||||
#include "comedi_pcmcia.h"
|
||||
#include <linux/comedi/comedi_pcmcia.h>
|
||||
|
||||
/**
|
||||
* comedi_to_pcmcia_dev() - Return PCMCIA device attached to COMEDI device
|
||||
|
@ -8,8 +8,7 @@
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
|
||||
#include "comedi_usb.h"
|
||||
#include <linux/comedi/comedi_usb.h>
|
||||
|
||||
/**
|
||||
* comedi_to_usb_interface() - Return USB interface attached to COMEDI device
|
||||
|
@ -17,8 +17,7 @@
|
||||
#include <linux/dma-direction.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/firmware.h>
|
||||
|
||||
#include "comedidev.h"
|
||||
#include <linux/comedi/comedidev.h>
|
||||
#include "comedi_internal.h"
|
||||
|
||||
struct comedi_driver *comedi_drivers;
|
||||
|
@ -40,9 +40,8 @@
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include "../comedidev.h"
|
||||
|
||||
#include "8255.h"
|
||||
#include <linux/comedi/comedidev.h>
|
||||
#include <linux/comedi/comedi_8255.h>
|
||||
|
||||
static int dev_8255_attach(struct comedi_device *dev,
|
||||
struct comedi_devconfig *it)
|
||||
|
@ -53,10 +53,8 @@
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
|
||||
#include "../comedi_pci.h"
|
||||
|
||||
#include "8255.h"
|
||||
#include <linux/comedi/comedi_pci.h>
|
||||
#include <linux/comedi/comedi_8255.h>
|
||||
|
||||
enum pci_8255_boardid {
|
||||
BOARD_ADLINK_PCI7224,
|
||||
|
@ -63,8 +63,8 @@
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/comedi/comedi_pci.h>
|
||||
|
||||
#include "../comedi_pci.h"
|
||||
#include "amcc_s5933.h"
|
||||
|
||||
/*
|
||||
|
@ -14,8 +14,8 @@
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/comedi/comedi_pci.h>
|
||||
|
||||
#include "../comedi_pci.h"
|
||||
#include "amcc_s5933.h"
|
||||
#include "z8536.h"
|
||||
|
||||
|
@ -14,8 +14,8 @@
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/comedi/comedi_pci.h>
|
||||
|
||||
#include "../comedi_pci.h"
|
||||
#include "addi_watchdog.h"
|
||||
|
||||
/*
|
||||
|
@ -68,8 +68,8 @@
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/comedi/comedi_pci.h>
|
||||
|
||||
#include "../comedi_pci.h"
|
||||
#include "addi_tcw.h"
|
||||
#include "addi_watchdog.h"
|
||||
|
||||
|
@ -14,8 +14,7 @@
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
|
||||
#include "../comedi_pci.h"
|
||||
#include <linux/comedi/comedi_pci.h>
|
||||
|
||||
/*
|
||||
* Register I/O map
|
||||
|
@ -16,8 +16,8 @@
|
||||
#include <linux/module.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/comedi/comedi_pci.h>
|
||||
|
||||
#include "../comedi_pci.h"
|
||||
#include "addi_watchdog.h"
|
||||
|
||||
/*
|
||||
|
@ -14,8 +14,8 @@
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/comedi/comedi_pci.h>
|
||||
|
||||
#include "../comedi_pci.h"
|
||||
#include "addi_watchdog.h"
|
||||
|
||||
/*
|
||||
|
@ -14,8 +14,8 @@
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/comedi/comedi_pci.h>
|
||||
|
||||
#include "../comedi_pci.h"
|
||||
#include "amcc_s5933.h"
|
||||
|
||||
/*
|
||||
|
@ -41,8 +41,8 @@
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/comedi/comedi_pci.h>
|
||||
|
||||
#include "../comedi_pci.h"
|
||||
#include "amcc_s5933.h"
|
||||
|
||||
/*
|
||||
|
@ -15,8 +15,7 @@
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/interrupt.h>
|
||||
|
||||
#include "../comedi_pci.h"
|
||||
#include <linux/comedi/comedi_pci.h>
|
||||
|
||||
#define CONV_UNIT_NS BIT(0)
|
||||
#define CONV_UNIT_US BIT(1)
|
||||
|
@ -10,7 +10,7 @@
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include "../comedidev.h"
|
||||
#include <linux/comedi/comedidev.h>
|
||||
#include "addi_tcw.h"
|
||||
#include "addi_watchdog.h"
|
||||
|
||||
|
@ -24,8 +24,7 @@
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/delay.h>
|
||||
|
||||
#include "../comedi_pci.h"
|
||||
#include <linux/comedi/comedi_pci.h>
|
||||
|
||||
/*
|
||||
* PCI-6208/6216-GL register map
|
||||
|
@ -46,8 +46,7 @@
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
|
||||
#include "../comedi_pci.h"
|
||||
#include <linux/comedi/comedi_pci.h>
|
||||
|
||||
#include "plx9052.h"
|
||||
|
||||
|
@ -19,8 +19,7 @@
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
|
||||
#include "../comedi_pci.h"
|
||||
#include <linux/comedi/comedi_pci.h>
|
||||
|
||||
#define PCI8164_AXIS(x) ((x) * 0x08)
|
||||
#define PCI8164_CMD_MSTS_REG 0x00
|
||||
|
@ -42,11 +42,10 @@
|
||||
#include <linux/module.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/interrupt.h>
|
||||
|
||||
#include "../comedi_pci.h"
|
||||
#include <linux/comedi/comedi_pci.h>
|
||||
#include <linux/comedi/comedi_8254.h>
|
||||
|
||||
#include "plx9052.h"
|
||||
#include "comedi_8254.h"
|
||||
|
||||
#define PCI9111_FIFO_HALF_SIZE 512
|
||||
|
||||
|
@ -78,11 +78,10 @@
|
||||
#include <linux/gfp.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/io.h>
|
||||
|
||||
#include "../comedi_pci.h"
|
||||
#include <linux/comedi/comedi_pci.h>
|
||||
#include <linux/comedi/comedi_8254.h>
|
||||
|
||||
#include "amcc_s5933.h"
|
||||
#include "comedi_8254.h"
|
||||
|
||||
/*
|
||||
* PCI BAR2 Register map (dev->iobase)
|
||||
|
@ -48,8 +48,7 @@
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/delay.h>
|
||||
|
||||
#include "../comedidev.h"
|
||||
#include <linux/comedi/comedidev.h>
|
||||
|
||||
/* address scheme (page 2.17 of the manual) */
|
||||
#define ADQ12B_CTREG 0x00
|
||||
|
@ -30,10 +30,9 @@
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/comedi/comedi_pci.h>
|
||||
#include <linux/comedi/comedi_8254.h>
|
||||
|
||||
#include "../comedi_pci.h"
|
||||
|
||||
#include "comedi_8254.h"
|
||||
#include "amcc_s5933.h"
|
||||
|
||||
/*
|
||||
|
@ -42,8 +42,7 @@
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/delay.h>
|
||||
|
||||
#include "../comedi_pci.h"
|
||||
#include <linux/comedi/comedi_pci.h>
|
||||
|
||||
/*
|
||||
* PCI BAR2 Register map (dev->iobase)
|
||||
|
@ -32,8 +32,7 @@
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
|
||||
#include "../comedi_pci.h"
|
||||
#include <linux/comedi/comedi_pci.h>
|
||||
|
||||
/*
|
||||
* PCI Bar 2 I/O Register map (dev->iobase)
|
||||
|
@ -38,8 +38,7 @@
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
|
||||
#include "../comedi_pci.h"
|
||||
#include <linux/comedi/comedi_pci.h>
|
||||
|
||||
/*
|
||||
* PCI bar 2 Register I/O map (dev->iobase)
|
||||
|
@ -22,8 +22,7 @@
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
|
||||
#include "../comedi_pci.h"
|
||||
#include <linux/comedi/comedi_pci.h>
|
||||
|
||||
/*
|
||||
* PCI-1760 Register Map
|
||||
|
@ -23,11 +23,9 @@
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/delay.h>
|
||||
|
||||
#include "../comedi_pci.h"
|
||||
|
||||
#include "8255.h"
|
||||
#include "comedi_8254.h"
|
||||
#include <linux/comedi/comedi_pci.h>
|
||||
#include <linux/comedi/comedi_8255.h>
|
||||
#include <linux/comedi/comedi_8254.h>
|
||||
|
||||
/*
|
||||
* Register offset definitions
|
||||
|
@ -22,10 +22,9 @@
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include "../comedidev.h"
|
||||
|
||||
#include "comedi_8254.h"
|
||||
#include "8255.h"
|
||||
#include <linux/comedi/comedidev.h>
|
||||
#include <linux/comedi/comedi_8255.h>
|
||||
#include <linux/comedi/comedi_8254.h>
|
||||
|
||||
/*
|
||||
* Register map
|
||||
|
@ -30,8 +30,7 @@
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/interrupt.h>
|
||||
|
||||
#include "../comedidev.h"
|
||||
#include <linux/comedi/comedidev.h>
|
||||
|
||||
#define AIO_IIRO_16_RELAY_0_7 0x00
|
||||
#define AIO_IIRO_16_INPUT_0_7 0x01
|
||||
|
@ -185,7 +185,7 @@
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include "../comedidev.h"
|
||||
#include <linux/comedi/comedidev.h>
|
||||
|
||||
#include "amplc_dio200.h"
|
||||
|
||||
|
@ -12,12 +12,11 @@
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/interrupt.h>
|
||||
|
||||
#include "../comedidev.h"
|
||||
#include <linux/comedi/comedidev.h>
|
||||
#include <linux/comedi/comedi_8255.h> /* only for register defines */
|
||||
#include <linux/comedi/comedi_8254.h>
|
||||
|
||||
#include "amplc_dio200.h"
|
||||
#include "comedi_8254.h"
|
||||
#include "8255.h" /* only for register defines */
|
||||
|
||||
/* 200 series registers */
|
||||
#define DIO200_IO_SIZE 0x20
|
||||
|
@ -214,8 +214,7 @@
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/interrupt.h>
|
||||
|
||||
#include "../comedi_pci.h"
|
||||
#include <linux/comedi/comedi_pci.h>
|
||||
|
||||
#include "amplc_dio200.h"
|
||||
|
||||
|
@ -32,8 +32,7 @@
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
|
||||
#include "../comedidev.h"
|
||||
#include <linux/comedi/comedidev.h>
|
||||
|
||||
#include "amplc_pc236.h"
|
||||
|
||||
|
@ -11,11 +11,10 @@
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/interrupt.h>
|
||||
|
||||
#include "../comedidev.h"
|
||||
#include <linux/comedi/comedidev.h>
|
||||
#include <linux/comedi/comedi_8255.h>
|
||||
|
||||
#include "amplc_pc236.h"
|
||||
#include "8255.h"
|
||||
|
||||
static void pc236_intr_update(struct comedi_device *dev, bool enable)
|
||||
{
|
||||
|
@ -25,7 +25,7 @@
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include "../comedidev.h"
|
||||
#include <linux/comedi/comedidev.h>
|
||||
|
||||
/* PC263 registers */
|
||||
#define PC263_DO_0_7_REG 0x00
|
||||
|
@ -96,10 +96,8 @@
|
||||
#include <linux/module.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
#include "../comedi_pci.h"
|
||||
|
||||
#include "comedi_8254.h"
|
||||
#include <linux/comedi/comedi_pci.h>
|
||||
#include <linux/comedi/comedi_8254.h>
|
||||
|
||||
/*
|
||||
* PCI224/234 i/o space 1 (PCIBAR2) registers.
|
||||
|
@ -174,11 +174,9 @@
|
||||
#include <linux/module.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/interrupt.h>
|
||||
|
||||
#include "../comedi_pci.h"
|
||||
|
||||
#include "comedi_8254.h"
|
||||
#include "8255.h"
|
||||
#include <linux/comedi/comedi_pci.h>
|
||||
#include <linux/comedi/comedi_8255.h>
|
||||
#include <linux/comedi/comedi_8254.h>
|
||||
|
||||
/*
|
||||
* PCI230 PCI configuration register information
|
||||
|
@ -34,8 +34,7 @@
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/interrupt.h>
|
||||
|
||||
#include "../comedi_pci.h"
|
||||
#include <linux/comedi/comedi_pci.h>
|
||||
|
||||
#include "amplc_pc236.h"
|
||||
#include "plx9052.h"
|
||||
|
@ -24,8 +24,7 @@
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
|
||||
#include "../comedi_pci.h"
|
||||
#include <linux/comedi/comedi_pci.h>
|
||||
|
||||
/* PCI263 registers */
|
||||
#define PCI263_DO_0_7_REG 0x00
|
||||
|
@ -30,8 +30,7 @@
|
||||
#include <linux/timer.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/pnp.h>
|
||||
|
||||
#include "../comedidev.h"
|
||||
#include <linux/comedi/comedidev.h>
|
||||
|
||||
/*
|
||||
* Register I/O map
|
||||
|
@ -27,10 +27,8 @@
|
||||
#include <linux/module.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/delay.h>
|
||||
|
||||
#include "../comedi_pcmcia.h"
|
||||
|
||||
#include "comedi_8254.h"
|
||||
#include <linux/comedi/comedi_pcmcia.h>
|
||||
#include <linux/comedi/comedi_8254.h>
|
||||
|
||||
/*
|
||||
* Register I/O map
|
||||
|
@ -54,11 +54,10 @@
|
||||
#include <linux/module.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/comedi/comedi_pci.h>
|
||||
#include <linux/comedi/comedi_8255.h>
|
||||
#include <linux/comedi/comedi_8254.h>
|
||||
|
||||
#include "../comedi_pci.h"
|
||||
|
||||
#include "comedi_8254.h"
|
||||
#include "8255.h"
|
||||
#include "amcc_s5933.h"
|
||||
|
||||
#define AI_BUFFER_SIZE 1024 /* max ai fifo size */
|
||||
|
@ -73,10 +73,9 @@
|
||||
#include <linux/module.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/comedi/comedi_pci.h>
|
||||
#include <linux/comedi/comedi_8255.h>
|
||||
|
||||
#include "../comedi_pci.h"
|
||||
|
||||
#include "8255.h"
|
||||
#include "plx9080.h"
|
||||
|
||||
#define TIMER_BASE 25 /* 40MHz master clock */
|
||||
|
@ -27,10 +27,8 @@
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
|
||||
#include "../comedi_pci.h"
|
||||
|
||||
#include "8255.h"
|
||||
#include <linux/comedi/comedi_pci.h>
|
||||
#include <linux/comedi/comedi_8255.h>
|
||||
|
||||
#define EEPROM_SIZE 128 /* number of entries in eeprom */
|
||||
/* maximum number of ao channels for supported boards */
|
||||
|
@ -34,12 +34,11 @@
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/comedi/comedi_pci.h>
|
||||
#include <linux/comedi/comedi_8255.h>
|
||||
#include <linux/comedi/comedi_8254.h>
|
||||
|
||||
#include "../comedi_pci.h"
|
||||
|
||||
#include "comedi_8254.h"
|
||||
#include "plx9052.h"
|
||||
#include "8255.h"
|
||||
|
||||
/*
|
||||
* PCI Bar 1 Register map
|
||||
|
@ -67,10 +67,8 @@
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
|
||||
#include "../comedi_pci.h"
|
||||
|
||||
#include "8255.h"
|
||||
#include <linux/comedi/comedi_pci.h>
|
||||
#include <linux/comedi/comedi_8255.h>
|
||||
|
||||
/* device ids of the cards we support -- currently only 1 card supported */
|
||||
#define PCI_ID_PCIM_DDA06_16 0x0053
|
||||
|
@ -116,10 +116,8 @@
|
||||
#include <linux/module.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/io.h>
|
||||
|
||||
#include "../comedidev.h"
|
||||
|
||||
#include "comedi_8254.h"
|
||||
#include <linux/comedi/comedidev.h>
|
||||
#include <linux/comedi/comedi_8254.h>
|
||||
|
||||
static unsigned int __i8254_read(struct comedi_8254 *i8254, unsigned int reg)
|
||||
{
|
||||
|
@ -29,9 +29,8 @@
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include "../comedidev.h"
|
||||
|
||||
#include "8255.h"
|
||||
#include <linux/comedi/comedidev.h>
|
||||
#include <linux/comedi/comedi_8255.h>
|
||||
|
||||
struct subdev_8255_private {
|
||||
unsigned long regbase;
|
||||
|
@ -40,9 +40,9 @@
|
||||
#include <linux/module.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/slab.h>
|
||||
#include "../comedi.h"
|
||||
#include "../comedilib.h"
|
||||
#include "../comedidev.h"
|
||||
#include <linux/comedi.h>
|
||||
#include <linux/comedi/comedilib.h>
|
||||
#include <linux/comedi/comedidev.h>
|
||||
|
||||
struct bonded_device {
|
||||
struct comedi_device *dev;
|
||||
|
@ -9,10 +9,8 @@
|
||||
#include <linux/delay.h>
|
||||
#include <linux/dma-mapping.h>
|
||||
#include <asm/dma.h>
|
||||
|
||||
#include "../comedidev.h"
|
||||
|
||||
#include "comedi_isadma.h"
|
||||
#include <linux/comedi/comedidev.h>
|
||||
#include <linux/comedi/comedi_isadma.h>
|
||||
|
||||
/**
|
||||
* comedi_isadma_program - program and enable an ISA DMA transfer
|
||||
|
@ -57,8 +57,7 @@
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/interrupt.h>
|
||||
|
||||
#include "../comedidev.h"
|
||||
#include <linux/comedi/comedidev.h>
|
||||
|
||||
/*
|
||||
* Register map
|
||||
|
@ -45,10 +45,8 @@
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include "../comedidev.h"
|
||||
|
||||
#include <linux/comedi/comedidev.h>
|
||||
#include <asm/div64.h>
|
||||
|
||||
#include <linux/timer.h>
|
||||
#include <linux/ktime.h>
|
||||
#include <linux/jiffies.h>
|
||||
|
@ -18,8 +18,7 @@
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
|
||||
#include "../comedi_pci.h"
|
||||
#include <linux/comedi/comedi_pci.h>
|
||||
|
||||
/*
|
||||
* Register map
|
||||
|
@ -25,8 +25,7 @@
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
|
||||
#include "../comedidev.h"
|
||||
#include <linux/comedi/comedidev.h>
|
||||
|
||||
/*
|
||||
* The output range is selected by jumpering pins on the I/O connector.
|
||||
|
@ -96,10 +96,9 @@
|
||||
#include <linux/module.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/comedi/comedi_pci.h>
|
||||
#include <linux/comedi/comedi_8255.h>
|
||||
|
||||
#include "../comedi_pci.h"
|
||||
|
||||
#include "8255.h"
|
||||
#include "plx9080.h"
|
||||
|
||||
#define DB2K_FIRMWARE "daqboard2000_firmware.bin"
|
||||
|
@ -10,11 +10,10 @@
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/comedi/comedidev.h>
|
||||
#include <linux/comedi/comedi_8255.h>
|
||||
#include <linux/comedi/comedi_8254.h>
|
||||
|
||||
#include "../comedidev.h"
|
||||
|
||||
#include "8255.h"
|
||||
#include "comedi_8254.h"
|
||||
#include "das08.h"
|
||||
|
||||
/*
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user