Lines Matching +full:mtd +full:- +full:ram

1 // SPDX-License-Identifier: GPL-2.0-only
3 * PMC551 PCI Mezzanine Ram Device
10 * This driver is intended to support the PMC551 PCI Ram device
15 * implements this PCI Ram device as an MTD (Memory Technology
28 * of ram configured (making a grand total of 256MiB onboard).
34 * the ram will cause the driver to detect the onboard memory
49 * Most of the MTD code for this driver was originally written
50 * for the slram.o module in the MTD drivers package which
51 * allows the mapping of system memory into an MTD device.
93 #include <linux/mtd/mtd.h>
96 "Ramix PMC551 PCI Mezzanine Ram Driver. (C) 1999,2000 Nortel Networks.\n"
132 static int pmc551_point(struct mtd_info *mtd, loff_t from, size_t len,
135 static int pmc551_erase(struct mtd_info *mtd, struct erase_info *instr) in pmc551_erase() argument
137 struct mypriv *priv = mtd->priv; in pmc551_erase()
145 printk(KERN_DEBUG "pmc551_erase(pos:%ld, len:%ld)\n", (long)instr->addr, in pmc551_erase()
146 (long)instr->len); in pmc551_erase()
149 end = instr->addr + instr->len - 1; in pmc551_erase()
150 eoff_hi = end & ~(priv->asize - 1); in pmc551_erase()
151 soff_hi = instr->addr & ~(priv->asize - 1); in pmc551_erase()
152 eoff_lo = end & (priv->asize - 1); in pmc551_erase()
154 pmc551_point(mtd, instr->addr, instr->len, &retlen, in pmc551_erase()
157 if (soff_hi == eoff_hi || mtd->size == priv->asize) { in pmc551_erase()
160 memset(ptr, 0xff, instr->len); in pmc551_erase()
169 memset(ptr, 0xff, priv->asize); in pmc551_erase()
170 if (soff_hi + priv->asize >= mtd->size) { in pmc551_erase()
173 soff_hi += priv->asize; in pmc551_erase()
174 pmc551_point(mtd, (priv->base_map0 | soff_hi), in pmc551_erase()
175 priv->asize, &retlen, in pmc551_erase()
189 static int pmc551_point(struct mtd_info *mtd, loff_t from, size_t len, in pmc551_point() argument
192 struct mypriv *priv = mtd->priv; in pmc551_point()
200 soff_hi = from & ~(priv->asize - 1); in pmc551_point()
201 soff_lo = from & (priv->asize - 1); in pmc551_point()
204 if (priv->curr_map0 != from) { in pmc551_point()
205 pci_write_config_dword(priv->dev, PMC551_PCI_MEM_MAP0, in pmc551_point()
206 (priv->base_map0 | soff_hi)); in pmc551_point()
207 priv->curr_map0 = soff_hi; in pmc551_point()
210 *virt = priv->start + soff_lo; in pmc551_point()
215 static int pmc551_unpoint(struct mtd_info *mtd, loff_t from, size_t len) in pmc551_unpoint() argument
223 static int pmc551_read(struct mtd_info *mtd, loff_t from, size_t len, in pmc551_read() argument
226 struct mypriv *priv = mtd->priv; in pmc551_read()
235 (long)from, (long)len, (long)priv->asize); in pmc551_read()
238 end = from + len - 1; in pmc551_read()
239 soff_hi = from & ~(priv->asize - 1); in pmc551_read()
240 eoff_hi = end & ~(priv->asize - 1); in pmc551_read()
241 eoff_lo = end & (priv->asize - 1); in pmc551_read()
243 pmc551_point(mtd, from, len, retlen, (void **)&ptr, NULL); in pmc551_read()
258 memcpy(copyto, ptr, priv->asize); in pmc551_read()
259 copyto += priv->asize; in pmc551_read()
260 if (soff_hi + priv->asize >= mtd->size) { in pmc551_read()
263 soff_hi += priv->asize; in pmc551_read()
264 pmc551_point(mtd, soff_hi, priv->asize, retlen, in pmc551_read()
275 *retlen = copyto - buf; in pmc551_read()
279 static int pmc551_write(struct mtd_info *mtd, loff_t to, size_t len, in pmc551_write() argument
282 struct mypriv *priv = mtd->priv; in pmc551_write()
291 (long)to, (long)len, (long)priv->asize); in pmc551_write()
294 end = to + len - 1; in pmc551_write()
295 soff_hi = to & ~(priv->asize - 1); in pmc551_write()
296 eoff_hi = end & ~(priv->asize - 1); in pmc551_write()
297 eoff_lo = end & (priv->asize - 1); in pmc551_write()
299 pmc551_point(mtd, to, len, retlen, (void **)&ptr, NULL); in pmc551_write()
314 memcpy(ptr, copyfrom, priv->asize); in pmc551_write()
315 copyfrom += priv->asize; in pmc551_write()
316 if (soff_hi >= mtd->size) { in pmc551_write()
319 soff_hi += priv->asize; in pmc551_write()
320 pmc551_point(mtd, soff_hi, priv->asize, retlen, in pmc551_write()
331 *retlen = copyfrom - buf; in pmc551_write()
358 return -ENODEV; in fixup_pmc551()
414 size &= ~(size - 1); in fixup_pmc551()
453 return -ENODEV; in fixup_pmc551()
458 return -ENODEV; in fixup_pmc551()
517 * Check to make certain fast back-to-back, if not in fixup_pmc551()
529 * to the memory when memory is read-only in fixup_pmc551()
558 ((dcmd & (0x1 << 3)) == 0) ? "non-" : "", in fixup_pmc551()
616 printk(KERN_DEBUG "pmc551: %sFast Back-to-Back\n", in fixup_pmc551()
644 MODULE_PARM_DESC(msize, "memory size in MiB [1 - 1024]");
646 MODULE_PARM_DESC(asize, "aperture size, must be <= memsize [1-1024]");
656 struct mtd_info *mtd; in init_pmc551() local
660 msize = (1 << (ffs(msize) - 1)) << 20; in init_pmc551()
664 return -EINVAL; in init_pmc551()
669 asize = (1 << (ffs(asize) - 1)) << 20; in init_pmc551()
673 return -EINVAL; in init_pmc551()
680 * PCU-bus chipset probe. in init_pmc551()
696 * some reason the sdram is in a wrote-protected state the in init_pmc551()
718 mtd = kzalloc(sizeof(struct mtd_info), GFP_KERNEL); in init_pmc551()
719 if (!mtd) in init_pmc551()
724 kfree(mtd); in init_pmc551()
727 mtd->priv = priv; in init_pmc551()
728 priv->dev = PCI_Device; in init_pmc551()
733 priv->asize = asize = length; in init_pmc551()
737 priv->asize = asize = length; in init_pmc551()
741 priv->asize = asize; in init_pmc551()
743 priv->start = pci_iomap(PCI_Device, 0, priv->asize); in init_pmc551()
745 if (!priv->start) { in init_pmc551()
747 kfree(mtd->priv); in init_pmc551()
748 kfree(mtd); in init_pmc551()
753 ffs(priv->asize >> 20) - 1); in init_pmc551()
756 priv->base_map0 = (PMC551_PCI_MEM_MAP_REG_EN in init_pmc551()
758 | (ffs(priv->asize >> 20) - 1) << 4); in init_pmc551()
759 priv->curr_map0 = priv->base_map0; in init_pmc551()
760 pci_write_config_dword(priv->dev, PMC551_PCI_MEM_MAP0, in init_pmc551()
761 priv->curr_map0); in init_pmc551()
765 (priv->base_map0 & 0xF0) >> 4); in init_pmc551()
768 mtd->size = msize; in init_pmc551()
769 mtd->flags = MTD_CAP_RAM; in init_pmc551()
770 mtd->_erase = pmc551_erase; in init_pmc551()
771 mtd->_read = pmc551_read; in init_pmc551()
772 mtd->_write = pmc551_write; in init_pmc551()
773 mtd->_point = pmc551_point; in init_pmc551()
774 mtd->_unpoint = pmc551_unpoint; in init_pmc551()
775 mtd->type = MTD_RAM; in init_pmc551()
776 mtd->name = "PMC551 RAM board"; in init_pmc551()
777 mtd->erasesize = 0x10000; in init_pmc551()
778 mtd->writesize = 1; in init_pmc551()
779 mtd->owner = THIS_MODULE; in init_pmc551()
781 if (mtd_device_register(mtd, NULL, 0)) { in init_pmc551()
783 pci_iounmap(PCI_Device, priv->start); in init_pmc551()
784 kfree(mtd->priv); in init_pmc551()
785 kfree(mtd); in init_pmc551()
794 priv->asize >> 20, in init_pmc551()
795 priv->start, priv->start + priv->asize); in init_pmc551()
800 priv->nextpmc551 = pmc551list; in init_pmc551()
801 pmc551list = mtd; in init_pmc551()
810 return -ENODEV; in init_pmc551()
823 struct mtd_info *mtd; in cleanup_pmc551() local
826 while ((mtd = pmc551list)) { in cleanup_pmc551()
827 priv = mtd->priv; in cleanup_pmc551()
828 pmc551list = priv->nextpmc551; in cleanup_pmc551()
830 if (priv->start) { in cleanup_pmc551()
832 "0x%p\n", priv->asize >> 20, priv->start); in cleanup_pmc551()
833 pci_iounmap(priv->dev, priv->start); in cleanup_pmc551()
835 pci_dev_put(priv->dev); in cleanup_pmc551()
837 kfree(mtd->priv); in cleanup_pmc551()
838 mtd_device_unregister(mtd); in cleanup_pmc551()
839 kfree(mtd); in cleanup_pmc551()