aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/sysdev/axonram.c
diff options
context:
space:
mode:
authorDan Williams <dan.j.williams@intel.com>2017-01-25 18:25:11 -0500
committerDan Williams <dan.j.williams@intel.com>2017-04-19 18:14:36 -0400
commit60fcd55cc236dbb3d6587f48120f00f59cb08540 (patch)
tree00da188329133a05706b69a0add1ee06033ff6aa /arch/powerpc/sysdev/axonram.c
parentc1d6e828a35df524df2af277eedd1471d05e4f4c (diff)
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>
Diffstat (limited to 'arch/powerpc/sysdev/axonram.c')
-rw-r--r--arch/powerpc/sysdev/axonram.c48
1 files changed, 42 insertions, 6 deletions
diff --git a/arch/powerpc/sysdev/axonram.c b/arch/powerpc/sysdev/axonram.c
index f523ac883150..171ba86a3494 100644
--- a/arch/powerpc/sysdev/axonram.c
+++ b/arch/powerpc/sysdev/axonram.c
@@ -25,6 +25,7 @@
25 25
26#include <linux/bio.h> 26#include <linux/bio.h>
27#include <linux/blkdev.h> 27#include <linux/blkdev.h>
28#include <linux/dax.h>
28#include <linux/device.h> 29#include <linux/device.h>
29#include <linux/errno.h> 30#include <linux/errno.h>
30#include <linux/fs.h> 31#include <linux/fs.h>
@@ -62,6 +63,7 @@ static int azfs_major, azfs_minor;
62struct axon_ram_bank { 63struct axon_ram_bank {
63 struct platform_device *device; 64 struct platform_device *device;
64 struct gendisk *disk; 65 struct gendisk *disk;
66 struct dax_device *dax_dev;
65 unsigned int irq_id; 67 unsigned int irq_id;
66 unsigned long ph_addr; 68 unsigned long ph_addr;
67 unsigned long io_addr; 69 unsigned long io_addr;
@@ -137,25 +139,47 @@ axon_ram_make_request(struct request_queue *queue, struct bio *bio)
137 return BLK_QC_T_NONE; 139 return BLK_QC_T_NONE;
138} 140}
139 141
142static long
143__axon_ram_direct_access(struct axon_ram_bank *bank, pgoff_t pgoff, long nr_pages,
144 void **kaddr, pfn_t *pfn)
145{
146 resource_size_t offset = pgoff * PAGE_SIZE;
147
148 *kaddr = (void *) bank->io_addr + offset;
149 *pfn = phys_to_pfn_t(bank->ph_addr + offset, PFN_DEV);
150 return (bank->size - offset) / PAGE_SIZE;
151}
152
140/** 153/**
141 * axon_ram_direct_access - direct_access() method for block device 154 * axon_ram_direct_access - direct_access() method for block device
142 * @device, @sector, @data: see block_device_operations method 155 * @device, @sector, @data: see block_device_operations method
143 */ 156 */
144static long 157static long
145axon_ram_direct_access(struct block_device *device, sector_t sector, 158axon_ram_blk_direct_access(struct block_device *device, sector_t sector,
146 void **kaddr, pfn_t *pfn, long size) 159 void **kaddr, pfn_t *pfn, long size)
147{ 160{
148 struct axon_ram_bank *bank = device->bd_disk->private_data; 161 struct axon_ram_bank *bank = device->bd_disk->private_data;
149 loff_t offset = (loff_t)sector << AXON_RAM_SECTOR_SHIFT;
150 162
151 *kaddr = (void *) bank->io_addr + offset; 163 return __axon_ram_direct_access(bank, (sector * 512) / PAGE_SIZE,
152 *pfn = phys_to_pfn_t(bank->ph_addr + offset, PFN_DEV); 164 size / PAGE_SIZE, kaddr, pfn) * PAGE_SIZE;
153 return bank->size - offset;
154} 165}
155 166
156static const struct block_device_operations axon_ram_devops = { 167static const struct block_device_operations axon_ram_devops = {
157 .owner = THIS_MODULE, 168 .owner = THIS_MODULE,
158 .direct_access = axon_ram_direct_access 169 .direct_access = axon_ram_blk_direct_access
170};
171
172static long
173axon_ram_dax_direct_access(struct dax_device *dax_dev, pgoff_t pgoff, long nr_pages,
174 void **kaddr, pfn_t *pfn)
175{
176 struct axon_ram_bank *bank = dax_get_private(dax_dev);
177
178 return __axon_ram_direct_access(bank, pgoff, nr_pages, kaddr, pfn);
179}
180
181static const struct dax_operations axon_ram_dax_ops = {
182 .direct_access = axon_ram_dax_direct_access,
159}; 183};
160 184
161/** 185/**
@@ -219,6 +243,7 @@ static int axon_ram_probe(struct platform_device *device)
219 goto failed; 243 goto failed;
220 } 244 }
221 245
246
222 bank->disk->major = azfs_major; 247 bank->disk->major = azfs_major;
223 bank->disk->first_minor = azfs_minor; 248 bank->disk->first_minor = azfs_minor;
224 bank->disk->fops = &axon_ram_devops; 249 bank->disk->fops = &axon_ram_devops;
@@ -227,6 +252,13 @@ static int axon_ram_probe(struct platform_device *device)
227 sprintf(bank->disk->disk_name, "%s%d", 252 sprintf(bank->disk->disk_name, "%s%d",
228 AXON_RAM_DEVICE_NAME, axon_ram_bank_id); 253 AXON_RAM_DEVICE_NAME, axon_ram_bank_id);
229 254
255 bank->dax_dev = alloc_dax(bank, bank->disk->disk_name,
256 &axon_ram_dax_ops);
257 if (!bank->dax_dev) {
258 rc = -ENOMEM;
259 goto failed;
260 }
261
230 bank->disk->queue = blk_alloc_queue(GFP_KERNEL); 262 bank->disk->queue = blk_alloc_queue(GFP_KERNEL);
231 if (bank->disk->queue == NULL) { 263 if (bank->disk->queue == NULL) {
232 dev_err(&device->dev, "Cannot register disk queue\n"); 264 dev_err(&device->dev, "Cannot register disk queue\n");
@@ -278,6 +310,8 @@ failed:
278 del_gendisk(bank->disk); 310 del_gendisk(bank->disk);
279 put_disk(bank->disk); 311 put_disk(bank->disk);
280 } 312 }
313 kill_dax(bank->dax_dev);
314 put_dax(bank->dax_dev);
281 device->dev.platform_data = NULL; 315 device->dev.platform_data = NULL;
282 if (bank->io_addr != 0) 316 if (bank->io_addr != 0)
283 iounmap((void __iomem *) bank->io_addr); 317 iounmap((void __iomem *) bank->io_addr);
@@ -300,6 +334,8 @@ axon_ram_remove(struct platform_device *device)
300 334
301 device_remove_file(&device->dev, &dev_attr_ecc); 335 device_remove_file(&device->dev, &dev_attr_ecc);
302 free_irq(bank->irq_id, device); 336 free_irq(bank->irq_id, device);
337 kill_dax(bank->dax_dev);
338 put_dax(bank->dax_dev);
303 del_gendisk(bank->disk); 339 del_gendisk(bank->disk);
304 put_disk(bank->disk); 340 put_disk(bank->disk);
305 iounmap((void __iomem *) bank->io_addr); 341 iounmap((void __iomem *) bank->io_addr);