cregit-Linux how code gets into the kernel

Release 4.11 drivers/mtd/maps/nettel.c

Directory: drivers/mtd/maps
/****************************************************************************/

/*
 *      nettel.c -- mappings for NETtel/SecureEdge/SnapGear (x86) boards.
 *
 *      (C) Copyright 2000-2001, Greg Ungerer (gerg@snapgear.com)
 *      (C) Copyright 2001-2002, SnapGear (www.snapgear.com)
 */

/****************************************************************************/

#include <linux/module.h>
#include <linux/init.h>
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/map.h>
#include <linux/mtd/partitions.h>
#include <linux/mtd/cfi.h>
#include <linux/reboot.h>
#include <linux/err.h>
#include <linux/kdev_t.h>
#include <linux/root_dev.h>
#include <asm/io.h>

/****************************************************************************/


#define INTEL_BUSWIDTH		1

#define AMD_WINDOW_MAXSIZE	0x00200000

#define AMD_BUSWIDTH	 	1

/*
 *      PAR masks and shifts, assuming 64K pages.
 */

#define SC520_PAR_ADDR_MASK	0x00003fff

#define SC520_PAR_ADDR_SHIFT	16

#define SC520_PAR_TO_ADDR(par) \
	(((par)&SC520_PAR_ADDR_MASK) << SC520_PAR_ADDR_SHIFT)


#define SC520_PAR_SIZE_MASK	0x01ffc000

#define SC520_PAR_SIZE_SHIFT	2

#define SC520_PAR_TO_SIZE(par) \
	((((par)&SC520_PAR_SIZE_MASK) << SC520_PAR_SIZE_SHIFT) + (64*1024))


#define SC520_PAR(cs, addr, size) \
	((cs) | \
        ((((size)-(64*1024)) >> SC520_PAR_SIZE_SHIFT) & SC520_PAR_SIZE_MASK) | \
        (((addr) >> SC520_PAR_ADDR_SHIFT) & SC520_PAR_ADDR_MASK))


#define SC520_PAR_BOOTCS	0x8a000000

#define	SC520_PAR_ROMCS1	0xaa000000

#define SC520_PAR_ROMCS2	0xca000000	
/* Cache disabled, 64K page */


static void *nettel_mmcrp = NULL;

#ifdef CONFIG_MTD_CFI_INTELEXT

static struct mtd_info *intel_mtd;
#endif

static struct mtd_info *amd_mtd;

/****************************************************************************/

/****************************************************************************/

#ifdef CONFIG_MTD_CFI_INTELEXT

static struct map_info nettel_intel_map = {
	.name = "SnapGear Intel",
	.size = 0,
	.bankwidth = INTEL_BUSWIDTH,
};


static struct mtd_partition nettel_intel_partitions[] = {
	{
		.name = "SnapGear kernel",
		.offset = 0,
		.size = 0x000e0000
	},
	{
		.name = "SnapGear filesystem",
		.offset = 0x00100000,
        },
	{
		.name = "SnapGear config",
		.offset = 0x000e0000,
		.size = 0x00020000
	},
	{
		.name = "SnapGear Intel",
		.offset = 0
	},
	{
		.name = "SnapGear BIOS Config",
		.offset = 0x007e0000,
		.size = 0x00020000
	},
	{
		.name = "SnapGear BIOS",
		.offset = 0x007e0000,
		.size = 0x00020000
	},
};
#endif


static struct map_info nettel_amd_map = {
	.name = "SnapGear AMD",
	.size = AMD_WINDOW_MAXSIZE,
	.bankwidth = AMD_BUSWIDTH,
};


static struct mtd_partition nettel_amd_partitions[] = {
	{
		.name = "SnapGear BIOS config",
		.offset = 0x000e0000,
		.size = 0x00010000
	},
	{
		.name = "SnapGear BIOS",
		.offset = 0x000f0000,
		.size = 0x00010000
	},
	{
		.name = "SnapGear AMD",
		.offset = 0
	},
	{
		.name = "SnapGear high BIOS",
		.offset = 0x001f0000,
		.size = 0x00010000
	}
};


#define NUM_AMD_PARTITIONS ARRAY_SIZE(nettel_amd_partitions)

/****************************************************************************/

#ifdef CONFIG_MTD_CFI_INTELEXT

/*
 *      Set the Intel flash back to read mode since some old boot
 *      loaders don't.
 */

static int nettel_reboot_notifier(struct notifier_block *nb, unsigned long val, void *v) { struct cfi_private *cfi = nettel_intel_map.fldrv_priv; unsigned long b; /* Make sure all FLASH chips are put back into read mode */ for (b = 0; (b < nettel_intel_partitions[3].size); b += 0x100000) { cfi_send_gen_cmd(0xff, 0x55, b, &nettel_intel_map, cfi, cfi->device_type, NULL); } return(NOTIFY_OK); }

Contributors

PersonTokensPropCommitsCommitProp
David Woodhouse81100.00%1100.00%
Total81100.00%1100.00%

static struct notifier_block nettel_notifier_block = { nettel_reboot_notifier, NULL, 0 }; #endif /****************************************************************************/
static int __init nettel_init(void) { volatile unsigned long *amdpar; unsigned long amdaddr, maxsize; int num_amd_partitions=0; #ifdef CONFIG_MTD_CFI_INTELEXT volatile unsigned long *intel0par, *intel1par; unsigned long orig_bootcspar, orig_romcs1par; unsigned long intel0addr, intel0size; unsigned long intel1addr, intel1size; int intelboot, intel0cs, intel1cs; int num_intel_partitions; #endif int rc = 0; nettel_mmcrp = (void *) ioremap_nocache(0xfffef000, 4096); if (nettel_mmcrp == NULL) { printk("SNAPGEAR: failed to disable MMCR cache??\n"); return(-EIO); } /* Set CPU clock to be 33.000MHz */ *((unsigned char *) (nettel_mmcrp + 0xc64)) = 0x01; amdpar = (volatile unsigned long *) (nettel_mmcrp + 0xc4); #ifdef CONFIG_MTD_CFI_INTELEXT intelboot = 0; intel0cs = SC520_PAR_ROMCS1; intel0par = (volatile unsigned long *) (nettel_mmcrp + 0xc0); intel1cs = SC520_PAR_ROMCS2; intel1par = (volatile unsigned long *) (nettel_mmcrp + 0xbc); /* * Save the CS settings then ensure ROMCS1 and ROMCS2 are off, * otherwise they might clash with where we try to map BOOTCS. */ orig_bootcspar = *amdpar; orig_romcs1par = *intel0par; *intel0par = 0; *intel1par = 0; #endif /* * The first thing to do is determine if we have a separate * boot FLASH device. Typically this is a small (1 to 2MB) * AMD FLASH part. It seems that device size is about the * only way to tell if this is the case... */ amdaddr = 0x20000000; maxsize = AMD_WINDOW_MAXSIZE; *amdpar = SC520_PAR(SC520_PAR_BOOTCS, amdaddr, maxsize); __asm__ ("wbinvd"); nettel_amd_map.phys = amdaddr; nettel_amd_map.virt = ioremap_nocache(amdaddr, maxsize); if (!nettel_amd_map.virt) { printk("SNAPGEAR: failed to ioremap() BOOTCS\n"); iounmap(nettel_mmcrp); return(-EIO); } simple_map_init(&nettel_amd_map); if ((amd_mtd = do_map_probe("jedec_probe", &nettel_amd_map))) { printk(KERN_NOTICE "SNAPGEAR: AMD flash device size = %dK\n", (int)(amd_mtd->size>>10)); amd_mtd->owner = THIS_MODULE; /* The high BIOS partition is only present for 2MB units */ num_amd_partitions = NUM_AMD_PARTITIONS; if (amd_mtd->size < AMD_WINDOW_MAXSIZE) num_amd_partitions--; /* Don't add the partition until after the primary INTEL's */ #ifdef CONFIG_MTD_CFI_INTELEXT /* * Map the Intel flash into memory after the AMD * It has to start on a multiple of maxsize. */ maxsize = SC520_PAR_TO_SIZE(orig_romcs1par); if (maxsize < (32 * 1024 * 1024)) maxsize = (32 * 1024 * 1024); intel0addr = amdaddr + maxsize; #endif } else { #ifdef CONFIG_MTD_CFI_INTELEXT /* INTEL boot FLASH */ intelboot++; if (!orig_romcs1par) { intel0cs = SC520_PAR_BOOTCS; intel0par = (volatile unsigned long *) (nettel_mmcrp + 0xc4); intel1cs = SC520_PAR_ROMCS1; intel1par = (volatile unsigned long *) (nettel_mmcrp + 0xc0); intel0addr = SC520_PAR_TO_ADDR(orig_bootcspar); maxsize = SC520_PAR_TO_SIZE(orig_bootcspar); } else { /* Kernel base is on ROMCS1, not BOOTCS */ intel0cs = SC520_PAR_ROMCS1; intel0par = (volatile unsigned long *) (nettel_mmcrp + 0xc0); intel1cs = SC520_PAR_BOOTCS; intel1par = (volatile unsigned long *) (nettel_mmcrp + 0xc4); intel0addr = SC520_PAR_TO_ADDR(orig_romcs1par); maxsize = SC520_PAR_TO_SIZE(orig_romcs1par); } /* Destroy useless AMD MTD mapping */ amd_mtd = NULL; iounmap(nettel_amd_map.virt); nettel_amd_map.virt = NULL; #else /* Only AMD flash supported */ rc = -ENXIO; goto out_unmap2; #endif } #ifdef CONFIG_MTD_CFI_INTELEXT /* * We have determined the INTEL FLASH configuration, so lets * go ahead and probe for them now. */ /* Set PAR to the maximum size */ if (maxsize < (32 * 1024 * 1024)) maxsize = (32 * 1024 * 1024); *intel0par = SC520_PAR(intel0cs, intel0addr, maxsize); /* Turn other PAR off so the first probe doesn't find it */ *intel1par = 0; /* Probe for the size of the first Intel flash */ nettel_intel_map.size = maxsize; nettel_intel_map.phys = intel0addr; nettel_intel_map.virt = ioremap_nocache(intel0addr, maxsize); if (!nettel_intel_map.virt) { printk("SNAPGEAR: failed to ioremap() ROMCS1\n"); rc = -EIO; goto out_unmap2; } simple_map_init(&nettel_intel_map); intel_mtd = do_map_probe("cfi_probe", &nettel_intel_map); if (!intel_mtd) { rc = -ENXIO; goto out_unmap1; } /* Set PAR to the detected size */ intel0size = intel_mtd->size; *intel0par = SC520_PAR(intel0cs, intel0addr, intel0size); /* * Map second Intel FLASH right after first. Set its size to the * same maxsize used for the first Intel FLASH. */ intel1addr = intel0addr + intel0size; *intel1par = SC520_PAR(intel1cs, intel1addr, maxsize); __asm__ ("wbinvd"); maxsize += intel0size; /* Delete the old map and probe again to do both chips */ map_destroy(intel_mtd); intel_mtd = NULL; iounmap(nettel_intel_map.virt); nettel_intel_map.size = maxsize; nettel_intel_map.virt = ioremap_nocache(intel0addr, maxsize); if (!nettel_intel_map.virt) { printk("SNAPGEAR: failed to ioremap() ROMCS1/2\n"); rc = -EIO; goto out_unmap2; } intel_mtd = do_map_probe("cfi_probe", &nettel_intel_map); if (! intel_mtd) { rc = -ENXIO; goto out_unmap1; } intel1size = intel_mtd->size - intel0size; if (intel1size > 0) { *intel1par = SC520_PAR(intel1cs, intel1addr, intel1size); __asm__ ("wbinvd"); } else { *intel1par = 0; } printk(KERN_NOTICE "SNAPGEAR: Intel flash device size = %lldKiB\n", (unsigned long long)(intel_mtd->size >> 10)); intel_mtd->owner = THIS_MODULE; num_intel_partitions = ARRAY_SIZE(nettel_intel_partitions); if (intelboot) { /* * Adjust offset and size of last boot partition. * Must allow for BIOS region at end of FLASH. */ nettel_intel_partitions[1].size = (intel0size + intel1size) - (1024*1024 + intel_mtd->erasesize); nettel_intel_partitions[3].size = intel0size + intel1size; nettel_intel_partitions[4].offset = (intel0size + intel1size) - intel_mtd->erasesize; nettel_intel_partitions[4].size = intel_mtd->erasesize; nettel_intel_partitions[5].offset = nettel_intel_partitions[4].offset; nettel_intel_partitions[5].size = nettel_intel_partitions[4].size; } else { /* No BIOS regions when AMD boot */ num_intel_partitions -= 2; } rc = mtd_device_register(intel_mtd, nettel_intel_partitions, num_intel_partitions); if (rc) goto out_map_destroy; #endif if (amd_mtd) { rc = mtd_device_register(amd_mtd, nettel_amd_partitions, num_amd_partitions); if (rc) goto out_mtd_unreg; } #ifdef CONFIG_MTD_CFI_INTELEXT register_reboot_notifier(&nettel_notifier_block); #endif return rc; out_mtd_unreg: #ifdef CONFIG_MTD_CFI_INTELEXT mtd_device_unregister(intel_mtd); out_map_destroy: map_destroy(intel_mtd); out_unmap1: iounmap(nettel_intel_map.virt); #endif out_unmap2: iounmap(nettel_mmcrp); iounmap(nettel_amd_map.virt); return rc; }

Contributors

PersonTokensPropCommitsCommitProp
David Woodhouse94090.04%222.22%
Amol Lad666.32%111.11%
Alexey Khoroshilov282.68%111.11%
Adrian Hunter50.48%111.11%
Jamie Iles20.19%111.11%
Julia Lawall10.10%111.11%
Adrian Bunk10.10%111.11%
Michael Opdenacker10.10%111.11%
Total1044100.00%9100.00%

/****************************************************************************/
static void __exit nettel_cleanup(void) { #ifdef CONFIG_MTD_CFI_INTELEXT unregister_reboot_notifier(&nettel_notifier_block); #endif if (amd_mtd) { mtd_device_unregister(amd_mtd); map_destroy(amd_mtd); } if (nettel_mmcrp) { iounmap(nettel_mmcrp); nettel_mmcrp = NULL; } if (nettel_amd_map.virt) { iounmap(nettel_amd_map.virt); nettel_amd_map.virt = NULL; } #ifdef CONFIG_MTD_CFI_INTELEXT if (intel_mtd) { mtd_device_unregister(intel_mtd); map_destroy(intel_mtd); } if (nettel_intel_map.virt) { iounmap(nettel_intel_map.virt); nettel_intel_map.virt = NULL; } #endif }

Contributors

PersonTokensPropCommitsCommitProp
David Woodhouse9583.33%233.33%
Amol Lad1513.16%116.67%
Jamie Iles21.75%116.67%
Adrian Bunk10.88%116.67%
Luiz Fernando N. Capitulino10.88%116.67%
Total114100.00%6100.00%

/****************************************************************************/ module_init(nettel_init); module_exit(nettel_cleanup); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Greg Ungerer <gerg@snapgear.com>"); MODULE_DESCRIPTION("SnapGear/SecureEdge FLASH support"); /****************************************************************************/

Overall Contributors

PersonTokensPropCommitsCommitProp
David Woodhouse151791.88%425.00%
Amol Lad814.91%16.25%
Alexey Khoroshilov281.70%16.25%
Jesper Juhl60.36%16.25%
Adrian Hunter50.30%16.25%
Jamie Iles40.24%16.25%
Artem B. Bityutskiy30.18%16.25%
Adrian Bunk30.18%212.50%
Tobias Klauser10.06%16.25%
Michael Opdenacker10.06%16.25%
Luiz Fernando N. Capitulino10.06%16.25%
Julia Lawall10.06%16.25%
Total1651100.00%16100.00%
Directory: drivers/mtd/maps
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.
Created with cregit.