diff options
Diffstat (limited to 'drivers/mtd/maps')
-rw-r--r-- | drivers/mtd/maps/Kconfig | 71 | ||||
-rw-r--r-- | drivers/mtd/maps/Makefile | 4 | ||||
-rw-r--r-- | drivers/mtd/maps/amd76xrom.c | 34 | ||||
-rw-r--r-- | drivers/mtd/maps/bast-flash.c | 2 | ||||
-rw-r--r-- | drivers/mtd/maps/ceiva.c | 3 | ||||
-rw-r--r-- | drivers/mtd/maps/ck804xrom.c | 356 | ||||
-rw-r--r-- | drivers/mtd/maps/cstm_mips_ixx.c | 283 | ||||
-rw-r--r-- | drivers/mtd/maps/esb2rom.c | 450 | ||||
-rw-r--r-- | drivers/mtd/maps/integrator-flash.c | 4 | ||||
-rw-r--r-- | drivers/mtd/maps/nettel.c | 5 | ||||
-rw-r--r-- | drivers/mtd/maps/omap_nor.c | 4 | ||||
-rw-r--r-- | drivers/mtd/maps/pcmciamtd.c | 3 | ||||
-rw-r--r-- | drivers/mtd/maps/physmap.c | 5 | ||||
-rw-r--r-- | drivers/mtd/maps/physmap_of.c | 255 | ||||
-rw-r--r-- | drivers/mtd/maps/plat-ram.c | 3 | ||||
-rw-r--r-- | drivers/mtd/maps/sa1100-flash.c | 4 | ||||
-rw-r--r-- | drivers/mtd/maps/tqm834x.c | 8 | ||||
-rw-r--r-- | drivers/mtd/maps/tqm8xxl.c | 3 |
18 files changed, 1134 insertions, 363 deletions
diff --git a/drivers/mtd/maps/Kconfig b/drivers/mtd/maps/Kconfig index d132ed571f13..f457315579db 100644 --- a/drivers/mtd/maps/Kconfig +++ b/drivers/mtd/maps/Kconfig | |||
@@ -60,6 +60,15 @@ config MTD_PHYSMAP_BANKWIDTH | |||
60 | Ignore this option if you use run-time physmap configuration | 60 | Ignore this option if you use run-time physmap configuration |
61 | (i.e., run-time calling physmap_configure()). | 61 | (i.e., run-time calling physmap_configure()). |
62 | 62 | ||
63 | config MTD_PHYSMAP_OF | ||
64 | tristate "Flash device in physical memory map based on OF descirption" | ||
65 | depends on PPC_OF && (MTD_CFI || MTD_JEDECPROBE || MTD_ROM) | ||
66 | help | ||
67 | This provides a 'mapping' driver which allows the NOR Flash and | ||
68 | ROM driver code to communicate with chips which are mapped | ||
69 | physically into the CPU's memory. The mapping description here is | ||
70 | taken from OF device tree. | ||
71 | |||
63 | config MTD_SUN_UFLASH | 72 | config MTD_SUN_UFLASH |
64 | tristate "Sun Microsystems userflash support" | 73 | tristate "Sun Microsystems userflash support" |
65 | depends on SPARC && MTD_CFI | 74 | depends on SPARC && MTD_CFI |
@@ -184,6 +193,24 @@ config MTD_ICHXROM | |||
184 | 193 | ||
185 | BE VERY CAREFUL. | 194 | BE VERY CAREFUL. |
186 | 195 | ||
196 | config MTD_ESB2ROM | ||
197 | tristate "BIOS flash chip on Intel ESB Controller Hub 2" | ||
198 | depends on X86 && MTD_JEDECPROBE && PCI | ||
199 | help | ||
200 | Support for treating the BIOS flash chip on ESB2 motherboards | ||
201 | as an MTD device - with this you can reprogram your BIOS. | ||
202 | |||
203 | BE VERY CAREFUL. | ||
204 | |||
205 | config MTD_CK804XROM | ||
206 | tristate "BIOS flash chip on Nvidia CK804" | ||
207 | depends on X86 && MTD_JEDECPROBE | ||
208 | help | ||
209 | Support for treating the BIOS flash chip on nvidia motherboards | ||
210 | as an MTD device - with this you can reprogram your BIOS. | ||
211 | |||
212 | BE VERY CAREFUL. | ||
213 | |||
187 | config MTD_SCB2_FLASH | 214 | config MTD_SCB2_FLASH |
188 | tristate "BIOS flash chip on Intel SCB2 boards" | 215 | tristate "BIOS flash chip on Intel SCB2 boards" |
189 | depends on X86 && MTD_JEDECPROBE | 216 | depends on X86 && MTD_JEDECPROBE |
@@ -355,50 +382,6 @@ config MTD_TQM834x | |||
355 | TQ Components TQM834x boards. If you have one of these boards | 382 | TQ Components TQM834x boards. If you have one of these boards |
356 | and would like to use the flash chips on it, say 'Y'. | 383 | and would like to use the flash chips on it, say 'Y'. |
357 | 384 | ||
358 | config MTD_CSTM_MIPS_IXX | ||
359 | tristate "Flash chip mapping on ITE QED-4N-S01B, Globespan IVR or custom board" | ||
360 | depends on MIPS && MTD_CFI && MTD_JEDECPROBE && MTD_PARTITIONS | ||
361 | help | ||
362 | This provides a mapping driver for the Integrated Technology | ||
363 | Express, Inc (ITE) QED-4N-S01B eval board and the Globespan IVR | ||
364 | Reference Board. It provides the necessary addressing, length, | ||
365 | buswidth, vpp code and addition setup of the flash device for | ||
366 | these boards. In addition, this mapping driver can be used for | ||
367 | other boards via setting of the CONFIG_MTD_CSTM_MIPS_IXX_START/ | ||
368 | LEN/BUSWIDTH parameters. This mapping will provide one mtd device | ||
369 | using one partition. The start address can be offset from the | ||
370 | beginning of flash and the len can be less than the total flash | ||
371 | device size to allow a window into the flash. Both CFI and JEDEC | ||
372 | probes are called. | ||
373 | |||
374 | config MTD_CSTM_MIPS_IXX_START | ||
375 | hex "Physical start address of flash mapping" | ||
376 | depends on MTD_CSTM_MIPS_IXX | ||
377 | default "0x8000000" | ||
378 | help | ||
379 | This is the physical memory location that the MTD driver will | ||
380 | use for the flash chips on your particular target board. | ||
381 | Refer to the memory map which should hopefully be in the | ||
382 | documentation for your board. | ||
383 | |||
384 | config MTD_CSTM_MIPS_IXX_LEN | ||
385 | hex "Physical length of flash mapping" | ||
386 | depends on MTD_CSTM_MIPS_IXX | ||
387 | default "0x4000000" | ||
388 | help | ||
389 | This is the total length that the MTD driver will use for the | ||
390 | flash chips on your particular board. Refer to the memory | ||
391 | map which should hopefully be in the documentation for your | ||
392 | board. | ||
393 | |||
394 | config MTD_CSTM_MIPS_IXX_BUSWIDTH | ||
395 | int "Bus width in octets" | ||
396 | depends on MTD_CSTM_MIPS_IXX | ||
397 | default "2" | ||
398 | help | ||
399 | This is the total bus width of the mapping of the flash chips | ||
400 | on your particular board. | ||
401 | |||
402 | config MTD_OCELOT | 385 | config MTD_OCELOT |
403 | tristate "Momenco Ocelot boot flash device" | 386 | tristate "Momenco Ocelot boot flash device" |
404 | depends on MIPS && MOMENCO_OCELOT | 387 | depends on MIPS && MOMENCO_OCELOT |
diff --git a/drivers/mtd/maps/Makefile b/drivers/mtd/maps/Makefile index 191c1928bbec..071d0bf922b6 100644 --- a/drivers/mtd/maps/Makefile +++ b/drivers/mtd/maps/Makefile | |||
@@ -12,12 +12,13 @@ obj-$(CONFIG_MTD_CDB89712) += cdb89712.o | |||
12 | obj-$(CONFIG_MTD_ARM_INTEGRATOR)+= integrator-flash.o | 12 | obj-$(CONFIG_MTD_ARM_INTEGRATOR)+= integrator-flash.o |
13 | obj-$(CONFIG_MTD_BAST) += bast-flash.o | 13 | obj-$(CONFIG_MTD_BAST) += bast-flash.o |
14 | obj-$(CONFIG_MTD_CFI_FLAGADM) += cfi_flagadm.o | 14 | obj-$(CONFIG_MTD_CFI_FLAGADM) += cfi_flagadm.o |
15 | obj-$(CONFIG_MTD_CSTM_MIPS_IXX) += cstm_mips_ixx.o | ||
16 | obj-$(CONFIG_MTD_DC21285) += dc21285.o | 15 | obj-$(CONFIG_MTD_DC21285) += dc21285.o |
17 | obj-$(CONFIG_MTD_DILNETPC) += dilnetpc.o | 16 | obj-$(CONFIG_MTD_DILNETPC) += dilnetpc.o |
18 | obj-$(CONFIG_MTD_L440GX) += l440gx.o | 17 | obj-$(CONFIG_MTD_L440GX) += l440gx.o |
19 | obj-$(CONFIG_MTD_AMD76XROM) += amd76xrom.o | 18 | obj-$(CONFIG_MTD_AMD76XROM) += amd76xrom.o |
19 | obj-$(CONFIG_MTD_ESB2ROM) += esb2rom.o | ||
20 | obj-$(CONFIG_MTD_ICHXROM) += ichxrom.o | 20 | obj-$(CONFIG_MTD_ICHXROM) += ichxrom.o |
21 | obj-$(CONFIG_MTD_CK804XROM) += ck804xrom.o | ||
21 | obj-$(CONFIG_MTD_TSUNAMI) += tsunami_flash.o | 22 | obj-$(CONFIG_MTD_TSUNAMI) += tsunami_flash.o |
22 | obj-$(CONFIG_MTD_LUBBOCK) += lubbock-flash.o | 23 | obj-$(CONFIG_MTD_LUBBOCK) += lubbock-flash.o |
23 | obj-$(CONFIG_MTD_MAINSTONE) += mainstone-flash.o | 24 | obj-$(CONFIG_MTD_MAINSTONE) += mainstone-flash.o |
@@ -25,6 +26,7 @@ obj-$(CONFIG_MTD_MBX860) += mbx860.o | |||
25 | obj-$(CONFIG_MTD_CEIVA) += ceiva.o | 26 | obj-$(CONFIG_MTD_CEIVA) += ceiva.o |
26 | obj-$(CONFIG_MTD_OCTAGON) += octagon-5066.o | 27 | obj-$(CONFIG_MTD_OCTAGON) += octagon-5066.o |
27 | obj-$(CONFIG_MTD_PHYSMAP) += physmap.o | 28 | obj-$(CONFIG_MTD_PHYSMAP) += physmap.o |
29 | obj-$(CONFIG_MTD_PHYSMAP_OF) += physmap_of.o | ||
28 | obj-$(CONFIG_MTD_PNC2000) += pnc2000.o | 30 | obj-$(CONFIG_MTD_PNC2000) += pnc2000.o |
29 | obj-$(CONFIG_MTD_PCMCIA) += pcmciamtd.o | 31 | obj-$(CONFIG_MTD_PCMCIA) += pcmciamtd.o |
30 | obj-$(CONFIG_MTD_RPXLITE) += rpxlite.o | 32 | obj-$(CONFIG_MTD_RPXLITE) += rpxlite.o |
diff --git a/drivers/mtd/maps/amd76xrom.c b/drivers/mtd/maps/amd76xrom.c index 797caffb20b1..78b671172bb2 100644 --- a/drivers/mtd/maps/amd76xrom.c +++ b/drivers/mtd/maps/amd76xrom.c | |||
@@ -7,6 +7,7 @@ | |||
7 | 7 | ||
8 | #include <linux/module.h> | 8 | #include <linux/module.h> |
9 | #include <linux/types.h> | 9 | #include <linux/types.h> |
10 | #include <linux/version.h> | ||
10 | #include <linux/kernel.h> | 11 | #include <linux/kernel.h> |
11 | #include <linux/init.h> | 12 | #include <linux/init.h> |
12 | #include <asm/io.h> | 13 | #include <asm/io.h> |
@@ -44,6 +45,23 @@ struct amd76xrom_map_info { | |||
44 | char map_name[sizeof(MOD_NAME) + 2 + ADDRESS_NAME_LEN]; | 45 | char map_name[sizeof(MOD_NAME) + 2 + ADDRESS_NAME_LEN]; |
45 | }; | 46 | }; |
46 | 47 | ||
48 | /* The 2 bits controlling the window size are often set to allow reading | ||
49 | * the BIOS, but too small to allow writing, since the lock registers are | ||
50 | * 4MiB lower in the address space than the data. | ||
51 | * | ||
52 | * This is intended to prevent flashing the bios, perhaps accidentally. | ||
53 | * | ||
54 | * This parameter allows the normal driver to over-ride the BIOS settings. | ||
55 | * | ||
56 | * The bits are 6 and 7. If both bits are set, it is a 5MiB window. | ||
57 | * If only the 7 Bit is set, it is a 4MiB window. Otherwise, a | ||
58 | * 64KiB window. | ||
59 | * | ||
60 | */ | ||
61 | static uint win_size_bits; | ||
62 | module_param(win_size_bits, uint, 0); | ||
63 | MODULE_PARM_DESC(win_size_bits, "ROM window size bits override for 0x43 byte, normally set by BIOS."); | ||
64 | |||
47 | static struct amd76xrom_window amd76xrom_window = { | 65 | static struct amd76xrom_window amd76xrom_window = { |
48 | .maps = LIST_HEAD_INIT(amd76xrom_window.maps), | 66 | .maps = LIST_HEAD_INIT(amd76xrom_window.maps), |
49 | }; | 67 | }; |
@@ -95,6 +113,16 @@ static int __devinit amd76xrom_init_one (struct pci_dev *pdev, | |||
95 | /* Remember the pci dev I find the window in - already have a ref */ | 113 | /* Remember the pci dev I find the window in - already have a ref */ |
96 | window->pdev = pdev; | 114 | window->pdev = pdev; |
97 | 115 | ||
116 | /* Enable the selected rom window. This is often incorrectly | ||
117 | * set up by the BIOS, and the 4MiB offset for the lock registers | ||
118 | * requires the full 5MiB of window space. | ||
119 | * | ||
120 | * This 'write, then read' approach leaves the bits for | ||
121 | * other uses of the hardware info. | ||
122 | */ | ||
123 | pci_read_config_byte(pdev, 0x43, &byte); | ||
124 | pci_write_config_byte(pdev, 0x43, byte | win_size_bits ); | ||
125 | |||
98 | /* Assume the rom window is properly setup, and find it's size */ | 126 | /* Assume the rom window is properly setup, and find it's size */ |
99 | pci_read_config_byte(pdev, 0x43, &byte); | 127 | pci_read_config_byte(pdev, 0x43, &byte); |
100 | if ((byte & ((1<<7)|(1<<6))) == ((1<<7)|(1<<6))) { | 128 | if ((byte & ((1<<7)|(1<<6))) == ((1<<7)|(1<<6))) { |
@@ -129,12 +157,6 @@ static int __devinit amd76xrom_init_one (struct pci_dev *pdev, | |||
129 | (unsigned long long)window->rsrc.end); | 157 | (unsigned long long)window->rsrc.end); |
130 | } | 158 | } |
131 | 159 | ||
132 | #if 0 | ||
133 | |||
134 | /* Enable the selected rom window */ | ||
135 | pci_read_config_byte(pdev, 0x43, &byte); | ||
136 | pci_write_config_byte(pdev, 0x43, byte | rwindow->segen_bits); | ||
137 | #endif | ||
138 | 160 | ||
139 | /* Enable writes through the rom window */ | 161 | /* Enable writes through the rom window */ |
140 | pci_read_config_byte(pdev, 0x40, &byte); | 162 | pci_read_config_byte(pdev, 0x40, &byte); |
diff --git a/drivers/mtd/maps/bast-flash.c b/drivers/mtd/maps/bast-flash.c index e074bb6787d2..fc3b2672d1e2 100644 --- a/drivers/mtd/maps/bast-flash.c +++ b/drivers/mtd/maps/bast-flash.c | |||
@@ -131,7 +131,7 @@ static int bast_flash_probe(struct platform_device *pdev) | |||
131 | 131 | ||
132 | info->map.phys = res->start; | 132 | info->map.phys = res->start; |
133 | info->map.size = res->end - res->start + 1; | 133 | info->map.size = res->end - res->start + 1; |
134 | info->map.name = pdev->dev.bus_id; | 134 | info->map.name = pdev->dev.bus_id; |
135 | info->map.bankwidth = 2; | 135 | info->map.bankwidth = 2; |
136 | 136 | ||
137 | if (info->map.size > AREA_MAXSIZE) | 137 | if (info->map.size > AREA_MAXSIZE) |
diff --git a/drivers/mtd/maps/ceiva.c b/drivers/mtd/maps/ceiva.c index 0402c21e291d..629e6e2641a8 100644 --- a/drivers/mtd/maps/ceiva.c +++ b/drivers/mtd/maps/ceiva.c | |||
@@ -122,10 +122,9 @@ static int __init clps_setup_mtd(struct clps_info *clps, int nr, struct mtd_info | |||
122 | /* | 122 | /* |
123 | * Allocate the map_info structs in one go. | 123 | * Allocate the map_info structs in one go. |
124 | */ | 124 | */ |
125 | maps = kmalloc(sizeof(struct map_info) * nr, GFP_KERNEL); | 125 | maps = kzalloc(sizeof(struct map_info) * nr, GFP_KERNEL); |
126 | if (!maps) | 126 | if (!maps) |
127 | return -ENOMEM; | 127 | return -ENOMEM; |
128 | memset(maps, 0, sizeof(struct map_info) * nr); | ||
129 | /* | 128 | /* |
130 | * Claim and then map the memory regions. | 129 | * Claim and then map the memory regions. |
131 | */ | 130 | */ |
diff --git a/drivers/mtd/maps/ck804xrom.c b/drivers/mtd/maps/ck804xrom.c new file mode 100644 index 000000000000..238d42e88ec5 --- /dev/null +++ b/drivers/mtd/maps/ck804xrom.c | |||
@@ -0,0 +1,356 @@ | |||
1 | /* | ||
2 | * ck804xrom.c | ||
3 | * | ||
4 | * Normal mappings of chips in physical memory | ||
5 | * | ||
6 | * Dave Olsen <dolsen@lnxi.com> | ||
7 | * Ryan Jackson <rjackson@lnxi.com> | ||
8 | */ | ||
9 | |||
10 | #include <linux/module.h> | ||
11 | #include <linux/types.h> | ||
12 | #include <linux/version.h> | ||
13 | #include <linux/kernel.h> | ||
14 | #include <linux/init.h> | ||
15 | #include <asm/io.h> | ||
16 | #include <linux/mtd/mtd.h> | ||
17 | #include <linux/mtd/map.h> | ||
18 | #include <linux/mtd/cfi.h> | ||
19 | #include <linux/mtd/flashchip.h> | ||
20 | #include <linux/pci.h> | ||
21 | #include <linux/pci_ids.h> | ||
22 | #include <linux/list.h> | ||
23 | |||
24 | |||
25 | #define MOD_NAME KBUILD_BASENAME | ||
26 | |||
27 | #define ADDRESS_NAME_LEN 18 | ||
28 | |||
29 | #define ROM_PROBE_STEP_SIZE (64*1024) | ||
30 | |||
31 | struct ck804xrom_window { | ||
32 | void __iomem *virt; | ||
33 | unsigned long phys; | ||
34 | unsigned long size; | ||
35 | struct list_head maps; | ||
36 | struct resource rsrc; | ||
37 | struct pci_dev *pdev; | ||
38 | }; | ||
39 | |||
40 | struct ck804xrom_map_info { | ||
41 | struct list_head list; | ||
42 | struct map_info map; | ||
43 | struct mtd_info *mtd; | ||
44 | struct resource rsrc; | ||
45 | char map_name[sizeof(MOD_NAME) + 2 + ADDRESS_NAME_LEN]; | ||
46 | }; | ||
47 | |||
48 | |||
49 | /* The 2 bits controlling the window size are often set to allow reading | ||
50 | * the BIOS, but too small to allow writing, since the lock registers are | ||
51 | * 4MiB lower in the address space than the data. | ||
52 | * | ||
53 | * This is intended to prevent flashing the bios, perhaps accidentally. | ||
54 | * | ||
55 | * This parameter allows the normal driver to override the BIOS settings. | ||
56 | * | ||
57 | * The bits are 6 and 7. If both bits are set, it is a 5MiB window. | ||
58 | * If only the 7 Bit is set, it is a 4MiB window. Otherwise, a | ||
59 | * 64KiB window. | ||
60 | * | ||
61 | */ | ||
62 | static uint win_size_bits = 0; | ||
63 | module_param(win_size_bits, uint, 0); | ||
64 | MODULE_PARM_DESC(win_size_bits, "ROM window size bits override for 0x88 byte, normally set by BIOS."); | ||
65 | |||
66 | static struct ck804xrom_window ck804xrom_window = { | ||
67 | .maps = LIST_HEAD_INIT(ck804xrom_window.maps), | ||
68 | }; | ||
69 | |||
70 | static void ck804xrom_cleanup(struct ck804xrom_window *window) | ||
71 | { | ||
72 | struct ck804xrom_map_info *map, *scratch; | ||
73 | u8 byte; | ||
74 | |||
75 | if (window->pdev) { | ||
76 | /* Disable writes through the rom window */ | ||
77 | pci_read_config_byte(window->pdev, 0x6d, &byte); | ||
78 | pci_write_config_byte(window->pdev, 0x6d, byte & ~1); | ||
79 | } | ||
80 | |||
81 | /* Free all of the mtd devices */ | ||
82 | list_for_each_entry_safe(map, scratch, &window->maps, list) { | ||
83 | if (map->rsrc.parent) | ||
84 | release_resource(&map->rsrc); | ||
85 | |||
86 | del_mtd_device(map->mtd); | ||
87 | map_destroy(map->mtd); | ||
88 | list_del(&map->list); | ||
89 | kfree(map); | ||
90 | } | ||
91 | if (window->rsrc.parent) | ||
92 | release_resource(&window->rsrc); | ||
93 | |||
94 | if (window->virt) { | ||
95 | iounmap(window->virt); | ||
96 | window->virt = NULL; | ||
97 | window->phys = 0; | ||
98 | window->size = 0; | ||
99 | } | ||
100 | pci_dev_put(window->pdev); | ||
101 | } | ||
102 | |||
103 | |||
104 | static int __devinit ck804xrom_init_one (struct pci_dev *pdev, | ||
105 | const struct pci_device_id *ent) | ||
106 | { | ||
107 | static char *rom_probe_types[] = { "cfi_probe", "jedec_probe", NULL }; | ||
108 | u8 byte; | ||
109 | struct ck804xrom_window *window = &ck804xrom_window; | ||
110 | struct ck804xrom_map_info *map = NULL; | ||
111 | unsigned long map_top; | ||
112 | |||
113 | /* Remember the pci dev I find the window in */ | ||
114 | window->pdev = pci_dev_get(pdev); | ||
115 | |||
116 | /* Enable the selected rom window. This is often incorrectly | ||
117 | * set up by the BIOS, and the 4MiB offset for the lock registers | ||
118 | * requires the full 5MiB of window space. | ||
119 | * | ||
120 | * This 'write, then read' approach leaves the bits for | ||
121 | * other uses of the hardware info. | ||
122 | */ | ||
123 | pci_read_config_byte(pdev, 0x88, &byte); | ||
124 | pci_write_config_byte(pdev, 0x88, byte | win_size_bits ); | ||
125 | |||
126 | |||
127 | /* Assume the rom window is properly setup, and find it's size */ | ||
128 | pci_read_config_byte(pdev, 0x88, &byte); | ||
129 | |||
130 | if ((byte & ((1<<7)|(1<<6))) == ((1<<7)|(1<<6))) | ||
131 | window->phys = 0xffb00000; /* 5MiB */ | ||
132 | else if ((byte & (1<<7)) == (1<<7)) | ||
133 | window->phys = 0xffc00000; /* 4MiB */ | ||
134 | else | ||
135 | window->phys = 0xffff0000; /* 64KiB */ | ||
136 | |||
137 | window->size = 0xffffffffUL - window->phys + 1UL; | ||
138 | |||
139 | /* | ||
140 | * Try to reserve the window mem region. If this fails then | ||
141 | * it is likely due to a fragment of the window being | ||
142 | * "reserved" by the BIOS. In the case that the | ||
143 | * request_mem_region() fails then once the rom size is | ||
144 | * discovered we will try to reserve the unreserved fragment. | ||
145 | */ | ||
146 | window->rsrc.name = MOD_NAME; | ||
147 | window->rsrc.start = window->phys; | ||
148 | window->rsrc.end = window->phys + window->size - 1; | ||
149 | window->rsrc.flags = IORESOURCE_MEM | IORESOURCE_BUSY; | ||
150 | if (request_resource(&iomem_resource, &window->rsrc)) { | ||
151 | window->rsrc.parent = NULL; | ||
152 | printk(KERN_ERR MOD_NAME | ||
153 | " %s(): Unable to register resource" | ||
154 | " 0x%.016llx-0x%.016llx - kernel bug?\n", | ||
155 | __func__, | ||
156 | (unsigned long long)window->rsrc.start, | ||
157 | (unsigned long long)window->rsrc.end); | ||
158 | } | ||
159 | |||
160 | |||
161 | /* Enable writes through the rom window */ | ||
162 | pci_read_config_byte(pdev, 0x6d, &byte); | ||
163 | pci_write_config_byte(pdev, 0x6d, byte | 1); | ||
164 | |||
165 | /* FIXME handle registers 0x80 - 0x8C the bios region locks */ | ||
166 | |||
167 | /* For write accesses caches are useless */ | ||
168 | window->virt = ioremap_nocache(window->phys, window->size); | ||
169 | if (!window->virt) { | ||
170 | printk(KERN_ERR MOD_NAME ": ioremap(%08lx, %08lx) failed\n", | ||
171 | window->phys, window->size); | ||
172 | goto out; | ||
173 | } | ||
174 | |||
175 | /* Get the first address to look for a rom chip at */ | ||
176 | map_top = window->phys; | ||
177 | #if 1 | ||
178 | /* The probe sequence run over the firmware hub lock | ||
179 | * registers sets them to 0x7 (no access). | ||
180 | * Probe at most the last 4MiB of the address space. | ||
181 | */ | ||
182 | if (map_top < 0xffc00000) | ||
183 | map_top = 0xffc00000; | ||
184 | #endif | ||
185 | /* Loop through and look for rom chips. Since we don't know the | ||
186 | * starting address for each chip, probe every ROM_PROBE_STEP_SIZE | ||
187 | * bytes from the starting address of the window. | ||
188 | */ | ||
189 | while((map_top - 1) < 0xffffffffUL) { | ||
190 | struct cfi_private *cfi; | ||
191 | unsigned long offset; | ||
192 | int i; | ||
193 | |||
194 | if (!map) | ||
195 | map = kmalloc(sizeof(*map), GFP_KERNEL); | ||
196 | |||
197 | if (!map) { | ||
198 | printk(KERN_ERR MOD_NAME ": kmalloc failed"); | ||
199 | goto out; | ||
200 | } | ||
201 | memset(map, 0, sizeof(*map)); | ||
202 | INIT_LIST_HEAD(&map->list); | ||
203 | map->map.name = map->map_name; | ||
204 | map->map.phys = map_top; | ||
205 | offset = map_top - window->phys; | ||
206 | map->map.virt = (void __iomem *) | ||
207 | (((unsigned long)(window->virt)) + offset); | ||
208 | map->map.size = 0xffffffffUL - map_top + 1UL; | ||
209 | /* Set the name of the map to the address I am trying */ | ||
210 | sprintf(map->map_name, "%s @%08lx", | ||
211 | MOD_NAME, map->map.phys); | ||
212 | |||
213 | /* There is no generic VPP support */ | ||
214 | for(map->map.bankwidth = 32; map->map.bankwidth; | ||
215 | map->map.bankwidth >>= 1) | ||
216 | { | ||
217 | char **probe_type; | ||
218 | /* Skip bankwidths that are not supported */ | ||
219 | if (!map_bankwidth_supported(map->map.bankwidth)) | ||
220 | continue; | ||
221 | |||
222 | /* Setup the map methods */ | ||
223 | simple_map_init(&map->map); | ||
224 | |||
225 | /* Try all of the probe methods */ | ||
226 | probe_type = rom_probe_types; | ||
227 | for(; *probe_type; probe_type++) { | ||
228 | map->mtd = do_map_probe(*probe_type, &map->map); | ||
229 | if (map->mtd) | ||
230 | goto found; | ||
231 | } | ||
232 | } | ||
233 | map_top += ROM_PROBE_STEP_SIZE; | ||
234 | continue; | ||
235 | found: | ||
236 | /* Trim the size if we are larger than the map */ | ||
237 | if (map->mtd->size > map->map.size) { | ||
238 | printk(KERN_WARNING MOD_NAME | ||
239 | " rom(%u) larger than window(%lu). fixing...\n", | ||
240 | map->mtd->size, map->map.size); | ||
241 | map->mtd->size = map->map.size; | ||
242 | } | ||
243 | if (window->rsrc.parent) { | ||
244 | /* | ||
245 | * Registering the MTD device in iomem may not be possible | ||
246 | * if there is a BIOS "reserved" and BUSY range. If this | ||
247 | * fails then continue anyway. | ||
248 | */ | ||
249 | map->rsrc.name = map->map_name; | ||
250 | map->rsrc.start = map->map.phys; | ||
251 | map->rsrc.end = map->map.phys + map->mtd->size - 1; | ||
252 | map->rsrc.flags = IORESOURCE_MEM | IORESOURCE_BUSY; | ||
253 | if (request_resource(&window->rsrc, &map->rsrc)) { | ||
254 | printk(KERN_ERR MOD_NAME | ||
255 | ": cannot reserve MTD resource\n"); | ||
256 | map->rsrc.parent = NULL; | ||
257 | } | ||
258 | } | ||
259 | |||
260 | /* Make the whole region visible in the map */ | ||
261 | map->map.virt = window->virt; | ||
262 | map->map.phys = window->phys; | ||
263 | cfi = map->map.fldrv_priv; | ||
264 | for(i = 0; i < cfi->numchips; i++) | ||
265 | cfi->chips[i].start += offset; | ||
266 | |||
267 | /* Now that the mtd devices is complete claim and export it */ | ||
268 | map->mtd->owner = THIS_MODULE; | ||
269 | if (add_mtd_device(map->mtd)) { | ||
270 | map_destroy(map->mtd); | ||
271 | map->mtd = NULL; | ||
272 | goto out; | ||
273 | } | ||
274 | |||
275 | |||
276 | /* Calculate the new value of map_top */ | ||
277 | map_top += map->mtd->size; | ||
278 | |||
279 | /* File away the map structure */ | ||
280 | list_add(&map->list, &window->maps); | ||
281 | map = NULL; | ||
282 | } | ||
283 | |||
284 | out: | ||
285 | /* Free any left over map structures */ | ||
286 | if (map) | ||
287 | kfree(map); | ||
288 | |||
289 | /* See if I have any map structures */ | ||
290 | if (list_empty(&window->maps)) { | ||
291 | ck804xrom_cleanup(window); | ||
292 | return -ENODEV; | ||
293 | } | ||
294 | return 0; | ||
295 | } | ||
296 | |||
297 | |||
298 | static void __devexit ck804xrom_remove_one (struct pci_dev *pdev) | ||
299 | { | ||
300 | struct ck804xrom_window *window = &ck804xrom_window; | ||
301 | |||
302 | ck804xrom_cleanup(window); | ||
303 | } | ||
304 | |||
305 | static struct pci_device_id ck804xrom_pci_tbl[] = { | ||
306 | { PCI_VENDOR_ID_NVIDIA, 0x0051, | ||
307 | PCI_ANY_ID, PCI_ANY_ID, }, /* nvidia ck804 */ | ||
308 | { 0, } | ||
309 | }; | ||
310 | |||
311 | MODULE_DEVICE_TABLE(pci, ck804xrom_pci_tbl); | ||
312 | |||
313 | #if 0 | ||
314 | static struct pci_driver ck804xrom_driver = { | ||
315 | .name = MOD_NAME, | ||
316 | .id_table = ck804xrom_pci_tbl, | ||
317 | .probe = ck804xrom_init_one, | ||
318 | .remove = ck804xrom_remove_one, | ||
319 | }; | ||
320 | #endif | ||
321 | |||
322 | static int __init init_ck804xrom(void) | ||
323 | { | ||
324 | struct pci_dev *pdev; | ||
325 | struct pci_device_id *id; | ||
326 | int retVal; | ||
327 | pdev = NULL; | ||
328 | |||
329 | for(id = ck804xrom_pci_tbl; id->vendor; id++) { | ||
330 | pdev = pci_find_device(id->vendor, id->device, NULL); | ||
331 | if (pdev) | ||
332 | break; | ||
333 | } | ||
334 | if (pdev) { | ||
335 | retVal = ck804xrom_init_one(pdev, &ck804xrom_pci_tbl[0]); | ||
336 | pci_dev_put(pdev); | ||
337 | return retVal; | ||
338 | } | ||
339 | return -ENXIO; | ||
340 | #if 0 | ||
341 | return pci_module_init(&ck804xrom_driver); | ||
342 | #endif | ||
343 | } | ||
344 | |||
345 | static void __exit cleanup_ck804xrom(void) | ||
346 | { | ||
347 | ck804xrom_remove_one(ck804xrom_window.pdev); | ||
348 | } | ||
349 | |||
350 | module_init(init_ck804xrom); | ||
351 | module_exit(cleanup_ck804xrom); | ||
352 | |||
353 | MODULE_LICENSE("GPL"); | ||
354 | MODULE_AUTHOR("Eric Biederman <ebiederman@lnxi.com>, Dave Olsen <dolsen@lnxi.com>"); | ||
355 | MODULE_DESCRIPTION("MTD map driver for BIOS chips on the Nvidia ck804 southbridge"); | ||
356 | |||
diff --git a/drivers/mtd/maps/cstm_mips_ixx.c b/drivers/mtd/maps/cstm_mips_ixx.c deleted file mode 100644 index df2c38ef105a..000000000000 --- a/drivers/mtd/maps/cstm_mips_ixx.c +++ /dev/null | |||
@@ -1,283 +0,0 @@ | |||
1 | /* | ||
2 | * $Id: cstm_mips_ixx.c,v 1.14 2005/11/07 11:14:26 gleixner Exp $ | ||
3 | * | ||
4 | * Mapping of a custom board with both AMD CFI and JEDEC flash in partitions. | ||
5 | * Config with both CFI and JEDEC device support. | ||
6 | * | ||
7 | * Basically physmap.c with the addition of partitions and | ||
8 | * an array of mapping info to accomodate more than one flash type per board. | ||
9 | * | ||
10 | * Copyright 2000 MontaVista Software Inc. | ||
11 | * | ||
12 | * This program is free software; you can redistribute it and/or modify it | ||
13 | * under the terms of the GNU General Public License as published by the | ||
14 | * Free Software Foundation; either version 2 of the License, or (at your | ||
15 | * option) any later version. | ||
16 | * | ||
17 | * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED | ||
18 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | ||
19 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN | ||
20 | * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | ||
21 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
22 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF | ||
23 | * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON | ||
24 | * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
25 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | ||
26 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
27 | * | ||
28 | * You should have received a copy of the GNU General Public License along | ||
29 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
30 | * 675 Mass Ave, Cambridge, MA 02139, USA. | ||
31 | */ | ||
32 | |||
33 | #include <linux/module.h> | ||
34 | #include <linux/types.h> | ||
35 | #include <linux/kernel.h> | ||
36 | #include <linux/init.h> | ||
37 | #include <asm/io.h> | ||
38 | #include <linux/mtd/mtd.h> | ||
39 | #include <linux/mtd/map.h> | ||
40 | #include <linux/mtd/partitions.h> | ||
41 | #include <linux/delay.h> | ||
42 | |||
43 | #if defined(CONFIG_MIPS_ITE8172) || defined(CONFIG_MIPS_IVR) | ||
44 | #define CC_GCR 0xB4013818 | ||
45 | #define CC_GPBCR 0xB401380A | ||
46 | #define CC_GPBDR 0xB4013808 | ||
47 | #define CC_M68K_DEVICE 1 | ||
48 | #define CC_M68K_FUNCTION 6 | ||
49 | #define CC_CONFADDR 0xB8004000 | ||
50 | #define CC_CONFDATA 0xB8004004 | ||
51 | #define CC_FC_FCR 0xB8002004 | ||
52 | #define CC_FC_DCR 0xB8002008 | ||
53 | #define CC_GPACR 0xB4013802 | ||
54 | #define CC_GPAICR 0xB4013804 | ||
55 | #endif /* defined(CONFIG_MIPS_ITE8172) || defined(CONFIG_MIPS_IVR) */ | ||
56 | |||
57 | #if defined(CONFIG_MIPS_ITE8172) || defined(CONFIG_MIPS_IVR) | ||
58 | void cstm_mips_ixx_set_vpp(struct map_info *map,int vpp) | ||
59 | { | ||
60 | static DEFINE_SPINLOCK(vpp_lock); | ||
61 | static int vpp_count = 0; | ||
62 | unsigned long flags; | ||
63 | |||
64 | spin_lock_irqsave(&vpp_lock, flags); | ||
65 | |||
66 | if (vpp) { | ||
67 | if (!vpp_count++) { | ||
68 | __u16 data; | ||
69 | __u8 data1; | ||
70 | static u8 first = 1; | ||
71 | |||
72 | // Set GPIO port B pin3 to high | ||
73 | data = *(__u16 *)(CC_GPBCR); | ||
74 | data = (data & 0xff0f) | 0x0040; | ||
75 | *(__u16 *)CC_GPBCR = data; | ||
76 | *(__u8 *)CC_GPBDR = (*(__u8*)CC_GPBDR) | 0x08; | ||
77 | if (first) { | ||
78 | first = 0; | ||
79 | /* need to have this delay for first | ||
80 | enabling vpp after powerup */ | ||
81 | udelay(40); | ||
82 | } | ||
83 | } | ||
84 | } else { | ||
85 | if (!--vpp_count) { | ||
86 | __u16 data; | ||
87 | |||
88 | // Set GPIO port B pin3 to high | ||
89 | data = *(__u16 *)(CC_GPBCR); | ||
90 | data = (data & 0xff3f) | 0x0040; | ||
91 | *(__u16 *)CC_GPBCR = data; | ||
92 | *(__u8 *)CC_GPBDR = (*(__u8*)CC_GPBDR) & 0xf7; | ||
93 | } | ||
94 | } | ||
95 | spin_unlock_irqrestore(&vpp_lock, flags); | ||
96 | } | ||
97 | #endif | ||
98 | |||
99 | /* board and partition description */ | ||
100 | |||
101 | #define MAX_PHYSMAP_PARTITIONS 8 | ||
102 | struct cstm_mips_ixx_info { | ||
103 | char *name; | ||
104 | unsigned long window_addr; | ||
105 | unsigned long window_size; | ||
106 | int bankwidth; | ||
107 | int num_partitions; | ||
108 | }; | ||
109 | |||
110 | #if defined(CONFIG_MIPS_ITE8172) || defined(CONFIG_MIPS_IVR) | ||
111 | #define PHYSMAP_NUMBER 1 // number of board desc structs needed, one per contiguous flash type | ||
112 | const struct cstm_mips_ixx_info cstm_mips_ixx_board_desc[PHYSMAP_NUMBER] = | ||
113 | { | ||
114 | { // 28F128J3A in 2x16 configuration | ||
115 | "big flash", // name | ||
116 | 0x08000000, // window_addr | ||
117 | 0x02000000, // window_size | ||
118 | 4, // bankwidth | ||
119 | 1, // num_partitions | ||
120 | } | ||
121 | |||
122 | }; | ||
123 | static struct mtd_partition cstm_mips_ixx_partitions[PHYSMAP_NUMBER][MAX_PHYSMAP_PARTITIONS] = { | ||
124 | { // 28F128J3A in 2x16 configuration | ||
125 | { | ||
126 | .name = "main partition ", | ||
127 | .size = 0x02000000, // 128 x 2 x 128k byte sectors | ||
128 | .offset = 0, | ||
129 | }, | ||
130 | }, | ||
131 | }; | ||
132 | #else /* defined(CONFIG_MIPS_ITE8172) || defined(CONFIG_MIPS_IVR) */ | ||
133 | #define PHYSMAP_NUMBER 1 // number of board desc structs needed, one per contiguous flash type | ||
134 | const struct cstm_mips_ixx_info cstm_mips_ixx_board_desc[PHYSMAP_NUMBER] = | ||
135 | { | ||
136 | { | ||
137 | "MTD flash", // name | ||
138 | CONFIG_MTD_CSTM_MIPS_IXX_START, // window_addr | ||
139 | CONFIG_MTD_CSTM_MIPS_IXX_LEN, // window_size | ||
140 | CONFIG_MTD_CSTM_MIPS_IXX_BUSWIDTH, // bankwidth | ||
141 | 1, // num_partitions | ||
142 | }, | ||
143 | |||
144 | }; | ||
145 | static struct mtd_partition cstm_mips_ixx_partitions[PHYSMAP_NUMBER][MAX_PHYSMAP_PARTITIONS] = { | ||
146 | { | ||
147 | { | ||
148 | .name = "main partition", | ||
149 | .size = CONFIG_MTD_CSTM_MIPS_IXX_LEN, | ||
150 | .offset = 0, | ||
151 | }, | ||
152 | }, | ||
153 | }; | ||
154 | #endif /* defined(CONFIG_MIPS_ITE8172) || defined(CONFIG_MIPS_IVR) */ | ||
155 | |||
156 | struct map_info cstm_mips_ixx_map[PHYSMAP_NUMBER]; | ||
157 | |||
158 | int __init init_cstm_mips_ixx(void) | ||
159 | { | ||
160 | int i; | ||
161 | int jedec; | ||
162 | struct mtd_info *mymtd; | ||
163 | struct mtd_partition *parts; | ||
164 | |||
165 | /* Initialize mapping */ | ||
166 | for (i=0;i<PHYSMAP_NUMBER;i++) { | ||
167 | printk(KERN_NOTICE "cstm_mips_ixx flash device: 0x%lx at 0x%lx\n", | ||
168 | cstm_mips_ixx_board_desc[i].window_size, cstm_mips_ixx_board_desc[i].window_addr); | ||
169 | |||
170 | |||
171 | cstm_mips_ixx_map[i].phys = cstm_mips_ixx_board_desc[i].window_addr; | ||
172 | cstm_mips_ixx_map[i].virt = ioremap(cstm_mips_ixx_board_desc[i].window_addr, cstm_mips_ixx_board_desc[i].window_size); | ||
173 | if (!cstm_mips_ixx_map[i].virt) { | ||
174 | int j = 0; | ||
175 | printk(KERN_WARNING "Failed to ioremap\n"); | ||
176 | for (j = 0; j < i; j++) { | ||
177 | if (cstm_mips_ixx_map[j].virt) { | ||
178 | iounmap(cstm_mips_ixx_map[j].virt); | ||
179 | cstm_mips_ixx_map[j].virt = NULL; | ||
180 | } | ||
181 | } | ||
182 | return -EIO; | ||
183 | } | ||
184 | cstm_mips_ixx_map[i].name = cstm_mips_ixx_board_desc[i].name; | ||
185 | cstm_mips_ixx_map[i].size = cstm_mips_ixx_board_desc[i].window_size; | ||
186 | cstm_mips_ixx_map[i].bankwidth = cstm_mips_ixx_board_desc[i].bankwidth; | ||
187 | #if defined(CONFIG_MIPS_ITE8172) || defined(CONFIG_MIPS_IVR) | ||
188 | cstm_mips_ixx_map[i].set_vpp = cstm_mips_ixx_set_vpp; | ||
189 | #endif | ||
190 | simple_map_init(&cstm_mips_ixx_map[i]); | ||
191 | //printk(KERN_NOTICE "cstm_mips_ixx: ioremap is %x\n",(unsigned int)(cstm_mips_ixx_map[i].virt)); | ||
192 | } | ||
193 | |||
194 | #if defined(CONFIG_MIPS_ITE8172) || defined(CONFIG_MIPS_IVR) | ||
195 | setup_ITE_IVR_flash(); | ||
196 | #endif /* defined(CONFIG_MIPS_ITE8172) || defined(CONFIG_MIPS_IVR) */ | ||
197 | |||
198 | for (i=0;i<PHYSMAP_NUMBER;i++) { | ||
199 | parts = &cstm_mips_ixx_partitions[i][0]; | ||
200 | jedec = 0; | ||
201 | mymtd = (struct mtd_info *)do_map_probe("cfi_probe", &cstm_mips_ixx_map[i]); | ||
202 | //printk(KERN_NOTICE "phymap %d cfi_probe: mymtd is %x\n",i,(unsigned int)mymtd); | ||
203 | if (!mymtd) { | ||
204 | jedec = 1; | ||
205 | mymtd = (struct mtd_info *)do_map_probe("jedec", &cstm_mips_ixx_map[i]); | ||
206 | printk(KERN_NOTICE "cstm_mips_ixx %d jedec: mymtd is %x\n",i,(unsigned int)mymtd); | ||
207 | } | ||
208 | if (mymtd) { | ||
209 | mymtd->owner = THIS_MODULE; | ||
210 | |||
211 | cstm_mips_ixx_map[i].map_priv_2 = (unsigned long)mymtd; | ||
212 | add_mtd_partitions(mymtd, parts, cstm_mips_ixx_board_desc[i].num_partitions); | ||
213 | } | ||
214 | else { | ||
215 | for (i = 0; i < PHYSMAP_NUMBER; i++) { | ||
216 | if (cstm_mips_ixx_map[i].virt) { | ||
217 | iounmap(cstm_mips_ixx_map[i].virt); | ||
218 | cstm_mips_ixx_map[i].virt = NULL; | ||
219 | } | ||
220 | } | ||
221 | return -ENXIO; | ||
222 | } | ||
223 | } | ||
224 | return 0; | ||
225 | } | ||
226 | |||
227 | static void __exit cleanup_cstm_mips_ixx(void) | ||
228 | { | ||
229 | int i; | ||
230 | struct mtd_info *mymtd; | ||
231 | |||
232 | for (i=0;i<PHYSMAP_NUMBER;i++) { | ||
233 | mymtd = (struct mtd_info *)cstm_mips_ixx_map[i].map_priv_2; | ||
234 | if (mymtd) { | ||
235 | del_mtd_partitions(mymtd); | ||
236 | map_destroy(mymtd); | ||
237 | } | ||
238 | if (cstm_mips_ixx_map[i].virt) { | ||
239 | iounmap((void *)cstm_mips_ixx_map[i].virt); | ||
240 | cstm_mips_ixx_map[i].virt = 0; | ||
241 | } | ||
242 | } | ||
243 | } | ||
244 | #if defined(CONFIG_MIPS_ITE8172) || defined(CONFIG_MIPS_IVR) | ||
245 | void PCISetULongByOffset(__u32 DevNumber, __u32 FuncNumber, __u32 Offset, __u32 data) | ||
246 | { | ||
247 | __u32 offset; | ||
248 | |||
249 | offset = ( unsigned long )( 0x80000000 | ( DevNumber << 11 ) + ( FuncNumber << 8 ) + Offset) ; | ||
250 | |||
251 | *(__u32 *)CC_CONFADDR = offset; | ||
252 | *(__u32 *)CC_CONFDATA = data; | ||
253 | } | ||
254 | void setup_ITE_IVR_flash() | ||
255 | { | ||
256 | __u32 size, base; | ||
257 | |||
258 | size = 0x0e000000; // 32MiB | ||
259 | base = (0x08000000) >> 8 >>1; // Bug: we must shift one more bit | ||
260 | |||
261 | /* need to set ITE flash to 32 bits instead of default 8 */ | ||
262 | #ifdef CONFIG_MIPS_IVR | ||
263 | *(__u32 *)CC_FC_FCR = 0x55; | ||
264 | *(__u32 *)CC_GPACR = 0xfffc; | ||
265 | #else | ||
266 | *(__u32 *)CC_FC_FCR = 0x77; | ||
267 | #endif | ||
268 | /* turn bursting off */ | ||
269 | *(__u32 *)CC_FC_DCR = 0x0; | ||
270 | |||
271 | /* setup for one chip 4 byte PCI access */ | ||
272 | PCISetULongByOffset(CC_M68K_DEVICE, CC_M68K_FUNCTION, 0x60, size | base); | ||
273 | PCISetULongByOffset(CC_M68K_DEVICE, CC_M68K_FUNCTION, 0x64, 0x02); | ||
274 | } | ||
275 | #endif /* defined(CONFIG_MIPS_ITE8172) || defined(CONFIG_MIPS_IVR) */ | ||
276 | |||
277 | module_init(init_cstm_mips_ixx); | ||
278 | module_exit(cleanup_cstm_mips_ixx); | ||
279 | |||
280 | |||
281 | MODULE_LICENSE("GPL"); | ||
282 | MODULE_AUTHOR("Alice Hennessy <ahennessy@mvista.com>"); | ||
283 | MODULE_DESCRIPTION("MTD map driver for ITE 8172G and Globespan IVR boards"); | ||
diff --git a/drivers/mtd/maps/esb2rom.c b/drivers/mtd/maps/esb2rom.c new file mode 100644 index 000000000000..a9d808a617c9 --- /dev/null +++ b/drivers/mtd/maps/esb2rom.c | |||
@@ -0,0 +1,450 @@ | |||
1 | /* | ||
2 | * esb2rom.c | ||
3 | * | ||
4 | * Normal mappings of flash chips in physical memory | ||
5 | * through the Intel ESB2 Southbridge. | ||
6 | * | ||
7 | * This was derived from ichxrom.c in May 2006 by | ||
8 | * Lew Glendenning <lglendenning@lnxi.com> | ||
9 | * | ||
10 | * Eric Biederman, of course, was a major help in this effort. | ||
11 | */ | ||
12 | |||
13 | #include <linux/module.h> | ||
14 | #include <linux/types.h> | ||
15 | #include <linux/version.h> | ||
16 | #include <linux/kernel.h> | ||
17 | #include <linux/init.h> | ||
18 | #include <asm/io.h> | ||
19 | #include <linux/mtd/mtd.h> | ||
20 | #include <linux/mtd/map.h> | ||
21 | #include <linux/mtd/cfi.h> | ||
22 | #include <linux/mtd/flashchip.h> | ||
23 | #include <linux/pci.h> | ||
24 | #include <linux/pci_ids.h> | ||
25 | #include <linux/list.h> | ||
26 | |||
27 | #define MOD_NAME KBUILD_BASENAME | ||
28 | |||
29 | #define ADDRESS_NAME_LEN 18 | ||
30 | |||
31 | #define ROM_PROBE_STEP_SIZE (64*1024) /* 64KiB */ | ||
32 | |||
33 | #define BIOS_CNTL 0xDC | ||
34 | #define BIOS_LOCK_ENABLE 0x02 | ||
35 | #define BIOS_WRITE_ENABLE 0x01 | ||
36 | |||
37 | /* This became a 16-bit register, and EN2 has disappeared */ | ||
38 | #define FWH_DEC_EN1 0xD8 | ||
39 | #define FWH_F8_EN 0x8000 | ||
40 | #define FWH_F0_EN 0x4000 | ||
41 | #define FWH_E8_EN 0x2000 | ||
42 | #define FWH_E0_EN 0x1000 | ||
43 | #define FWH_D8_EN 0x0800 | ||
44 | #define FWH_D0_EN 0x0400 | ||
45 | #define FWH_C8_EN 0x0200 | ||
46 | #define FWH_C0_EN 0x0100 | ||
47 | #define FWH_LEGACY_F_EN 0x0080 | ||
48 | #define FWH_LEGACY_E_EN 0x0040 | ||
49 | /* reserved 0x0020 and 0x0010 */ | ||
50 | #define FWH_70_EN 0x0008 | ||
51 | #define FWH_60_EN 0x0004 | ||
52 | #define FWH_50_EN 0x0002 | ||
53 | #define FWH_40_EN 0x0001 | ||
54 | |||
55 | /* these are 32-bit values */ | ||
56 | #define FWH_SEL1 0xD0 | ||
57 | #define FWH_SEL2 0xD4 | ||
58 | |||
59 | #define FWH_8MiB (FWH_F8_EN | FWH_F0_EN | FWH_E8_EN | FWH_E0_EN | \ | ||
60 | FWH_D8_EN | FWH_D0_EN | FWH_C8_EN | FWH_C0_EN | \ | ||
61 | FWH_70_EN | FWH_60_EN | FWH_50_EN | FWH_40_EN) | ||
62 | |||
63 | #define FWH_7MiB (FWH_F8_EN | FWH_F0_EN | FWH_E8_EN | FWH_E0_EN | \ | ||
64 | FWH_D8_EN | FWH_D0_EN | FWH_C8_EN | FWH_C0_EN | \ | ||
65 | FWH_70_EN | FWH_60_EN | FWH_50_EN) | ||
66 | |||
67 | #define FWH_6MiB (FWH_F8_EN | FWH_F0_EN | FWH_E8_EN | FWH_E0_EN | \ | ||
68 | FWH_D8_EN | FWH_D0_EN | FWH_C8_EN | FWH_C0_EN | \ | ||
69 | FWH_70_EN | FWH_60_EN) | ||
70 | |||
71 | #define FWH_5MiB (FWH_F8_EN | FWH_F0_EN | FWH_E8_EN | FWH_E0_EN | \ | ||
72 | FWH_D8_EN | FWH_D0_EN | FWH_C8_EN | FWH_C0_EN | \ | ||
73 | FWH_70_EN) | ||
74 | |||
75 | #define FWH_4MiB (FWH_F8_EN | FWH_F0_EN | FWH_E8_EN | FWH_E0_EN | \ | ||
76 | FWH_D8_EN | FWH_D0_EN | FWH_C8_EN | FWH_C0_EN) | ||
77 | |||
78 | #define FWH_3_5MiB (FWH_F8_EN | FWH_F0_EN | FWH_E8_EN | FWH_E0_EN | \ | ||
79 | FWH_D8_EN | FWH_D0_EN | FWH_C8_EN) | ||
80 | |||
81 | #define FWH_3MiB (FWH_F8_EN | FWH_F0_EN | FWH_E8_EN | FWH_E0_EN | \ | ||
82 | FWH_D8_EN | FWH_D0_EN) | ||
83 | |||
84 | #define FWH_2_5MiB (FWH_F8_EN | FWH_F0_EN | FWH_E8_EN | FWH_E0_EN | \ | ||
85 | FWH_D8_EN) | ||
86 | |||
87 | #define FWH_2MiB (FWH_F8_EN | FWH_F0_EN | FWH_E8_EN | FWH_E0_EN) | ||
88 | |||
89 | #define FWH_1_5MiB (FWH_F8_EN | FWH_F0_EN | FWH_E8_EN) | ||
90 | |||
91 | #define FWH_1MiB (FWH_F8_EN | FWH_F0_EN) | ||
92 | |||
93 | #define FWH_0_5MiB (FWH_F8_EN) | ||
94 | |||
95 | |||
96 | struct esb2rom_window { | ||
97 | void __iomem* virt; | ||
98 | unsigned long phys; | ||
99 | unsigned long size; | ||
100 | struct list_head maps; | ||
101 | struct resource rsrc; | ||
102 | struct pci_dev *pdev; | ||
103 | }; | ||
104 | |||
105 | struct esb2rom_map_info { | ||
106 | struct list_head list; | ||
107 | struct map_info map; | ||
108 | struct mtd_info *mtd; | ||
109 | struct resource rsrc; | ||
110 | char map_name[sizeof(MOD_NAME) + 2 + ADDRESS_NAME_LEN]; | ||
111 | }; | ||
112 | |||
113 | static struct esb2rom_window esb2rom_window = { | ||
114 | .maps = LIST_HEAD_INIT(esb2rom_window.maps), | ||
115 | }; | ||
116 | |||
117 | static void esb2rom_cleanup(struct esb2rom_window *window) | ||
118 | { | ||
119 | struct esb2rom_map_info *map, *scratch; | ||
120 | u8 byte; | ||
121 | |||
122 | /* Disable writes through the rom window */ | ||
123 | pci_read_config_byte(window->pdev, BIOS_CNTL, &byte); | ||
124 | pci_write_config_byte(window->pdev, BIOS_CNTL, | ||
125 | byte & ~BIOS_WRITE_ENABLE); | ||
126 | |||
127 | /* Free all of the mtd devices */ | ||
128 | list_for_each_entry_safe(map, scratch, &window->maps, list) { | ||
129 | if (map->rsrc.parent) | ||
130 | release_resource(&map->rsrc); | ||
131 | del_mtd_device(map->mtd); | ||
132 | map_destroy(map->mtd); | ||
133 | list_del(&map->list); | ||
134 | kfree(map); | ||
135 | } | ||
136 | if (window->rsrc.parent) | ||
137 | release_resource(&window->rsrc); | ||
138 | if (window->virt) { | ||
139 | iounmap(window->virt); | ||
140 | window->virt = NULL; | ||
141 | window->phys = 0; | ||
142 | window->size = 0; | ||
143 | } | ||
144 | pci_dev_put(window->pdev); | ||
145 | } | ||
146 | |||
147 | static int __devinit esb2rom_init_one(struct pci_dev *pdev, | ||
148 | const struct pci_device_id *ent) | ||
149 | { | ||
150 | static char *rom_probe_types[] = { "cfi_probe", "jedec_probe", NULL }; | ||
151 | struct esb2rom_window *window = &esb2rom_window; | ||
152 | struct esb2rom_map_info *map = NULL; | ||
153 | unsigned long map_top; | ||
154 | u8 byte; | ||
155 | u16 word; | ||
156 | |||
157 | /* For now I just handle the ecb2 and I assume there | ||
158 | * are not a lot of resources up at the top of the address | ||
159 | * space. It is possible to handle other devices in the | ||
160 | * top 16MiB but it is very painful. Also since | ||
161 | * you can only really attach a FWH to an ICHX there | ||
162 | * a number of simplifications you can make. | ||
163 | * | ||
164 | * Also you can page firmware hubs if an 8MiB window isn't enough | ||
165 | * but don't currently handle that case either. | ||
166 | */ | ||
167 | window->pdev = pci_dev_get(pdev); | ||
168 | |||
169 | /* RLG: experiment 2. Force the window registers to the widest values */ | ||
170 | |||
171 | /* | ||
172 | pci_read_config_word(pdev, FWH_DEC_EN1, &word); | ||
173 | printk(KERN_DEBUG "Original FWH_DEC_EN1 : %x\n", word); | ||
174 | pci_write_config_byte(pdev, FWH_DEC_EN1, 0xff); | ||
175 | pci_read_config_byte(pdev, FWH_DEC_EN1, &byte); | ||
176 | printk(KERN_DEBUG "New FWH_DEC_EN1 : %x\n", byte); | ||
177 | |||
178 | pci_read_config_byte(pdev, FWH_DEC_EN2, &byte); | ||
179 | printk(KERN_DEBUG "Original FWH_DEC_EN2 : %x\n", byte); | ||
180 | pci_write_config_byte(pdev, FWH_DEC_EN2, 0x0f); | ||
181 | pci_read_config_byte(pdev, FWH_DEC_EN2, &byte); | ||
182 | printk(KERN_DEBUG "New FWH_DEC_EN2 : %x\n", byte); | ||
183 | */ | ||
184 | |||
185 | /* Find a region continuous to the end of the ROM window */ | ||
186 | window->phys = 0; | ||
187 | pci_read_config_word(pdev, FWH_DEC_EN1, &word); | ||
188 | printk(KERN_DEBUG "pci_read_config_byte : %x\n", word); | ||
189 | |||
190 | if ((word & FWH_8MiB) == FWH_8MiB) | ||
191 | window->phys = 0xff400000; | ||
192 | else if ((word & FWH_7MiB) == FWH_7MiB) | ||
193 | window->phys = 0xff500000; | ||
194 | else if ((word & FWH_6MiB) == FWH_6MiB) | ||
195 | window->phys = 0xff600000; | ||
196 | else if ((word & FWH_5MiB) == FWH_5MiB) | ||
197 | window->phys = 0xFF700000; | ||
198 | else if ((word & FWH_4MiB) == FWH_4MiB) | ||
199 | window->phys = 0xffc00000; | ||
200 | else if ((word & FWH_3_5MiB) == FWH_3_5MiB) | ||
201 | window->phys = 0xffc80000; | ||
202 | else if ((word & FWH_3MiB) == FWH_3MiB) | ||
203 | window->phys = 0xffd00000; | ||
204 | else if ((word & FWH_2_5MiB) == FWH_2_5MiB) | ||
205 | window->phys = 0xffd80000; | ||
206 | else if ((word & FWH_2MiB) == FWH_2MiB) | ||
207 | window->phys = 0xffe00000; | ||
208 | else if ((word & FWH_1_5MiB) == FWH_1_5MiB) | ||
209 | window->phys = 0xffe80000; | ||
210 | else if ((word & FWH_1MiB) == FWH_1MiB) | ||
211 | window->phys = 0xfff00000; | ||
212 | else if ((word & FWH_0_5MiB) == FWH_0_5MiB) | ||
213 | window->phys = 0xfff80000; | ||
214 | |||
215 | /* reserved 0x0020 and 0x0010 */ | ||
216 | window->phys -= 0x400000UL; | ||
217 | window->size = (0xffffffffUL - window->phys) + 1UL; | ||
218 | |||
219 | /* Enable writes through the rom window */ | ||
220 | pci_read_config_byte(pdev, BIOS_CNTL, &byte); | ||
221 | if (!(byte & BIOS_WRITE_ENABLE) && (byte & (BIOS_LOCK_ENABLE))) { | ||
222 | /* The BIOS will generate an error if I enable | ||
223 | * this device, so don't even try. | ||
224 | */ | ||
225 | printk(KERN_ERR MOD_NAME ": firmware access control, I can't enable writes\n"); | ||
226 | goto out; | ||
227 | } | ||
228 | pci_write_config_byte(pdev, BIOS_CNTL, byte | BIOS_WRITE_ENABLE); | ||
229 | |||
230 | /* | ||
231 | * Try to reserve the window mem region. If this fails then | ||
232 | * it is likely due to the window being "reseved" by the BIOS. | ||
233 | */ | ||
234 | window->rsrc.name = MOD_NAME; | ||
235 | window->rsrc.start = window->phys; | ||
236 | window->rsrc.end = window->phys + window->size - 1; | ||
237 | window->rsrc.flags = IORESOURCE_MEM | IORESOURCE_BUSY; | ||
238 | if (request_resource(&iomem_resource, &window->rsrc)) { | ||
239 | window->rsrc.parent = NULL; | ||
240 | printk(KERN_DEBUG MOD_NAME | ||
241 | ": %s(): Unable to register resource" | ||
242 | " 0x%.08llx-0x%.08llx - kernel bug?\n", | ||
243 | __func__, | ||
244 | (unsigned long long)window->rsrc.start, | ||
245 | (unsigned long long)window->rsrc.end); | ||
246 | } | ||
247 | |||
248 | /* Map the firmware hub into my address space. */ | ||
249 | window->virt = ioremap_nocache(window->phys, window->size); | ||
250 | if (!window->virt) { | ||
251 | printk(KERN_ERR MOD_NAME ": ioremap(%08lx, %08lx) failed\n", | ||
252 | window->phys, window->size); | ||
253 | goto out; | ||
254 | } | ||
255 | |||
256 | /* Get the first address to look for an rom chip at */ | ||
257 | map_top = window->phys; | ||
258 | if ((window->phys & 0x3fffff) != 0) { | ||
259 | /* if not aligned on 4MiB, look 4MiB lower in address space */ | ||
260 | map_top = window->phys + 0x400000; | ||
261 | } | ||
262 | #if 1 | ||
263 | /* The probe sequence run over the firmware hub lock | ||
264 | * registers sets them to 0x7 (no access). | ||
265 | * (Insane hardware design, but most copied Intel's.) | ||
266 | * ==> Probe at most the last 4M of the address space. | ||
267 | */ | ||
268 | if (map_top < 0xffc00000) | ||
269 | map_top = 0xffc00000; | ||
270 | #endif | ||
271 | /* Loop through and look for rom chips */ | ||
272 | while ((map_top - 1) < 0xffffffffUL) { | ||
273 | struct cfi_private *cfi; | ||
274 | unsigned long offset; | ||
275 | int i; | ||
276 | |||
277 | if (!map) | ||
278 | map = kmalloc(sizeof(*map), GFP_KERNEL); | ||
279 | if (!map) { | ||
280 | printk(KERN_ERR MOD_NAME ": kmalloc failed"); | ||
281 | goto out; | ||
282 | } | ||
283 | memset(map, 0, sizeof(*map)); | ||
284 | INIT_LIST_HEAD(&map->list); | ||
285 | map->map.name = map->map_name; | ||
286 | map->map.phys = map_top; | ||
287 | offset = map_top - window->phys; | ||
288 | map->map.virt = (void __iomem *) | ||
289 | (((unsigned long)(window->virt)) + offset); | ||
290 | map->map.size = 0xffffffffUL - map_top + 1UL; | ||
291 | /* Set the name of the map to the address I am trying */ | ||
292 | sprintf(map->map_name, "%s @%08lx", | ||
293 | MOD_NAME, map->map.phys); | ||
294 | |||
295 | /* Firmware hubs only use vpp when being programmed | ||
296 | * in a factory setting. So in-place programming | ||
297 | * needs to use a different method. | ||
298 | */ | ||
299 | for(map->map.bankwidth = 32; map->map.bankwidth; | ||
300 | map->map.bankwidth >>= 1) { | ||
301 | char **probe_type; | ||
302 | /* Skip bankwidths that are not supported */ | ||
303 | if (!map_bankwidth_supported(map->map.bankwidth)) | ||
304 | continue; | ||
305 | |||
306 | /* Setup the map methods */ | ||
307 | simple_map_init(&map->map); | ||
308 | |||
309 | /* Try all of the probe methods */ | ||
310 | probe_type = rom_probe_types; | ||
311 | for(; *probe_type; probe_type++) { | ||
312 | map->mtd = do_map_probe(*probe_type, &map->map); | ||
313 | if (map->mtd) | ||
314 | goto found; | ||
315 | } | ||
316 | } | ||
317 | map_top += ROM_PROBE_STEP_SIZE; | ||
318 | continue; | ||
319 | found: | ||
320 | /* Trim the size if we are larger than the map */ | ||
321 | if (map->mtd->size > map->map.size) { | ||
322 | printk(KERN_WARNING MOD_NAME | ||
323 | " rom(%u) larger than window(%lu). fixing...\n", | ||
324 | map->mtd->size, map->map.size); | ||
325 | map->mtd->size = map->map.size; | ||
326 | } | ||
327 | if (window->rsrc.parent) { | ||
328 | /* | ||
329 | * Registering the MTD device in iomem may not be possible | ||
330 | * if there is a BIOS "reserved" and BUSY range. If this | ||
331 | * fails then continue anyway. | ||
332 | */ | ||
333 | map->rsrc.name = map->map_name; | ||
334 | map->rsrc.start = map->map.phys; | ||
335 | map->rsrc.end = map->map.phys + map->mtd->size - 1; | ||
336 | map->rsrc.flags = IORESOURCE_MEM | IORESOURCE_BUSY; | ||
337 | if (request_resource(&window->rsrc, &map->rsrc)) { | ||
338 | printk(KERN_ERR MOD_NAME | ||
339 | ": cannot reserve MTD resource\n"); | ||
340 | map->rsrc.parent = NULL; | ||
341 | } | ||
342 | } | ||
343 | |||
344 | /* Make the whole region visible in the map */ | ||
345 | map->map.virt = window->virt; | ||
346 | map->map.phys = window->phys; | ||
347 | cfi = map->map.fldrv_priv; | ||
348 | for(i = 0; i < cfi->numchips; i++) | ||
349 | cfi->chips[i].start += offset; | ||
350 | |||
351 | /* Now that the mtd devices is complete claim and export it */ | ||
352 | map->mtd->owner = THIS_MODULE; | ||
353 | if (add_mtd_device(map->mtd)) { | ||
354 | map_destroy(map->mtd); | ||
355 | map->mtd = NULL; | ||
356 | goto out; | ||
357 | } | ||
358 | |||
359 | /* Calculate the new value of map_top */ | ||
360 | map_top += map->mtd->size; | ||
361 | |||
362 | /* File away the map structure */ | ||
363 | list_add(&map->list, &window->maps); | ||
364 | map = NULL; | ||
365 | } | ||
366 | |||
367 | out: | ||
368 | /* Free any left over map structures */ | ||
369 | kfree(map); | ||
370 | |||
371 | /* See if I have any map structures */ | ||
372 | if (list_empty(&window->maps)) { | ||
373 | esb2rom_cleanup(window); | ||
374 | return -ENODEV; | ||
375 | } | ||
376 | return 0; | ||
377 | } | ||
378 | |||
379 | static void __devexit esb2rom_remove_one (struct pci_dev *pdev) | ||
380 | { | ||
381 | struct esb2rom_window *window = &esb2rom_window; | ||
382 | esb2rom_cleanup(window); | ||
383 | } | ||
384 | |||
385 | static struct pci_device_id esb2rom_pci_tbl[] __devinitdata = { | ||
386 | { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_0, | ||
387 | PCI_ANY_ID, PCI_ANY_ID, }, | ||
388 | { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_0, | ||
389 | PCI_ANY_ID, PCI_ANY_ID, }, | ||
390 | { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_0, | ||
391 | PCI_ANY_ID, PCI_ANY_ID, }, | ||
392 | { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_0, | ||
393 | PCI_ANY_ID, PCI_ANY_ID, }, | ||
394 | { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ESB_1, | ||
395 | PCI_ANY_ID, PCI_ANY_ID, }, | ||
396 | { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ESB2_0, | ||
397 | PCI_ANY_ID, PCI_ANY_ID, }, | ||
398 | { 0, }, | ||
399 | }; | ||
400 | |||
401 | #if 0 | ||
402 | MODULE_DEVICE_TABLE(pci, esb2rom_pci_tbl); | ||
403 | |||
404 | static struct pci_driver esb2rom_driver = { | ||
405 | .name = MOD_NAME, | ||
406 | .id_table = esb2rom_pci_tbl, | ||
407 | .probe = esb2rom_init_one, | ||
408 | .remove = esb2rom_remove_one, | ||
409 | }; | ||
410 | #endif | ||
411 | |||
412 | static int __init init_esb2rom(void) | ||
413 | { | ||
414 | struct pci_dev *pdev; | ||
415 | struct pci_device_id *id; | ||
416 | int retVal; | ||
417 | |||
418 | pdev = NULL; | ||
419 | for (id = esb2rom_pci_tbl; id->vendor; id++) { | ||
420 | printk(KERN_DEBUG "device id = %x\n", id->device); | ||
421 | pdev = pci_get_device(id->vendor, id->device, NULL); | ||
422 | if (pdev) { | ||
423 | printk(KERN_DEBUG "matched device = %x\n", id->device); | ||
424 | break; | ||
425 | } | ||
426 | } | ||
427 | if (pdev) { | ||
428 | printk(KERN_DEBUG "matched device id %x\n", id->device); | ||
429 | retVal = esb2rom_init_one(pdev, &esb2rom_pci_tbl[0]); | ||
430 | pci_dev_put(pdev); | ||
431 | printk(KERN_DEBUG "retVal = %d\n", retVal); | ||
432 | return retVal; | ||
433 | } | ||
434 | return -ENXIO; | ||
435 | #if 0 | ||
436 | return pci_register_driver(&esb2rom_driver); | ||
437 | #endif | ||
438 | } | ||
439 | |||
440 | static void __exit cleanup_esb2rom(void) | ||
441 | { | ||
442 | esb2rom_remove_one(esb2rom_window.pdev); | ||
443 | } | ||
444 | |||
445 | module_init(init_esb2rom); | ||
446 | module_exit(cleanup_esb2rom); | ||
447 | |||
448 | MODULE_LICENSE("GPL"); | ||
449 | MODULE_AUTHOR("Lew Glendenning <lglendenning@lnxi.com>"); | ||
450 | MODULE_DESCRIPTION("MTD map driver for BIOS chips on the ESB2 southbridge"); | ||
diff --git a/drivers/mtd/maps/integrator-flash.c b/drivers/mtd/maps/integrator-flash.c index c8db01b3e45f..6946d802e6f6 100644 --- a/drivers/mtd/maps/integrator-flash.c +++ b/drivers/mtd/maps/integrator-flash.c | |||
@@ -75,14 +75,12 @@ static int armflash_probe(struct platform_device *dev) | |||
75 | int err; | 75 | int err; |
76 | void __iomem *base; | 76 | void __iomem *base; |
77 | 77 | ||
78 | info = kmalloc(sizeof(struct armflash_info), GFP_KERNEL); | 78 | info = kzalloc(sizeof(struct armflash_info), GFP_KERNEL); |
79 | if (!info) { | 79 | if (!info) { |
80 | err = -ENOMEM; | 80 | err = -ENOMEM; |
81 | goto out; | 81 | goto out; |
82 | } | 82 | } |
83 | 83 | ||
84 | memset(info, 0, sizeof(struct armflash_info)); | ||
85 | |||
86 | info->plat = plat; | 84 | info->plat = plat; |
87 | if (plat && plat->init) { | 85 | if (plat && plat->init) { |
88 | err = plat->init(); | 86 | err = plat->init(); |
diff --git a/drivers/mtd/maps/nettel.c b/drivers/mtd/maps/nettel.c index f9e8e5bcbc33..9f53c655af3a 100644 --- a/drivers/mtd/maps/nettel.c +++ b/drivers/mtd/maps/nettel.c | |||
@@ -20,6 +20,7 @@ | |||
20 | #include <linux/mtd/partitions.h> | 20 | #include <linux/mtd/partitions.h> |
21 | #include <linux/mtd/cfi.h> | 21 | #include <linux/mtd/cfi.h> |
22 | #include <linux/reboot.h> | 22 | #include <linux/reboot.h> |
23 | #include <linux/err.h> | ||
23 | #include <linux/kdev_t.h> | 24 | #include <linux/kdev_t.h> |
24 | #include <linux/root_dev.h> | 25 | #include <linux/root_dev.h> |
25 | #include <asm/io.h> | 26 | #include <asm/io.h> |
@@ -178,7 +179,7 @@ int nettel_eraseconfig(void) | |||
178 | 179 | ||
179 | init_waitqueue_head(&wait_q); | 180 | init_waitqueue_head(&wait_q); |
180 | mtd = get_mtd_device(NULL, 2); | 181 | mtd = get_mtd_device(NULL, 2); |
181 | if (mtd) { | 182 | if (!IS_ERR(mtd)) { |
182 | nettel_erase.mtd = mtd; | 183 | nettel_erase.mtd = mtd; |
183 | nettel_erase.callback = nettel_erasecallback; | 184 | nettel_erase.callback = nettel_erasecallback; |
184 | nettel_erase.callback = NULL; | 185 | nettel_erase.callback = NULL; |
@@ -471,7 +472,7 @@ out_unmap2: | |||
471 | iounmap(nettel_amd_map.virt); | 472 | iounmap(nettel_amd_map.virt); |
472 | 473 | ||
473 | return(rc); | 474 | return(rc); |
474 | 475 | ||
475 | } | 476 | } |
476 | 477 | ||
477 | /****************************************************************************/ | 478 | /****************************************************************************/ |
diff --git a/drivers/mtd/maps/omap_nor.c b/drivers/mtd/maps/omap_nor.c index 418afffb2d80..e8d9ae535673 100644 --- a/drivers/mtd/maps/omap_nor.c +++ b/drivers/mtd/maps/omap_nor.c | |||
@@ -78,12 +78,10 @@ static int __devinit omapflash_probe(struct platform_device *pdev) | |||
78 | struct resource *res = pdev->resource; | 78 | struct resource *res = pdev->resource; |
79 | unsigned long size = res->end - res->start + 1; | 79 | unsigned long size = res->end - res->start + 1; |
80 | 80 | ||
81 | info = kmalloc(sizeof(struct omapflash_info), GFP_KERNEL); | 81 | info = kzalloc(sizeof(struct omapflash_info), GFP_KERNEL); |
82 | if (!info) | 82 | if (!info) |
83 | return -ENOMEM; | 83 | return -ENOMEM; |
84 | 84 | ||
85 | memset(info, 0, sizeof(struct omapflash_info)); | ||
86 | |||
87 | if (!request_mem_region(res->start, size, "flash")) { | 85 | if (!request_mem_region(res->start, size, "flash")) { |
88 | err = -EBUSY; | 86 | err = -EBUSY; |
89 | goto out_free_info; | 87 | goto out_free_info; |
diff --git a/drivers/mtd/maps/pcmciamtd.c b/drivers/mtd/maps/pcmciamtd.c index 995347b1beba..eaeb56a4070a 100644 --- a/drivers/mtd/maps/pcmciamtd.c +++ b/drivers/mtd/maps/pcmciamtd.c | |||
@@ -735,11 +735,10 @@ static int pcmciamtd_probe(struct pcmcia_device *link) | |||
735 | struct pcmciamtd_dev *dev; | 735 | struct pcmciamtd_dev *dev; |
736 | 736 | ||
737 | /* Create new memory card device */ | 737 | /* Create new memory card device */ |
738 | dev = kmalloc(sizeof(*dev), GFP_KERNEL); | 738 | dev = kzalloc(sizeof(*dev), GFP_KERNEL); |
739 | if (!dev) return -ENOMEM; | 739 | if (!dev) return -ENOMEM; |
740 | DEBUG(1, "dev=0x%p", dev); | 740 | DEBUG(1, "dev=0x%p", dev); |
741 | 741 | ||
742 | memset(dev, 0, sizeof(*dev)); | ||
743 | dev->p_dev = link; | 742 | dev->p_dev = link; |
744 | link->priv = dev; | 743 | link->priv = dev; |
745 | 744 | ||
diff --git a/drivers/mtd/maps/physmap.c b/drivers/mtd/maps/physmap.c index d1717763f719..28c5ffd75233 100644 --- a/drivers/mtd/maps/physmap.c +++ b/drivers/mtd/maps/physmap.c | |||
@@ -89,15 +89,14 @@ static int physmap_flash_probe(struct platform_device *dev) | |||
89 | return -ENODEV; | 89 | return -ENODEV; |
90 | 90 | ||
91 | printk(KERN_NOTICE "physmap platform flash device: %.8llx at %.8llx\n", | 91 | printk(KERN_NOTICE "physmap platform flash device: %.8llx at %.8llx\n", |
92 | (unsigned long long)dev->resource->end - dev->resource->start + 1, | 92 | (unsigned long long)(dev->resource->end - dev->resource->start + 1), |
93 | (unsigned long long)dev->resource->start); | 93 | (unsigned long long)dev->resource->start); |
94 | 94 | ||
95 | info = kmalloc(sizeof(struct physmap_flash_info), GFP_KERNEL); | 95 | info = kzalloc(sizeof(struct physmap_flash_info), GFP_KERNEL); |
96 | if (info == NULL) { | 96 | if (info == NULL) { |
97 | err = -ENOMEM; | 97 | err = -ENOMEM; |
98 | goto err_out; | 98 | goto err_out; |
99 | } | 99 | } |
100 | memset(info, 0, sizeof(*info)); | ||
101 | 100 | ||
102 | platform_set_drvdata(dev, info); | 101 | platform_set_drvdata(dev, info); |
103 | 102 | ||
diff --git a/drivers/mtd/maps/physmap_of.c b/drivers/mtd/maps/physmap_of.c new file mode 100644 index 000000000000..7efe744ad31e --- /dev/null +++ b/drivers/mtd/maps/physmap_of.c | |||
@@ -0,0 +1,255 @@ | |||
1 | /* | ||
2 | * Normal mappings of chips in physical memory for OF devices | ||
3 | * | ||
4 | * Copyright (C) 2006 MontaVista Software Inc. | ||
5 | * Author: Vitaly Wool <vwool@ru.mvista.com> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify it | ||
8 | * under the terms of the GNU General Public License as published by the | ||
9 | * Free Software Foundation; either version 2 of the License, or (at your | ||
10 | * option) any later version. | ||
11 | */ | ||
12 | |||
13 | #include <linux/module.h> | ||
14 | #include <linux/types.h> | ||
15 | #include <linux/kernel.h> | ||
16 | #include <linux/init.h> | ||
17 | #include <linux/slab.h> | ||
18 | #include <linux/device.h> | ||
19 | #include <linux/mtd/mtd.h> | ||
20 | #include <linux/mtd/map.h> | ||
21 | #include <linux/mtd/partitions.h> | ||
22 | #include <linux/mtd/physmap.h> | ||
23 | #include <asm/io.h> | ||
24 | #include <asm/prom.h> | ||
25 | #include <asm/of_device.h> | ||
26 | #include <asm/of_platform.h> | ||
27 | |||
28 | struct physmap_flash_info { | ||
29 | struct mtd_info *mtd; | ||
30 | struct map_info map; | ||
31 | struct resource *res; | ||
32 | #ifdef CONFIG_MTD_PARTITIONS | ||
33 | int nr_parts; | ||
34 | struct mtd_partition *parts; | ||
35 | #endif | ||
36 | }; | ||
37 | |||
38 | static const char *rom_probe_types[] = { "cfi_probe", "jedec_probe", "map_rom", NULL }; | ||
39 | #ifdef CONFIG_MTD_PARTITIONS | ||
40 | static const char *part_probe_types[] = { "cmdlinepart", "RedBoot", NULL }; | ||
41 | #endif | ||
42 | |||
43 | #ifdef CONFIG_MTD_PARTITIONS | ||
44 | static int parse_flash_partitions(struct device_node *node, | ||
45 | struct mtd_partition **parts) | ||
46 | { | ||
47 | int i, plen, retval = -ENOMEM; | ||
48 | const u32 *part; | ||
49 | const char *name; | ||
50 | |||
51 | part = get_property(node, "partitions", &plen); | ||
52 | if (part == NULL) | ||
53 | goto err; | ||
54 | |||
55 | retval = plen / (2 * sizeof(u32)); | ||
56 | *parts = kzalloc(retval * sizeof(struct mtd_partition), GFP_KERNEL); | ||
57 | if (*parts == NULL) { | ||
58 | printk(KERN_ERR "Can't allocate the flash partition data!\n"); | ||
59 | goto err; | ||
60 | } | ||
61 | |||
62 | name = get_property(node, "partition-names", &plen); | ||
63 | |||
64 | for (i = 0; i < retval; i++) { | ||
65 | (*parts)[i].offset = *part++; | ||
66 | (*parts)[i].size = *part & ~1; | ||
67 | if (*part++ & 1) /* bit 0 set signifies read only partition */ | ||
68 | (*parts)[i].mask_flags = MTD_WRITEABLE; | ||
69 | |||
70 | if (name != NULL && plen > 0) { | ||
71 | int len = strlen(name) + 1; | ||
72 | |||
73 | (*parts)[i].name = (char *)name; | ||
74 | plen -= len; | ||
75 | name += len; | ||
76 | } else | ||
77 | (*parts)[i].name = "unnamed"; | ||
78 | } | ||
79 | err: | ||
80 | return retval; | ||
81 | } | ||
82 | #endif | ||
83 | |||
84 | static int of_physmap_remove(struct of_device *dev) | ||
85 | { | ||
86 | struct physmap_flash_info *info; | ||
87 | |||
88 | info = dev_get_drvdata(&dev->dev); | ||
89 | if (info == NULL) | ||
90 | return 0; | ||
91 | dev_set_drvdata(&dev->dev, NULL); | ||
92 | |||
93 | if (info->mtd != NULL) { | ||
94 | #ifdef CONFIG_MTD_PARTITIONS | ||
95 | if (info->nr_parts) { | ||
96 | del_mtd_partitions(info->mtd); | ||
97 | kfree(info->parts); | ||
98 | } else { | ||
99 | del_mtd_device(info->mtd); | ||
100 | } | ||
101 | #else | ||
102 | del_mtd_device(info->mtd); | ||
103 | #endif | ||
104 | map_destroy(info->mtd); | ||
105 | } | ||
106 | |||
107 | if (info->map.virt != NULL) | ||
108 | iounmap(info->map.virt); | ||
109 | |||
110 | if (info->res != NULL) { | ||
111 | release_resource(info->res); | ||
112 | kfree(info->res); | ||
113 | } | ||
114 | |||
115 | return 0; | ||
116 | } | ||
117 | |||
118 | static int __devinit of_physmap_probe(struct of_device *dev, const struct of_device_id *match) | ||
119 | { | ||
120 | struct device_node *dp = dev->node; | ||
121 | struct resource res; | ||
122 | struct physmap_flash_info *info; | ||
123 | const char **probe_type; | ||
124 | const char *of_probe; | ||
125 | const u32 *width; | ||
126 | int err; | ||
127 | |||
128 | |||
129 | if (of_address_to_resource(dp, 0, &res)) { | ||
130 | dev_err(&dev->dev, "Can't get the flash mapping!\n"); | ||
131 | err = -EINVAL; | ||
132 | goto err_out; | ||
133 | } | ||
134 | |||
135 | dev_dbg(&dev->dev, "physmap flash device: %.8llx at %.8llx\n", | ||
136 | (unsigned long long)res.end - res.start + 1, | ||
137 | (unsigned long long)res.start); | ||
138 | |||
139 | info = kzalloc(sizeof(struct physmap_flash_info), GFP_KERNEL); | ||
140 | if (info == NULL) { | ||
141 | err = -ENOMEM; | ||
142 | goto err_out; | ||
143 | } | ||
144 | memset(info, 0, sizeof(*info)); | ||
145 | |||
146 | dev_set_drvdata(&dev->dev, info); | ||
147 | |||
148 | info->res = request_mem_region(res.start, res.end - res.start + 1, | ||
149 | dev->dev.bus_id); | ||
150 | if (info->res == NULL) { | ||
151 | dev_err(&dev->dev, "Could not reserve memory region\n"); | ||
152 | err = -ENOMEM; | ||
153 | goto err_out; | ||
154 | } | ||
155 | |||
156 | width = get_property(dp, "bank-width", NULL); | ||
157 | if (width == NULL) { | ||
158 | dev_err(&dev->dev, "Can't get the flash bank width!\n"); | ||
159 | err = -EINVAL; | ||
160 | goto err_out; | ||
161 | } | ||
162 | |||
163 | info->map.name = dev->dev.bus_id; | ||
164 | info->map.phys = res.start; | ||
165 | info->map.size = res.end - res.start + 1; | ||
166 | info->map.bankwidth = *width; | ||
167 | |||
168 | info->map.virt = ioremap(info->map.phys, info->map.size); | ||
169 | if (info->map.virt == NULL) { | ||
170 | dev_err(&dev->dev, "Failed to ioremap flash region\n"); | ||
171 | err = EIO; | ||
172 | goto err_out; | ||
173 | } | ||
174 | |||
175 | simple_map_init(&info->map); | ||
176 | |||
177 | of_probe = get_property(dp, "probe-type", NULL); | ||
178 | if (of_probe == NULL) { | ||
179 | probe_type = rom_probe_types; | ||
180 | for (; info->mtd == NULL && *probe_type != NULL; probe_type++) | ||
181 | info->mtd = do_map_probe(*probe_type, &info->map); | ||
182 | } else if (!strcmp(of_probe, "CFI")) | ||
183 | info->mtd = do_map_probe("cfi_probe", &info->map); | ||
184 | else if (!strcmp(of_probe, "JEDEC")) | ||
185 | info->mtd = do_map_probe("jedec_probe", &info->map); | ||
186 | else { | ||
187 | if (strcmp(of_probe, "ROM")) | ||
188 | dev_dbg(&dev->dev, "map_probe: don't know probe type " | ||
189 | "'%s', mapping as rom\n"); | ||
190 | info->mtd = do_map_probe("mtd_rom", &info->map); | ||
191 | } | ||
192 | if (info->mtd == NULL) { | ||
193 | dev_err(&dev->dev, "map_probe failed\n"); | ||
194 | err = -ENXIO; | ||
195 | goto err_out; | ||
196 | } | ||
197 | info->mtd->owner = THIS_MODULE; | ||
198 | |||
199 | #ifdef CONFIG_MTD_PARTITIONS | ||
200 | err = parse_mtd_partitions(info->mtd, part_probe_types, &info->parts, 0); | ||
201 | if (err > 0) { | ||
202 | add_mtd_partitions(info->mtd, info->parts, err); | ||
203 | } else if ((err = parse_flash_partitions(dp, &info->parts)) > 0) { | ||
204 | dev_info(&dev->dev, "Using OF partition information\n"); | ||
205 | add_mtd_partitions(info->mtd, info->parts, err); | ||
206 | info->nr_parts = err; | ||
207 | } else | ||
208 | #endif | ||
209 | |||
210 | add_mtd_device(info->mtd); | ||
211 | return 0; | ||
212 | |||
213 | err_out: | ||
214 | of_physmap_remove(dev); | ||
215 | return err; | ||
216 | |||
217 | return 0; | ||
218 | |||
219 | |||
220 | } | ||
221 | |||
222 | static struct of_device_id of_physmap_match[] = { | ||
223 | { | ||
224 | .type = "rom", | ||
225 | .compatible = "direct-mapped" | ||
226 | }, | ||
227 | { }, | ||
228 | }; | ||
229 | |||
230 | MODULE_DEVICE_TABLE(of, of_physmap_match); | ||
231 | |||
232 | |||
233 | static struct of_platform_driver of_physmap_flash_driver = { | ||
234 | .name = "physmap-flash", | ||
235 | .match_table = of_physmap_match, | ||
236 | .probe = of_physmap_probe, | ||
237 | .remove = of_physmap_remove, | ||
238 | }; | ||
239 | |||
240 | static int __init of_physmap_init(void) | ||
241 | { | ||
242 | return of_register_platform_driver(&of_physmap_flash_driver); | ||
243 | } | ||
244 | |||
245 | static void __exit of_physmap_exit(void) | ||
246 | { | ||
247 | of_unregister_platform_driver(&of_physmap_flash_driver); | ||
248 | } | ||
249 | |||
250 | module_init(of_physmap_init); | ||
251 | module_exit(of_physmap_exit); | ||
252 | |||
253 | MODULE_LICENSE("GPL"); | ||
254 | MODULE_AUTHOR("Vitaly Wool <vwool@ru.mvista.com>"); | ||
255 | MODULE_DESCRIPTION("Configurable MTD map driver for OF"); | ||
diff --git a/drivers/mtd/maps/plat-ram.c b/drivers/mtd/maps/plat-ram.c index 5d3c75451ca2..2b6504ecbbd1 100644 --- a/drivers/mtd/maps/plat-ram.c +++ b/drivers/mtd/maps/plat-ram.c | |||
@@ -147,14 +147,13 @@ static int platram_probe(struct platform_device *pdev) | |||
147 | 147 | ||
148 | pdata = pdev->dev.platform_data; | 148 | pdata = pdev->dev.platform_data; |
149 | 149 | ||
150 | info = kmalloc(sizeof(*info), GFP_KERNEL); | 150 | info = kzalloc(sizeof(*info), GFP_KERNEL); |
151 | if (info == NULL) { | 151 | if (info == NULL) { |
152 | dev_err(&pdev->dev, "no memory for flash info\n"); | 152 | dev_err(&pdev->dev, "no memory for flash info\n"); |
153 | err = -ENOMEM; | 153 | err = -ENOMEM; |
154 | goto exit_error; | 154 | goto exit_error; |
155 | } | 155 | } |
156 | 156 | ||
157 | memset(info, 0, sizeof(*info)); | ||
158 | platform_set_drvdata(pdev, info); | 157 | platform_set_drvdata(pdev, info); |
159 | 158 | ||
160 | info->dev = &pdev->dev; | 159 | info->dev = &pdev->dev; |
diff --git a/drivers/mtd/maps/sa1100-flash.c b/drivers/mtd/maps/sa1100-flash.c index 950bf1c57841..f904e6bd02e0 100644 --- a/drivers/mtd/maps/sa1100-flash.c +++ b/drivers/mtd/maps/sa1100-flash.c | |||
@@ -273,14 +273,12 @@ sa1100_setup_mtd(struct platform_device *pdev, struct flash_platform_data *plat) | |||
273 | /* | 273 | /* |
274 | * Allocate the map_info structs in one go. | 274 | * Allocate the map_info structs in one go. |
275 | */ | 275 | */ |
276 | info = kmalloc(size, GFP_KERNEL); | 276 | info = kzalloc(size, GFP_KERNEL); |
277 | if (!info) { | 277 | if (!info) { |
278 | ret = -ENOMEM; | 278 | ret = -ENOMEM; |
279 | goto out; | 279 | goto out; |
280 | } | 280 | } |
281 | 281 | ||
282 | memset(info, 0, size); | ||
283 | |||
284 | if (plat->init) { | 282 | if (plat->init) { |
285 | ret = plat->init(); | 283 | ret = plat->init(); |
286 | if (ret) | 284 | if (ret) |
diff --git a/drivers/mtd/maps/tqm834x.c b/drivers/mtd/maps/tqm834x.c index 58e5912bd381..9adc970e55e6 100644 --- a/drivers/mtd/maps/tqm834x.c +++ b/drivers/mtd/maps/tqm834x.c | |||
@@ -132,20 +132,16 @@ static int __init init_tqm834x_mtd(void) | |||
132 | 132 | ||
133 | pr_debug("%s: chip probing count %d\n", __FUNCTION__, idx); | 133 | pr_debug("%s: chip probing count %d\n", __FUNCTION__, idx); |
134 | 134 | ||
135 | map_banks[idx] = | 135 | map_banks[idx] = kzalloc(sizeof(struct map_info), GFP_KERNEL); |
136 | (struct map_info *)kmalloc(sizeof(struct map_info), | ||
137 | GFP_KERNEL); | ||
138 | if (map_banks[idx] == NULL) { | 136 | if (map_banks[idx] == NULL) { |
139 | ret = -ENOMEM; | 137 | ret = -ENOMEM; |
140 | goto error_mem; | 138 | goto error_mem; |
141 | } | 139 | } |
142 | memset((void *)map_banks[idx], 0, sizeof(struct map_info)); | 140 | map_banks[idx]->name = kzalloc(16, GFP_KERNEL); |
143 | map_banks[idx]->name = (char *)kmalloc(16, GFP_KERNEL); | ||
144 | if (map_banks[idx]->name == NULL) { | 141 | if (map_banks[idx]->name == NULL) { |
145 | ret = -ENOMEM; | 142 | ret = -ENOMEM; |
146 | goto error_mem; | 143 | goto error_mem; |
147 | } | 144 | } |
148 | memset((void *)map_banks[idx]->name, 0, 16); | ||
149 | 145 | ||
150 | sprintf(map_banks[idx]->name, "TQM834x-%d", idx); | 146 | sprintf(map_banks[idx]->name, "TQM834x-%d", idx); |
151 | map_banks[idx]->size = flash_size; | 147 | map_banks[idx]->size = flash_size; |
diff --git a/drivers/mtd/maps/tqm8xxl.c b/drivers/mtd/maps/tqm8xxl.c index 19578ba84ee8..37e4ded9b600 100644 --- a/drivers/mtd/maps/tqm8xxl.c +++ b/drivers/mtd/maps/tqm8xxl.c | |||
@@ -134,14 +134,13 @@ int __init init_tqm_mtd(void) | |||
134 | 134 | ||
135 | printk(KERN_INFO "%s: chip probing count %d\n", __FUNCTION__, idx); | 135 | printk(KERN_INFO "%s: chip probing count %d\n", __FUNCTION__, idx); |
136 | 136 | ||
137 | map_banks[idx] = (struct map_info *)kmalloc(sizeof(struct map_info), GFP_KERNEL); | 137 | map_banks[idx] = kzalloc(sizeof(struct map_info), GFP_KERNEL); |
138 | if(map_banks[idx] == NULL) { | 138 | if(map_banks[idx] == NULL) { |
139 | ret = -ENOMEM; | 139 | ret = -ENOMEM; |
140 | /* FIXME: What if some MTD devices were probed already? */ | 140 | /* FIXME: What if some MTD devices were probed already? */ |
141 | goto error_mem; | 141 | goto error_mem; |
142 | } | 142 | } |
143 | 143 | ||
144 | memset((void *)map_banks[idx], 0, sizeof(struct map_info)); | ||
145 | map_banks[idx]->name = (char *)kmalloc(16, GFP_KERNEL); | 144 | map_banks[idx]->name = (char *)kmalloc(16, GFP_KERNEL); |
146 | 145 | ||
147 | if (!map_banks[idx]->name) { | 146 | if (!map_banks[idx]->name) { |