Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
at v4.14-rc2 383 lines 9.9 kB view raw
1/* 2 * (C) Copyright IBM Deutschland Entwicklung GmbH 2006 3 * 4 * Author: Maxim Shchetynin <maxim@de.ibm.com> 5 * 6 * Axon DDR2 device driver. 7 * It registers one block device per Axon's DDR2 memory bank found on a system. 8 * Block devices are called axonram?, their major and minor numbers are 9 * available in /proc/devices, /proc/partitions or in /sys/block/axonram?/dev. 10 * 11 * This program is free software; you can redistribute it and/or modify 12 * it under the terms of the GNU General Public License as published by 13 * the Free Software Foundation; either version 2, or (at your option) 14 * any later version. 15 * 16 * This program is distributed in the hope that it will be useful, 17 * but WITHOUT ANY WARRANTY; without even the implied warranty of 18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 * GNU General Public License for more details. 20 * 21 * You should have received a copy of the GNU General Public License 22 * along with this program; if not, write to the Free Software 23 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 24 */ 25 26#include <linux/bio.h> 27#include <linux/blkdev.h> 28#include <linux/dax.h> 29#include <linux/device.h> 30#include <linux/errno.h> 31#include <linux/fs.h> 32#include <linux/genhd.h> 33#include <linux/interrupt.h> 34#include <linux/io.h> 35#include <linux/ioport.h> 36#include <linux/irq.h> 37#include <linux/irqreturn.h> 38#include <linux/kernel.h> 39#include <linux/mm.h> 40#include <linux/mod_devicetable.h> 41#include <linux/module.h> 42#include <linux/slab.h> 43#include <linux/string.h> 44#include <linux/types.h> 45#include <linux/of_device.h> 46#include <linux/of_platform.h> 47#include <linux/pfn_t.h> 48#include <linux/uio.h> 49 50#include <asm/page.h> 51#include <asm/prom.h> 52 53#define AXON_RAM_MODULE_NAME "axonram" 54#define AXON_RAM_DEVICE_NAME "axonram" 55#define AXON_RAM_MINORS_PER_DISK 16 56#define AXON_RAM_BLOCK_SHIFT PAGE_SHIFT 57#define AXON_RAM_BLOCK_SIZE 1 << AXON_RAM_BLOCK_SHIFT 58#define AXON_RAM_SECTOR_SHIFT 9 59#define AXON_RAM_SECTOR_SIZE 1 << AXON_RAM_SECTOR_SHIFT 60#define AXON_RAM_IRQ_FLAGS IRQF_SHARED | IRQF_TRIGGER_RISING 61 62static int azfs_major, azfs_minor; 63 64struct axon_ram_bank { 65 struct platform_device *device; 66 struct gendisk *disk; 67 struct dax_device *dax_dev; 68 unsigned int irq_id; 69 unsigned long ph_addr; 70 unsigned long io_addr; 71 unsigned long size; 72 unsigned long ecc_counter; 73}; 74 75static ssize_t 76axon_ram_sysfs_ecc(struct device *dev, struct device_attribute *attr, char *buf) 77{ 78 struct platform_device *device = to_platform_device(dev); 79 struct axon_ram_bank *bank = device->dev.platform_data; 80 81 BUG_ON(!bank); 82 83 return sprintf(buf, "%ld\n", bank->ecc_counter); 84} 85 86static DEVICE_ATTR(ecc, S_IRUGO, axon_ram_sysfs_ecc, NULL); 87 88/** 89 * axon_ram_irq_handler - interrupt handler for Axon RAM ECC 90 * @irq: interrupt ID 91 * @dev: pointer to of_device 92 */ 93static irqreturn_t 94axon_ram_irq_handler(int irq, void *dev) 95{ 96 struct platform_device *device = dev; 97 struct axon_ram_bank *bank = device->dev.platform_data; 98 99 BUG_ON(!bank); 100 101 dev_err(&device->dev, "Correctable memory error occurred\n"); 102 bank->ecc_counter++; 103 return IRQ_HANDLED; 104} 105 106/** 107 * axon_ram_make_request - make_request() method for block device 108 * @queue, @bio: see blk_queue_make_request() 109 */ 110static blk_qc_t 111axon_ram_make_request(struct request_queue *queue, struct bio *bio) 112{ 113 struct axon_ram_bank *bank = bio->bi_disk->private_data; 114 unsigned long phys_mem, phys_end; 115 void *user_mem; 116 struct bio_vec vec; 117 unsigned int transfered; 118 struct bvec_iter iter; 119 120 phys_mem = bank->io_addr + (bio->bi_iter.bi_sector << 121 AXON_RAM_SECTOR_SHIFT); 122 phys_end = bank->io_addr + bank->size; 123 transfered = 0; 124 bio_for_each_segment(vec, bio, iter) { 125 if (unlikely(phys_mem + vec.bv_len > phys_end)) { 126 bio_io_error(bio); 127 return BLK_QC_T_NONE; 128 } 129 130 user_mem = page_address(vec.bv_page) + vec.bv_offset; 131 if (bio_data_dir(bio) == READ) 132 memcpy(user_mem, (void *) phys_mem, vec.bv_len); 133 else 134 memcpy((void *) phys_mem, user_mem, vec.bv_len); 135 136 phys_mem += vec.bv_len; 137 transfered += vec.bv_len; 138 } 139 bio_endio(bio); 140 return BLK_QC_T_NONE; 141} 142 143static const struct block_device_operations axon_ram_devops = { 144 .owner = THIS_MODULE, 145}; 146 147static long 148__axon_ram_direct_access(struct axon_ram_bank *bank, pgoff_t pgoff, long nr_pages, 149 void **kaddr, pfn_t *pfn) 150{ 151 resource_size_t offset = pgoff * PAGE_SIZE; 152 153 *kaddr = (void *) bank->io_addr + offset; 154 *pfn = phys_to_pfn_t(bank->ph_addr + offset, PFN_DEV); 155 return (bank->size - offset) / PAGE_SIZE; 156} 157 158static long 159axon_ram_dax_direct_access(struct dax_device *dax_dev, pgoff_t pgoff, long nr_pages, 160 void **kaddr, pfn_t *pfn) 161{ 162 struct axon_ram_bank *bank = dax_get_private(dax_dev); 163 164 return __axon_ram_direct_access(bank, pgoff, nr_pages, kaddr, pfn); 165} 166 167static size_t axon_ram_copy_from_iter(struct dax_device *dax_dev, pgoff_t pgoff, 168 void *addr, size_t bytes, struct iov_iter *i) 169{ 170 return copy_from_iter(addr, bytes, i); 171} 172 173static const struct dax_operations axon_ram_dax_ops = { 174 .direct_access = axon_ram_dax_direct_access, 175 .copy_from_iter = axon_ram_copy_from_iter, 176}; 177 178/** 179 * axon_ram_probe - probe() method for platform driver 180 * @device: see platform_driver method 181 */ 182static int axon_ram_probe(struct platform_device *device) 183{ 184 static int axon_ram_bank_id = -1; 185 struct axon_ram_bank *bank; 186 struct resource resource; 187 int rc = 0; 188 189 axon_ram_bank_id++; 190 191 dev_info(&device->dev, "Found memory controller on %pOF\n", 192 device->dev.of_node); 193 194 bank = kzalloc(sizeof(*bank), GFP_KERNEL); 195 if (!bank) 196 return -ENOMEM; 197 198 device->dev.platform_data = bank; 199 200 bank->device = device; 201 202 if (of_address_to_resource(device->dev.of_node, 0, &resource) != 0) { 203 dev_err(&device->dev, "Cannot access device tree\n"); 204 rc = -EFAULT; 205 goto failed; 206 } 207 208 bank->size = resource_size(&resource); 209 210 if (bank->size == 0) { 211 dev_err(&device->dev, "No DDR2 memory found for %s%d\n", 212 AXON_RAM_DEVICE_NAME, axon_ram_bank_id); 213 rc = -ENODEV; 214 goto failed; 215 } 216 217 dev_info(&device->dev, "Register DDR2 memory device %s%d with %luMB\n", 218 AXON_RAM_DEVICE_NAME, axon_ram_bank_id, bank->size >> 20); 219 220 bank->ph_addr = resource.start; 221 bank->io_addr = (unsigned long) ioremap_prot( 222 bank->ph_addr, bank->size, _PAGE_NO_CACHE); 223 if (bank->io_addr == 0) { 224 dev_err(&device->dev, "ioremap() failed\n"); 225 rc = -EFAULT; 226 goto failed; 227 } 228 229 bank->disk = alloc_disk(AXON_RAM_MINORS_PER_DISK); 230 if (bank->disk == NULL) { 231 dev_err(&device->dev, "Cannot register disk\n"); 232 rc = -EFAULT; 233 goto failed; 234 } 235 236 237 bank->disk->major = azfs_major; 238 bank->disk->first_minor = azfs_minor; 239 bank->disk->fops = &axon_ram_devops; 240 bank->disk->private_data = bank; 241 242 sprintf(bank->disk->disk_name, "%s%d", 243 AXON_RAM_DEVICE_NAME, axon_ram_bank_id); 244 245 bank->dax_dev = alloc_dax(bank, bank->disk->disk_name, 246 &axon_ram_dax_ops); 247 if (!bank->dax_dev) { 248 rc = -ENOMEM; 249 goto failed; 250 } 251 252 bank->disk->queue = blk_alloc_queue(GFP_KERNEL); 253 if (bank->disk->queue == NULL) { 254 dev_err(&device->dev, "Cannot register disk queue\n"); 255 rc = -EFAULT; 256 goto failed; 257 } 258 259 set_capacity(bank->disk, bank->size >> AXON_RAM_SECTOR_SHIFT); 260 blk_queue_make_request(bank->disk->queue, axon_ram_make_request); 261 blk_queue_logical_block_size(bank->disk->queue, AXON_RAM_SECTOR_SIZE); 262 device_add_disk(&device->dev, bank->disk); 263 264 bank->irq_id = irq_of_parse_and_map(device->dev.of_node, 0); 265 if (!bank->irq_id) { 266 dev_err(&device->dev, "Cannot access ECC interrupt ID\n"); 267 rc = -EFAULT; 268 goto failed; 269 } 270 271 rc = request_irq(bank->irq_id, axon_ram_irq_handler, 272 AXON_RAM_IRQ_FLAGS, bank->disk->disk_name, device); 273 if (rc != 0) { 274 dev_err(&device->dev, "Cannot register ECC interrupt handler\n"); 275 bank->irq_id = 0; 276 rc = -EFAULT; 277 goto failed; 278 } 279 280 rc = device_create_file(&device->dev, &dev_attr_ecc); 281 if (rc != 0) { 282 dev_err(&device->dev, "Cannot create sysfs file\n"); 283 rc = -EFAULT; 284 goto failed; 285 } 286 287 azfs_minor += bank->disk->minors; 288 289 return 0; 290 291failed: 292 if (bank->irq_id) 293 free_irq(bank->irq_id, device); 294 if (bank->disk != NULL) { 295 if (bank->disk->major > 0) 296 unregister_blkdev(bank->disk->major, 297 bank->disk->disk_name); 298 if (bank->disk->flags & GENHD_FL_UP) 299 del_gendisk(bank->disk); 300 put_disk(bank->disk); 301 } 302 kill_dax(bank->dax_dev); 303 put_dax(bank->dax_dev); 304 device->dev.platform_data = NULL; 305 if (bank->io_addr != 0) 306 iounmap((void __iomem *) bank->io_addr); 307 kfree(bank); 308 return rc; 309} 310 311/** 312 * axon_ram_remove - remove() method for platform driver 313 * @device: see of_platform_driver method 314 */ 315static int 316axon_ram_remove(struct platform_device *device) 317{ 318 struct axon_ram_bank *bank = device->dev.platform_data; 319 320 BUG_ON(!bank || !bank->disk); 321 322 device_remove_file(&device->dev, &dev_attr_ecc); 323 free_irq(bank->irq_id, device); 324 kill_dax(bank->dax_dev); 325 put_dax(bank->dax_dev); 326 del_gendisk(bank->disk); 327 put_disk(bank->disk); 328 iounmap((void __iomem *) bank->io_addr); 329 kfree(bank); 330 331 return 0; 332} 333 334static const struct of_device_id axon_ram_device_id[] = { 335 { 336 .type = "dma-memory" 337 }, 338 {} 339}; 340MODULE_DEVICE_TABLE(of, axon_ram_device_id); 341 342static struct platform_driver axon_ram_driver = { 343 .probe = axon_ram_probe, 344 .remove = axon_ram_remove, 345 .driver = { 346 .name = AXON_RAM_MODULE_NAME, 347 .of_match_table = axon_ram_device_id, 348 }, 349}; 350 351/** 352 * axon_ram_init 353 */ 354static int __init 355axon_ram_init(void) 356{ 357 azfs_major = register_blkdev(azfs_major, AXON_RAM_DEVICE_NAME); 358 if (azfs_major < 0) { 359 printk(KERN_ERR "%s cannot become block device major number\n", 360 AXON_RAM_MODULE_NAME); 361 return -EFAULT; 362 } 363 azfs_minor = 0; 364 365 return platform_driver_register(&axon_ram_driver); 366} 367 368/** 369 * axon_ram_exit 370 */ 371static void __exit 372axon_ram_exit(void) 373{ 374 platform_driver_unregister(&axon_ram_driver); 375 unregister_blkdev(azfs_major, AXON_RAM_DEVICE_NAME); 376} 377 378module_init(axon_ram_init); 379module_exit(axon_ram_exit); 380 381MODULE_LICENSE("GPL"); 382MODULE_AUTHOR("Maxim Shchetynin <maxim@de.ibm.com>"); 383MODULE_DESCRIPTION("Axon DDR2 RAM device driver for IBM Cell BE");