diff options
author | Mark A. Greer <mgreer@mvista.com> | 2005-09-03 18:55:56 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@evo.osdl.org> | 2005-09-05 03:06:00 -0400 |
commit | d01c08c9ae91c1526d4564b400b3e0e04b49d1ba (patch) | |
tree | a1cc06a5342fdaf6185d2655a636cc181d56cb08 /arch/ppc | |
parent | bbde630b553d349307fe719486bc06f8cf9c1a2d (diff) |
[PATCH] ppc32: mv64x60 updates & enhancements
Updates and enhancement to the ppc32 mv64x60 code:
- move code to get mem size from mem ctlr to bootwrapper
- address some errata in the mv64360 pic code
- some minor cleanups
- export one of the bridge's regs via sysfs so user daemon can watch for
extraction events
Signed-off-by: Mark A. Greer <mgreer@mvista.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'arch/ppc')
-rw-r--r-- | arch/ppc/Kconfig.debug | 3 | ||||
-rw-r--r-- | arch/ppc/boot/simple/misc-mv64x60.c | 27 | ||||
-rw-r--r-- | arch/ppc/syslib/mv64360_pic.c | 31 | ||||
-rw-r--r-- | arch/ppc/syslib/mv64x60.c | 246 |
4 files changed, 198 insertions, 109 deletions
diff --git a/arch/ppc/Kconfig.debug b/arch/ppc/Kconfig.debug index e16c7710d4be..61653cb60c4e 100644 --- a/arch/ppc/Kconfig.debug +++ b/arch/ppc/Kconfig.debug | |||
@@ -62,7 +62,8 @@ config BOOTX_TEXT | |||
62 | 62 | ||
63 | config SERIAL_TEXT_DEBUG | 63 | config SERIAL_TEXT_DEBUG |
64 | bool "Support for early boot texts over serial port" | 64 | bool "Support for early boot texts over serial port" |
65 | depends on 4xx || GT64260 || LOPEC || PPLUS || PRPMC800 || PPC_GEN550 || PPC_MPC52xx | 65 | depends on 4xx || LOPEC || MV64X60 || PPLUS || PRPMC800 || \ |
66 | PPC_GEN550 || PPC_MPC52xx | ||
66 | 67 | ||
67 | config PPC_OCP | 68 | config PPC_OCP |
68 | bool | 69 | bool |
diff --git a/arch/ppc/boot/simple/misc-mv64x60.c b/arch/ppc/boot/simple/misc-mv64x60.c index 7e88fc6d207d..258d4599fadc 100644 --- a/arch/ppc/boot/simple/misc-mv64x60.c +++ b/arch/ppc/boot/simple/misc-mv64x60.c | |||
@@ -19,6 +19,33 @@ | |||
19 | extern struct bi_record *decompress_kernel(unsigned long load_addr, | 19 | extern struct bi_record *decompress_kernel(unsigned long load_addr, |
20 | int num_words, unsigned long cksum); | 20 | int num_words, unsigned long cksum); |
21 | 21 | ||
22 | |||
23 | u32 size_reg[MV64x60_CPU2MEM_WINDOWS] = { | ||
24 | MV64x60_CPU2MEM_0_SIZE, MV64x60_CPU2MEM_1_SIZE, | ||
25 | MV64x60_CPU2MEM_2_SIZE, MV64x60_CPU2MEM_3_SIZE | ||
26 | }; | ||
27 | |||
28 | /* Read mem ctlr to get the amount of mem in system */ | ||
29 | unsigned long | ||
30 | mv64360_get_mem_size(void) | ||
31 | { | ||
32 | u32 enables, i, v; | ||
33 | u32 mem = 0; | ||
34 | |||
35 | enables = in_le32((void __iomem *)CONFIG_MV64X60_NEW_BASE + | ||
36 | MV64360_CPU_BAR_ENABLE) & 0xf; | ||
37 | |||
38 | for (i=0; i<MV64x60_CPU2MEM_WINDOWS; i++) | ||
39 | if (!(enables & (1<<i))) { | ||
40 | v = in_le32((void __iomem *)CONFIG_MV64X60_NEW_BASE | ||
41 | + size_reg[i]) & 0xffff; | ||
42 | v = (v + 1) << 16; | ||
43 | mem += v; | ||
44 | } | ||
45 | |||
46 | return mem; | ||
47 | } | ||
48 | |||
22 | void | 49 | void |
23 | mv64x60_move_base(void __iomem *old_base, void __iomem *new_base) | 50 | mv64x60_move_base(void __iomem *old_base, void __iomem *new_base) |
24 | { | 51 | { |
diff --git a/arch/ppc/syslib/mv64360_pic.c b/arch/ppc/syslib/mv64360_pic.c index 74d8996418e9..8356da4678a2 100644 --- a/arch/ppc/syslib/mv64360_pic.c +++ b/arch/ppc/syslib/mv64360_pic.c | |||
@@ -366,10 +366,16 @@ mv64360_pci_error_int_handler(int irq, void *dev_id, struct pt_regs *regs) | |||
366 | return IRQ_HANDLED; | 366 | return IRQ_HANDLED; |
367 | } | 367 | } |
368 | 368 | ||
369 | /* | ||
370 | * Bit 0 of MV64x60_PCIx_ERR_MASK does not exist on the 64360 and because of | ||
371 | * errata FEr-#11 and FEr-##16 for the 64460, it should be 0 on that chip as | ||
372 | * well. IOW, don't set bit 0. | ||
373 | */ | ||
374 | #define MV64360_PCI0_ERR_MASK_VAL 0x00a50c24 | ||
375 | |||
369 | static int __init | 376 | static int __init |
370 | mv64360_register_hdlrs(void) | 377 | mv64360_register_hdlrs(void) |
371 | { | 378 | { |
372 | u32 mask; | ||
373 | int rc; | 379 | int rc; |
374 | 380 | ||
375 | /* Clear old errors and register CPU interface error intr handler */ | 381 | /* Clear old errors and register CPU interface error intr handler */ |
@@ -387,17 +393,6 @@ mv64360_register_hdlrs(void) | |||
387 | mv64360_sram_error_int_handler,SA_INTERRUPT,SRAM_INTR_STR, 0))) | 393 | mv64360_sram_error_int_handler,SA_INTERRUPT,SRAM_INTR_STR, 0))) |
388 | printk(KERN_WARNING "Can't register SRAM error handler: %d",rc); | 394 | printk(KERN_WARNING "Can't register SRAM error handler: %d",rc); |
389 | 395 | ||
390 | /* | ||
391 | * Bit 0 reserved on 64360 and erratum FEr PCI-#11 (PCI internal | ||
392 | * data parity error set incorrectly) on rev 0 & 1 of 64460 requires | ||
393 | * bit 0 to be cleared. | ||
394 | */ | ||
395 | mask = 0x00a50c24; | ||
396 | |||
397 | if ((mv64x60_get_bridge_type() == MV64x60_TYPE_MV64460) && | ||
398 | (mv64x60_get_bridge_rev() > 1)) | ||
399 | mask |= 0x1; /* enable DPErr on 64460 */ | ||
400 | |||
401 | /* Clear old errors and register PCI 0 error intr handler */ | 396 | /* Clear old errors and register PCI 0 error intr handler */ |
402 | mv64x60_write(&bh, MV64x60_PCI0_ERR_CAUSE, 0); | 397 | mv64x60_write(&bh, MV64x60_PCI0_ERR_CAUSE, 0); |
403 | if ((rc = request_irq(MV64360_IRQ_PCI0 + mv64360_irq_base, | 398 | if ((rc = request_irq(MV64360_IRQ_PCI0 + mv64360_irq_base, |
@@ -407,7 +402,11 @@ mv64360_register_hdlrs(void) | |||
407 | rc); | 402 | rc); |
408 | 403 | ||
409 | mv64x60_write(&bh, MV64x60_PCI0_ERR_MASK, 0); | 404 | mv64x60_write(&bh, MV64x60_PCI0_ERR_MASK, 0); |
410 | mv64x60_write(&bh, MV64x60_PCI0_ERR_MASK, mask); | 405 | mv64x60_write(&bh, MV64x60_PCI0_ERR_MASK, MV64360_PCI0_ERR_MASK_VAL); |
406 | |||
407 | /* Erratum FEr PCI-#16 says to clear bit 0 of PCI SERRn Mask reg. */ | ||
408 | mv64x60_write(&bh, MV64x60_PCI0_ERR_SERR_MASK, | ||
409 | mv64x60_read(&bh, MV64x60_PCI0_ERR_SERR_MASK) & ~0x1UL); | ||
411 | 410 | ||
412 | /* Clear old errors and register PCI 1 error intr handler */ | 411 | /* Clear old errors and register PCI 1 error intr handler */ |
413 | mv64x60_write(&bh, MV64x60_PCI1_ERR_CAUSE, 0); | 412 | mv64x60_write(&bh, MV64x60_PCI1_ERR_CAUSE, 0); |
@@ -418,7 +417,11 @@ mv64360_register_hdlrs(void) | |||
418 | rc); | 417 | rc); |
419 | 418 | ||
420 | mv64x60_write(&bh, MV64x60_PCI1_ERR_MASK, 0); | 419 | mv64x60_write(&bh, MV64x60_PCI1_ERR_MASK, 0); |
421 | mv64x60_write(&bh, MV64x60_PCI1_ERR_MASK, mask); | 420 | mv64x60_write(&bh, MV64x60_PCI1_ERR_MASK, MV64360_PCI0_ERR_MASK_VAL); |
421 | |||
422 | /* Erratum FEr PCI-#16 says to clear bit 0 of PCI Intr Mask reg. */ | ||
423 | mv64x60_write(&bh, MV64x60_PCI1_ERR_SERR_MASK, | ||
424 | mv64x60_read(&bh, MV64x60_PCI1_ERR_SERR_MASK) & ~0x1UL); | ||
422 | 425 | ||
423 | return 0; | 426 | return 0; |
424 | } | 427 | } |
diff --git a/arch/ppc/syslib/mv64x60.c b/arch/ppc/syslib/mv64x60.c index cc77177fa1c6..6262b11f366f 100644 --- a/arch/ppc/syslib/mv64x60.c +++ b/arch/ppc/syslib/mv64x60.c | |||
@@ -30,13 +30,16 @@ | |||
30 | #include <asm/mv64x60.h> | 30 | #include <asm/mv64x60.h> |
31 | 31 | ||
32 | 32 | ||
33 | u8 mv64x60_pci_exclude_bridge = 1; | 33 | u8 mv64x60_pci_exclude_bridge = 1; |
34 | spinlock_t mv64x60_lock = SPIN_LOCK_UNLOCKED; | 34 | spinlock_t mv64x60_lock = SPIN_LOCK_UNLOCKED; |
35 | 35 | ||
36 | static phys_addr_t mv64x60_bridge_pbase = 0; | 36 | static phys_addr_t mv64x60_bridge_pbase; |
37 | static void *mv64x60_bridge_vbase = 0; | 37 | static void *mv64x60_bridge_vbase; |
38 | static u32 mv64x60_bridge_type = MV64x60_TYPE_INVALID; | 38 | static u32 mv64x60_bridge_type = MV64x60_TYPE_INVALID; |
39 | static u32 mv64x60_bridge_rev = 0; | 39 | static u32 mv64x60_bridge_rev; |
40 | #if defined(CONFIG_SYSFS) && !defined(CONFIG_GT64260) | ||
41 | static struct pci_controller sysfs_hose_a; | ||
42 | #endif | ||
40 | 43 | ||
41 | static u32 gt64260_translate_size(u32 base, u32 size, u32 num_bits); | 44 | static u32 gt64260_translate_size(u32 base, u32 size, u32 num_bits); |
42 | static u32 gt64260_untranslate_size(u32 base, u32 size, u32 num_bits); | 45 | static u32 gt64260_untranslate_size(u32 base, u32 size, u32 num_bits); |
@@ -432,6 +435,20 @@ static struct platform_device i2c_device = { | |||
432 | }; | 435 | }; |
433 | #endif | 436 | #endif |
434 | 437 | ||
438 | #if defined(CONFIG_SYSFS) && !defined(CONFIG_GT64260) | ||
439 | static struct mv64xxx_pdata mv64xxx_pdata = { | ||
440 | .hs_reg_valid = 0, | ||
441 | }; | ||
442 | |||
443 | static struct platform_device mv64xxx_device = { /* general mv64x60 stuff */ | ||
444 | .name = MV64XXX_DEV_NAME, | ||
445 | .id = 0, | ||
446 | .dev = { | ||
447 | .platform_data = &mv64xxx_pdata, | ||
448 | }, | ||
449 | }; | ||
450 | #endif | ||
451 | |||
435 | static struct platform_device *mv64x60_pd_devs[] __initdata = { | 452 | static struct platform_device *mv64x60_pd_devs[] __initdata = { |
436 | #ifdef CONFIG_SERIAL_MPSC | 453 | #ifdef CONFIG_SERIAL_MPSC |
437 | &mpsc_shared_device, | 454 | &mpsc_shared_device, |
@@ -453,6 +470,9 @@ static struct platform_device *mv64x60_pd_devs[] __initdata = { | |||
453 | #ifdef CONFIG_I2C_MV64XXX | 470 | #ifdef CONFIG_I2C_MV64XXX |
454 | &i2c_device, | 471 | &i2c_device, |
455 | #endif | 472 | #endif |
473 | #if defined(CONFIG_SYSFS) && !defined(CONFIG_GT64260) | ||
474 | &mv64xxx_device, | ||
475 | #endif | ||
456 | }; | 476 | }; |
457 | 477 | ||
458 | /* | 478 | /* |
@@ -574,6 +594,11 @@ mv64x60_early_init(struct mv64x60_handle *bh, struct mv64x60_setup_info *si) | |||
574 | bh->hose_a = &hose_a; | 594 | bh->hose_a = &hose_a; |
575 | bh->hose_b = &hose_b; | 595 | bh->hose_b = &hose_b; |
576 | 596 | ||
597 | #if defined(CONFIG_SYSFS) && !defined(CONFIG_GT64260) | ||
598 | /* Save a copy of hose_a for sysfs functions -- hack */ | ||
599 | memcpy(&sysfs_hose_a, &hose_a, sizeof(hose_a)); | ||
600 | #endif | ||
601 | |||
577 | mv64x60_set_bus(bh, 0, 0); | 602 | mv64x60_set_bus(bh, 0, 0); |
578 | mv64x60_set_bus(bh, 1, 0); | 603 | mv64x60_set_bus(bh, 1, 0); |
579 | 604 | ||
@@ -590,8 +615,6 @@ mv64x60_early_init(struct mv64x60_handle *bh, struct mv64x60_setup_info *si) | |||
590 | 615 | ||
591 | mv64x60_set_bits(bh, MV64x60_PCI0_TO_RETRY, 0xffff); | 616 | mv64x60_set_bits(bh, MV64x60_PCI0_TO_RETRY, 0xffff); |
592 | mv64x60_set_bits(bh, MV64x60_PCI1_TO_RETRY, 0xffff); | 617 | mv64x60_set_bits(bh, MV64x60_PCI1_TO_RETRY, 0xffff); |
593 | |||
594 | return; | ||
595 | } | 618 | } |
596 | 619 | ||
597 | /* | 620 | /* |
@@ -628,19 +651,15 @@ mv64x60_get_32bit_window(struct mv64x60_handle *bh, u32 window, | |||
628 | val = mv64x60_read(bh, size_reg); | 651 | val = mv64x60_read(bh, size_reg); |
629 | val = get_from_field(val, size_bits); | 652 | val = get_from_field(val, size_bits); |
630 | *size = bh->ci->untranslate_size(*base, val, size_bits); | 653 | *size = bh->ci->untranslate_size(*base, val, size_bits); |
631 | } | 654 | } else |
632 | else | ||
633 | *size = 0; | 655 | *size = 0; |
634 | } | 656 | } else { |
635 | else { | ||
636 | *base = 0; | 657 | *base = 0; |
637 | *size = 0; | 658 | *size = 0; |
638 | } | 659 | } |
639 | 660 | ||
640 | pr_debug("get 32bit window: %d, base: 0x%x, size: 0x%x\n", | 661 | pr_debug("get 32bit window: %d, base: 0x%x, size: 0x%x\n", |
641 | window, *base, *size); | 662 | window, *base, *size); |
642 | |||
643 | return; | ||
644 | } | 663 | } |
645 | 664 | ||
646 | /* | 665 | /* |
@@ -677,8 +696,6 @@ mv64x60_set_32bit_window(struct mv64x60_handle *bh, u32 window, | |||
677 | 696 | ||
678 | (void)mv64x60_read(bh, base_reg); /* Flush FIFO */ | 697 | (void)mv64x60_read(bh, base_reg); /* Flush FIFO */ |
679 | } | 698 | } |
680 | |||
681 | return; | ||
682 | } | 699 | } |
683 | 700 | ||
684 | /* | 701 | /* |
@@ -712,11 +729,9 @@ mv64x60_get_64bit_window(struct mv64x60_handle *bh, u32 window, | |||
712 | val = get_from_field(val, size_bits); | 729 | val = get_from_field(val, size_bits); |
713 | *size = bh->ci->untranslate_size(*base_lo, val, | 730 | *size = bh->ci->untranslate_size(*base_lo, val, |
714 | size_bits); | 731 | size_bits); |
715 | } | 732 | } else |
716 | else | ||
717 | *size = 0; | 733 | *size = 0; |
718 | } | 734 | } else { |
719 | else { | ||
720 | *base_hi = 0; | 735 | *base_hi = 0; |
721 | *base_lo = 0; | 736 | *base_lo = 0; |
722 | *size = 0; | 737 | *size = 0; |
@@ -724,8 +739,6 @@ mv64x60_get_64bit_window(struct mv64x60_handle *bh, u32 window, | |||
724 | 739 | ||
725 | pr_debug("get 64bit window: %d, base hi: 0x%x, base lo: 0x%x, " | 740 | pr_debug("get 64bit window: %d, base hi: 0x%x, base lo: 0x%x, " |
726 | "size: 0x%x\n", window, *base_hi, *base_lo, *size); | 741 | "size: 0x%x\n", window, *base_hi, *base_lo, *size); |
727 | |||
728 | return; | ||
729 | } | 742 | } |
730 | 743 | ||
731 | /* | 744 | /* |
@@ -766,8 +779,6 @@ mv64x60_set_64bit_window(struct mv64x60_handle *bh, u32 window, | |||
766 | 779 | ||
767 | (void)mv64x60_read(bh, base_lo_reg); /* Flush FIFO */ | 780 | (void)mv64x60_read(bh, base_lo_reg); /* Flush FIFO */ |
768 | } | 781 | } |
769 | |||
770 | return; | ||
771 | } | 782 | } |
772 | 783 | ||
773 | /* | 784 | /* |
@@ -1008,8 +1019,6 @@ mv64x60_get_mem_windows(struct mv64x60_handle *bh, | |||
1008 | mem_windows[i][0] = 0; | 1019 | mem_windows[i][0] = 0; |
1009 | mem_windows[i][1] = 0; | 1020 | mem_windows[i][1] = 0; |
1010 | } | 1021 | } |
1011 | |||
1012 | return; | ||
1013 | } | 1022 | } |
1014 | 1023 | ||
1015 | /* | 1024 | /* |
@@ -1077,8 +1086,6 @@ mv64x60_config_cpu2mem_windows(struct mv64x60_handle *bh, | |||
1077 | } | 1086 | } |
1078 | 1087 | ||
1079 | } | 1088 | } |
1080 | |||
1081 | return; | ||
1082 | } | 1089 | } |
1083 | 1090 | ||
1084 | /* | 1091 | /* |
@@ -1112,8 +1119,7 @@ mv64x60_config_cpu2pci_windows(struct mv64x60_handle *bh, | |||
1112 | mv64x60_set_32bit_window(bh, remap_tab[bus][0], | 1119 | mv64x60_set_32bit_window(bh, remap_tab[bus][0], |
1113 | pi->pci_io.pci_base_lo, 0, 0); | 1120 | pi->pci_io.pci_base_lo, 0, 0); |
1114 | bh->ci->enable_window_32bit(bh, win_tab[bus][0]); | 1121 | bh->ci->enable_window_32bit(bh, win_tab[bus][0]); |
1115 | } | 1122 | } else /* Actually, the window should already be disabled */ |
1116 | else /* Actually, the window should already be disabled */ | ||
1117 | bh->ci->disable_window_32bit(bh, win_tab[bus][0]); | 1123 | bh->ci->disable_window_32bit(bh, win_tab[bus][0]); |
1118 | 1124 | ||
1119 | for (i=0; i<3; i++) | 1125 | for (i=0; i<3; i++) |
@@ -1125,11 +1131,8 @@ mv64x60_config_cpu2pci_windows(struct mv64x60_handle *bh, | |||
1125 | pi->pci_mem[i].pci_base_hi, | 1131 | pi->pci_mem[i].pci_base_hi, |
1126 | pi->pci_mem[i].pci_base_lo, 0, 0); | 1132 | pi->pci_mem[i].pci_base_lo, 0, 0); |
1127 | bh->ci->enable_window_32bit(bh, win_tab[bus][i+1]); | 1133 | bh->ci->enable_window_32bit(bh, win_tab[bus][i+1]); |
1128 | } | 1134 | } else /* Actually, the window should already be disabled */ |
1129 | else /* Actually, the window should already be disabled */ | ||
1130 | bh->ci->disable_window_32bit(bh, win_tab[bus][i+1]); | 1135 | bh->ci->disable_window_32bit(bh, win_tab[bus][i+1]); |
1131 | |||
1132 | return; | ||
1133 | } | 1136 | } |
1134 | 1137 | ||
1135 | /* | 1138 | /* |
@@ -1206,8 +1209,6 @@ mv64x60_config_pci2mem_windows(struct mv64x60_handle *bh, | |||
1206 | MV64x60_PCI0_BAR_ENABLE : | 1209 | MV64x60_PCI0_BAR_ENABLE : |
1207 | MV64x60_PCI1_BAR_ENABLE), (1 << i)); | 1210 | MV64x60_PCI1_BAR_ENABLE), (1 << i)); |
1208 | } | 1211 | } |
1209 | |||
1210 | return; | ||
1211 | } | 1212 | } |
1212 | 1213 | ||
1213 | /* | 1214 | /* |
@@ -1229,7 +1230,6 @@ mv64x60_alloc_hose(struct mv64x60_handle *bh, u32 cfg_addr, u32 cfg_data, | |||
1229 | *hose = pcibios_alloc_controller(); | 1230 | *hose = pcibios_alloc_controller(); |
1230 | setup_indirect_pci_nomap(*hose, bh->v_base + cfg_addr, | 1231 | setup_indirect_pci_nomap(*hose, bh->v_base + cfg_addr, |
1231 | bh->v_base + cfg_data); | 1232 | bh->v_base + cfg_data); |
1232 | return; | ||
1233 | } | 1233 | } |
1234 | 1234 | ||
1235 | /* | 1235 | /* |
@@ -1272,7 +1272,6 @@ mv64x60_config_resources(struct pci_controller *hose, | |||
1272 | pi->pci_mem[0].size - 1; | 1272 | pi->pci_mem[0].size - 1; |
1273 | hose->pci_mem_offset = pi->pci_mem[0].cpu_base - | 1273 | hose->pci_mem_offset = pi->pci_mem[0].cpu_base - |
1274 | pi->pci_mem[0].pci_base_lo; | 1274 | pi->pci_mem[0].pci_base_lo; |
1275 | return; | ||
1276 | } | 1275 | } |
1277 | 1276 | ||
1278 | /* | 1277 | /* |
@@ -1309,7 +1308,6 @@ mv64x60_config_pci_params(struct pci_controller *hose, | |||
1309 | early_write_config_word(hose, 0, devfn, PCI_CACHE_LINE_SIZE, u16_val); | 1308 | early_write_config_word(hose, 0, devfn, PCI_CACHE_LINE_SIZE, u16_val); |
1310 | 1309 | ||
1311 | mv64x60_pci_exclude_bridge = save_exclude; | 1310 | mv64x60_pci_exclude_bridge = save_exclude; |
1312 | return; | ||
1313 | } | 1311 | } |
1314 | 1312 | ||
1315 | /* | 1313 | /* |
@@ -1336,8 +1334,7 @@ mv64x60_set_bus(struct mv64x60_handle *bh, u32 bus, u32 child_bus) | |||
1336 | p2p_cfg = MV64x60_PCI0_P2P_CONFIG; | 1334 | p2p_cfg = MV64x60_PCI0_P2P_CONFIG; |
1337 | pci_cfg_offset = 0x64; | 1335 | pci_cfg_offset = 0x64; |
1338 | hose = bh->hose_a; | 1336 | hose = bh->hose_a; |
1339 | } | 1337 | } else { |
1340 | else { | ||
1341 | pci_mode = bh->pci_mode_b; | 1338 | pci_mode = bh->pci_mode_b; |
1342 | p2p_cfg = MV64x60_PCI1_P2P_CONFIG; | 1339 | p2p_cfg = MV64x60_PCI1_P2P_CONFIG; |
1343 | pci_cfg_offset = 0xe4; | 1340 | pci_cfg_offset = 0xe4; |
@@ -1352,8 +1349,7 @@ mv64x60_set_bus(struct mv64x60_handle *bh, u32 bus, u32 child_bus) | |||
1352 | val |= (child_bus << 16) | 0xff; | 1349 | val |= (child_bus << 16) | 0xff; |
1353 | mv64x60_write(bh, p2p_cfg, val); | 1350 | mv64x60_write(bh, p2p_cfg, val); |
1354 | (void)mv64x60_read(bh, p2p_cfg); /* Flush FIFO */ | 1351 | (void)mv64x60_read(bh, p2p_cfg); /* Flush FIFO */ |
1355 | } | 1352 | } else { /* PCI-X */ |
1356 | else { /* PCI-X */ | ||
1357 | /* | 1353 | /* |
1358 | * Need to use the current bus/dev number (that's in the | 1354 | * Need to use the current bus/dev number (that's in the |
1359 | * P2P CONFIG reg) to access the bridge's pci config space. | 1355 | * P2P CONFIG reg) to access the bridge's pci config space. |
@@ -1365,8 +1361,6 @@ mv64x60_set_bus(struct mv64x60_handle *bh, u32 bus, u32 child_bus) | |||
1365 | pci_cfg_offset, child_bus << 8); | 1361 | pci_cfg_offset, child_bus << 8); |
1366 | mv64x60_pci_exclude_bridge = save_exclude; | 1362 | mv64x60_pci_exclude_bridge = save_exclude; |
1367 | } | 1363 | } |
1368 | |||
1369 | return; | ||
1370 | } | 1364 | } |
1371 | 1365 | ||
1372 | /* | 1366 | /* |
@@ -1423,8 +1417,6 @@ mv64x60_pd_fixup(struct mv64x60_handle *bh, struct platform_device *pd_devs[], | |||
1423 | j++; | 1417 | j++; |
1424 | } | 1418 | } |
1425 | } | 1419 | } |
1426 | |||
1427 | return; | ||
1428 | } | 1420 | } |
1429 | 1421 | ||
1430 | /* | 1422 | /* |
@@ -1498,8 +1490,6 @@ gt64260_set_pci2mem_window(struct pci_controller *hose, u32 bus, u32 window, | |||
1498 | early_write_config_dword(hose, 0, PCI_DEVFN(0, 0), | 1490 | early_write_config_dword(hose, 0, PCI_DEVFN(0, 0), |
1499 | gt64260_reg_addrs[bus][window], mv64x60_mask(base, 20) | 0x8); | 1491 | gt64260_reg_addrs[bus][window], mv64x60_mask(base, 20) | 0x8); |
1500 | mv64x60_pci_exclude_bridge = save_exclude; | 1492 | mv64x60_pci_exclude_bridge = save_exclude; |
1501 | |||
1502 | return; | ||
1503 | } | 1493 | } |
1504 | 1494 | ||
1505 | /* | 1495 | /* |
@@ -1523,8 +1513,6 @@ gt64260_set_pci2regs_window(struct mv64x60_handle *bh, | |||
1523 | early_write_config_dword(hose, 0, PCI_DEVFN(0,0), gt64260_offset[bus], | 1513 | early_write_config_dword(hose, 0, PCI_DEVFN(0,0), gt64260_offset[bus], |
1524 | (base << 16)); | 1514 | (base << 16)); |
1525 | mv64x60_pci_exclude_bridge = save_exclude; | 1515 | mv64x60_pci_exclude_bridge = save_exclude; |
1526 | |||
1527 | return; | ||
1528 | } | 1516 | } |
1529 | 1517 | ||
1530 | /* | 1518 | /* |
@@ -1561,7 +1549,6 @@ static void __init | |||
1561 | gt64260_enable_window_32bit(struct mv64x60_handle *bh, u32 window) | 1549 | gt64260_enable_window_32bit(struct mv64x60_handle *bh, u32 window) |
1562 | { | 1550 | { |
1563 | pr_debug("enable 32bit window: %d\n", window); | 1551 | pr_debug("enable 32bit window: %d\n", window); |
1564 | return; | ||
1565 | } | 1552 | } |
1566 | 1553 | ||
1567 | /* | 1554 | /* |
@@ -1584,8 +1571,6 @@ gt64260_disable_window_32bit(struct mv64x60_handle *bh, u32 window) | |||
1584 | mv64x60_write(bh, gt64260_32bit_windows[window].base_reg,0xfff); | 1571 | mv64x60_write(bh, gt64260_32bit_windows[window].base_reg,0xfff); |
1585 | mv64x60_write(bh, gt64260_32bit_windows[window].size_reg, 0); | 1572 | mv64x60_write(bh, gt64260_32bit_windows[window].size_reg, 0); |
1586 | } | 1573 | } |
1587 | |||
1588 | return; | ||
1589 | } | 1574 | } |
1590 | 1575 | ||
1591 | /* | 1576 | /* |
@@ -1599,7 +1584,6 @@ static void __init | |||
1599 | gt64260_enable_window_64bit(struct mv64x60_handle *bh, u32 window) | 1584 | gt64260_enable_window_64bit(struct mv64x60_handle *bh, u32 window) |
1600 | { | 1585 | { |
1601 | pr_debug("enable 64bit window: %d\n", window); | 1586 | pr_debug("enable 64bit window: %d\n", window); |
1602 | return; /* Enabled when window configured (i.e., when top >= base) */ | ||
1603 | } | 1587 | } |
1604 | 1588 | ||
1605 | /* | 1589 | /* |
@@ -1624,8 +1608,6 @@ gt64260_disable_window_64bit(struct mv64x60_handle *bh, u32 window) | |||
1624 | mv64x60_write(bh, gt64260_64bit_windows[window].base_hi_reg, 0); | 1608 | mv64x60_write(bh, gt64260_64bit_windows[window].base_hi_reg, 0); |
1625 | mv64x60_write(bh, gt64260_64bit_windows[window].size_reg, 0); | 1609 | mv64x60_write(bh, gt64260_64bit_windows[window].size_reg, 0); |
1626 | } | 1610 | } |
1627 | |||
1628 | return; | ||
1629 | } | 1611 | } |
1630 | 1612 | ||
1631 | /* | 1613 | /* |
@@ -1712,8 +1694,6 @@ gt64260_disable_all_windows(struct mv64x60_handle *bh, | |||
1712 | mv64x60_write(bh, GT64260_IC_CPU_INT_1_MASK, 0); | 1694 | mv64x60_write(bh, GT64260_IC_CPU_INT_1_MASK, 0); |
1713 | mv64x60_write(bh, GT64260_IC_CPU_INT_2_MASK, 0); | 1695 | mv64x60_write(bh, GT64260_IC_CPU_INT_2_MASK, 0); |
1714 | mv64x60_write(bh, GT64260_IC_CPU_INT_3_MASK, 0); | 1696 | mv64x60_write(bh, GT64260_IC_CPU_INT_3_MASK, 0); |
1715 | |||
1716 | return; | ||
1717 | } | 1697 | } |
1718 | 1698 | ||
1719 | /* | 1699 | /* |
@@ -1781,14 +1761,11 @@ gt64260a_chip_specific_init(struct mv64x60_handle *bh, | |||
1781 | mv64x60_mpsc1_pdata.cache_mgmt = 1; | 1761 | mv64x60_mpsc1_pdata.cache_mgmt = 1; |
1782 | 1762 | ||
1783 | if ((r = platform_get_resource(&mpsc1_device, IORESOURCE_IRQ, 0)) | 1763 | if ((r = platform_get_resource(&mpsc1_device, IORESOURCE_IRQ, 0)) |
1784 | != NULL) { | 1764 | != NULL) { |
1785 | |||
1786 | r->start = MV64x60_IRQ_SDMA_0; | 1765 | r->start = MV64x60_IRQ_SDMA_0; |
1787 | r->end = MV64x60_IRQ_SDMA_0; | 1766 | r->end = MV64x60_IRQ_SDMA_0; |
1788 | } | 1767 | } |
1789 | #endif | 1768 | #endif |
1790 | |||
1791 | return; | ||
1792 | } | 1769 | } |
1793 | 1770 | ||
1794 | /* | 1771 | /* |
@@ -1861,14 +1838,11 @@ gt64260b_chip_specific_init(struct mv64x60_handle *bh, | |||
1861 | mv64x60_mpsc1_pdata.cache_mgmt = 1; | 1838 | mv64x60_mpsc1_pdata.cache_mgmt = 1; |
1862 | 1839 | ||
1863 | if ((r = platform_get_resource(&mpsc1_device, IORESOURCE_IRQ, 0)) | 1840 | if ((r = platform_get_resource(&mpsc1_device, IORESOURCE_IRQ, 0)) |
1864 | != NULL) { | 1841 | != NULL) { |
1865 | |||
1866 | r->start = MV64x60_IRQ_SDMA_0; | 1842 | r->start = MV64x60_IRQ_SDMA_0; |
1867 | r->end = MV64x60_IRQ_SDMA_0; | 1843 | r->end = MV64x60_IRQ_SDMA_0; |
1868 | } | 1844 | } |
1869 | #endif | 1845 | #endif |
1870 | |||
1871 | return; | ||
1872 | } | 1846 | } |
1873 | 1847 | ||
1874 | /* | 1848 | /* |
@@ -1945,8 +1919,6 @@ mv64360_set_pci2mem_window(struct pci_controller *hose, u32 bus, u32 window, | |||
1945 | mv64360_reg_addrs[bus][window].base_lo_bar, | 1919 | mv64360_reg_addrs[bus][window].base_lo_bar, |
1946 | mv64x60_mask(base,20) | 0xc); | 1920 | mv64x60_mask(base,20) | 0xc); |
1947 | mv64x60_pci_exclude_bridge = save_exclude; | 1921 | mv64x60_pci_exclude_bridge = save_exclude; |
1948 | |||
1949 | return; | ||
1950 | } | 1922 | } |
1951 | 1923 | ||
1952 | /* | 1924 | /* |
@@ -1972,8 +1944,6 @@ mv64360_set_pci2regs_window(struct mv64x60_handle *bh, | |||
1972 | early_write_config_dword(hose, 0, PCI_DEVFN(0,0), | 1944 | early_write_config_dword(hose, 0, PCI_DEVFN(0,0), |
1973 | mv64360_offset[bus][1], 0); | 1945 | mv64360_offset[bus][1], 0); |
1974 | mv64x60_pci_exclude_bridge = save_exclude; | 1946 | mv64x60_pci_exclude_bridge = save_exclude; |
1975 | |||
1976 | return; | ||
1977 | } | 1947 | } |
1978 | 1948 | ||
1979 | /* | 1949 | /* |
@@ -2082,8 +2052,6 @@ mv64360_enable_window_32bit(struct mv64x60_handle *bh, u32 window) | |||
2082 | "32bit table corrupted"); | 2052 | "32bit table corrupted"); |
2083 | } | 2053 | } |
2084 | } | 2054 | } |
2085 | |||
2086 | return; | ||
2087 | } | 2055 | } |
2088 | 2056 | ||
2089 | /* | 2057 | /* |
@@ -2139,8 +2107,6 @@ mv64360_disable_window_32bit(struct mv64x60_handle *bh, u32 window) | |||
2139 | "32bit table corrupted"); | 2107 | "32bit table corrupted"); |
2140 | } | 2108 | } |
2141 | } | 2109 | } |
2142 | |||
2143 | return; | ||
2144 | } | 2110 | } |
2145 | 2111 | ||
2146 | /* | 2112 | /* |
@@ -2158,8 +2124,7 @@ mv64360_enable_window_64bit(struct mv64x60_handle *bh, u32 window) | |||
2158 | (mv64360_64bit_windows[window].size_reg != 0)) { | 2124 | (mv64360_64bit_windows[window].size_reg != 0)) { |
2159 | 2125 | ||
2160 | if ((mv64360_64bit_windows[window].extra & MV64x60_EXTRA_MASK) | 2126 | if ((mv64360_64bit_windows[window].extra & MV64x60_EXTRA_MASK) |
2161 | == MV64x60_EXTRA_PCIACC_ENAB) | 2127 | == MV64x60_EXTRA_PCIACC_ENAB) |
2162 | |||
2163 | mv64x60_set_bits(bh, | 2128 | mv64x60_set_bits(bh, |
2164 | mv64360_64bit_windows[window].base_lo_reg, | 2129 | mv64360_64bit_windows[window].base_lo_reg, |
2165 | (1 << (mv64360_64bit_windows[window].extra & | 2130 | (1 << (mv64360_64bit_windows[window].extra & |
@@ -2168,8 +2133,6 @@ mv64360_enable_window_64bit(struct mv64x60_handle *bh, u32 window) | |||
2168 | printk(KERN_ERR "mv64360_enable: %s\n", | 2133 | printk(KERN_ERR "mv64360_enable: %s\n", |
2169 | "64bit table corrupted"); | 2134 | "64bit table corrupted"); |
2170 | } | 2135 | } |
2171 | |||
2172 | return; | ||
2173 | } | 2136 | } |
2174 | 2137 | ||
2175 | /* | 2138 | /* |
@@ -2186,11 +2149,9 @@ mv64360_disable_window_64bit(struct mv64x60_handle *bh, u32 window) | |||
2186 | mv64360_64bit_windows[window].size_reg); | 2149 | mv64360_64bit_windows[window].size_reg); |
2187 | 2150 | ||
2188 | if ((mv64360_64bit_windows[window].base_lo_reg != 0) && | 2151 | if ((mv64360_64bit_windows[window].base_lo_reg != 0) && |
2189 | (mv64360_64bit_windows[window].size_reg != 0)) { | 2152 | (mv64360_64bit_windows[window].size_reg != 0)) { |
2190 | |||
2191 | if ((mv64360_64bit_windows[window].extra & MV64x60_EXTRA_MASK) | 2153 | if ((mv64360_64bit_windows[window].extra & MV64x60_EXTRA_MASK) |
2192 | == MV64x60_EXTRA_PCIACC_ENAB) | 2154 | == MV64x60_EXTRA_PCIACC_ENAB) |
2193 | |||
2194 | mv64x60_clr_bits(bh, | 2155 | mv64x60_clr_bits(bh, |
2195 | mv64360_64bit_windows[window].base_lo_reg, | 2156 | mv64360_64bit_windows[window].base_lo_reg, |
2196 | (1 << (mv64360_64bit_windows[window].extra & | 2157 | (1 << (mv64360_64bit_windows[window].extra & |
@@ -2199,8 +2160,6 @@ mv64360_disable_window_64bit(struct mv64x60_handle *bh, u32 window) | |||
2199 | printk(KERN_ERR "mv64360_disable: %s\n", | 2160 | printk(KERN_ERR "mv64360_disable: %s\n", |
2200 | "64bit table corrupted"); | 2161 | "64bit table corrupted"); |
2201 | } | 2162 | } |
2202 | |||
2203 | return; | ||
2204 | } | 2163 | } |
2205 | 2164 | ||
2206 | /* | 2165 | /* |
@@ -2241,8 +2200,6 @@ mv64360_disable_all_windows(struct mv64x60_handle *bh, | |||
2241 | /* Disable all PCI-><whatever> windows */ | 2200 | /* Disable all PCI-><whatever> windows */ |
2242 | mv64x60_set_bits(bh, MV64x60_PCI0_BAR_ENABLE, 0x0000f9ff); | 2201 | mv64x60_set_bits(bh, MV64x60_PCI0_BAR_ENABLE, 0x0000f9ff); |
2243 | mv64x60_set_bits(bh, MV64x60_PCI1_BAR_ENABLE, 0x0000f9ff); | 2202 | mv64x60_set_bits(bh, MV64x60_PCI1_BAR_ENABLE, 0x0000f9ff); |
2244 | |||
2245 | return; | ||
2246 | } | 2203 | } |
2247 | 2204 | ||
2248 | /* | 2205 | /* |
@@ -2335,8 +2292,6 @@ mv64360_config_io2mem_windows(struct mv64x60_handle *bh, | |||
2335 | mv64x60_set_bits(bh, MV64360_IDMA2MEM_ACC_PROT_3, | 2292 | mv64x60_set_bits(bh, MV64360_IDMA2MEM_ACC_PROT_3, |
2336 | (0x3 << (i << 1))); | 2293 | (0x3 << (i << 1))); |
2337 | } | 2294 | } |
2338 | |||
2339 | return; | ||
2340 | } | 2295 | } |
2341 | 2296 | ||
2342 | /* | 2297 | /* |
@@ -2350,42 +2305,145 @@ static void __init | |||
2350 | mv64360_set_mpsc2regs_window(struct mv64x60_handle *bh, u32 base) | 2305 | mv64360_set_mpsc2regs_window(struct mv64x60_handle *bh, u32 base) |
2351 | { | 2306 | { |
2352 | pr_debug("set mpsc->internal regs, base: 0x%x\n", base); | 2307 | pr_debug("set mpsc->internal regs, base: 0x%x\n", base); |
2353 | |||
2354 | mv64x60_write(bh, MV64360_MPSC2REGS_BASE, base & 0xffff0000); | 2308 | mv64x60_write(bh, MV64360_MPSC2REGS_BASE, base & 0xffff0000); |
2355 | return; | ||
2356 | } | 2309 | } |
2357 | 2310 | ||
2358 | /* | 2311 | /* |
2359 | * mv64360_chip_specific_init() | 2312 | * mv64360_chip_specific_init() |
2360 | * | 2313 | * |
2361 | * No errata work arounds for the MV64360 implemented at this point. | 2314 | * Implement errata work arounds for the MV64360. |
2362 | */ | 2315 | */ |
2363 | static void __init | 2316 | static void __init |
2364 | mv64360_chip_specific_init(struct mv64x60_handle *bh, | 2317 | mv64360_chip_specific_init(struct mv64x60_handle *bh, |
2365 | struct mv64x60_setup_info *si) | 2318 | struct mv64x60_setup_info *si) |
2366 | { | 2319 | { |
2320 | #if !defined(CONFIG_NOT_COHERENT_CACHE) | ||
2321 | mv64x60_set_bits(bh, MV64360_D_UNIT_CONTROL_HIGH, (1<<24)); | ||
2322 | #endif | ||
2367 | #ifdef CONFIG_SERIAL_MPSC | 2323 | #ifdef CONFIG_SERIAL_MPSC |
2368 | mv64x60_mpsc0_pdata.brg_can_tune = 1; | 2324 | mv64x60_mpsc0_pdata.brg_can_tune = 1; |
2369 | mv64x60_mpsc0_pdata.cache_mgmt = 1; | 2325 | mv64x60_mpsc0_pdata.cache_mgmt = 1; |
2370 | mv64x60_mpsc1_pdata.brg_can_tune = 1; | 2326 | mv64x60_mpsc1_pdata.brg_can_tune = 1; |
2371 | mv64x60_mpsc1_pdata.cache_mgmt = 1; | 2327 | mv64x60_mpsc1_pdata.cache_mgmt = 1; |
2372 | #endif | 2328 | #endif |
2373 | |||
2374 | return; | ||
2375 | } | 2329 | } |
2376 | 2330 | ||
2377 | /* | 2331 | /* |
2378 | * mv64460_chip_specific_init() | 2332 | * mv64460_chip_specific_init() |
2379 | * | 2333 | * |
2380 | * No errata work arounds for the MV64460 implemented at this point. | 2334 | * Implement errata work arounds for the MV64460. |
2381 | */ | 2335 | */ |
2382 | static void __init | 2336 | static void __init |
2383 | mv64460_chip_specific_init(struct mv64x60_handle *bh, | 2337 | mv64460_chip_specific_init(struct mv64x60_handle *bh, |
2384 | struct mv64x60_setup_info *si) | 2338 | struct mv64x60_setup_info *si) |
2385 | { | 2339 | { |
2340 | #if !defined(CONFIG_NOT_COHERENT_CACHE) | ||
2341 | mv64x60_set_bits(bh, MV64360_D_UNIT_CONTROL_HIGH, (1<<24) | (1<<25)); | ||
2342 | mv64x60_set_bits(bh, MV64460_D_UNIT_MMASK, (1<<1) | (1<<4)); | ||
2343 | #endif | ||
2386 | #ifdef CONFIG_SERIAL_MPSC | 2344 | #ifdef CONFIG_SERIAL_MPSC |
2387 | mv64x60_mpsc0_pdata.brg_can_tune = 1; | 2345 | mv64x60_mpsc0_pdata.brg_can_tune = 1; |
2346 | mv64x60_mpsc0_pdata.cache_mgmt = 1; | ||
2388 | mv64x60_mpsc1_pdata.brg_can_tune = 1; | 2347 | mv64x60_mpsc1_pdata.brg_can_tune = 1; |
2348 | mv64x60_mpsc1_pdata.cache_mgmt = 1; | ||
2389 | #endif | 2349 | #endif |
2390 | return; | ||
2391 | } | 2350 | } |
2351 | |||
2352 | |||
2353 | #if defined(CONFIG_SYSFS) && !defined(CONFIG_GT64260) | ||
2354 | /* Export the hotswap register via sysfs for enum event monitoring */ | ||
2355 | #define VAL_LEN_MAX 11 /* 32-bit hex or dec stringified number + '\n' */ | ||
2356 | |||
2357 | DECLARE_MUTEX(mv64xxx_hs_lock); | ||
2358 | |||
2359 | static ssize_t | ||
2360 | mv64xxx_hs_reg_read(struct kobject *kobj, char *buf, loff_t off, size_t count) | ||
2361 | { | ||
2362 | u32 v; | ||
2363 | u8 save_exclude; | ||
2364 | |||
2365 | if (off > 0) | ||
2366 | return 0; | ||
2367 | if (count < VAL_LEN_MAX) | ||
2368 | return -EINVAL; | ||
2369 | |||
2370 | if (down_interruptible(&mv64xxx_hs_lock)) | ||
2371 | return -ERESTARTSYS; | ||
2372 | save_exclude = mv64x60_pci_exclude_bridge; | ||
2373 | mv64x60_pci_exclude_bridge = 0; | ||
2374 | early_read_config_dword(&sysfs_hose_a, 0, PCI_DEVFN(0, 0), | ||
2375 | MV64360_PCICFG_CPCI_HOTSWAP, &v); | ||
2376 | mv64x60_pci_exclude_bridge = save_exclude; | ||
2377 | up(&mv64xxx_hs_lock); | ||
2378 | |||
2379 | return sprintf(buf, "0x%08x\n", v); | ||
2380 | } | ||
2381 | |||
2382 | static ssize_t | ||
2383 | mv64xxx_hs_reg_write(struct kobject *kobj, char *buf, loff_t off, size_t count) | ||
2384 | { | ||
2385 | u32 v; | ||
2386 | u8 save_exclude; | ||
2387 | |||
2388 | if (off > 0) | ||
2389 | return 0; | ||
2390 | if (count <= 0) | ||
2391 | return -EINVAL; | ||
2392 | |||
2393 | if (sscanf(buf, "%i", &v) == 1) { | ||
2394 | if (down_interruptible(&mv64xxx_hs_lock)) | ||
2395 | return -ERESTARTSYS; | ||
2396 | save_exclude = mv64x60_pci_exclude_bridge; | ||
2397 | mv64x60_pci_exclude_bridge = 0; | ||
2398 | early_write_config_dword(&sysfs_hose_a, 0, PCI_DEVFN(0, 0), | ||
2399 | MV64360_PCICFG_CPCI_HOTSWAP, v); | ||
2400 | mv64x60_pci_exclude_bridge = save_exclude; | ||
2401 | up(&mv64xxx_hs_lock); | ||
2402 | } | ||
2403 | else | ||
2404 | count = -EINVAL; | ||
2405 | |||
2406 | return count; | ||
2407 | } | ||
2408 | |||
2409 | static struct bin_attribute mv64xxx_hs_reg_attr = { /* Hotswap register */ | ||
2410 | .attr = { | ||
2411 | .name = "hs_reg", | ||
2412 | .mode = S_IRUGO | S_IWUSR, | ||
2413 | .owner = THIS_MODULE, | ||
2414 | }, | ||
2415 | .size = VAL_LEN_MAX, | ||
2416 | .read = mv64xxx_hs_reg_read, | ||
2417 | .write = mv64xxx_hs_reg_write, | ||
2418 | }; | ||
2419 | |||
2420 | /* Provide sysfs file indicating if this platform supports the hs_reg */ | ||
2421 | static ssize_t | ||
2422 | mv64xxx_hs_reg_valid_show(struct device *dev, struct device_attribute *attr, | ||
2423 | char *buf) | ||
2424 | { | ||
2425 | struct platform_device *pdev; | ||
2426 | struct mv64xxx_pdata *pdp; | ||
2427 | u32 v; | ||
2428 | |||
2429 | pdev = container_of(dev, struct platform_device, dev); | ||
2430 | pdp = (struct mv64xxx_pdata *)pdev->dev.platform_data; | ||
2431 | |||
2432 | if (down_interruptible(&mv64xxx_hs_lock)) | ||
2433 | return -ERESTARTSYS; | ||
2434 | v = pdp->hs_reg_valid; | ||
2435 | up(&mv64xxx_hs_lock); | ||
2436 | |||
2437 | return sprintf(buf, "%i\n", v); | ||
2438 | } | ||
2439 | static DEVICE_ATTR(hs_reg_valid, S_IRUGO, mv64xxx_hs_reg_valid_show, NULL); | ||
2440 | |||
2441 | static int __init | ||
2442 | mv64xxx_sysfs_init(void) | ||
2443 | { | ||
2444 | sysfs_create_bin_file(&mv64xxx_device.dev.kobj, &mv64xxx_hs_reg_attr); | ||
2445 | sysfs_create_file(&mv64xxx_device.dev.kobj,&dev_attr_hs_reg_valid.attr); | ||
2446 | return 0; | ||
2447 | } | ||
2448 | subsys_initcall(mv64xxx_sysfs_init); | ||
2449 | #endif | ||