cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

generic.c (2788B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/*
      3 *  Copyright (c) 2005 Samsung Electronics
      4 *  Kyungmin Park <kyungmin.park@samsung.com>
      5 *
      6 *  Overview:
      7 *   This is a device driver for the OneNAND flash for generic boards.
      8 */
      9
     10#include <linux/module.h>
     11#include <linux/slab.h>
     12#include <linux/platform_device.h>
     13#include <linux/mtd/mtd.h>
     14#include <linux/mtd/onenand.h>
     15#include <linux/mtd/partitions.h>
     16#include <linux/io.h>
     17
     18/*
     19 * Note: Driver name and platform data format have been updated!
     20 *
     21 * This version of the driver is named "onenand-flash" and takes struct
     22 * onenand_platform_data as platform data. The old ARM-specific version
     23 * with the name "onenand" used to take struct flash_platform_data.
     24 */
     25#define DRIVER_NAME	"onenand-flash"
     26
     27struct onenand_info {
     28	struct mtd_info		mtd;
     29	struct onenand_chip	onenand;
     30};
     31
     32static int generic_onenand_probe(struct platform_device *pdev)
     33{
     34	struct onenand_info *info;
     35	struct onenand_platform_data *pdata = dev_get_platdata(&pdev->dev);
     36	struct resource *res = pdev->resource;
     37	unsigned long size = resource_size(res);
     38	int err;
     39
     40	info = kzalloc(sizeof(struct onenand_info), GFP_KERNEL);
     41	if (!info)
     42		return -ENOMEM;
     43
     44	if (!request_mem_region(res->start, size, dev_name(&pdev->dev))) {
     45		err = -EBUSY;
     46		goto out_free_info;
     47	}
     48
     49	info->onenand.base = ioremap(res->start, size);
     50	if (!info->onenand.base) {
     51		err = -ENOMEM;
     52		goto out_release_mem_region;
     53	}
     54
     55	info->onenand.mmcontrol = pdata ? pdata->mmcontrol : NULL;
     56
     57	err = platform_get_irq(pdev, 0);
     58	if (err < 0)
     59		goto out_iounmap;
     60
     61	info->onenand.irq = err;
     62
     63	info->mtd.dev.parent = &pdev->dev;
     64	info->mtd.priv = &info->onenand;
     65
     66	if (onenand_scan(&info->mtd, 1)) {
     67		err = -ENXIO;
     68		goto out_iounmap;
     69	}
     70
     71	err = mtd_device_register(&info->mtd, pdata ? pdata->parts : NULL,
     72				  pdata ? pdata->nr_parts : 0);
     73
     74	platform_set_drvdata(pdev, info);
     75
     76	return 0;
     77
     78out_iounmap:
     79	iounmap(info->onenand.base);
     80out_release_mem_region:
     81	release_mem_region(res->start, size);
     82out_free_info:
     83	kfree(info);
     84
     85	return err;
     86}
     87
     88static int generic_onenand_remove(struct platform_device *pdev)
     89{
     90	struct onenand_info *info = platform_get_drvdata(pdev);
     91	struct resource *res = pdev->resource;
     92	unsigned long size = resource_size(res);
     93
     94	if (info) {
     95		onenand_release(&info->mtd);
     96		release_mem_region(res->start, size);
     97		iounmap(info->onenand.base);
     98		kfree(info);
     99	}
    100
    101	return 0;
    102}
    103
    104static struct platform_driver generic_onenand_driver = {
    105	.driver = {
    106		.name		= DRIVER_NAME,
    107	},
    108	.probe		= generic_onenand_probe,
    109	.remove		= generic_onenand_remove,
    110};
    111
    112module_platform_driver(generic_onenand_driver);
    113
    114MODULE_LICENSE("GPL");
    115MODULE_AUTHOR("Kyungmin Park <kyungmin.park@samsung.com>");
    116MODULE_DESCRIPTION("Glue layer for OneNAND flash on generic boards");
    117MODULE_ALIAS("platform:" DRIVER_NAME);