mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-01-09 23:00:21 +00:00
axon_ram: add dax_operations support
Setup a dax_device to have the same lifetime as the axon_ram block device and add a ->direct_access() method that is equivalent to axon_ram_direct_access(). Once fs/dax.c has been converted to use dax_operations the old axon_ram_direct_access() will be removed. Reported-by: Gerald Schaefer <gerald.schaefer@de.ibm.com> Signed-off-by: Dan Williams <dan.j.williams@intel.com>
This commit is contained in:
parent
c1d6e828a3
commit
60fcd55cc2
@ -284,6 +284,7 @@ config CPM2
|
|||||||
config AXON_RAM
|
config AXON_RAM
|
||||||
tristate "Axon DDR2 memory device driver"
|
tristate "Axon DDR2 memory device driver"
|
||||||
depends on PPC_IBM_CELL_BLADE && BLOCK
|
depends on PPC_IBM_CELL_BLADE && BLOCK
|
||||||
|
select DAX
|
||||||
default m
|
default m
|
||||||
help
|
help
|
||||||
It registers one block device per Axon's DDR2 memory bank found
|
It registers one block device per Axon's DDR2 memory bank found
|
||||||
|
@ -25,6 +25,7 @@
|
|||||||
|
|
||||||
#include <linux/bio.h>
|
#include <linux/bio.h>
|
||||||
#include <linux/blkdev.h>
|
#include <linux/blkdev.h>
|
||||||
|
#include <linux/dax.h>
|
||||||
#include <linux/device.h>
|
#include <linux/device.h>
|
||||||
#include <linux/errno.h>
|
#include <linux/errno.h>
|
||||||
#include <linux/fs.h>
|
#include <linux/fs.h>
|
||||||
@ -62,6 +63,7 @@ static int azfs_major, azfs_minor;
|
|||||||
struct axon_ram_bank {
|
struct axon_ram_bank {
|
||||||
struct platform_device *device;
|
struct platform_device *device;
|
||||||
struct gendisk *disk;
|
struct gendisk *disk;
|
||||||
|
struct dax_device *dax_dev;
|
||||||
unsigned int irq_id;
|
unsigned int irq_id;
|
||||||
unsigned long ph_addr;
|
unsigned long ph_addr;
|
||||||
unsigned long io_addr;
|
unsigned long io_addr;
|
||||||
@ -137,25 +139,47 @@ axon_ram_make_request(struct request_queue *queue, struct bio *bio)
|
|||||||
return BLK_QC_T_NONE;
|
return BLK_QC_T_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static long
|
||||||
|
__axon_ram_direct_access(struct axon_ram_bank *bank, pgoff_t pgoff, long nr_pages,
|
||||||
|
void **kaddr, pfn_t *pfn)
|
||||||
|
{
|
||||||
|
resource_size_t offset = pgoff * PAGE_SIZE;
|
||||||
|
|
||||||
|
*kaddr = (void *) bank->io_addr + offset;
|
||||||
|
*pfn = phys_to_pfn_t(bank->ph_addr + offset, PFN_DEV);
|
||||||
|
return (bank->size - offset) / PAGE_SIZE;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* axon_ram_direct_access - direct_access() method for block device
|
* axon_ram_direct_access - direct_access() method for block device
|
||||||
* @device, @sector, @data: see block_device_operations method
|
* @device, @sector, @data: see block_device_operations method
|
||||||
*/
|
*/
|
||||||
static long
|
static long
|
||||||
axon_ram_direct_access(struct block_device *device, sector_t sector,
|
axon_ram_blk_direct_access(struct block_device *device, sector_t sector,
|
||||||
void **kaddr, pfn_t *pfn, long size)
|
void **kaddr, pfn_t *pfn, long size)
|
||||||
{
|
{
|
||||||
struct axon_ram_bank *bank = device->bd_disk->private_data;
|
struct axon_ram_bank *bank = device->bd_disk->private_data;
|
||||||
loff_t offset = (loff_t)sector << AXON_RAM_SECTOR_SHIFT;
|
|
||||||
|
|
||||||
*kaddr = (void *) bank->io_addr + offset;
|
return __axon_ram_direct_access(bank, (sector * 512) / PAGE_SIZE,
|
||||||
*pfn = phys_to_pfn_t(bank->ph_addr + offset, PFN_DEV);
|
size / PAGE_SIZE, kaddr, pfn) * PAGE_SIZE;
|
||||||
return bank->size - offset;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct block_device_operations axon_ram_devops = {
|
static const struct block_device_operations axon_ram_devops = {
|
||||||
.owner = THIS_MODULE,
|
.owner = THIS_MODULE,
|
||||||
.direct_access = axon_ram_direct_access
|
.direct_access = axon_ram_blk_direct_access
|
||||||
|
};
|
||||||
|
|
||||||
|
static long
|
||||||
|
axon_ram_dax_direct_access(struct dax_device *dax_dev, pgoff_t pgoff, long nr_pages,
|
||||||
|
void **kaddr, pfn_t *pfn)
|
||||||
|
{
|
||||||
|
struct axon_ram_bank *bank = dax_get_private(dax_dev);
|
||||||
|
|
||||||
|
return __axon_ram_direct_access(bank, pgoff, nr_pages, kaddr, pfn);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct dax_operations axon_ram_dax_ops = {
|
||||||
|
.direct_access = axon_ram_dax_direct_access,
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -219,6 +243,7 @@ static int axon_ram_probe(struct platform_device *device)
|
|||||||
goto failed;
|
goto failed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bank->disk->major = azfs_major;
|
bank->disk->major = azfs_major;
|
||||||
bank->disk->first_minor = azfs_minor;
|
bank->disk->first_minor = azfs_minor;
|
||||||
bank->disk->fops = &axon_ram_devops;
|
bank->disk->fops = &axon_ram_devops;
|
||||||
@ -227,6 +252,13 @@ static int axon_ram_probe(struct platform_device *device)
|
|||||||
sprintf(bank->disk->disk_name, "%s%d",
|
sprintf(bank->disk->disk_name, "%s%d",
|
||||||
AXON_RAM_DEVICE_NAME, axon_ram_bank_id);
|
AXON_RAM_DEVICE_NAME, axon_ram_bank_id);
|
||||||
|
|
||||||
|
bank->dax_dev = alloc_dax(bank, bank->disk->disk_name,
|
||||||
|
&axon_ram_dax_ops);
|
||||||
|
if (!bank->dax_dev) {
|
||||||
|
rc = -ENOMEM;
|
||||||
|
goto failed;
|
||||||
|
}
|
||||||
|
|
||||||
bank->disk->queue = blk_alloc_queue(GFP_KERNEL);
|
bank->disk->queue = blk_alloc_queue(GFP_KERNEL);
|
||||||
if (bank->disk->queue == NULL) {
|
if (bank->disk->queue == NULL) {
|
||||||
dev_err(&device->dev, "Cannot register disk queue\n");
|
dev_err(&device->dev, "Cannot register disk queue\n");
|
||||||
@ -278,6 +310,8 @@ failed:
|
|||||||
del_gendisk(bank->disk);
|
del_gendisk(bank->disk);
|
||||||
put_disk(bank->disk);
|
put_disk(bank->disk);
|
||||||
}
|
}
|
||||||
|
kill_dax(bank->dax_dev);
|
||||||
|
put_dax(bank->dax_dev);
|
||||||
device->dev.platform_data = NULL;
|
device->dev.platform_data = NULL;
|
||||||
if (bank->io_addr != 0)
|
if (bank->io_addr != 0)
|
||||||
iounmap((void __iomem *) bank->io_addr);
|
iounmap((void __iomem *) bank->io_addr);
|
||||||
@ -300,6 +334,8 @@ axon_ram_remove(struct platform_device *device)
|
|||||||
|
|
||||||
device_remove_file(&device->dev, &dev_attr_ecc);
|
device_remove_file(&device->dev, &dev_attr_ecc);
|
||||||
free_irq(bank->irq_id, device);
|
free_irq(bank->irq_id, device);
|
||||||
|
kill_dax(bank->dax_dev);
|
||||||
|
put_dax(bank->dax_dev);
|
||||||
del_gendisk(bank->disk);
|
del_gendisk(bank->disk);
|
||||||
put_disk(bank->disk);
|
put_disk(bank->disk);
|
||||||
iounmap((void __iomem *) bank->io_addr);
|
iounmap((void __iomem *) bank->io_addr);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user