mtd/drivers/mtd/maps ich2rom.c,1.7,1.8 amd76xrom.c,1.8,1.9

Thayne Harbaugh tharbaugh at lnxi.com
Thu Oct 23 19:11:02 EDT 2003


Update of /home/cvs/mtd/drivers/mtd/maps
In directory phoenix.infradead.org:/tmp/cvs-serv26025/drivers/mtd/maps

Modified Files:
	ich2rom.c amd76xrom.c 
Log Message:
register resources in iomem

Index: ich2rom.c
===================================================================
RCS file: /home/cvs/mtd/drivers/mtd/maps/ich2rom.c,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -r1.7 -r1.8
--- ich2rom.c	21 May 2003 12:45:18 -0000	1.7
+++ ich2rom.c	23 Oct 2003 23:10:59 -0000	1.8
@@ -16,6 +16,12 @@
 #include <linux/pci.h>
 #include <linux/pci_ids.h>
 
+#define xstr(s) str(s)
+#define str(s) #s
+#define MOD_NAME xstr(KBUILD_BASENAME)
+
+#define MTD_DEV_NAME_LENGTH 16
+
 #define RESERVE_MEM_REGION 0
 
 #define ICH2_FWH_REGION_START	0xFF000000UL
@@ -30,6 +36,10 @@
 	struct map_info map;
 	struct mtd_info *mtd;
 	unsigned long window_addr;
+	struct pci_dev *pdev;
+	struct resource window_rsrc;
+	struct resource rom_rsrc;
+	char mtd_name[MTD_DEV_NAME_LENGTH];
 };
 
 static inline unsigned long addr(struct map_info *map, unsigned long ofs)
@@ -92,7 +102,7 @@
 
 static struct ich2rom_map_info ich2rom_map = {
 	.map = {
-		.name = "ICH2 rom",
+		.name = MOD_NAME,
 		.phys = NO_XIP,
 		.size = 0,
 		.buswidth = 1,
@@ -105,12 +115,11 @@
 		.write32 = ich2rom_write32,
 		.copy_to = ich2rom_copy_to,
 		/* Firmware hubs only use vpp when being programmed
-		 * in a factory setting.  So in place programming
+		 * in a factory setting.  So in-place programming
 		 * needs to use a different method.
 		 */
 	},
-	.mtd = 0,
-	.window_addr = 0,
+	/* remaining fields of structure are initialized to 0 */
 };
 
 enum fwh_lock_state {
@@ -119,6 +128,32 @@
 	FWH_DENY_READ  = 4,
 };
 
+static void ich2rom_cleanup(struct ich2rom_map_info *info)
+{
+	u16 word;
+
+	/* Disable writes through the rom window */
+	pci_read_config_word(info->pdev, BIOS_CNTL, &word);
+	pci_write_config_word(info->pdev, BIOS_CNTL, word & ~1);
+
+	if (info->mtd) {
+		del_mtd_device(info->mtd);
+		map_destroy(info->mtd);
+		info->mtd = NULL;
+		info->map.virt = 0;
+	}
+	if (info->rom_rsrc.parent)
+		release_resource(&info->rom_rsrc);
+	if (info->window_rsrc.parent)
+		release_resource(&info->window_rsrc);
+
+	if (info->window_addr) {
+		iounmap((void *)(info->window_addr));
+		info->window_addr = 0;
+	}
+}
+
+
 static int ich2rom_set_lock_state(struct mtd_info *mtd, loff_t ofs, size_t len,
 	enum fwh_lock_state state)
 {
@@ -167,15 +202,24 @@
 	 * but don't currently handle that case either.
 	 */
 
-#if RESERVE_MEM_REGION
-	/* Some boards have this reserved and I haven't found a good work
-	 * around to say I know what I'm doing!
+	info->pdev = pdev;
+
+	/*
+	 * Try to reserve the window mem region.  If this fails then
+	 * it is likely due to the window being "reseved" by the BIOS.
 	 */
-	if (!request_mem_region(ICH2_FWH_REGION_START, ICH2_FWH_REGION_SIZE, "ich2rom")) {
-		printk(KERN_ERR "ich2rom: cannot reserve rom window\n");
-		goto err_out_none;
+	info->window_rsrc.name = MOD_NAME;
+	info->window_rsrc.start = ICH2_FWH_REGION_START;
+	info->window_rsrc.end = ICH2_FWH_REGION_START + ICH2_FWH_REGION_SIZE - 1;
+	info->window_rsrc.flags = IORESOURCE_MEM | IORESOURCE_BUSY;
+	if (request_resource(&iomem_resource, &info->window_rsrc)) {
+		info->window_rsrc.parent = NULL;
+		printk(KERN_ERR MOD_NAME
+		       " %s(): Unable to register resource"
+		       " 0x%.08lx-0x%.08lx - kernel bug?\n",
+		       __func__,
+		       info->window_rsrc.start, info->window_rsrc.end);
 	}
-#endif /* RESERVE_MEM_REGION */
 	
 	/* Enable writes through the rom window */
 	pci_read_config_word(pdev, BIOS_CNTL, &word);
@@ -183,19 +227,19 @@
 		/* The BIOS will generate an error if I enable
 		 * this device, so don't even try.
 		 */
-		printk(KERN_ERR "ich2rom: firmware access control, I can't enable writes\n");
-		goto err_out_none;
+		printk(KERN_ERR MOD_NAME ": firmware access control, I can't enable writes\n");
+		goto failed;
 	}
 	pci_write_config_word(pdev, BIOS_CNTL, word | 1);
 
 
 	/* Map the firmware hub into my address space. */
-	/* Does this use to much virtual address space? */
+	/* Does this use too much virtual address space? */
 	info->window_addr = (unsigned long)ioremap(
 		ICH2_FWH_REGION_START, ICH2_FWH_REGION_SIZE);
 	if (!info->window_addr) {
 		printk(KERN_ERR "Failed to ioremap\n");
-		goto err_out_free_mmio_region;
+		goto failed;
 	}
 
 	/* For now assume the firmware has setup all relevant firmware
@@ -206,7 +250,7 @@
 	/* FIXME select the firmware hub and enable a window to it. */
 
 	info->mtd = 0;
-	info->map.map_priv_1 = 	info->window_addr;
+	info->map.map_priv_1 = info->window_addr;
 
 	map_size = ICH2_FWH_REGION_SIZE;
 	while(!info->mtd && (map_size > 0)) {
@@ -215,7 +259,7 @@
 		map_size -= 512*1024;
 	}
 	if (!info->mtd) {
-		goto err_out_iounmap;
+		goto failed;
 	}
 	/* I know I can only be a firmware hub here so put
 	 * in the special lock and unlock routines.
@@ -225,15 +269,33 @@
 		
 	info->mtd->owner = THIS_MODULE;
 	add_mtd_device(info->mtd);
+
+	if (info->window_rsrc.parent) {
+		/*
+		 * Registering the MTD device in iomem may not be possible
+		 * if there is a BIOS "reserved" and BUSY range.  If this
+		 * fails then continue anyway.
+		 */
+		snprintf(info->mtd_name, MTD_DEV_NAME_LENGTH,
+			 "mtd%d", info->mtd->index);
+
+		info->rom_rsrc.name = info->mtd_name;
+		info->rom_rsrc.start = ICH2_FWH_REGION_START
+			+ ICH2_FWH_REGION_SIZE - map_size;
+		info->rom_rsrc.end = ICH2_FWH_REGION_START
+			+ ICH2_FWH_REGION_SIZE;
+		info->rom_rsrc.flags = IORESOURCE_MEM | IORESOURCE_BUSY;
+		if (request_resource(&info->window_rsrc, &info->rom_rsrc)) {
+			printk(KERN_ERR MOD_NAME
+			       ": cannot reserve MTD resource\n");
+			info->rom_rsrc.parent = NULL;
+		}
+	}
+
 	return 0;
 
-err_out_iounmap:
-	iounmap((void *)(info->window_addr));
-err_out_free_mmio_region:
-#if RESERVE_MEM_REGION
-	release_mem_region(ICH2_FWH_REGION_START, ICH2_FWH_REGION_SIZE);
-#endif
-err_out_none:
+ failed:
+	ich2rom_cleanup(info);
 	return -ENODEV;
 }
 
@@ -274,7 +336,7 @@
 
 #if 0
 static struct pci_driver ich2rom_driver = {
-	.name =		"ich2rom",
+	.name =		MOD_NAME,
 	.id_table =	ich2rom_pci_tbl,
 	.probe =	ich2rom_init_one,
 	.remove =	ich2rom_remove_one,

Index: amd76xrom.c
===================================================================
RCS file: /home/cvs/mtd/drivers/mtd/maps/amd76xrom.c,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -r1.8 -r1.9
--- amd76xrom.c	28 May 2003 15:44:28 -0000	1.8
+++ amd76xrom.c	23 Oct 2003 23:10:59 -0000	1.9
@@ -17,25 +17,60 @@
 #include <linux/pci_ids.h>
 
 
+#define xstr(s) str(s)
+#define str(s) #s
+#define MOD_NAME xstr(KBUILD_BASENAME)
+
+#define MTD_DEV_NAME_LENGTH 16
+
 struct amd76xrom_map_info {
 	struct map_info map;
 	struct mtd_info *mtd;
 	unsigned long window_addr;
 	u32 window_start, window_size;
 	struct pci_dev *pdev;
+	struct resource window_rsrc;
+	struct resource rom_rsrc;
+	char mtd_name[MTD_DEV_NAME_LENGTH];
 };
 
 
 static struct amd76xrom_map_info amd76xrom_map = {
 	.map = {
-		.name = "AMD76X rom",
+		.name = MOD_NAME,
 		.size = 0,
 		.buswidth = 1,
-	},
-	.mtd = 0,
-	.window_addr = 0,
+	}
+	/* remaining fields of structure are initialized to 0 */
 };
 
+
+static void amd76xrom_cleanup(struct amd76xrom_map_info *info)
+{
+	u8 byte;
+
+	/* Disable writes through the rom window */
+	pci_read_config_byte(info->pdev, 0x40, &byte);
+	pci_write_config_byte(info->pdev, 0x40, byte & ~1);
+
+	if (info->mtd) {
+		del_mtd_device(info->mtd);
+		map_destroy(info->mtd);
+		info->mtd = NULL;
+		info->map.virt = 0;
+	}
+	if (info->rom_rsrc.parent)
+		release_resource(&info->rom_rsrc);
+	if (info->window_rsrc.parent)
+		release_resource(&info->window_rsrc);
+
+	if (info->window_addr) {
+		iounmap((void *)(info->window_addr));
+		info->window_addr = 0;
+	}
+}
+
+
 static int __devinit amd76xrom_init_one (struct pci_dev *pdev,
 	const struct pci_device_id *ent)
 {
@@ -45,6 +80,10 @@
 		u8 segen_bits;
 	};
 	static struct rom_window rom_window[] = {
+		/*
+		 * Need the 5MiB window for chips that have block lock/unlock
+		 * registers located below 4MiB window.
+		 */
 		{ 0xffb00000, 5*1024*1024, (1<<7) | (1<<6), },
 		{ 0xffc00000, 4*1024*1024, (1<<7), },
 		{ 0xffff0000, 64*1024,     0 },
@@ -60,80 +99,128 @@
 	int i;
 	u32 rom_size;
 
+	info->pdev = pdev;
 	window = &rom_window[0];
 
-	/* disabled because it fights with BIOS reserved regions */
-#define REQUEST_MEM_REGION 0
-#if REQUEST_MEM_REGION
-	while(window->size) {
-		if (request_mem_region(window->start, window->size, "amd76xrom")) {
-			break;
+	while (window->size) {
+		/*
+		 * Try to reserve the window mem region.  If this fails then
+		 * it is likely due to a fragment of the window being
+		 * "reseved" by the BIOS.  In the case that the
+		 * request_mem_region() fails then once the rom size is
+		 * discovered we will try to reserve the unreserved fragment.
+		 */
+		info->window_rsrc.name = MOD_NAME;
+		info->window_rsrc.start = window->start;
+		info->window_rsrc.end = window->start + window->size - 1;
+		info->window_rsrc.flags = IORESOURCE_MEM | IORESOURCE_BUSY;
+		if (request_resource(&iomem_resource, &info->window_rsrc)) {
+			info->window_rsrc.parent = NULL;
+			printk(KERN_ERR MOD_NAME
+			       " %s(): Unable to register resource"
+			       " 0x%.08lx-0x%.08lx - kernel bug?\n",
+			       __func__,
+			       info->window_rsrc.start, info->window_rsrc.end);
 		}
-		window++;
-	}
-	if (!window->size) {
-		printk(KERN_ERR "amd76xrom: cannot reserve rom window\n");
-		goto err_out_none;
-	}
-#endif /* REQUEST_MEM_REGION */
-
-	/* Enable the selected rom window */
-	pci_read_config_byte(pdev, 0x43, &byte);
-	pci_write_config_byte(pdev, 0x43, byte | window->segen_bits);
-
-	/* Enable writes through the rom window */
-	pci_read_config_byte(pdev, 0x40, &byte);
-	pci_write_config_byte(pdev, 0x40, byte | 1);
-
-	/* FIXME handle registers 0x80 - 0x8C the bios region locks */
-
-	printk(KERN_NOTICE "amd76xrom window : %x at %x\n", 
-		window->size, window->start);
-	/* For write accesses caches are useless */
-	info->window_addr = (unsigned long)ioremap_nocache(window->start, window->size);
-
-	if (!info->window_addr) {
-		printk(KERN_ERR "Failed to ioremap\n");
-		goto err_out_free_mmio_region;
-	}
-	info->mtd = 0;
-	for(i = 0; (rom_size = rom_probe_sizes[i]); i++) {
-		char **chip_type;
-		if (rom_size > window->size) {
+
+		/* Enable the selected rom window */
+		pci_read_config_byte(pdev, 0x43, &byte);
+		pci_write_config_byte(pdev, 0x43, byte | window->segen_bits);
+
+		/* Enable writes through the rom window */
+		pci_read_config_byte(pdev, 0x40, &byte);
+		pci_write_config_byte(pdev, 0x40, byte | 1);
+
+		/* FIXME handle registers 0x80 - 0x8C the bios region locks */
+
+		printk(KERN_NOTICE MOD_NAME " window : %x at %x\n", 
+		       window->size, window->start);
+		/* For write accesses caches are useless */
+		info->window_addr =
+			(unsigned long)ioremap_nocache(window->start,
+						       window->size);
+
+		if (!info->window_addr) {
+			printk(KERN_ERR "Failed to ioremap\n");
 			continue;
 		}
-		info->map.phys = window->start + window->size - rom_size;
-		info->map.virt = 
-			info->window_addr + window->size - rom_size;
-		info->map.size = rom_size;
-		simple_map_init(&info->map);
-		chip_type = rom_probe_types;
-		for(; !info->mtd && *chip_type; chip_type++) {
-			info->mtd = do_map_probe(*chip_type, &amd76xrom_map.map);
-		}
-		if (info->mtd) {
-			break;
+
+		info->mtd = NULL;
+
+		for(i = 0; (rom_size = rom_probe_sizes[i]); i++) {
+			char **chip_type;
+			if (rom_size > window->size) {
+				continue;
+			}
+			info->map.phys = window->start + window->size - rom_size;
+			info->map.virt = 
+				info->window_addr + window->size - rom_size;
+			info->map.size = rom_size;
+			simple_map_init(&info->map);
+			chip_type = rom_probe_types;
+			for(; !info->mtd && *chip_type; chip_type++) {
+				info->mtd = do_map_probe(*chip_type, &amd76xrom_map.map);
+			}
+			if (info->mtd) goto found_mtd;
 		}
+		iounmap((void *)(info->window_addr));
+		info->window_addr = 0;
+
+		/* Disable writes through the rom window */
+		pci_read_config_byte(pdev, 0x40, &byte);
+		pci_write_config_byte(pdev, 0x40, byte & ~1);
+
+		window++;
 	}
-	if (!info->mtd) {
-		goto err_out_iounmap;
-	}
-	printk(KERN_NOTICE "amd76xrom chip at offset: 0x%x\n",
+	goto failed;
+
+ found_mtd:
+	printk(KERN_NOTICE MOD_NAME " chip at offset: 0x%x\n",
 		window->size - rom_size);
-		
+
 	info->mtd->owner = THIS_MODULE;
+
+	if (!info->window_rsrc.parent) {
+		/* failed to reserve entire window - try fragments */
+		info->window_rsrc.name = MOD_NAME;
+		info->window_rsrc.start = window->start;
+		info->window_rsrc.end = window->start + window->size - rom_size - 1;
+		info->window_rsrc.flags = IORESOURCE_MEM | IORESOURCE_BUSY;
+		if (request_resource(&iomem_resource, &info->window_rsrc)) {
+			printk(KERN_ERR MOD_NAME
+			       ": cannot reserve window resource fragment\n");
+			goto failed;
+		}
+	}
+
 	add_mtd_device(info->mtd);
 	info->window_start = window->start;
 	info->window_size = window->size;
+
+	if (info->window_rsrc.parent) {
+		/*
+		 * Registering the MTD device in iomem may not be possible
+		 * if there is a BIOS "reserved" and BUSY range.  If this
+		 * fails then continue anyway.
+		 */
+		snprintf(info->mtd_name, MTD_DEV_NAME_LENGTH,
+			 "mtd%d", info->mtd->index);
+
+		info->rom_rsrc.name = info->mtd_name;
+		info->rom_rsrc.start = window->start + window->size - rom_size;
+		info->rom_rsrc.end = window->start + window->size - 1;
+		info->rom_rsrc.flags = IORESOURCE_MEM | IORESOURCE_BUSY;
+		if (request_resource(&info->window_rsrc, &info->rom_rsrc)) {
+			printk(KERN_ERR MOD_NAME
+			       ": cannot reserve MTD resource\n");
+			info->rom_rsrc.parent = NULL;
+		}
+	}
+
 	return 0;
 
-err_out_iounmap:
-	iounmap((void *)(info->window_addr));
-err_out_free_mmio_region:
-#if REQUEST_MEM_REGION
-	release_mem_region(window->start, window->size);
-err_out_none:
-#endif /* REQUEST_MEM_REGION */
+ failed:
+	amd76xrom_cleanup(info);
 	return -ENODEV;
 }
 
@@ -141,23 +228,8 @@
 static void __devexit amd76xrom_remove_one (struct pci_dev *pdev)
 {
 	struct amd76xrom_map_info *info = &amd76xrom_map;
-	u8 byte;
-
-	del_mtd_device(info->mtd);
-	map_destroy(info->mtd);
-	info->mtd = 0;
-	info->map.virt = 0;
-
-	iounmap((void *)(info->window_addr));
-	info->window_addr = 0;
-
-	/* Disable writes through the rom window */
-	pci_read_config_byte(pdev, 0x40, &byte);
-	pci_write_config_byte(pdev, 0x40, byte & ~1);
 
-#if REQUEST_MEM_REGION
-	release_mem_region(info->window_start, info->window_size);
-#endif /* REQUEST_MEM_REGION */
+	amd76xrom_cleanup(info);
 }
 
 static struct pci_device_id amd76xrom_pci_tbl[] __devinitdata = {
@@ -173,7 +245,7 @@
 
 #if 0
 static struct pci_driver amd76xrom_driver = {
-	.name =		"amd76xrom",
+	.name =		MOD_NAME,
 	.id_table =	amd76xrom_pci_tbl,
 	.probe =	amd76xrom_init_one,
 	.remove =	amd76xrom_remove_one,




More information about the linux-mtd-cvs mailing list