diff options
-rw-r--r-- | arch/x86/Kconfig | 35 | ||||
-rw-r--r-- | arch/x86/kernel/cpu/intel.c | 32 | ||||
-rw-r--r-- | arch/x86/kernel/iosf_mbi.c | 91 | ||||
-rw-r--r-- | arch/x86/kernel/pmc_atom.c | 11 | ||||
-rw-r--r-- | arch/x86/kernel/quirks.c | 18 | ||||
-rw-r--r-- | arch/x86/kernel/setup.c | 9 | ||||
-rw-r--r-- | include/linux/pci_ids.h | 1 |
7 files changed, 187 insertions, 10 deletions
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index 3eb8a41509b3..f2327e88e07c 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig | |||
@@ -491,6 +491,36 @@ config X86_INTEL_LPSS | |||
491 | things like clock tree (common clock framework) and pincontrol | 491 | things like clock tree (common clock framework) and pincontrol |
492 | which are needed by the LPSS peripheral drivers. | 492 | which are needed by the LPSS peripheral drivers. |
493 | 493 | ||
494 | config IOSF_MBI | ||
495 | tristate "Intel SoC IOSF Sideband support for SoC platforms" | ||
496 | depends on PCI | ||
497 | ---help--- | ||
498 | This option enables sideband register access support for Intel SoC | ||
499 | platforms. On these platforms the IOSF sideband is used in lieu of | ||
500 | MSR's for some register accesses, mostly but not limited to thermal | ||
501 | and power. Drivers may query the availability of this device to | ||
502 | determine if they need the sideband in order to work on these | ||
503 | platforms. The sideband is available on the following SoC products. | ||
504 | This list is not meant to be exclusive. | ||
505 | - BayTrail | ||
506 | - Braswell | ||
507 | - Quark | ||
508 | |||
509 | You should say Y if you are running a kernel on one of these SoC's. | ||
510 | |||
511 | config IOSF_MBI_DEBUG | ||
512 | bool "Enable IOSF sideband access through debugfs" | ||
513 | depends on IOSF_MBI && DEBUG_FS | ||
514 | ---help--- | ||
515 | Select this option to expose the IOSF sideband access registers (MCR, | ||
516 | MDR, MCRX) through debugfs to write and read register information from | ||
517 | different units on the SoC. This is most useful for obtaining device | ||
518 | state information for debug and analysis. As this is a general access | ||
519 | mechanism, users of this option would have specific knowledge of the | ||
520 | device they want to access. | ||
521 | |||
522 | If you don't require the option or are in doubt, say N. | ||
523 | |||
494 | config X86_RDC321X | 524 | config X86_RDC321X |
495 | bool "RDC R-321x SoC" | 525 | bool "RDC R-321x SoC" |
496 | depends on X86_32 | 526 | depends on X86_32 |
@@ -2454,11 +2484,6 @@ config X86_DMA_REMAP | |||
2454 | bool | 2484 | bool |
2455 | depends on STA2X11 | 2485 | depends on STA2X11 |
2456 | 2486 | ||
2457 | config IOSF_MBI | ||
2458 | tristate | ||
2459 | default m | ||
2460 | depends on PCI | ||
2461 | |||
2462 | config PMC_ATOM | 2487 | config PMC_ATOM |
2463 | def_bool y | 2488 | def_bool y |
2464 | depends on PCI | 2489 | depends on PCI |
diff --git a/arch/x86/kernel/cpu/intel.c b/arch/x86/kernel/cpu/intel.c index 74e804ddc5c7..1ef456273172 100644 --- a/arch/x86/kernel/cpu/intel.c +++ b/arch/x86/kernel/cpu/intel.c | |||
@@ -144,6 +144,21 @@ static void early_init_intel(struct cpuinfo_x86 *c) | |||
144 | setup_clear_cpu_cap(X86_FEATURE_ERMS); | 144 | setup_clear_cpu_cap(X86_FEATURE_ERMS); |
145 | } | 145 | } |
146 | } | 146 | } |
147 | |||
148 | /* | ||
149 | * Intel Quark Core DevMan_001.pdf section 6.4.11 | ||
150 | * "The operating system also is required to invalidate (i.e., flush) | ||
151 | * the TLB when any changes are made to any of the page table entries. | ||
152 | * The operating system must reload CR3 to cause the TLB to be flushed" | ||
153 | * | ||
154 | * As a result cpu_has_pge() in arch/x86/include/asm/tlbflush.h should | ||
155 | * be false so that __flush_tlb_all() causes CR3 insted of CR4.PGE | ||
156 | * to be modified | ||
157 | */ | ||
158 | if (c->x86 == 5 && c->x86_model == 9) { | ||
159 | pr_info("Disabling PGE capability bit\n"); | ||
160 | setup_clear_cpu_cap(X86_FEATURE_PGE); | ||
161 | } | ||
147 | } | 162 | } |
148 | 163 | ||
149 | #ifdef CONFIG_X86_32 | 164 | #ifdef CONFIG_X86_32 |
@@ -382,6 +397,13 @@ static void init_intel(struct cpuinfo_x86 *c) | |||
382 | } | 397 | } |
383 | 398 | ||
384 | l2 = init_intel_cacheinfo(c); | 399 | l2 = init_intel_cacheinfo(c); |
400 | |||
401 | /* Detect legacy cache sizes if init_intel_cacheinfo did not */ | ||
402 | if (l2 == 0) { | ||
403 | cpu_detect_cache_sizes(c); | ||
404 | l2 = c->x86_cache_size; | ||
405 | } | ||
406 | |||
385 | if (c->cpuid_level > 9) { | 407 | if (c->cpuid_level > 9) { |
386 | unsigned eax = cpuid_eax(10); | 408 | unsigned eax = cpuid_eax(10); |
387 | /* Check for version and the number of counters */ | 409 | /* Check for version and the number of counters */ |
@@ -485,6 +507,13 @@ static unsigned int intel_size_cache(struct cpuinfo_x86 *c, unsigned int size) | |||
485 | */ | 507 | */ |
486 | if ((c->x86 == 6) && (c->x86_model == 11) && (size == 0)) | 508 | if ((c->x86 == 6) && (c->x86_model == 11) && (size == 0)) |
487 | size = 256; | 509 | size = 256; |
510 | |||
511 | /* | ||
512 | * Intel Quark SoC X1000 contains a 4-way set associative | ||
513 | * 16K cache with a 16 byte cache line and 256 lines per tag | ||
514 | */ | ||
515 | if ((c->x86 == 5) && (c->x86_model == 9)) | ||
516 | size = 16; | ||
488 | return size; | 517 | return size; |
489 | } | 518 | } |
490 | #endif | 519 | #endif |
@@ -686,7 +715,8 @@ static const struct cpu_dev intel_cpu_dev = { | |||
686 | [3] = "OverDrive PODP5V83", | 715 | [3] = "OverDrive PODP5V83", |
687 | [4] = "Pentium MMX", | 716 | [4] = "Pentium MMX", |
688 | [7] = "Mobile Pentium 75 - 200", | 717 | [7] = "Mobile Pentium 75 - 200", |
689 | [8] = "Mobile Pentium MMX" | 718 | [8] = "Mobile Pentium MMX", |
719 | [9] = "Quark SoC X1000", | ||
690 | } | 720 | } |
691 | }, | 721 | }, |
692 | { .family = 6, .model_names = | 722 | { .family = 6, .model_names = |
diff --git a/arch/x86/kernel/iosf_mbi.c b/arch/x86/kernel/iosf_mbi.c index 9030e83db6ee..82f8d02f0df2 100644 --- a/arch/x86/kernel/iosf_mbi.c +++ b/arch/x86/kernel/iosf_mbi.c | |||
@@ -22,10 +22,13 @@ | |||
22 | #include <linux/init.h> | 22 | #include <linux/init.h> |
23 | #include <linux/spinlock.h> | 23 | #include <linux/spinlock.h> |
24 | #include <linux/pci.h> | 24 | #include <linux/pci.h> |
25 | #include <linux/debugfs.h> | ||
26 | #include <linux/capability.h> | ||
25 | 27 | ||
26 | #include <asm/iosf_mbi.h> | 28 | #include <asm/iosf_mbi.h> |
27 | 29 | ||
28 | #define PCI_DEVICE_ID_BAYTRAIL 0x0F00 | 30 | #define PCI_DEVICE_ID_BAYTRAIL 0x0F00 |
31 | #define PCI_DEVICE_ID_BRASWELL 0x2280 | ||
29 | #define PCI_DEVICE_ID_QUARK_X1000 0x0958 | 32 | #define PCI_DEVICE_ID_QUARK_X1000 0x0958 |
30 | 33 | ||
31 | static DEFINE_SPINLOCK(iosf_mbi_lock); | 34 | static DEFINE_SPINLOCK(iosf_mbi_lock); |
@@ -187,6 +190,89 @@ bool iosf_mbi_available(void) | |||
187 | } | 190 | } |
188 | EXPORT_SYMBOL(iosf_mbi_available); | 191 | EXPORT_SYMBOL(iosf_mbi_available); |
189 | 192 | ||
193 | #ifdef CONFIG_IOSF_MBI_DEBUG | ||
194 | static u32 dbg_mdr; | ||
195 | static u32 dbg_mcr; | ||
196 | static u32 dbg_mcrx; | ||
197 | |||
198 | static int mcr_get(void *data, u64 *val) | ||
199 | { | ||
200 | *val = *(u32 *)data; | ||
201 | return 0; | ||
202 | } | ||
203 | |||
204 | static int mcr_set(void *data, u64 val) | ||
205 | { | ||
206 | u8 command = ((u32)val & 0xFF000000) >> 24, | ||
207 | port = ((u32)val & 0x00FF0000) >> 16, | ||
208 | offset = ((u32)val & 0x0000FF00) >> 8; | ||
209 | int err; | ||
210 | |||
211 | *(u32 *)data = val; | ||
212 | |||
213 | if (!capable(CAP_SYS_RAWIO)) | ||
214 | return -EACCES; | ||
215 | |||
216 | if (command & 1u) | ||
217 | err = iosf_mbi_write(port, | ||
218 | command, | ||
219 | dbg_mcrx | offset, | ||
220 | dbg_mdr); | ||
221 | else | ||
222 | err = iosf_mbi_read(port, | ||
223 | command, | ||
224 | dbg_mcrx | offset, | ||
225 | &dbg_mdr); | ||
226 | |||
227 | return err; | ||
228 | } | ||
229 | DEFINE_SIMPLE_ATTRIBUTE(iosf_mcr_fops, mcr_get, mcr_set , "%llx\n"); | ||
230 | |||
231 | static struct dentry *iosf_dbg; | ||
232 | |||
233 | static void iosf_sideband_debug_init(void) | ||
234 | { | ||
235 | struct dentry *d; | ||
236 | |||
237 | iosf_dbg = debugfs_create_dir("iosf_sb", NULL); | ||
238 | if (IS_ERR_OR_NULL(iosf_dbg)) | ||
239 | return; | ||
240 | |||
241 | /* mdr */ | ||
242 | d = debugfs_create_x32("mdr", 0660, iosf_dbg, &dbg_mdr); | ||
243 | if (IS_ERR_OR_NULL(d)) | ||
244 | goto cleanup; | ||
245 | |||
246 | /* mcrx */ | ||
247 | debugfs_create_x32("mcrx", 0660, iosf_dbg, &dbg_mcrx); | ||
248 | if (IS_ERR_OR_NULL(d)) | ||
249 | goto cleanup; | ||
250 | |||
251 | /* mcr - initiates mailbox tranaction */ | ||
252 | debugfs_create_file("mcr", 0660, iosf_dbg, &dbg_mcr, &iosf_mcr_fops); | ||
253 | if (IS_ERR_OR_NULL(d)) | ||
254 | goto cleanup; | ||
255 | |||
256 | return; | ||
257 | |||
258 | cleanup: | ||
259 | debugfs_remove_recursive(d); | ||
260 | } | ||
261 | |||
262 | static void iosf_debugfs_init(void) | ||
263 | { | ||
264 | iosf_sideband_debug_init(); | ||
265 | } | ||
266 | |||
267 | static void iosf_debugfs_remove(void) | ||
268 | { | ||
269 | debugfs_remove_recursive(iosf_dbg); | ||
270 | } | ||
271 | #else | ||
272 | static inline void iosf_debugfs_init(void) { } | ||
273 | static inline void iosf_debugfs_remove(void) { } | ||
274 | #endif /* CONFIG_IOSF_MBI_DEBUG */ | ||
275 | |||
190 | static int iosf_mbi_probe(struct pci_dev *pdev, | 276 | static int iosf_mbi_probe(struct pci_dev *pdev, |
191 | const struct pci_device_id *unused) | 277 | const struct pci_device_id *unused) |
192 | { | 278 | { |
@@ -204,6 +290,7 @@ static int iosf_mbi_probe(struct pci_dev *pdev, | |||
204 | 290 | ||
205 | static const struct pci_device_id iosf_mbi_pci_ids[] = { | 291 | static const struct pci_device_id iosf_mbi_pci_ids[] = { |
206 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_BAYTRAIL) }, | 292 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_BAYTRAIL) }, |
293 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_BRASWELL) }, | ||
207 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_QUARK_X1000) }, | 294 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_QUARK_X1000) }, |
208 | { 0, }, | 295 | { 0, }, |
209 | }; | 296 | }; |
@@ -217,11 +304,15 @@ static struct pci_driver iosf_mbi_pci_driver = { | |||
217 | 304 | ||
218 | static int __init iosf_mbi_init(void) | 305 | static int __init iosf_mbi_init(void) |
219 | { | 306 | { |
307 | iosf_debugfs_init(); | ||
308 | |||
220 | return pci_register_driver(&iosf_mbi_pci_driver); | 309 | return pci_register_driver(&iosf_mbi_pci_driver); |
221 | } | 310 | } |
222 | 311 | ||
223 | static void __exit iosf_mbi_exit(void) | 312 | static void __exit iosf_mbi_exit(void) |
224 | { | 313 | { |
314 | iosf_debugfs_remove(); | ||
315 | |||
225 | pci_unregister_driver(&iosf_mbi_pci_driver); | 316 | pci_unregister_driver(&iosf_mbi_pci_driver); |
226 | if (mbi_pdev) { | 317 | if (mbi_pdev) { |
227 | pci_dev_put(mbi_pdev); | 318 | pci_dev_put(mbi_pdev); |
diff --git a/arch/x86/kernel/pmc_atom.c b/arch/x86/kernel/pmc_atom.c index 0c424a67985d..0ee5025e0fa4 100644 --- a/arch/x86/kernel/pmc_atom.c +++ b/arch/x86/kernel/pmc_atom.c | |||
@@ -235,6 +235,11 @@ err: | |||
235 | pmc_dbgfs_unregister(pmc); | 235 | pmc_dbgfs_unregister(pmc); |
236 | return -ENODEV; | 236 | return -ENODEV; |
237 | } | 237 | } |
238 | #else | ||
239 | static int pmc_dbgfs_register(struct pmc_dev *pmc, struct pci_dev *pdev) | ||
240 | { | ||
241 | return 0; | ||
242 | } | ||
238 | #endif /* CONFIG_DEBUG_FS */ | 243 | #endif /* CONFIG_DEBUG_FS */ |
239 | 244 | ||
240 | static int pmc_setup_dev(struct pci_dev *pdev) | 245 | static int pmc_setup_dev(struct pci_dev *pdev) |
@@ -262,14 +267,12 @@ static int pmc_setup_dev(struct pci_dev *pdev) | |||
262 | /* PMC hardware registers setup */ | 267 | /* PMC hardware registers setup */ |
263 | pmc_hw_reg_setup(pmc); | 268 | pmc_hw_reg_setup(pmc); |
264 | 269 | ||
265 | #ifdef CONFIG_DEBUG_FS | ||
266 | ret = pmc_dbgfs_register(pmc, pdev); | 270 | ret = pmc_dbgfs_register(pmc, pdev); |
267 | if (ret) { | 271 | if (ret) { |
268 | iounmap(pmc->regmap); | 272 | iounmap(pmc->regmap); |
269 | return ret; | ||
270 | } | 273 | } |
271 | #endif /* CONFIG_DEBUG_FS */ | 274 | |
272 | return 0; | 275 | return ret; |
273 | } | 276 | } |
274 | 277 | ||
275 | /* | 278 | /* |
diff --git a/arch/x86/kernel/quirks.c b/arch/x86/kernel/quirks.c index ff898bbf579d..176a0f99d4da 100644 --- a/arch/x86/kernel/quirks.c +++ b/arch/x86/kernel/quirks.c | |||
@@ -498,6 +498,24 @@ void force_hpet_resume(void) | |||
498 | } | 498 | } |
499 | 499 | ||
500 | /* | 500 | /* |
501 | * According to the datasheet e6xx systems have the HPET hardwired to | ||
502 | * 0xfed00000 | ||
503 | */ | ||
504 | static void e6xx_force_enable_hpet(struct pci_dev *dev) | ||
505 | { | ||
506 | if (hpet_address || force_hpet_address) | ||
507 | return; | ||
508 | |||
509 | force_hpet_address = 0xFED00000; | ||
510 | force_hpet_resume_type = NONE_FORCE_HPET_RESUME; | ||
511 | dev_printk(KERN_DEBUG, &dev->dev, "Force enabled HPET at " | ||
512 | "0x%lx\n", force_hpet_address); | ||
513 | return; | ||
514 | } | ||
515 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_E6XX_CU, | ||
516 | e6xx_force_enable_hpet); | ||
517 | |||
518 | /* | ||
501 | * HPET MSI on some boards (ATI SB700/SB800) has side effect on | 519 | * HPET MSI on some boards (ATI SB700/SB800) has side effect on |
502 | * floppy DMA. Disable HPET MSI on such platforms. | 520 | * floppy DMA. Disable HPET MSI on such platforms. |
503 | * See erratum #27 (Misinterpreted MSI Requests May Result in | 521 | * See erratum #27 (Misinterpreted MSI Requests May Result in |
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c index 41ead8d3bc0b..235cfd39e0d7 100644 --- a/arch/x86/kernel/setup.c +++ b/arch/x86/kernel/setup.c | |||
@@ -879,6 +879,15 @@ void __init setup_arch(char **cmdline_p) | |||
879 | KERNEL_PGD_PTRS); | 879 | KERNEL_PGD_PTRS); |
880 | 880 | ||
881 | load_cr3(swapper_pg_dir); | 881 | load_cr3(swapper_pg_dir); |
882 | /* | ||
883 | * Note: Quark X1000 CPUs advertise PGE incorrectly and require | ||
884 | * a cr3 based tlb flush, so the following __flush_tlb_all() | ||
885 | * will not flush anything because the cpu quirk which clears | ||
886 | * X86_FEATURE_PGE has not been invoked yet. Though due to the | ||
887 | * load_cr3() above the TLB has been flushed already. The | ||
888 | * quirk is invoked before subsequent calls to __flush_tlb_all() | ||
889 | * so proper operation is guaranteed. | ||
890 | */ | ||
882 | __flush_tlb_all(); | 891 | __flush_tlb_all(); |
883 | #else | 892 | #else |
884 | printk(KERN_INFO "Command line: %s\n", boot_command_line); | 893 | printk(KERN_INFO "Command line: %s\n", boot_command_line); |
diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index 0aa51b451597..24f97bf74266 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h | |||
@@ -2878,6 +2878,7 @@ | |||
2878 | #define PCI_DEVICE_ID_INTEL_82372FB_1 0x7601 | 2878 | #define PCI_DEVICE_ID_INTEL_82372FB_1 0x7601 |
2879 | #define PCI_DEVICE_ID_INTEL_SCH_LPC 0x8119 | 2879 | #define PCI_DEVICE_ID_INTEL_SCH_LPC 0x8119 |
2880 | #define PCI_DEVICE_ID_INTEL_SCH_IDE 0x811a | 2880 | #define PCI_DEVICE_ID_INTEL_SCH_IDE 0x811a |
2881 | #define PCI_DEVICE_ID_INTEL_E6XX_CU 0x8183 | ||
2881 | #define PCI_DEVICE_ID_INTEL_ITC_LPC 0x8186 | 2882 | #define PCI_DEVICE_ID_INTEL_ITC_LPC 0x8186 |
2882 | #define PCI_DEVICE_ID_INTEL_82454GX 0x84c4 | 2883 | #define PCI_DEVICE_ID_INTEL_82454GX 0x84c4 |
2883 | #define PCI_DEVICE_ID_INTEL_82450GX 0x84c5 | 2884 | #define PCI_DEVICE_ID_INTEL_82450GX 0x84c5 |