diff options
author | Dan Williams <dan.j.williams@intel.com> | 2017-01-25 18:25:11 -0500 |
---|---|---|
committer | Dan Williams <dan.j.williams@intel.com> | 2017-04-19 18:14:36 -0400 |
commit | 60fcd55cc236dbb3d6587f48120f00f59cb08540 (patch) | |
tree | 00da188329133a05706b69a0add1ee06033ff6aa /arch/powerpc/sysdev/axonram.c | |
parent | c1d6e828a35df524df2af277eedd1471d05e4f4c (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.c | 48 |
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; | |||
62 | struct axon_ram_bank { | 63 | struct 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 | ||
142 | static 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 | */ |
144 | static long | 157 | static long |
145 | axon_ram_direct_access(struct block_device *device, sector_t sector, | 158 | axon_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 | ||
156 | static const struct block_device_operations axon_ram_devops = { | 167 | static 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 | |||
172 | static long | ||
173 | axon_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 | |||
181 | static 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); |