Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  * OPAL PNOR flash MTD abstraction
0004  *
0005  * Copyright IBM 2015
0006  */
0007 
0008 #include <linux/kernel.h>
0009 #include <linux/module.h>
0010 #include <linux/errno.h>
0011 #include <linux/of.h>
0012 #include <linux/of_address.h>
0013 #include <linux/platform_device.h>
0014 #include <linux/string.h>
0015 #include <linux/slab.h>
0016 #include <linux/mtd/mtd.h>
0017 #include <linux/mtd/partitions.h>
0018 
0019 #include <linux/debugfs.h>
0020 #include <linux/seq_file.h>
0021 
0022 #include <asm/opal.h>
0023 
0024 
0025 /*
0026  * This driver creates the a Linux MTD abstraction for platform PNOR flash
0027  * backed by OPAL calls
0028  */
0029 
0030 struct powernv_flash {
0031     struct mtd_info mtd;
0032     u32 id;
0033 };
0034 
0035 enum flash_op {
0036     FLASH_OP_READ,
0037     FLASH_OP_WRITE,
0038     FLASH_OP_ERASE,
0039 };
0040 
0041 /*
0042  * Don't return -ERESTARTSYS if we can't get a token, the MTD core
0043  * might have split up the call from userspace and called into the
0044  * driver more than once, we'll already have done some amount of work.
0045  */
0046 static int powernv_flash_async_op(struct mtd_info *mtd, enum flash_op op,
0047         loff_t offset, size_t len, size_t *retlen, u_char *buf)
0048 {
0049     struct powernv_flash *info = (struct powernv_flash *)mtd->priv;
0050     struct device *dev = &mtd->dev;
0051     int token;
0052     struct opal_msg msg;
0053     int rc;
0054 
0055     dev_dbg(dev, "%s(op=%d, offset=0x%llx, len=%zu)\n",
0056             __func__, op, offset, len);
0057 
0058     token = opal_async_get_token_interruptible();
0059     if (token < 0) {
0060         if (token != -ERESTARTSYS)
0061             dev_err(dev, "Failed to get an async token\n");
0062         else
0063             token = -EINTR;
0064         return token;
0065     }
0066 
0067     switch (op) {
0068     case FLASH_OP_READ:
0069         rc = opal_flash_read(info->id, offset, __pa(buf), len, token);
0070         break;
0071     case FLASH_OP_WRITE:
0072         rc = opal_flash_write(info->id, offset, __pa(buf), len, token);
0073         break;
0074     case FLASH_OP_ERASE:
0075         rc = opal_flash_erase(info->id, offset, len, token);
0076         break;
0077     default:
0078         WARN_ON_ONCE(1);
0079         opal_async_release_token(token);
0080         return -EIO;
0081     }
0082 
0083     if (rc == OPAL_ASYNC_COMPLETION) {
0084         rc = opal_async_wait_response_interruptible(token, &msg);
0085         if (rc) {
0086             /*
0087              * If we return the mtd core will free the
0088              * buffer we've just passed to OPAL but OPAL
0089              * will continue to read or write from that
0090              * memory.
0091              * It may be tempting to ultimately return 0
0092              * if we're doing a read or a write since we
0093              * are going to end up waiting until OPAL is
0094              * done. However, because the MTD core sends
0095              * us the userspace request in chunks, we need
0096              * it to know we've been interrupted.
0097              */
0098             rc = -EINTR;
0099             if (opal_async_wait_response(token, &msg))
0100                 dev_err(dev, "opal_async_wait_response() failed\n");
0101             goto out;
0102         }
0103         rc = opal_get_async_rc(msg);
0104     }
0105 
0106     /*
0107      * OPAL does mutual exclusion on the flash, it will return
0108      * OPAL_BUSY.
0109      * During firmware updates by the service processor OPAL may
0110      * be (temporarily) prevented from accessing the flash, in
0111      * this case OPAL will also return OPAL_BUSY.
0112      * Both cases aren't errors exactly but the flash could have
0113      * changed, userspace should be informed.
0114      */
0115     if (rc != OPAL_SUCCESS && rc != OPAL_BUSY)
0116         dev_err(dev, "opal_flash_async_op(op=%d) failed (rc %d)\n",
0117                 op, rc);
0118 
0119     if (rc == OPAL_SUCCESS && retlen)
0120         *retlen = len;
0121 
0122     rc = opal_error_code(rc);
0123 out:
0124     opal_async_release_token(token);
0125     return rc;
0126 }
0127 
0128 /**
0129  * powernv_flash_read
0130  * @mtd: the device
0131  * @from: the offset to read from
0132  * @len: the number of bytes to read
0133  * @retlen: the number of bytes actually read
0134  * @buf: the filled in buffer
0135  *
0136  * Returns 0 if read successful, or -ERRNO if an error occurred
0137  */
0138 static int powernv_flash_read(struct mtd_info *mtd, loff_t from, size_t len,
0139          size_t *retlen, u_char *buf)
0140 {
0141     return powernv_flash_async_op(mtd, FLASH_OP_READ, from,
0142             len, retlen, buf);
0143 }
0144 
0145 /**
0146  * powernv_flash_write
0147  * @mtd: the device
0148  * @to: the offset to write to
0149  * @len: the number of bytes to write
0150  * @retlen: the number of bytes actually written
0151  * @buf: the buffer to get bytes from
0152  *
0153  * Returns 0 if write successful, -ERRNO if error occurred
0154  */
0155 static int powernv_flash_write(struct mtd_info *mtd, loff_t to, size_t len,
0156              size_t *retlen, const u_char *buf)
0157 {
0158     return powernv_flash_async_op(mtd, FLASH_OP_WRITE, to,
0159             len, retlen, (u_char *)buf);
0160 }
0161 
0162 /**
0163  * powernv_flash_erase
0164  * @mtd: the device
0165  * @erase: the erase info
0166  * Returns 0 if erase successful or -ERRNO if an error occurred
0167  */
0168 static int powernv_flash_erase(struct mtd_info *mtd, struct erase_info *erase)
0169 {
0170     int rc;
0171 
0172     rc =  powernv_flash_async_op(mtd, FLASH_OP_ERASE, erase->addr,
0173             erase->len, NULL, NULL);
0174     if (rc)
0175         erase->fail_addr = erase->addr;
0176 
0177     return rc;
0178 }
0179 
0180 /**
0181  * powernv_flash_set_driver_info - Fill the mtd_info structure and docg3
0182  * @dev: The device structure
0183  * @mtd: The structure to fill
0184  */
0185 static int powernv_flash_set_driver_info(struct device *dev,
0186         struct mtd_info *mtd)
0187 {
0188     u64 size;
0189     u32 erase_size;
0190     int rc;
0191 
0192     rc = of_property_read_u32(dev->of_node, "ibm,flash-block-size",
0193             &erase_size);
0194     if (rc) {
0195         dev_err(dev, "couldn't get resource block size information\n");
0196         return rc;
0197     }
0198 
0199     rc = of_property_read_u64(dev->of_node, "reg", &size);
0200     if (rc) {
0201         dev_err(dev, "couldn't get resource size information\n");
0202         return rc;
0203     }
0204 
0205     /*
0206      * Going to have to check what details I need to set and how to
0207      * get them
0208      */
0209     mtd->name = devm_kasprintf(dev, GFP_KERNEL, "%pOFP", dev->of_node);
0210     mtd->type = MTD_NORFLASH;
0211     mtd->flags = MTD_WRITEABLE;
0212     mtd->size = size;
0213     mtd->erasesize = erase_size;
0214     mtd->writebufsize = mtd->writesize = 1;
0215     mtd->owner = THIS_MODULE;
0216     mtd->_erase = powernv_flash_erase;
0217     mtd->_read = powernv_flash_read;
0218     mtd->_write = powernv_flash_write;
0219     mtd->dev.parent = dev;
0220     mtd_set_of_node(mtd, dev->of_node);
0221     return 0;
0222 }
0223 
0224 /**
0225  * powernv_flash_probe
0226  * @pdev: platform device
0227  *
0228  * Returns 0 on success, -ENOMEM, -ENXIO on error
0229  */
0230 static int powernv_flash_probe(struct platform_device *pdev)
0231 {
0232     struct device *dev = &pdev->dev;
0233     struct powernv_flash *data;
0234     int ret;
0235 
0236     data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
0237     if (!data)
0238         return -ENOMEM;
0239 
0240     data->mtd.priv = data;
0241 
0242     ret = of_property_read_u32(dev->of_node, "ibm,opal-id", &(data->id));
0243     if (ret) {
0244         dev_err(dev, "no device property 'ibm,opal-id'\n");
0245         return ret;
0246     }
0247 
0248     ret = powernv_flash_set_driver_info(dev, &data->mtd);
0249     if (ret)
0250         return ret;
0251 
0252     dev_set_drvdata(dev, data);
0253 
0254     /*
0255      * The current flash that skiboot exposes is one contiguous flash chip
0256      * with an ffs partition at the start, it should prove easier for users
0257      * to deal with partitions or not as they see fit
0258      */
0259     return mtd_device_register(&data->mtd, NULL, 0);
0260 }
0261 
0262 /**
0263  * op_release - Release the driver
0264  * @pdev: the platform device
0265  *
0266  * Returns 0
0267  */
0268 static int powernv_flash_release(struct platform_device *pdev)
0269 {
0270     struct powernv_flash *data = dev_get_drvdata(&(pdev->dev));
0271 
0272     /* All resources should be freed automatically */
0273     WARN_ON(mtd_device_unregister(&data->mtd));
0274 
0275     return 0;
0276 }
0277 
0278 static const struct of_device_id powernv_flash_match[] = {
0279     { .compatible = "ibm,opal-flash" },
0280     {}
0281 };
0282 
0283 static struct platform_driver powernv_flash_driver = {
0284     .driver     = {
0285         .name       = "powernv_flash",
0286         .of_match_table = powernv_flash_match,
0287     },
0288     .remove     = powernv_flash_release,
0289     .probe      = powernv_flash_probe,
0290 };
0291 
0292 module_platform_driver(powernv_flash_driver);
0293 
0294 MODULE_DEVICE_TABLE(of, powernv_flash_match);
0295 MODULE_LICENSE("GPL");
0296 MODULE_AUTHOR("Cyril Bur <cyril.bur@au1.ibm.com>");
0297 MODULE_DESCRIPTION("MTD abstraction for OPAL flash");