diff options
29 files changed, 366 insertions, 184 deletions
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index 87a17337c7f6..71d05f481727 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt | |||
@@ -1189,8 +1189,6 @@ running once the system is up. | |||
1189 | Mechanism 2. | 1189 | Mechanism 2. |
1190 | nommconf [IA-32,X86_64] Disable use of MMCONFIG for PCI | 1190 | nommconf [IA-32,X86_64] Disable use of MMCONFIG for PCI |
1191 | Configuration | 1191 | Configuration |
1192 | mmconf [IA-32,X86_64] Force MMCONFIG. This is useful | ||
1193 | to override the builtin blacklist. | ||
1194 | nomsi [MSI] If the PCI_MSI kernel config parameter is | 1192 | nomsi [MSI] If the PCI_MSI kernel config parameter is |
1195 | enabled, this kernel boot option can be used to | 1193 | enabled, this kernel boot option can be used to |
1196 | disable the use of MSI interrupts system-wide. | 1194 | disable the use of MSI interrupts system-wide. |
@@ -1082,6 +1082,7 @@ help: | |||
1082 | @echo 'Static analysers' | 1082 | @echo 'Static analysers' |
1083 | @echo ' checkstack - Generate a list of stack hogs' | 1083 | @echo ' checkstack - Generate a list of stack hogs' |
1084 | @echo ' namespacecheck - Name space analysis on compiled kernel' | 1084 | @echo ' namespacecheck - Name space analysis on compiled kernel' |
1085 | @echo ' headers_check - Sanity check on exported headers' | ||
1085 | @echo '' | 1086 | @echo '' |
1086 | @echo 'Kernel packaging:' | 1087 | @echo 'Kernel packaging:' |
1087 | @$(MAKE) $(build)=$(package-dir) help | 1088 | @$(MAKE) $(build)=$(package-dir) help |
diff --git a/arch/i386/kernel/setup.c b/arch/i386/kernel/setup.c index 345ffb7d904d..f1682206d304 100644 --- a/arch/i386/kernel/setup.c +++ b/arch/i386/kernel/setup.c | |||
@@ -956,6 +956,38 @@ efi_memory_present_wrapper(unsigned long start, unsigned long end, void *arg) | |||
956 | return 0; | 956 | return 0; |
957 | } | 957 | } |
958 | 958 | ||
959 | /* | ||
960 | * This function checks if the entire range <start,end> is mapped with type. | ||
961 | * | ||
962 | * Note: this function only works correct if the e820 table is sorted and | ||
963 | * not-overlapping, which is the case | ||
964 | */ | ||
965 | int __init | ||
966 | e820_all_mapped(unsigned long s, unsigned long e, unsigned type) | ||
967 | { | ||
968 | u64 start = s; | ||
969 | u64 end = e; | ||
970 | int i; | ||
971 | for (i = 0; i < e820.nr_map; i++) { | ||
972 | struct e820entry *ei = &e820.map[i]; | ||
973 | if (type && ei->type != type) | ||
974 | continue; | ||
975 | /* is the region (part) in overlap with the current region ?*/ | ||
976 | if (ei->addr >= end || ei->addr + ei->size <= start) | ||
977 | continue; | ||
978 | /* if the region is at the beginning of <start,end> we move | ||
979 | * start to the end of the region since it's ok until there | ||
980 | */ | ||
981 | if (ei->addr <= start) | ||
982 | start = ei->addr + ei->size; | ||
983 | /* if start is now at or beyond end, we're done, full | ||
984 | * coverage */ | ||
985 | if (start >= end) | ||
986 | return 1; /* we're done */ | ||
987 | } | ||
988 | return 0; | ||
989 | } | ||
990 | |||
959 | /* | 991 | /* |
960 | * Find the highest page frame number we have available | 992 | * Find the highest page frame number we have available |
961 | */ | 993 | */ |
diff --git a/arch/i386/pci/common.c b/arch/i386/pci/common.c index 1220dd828ce3..0a362e3aeac5 100644 --- a/arch/i386/pci/common.c +++ b/arch/i386/pci/common.c | |||
@@ -237,11 +237,6 @@ char * __devinit pcibios_setup(char *str) | |||
237 | pci_probe &= ~PCI_PROBE_MMCONF; | 237 | pci_probe &= ~PCI_PROBE_MMCONF; |
238 | return NULL; | 238 | return NULL; |
239 | } | 239 | } |
240 | /* override DMI blacklist */ | ||
241 | else if (!strcmp(str, "mmconf")) { | ||
242 | pci_probe |= PCI_PROBE_MMCONF_FORCE; | ||
243 | return NULL; | ||
244 | } | ||
245 | #endif | 240 | #endif |
246 | else if (!strcmp(str, "noacpi")) { | 241 | else if (!strcmp(str, "noacpi")) { |
247 | acpi_noirq_set(); | 242 | acpi_noirq_set(); |
diff --git a/arch/i386/pci/mmconfig.c b/arch/i386/pci/mmconfig.c index ef5a2faa7d82..972180f738d9 100644 --- a/arch/i386/pci/mmconfig.c +++ b/arch/i386/pci/mmconfig.c | |||
@@ -12,7 +12,6 @@ | |||
12 | #include <linux/pci.h> | 12 | #include <linux/pci.h> |
13 | #include <linux/init.h> | 13 | #include <linux/init.h> |
14 | #include <linux/acpi.h> | 14 | #include <linux/acpi.h> |
15 | #include <linux/dmi.h> | ||
16 | #include <asm/e820.h> | 15 | #include <asm/e820.h> |
17 | #include "pci.h" | 16 | #include "pci.h" |
18 | 17 | ||
@@ -188,31 +187,9 @@ static __init void unreachable_devices(void) | |||
188 | } | 187 | } |
189 | } | 188 | } |
190 | 189 | ||
191 | static int disable_mcfg(struct dmi_system_id *d) | ||
192 | { | ||
193 | printk("PCI: %s detected. Disabling MCFG.\n", d->ident); | ||
194 | pci_probe &= ~PCI_PROBE_MMCONF; | ||
195 | return 0; | ||
196 | } | ||
197 | |||
198 | static struct dmi_system_id __initdata dmi_bad_mcfg[] = { | ||
199 | /* Has broken MCFG table that makes the system hang when used */ | ||
200 | { | ||
201 | .callback = disable_mcfg, | ||
202 | .ident = "Intel D3C5105 SDV", | ||
203 | .matches = { | ||
204 | DMI_MATCH(DMI_BIOS_VENDOR, "Intel"), | ||
205 | DMI_MATCH(DMI_BOARD_NAME, "D26928"), | ||
206 | }, | ||
207 | }, | ||
208 | {} | ||
209 | }; | ||
210 | |||
211 | void __init pci_mmcfg_init(void) | 190 | void __init pci_mmcfg_init(void) |
212 | { | 191 | { |
213 | dmi_check_system(dmi_bad_mcfg); | 192 | if ((pci_probe & PCI_PROBE_MMCONF) == 0) |
214 | |||
215 | if ((pci_probe & (PCI_PROBE_MMCONF_FORCE|PCI_PROBE_MMCONF)) == 0) | ||
216 | return; | 193 | return; |
217 | 194 | ||
218 | acpi_table_parse(ACPI_MCFG, acpi_parse_mcfg); | 195 | acpi_table_parse(ACPI_MCFG, acpi_parse_mcfg); |
@@ -221,6 +198,15 @@ void __init pci_mmcfg_init(void) | |||
221 | (pci_mmcfg_config[0].base_address == 0)) | 198 | (pci_mmcfg_config[0].base_address == 0)) |
222 | return; | 199 | return; |
223 | 200 | ||
201 | if (!e820_all_mapped(pci_mmcfg_config[0].base_address, | ||
202 | pci_mmcfg_config[0].base_address + MMCONFIG_APER_MIN, | ||
203 | E820_RESERVED)) { | ||
204 | printk(KERN_ERR "PCI: BIOS Bug: MCFG area at %x is not E820-reserved\n", | ||
205 | pci_mmcfg_config[0].base_address); | ||
206 | printk(KERN_ERR "PCI: Not using MMCONFIG.\n"); | ||
207 | return; | ||
208 | } | ||
209 | |||
224 | printk(KERN_INFO "PCI: Using MMCONFIG\n"); | 210 | printk(KERN_INFO "PCI: Using MMCONFIG\n"); |
225 | raw_pci_ops = &pci_mmcfg; | 211 | raw_pci_ops = &pci_mmcfg; |
226 | pci_probe = (pci_probe & ~PCI_PROBE_MASK) | PCI_PROBE_MMCONF; | 212 | pci_probe = (pci_probe & ~PCI_PROBE_MASK) | PCI_PROBE_MMCONF; |
diff --git a/arch/i386/pci/pci.h b/arch/i386/pci/pci.h index 49a849b3a241..bf4e79335388 100644 --- a/arch/i386/pci/pci.h +++ b/arch/i386/pci/pci.h | |||
@@ -16,8 +16,7 @@ | |||
16 | #define PCI_PROBE_CONF1 0x0002 | 16 | #define PCI_PROBE_CONF1 0x0002 |
17 | #define PCI_PROBE_CONF2 0x0004 | 17 | #define PCI_PROBE_CONF2 0x0004 |
18 | #define PCI_PROBE_MMCONF 0x0008 | 18 | #define PCI_PROBE_MMCONF 0x0008 |
19 | #define PCI_PROBE_MMCONF_FORCE 0x0010 | 19 | #define PCI_PROBE_MASK 0x000f |
20 | #define PCI_PROBE_MASK 0x00ff | ||
21 | 20 | ||
22 | #define PCI_NO_SORT 0x0100 | 21 | #define PCI_NO_SORT 0x0100 |
23 | #define PCI_BIOS_SORT 0x0200 | 22 | #define PCI_BIOS_SORT 0x0200 |
diff --git a/arch/x86_64/kernel/e820.c b/arch/x86_64/kernel/e820.c index 764bf23c7103..d6d7f731f6f0 100644 --- a/arch/x86_64/kernel/e820.c +++ b/arch/x86_64/kernel/e820.c | |||
@@ -108,6 +108,35 @@ e820_any_mapped(unsigned long start, unsigned long end, unsigned type) | |||
108 | return 0; | 108 | return 0; |
109 | } | 109 | } |
110 | 110 | ||
111 | /* | ||
112 | * This function checks if the entire range <start,end> is mapped with type. | ||
113 | * | ||
114 | * Note: this function only works correct if the e820 table is sorted and | ||
115 | * not-overlapping, which is the case | ||
116 | */ | ||
117 | int __init e820_all_mapped(unsigned long start, unsigned long end, unsigned type) | ||
118 | { | ||
119 | int i; | ||
120 | for (i = 0; i < e820.nr_map; i++) { | ||
121 | struct e820entry *ei = &e820.map[i]; | ||
122 | if (type && ei->type != type) | ||
123 | continue; | ||
124 | /* is the region (part) in overlap with the current region ?*/ | ||
125 | if (ei->addr >= end || ei->addr + ei->size <= start) | ||
126 | continue; | ||
127 | |||
128 | /* if the region is at the beginning of <start,end> we move | ||
129 | * start to the end of the region since it's ok until there | ||
130 | */ | ||
131 | if (ei->addr <= start) | ||
132 | start = ei->addr + ei->size; | ||
133 | /* if start is now at or beyond end, we're done, full coverage */ | ||
134 | if (start >= end) | ||
135 | return 1; /* we're done */ | ||
136 | } | ||
137 | return 0; | ||
138 | } | ||
139 | |||
111 | /* | 140 | /* |
112 | * Find a free area in a specific range. | 141 | * Find a free area in a specific range. |
113 | */ | 142 | */ |
diff --git a/arch/x86_64/pci/mmconfig.c b/arch/x86_64/pci/mmconfig.c index 2d48a7941d48..3c55c76c6fd5 100644 --- a/arch/x86_64/pci/mmconfig.c +++ b/arch/x86_64/pci/mmconfig.c | |||
@@ -9,7 +9,6 @@ | |||
9 | #include <linux/init.h> | 9 | #include <linux/init.h> |
10 | #include <linux/acpi.h> | 10 | #include <linux/acpi.h> |
11 | #include <linux/bitmap.h> | 11 | #include <linux/bitmap.h> |
12 | #include <linux/dmi.h> | ||
13 | #include <asm/e820.h> | 12 | #include <asm/e820.h> |
14 | 13 | ||
15 | #include "pci.h" | 14 | #include "pci.h" |
@@ -165,33 +164,11 @@ static __init void unreachable_devices(void) | |||
165 | } | 164 | } |
166 | } | 165 | } |
167 | 166 | ||
168 | static int disable_mcfg(struct dmi_system_id *d) | ||
169 | { | ||
170 | printk("PCI: %s detected. Disabling MCFG.\n", d->ident); | ||
171 | pci_probe &= ~PCI_PROBE_MMCONF; | ||
172 | return 0; | ||
173 | } | ||
174 | |||
175 | static struct dmi_system_id __initdata dmi_bad_mcfg[] = { | ||
176 | /* Has broken MCFG table that makes the system hang when used */ | ||
177 | { | ||
178 | .callback = disable_mcfg, | ||
179 | .ident = "Intel D3C5105 SDV", | ||
180 | .matches = { | ||
181 | DMI_MATCH(DMI_BIOS_VENDOR, "Intel"), | ||
182 | DMI_MATCH(DMI_BOARD_NAME, "D26928"), | ||
183 | }, | ||
184 | }, | ||
185 | {} | ||
186 | }; | ||
187 | |||
188 | void __init pci_mmcfg_init(void) | 167 | void __init pci_mmcfg_init(void) |
189 | { | 168 | { |
190 | int i; | 169 | int i; |
191 | 170 | ||
192 | dmi_check_system(dmi_bad_mcfg); | 171 | if ((pci_probe & PCI_PROBE_MMCONF) == 0) |
193 | |||
194 | if ((pci_probe & (PCI_PROBE_MMCONF|PCI_PROBE_MMCONF_FORCE)) == 0) | ||
195 | return; | 172 | return; |
196 | 173 | ||
197 | acpi_table_parse(ACPI_MCFG, acpi_parse_mcfg); | 174 | acpi_table_parse(ACPI_MCFG, acpi_parse_mcfg); |
@@ -200,6 +177,15 @@ void __init pci_mmcfg_init(void) | |||
200 | (pci_mmcfg_config[0].base_address == 0)) | 177 | (pci_mmcfg_config[0].base_address == 0)) |
201 | return; | 178 | return; |
202 | 179 | ||
180 | if (!e820_all_mapped(pci_mmcfg_config[0].base_address, | ||
181 | pci_mmcfg_config[0].base_address + MMCONFIG_APER_MIN, | ||
182 | E820_RESERVED)) { | ||
183 | printk(KERN_ERR "PCI: BIOS Bug: MCFG area at %x is not E820-reserved\n", | ||
184 | pci_mmcfg_config[0].base_address); | ||
185 | printk(KERN_ERR "PCI: Not using MMCONFIG.\n"); | ||
186 | return; | ||
187 | } | ||
188 | |||
203 | /* RED-PEN i386 doesn't do _nocache right now */ | 189 | /* RED-PEN i386 doesn't do _nocache right now */ |
204 | pci_mmcfg_virt = kmalloc(sizeof(*pci_mmcfg_virt) * pci_mmcfg_config_num, GFP_KERNEL); | 190 | pci_mmcfg_virt = kmalloc(sizeof(*pci_mmcfg_virt) * pci_mmcfg_config_num, GFP_KERNEL); |
205 | if (pci_mmcfg_virt == NULL) { | 191 | if (pci_mmcfg_virt == NULL) { |
diff --git a/drivers/mtd/chips/cfi_cmdset_0001.c b/drivers/mtd/chips/cfi_cmdset_0001.c index 39edb8250fbc..7ea49a0d5ec3 100644 --- a/drivers/mtd/chips/cfi_cmdset_0001.c +++ b/drivers/mtd/chips/cfi_cmdset_0001.c | |||
@@ -908,7 +908,7 @@ static void __xipram xip_enable(struct map_info *map, struct flchip *chip, | |||
908 | 908 | ||
909 | static int __xipram xip_wait_for_operation( | 909 | static int __xipram xip_wait_for_operation( |
910 | struct map_info *map, struct flchip *chip, | 910 | struct map_info *map, struct flchip *chip, |
911 | unsigned long adr, int *chip_op_time ) | 911 | unsigned long adr, unsigned int chip_op_time ) |
912 | { | 912 | { |
913 | struct cfi_private *cfi = map->fldrv_priv; | 913 | struct cfi_private *cfi = map->fldrv_priv; |
914 | struct cfi_pri_intelext *cfip = cfi->cmdset_priv; | 914 | struct cfi_pri_intelext *cfip = cfi->cmdset_priv; |
@@ -917,7 +917,7 @@ static int __xipram xip_wait_for_operation( | |||
917 | flstate_t oldstate, newstate; | 917 | flstate_t oldstate, newstate; |
918 | 918 | ||
919 | start = xip_currtime(); | 919 | start = xip_currtime(); |
920 | usec = *chip_op_time * 8; | 920 | usec = chip_op_time * 8; |
921 | if (usec == 0) | 921 | if (usec == 0) |
922 | usec = 500000; | 922 | usec = 500000; |
923 | done = 0; | 923 | done = 0; |
@@ -1027,8 +1027,8 @@ static int __xipram xip_wait_for_operation( | |||
1027 | #define XIP_INVAL_CACHED_RANGE(map, from, size) \ | 1027 | #define XIP_INVAL_CACHED_RANGE(map, from, size) \ |
1028 | INVALIDATE_CACHED_RANGE(map, from, size) | 1028 | INVALIDATE_CACHED_RANGE(map, from, size) |
1029 | 1029 | ||
1030 | #define INVAL_CACHE_AND_WAIT(map, chip, cmd_adr, inval_adr, inval_len, p_usec) \ | 1030 | #define INVAL_CACHE_AND_WAIT(map, chip, cmd_adr, inval_adr, inval_len, usec) \ |
1031 | xip_wait_for_operation(map, chip, cmd_adr, p_usec) | 1031 | xip_wait_for_operation(map, chip, cmd_adr, usec) |
1032 | 1032 | ||
1033 | #else | 1033 | #else |
1034 | 1034 | ||
@@ -1040,64 +1040,64 @@ static int __xipram xip_wait_for_operation( | |||
1040 | static int inval_cache_and_wait_for_operation( | 1040 | static int inval_cache_and_wait_for_operation( |
1041 | struct map_info *map, struct flchip *chip, | 1041 | struct map_info *map, struct flchip *chip, |
1042 | unsigned long cmd_adr, unsigned long inval_adr, int inval_len, | 1042 | unsigned long cmd_adr, unsigned long inval_adr, int inval_len, |
1043 | int *chip_op_time ) | 1043 | unsigned int chip_op_time) |
1044 | { | 1044 | { |
1045 | struct cfi_private *cfi = map->fldrv_priv; | 1045 | struct cfi_private *cfi = map->fldrv_priv; |
1046 | map_word status, status_OK = CMD(0x80); | 1046 | map_word status, status_OK = CMD(0x80); |
1047 | int z, chip_state = chip->state; | 1047 | int chip_state = chip->state; |
1048 | unsigned long timeo; | 1048 | unsigned int timeo, sleep_time; |
1049 | 1049 | ||
1050 | spin_unlock(chip->mutex); | 1050 | spin_unlock(chip->mutex); |
1051 | if (inval_len) | 1051 | if (inval_len) |
1052 | INVALIDATE_CACHED_RANGE(map, inval_adr, inval_len); | 1052 | INVALIDATE_CACHED_RANGE(map, inval_adr, inval_len); |
1053 | if (*chip_op_time) | ||
1054 | cfi_udelay(*chip_op_time); | ||
1055 | spin_lock(chip->mutex); | 1053 | spin_lock(chip->mutex); |
1056 | 1054 | ||
1057 | timeo = *chip_op_time * 8 * HZ / 1000000; | 1055 | /* set our timeout to 8 times the expected delay */ |
1058 | if (timeo < HZ/2) | 1056 | timeo = chip_op_time * 8; |
1059 | timeo = HZ/2; | 1057 | if (!timeo) |
1060 | timeo += jiffies; | 1058 | timeo = 500000; |
1059 | sleep_time = chip_op_time / 2; | ||
1061 | 1060 | ||
1062 | z = 0; | ||
1063 | for (;;) { | 1061 | for (;;) { |
1064 | if (chip->state != chip_state) { | ||
1065 | /* Someone's suspended the operation: sleep */ | ||
1066 | DECLARE_WAITQUEUE(wait, current); | ||
1067 | |||
1068 | set_current_state(TASK_UNINTERRUPTIBLE); | ||
1069 | add_wait_queue(&chip->wq, &wait); | ||
1070 | spin_unlock(chip->mutex); | ||
1071 | schedule(); | ||
1072 | remove_wait_queue(&chip->wq, &wait); | ||
1073 | timeo = jiffies + (HZ / 2); /* FIXME */ | ||
1074 | spin_lock(chip->mutex); | ||
1075 | continue; | ||
1076 | } | ||
1077 | |||
1078 | status = map_read(map, cmd_adr); | 1062 | status = map_read(map, cmd_adr); |
1079 | if (map_word_andequal(map, status, status_OK, status_OK)) | 1063 | if (map_word_andequal(map, status, status_OK, status_OK)) |
1080 | break; | 1064 | break; |
1081 | 1065 | ||
1082 | /* OK Still waiting */ | 1066 | if (!timeo) { |
1083 | if (time_after(jiffies, timeo)) { | ||
1084 | map_write(map, CMD(0x70), cmd_adr); | 1067 | map_write(map, CMD(0x70), cmd_adr); |
1085 | chip->state = FL_STATUS; | 1068 | chip->state = FL_STATUS; |
1086 | return -ETIME; | 1069 | return -ETIME; |
1087 | } | 1070 | } |
1088 | 1071 | ||
1089 | /* Latency issues. Drop the lock, wait a while and retry */ | 1072 | /* OK Still waiting. Drop the lock, wait a while and retry. */ |
1090 | z++; | ||
1091 | spin_unlock(chip->mutex); | 1073 | spin_unlock(chip->mutex); |
1092 | cfi_udelay(1); | 1074 | if (sleep_time >= 1000000/HZ) { |
1075 | /* | ||
1076 | * Half of the normal delay still remaining | ||
1077 | * can be performed with a sleeping delay instead | ||
1078 | * of busy waiting. | ||
1079 | */ | ||
1080 | msleep(sleep_time/1000); | ||
1081 | timeo -= sleep_time; | ||
1082 | sleep_time = 1000000/HZ; | ||
1083 | } else { | ||
1084 | udelay(1); | ||
1085 | cond_resched(); | ||
1086 | timeo--; | ||
1087 | } | ||
1093 | spin_lock(chip->mutex); | 1088 | spin_lock(chip->mutex); |
1094 | } | ||
1095 | 1089 | ||
1096 | if (!z) { | 1090 | if (chip->state != chip_state) { |
1097 | if (!--(*chip_op_time)) | 1091 | /* Someone's suspended the operation: sleep */ |
1098 | *chip_op_time = 1; | 1092 | DECLARE_WAITQUEUE(wait, current); |
1099 | } else if (z > 1) | 1093 | set_current_state(TASK_UNINTERRUPTIBLE); |
1100 | ++(*chip_op_time); | 1094 | add_wait_queue(&chip->wq, &wait); |
1095 | spin_unlock(chip->mutex); | ||
1096 | schedule(); | ||
1097 | remove_wait_queue(&chip->wq, &wait); | ||
1098 | spin_lock(chip->mutex); | ||
1099 | } | ||
1100 | } | ||
1101 | 1101 | ||
1102 | /* Done and happy. */ | 1102 | /* Done and happy. */ |
1103 | chip->state = FL_STATUS; | 1103 | chip->state = FL_STATUS; |
@@ -1107,8 +1107,7 @@ static int inval_cache_and_wait_for_operation( | |||
1107 | #endif | 1107 | #endif |
1108 | 1108 | ||
1109 | #define WAIT_TIMEOUT(map, chip, adr, udelay) \ | 1109 | #define WAIT_TIMEOUT(map, chip, adr, udelay) \ |
1110 | ({ int __udelay = (udelay); \ | 1110 | INVAL_CACHE_AND_WAIT(map, chip, adr, 0, 0, udelay); |
1111 | INVAL_CACHE_AND_WAIT(map, chip, adr, 0, 0, &__udelay); }) | ||
1112 | 1111 | ||
1113 | 1112 | ||
1114 | static int do_point_onechip (struct map_info *map, struct flchip *chip, loff_t adr, size_t len) | 1113 | static int do_point_onechip (struct map_info *map, struct flchip *chip, loff_t adr, size_t len) |
@@ -1332,7 +1331,7 @@ static int __xipram do_write_oneword(struct map_info *map, struct flchip *chip, | |||
1332 | 1331 | ||
1333 | ret = INVAL_CACHE_AND_WAIT(map, chip, adr, | 1332 | ret = INVAL_CACHE_AND_WAIT(map, chip, adr, |
1334 | adr, map_bankwidth(map), | 1333 | adr, map_bankwidth(map), |
1335 | &chip->word_write_time); | 1334 | chip->word_write_time); |
1336 | if (ret) { | 1335 | if (ret) { |
1337 | xip_enable(map, chip, adr); | 1336 | xip_enable(map, chip, adr); |
1338 | printk(KERN_ERR "%s: word write error (status timeout)\n", map->name); | 1337 | printk(KERN_ERR "%s: word write error (status timeout)\n", map->name); |
@@ -1569,7 +1568,7 @@ static int __xipram do_write_buffer(struct map_info *map, struct flchip *chip, | |||
1569 | 1568 | ||
1570 | ret = INVAL_CACHE_AND_WAIT(map, chip, cmd_adr, | 1569 | ret = INVAL_CACHE_AND_WAIT(map, chip, cmd_adr, |
1571 | adr, len, | 1570 | adr, len, |
1572 | &chip->buffer_write_time); | 1571 | chip->buffer_write_time); |
1573 | if (ret) { | 1572 | if (ret) { |
1574 | map_write(map, CMD(0x70), cmd_adr); | 1573 | map_write(map, CMD(0x70), cmd_adr); |
1575 | chip->state = FL_STATUS; | 1574 | chip->state = FL_STATUS; |
@@ -1704,7 +1703,7 @@ static int __xipram do_erase_oneblock(struct map_info *map, struct flchip *chip, | |||
1704 | 1703 | ||
1705 | ret = INVAL_CACHE_AND_WAIT(map, chip, adr, | 1704 | ret = INVAL_CACHE_AND_WAIT(map, chip, adr, |
1706 | adr, len, | 1705 | adr, len, |
1707 | &chip->erase_time); | 1706 | chip->erase_time); |
1708 | if (ret) { | 1707 | if (ret) { |
1709 | map_write(map, CMD(0x70), adr); | 1708 | map_write(map, CMD(0x70), adr); |
1710 | chip->state = FL_STATUS; | 1709 | chip->state = FL_STATUS; |
diff --git a/drivers/mtd/chips/cfi_cmdset_0002.c b/drivers/mtd/chips/cfi_cmdset_0002.c index 9885726a16e4..a482e8922de1 100644 --- a/drivers/mtd/chips/cfi_cmdset_0002.c +++ b/drivers/mtd/chips/cfi_cmdset_0002.c | |||
@@ -45,9 +45,11 @@ | |||
45 | #define MAX_WORD_RETRIES 3 | 45 | #define MAX_WORD_RETRIES 3 |
46 | 46 | ||
47 | #define MANUFACTURER_AMD 0x0001 | 47 | #define MANUFACTURER_AMD 0x0001 |
48 | #define MANUFACTURER_ATMEL 0x001F | ||
48 | #define MANUFACTURER_SST 0x00BF | 49 | #define MANUFACTURER_SST 0x00BF |
49 | #define SST49LF004B 0x0060 | 50 | #define SST49LF004B 0x0060 |
50 | #define SST49LF008A 0x005a | 51 | #define SST49LF008A 0x005a |
52 | #define AT49BV6416 0x00d6 | ||
51 | 53 | ||
52 | static int cfi_amdstd_read (struct mtd_info *, loff_t, size_t, size_t *, u_char *); | 54 | static int cfi_amdstd_read (struct mtd_info *, loff_t, size_t, size_t *, u_char *); |
53 | static int cfi_amdstd_write_words(struct mtd_info *, loff_t, size_t, size_t *, const u_char *); | 55 | static int cfi_amdstd_write_words(struct mtd_info *, loff_t, size_t, size_t *, const u_char *); |
@@ -68,6 +70,9 @@ static int get_chip(struct map_info *map, struct flchip *chip, unsigned long adr | |||
68 | static void put_chip(struct map_info *map, struct flchip *chip, unsigned long adr); | 70 | static void put_chip(struct map_info *map, struct flchip *chip, unsigned long adr); |
69 | #include "fwh_lock.h" | 71 | #include "fwh_lock.h" |
70 | 72 | ||
73 | static int cfi_atmel_lock(struct mtd_info *mtd, loff_t ofs, size_t len); | ||
74 | static int cfi_atmel_unlock(struct mtd_info *mtd, loff_t ofs, size_t len); | ||
75 | |||
71 | static struct mtd_chip_driver cfi_amdstd_chipdrv = { | 76 | static struct mtd_chip_driver cfi_amdstd_chipdrv = { |
72 | .probe = NULL, /* Not usable directly */ | 77 | .probe = NULL, /* Not usable directly */ |
73 | .destroy = cfi_amdstd_destroy, | 78 | .destroy = cfi_amdstd_destroy, |
@@ -161,6 +166,26 @@ static void fixup_use_write_buffers(struct mtd_info *mtd, void *param) | |||
161 | } | 166 | } |
162 | } | 167 | } |
163 | 168 | ||
169 | /* Atmel chips don't use the same PRI format as AMD chips */ | ||
170 | static void fixup_convert_atmel_pri(struct mtd_info *mtd, void *param) | ||
171 | { | ||
172 | struct map_info *map = mtd->priv; | ||
173 | struct cfi_private *cfi = map->fldrv_priv; | ||
174 | struct cfi_pri_amdstd *extp = cfi->cmdset_priv; | ||
175 | struct cfi_pri_atmel atmel_pri; | ||
176 | |||
177 | memcpy(&atmel_pri, extp, sizeof(atmel_pri)); | ||
178 | memset((char *)extp + 5, 0, sizeof(*extp) - 5); | ||
179 | |||
180 | if (atmel_pri.Features & 0x02) | ||
181 | extp->EraseSuspend = 2; | ||
182 | |||
183 | if (atmel_pri.BottomBoot) | ||
184 | extp->TopBottom = 2; | ||
185 | else | ||
186 | extp->TopBottom = 3; | ||
187 | } | ||
188 | |||
164 | static void fixup_use_secsi(struct mtd_info *mtd, void *param) | 189 | static void fixup_use_secsi(struct mtd_info *mtd, void *param) |
165 | { | 190 | { |
166 | /* Setup for chips with a secsi area */ | 191 | /* Setup for chips with a secsi area */ |
@@ -179,6 +204,16 @@ static void fixup_use_erase_chip(struct mtd_info *mtd, void *param) | |||
179 | 204 | ||
180 | } | 205 | } |
181 | 206 | ||
207 | /* | ||
208 | * Some Atmel chips (e.g. the AT49BV6416) power-up with all sectors | ||
209 | * locked by default. | ||
210 | */ | ||
211 | static void fixup_use_atmel_lock(struct mtd_info *mtd, void *param) | ||
212 | { | ||
213 | mtd->lock = cfi_atmel_lock; | ||
214 | mtd->unlock = cfi_atmel_unlock; | ||
215 | } | ||
216 | |||
182 | static struct cfi_fixup cfi_fixup_table[] = { | 217 | static struct cfi_fixup cfi_fixup_table[] = { |
183 | #ifdef AMD_BOOTLOC_BUG | 218 | #ifdef AMD_BOOTLOC_BUG |
184 | { CFI_MFR_AMD, CFI_ID_ANY, fixup_amd_bootblock, NULL }, | 219 | { CFI_MFR_AMD, CFI_ID_ANY, fixup_amd_bootblock, NULL }, |
@@ -192,6 +227,7 @@ static struct cfi_fixup cfi_fixup_table[] = { | |||
192 | #if !FORCE_WORD_WRITE | 227 | #if !FORCE_WORD_WRITE |
193 | { CFI_MFR_ANY, CFI_ID_ANY, fixup_use_write_buffers, NULL, }, | 228 | { CFI_MFR_ANY, CFI_ID_ANY, fixup_use_write_buffers, NULL, }, |
194 | #endif | 229 | #endif |
230 | { CFI_MFR_ATMEL, CFI_ID_ANY, fixup_convert_atmel_pri, NULL }, | ||
195 | { 0, 0, NULL, NULL } | 231 | { 0, 0, NULL, NULL } |
196 | }; | 232 | }; |
197 | static struct cfi_fixup jedec_fixup_table[] = { | 233 | static struct cfi_fixup jedec_fixup_table[] = { |
@@ -207,6 +243,7 @@ static struct cfi_fixup fixup_table[] = { | |||
207 | * we know that is the case. | 243 | * we know that is the case. |
208 | */ | 244 | */ |
209 | { CFI_MFR_ANY, CFI_ID_ANY, fixup_use_erase_chip, NULL }, | 245 | { CFI_MFR_ANY, CFI_ID_ANY, fixup_use_erase_chip, NULL }, |
246 | { CFI_MFR_ATMEL, AT49BV6416, fixup_use_atmel_lock, NULL }, | ||
210 | { 0, 0, NULL, NULL } | 247 | { 0, 0, NULL, NULL } |
211 | }; | 248 | }; |
212 | 249 | ||
@@ -1607,6 +1644,80 @@ static int cfi_amdstd_erase_chip(struct mtd_info *mtd, struct erase_info *instr) | |||
1607 | return 0; | 1644 | return 0; |
1608 | } | 1645 | } |
1609 | 1646 | ||
1647 | static int do_atmel_lock(struct map_info *map, struct flchip *chip, | ||
1648 | unsigned long adr, int len, void *thunk) | ||
1649 | { | ||
1650 | struct cfi_private *cfi = map->fldrv_priv; | ||
1651 | int ret; | ||
1652 | |||
1653 | spin_lock(chip->mutex); | ||
1654 | ret = get_chip(map, chip, adr + chip->start, FL_LOCKING); | ||
1655 | if (ret) | ||
1656 | goto out_unlock; | ||
1657 | chip->state = FL_LOCKING; | ||
1658 | |||
1659 | DEBUG(MTD_DEBUG_LEVEL3, "MTD %s(): LOCK 0x%08lx len %d\n", | ||
1660 | __func__, adr, len); | ||
1661 | |||
1662 | cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi, | ||
1663 | cfi->device_type, NULL); | ||
1664 | cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chip->start, map, cfi, | ||
1665 | cfi->device_type, NULL); | ||
1666 | cfi_send_gen_cmd(0x80, cfi->addr_unlock1, chip->start, map, cfi, | ||
1667 | cfi->device_type, NULL); | ||
1668 | cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi, | ||
1669 | cfi->device_type, NULL); | ||
1670 | cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chip->start, map, cfi, | ||
1671 | cfi->device_type, NULL); | ||
1672 | map_write(map, CMD(0x40), chip->start + adr); | ||
1673 | |||
1674 | chip->state = FL_READY; | ||
1675 | put_chip(map, chip, adr + chip->start); | ||
1676 | ret = 0; | ||
1677 | |||
1678 | out_unlock: | ||
1679 | spin_unlock(chip->mutex); | ||
1680 | return ret; | ||
1681 | } | ||
1682 | |||
1683 | static int do_atmel_unlock(struct map_info *map, struct flchip *chip, | ||
1684 | unsigned long adr, int len, void *thunk) | ||
1685 | { | ||
1686 | struct cfi_private *cfi = map->fldrv_priv; | ||
1687 | int ret; | ||
1688 | |||
1689 | spin_lock(chip->mutex); | ||
1690 | ret = get_chip(map, chip, adr + chip->start, FL_UNLOCKING); | ||
1691 | if (ret) | ||
1692 | goto out_unlock; | ||
1693 | chip->state = FL_UNLOCKING; | ||
1694 | |||
1695 | DEBUG(MTD_DEBUG_LEVEL3, "MTD %s(): LOCK 0x%08lx len %d\n", | ||
1696 | __func__, adr, len); | ||
1697 | |||
1698 | cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi, | ||
1699 | cfi->device_type, NULL); | ||
1700 | map_write(map, CMD(0x70), adr); | ||
1701 | |||
1702 | chip->state = FL_READY; | ||
1703 | put_chip(map, chip, adr + chip->start); | ||
1704 | ret = 0; | ||
1705 | |||
1706 | out_unlock: | ||
1707 | spin_unlock(chip->mutex); | ||
1708 | return ret; | ||
1709 | } | ||
1710 | |||
1711 | static int cfi_atmel_lock(struct mtd_info *mtd, loff_t ofs, size_t len) | ||
1712 | { | ||
1713 | return cfi_varsize_frob(mtd, do_atmel_lock, ofs, len, NULL); | ||
1714 | } | ||
1715 | |||
1716 | static int cfi_atmel_unlock(struct mtd_info *mtd, loff_t ofs, size_t len) | ||
1717 | { | ||
1718 | return cfi_varsize_frob(mtd, do_atmel_unlock, ofs, len, NULL); | ||
1719 | } | ||
1720 | |||
1610 | 1721 | ||
1611 | static void cfi_amdstd_sync (struct mtd_info *mtd) | 1722 | static void cfi_amdstd_sync (struct mtd_info *mtd) |
1612 | { | 1723 | { |
diff --git a/drivers/mtd/chips/jedec_probe.c b/drivers/mtd/chips/jedec_probe.c index 8f39d0a31438..1154dac715aa 100644 --- a/drivers/mtd/chips/jedec_probe.c +++ b/drivers/mtd/chips/jedec_probe.c | |||
@@ -111,6 +111,7 @@ | |||
111 | #define MX29LV040C 0x004F | 111 | #define MX29LV040C 0x004F |
112 | #define MX29LV160T 0x22C4 | 112 | #define MX29LV160T 0x22C4 |
113 | #define MX29LV160B 0x2249 | 113 | #define MX29LV160B 0x2249 |
114 | #define MX29F040 0x00A4 | ||
114 | #define MX29F016 0x00AD | 115 | #define MX29F016 0x00AD |
115 | #define MX29F002T 0x00B0 | 116 | #define MX29F002T 0x00B0 |
116 | #define MX29F004T 0x0045 | 117 | #define MX29F004T 0x0045 |
@@ -1172,6 +1173,19 @@ static const struct amd_flash_info jedec_table[] = { | |||
1172 | } | 1173 | } |
1173 | }, { | 1174 | }, { |
1174 | .mfr_id = MANUFACTURER_MACRONIX, | 1175 | .mfr_id = MANUFACTURER_MACRONIX, |
1176 | .dev_id = MX29F040, | ||
1177 | .name = "Macronix MX29F040", | ||
1178 | .uaddr = { | ||
1179 | [0] = MTD_UADDR_0x0555_0x02AA /* x8 */ | ||
1180 | }, | ||
1181 | .DevSize = SIZE_512KiB, | ||
1182 | .CmdSet = P_ID_AMD_STD, | ||
1183 | .NumEraseRegions= 1, | ||
1184 | .regions = { | ||
1185 | ERASEINFO(0x10000,8), | ||
1186 | } | ||
1187 | }, { | ||
1188 | .mfr_id = MANUFACTURER_MACRONIX, | ||
1175 | .dev_id = MX29F016, | 1189 | .dev_id = MX29F016, |
1176 | .name = "Macronix MX29F016", | 1190 | .name = "Macronix MX29F016", |
1177 | .uaddr = { | 1191 | .uaddr = { |
diff --git a/drivers/mtd/devices/block2mtd.c b/drivers/mtd/devices/block2mtd.c index ede3561be870..401c6a294baa 100644 --- a/drivers/mtd/devices/block2mtd.c +++ b/drivers/mtd/devices/block2mtd.c | |||
@@ -18,6 +18,7 @@ | |||
18 | #include <linux/mtd/mtd.h> | 18 | #include <linux/mtd/mtd.h> |
19 | #include <linux/buffer_head.h> | 19 | #include <linux/buffer_head.h> |
20 | #include <linux/mutex.h> | 20 | #include <linux/mutex.h> |
21 | #include <linux/mount.h> | ||
21 | 22 | ||
22 | #define VERSION "$Revision: 1.30 $" | 23 | #define VERSION "$Revision: 1.30 $" |
23 | 24 | ||
@@ -236,6 +237,8 @@ static int _block2mtd_write(struct block2mtd_dev *dev, const u_char *buf, | |||
236 | } | 237 | } |
237 | return 0; | 238 | return 0; |
238 | } | 239 | } |
240 | |||
241 | |||
239 | static int block2mtd_write(struct mtd_info *mtd, loff_t to, size_t len, | 242 | static int block2mtd_write(struct mtd_info *mtd, loff_t to, size_t len, |
240 | size_t *retlen, const u_char *buf) | 243 | size_t *retlen, const u_char *buf) |
241 | { | 244 | { |
@@ -299,6 +302,19 @@ static struct block2mtd_dev *add_device(char *devname, int erase_size) | |||
299 | 302 | ||
300 | /* Get a handle on the device */ | 303 | /* Get a handle on the device */ |
301 | bdev = open_bdev_excl(devname, O_RDWR, NULL); | 304 | bdev = open_bdev_excl(devname, O_RDWR, NULL); |
305 | #ifndef MODULE | ||
306 | if (IS_ERR(bdev)) { | ||
307 | |||
308 | /* We might not have rootfs mounted at this point. Try | ||
309 | to resolve the device name by other means. */ | ||
310 | |||
311 | dev_t dev = name_to_dev_t(devname); | ||
312 | if (dev != 0) { | ||
313 | bdev = open_by_devnum(dev, FMODE_WRITE | FMODE_READ); | ||
314 | } | ||
315 | } | ||
316 | #endif | ||
317 | |||
302 | if (IS_ERR(bdev)) { | 318 | if (IS_ERR(bdev)) { |
303 | ERROR("error: cannot open device %s", devname); | 319 | ERROR("error: cannot open device %s", devname); |
304 | goto devinit_err; | 320 | goto devinit_err; |
@@ -393,26 +409,6 @@ static int parse_num(size_t *num, const char *token) | |||
393 | } | 409 | } |
394 | 410 | ||
395 | 411 | ||
396 | static int parse_name(char **pname, const char *token, size_t limit) | ||
397 | { | ||
398 | size_t len; | ||
399 | char *name; | ||
400 | |||
401 | len = strlen(token) + 1; | ||
402 | if (len > limit) | ||
403 | return -ENOSPC; | ||
404 | |||
405 | name = kmalloc(len, GFP_KERNEL); | ||
406 | if (!name) | ||
407 | return -ENOMEM; | ||
408 | |||
409 | strcpy(name, token); | ||
410 | |||
411 | *pname = name; | ||
412 | return 0; | ||
413 | } | ||
414 | |||
415 | |||
416 | static inline void kill_final_newline(char *str) | 412 | static inline void kill_final_newline(char *str) |
417 | { | 413 | { |
418 | char *newline = strrchr(str, '\n'); | 414 | char *newline = strrchr(str, '\n'); |
@@ -426,9 +422,15 @@ static inline void kill_final_newline(char *str) | |||
426 | return 0; \ | 422 | return 0; \ |
427 | } while (0) | 423 | } while (0) |
428 | 424 | ||
429 | static int block2mtd_setup(const char *val, struct kernel_param *kp) | 425 | #ifndef MODULE |
426 | static int block2mtd_init_called = 0; | ||
427 | static __initdata char block2mtd_paramline[80 + 12]; /* 80 for device, 12 for erase size */ | ||
428 | #endif | ||
429 | |||
430 | |||
431 | static int block2mtd_setup2(const char *val) | ||
430 | { | 432 | { |
431 | char buf[80+12]; /* 80 for device, 12 for erase size */ | 433 | char buf[80 + 12]; /* 80 for device, 12 for erase size */ |
432 | char *str = buf; | 434 | char *str = buf; |
433 | char *token[2]; | 435 | char *token[2]; |
434 | char *name; | 436 | char *name; |
@@ -450,13 +452,9 @@ static int block2mtd_setup(const char *val, struct kernel_param *kp) | |||
450 | if (!token[0]) | 452 | if (!token[0]) |
451 | parse_err("no argument"); | 453 | parse_err("no argument"); |
452 | 454 | ||
453 | ret = parse_name(&name, token[0], 80); | 455 | name = token[0]; |
454 | if (ret == -ENOMEM) | 456 | if (strlen(name) + 1 > 80) |
455 | parse_err("out of memory"); | 457 | parse_err("device name too long"); |
456 | if (ret == -ENOSPC) | ||
457 | parse_err("name too long"); | ||
458 | if (ret) | ||
459 | return 0; | ||
460 | 458 | ||
461 | if (token[1]) { | 459 | if (token[1]) { |
462 | ret = parse_num(&erase_size, token[1]); | 460 | ret = parse_num(&erase_size, token[1]); |
@@ -472,13 +470,48 @@ static int block2mtd_setup(const char *val, struct kernel_param *kp) | |||
472 | } | 470 | } |
473 | 471 | ||
474 | 472 | ||
473 | static int block2mtd_setup(const char *val, struct kernel_param *kp) | ||
474 | { | ||
475 | #ifdef MODULE | ||
476 | return block2mtd_setup2(val); | ||
477 | #else | ||
478 | /* If more parameters are later passed in via | ||
479 | /sys/module/block2mtd/parameters/block2mtd | ||
480 | and block2mtd_init() has already been called, | ||
481 | we can parse the argument now. */ | ||
482 | |||
483 | if (block2mtd_init_called) | ||
484 | return block2mtd_setup2(val); | ||
485 | |||
486 | /* During early boot stage, we only save the parameters | ||
487 | here. We must parse them later: if the param passed | ||
488 | from kernel boot command line, block2mtd_setup() is | ||
489 | called so early that it is not possible to resolve | ||
490 | the device (even kmalloc() fails). Deter that work to | ||
491 | block2mtd_setup2(). */ | ||
492 | |||
493 | strlcpy(block2mtd_paramline, val, sizeof(block2mtd_paramline)); | ||
494 | |||
495 | return 0; | ||
496 | #endif | ||
497 | } | ||
498 | |||
499 | |||
475 | module_param_call(block2mtd, block2mtd_setup, NULL, NULL, 0200); | 500 | module_param_call(block2mtd, block2mtd_setup, NULL, NULL, 0200); |
476 | MODULE_PARM_DESC(block2mtd, "Device to use. \"block2mtd=<dev>[,<erasesize>]\""); | 501 | MODULE_PARM_DESC(block2mtd, "Device to use. \"block2mtd=<dev>[,<erasesize>]\""); |
477 | 502 | ||
478 | static int __init block2mtd_init(void) | 503 | static int __init block2mtd_init(void) |
479 | { | 504 | { |
505 | int ret = 0; | ||
480 | INFO("version " VERSION); | 506 | INFO("version " VERSION); |
481 | return 0; | 507 | |
508 | #ifndef MODULE | ||
509 | if (strlen(block2mtd_paramline)) | ||
510 | ret = block2mtd_setup2(block2mtd_paramline); | ||
511 | block2mtd_init_called = 1; | ||
512 | #endif | ||
513 | |||
514 | return ret; | ||
482 | } | 515 | } |
483 | 516 | ||
484 | 517 | ||
diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c index a8466141e914..ef4a731ca5c2 100644 --- a/drivers/mtd/devices/m25p80.c +++ b/drivers/mtd/devices/m25p80.c | |||
@@ -406,13 +406,13 @@ struct flash_info { | |||
406 | 406 | ||
407 | static struct flash_info __devinitdata m25p_data [] = { | 407 | static struct flash_info __devinitdata m25p_data [] = { |
408 | /* REVISIT: fill in JEDEC ids, for parts that have them */ | 408 | /* REVISIT: fill in JEDEC ids, for parts that have them */ |
409 | { "m25p05", 0x05, 0x0000, 32 * 1024, 2 }, | 409 | { "m25p05", 0x05, 0x2010, 32 * 1024, 2 }, |
410 | { "m25p10", 0x10, 0x0000, 32 * 1024, 4 }, | 410 | { "m25p10", 0x10, 0x2011, 32 * 1024, 4 }, |
411 | { "m25p20", 0x11, 0x0000, 64 * 1024, 4 }, | 411 | { "m25p20", 0x11, 0x2012, 64 * 1024, 4 }, |
412 | { "m25p40", 0x12, 0x0000, 64 * 1024, 8 }, | 412 | { "m25p40", 0x12, 0x2013, 64 * 1024, 8 }, |
413 | { "m25p80", 0x13, 0x0000, 64 * 1024, 16 }, | 413 | { "m25p80", 0x13, 0x0000, 64 * 1024, 16 }, |
414 | { "m25p16", 0x14, 0x0000, 64 * 1024, 32 }, | 414 | { "m25p16", 0x14, 0x2015, 64 * 1024, 32 }, |
415 | { "m25p32", 0x15, 0x0000, 64 * 1024, 64 }, | 415 | { "m25p32", 0x15, 0x2016, 64 * 1024, 64 }, |
416 | { "m25p64", 0x16, 0x2017, 64 * 1024, 128 }, | 416 | { "m25p64", 0x16, 0x2017, 64 * 1024, 128 }, |
417 | }; | 417 | }; |
418 | 418 | ||
diff --git a/drivers/mtd/devices/pmc551.c b/drivers/mtd/devices/pmc551.c index 6f9bbf6fee4d..2c0149708739 100644 --- a/drivers/mtd/devices/pmc551.c +++ b/drivers/mtd/devices/pmc551.c | |||
@@ -99,10 +99,6 @@ | |||
99 | #include <asm/system.h> | 99 | #include <asm/system.h> |
100 | #include <linux/pci.h> | 100 | #include <linux/pci.h> |
101 | 101 | ||
102 | #ifndef CONFIG_PCI | ||
103 | #error Enable PCI in your kernel config | ||
104 | #endif | ||
105 | |||
106 | #include <linux/mtd/mtd.h> | 102 | #include <linux/mtd/mtd.h> |
107 | #include <linux/mtd/pmc551.h> | 103 | #include <linux/mtd/pmc551.h> |
108 | #include <linux/mtd/compatmac.h> | 104 | #include <linux/mtd/compatmac.h> |
diff --git a/drivers/mtd/maps/Kconfig b/drivers/mtd/maps/Kconfig index 83d0b2a52527..64d1b6a6c920 100644 --- a/drivers/mtd/maps/Kconfig +++ b/drivers/mtd/maps/Kconfig | |||
@@ -13,13 +13,13 @@ config MTD_COMPLEX_MAPPINGS | |||
13 | 13 | ||
14 | config MTD_PHYSMAP | 14 | config MTD_PHYSMAP |
15 | tristate "CFI Flash device in physical memory map" | 15 | tristate "CFI Flash device in physical memory map" |
16 | depends on MTD_CFI | 16 | depends on MTD_CFI || MTD_JEDECPROBE || MTD_ROM |
17 | help | 17 | help |
18 | This provides a 'mapping' driver which allows the CFI probe and | 18 | This provides a 'mapping' driver which allows the NOR Flash and |
19 | command set driver code to communicate with flash chips which | 19 | ROM driver code to communicate with chips which are mapped |
20 | are mapped physically into the CPU's memory. You will need to | 20 | physically into the CPU's memory. You will need to configure |
21 | configure the physical address and size of the flash chips on | 21 | the physical address and size of the flash chips on your |
22 | your particular board as well as the bus width, either statically | 22 | particular board as well as the bus width, either statically |
23 | with config options or at run-time. | 23 | with config options or at run-time. |
24 | 24 | ||
25 | config MTD_PHYSMAP_START | 25 | config MTD_PHYSMAP_START |
diff --git a/drivers/mtd/mtdchar.c b/drivers/mtd/mtdchar.c index fb8b4f7e48d3..5b6acfcb2b88 100644 --- a/drivers/mtd/mtdchar.c +++ b/drivers/mtd/mtdchar.c | |||
@@ -62,15 +62,12 @@ static loff_t mtd_lseek (struct file *file, loff_t offset, int orig) | |||
62 | struct mtd_info *mtd = mfi->mtd; | 62 | struct mtd_info *mtd = mfi->mtd; |
63 | 63 | ||
64 | switch (orig) { | 64 | switch (orig) { |
65 | case 0: | 65 | case SEEK_SET: |
66 | /* SEEK_SET */ | ||
67 | break; | 66 | break; |
68 | case 1: | 67 | case SEEK_CUR: |
69 | /* SEEK_CUR */ | ||
70 | offset += file->f_pos; | 68 | offset += file->f_pos; |
71 | break; | 69 | break; |
72 | case 2: | 70 | case SEEK_END: |
73 | /* SEEK_END */ | ||
74 | offset += mtd->size; | 71 | offset += mtd->size; |
75 | break; | 72 | break; |
76 | default: | 73 | default: |
diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig index 3db77eec0ed2..c99302ed3823 100644 --- a/drivers/mtd/nand/Kconfig +++ b/drivers/mtd/nand/Kconfig | |||
@@ -11,7 +11,7 @@ config MTD_NAND | |||
11 | help | 11 | help |
12 | This enables support for accessing all type of NAND flash | 12 | This enables support for accessing all type of NAND flash |
13 | devices. For further information see | 13 | devices. For further information see |
14 | <http://www.linux-mtd.infradead.org/tech/nand.html>. | 14 | <http://www.linux-mtd.infradead.org/doc/nand.html>. |
15 | 15 | ||
16 | config MTD_NAND_VERIFY_WRITE | 16 | config MTD_NAND_VERIFY_WRITE |
17 | bool "Verify NAND page writes" | 17 | bool "Verify NAND page writes" |
diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c index 0a54d003ef34..975b2ef61121 100644 --- a/drivers/mtd/nand/nand_base.c +++ b/drivers/mtd/nand/nand_base.c | |||
@@ -2224,7 +2224,7 @@ static struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd, | |||
2224 | } | 2224 | } |
2225 | 2225 | ||
2226 | /* Try to identify manufacturer */ | 2226 | /* Try to identify manufacturer */ |
2227 | for (maf_idx = 0; nand_manuf_ids[maf_idx].id != 0x0; maf_id++) { | 2227 | for (maf_idx = 0; nand_manuf_ids[maf_idx].id != 0x0; maf_idx++) { |
2228 | if (nand_manuf_ids[maf_idx].id == *maf_id) | 2228 | if (nand_manuf_ids[maf_idx].id == *maf_id) |
2229 | break; | 2229 | break; |
2230 | } | 2230 | } |
diff --git a/drivers/mtd/nand/sharpsl.c b/drivers/mtd/nand/sharpsl.c index fbeedc3184e9..51c7288ab49a 100644 --- a/drivers/mtd/nand/sharpsl.c +++ b/drivers/mtd/nand/sharpsl.c | |||
@@ -78,7 +78,7 @@ static struct mtd_partition sharpsl_nand_default_partition_info[] = { | |||
78 | /* | 78 | /* |
79 | * hardware specific access to control-lines | 79 | * hardware specific access to control-lines |
80 | * ctrl: | 80 | * ctrl: |
81 | * NAND_CNE: bit 0 -> bit 0 & 4 | 81 | * NAND_CNE: bit 0 -> ! bit 0 & 4 |
82 | * NAND_CLE: bit 1 -> bit 1 | 82 | * NAND_CLE: bit 1 -> bit 1 |
83 | * NAND_ALE: bit 2 -> bit 2 | 83 | * NAND_ALE: bit 2 -> bit 2 |
84 | * | 84 | * |
@@ -92,7 +92,10 @@ static void sharpsl_nand_hwcontrol(struct mtd_info *mtd, int cmd, | |||
92 | unsigned char bits = ctrl & 0x07; | 92 | unsigned char bits = ctrl & 0x07; |
93 | 93 | ||
94 | bits |= (ctrl & 0x01) << 4; | 94 | bits |= (ctrl & 0x01) << 4; |
95 | writeb((readb(FLASHCTL) & 0x17) | bits, FLASHCTL); | 95 | |
96 | bits ^= 0x11; | ||
97 | |||
98 | writeb((readb(FLASHCTL) & ~0x17) | bits, FLASHCTL); | ||
96 | } | 99 | } |
97 | 100 | ||
98 | if (cmd != NAND_CMD_NONE) | 101 | if (cmd != NAND_CMD_NONE) |
diff --git a/fs/ext2/balloc.c b/fs/ext2/balloc.c index d4870432ecfc..b1981d0e95ad 100644 --- a/fs/ext2/balloc.c +++ b/fs/ext2/balloc.c | |||
@@ -539,7 +539,6 @@ unsigned long ext2_count_free (struct buffer_head * map, unsigned int numchars) | |||
539 | 539 | ||
540 | #endif /* EXT2FS_DEBUG */ | 540 | #endif /* EXT2FS_DEBUG */ |
541 | 541 | ||
542 | /* Superblock must be locked */ | ||
543 | unsigned long ext2_count_free_blocks (struct super_block * sb) | 542 | unsigned long ext2_count_free_blocks (struct super_block * sb) |
544 | { | 543 | { |
545 | struct ext2_group_desc * desc; | 544 | struct ext2_group_desc * desc; |
diff --git a/fs/ext2/ialloc.c b/fs/ext2/ialloc.c index de85c61c58c5..695f69ccf908 100644 --- a/fs/ext2/ialloc.c +++ b/fs/ext2/ialloc.c | |||
@@ -637,7 +637,6 @@ fail: | |||
637 | return ERR_PTR(err); | 637 | return ERR_PTR(err); |
638 | } | 638 | } |
639 | 639 | ||
640 | /* Superblock must be locked */ | ||
641 | unsigned long ext2_count_free_inodes (struct super_block * sb) | 640 | unsigned long ext2_count_free_inodes (struct super_block * sb) |
642 | { | 641 | { |
643 | struct ext2_group_desc *desc; | 642 | struct ext2_group_desc *desc; |
diff --git a/fs/ext2/super.c b/fs/ext2/super.c index ca5bfb6914d2..4286ff6330b6 100644 --- a/fs/ext2/super.c +++ b/fs/ext2/super.c | |||
@@ -1083,7 +1083,6 @@ static int ext2_statfs (struct dentry * dentry, struct kstatfs * buf) | |||
1083 | unsigned long overhead; | 1083 | unsigned long overhead; |
1084 | int i; | 1084 | int i; |
1085 | 1085 | ||
1086 | lock_super(sb); | ||
1087 | if (test_opt (sb, MINIX_DF)) | 1086 | if (test_opt (sb, MINIX_DF)) |
1088 | overhead = 0; | 1087 | overhead = 0; |
1089 | else { | 1088 | else { |
@@ -1124,7 +1123,6 @@ static int ext2_statfs (struct dentry * dentry, struct kstatfs * buf) | |||
1124 | buf->f_files = le32_to_cpu(sbi->s_es->s_inodes_count); | 1123 | buf->f_files = le32_to_cpu(sbi->s_es->s_inodes_count); |
1125 | buf->f_ffree = ext2_count_free_inodes (sb); | 1124 | buf->f_ffree = ext2_count_free_inodes (sb); |
1126 | buf->f_namelen = EXT2_NAME_LEN; | 1125 | buf->f_namelen = EXT2_NAME_LEN; |
1127 | unlock_super(sb); | ||
1128 | return 0; | 1126 | return 0; |
1129 | } | 1127 | } |
1130 | 1128 | ||
diff --git a/fs/jffs2/nodelist.c b/fs/jffs2/nodelist.c index 7675b33396c7..5a6b4d64206c 100644 --- a/fs/jffs2/nodelist.c +++ b/fs/jffs2/nodelist.c | |||
@@ -21,6 +21,9 @@ | |||
21 | #include <linux/pagemap.h> | 21 | #include <linux/pagemap.h> |
22 | #include "nodelist.h" | 22 | #include "nodelist.h" |
23 | 23 | ||
24 | static void jffs2_obsolete_node_frag(struct jffs2_sb_info *c, | ||
25 | struct jffs2_node_frag *this); | ||
26 | |||
24 | void jffs2_add_fd_to_list(struct jffs2_sb_info *c, struct jffs2_full_dirent *new, struct jffs2_full_dirent **list) | 27 | void jffs2_add_fd_to_list(struct jffs2_sb_info *c, struct jffs2_full_dirent *new, struct jffs2_full_dirent **list) |
25 | { | 28 | { |
26 | struct jffs2_full_dirent **prev = list; | 29 | struct jffs2_full_dirent **prev = list; |
@@ -87,7 +90,8 @@ void jffs2_truncate_fragtree(struct jffs2_sb_info *c, struct rb_root *list, uint | |||
87 | } | 90 | } |
88 | } | 91 | } |
89 | 92 | ||
90 | void jffs2_obsolete_node_frag(struct jffs2_sb_info *c, struct jffs2_node_frag *this) | 93 | static void jffs2_obsolete_node_frag(struct jffs2_sb_info *c, |
94 | struct jffs2_node_frag *this) | ||
91 | { | 95 | { |
92 | if (this->node) { | 96 | if (this->node) { |
93 | this->node->frags--; | 97 | this->node->frags--; |
diff --git a/fs/jffs2/nodelist.h b/fs/jffs2/nodelist.h index cae92c14116d..0ddfd70307fb 100644 --- a/fs/jffs2/nodelist.h +++ b/fs/jffs2/nodelist.h | |||
@@ -334,7 +334,6 @@ void jffs2_kill_fragtree(struct rb_root *root, struct jffs2_sb_info *c_delete); | |||
334 | struct rb_node *rb_next(struct rb_node *); | 334 | struct rb_node *rb_next(struct rb_node *); |
335 | struct rb_node *rb_prev(struct rb_node *); | 335 | struct rb_node *rb_prev(struct rb_node *); |
336 | void rb_replace_node(struct rb_node *victim, struct rb_node *new, struct rb_root *root); | 336 | void rb_replace_node(struct rb_node *victim, struct rb_node *new, struct rb_root *root); |
337 | void jffs2_obsolete_node_frag(struct jffs2_sb_info *c, struct jffs2_node_frag *this); | ||
338 | int jffs2_add_full_dnode_to_inode(struct jffs2_sb_info *c, struct jffs2_inode_info *f, struct jffs2_full_dnode *fn); | 337 | int jffs2_add_full_dnode_to_inode(struct jffs2_sb_info *c, struct jffs2_inode_info *f, struct jffs2_full_dnode *fn); |
339 | void jffs2_truncate_fragtree (struct jffs2_sb_info *c, struct rb_root *list, uint32_t size); | 338 | void jffs2_truncate_fragtree (struct jffs2_sb_info *c, struct rb_root *list, uint32_t size); |
340 | int jffs2_add_older_frag_to_fragtree(struct jffs2_sb_info *c, struct jffs2_inode_info *f, struct jffs2_tmp_dnode_info *tn); | 339 | int jffs2_add_older_frag_to_fragtree(struct jffs2_sb_info *c, struct jffs2_inode_info *f, struct jffs2_tmp_dnode_info *tn); |
diff --git a/fs/jffs2/xattr.c b/fs/jffs2/xattr.c index 25bc1ae08648..4da09ce1d1f5 100644 --- a/fs/jffs2/xattr.c +++ b/fs/jffs2/xattr.c | |||
@@ -1215,7 +1215,6 @@ int jffs2_garbage_collect_xattr_datum(struct jffs2_sb_info *c, struct jffs2_xatt | |||
1215 | rc = jffs2_reserve_space_gc(c, totlen, &length, JFFS2_SUMMARY_XATTR_SIZE); | 1215 | rc = jffs2_reserve_space_gc(c, totlen, &length, JFFS2_SUMMARY_XATTR_SIZE); |
1216 | if (rc) { | 1216 | if (rc) { |
1217 | JFFS2_WARNING("jffs2_reserve_space_gc()=%d, request=%u\n", rc, totlen); | 1217 | JFFS2_WARNING("jffs2_reserve_space_gc()=%d, request=%u\n", rc, totlen); |
1218 | rc = rc ? rc : -EBADFD; | ||
1219 | goto out; | 1218 | goto out; |
1220 | } | 1219 | } |
1221 | rc = save_xattr_datum(c, xd); | 1220 | rc = save_xattr_datum(c, xd); |
diff --git a/include/asm-m68k/page.h b/include/asm-m68k/page.h index db017f838c29..fcc165ddd09e 100644 --- a/include/asm-m68k/page.h +++ b/include/asm-m68k/page.h | |||
@@ -2,6 +2,8 @@ | |||
2 | #define _M68K_PAGE_H | 2 | #define _M68K_PAGE_H |
3 | 3 | ||
4 | 4 | ||
5 | #ifdef __KERNEL__ | ||
6 | |||
5 | /* PAGE_SHIFT determines the page size */ | 7 | /* PAGE_SHIFT determines the page size */ |
6 | #ifndef CONFIG_SUN3 | 8 | #ifndef CONFIG_SUN3 |
7 | #define PAGE_SHIFT (12) | 9 | #define PAGE_SHIFT (12) |
@@ -15,8 +17,6 @@ | |||
15 | #endif | 17 | #endif |
16 | #define PAGE_MASK (~(PAGE_SIZE-1)) | 18 | #define PAGE_MASK (~(PAGE_SIZE-1)) |
17 | 19 | ||
18 | #ifdef __KERNEL__ | ||
19 | |||
20 | #include <asm/setup.h> | 20 | #include <asm/setup.h> |
21 | 21 | ||
22 | #if PAGE_SHIFT < 13 | 22 | #if PAGE_SHIFT < 13 |
@@ -175,8 +175,8 @@ static inline void *__va(unsigned long x) | |||
175 | #define VM_DATA_DEFAULT_FLAGS (VM_READ | VM_WRITE | VM_EXEC | \ | 175 | #define VM_DATA_DEFAULT_FLAGS (VM_READ | VM_WRITE | VM_EXEC | \ |
176 | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC) | 176 | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC) |
177 | 177 | ||
178 | #endif /* __KERNEL__ */ | ||
179 | |||
180 | #include <asm-generic/page.h> | 178 | #include <asm-generic/page.h> |
181 | 179 | ||
180 | #endif /* __KERNEL__ */ | ||
181 | |||
182 | #endif /* _M68K_PAGE_H */ | 182 | #endif /* _M68K_PAGE_H */ |
diff --git a/include/asm-parisc/page.h b/include/asm-parisc/page.h index 0695bc958d56..57d6d82756dd 100644 --- a/include/asm-parisc/page.h +++ b/include/asm-parisc/page.h | |||
@@ -1,22 +1,14 @@ | |||
1 | #ifndef _PARISC_PAGE_H | 1 | #ifndef _PARISC_PAGE_H |
2 | #define _PARISC_PAGE_H | 2 | #define _PARISC_PAGE_H |
3 | 3 | ||
4 | #if !defined(__KERNEL__) | ||
5 | /* this is for userspace applications (4k page size) */ | ||
6 | # define PAGE_SHIFT 12 /* 4k */ | ||
7 | # define PAGE_SIZE (1UL << PAGE_SHIFT) | ||
8 | # define PAGE_MASK (~(PAGE_SIZE-1)) | ||
9 | #endif | ||
10 | |||
11 | |||
12 | #ifdef __KERNEL__ | 4 | #ifdef __KERNEL__ |
13 | 5 | ||
14 | #if defined(CONFIG_PARISC_PAGE_SIZE_4KB) | 6 | #if defined(CONFIG_PARISC_PAGE_SIZE_4KB) |
15 | # define PAGE_SHIFT 12 /* 4k */ | 7 | # define PAGE_SHIFT 12 |
16 | #elif defined(CONFIG_PARISC_PAGE_SIZE_16KB) | 8 | #elif defined(CONFIG_PARISC_PAGE_SIZE_16KB) |
17 | # define PAGE_SHIFT 14 /* 16k */ | 9 | # define PAGE_SHIFT 14 |
18 | #elif defined(CONFIG_PARISC_PAGE_SIZE_64KB) | 10 | #elif defined(CONFIG_PARISC_PAGE_SIZE_64KB) |
19 | # define PAGE_SHIFT 16 /* 64k */ | 11 | # define PAGE_SHIFT 16 |
20 | #else | 12 | #else |
21 | # error "unknown default kernel page size" | 13 | # error "unknown default kernel page size" |
22 | #endif | 14 | #endif |
@@ -188,9 +180,9 @@ extern int npmem_ranges; | |||
188 | #define VM_DATA_DEFAULT_FLAGS (VM_READ | VM_WRITE | VM_EXEC | \ | 180 | #define VM_DATA_DEFAULT_FLAGS (VM_READ | VM_WRITE | VM_EXEC | \ |
189 | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC) | 181 | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC) |
190 | 182 | ||
191 | #endif /* __KERNEL__ */ | ||
192 | |||
193 | #include <asm-generic/memory_model.h> | 183 | #include <asm-generic/memory_model.h> |
194 | #include <asm-generic/page.h> | 184 | #include <asm-generic/page.h> |
195 | 185 | ||
186 | #endif /* __KERNEL__ */ | ||
187 | |||
196 | #endif /* _PARISC_PAGE_H */ | 188 | #endif /* _PARISC_PAGE_H */ |
diff --git a/include/linux/mtd/cfi.h b/include/linux/mtd/cfi.h index 09bfae6938b3..123948b14547 100644 --- a/include/linux/mtd/cfi.h +++ b/include/linux/mtd/cfi.h | |||
@@ -199,6 +199,18 @@ struct cfi_pri_amdstd { | |||
199 | uint8_t TopBottom; | 199 | uint8_t TopBottom; |
200 | } __attribute__((packed)); | 200 | } __attribute__((packed)); |
201 | 201 | ||
202 | /* Vendor-Specific PRI for Atmel chips (command set 0x0002) */ | ||
203 | |||
204 | struct cfi_pri_atmel { | ||
205 | uint8_t pri[3]; | ||
206 | uint8_t MajorVersion; | ||
207 | uint8_t MinorVersion; | ||
208 | uint8_t Features; | ||
209 | uint8_t BottomBoot; | ||
210 | uint8_t BurstMode; | ||
211 | uint8_t PageMode; | ||
212 | } __attribute__((packed)); | ||
213 | |||
202 | struct cfi_pri_query { | 214 | struct cfi_pri_query { |
203 | uint8_t NumFields; | 215 | uint8_t NumFields; |
204 | uint32_t ProtField[1]; /* Not host ordered */ | 216 | uint32_t ProtField[1]; /* Not host ordered */ |
@@ -464,6 +476,7 @@ struct cfi_fixup { | |||
464 | #define CFI_ID_ANY 0xffff | 476 | #define CFI_ID_ANY 0xffff |
465 | 477 | ||
466 | #define CFI_MFR_AMD 0x0001 | 478 | #define CFI_MFR_AMD 0x0001 |
479 | #define CFI_MFR_ATMEL 0x001F | ||
467 | #define CFI_MFR_ST 0x0020 /* STMicroelectronics */ | 480 | #define CFI_MFR_ST 0x0020 /* STMicroelectronics */ |
468 | 481 | ||
469 | void cfi_fixup(struct mtd_info *mtd, struct cfi_fixup* fixups); | 482 | void cfi_fixup(struct mtd_info *mtd, struct cfi_fixup* fixups); |
diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c index 9336f2e89e40..ac1f850d4937 100644 --- a/kernel/irq/chip.c +++ b/kernel/irq/chip.c | |||
@@ -252,7 +252,7 @@ handle_level_irq(unsigned int irq, struct irq_desc *desc, struct pt_regs *regs) | |||
252 | mask_ack_irq(desc, irq); | 252 | mask_ack_irq(desc, irq); |
253 | 253 | ||
254 | if (unlikely(desc->status & IRQ_INPROGRESS)) | 254 | if (unlikely(desc->status & IRQ_INPROGRESS)) |
255 | goto out; | 255 | goto out_unlock; |
256 | desc->status &= ~(IRQ_REPLAY | IRQ_WAITING); | 256 | desc->status &= ~(IRQ_REPLAY | IRQ_WAITING); |
257 | kstat_cpu(cpu).irqs[irq]++; | 257 | kstat_cpu(cpu).irqs[irq]++; |
258 | 258 | ||
@@ -263,7 +263,7 @@ handle_level_irq(unsigned int irq, struct irq_desc *desc, struct pt_regs *regs) | |||
263 | action = desc->action; | 263 | action = desc->action; |
264 | if (unlikely(!action || (desc->status & IRQ_DISABLED))) { | 264 | if (unlikely(!action || (desc->status & IRQ_DISABLED))) { |
265 | desc->status |= IRQ_PENDING; | 265 | desc->status |= IRQ_PENDING; |
266 | goto out; | 266 | goto out_unlock; |
267 | } | 267 | } |
268 | 268 | ||
269 | desc->status |= IRQ_INPROGRESS; | 269 | desc->status |= IRQ_INPROGRESS; |
@@ -276,9 +276,9 @@ handle_level_irq(unsigned int irq, struct irq_desc *desc, struct pt_regs *regs) | |||
276 | 276 | ||
277 | spin_lock(&desc->lock); | 277 | spin_lock(&desc->lock); |
278 | desc->status &= ~IRQ_INPROGRESS; | 278 | desc->status &= ~IRQ_INPROGRESS; |
279 | out: | ||
280 | if (!(desc->status & IRQ_DISABLED) && desc->chip->unmask) | 279 | if (!(desc->status & IRQ_DISABLED) && desc->chip->unmask) |
281 | desc->chip->unmask(irq); | 280 | desc->chip->unmask(irq); |
281 | out_unlock: | ||
282 | spin_unlock(&desc->lock); | 282 | spin_unlock(&desc->lock); |
283 | } | 283 | } |
284 | 284 | ||