mirror of
https://github.com/torvalds/linux.git
synced 2026-05-30 18:13:41 +02:00
mtd: add driver for intel graphics non-volatile memory device
Add auxiliary driver for intel discrete graphics non-volatile memory device. CC: Lucas De Marchi <lucas.demarchi@intel.com> Reviewed-by: Raag Jadav <raag.jadav@intel.com> Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com> Acked-by: Miquel Raynal <miquel.raynal@bootlin.com> Co-developed-by: Tomas Winkler <tomasw@gmail.com> Signed-off-by: Tomas Winkler <tomasw@gmail.com> Signed-off-by: Alexander Usyskin <alexander.usyskin@intel.com> Link: https://lore.kernel.org/r/20250617145159.3803852-2-alexander.usyskin@intel.com Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
This commit is contained in:
parent
0089d6ee3b
commit
ceb5ab3cb6
|
|
@ -12086,6 +12086,13 @@ L: linux-kernel@vger.kernel.org
|
||||||
S: Supported
|
S: Supported
|
||||||
F: arch/x86/include/asm/intel-family.h
|
F: arch/x86/include/asm/intel-family.h
|
||||||
|
|
||||||
|
INTEL DISCRETE GRAPHICS NVM MTD DRIVER
|
||||||
|
M: Alexander Usyskin <alexander.usyskin@intel.com>
|
||||||
|
L: linux-mtd@lists.infradead.org
|
||||||
|
S: Supported
|
||||||
|
F: drivers/mtd/devices/mtd_intel_dg.c
|
||||||
|
F: include/linux/intel_dg_nvm_aux.h
|
||||||
|
|
||||||
INTEL DRM DISPLAY FOR XE AND I915 DRIVERS
|
INTEL DRM DISPLAY FOR XE AND I915 DRIVERS
|
||||||
M: Jani Nikula <jani.nikula@linux.intel.com>
|
M: Jani Nikula <jani.nikula@linux.intel.com>
|
||||||
M: Rodrigo Vivi <rodrigo.vivi@intel.com>
|
M: Rodrigo Vivi <rodrigo.vivi@intel.com>
|
||||||
|
|
|
||||||
|
|
@ -183,6 +183,17 @@ config MTD_POWERNV_FLASH
|
||||||
platforms from Linux. This device abstracts away the
|
platforms from Linux. This device abstracts away the
|
||||||
firmware interface for flash access.
|
firmware interface for flash access.
|
||||||
|
|
||||||
|
config MTD_INTEL_DG
|
||||||
|
tristate "Intel Discrete Graphics non-volatile memory driver"
|
||||||
|
depends on AUXILIARY_BUS
|
||||||
|
depends on MTD
|
||||||
|
help
|
||||||
|
This provides an MTD device to access Intel Discrete Graphics
|
||||||
|
non-volatile memory.
|
||||||
|
|
||||||
|
To compile this driver as a module, choose M here: the module
|
||||||
|
will be called mtd-intel-dg.
|
||||||
|
|
||||||
comment "Disk-On-Chip Device Drivers"
|
comment "Disk-On-Chip Device Drivers"
|
||||||
|
|
||||||
config MTD_DOCG3
|
config MTD_DOCG3
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,7 @@ obj-$(CONFIG_MTD_SST25L) += sst25l.o
|
||||||
obj-$(CONFIG_MTD_BCM47XXSFLASH) += bcm47xxsflash.o
|
obj-$(CONFIG_MTD_BCM47XXSFLASH) += bcm47xxsflash.o
|
||||||
obj-$(CONFIG_MTD_ST_SPI_FSM) += st_spi_fsm.o
|
obj-$(CONFIG_MTD_ST_SPI_FSM) += st_spi_fsm.o
|
||||||
obj-$(CONFIG_MTD_POWERNV_FLASH) += powernv_flash.o
|
obj-$(CONFIG_MTD_POWERNV_FLASH) += powernv_flash.o
|
||||||
|
obj-$(CONFIG_MTD_INTEL_DG) += mtd_intel_dg.o
|
||||||
|
|
||||||
|
|
||||||
CFLAGS_docg3.o += -I$(src)
|
CFLAGS_docg3.o += -I$(src)
|
||||||
|
|
|
||||||
134
drivers/mtd/devices/mtd_intel_dg.c
Normal file
134
drivers/mtd/devices/mtd_intel_dg.c
Normal file
|
|
@ -0,0 +1,134 @@
|
||||||
|
// SPDX-License-Identifier: GPL-2.0
|
||||||
|
/*
|
||||||
|
* Copyright(c) 2019-2025, Intel Corporation. All rights reserved.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <linux/device.h>
|
||||||
|
#include <linux/intel_dg_nvm_aux.h>
|
||||||
|
#include <linux/io.h>
|
||||||
|
#include <linux/kernel.h>
|
||||||
|
#include <linux/module.h>
|
||||||
|
#include <linux/string.h>
|
||||||
|
#include <linux/slab.h>
|
||||||
|
#include <linux/types.h>
|
||||||
|
|
||||||
|
struct intel_dg_nvm {
|
||||||
|
struct kref refcnt;
|
||||||
|
void __iomem *base;
|
||||||
|
size_t size;
|
||||||
|
unsigned int nregions;
|
||||||
|
struct {
|
||||||
|
const char *name;
|
||||||
|
u8 id;
|
||||||
|
u64 offset;
|
||||||
|
u64 size;
|
||||||
|
} regions[] __counted_by(nregions);
|
||||||
|
};
|
||||||
|
|
||||||
|
static void intel_dg_nvm_release(struct kref *kref)
|
||||||
|
{
|
||||||
|
struct intel_dg_nvm *nvm = container_of(kref, struct intel_dg_nvm, refcnt);
|
||||||
|
int i;
|
||||||
|
|
||||||
|
pr_debug("freeing intel_dg nvm\n");
|
||||||
|
for (i = 0; i < nvm->nregions; i++)
|
||||||
|
kfree(nvm->regions[i].name);
|
||||||
|
kfree(nvm);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int intel_dg_mtd_probe(struct auxiliary_device *aux_dev,
|
||||||
|
const struct auxiliary_device_id *aux_dev_id)
|
||||||
|
{
|
||||||
|
struct intel_dg_nvm_dev *invm = auxiliary_dev_to_intel_dg_nvm_dev(aux_dev);
|
||||||
|
struct intel_dg_nvm *nvm;
|
||||||
|
struct device *device;
|
||||||
|
unsigned int nregions;
|
||||||
|
unsigned int i, n;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
device = &aux_dev->dev;
|
||||||
|
|
||||||
|
/* count available regions */
|
||||||
|
for (nregions = 0, i = 0; i < INTEL_DG_NVM_REGIONS; i++) {
|
||||||
|
if (invm->regions[i].name)
|
||||||
|
nregions++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!nregions) {
|
||||||
|
dev_err(device, "no regions defined\n");
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
|
||||||
|
nvm = kzalloc(struct_size(nvm, regions, nregions), GFP_KERNEL);
|
||||||
|
if (!nvm)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
kref_init(&nvm->refcnt);
|
||||||
|
|
||||||
|
for (n = 0, i = 0; i < INTEL_DG_NVM_REGIONS; i++) {
|
||||||
|
if (!invm->regions[i].name)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
char *name = kasprintf(GFP_KERNEL, "%s.%s",
|
||||||
|
dev_name(&aux_dev->dev), invm->regions[i].name);
|
||||||
|
if (!name)
|
||||||
|
continue;
|
||||||
|
nvm->regions[n].name = name;
|
||||||
|
nvm->regions[n].id = i;
|
||||||
|
n++;
|
||||||
|
}
|
||||||
|
nvm->nregions = n; /* in case where kasprintf fail */
|
||||||
|
|
||||||
|
nvm->base = devm_ioremap_resource(device, &invm->bar);
|
||||||
|
if (IS_ERR(nvm->base)) {
|
||||||
|
ret = PTR_ERR(nvm->base);
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
dev_set_drvdata(&aux_dev->dev, nvm);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
err:
|
||||||
|
kref_put(&nvm->refcnt, intel_dg_nvm_release);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void intel_dg_mtd_remove(struct auxiliary_device *aux_dev)
|
||||||
|
{
|
||||||
|
struct intel_dg_nvm *nvm = dev_get_drvdata(&aux_dev->dev);
|
||||||
|
|
||||||
|
if (!nvm)
|
||||||
|
return;
|
||||||
|
|
||||||
|
dev_set_drvdata(&aux_dev->dev, NULL);
|
||||||
|
|
||||||
|
kref_put(&nvm->refcnt, intel_dg_nvm_release);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct auxiliary_device_id intel_dg_mtd_id_table[] = {
|
||||||
|
{
|
||||||
|
.name = "i915.nvm",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.name = "xe.nvm",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
/* sentinel */
|
||||||
|
}
|
||||||
|
};
|
||||||
|
MODULE_DEVICE_TABLE(auxiliary, intel_dg_mtd_id_table);
|
||||||
|
|
||||||
|
static struct auxiliary_driver intel_dg_mtd_driver = {
|
||||||
|
.probe = intel_dg_mtd_probe,
|
||||||
|
.remove = intel_dg_mtd_remove,
|
||||||
|
.driver = {
|
||||||
|
/* auxiliary_driver_register() sets .name to be the modname */
|
||||||
|
},
|
||||||
|
.id_table = intel_dg_mtd_id_table
|
||||||
|
};
|
||||||
|
module_auxiliary_driver(intel_dg_mtd_driver);
|
||||||
|
|
||||||
|
MODULE_LICENSE("GPL");
|
||||||
|
MODULE_AUTHOR("Intel Corporation");
|
||||||
|
MODULE_DESCRIPTION("Intel DGFX MTD driver");
|
||||||
30
include/linux/intel_dg_nvm_aux.h
Normal file
30
include/linux/intel_dg_nvm_aux.h
Normal file
|
|
@ -0,0 +1,30 @@
|
||||||
|
/* SPDX-License-Identifier: MIT */
|
||||||
|
/*
|
||||||
|
* Copyright(c) 2019-2025, Intel Corporation. All rights reserved.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __INTEL_DG_NVM_AUX_H__
|
||||||
|
#define __INTEL_DG_NVM_AUX_H__
|
||||||
|
|
||||||
|
#include <linux/auxiliary_bus.h>
|
||||||
|
#include <linux/container_of.h>
|
||||||
|
#include <linux/ioport.h>
|
||||||
|
#include <linux/types.h>
|
||||||
|
|
||||||
|
#define INTEL_DG_NVM_REGIONS 13
|
||||||
|
|
||||||
|
struct intel_dg_nvm_region {
|
||||||
|
const char *name;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct intel_dg_nvm_dev {
|
||||||
|
struct auxiliary_device aux_dev;
|
||||||
|
bool writable_override;
|
||||||
|
struct resource bar;
|
||||||
|
const struct intel_dg_nvm_region *regions;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define auxiliary_dev_to_intel_dg_nvm_dev(auxiliary_dev) \
|
||||||
|
container_of(auxiliary_dev, struct intel_dg_nvm_dev, aux_dev)
|
||||||
|
|
||||||
|
#endif /* __INTEL_DG_NVM_AUX_H__ */
|
||||||
Loading…
Reference in New Issue
Block a user