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

plat-ram.c (4790B)


      1// SPDX-License-Identifier: GPL-2.0-or-later
      2/* drivers/mtd/maps/plat-ram.c
      3 *
      4 * (c) 2004-2005 Simtec Electronics
      5 *	http://www.simtec.co.uk/products/SWLINUX/
      6 *	Ben Dooks <ben@simtec.co.uk>
      7 *
      8 * Generic platform device based RAM map
      9*/
     10
     11#include <linux/module.h>
     12#include <linux/types.h>
     13#include <linux/kernel.h>
     14#include <linux/string.h>
     15#include <linux/ioport.h>
     16#include <linux/device.h>
     17#include <linux/slab.h>
     18#include <linux/platform_device.h>
     19
     20#include <linux/mtd/mtd.h>
     21#include <linux/mtd/map.h>
     22#include <linux/mtd/partitions.h>
     23#include <linux/mtd/plat-ram.h>
     24
     25#include <asm/io.h>
     26
     27/* private structure for each mtd platform ram device created */
     28
     29struct platram_info {
     30	struct device		*dev;
     31	struct mtd_info		*mtd;
     32	struct map_info		 map;
     33	struct platdata_mtd_ram	*pdata;
     34};
     35
     36/* to_platram_info()
     37 *
     38 * device private data to struct platram_info conversion
     39*/
     40
     41static inline struct platram_info *to_platram_info(struct platform_device *dev)
     42{
     43	return platform_get_drvdata(dev);
     44}
     45
     46/* platram_setrw
     47 *
     48 * call the platform device's set rw/ro control
     49 *
     50 * to = 0 => read-only
     51 *    = 1 => read-write
     52*/
     53
     54static inline void platram_setrw(struct platram_info *info, int to)
     55{
     56	if (info->pdata == NULL)
     57		return;
     58
     59	if (info->pdata->set_rw != NULL)
     60		(info->pdata->set_rw)(info->dev, to);
     61}
     62
     63/* platram_remove
     64 *
     65 * called to remove the device from the driver's control
     66*/
     67
     68static int platram_remove(struct platform_device *pdev)
     69{
     70	struct platram_info *info = to_platram_info(pdev);
     71
     72	dev_dbg(&pdev->dev, "removing device\n");
     73
     74	if (info == NULL)
     75		return 0;
     76
     77	if (info->mtd) {
     78		mtd_device_unregister(info->mtd);
     79		map_destroy(info->mtd);
     80	}
     81
     82	/* ensure ram is left read-only */
     83
     84	platram_setrw(info, PLATRAM_RO);
     85
     86	kfree(info);
     87
     88	return 0;
     89}
     90
     91/* platram_probe
     92 *
     93 * called from device drive system when a device matching our
     94 * driver is found.
     95*/
     96
     97static int platram_probe(struct platform_device *pdev)
     98{
     99	struct platdata_mtd_ram	*pdata;
    100	struct platram_info *info;
    101	struct resource *res;
    102	int err = 0;
    103
    104	dev_dbg(&pdev->dev, "probe entered\n");
    105
    106	if (dev_get_platdata(&pdev->dev) == NULL) {
    107		dev_err(&pdev->dev, "no platform data supplied\n");
    108		err = -ENOENT;
    109		goto exit_error;
    110	}
    111
    112	pdata = dev_get_platdata(&pdev->dev);
    113
    114	info = kzalloc(sizeof(*info), GFP_KERNEL);
    115	if (info == NULL) {
    116		err = -ENOMEM;
    117		goto exit_error;
    118	}
    119
    120	platform_set_drvdata(pdev, info);
    121
    122	info->dev = &pdev->dev;
    123	info->pdata = pdata;
    124
    125	/* get the resource for the memory mapping */
    126	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
    127	info->map.virt = devm_ioremap_resource(&pdev->dev, res);
    128	if (IS_ERR(info->map.virt)) {
    129		err = PTR_ERR(info->map.virt);
    130		goto exit_free;
    131	}
    132
    133	dev_dbg(&pdev->dev, "got platform resource %p (0x%llx)\n", res,
    134		(unsigned long long)res->start);
    135
    136	/* setup map parameters */
    137
    138	info->map.phys = res->start;
    139	info->map.size = resource_size(res);
    140	info->map.name = pdata->mapname != NULL ?
    141			(char *)pdata->mapname : (char *)pdev->name;
    142	info->map.bankwidth = pdata->bankwidth;
    143
    144	dev_dbg(&pdev->dev, "virt %p, %lu bytes\n", info->map.virt, info->map.size);
    145
    146	simple_map_init(&info->map);
    147
    148	dev_dbg(&pdev->dev, "initialised map, probing for mtd\n");
    149
    150	/* probe for the right mtd map driver
    151	 * supplied by the platform_data struct */
    152
    153	if (pdata->map_probes) {
    154		const char * const *map_probes = pdata->map_probes;
    155
    156		for ( ; !info->mtd && *map_probes; map_probes++)
    157			info->mtd = do_map_probe(*map_probes , &info->map);
    158	}
    159	/* fallback to map_ram */
    160	else
    161		info->mtd = do_map_probe("map_ram", &info->map);
    162
    163	if (info->mtd == NULL) {
    164		dev_err(&pdev->dev, "failed to probe for map_ram\n");
    165		err = -ENOMEM;
    166		goto exit_free;
    167	}
    168
    169	info->mtd->dev.parent = &pdev->dev;
    170
    171	platram_setrw(info, PLATRAM_RW);
    172
    173	/* check to see if there are any available partitions, or whether
    174	 * to add this device whole */
    175
    176	err = mtd_device_parse_register(info->mtd, pdata->probes, NULL,
    177					pdata->partitions,
    178					pdata->nr_partitions);
    179	if (err) {
    180		dev_err(&pdev->dev, "failed to register mtd device\n");
    181		goto exit_free;
    182	}
    183
    184	dev_info(&pdev->dev, "registered mtd device\n");
    185
    186	if (pdata->nr_partitions) {
    187		/* add the whole device. */
    188		err = mtd_device_register(info->mtd, NULL, 0);
    189		if (err) {
    190			dev_err(&pdev->dev,
    191				"failed to register the entire device\n");
    192			goto exit_free;
    193		}
    194	}
    195
    196	return 0;
    197
    198 exit_free:
    199	platram_remove(pdev);
    200 exit_error:
    201	return err;
    202}
    203
    204/* device driver info */
    205
    206/* work with hotplug and coldplug */
    207MODULE_ALIAS("platform:mtd-ram");
    208
    209static struct platform_driver platram_driver = {
    210	.probe		= platram_probe,
    211	.remove		= platram_remove,
    212	.driver		= {
    213		.name	= "mtd-ram",
    214	},
    215};
    216
    217module_platform_driver(platram_driver);
    218
    219MODULE_LICENSE("GPL");
    220MODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>");
    221MODULE_DESCRIPTION("MTD platform RAM map driver");