--- zzzz-none-000/linux-2.6.39.4/drivers/mtd/mtdblock.c 2011-08-03 19:43:28.000000000 +0000 +++ puma6-atom-6490-729/linux-2.6.39.4/drivers/mtd/mtdblock.c 2021-11-10 13:38:15.000000000 +0000 @@ -29,6 +29,8 @@ #include #include +#include + #include #include #include @@ -36,6 +38,7 @@ struct mtdblk_dev { struct mtd_blktrans_dev mbd; + struct device dev; int count; struct mutex cache_mutex; unsigned char *cache_data; @@ -56,6 +59,61 @@ * being written to until a different sector is required. */ +#ifdef CONFIG_PM +static int mtdblock_dev_suspend(struct device *dev); +static int mtdblock_dev_resume(struct device *dev); + +static struct dev_pm_ops mtdblock_dev_pm = { + .suspend = mtdblock_dev_suspend, + .resume = mtdblock_dev_resume, +}; + +static int mtdblock_dev_suspend(struct device *dev) +{ + struct mtdblk_dev *mtdblk = container_of(dev, struct mtdblk_dev, dev); + + if (mtdblk) { + spin_lock_irq(mtdblk->mbd.rq->queue_lock); + blk_stop_queue(mtdblk->mbd.rq); + spin_unlock_irq(mtdblk->mbd.rq->queue_lock); +#ifdef CONFIG_ARCH_GEN3 + down(&mtdblk->mbd.thread_sem); +#endif + } + return 0; +} + +static int mtdblock_dev_resume(struct device *dev) +{ + struct mtdblk_dev *mtdblk = container_of(dev, struct mtdblk_dev, dev); + + if (mtdblk){ +#ifdef CONFIG_ARCH_GEN3 + up(&mtdblk->mbd.thread_sem); +#endif + spin_lock_irq(mtdblk->mbd.rq->queue_lock); + blk_start_queue(mtdblk->mbd.rq); + spin_unlock_irq(mtdblk->mbd.rq->queue_lock); + } + return 0; +} + +#endif + +static void mtdblk_release(struct device *dev) +{ + return; +} + +static struct class mtdblock_class = { + .name = "mtdblock", + .owner = THIS_MODULE, +#ifdef CONFIG_PM + .pm = &mtdblock_dev_pm, +#endif + .dev_release = mtdblk_release, +}; + static void erase_callback(struct erase_info *done) { wait_queue_head_t *wait_q = (wait_queue_head_t *)done->priv; @@ -359,6 +417,12 @@ dev->mbd.size = mtd->size >> 9; dev->mbd.tr = tr; + + dev->dev.class = &mtdblock_class; + dev_set_name(&dev->dev, "mtdblock%d", mtd->index); + dev_set_drvdata(&dev->dev, dev); + if (device_register(&dev->dev) != 0) + return; if (!(mtd->flags & MTD_WRITEABLE)) dev->mbd.readonly = 1; @@ -369,7 +433,11 @@ static void mtdblock_remove_dev(struct mtd_blktrans_dev *dev) { + struct mtdblk_dev *mtdblk_dev = container_of(dev, struct mtdblk_dev, mbd); + del_mtd_blktrans_dev(dev); + device_unregister(&mtdblk_dev->dev); + dev_set_drvdata(&mtdblk_dev->dev, NULL); } static struct mtd_blktrans_ops mtdblock_tr = { @@ -389,14 +457,20 @@ static int __init init_mtdblock(void) { - mutex_init(&mtdblks_lock); + int ret = 0; + mutex_init(&mtdblks_lock); + + ret = class_register(&mtdblock_class); + if (ret) + return ret; return register_mtd_blktrans(&mtdblock_tr); } static void __exit cleanup_mtdblock(void) { deregister_mtd_blktrans(&mtdblock_tr); + class_unregister(&mtdblock_class); } module_init(init_mtdblock);