aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/powerpc/configs/cell_defconfig40
-rw-r--r--arch/powerpc/kernel/cputable.c16
-rw-r--r--arch/powerpc/kernel/module_64.c16
-rw-r--r--arch/powerpc/kernel/prom_init.c112
-rw-r--r--arch/powerpc/kernel/setup-common.c8
-rw-r--r--arch/powerpc/kernel/setup_64.c8
-rw-r--r--arch/powerpc/kernel/systbl.S13
-rw-r--r--arch/powerpc/mm/hugetlbpage.c295
-rw-r--r--arch/powerpc/mm/init_64.c7
-rw-r--r--arch/powerpc/platforms/cell/spu_base.c10
-rw-r--r--arch/powerpc/platforms/cell/spu_callbacks.c13
-rw-r--r--arch/ppc/platforms/4xx/ocotea.c2
-rw-r--r--arch/ppc/platforms/mpc8272ads_setup.c114
-rw-r--r--arch/ppc/platforms/mpc866ads_setup.c140
-rw-r--r--arch/ppc/platforms/mpc885ads_setup.c131
-rw-r--r--arch/ppc/platforms/pq2ads.c31
-rw-r--r--arch/ppc/syslib/ibm440gx_common.c13
-rw-r--r--arch/ppc/syslib/ibm440gx_common.h4
-rw-r--r--arch/ppc/syslib/mpc8xx_devices.c25
-rw-r--r--arch/ppc/syslib/ppc_sys.c4
-rw-r--r--arch/ppc/syslib/pq2_sys.c8
-rw-r--r--drivers/block/floppy.c2
-rw-r--r--drivers/input/serio/i8042-io.h4
-rw-r--r--drivers/scsi/Kconfig4
-rw-r--r--drivers/scsi/advansys.c2
-rw-r--r--drivers/serial/cpm_uart/cpm_uart.h49
-rw-r--r--drivers/serial/cpm_uart/cpm_uart_core.c280
-rw-r--r--drivers/serial/cpm_uart/cpm_uart_cpm1.c54
-rw-r--r--drivers/serial/cpm_uart/cpm_uart_cpm2.c14
-rw-r--r--drivers/video/au1200fb.c1922
-rw-r--r--fs/stat.c2
-rw-r--r--include/asm-i386/i387.h4
-rw-r--r--include/asm-powerpc/cputable.h14
-rw-r--r--include/asm-powerpc/io.h6
-rw-r--r--include/asm-powerpc/page_64.h1
-rw-r--r--include/asm-powerpc/pgalloc.h2
-rw-r--r--include/asm-powerpc/unistd.h20
-rw-r--r--include/asm-ppc/ppc_sys.h2
-rw-r--r--include/asm-ppc/reg_booke.h1
-rw-r--r--sound/ppc/toonie.c2
40 files changed, 1240 insertions, 2155 deletions
diff --git a/arch/powerpc/configs/cell_defconfig b/arch/powerpc/configs/cell_defconfig
index fe22e54ab2b0..dbe421dc3c11 100644
--- a/arch/powerpc/configs/cell_defconfig
+++ b/arch/powerpc/configs/cell_defconfig
@@ -9,6 +9,7 @@ CONFIG_PPC_MERGE=y
9CONFIG_MMU=y 9CONFIG_MMU=y
10CONFIG_GENERIC_HARDIRQS=y 10CONFIG_GENERIC_HARDIRQS=y
11CONFIG_RWSEM_XCHGADD_ALGORITHM=y 11CONFIG_RWSEM_XCHGADD_ALGORITHM=y
12CONFIG_GENERIC_HWEIGHT=y
12CONFIG_GENERIC_CALIBRATE_DELAY=y 13CONFIG_GENERIC_CALIBRATE_DELAY=y
13CONFIG_PPC=y 14CONFIG_PPC=y
14CONFIG_EARLY_PRINTK=y 15CONFIG_EARLY_PRINTK=y
@@ -55,6 +56,7 @@ CONFIG_SYSCTL=y
55CONFIG_IKCONFIG=y 56CONFIG_IKCONFIG=y
56CONFIG_IKCONFIG_PROC=y 57CONFIG_IKCONFIG_PROC=y
57# CONFIG_CPUSETS is not set 58# CONFIG_CPUSETS is not set
59# CONFIG_RELAY is not set
58CONFIG_INITRAMFS_SOURCE="" 60CONFIG_INITRAMFS_SOURCE=""
59CONFIG_CC_OPTIMIZE_FOR_SIZE=y 61CONFIG_CC_OPTIMIZE_FOR_SIZE=y
60# CONFIG_EMBEDDED is not set 62# CONFIG_EMBEDDED is not set
@@ -69,10 +71,6 @@ CONFIG_BASE_FULL=y
69CONFIG_FUTEX=y 71CONFIG_FUTEX=y
70CONFIG_EPOLL=y 72CONFIG_EPOLL=y
71CONFIG_SHMEM=y 73CONFIG_SHMEM=y
72CONFIG_CC_ALIGN_FUNCTIONS=0
73CONFIG_CC_ALIGN_LABELS=0
74CONFIG_CC_ALIGN_LOOPS=0
75CONFIG_CC_ALIGN_JUMPS=0
76CONFIG_SLAB=y 74CONFIG_SLAB=y
77# CONFIG_TINY_SHMEM is not set 75# CONFIG_TINY_SHMEM is not set
78CONFIG_BASE_SMALL=0 76CONFIG_BASE_SMALL=0
@@ -84,7 +82,6 @@ CONFIG_BASE_SMALL=0
84CONFIG_MODULES=y 82CONFIG_MODULES=y
85CONFIG_MODULE_UNLOAD=y 83CONFIG_MODULE_UNLOAD=y
86# CONFIG_MODULE_FORCE_UNLOAD is not set 84# CONFIG_MODULE_FORCE_UNLOAD is not set
87CONFIG_OBSOLETE_MODPARM=y
88# CONFIG_MODVERSIONS is not set 85# CONFIG_MODVERSIONS is not set
89# CONFIG_MODULE_SRCVERSION_ALL is not set 86# CONFIG_MODULE_SRCVERSION_ALL is not set
90CONFIG_KMOD=y 87CONFIG_KMOD=y
@@ -93,6 +90,7 @@ CONFIG_STOP_MACHINE=y
93# 90#
94# Block layer 91# Block layer
95# 92#
93# CONFIG_BLK_DEV_IO_TRACE is not set
96 94
97# 95#
98# IO Schedulers 96# IO Schedulers
@@ -126,6 +124,7 @@ CONFIG_RTAS_FLASH=y
126CONFIG_MMIO_NVRAM=y 124CONFIG_MMIO_NVRAM=y
127CONFIG_CELL_IIC=y 125CONFIG_CELL_IIC=y
128# CONFIG_PPC_MPC106 is not set 126# CONFIG_PPC_MPC106 is not set
127# CONFIG_PPC_970_NAP is not set
129# CONFIG_CPU_FREQ is not set 128# CONFIG_CPU_FREQ is not set
130# CONFIG_WANT_EARLY_SERIAL is not set 129# CONFIG_WANT_EARLY_SERIAL is not set
131 130
@@ -167,7 +166,6 @@ CONFIG_HAVE_MEMORY_PRESENT=y
167CONFIG_SPARSEMEM_EXTREME=y 166CONFIG_SPARSEMEM_EXTREME=y
168# CONFIG_MEMORY_HOTPLUG is not set 167# CONFIG_MEMORY_HOTPLUG is not set
169CONFIG_SPLIT_PTLOCK_CPUS=4 168CONFIG_SPLIT_PTLOCK_CPUS=4
170CONFIG_MIGRATION=y
171# CONFIG_PPC_64K_PAGES is not set 169# CONFIG_PPC_64K_PAGES is not set
172CONFIG_SCHED_SMT=y 170CONFIG_SCHED_SMT=y
173CONFIG_PROC_DEVICETREE=y 171CONFIG_PROC_DEVICETREE=y
@@ -184,7 +182,6 @@ CONFIG_GENERIC_ISA_DMA=y
184# CONFIG_PPC_INDIRECT_PCI is not set 182# CONFIG_PPC_INDIRECT_PCI is not set
185CONFIG_PCI=y 183CONFIG_PCI=y
186CONFIG_PCI_DOMAINS=y 184CONFIG_PCI_DOMAINS=y
187CONFIG_PCI_LEGACY_PROC=y
188# CONFIG_PCI_DEBUG is not set 185# CONFIG_PCI_DEBUG is not set
189 186
190# 187#
@@ -226,6 +223,7 @@ CONFIG_SYN_COOKIES=y
226# CONFIG_INET_AH is not set 223# CONFIG_INET_AH is not set
227# CONFIG_INET_ESP is not set 224# CONFIG_INET_ESP is not set
228# CONFIG_INET_IPCOMP is not set 225# CONFIG_INET_IPCOMP is not set
226# CONFIG_INET_XFRM_TUNNEL is not set
229CONFIG_INET_TUNNEL=y 227CONFIG_INET_TUNNEL=y
230CONFIG_INET_DIAG=y 228CONFIG_INET_DIAG=y
231CONFIG_INET_TCP_DIAG=y 229CONFIG_INET_TCP_DIAG=y
@@ -242,6 +240,7 @@ CONFIG_IPV6=y
242CONFIG_INET6_AH=m 240CONFIG_INET6_AH=m
243CONFIG_INET6_ESP=m 241CONFIG_INET6_ESP=m
244CONFIG_INET6_IPCOMP=m 242CONFIG_INET6_IPCOMP=m
243CONFIG_INET6_XFRM_TUNNEL=m
245CONFIG_INET6_TUNNEL=m 244CONFIG_INET6_TUNNEL=m
246CONFIG_IPV6_TUNNEL=m 245CONFIG_IPV6_TUNNEL=m
247CONFIG_NETFILTER=y 246CONFIG_NETFILTER=y
@@ -632,6 +631,7 @@ CONFIG_SERIAL_NONSTANDARD=y
632# 631#
633CONFIG_SERIAL_8250=y 632CONFIG_SERIAL_8250=y
634CONFIG_SERIAL_8250_CONSOLE=y 633CONFIG_SERIAL_8250_CONSOLE=y
634CONFIG_SERIAL_8250_PCI=y
635CONFIG_SERIAL_8250_NR_UARTS=4 635CONFIG_SERIAL_8250_NR_UARTS=4
636CONFIG_SERIAL_8250_RUNTIME_UARTS=4 636CONFIG_SERIAL_8250_RUNTIME_UARTS=4
637# CONFIG_SERIAL_8250_EXTENDED is not set 637# CONFIG_SERIAL_8250_EXTENDED is not set
@@ -717,7 +717,6 @@ CONFIG_I2C_ALGOBIT=y
717# CONFIG_I2C_PARPORT_LIGHT is not set 717# CONFIG_I2C_PARPORT_LIGHT is not set
718# CONFIG_I2C_PROSAVAGE is not set 718# CONFIG_I2C_PROSAVAGE is not set
719# CONFIG_I2C_SAVAGE4 is not set 719# CONFIG_I2C_SAVAGE4 is not set
720# CONFIG_SCx200_ACB is not set
721# CONFIG_I2C_SIS5595 is not set 720# CONFIG_I2C_SIS5595 is not set
722# CONFIG_I2C_SIS630 is not set 721# CONFIG_I2C_SIS630 is not set
723# CONFIG_I2C_SIS96X is not set 722# CONFIG_I2C_SIS96X is not set
@@ -736,9 +735,7 @@ CONFIG_I2C_ALGOBIT=y
736# CONFIG_SENSORS_PCF8574 is not set 735# CONFIG_SENSORS_PCF8574 is not set
737# CONFIG_SENSORS_PCA9539 is not set 736# CONFIG_SENSORS_PCA9539 is not set
738# CONFIG_SENSORS_PCF8591 is not set 737# CONFIG_SENSORS_PCF8591 is not set
739# CONFIG_SENSORS_RTC8564 is not set
740# CONFIG_SENSORS_MAX6875 is not set 738# CONFIG_SENSORS_MAX6875 is not set
741# CONFIG_RTC_X1205_I2C is not set
742# CONFIG_I2C_DEBUG_CORE is not set 739# CONFIG_I2C_DEBUG_CORE is not set
743# CONFIG_I2C_DEBUG_ALGO is not set 740# CONFIG_I2C_DEBUG_ALGO is not set
744# CONFIG_I2C_DEBUG_BUS is not set 741# CONFIG_I2C_DEBUG_BUS is not set
@@ -766,10 +763,6 @@ CONFIG_I2C_ALGOBIT=y
766# 763#
767 764
768# 765#
769# Multimedia Capabilities Port drivers
770#
771
772#
773# Multimedia devices 766# Multimedia devices
774# 767#
775# CONFIG_VIDEO_DEV is not set 768# CONFIG_VIDEO_DEV is not set
@@ -818,6 +811,19 @@ CONFIG_USB_ARCH_HAS_EHCI=y
818# CONFIG_MMC is not set 811# CONFIG_MMC is not set
819 812
820# 813#
814# LED devices
815#
816# CONFIG_NEW_LEDS is not set
817
818#
819# LED drivers
820#
821
822#
823# LED Triggers
824#
825
826#
821# InfiniBand support 827# InfiniBand support
822# 828#
823CONFIG_INFINIBAND=y 829CONFIG_INFINIBAND=y
@@ -834,6 +840,11 @@ CONFIG_INFINIBAND_IPOIB_DEBUG_DATA=y
834# 840#
835 841
836# 842#
843# Real Time Clock
844#
845# CONFIG_RTC_CLASS is not set
846
847#
837# File systems 848# File systems
838# 849#
839CONFIG_EXT2_FS=y 850CONFIG_EXT2_FS=y
@@ -889,7 +900,6 @@ CONFIG_TMPFS=y
889CONFIG_HUGETLBFS=y 900CONFIG_HUGETLBFS=y
890CONFIG_HUGETLB_PAGE=y 901CONFIG_HUGETLB_PAGE=y
891CONFIG_RAMFS=y 902CONFIG_RAMFS=y
892# CONFIG_RELAYFS_FS is not set
893# CONFIG_CONFIGFS_FS is not set 903# CONFIG_CONFIGFS_FS is not set
894 904
895# 905#
diff --git a/arch/powerpc/kernel/cputable.c b/arch/powerpc/kernel/cputable.c
index 39e348a3ade2..3f7182db9ed5 100644
--- a/arch/powerpc/kernel/cputable.c
+++ b/arch/powerpc/kernel/cputable.c
@@ -57,6 +57,8 @@ extern void __setup_cpu_ppc970(unsigned long offset, struct cpu_spec* spec);
57 PPC_FEATURE_SMT | PPC_FEATURE_ICACHE_SNOOP) 57 PPC_FEATURE_SMT | PPC_FEATURE_ICACHE_SNOOP)
58#define COMMON_USER_POWER5_PLUS (COMMON_USER_PPC64 | PPC_FEATURE_POWER5_PLUS|\ 58#define COMMON_USER_POWER5_PLUS (COMMON_USER_PPC64 | PPC_FEATURE_POWER5_PLUS|\
59 PPC_FEATURE_SMT | PPC_FEATURE_ICACHE_SNOOP) 59 PPC_FEATURE_SMT | PPC_FEATURE_ICACHE_SNOOP)
60#define COMMON_USER_POWER6 (COMMON_USER_PPC64 | PPC_FEATURE_ARCH_2_05 |\
61 PPC_FEATURE_SMT | PPC_FEATURE_ICACHE_SNOOP)
60#define COMMON_USER_BOOKE (PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU | \ 62#define COMMON_USER_BOOKE (PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU | \
61 PPC_FEATURE_BOOKE) 63 PPC_FEATURE_BOOKE)
62 64
@@ -263,6 +265,20 @@ struct cpu_spec cpu_specs[] = {
263 .oprofile_type = PPC_OPROFILE_POWER4, 265 .oprofile_type = PPC_OPROFILE_POWER4,
264 .platform = "power5+", 266 .platform = "power5+",
265 }, 267 },
268 { /* Power6 */
269 .pvr_mask = 0xffff0000,
270 .pvr_value = 0x003e0000,
271 .cpu_name = "POWER6",
272 .cpu_features = CPU_FTRS_POWER6,
273 .cpu_user_features = COMMON_USER_POWER6,
274 .icache_bsize = 128,
275 .dcache_bsize = 128,
276 .num_pmcs = 6,
277 .cpu_setup = __setup_cpu_power4,
278 .oprofile_cpu_type = "ppc64/power6",
279 .oprofile_type = PPC_OPROFILE_POWER4,
280 .platform = "power6",
281 },
266 { /* Cell Broadband Engine */ 282 { /* Cell Broadband Engine */
267 .pvr_mask = 0xffff0000, 283 .pvr_mask = 0xffff0000,
268 .pvr_value = 0x00700000, 284 .pvr_value = 0x00700000,
diff --git a/arch/powerpc/kernel/module_64.c b/arch/powerpc/kernel/module_64.c
index 928b8581fcb0..ba34001fca8e 100644
--- a/arch/powerpc/kernel/module_64.c
+++ b/arch/powerpc/kernel/module_64.c
@@ -191,11 +191,19 @@ int module_frob_arch_sections(Elf64_Ehdr *hdr,
191 (void *)hdr 191 (void *)hdr
192 + sechdrs[sechdrs[i].sh_link].sh_offset); 192 + sechdrs[sechdrs[i].sh_link].sh_offset);
193 } 193 }
194 if (!me->arch.stubs_section || !me->arch.toc_section) { 194
195 printk("%s: doesn't contain .toc or .stubs.\n", me->name); 195 if (!me->arch.stubs_section) {
196 printk("%s: doesn't contain .stubs.\n", me->name);
196 return -ENOEXEC; 197 return -ENOEXEC;
197 } 198 }
198 199
200 /* If we don't have a .toc, just use .stubs. We need to set r2
201 to some reasonable value in case the module calls out to
202 other functions via a stub, or if a function pointer escapes
203 the module by some means. */
204 if (!me->arch.toc_section)
205 me->arch.toc_section = me->arch.stubs_section;
206
199 /* Override the stubs size */ 207 /* Override the stubs size */
200 sechdrs[me->arch.stubs_section].sh_size = get_stubs_size(hdr, sechdrs); 208 sechdrs[me->arch.stubs_section].sh_size = get_stubs_size(hdr, sechdrs);
201 return 0; 209 return 0;
@@ -342,7 +350,7 @@ int apply_relocate_add(Elf64_Shdr *sechdrs,
342 break; 350 break;
343 351
344 case R_PPC64_TOC16: 352 case R_PPC64_TOC16:
345 /* Subtact TOC pointer */ 353 /* Subtract TOC pointer */
346 value -= my_r2(sechdrs, me); 354 value -= my_r2(sechdrs, me);
347 if (value + 0x8000 > 0xffff) { 355 if (value + 0x8000 > 0xffff) {
348 printk("%s: bad TOC16 relocation (%lu)\n", 356 printk("%s: bad TOC16 relocation (%lu)\n",
@@ -355,7 +363,7 @@ int apply_relocate_add(Elf64_Shdr *sechdrs,
355 break; 363 break;
356 364
357 case R_PPC64_TOC16_DS: 365 case R_PPC64_TOC16_DS:
358 /* Subtact TOC pointer */ 366 /* Subtract TOC pointer */
359 value -= my_r2(sechdrs, me); 367 value -= my_r2(sechdrs, me);
360 if ((value & 3) != 0 || value + 0x8000 > 0xffff) { 368 if ((value & 3) != 0 || value + 0x8000 > 0xffff) {
361 printk("%s: bad TOC16_DS relocation (%lu)\n", 369 printk("%s: bad TOC16_DS relocation (%lu)\n",
diff --git a/arch/powerpc/kernel/prom_init.c b/arch/powerpc/kernel/prom_init.c
index 7e4d54821a07..078fb5533541 100644
--- a/arch/powerpc/kernel/prom_init.c
+++ b/arch/powerpc/kernel/prom_init.c
@@ -636,10 +636,96 @@ static void __init early_cmdline_parse(void)
636 636
637#ifdef CONFIG_PPC_PSERIES 637#ifdef CONFIG_PPC_PSERIES
638/* 638/*
639 * To tell the firmware what our capabilities are, we have to pass 639 * There are two methods for telling firmware what our capabilities are.
640 * it a fake 32-bit ELF header containing a couple of PT_NOTE sections 640 * Newer machines have an "ibm,client-architecture-support" method on the
641 * that contain structures that contain the actual values. 641 * root node. For older machines, we have to call the "process-elf-header"
642 * method in the /packages/elf-loader node, passing it a fake 32-bit
643 * ELF header containing a couple of PT_NOTE sections that contain
644 * structures that contain various information.
642 */ 645 */
646
647/*
648 * New method - extensible architecture description vector.
649 *
650 * Because the description vector contains a mix of byte and word
651 * values, we declare it as an unsigned char array, and use this
652 * macro to put word values in.
653 */
654#define W(x) ((x) >> 24) & 0xff, ((x) >> 16) & 0xff, \
655 ((x) >> 8) & 0xff, (x) & 0xff
656
657/* Option vector bits - generic bits in byte 1 */
658#define OV_IGNORE 0x80 /* ignore this vector */
659#define OV_CESSATION_POLICY 0x40 /* halt if unsupported option present*/
660
661/* Option vector 1: processor architectures supported */
662#define OV1_PPC_2_00 0x80 /* set if we support PowerPC 2.00 */
663#define OV1_PPC_2_01 0x40 /* set if we support PowerPC 2.01 */
664#define OV1_PPC_2_02 0x20 /* set if we support PowerPC 2.02 */
665#define OV1_PPC_2_03 0x10 /* set if we support PowerPC 2.03 */
666#define OV1_PPC_2_04 0x08 /* set if we support PowerPC 2.04 */
667#define OV1_PPC_2_05 0x04 /* set if we support PowerPC 2.05 */
668
669/* Option vector 2: Open Firmware options supported */
670#define OV2_REAL_MODE 0x20 /* set if we want OF in real mode */
671
672/* Option vector 3: processor options supported */
673#define OV3_FP 0x80 /* floating point */
674#define OV3_VMX 0x40 /* VMX/Altivec */
675
676/* Option vector 5: PAPR/OF options supported */
677#define OV5_LPAR 0x80 /* logical partitioning supported */
678#define OV5_SPLPAR 0x40 /* shared-processor LPAR supported */
679/* ibm,dynamic-reconfiguration-memory property supported */
680#define OV5_DRCONF_MEMORY 0x20
681#define OV5_LARGE_PAGES 0x10 /* large pages supported */
682
683/*
684 * The architecture vector has an array of PVR mask/value pairs,
685 * followed by # option vectors - 1, followed by the option vectors.
686 */
687static unsigned char ibm_architecture_vec[] = {
688 W(0xfffe0000), W(0x003a0000), /* POWER5/POWER5+ */
689 W(0xffff0000), W(0x003e0000), /* POWER6 */
690 W(0xfffffffe), W(0x0f000001), /* all 2.04-compliant and earlier */
691 5 - 1, /* 5 option vectors */
692
693 /* option vector 1: processor architectures supported */
694 3 - 1, /* length */
695 0, /* don't ignore, don't halt */
696 OV1_PPC_2_00 | OV1_PPC_2_01 | OV1_PPC_2_02 | OV1_PPC_2_03 |
697 OV1_PPC_2_04 | OV1_PPC_2_05,
698
699 /* option vector 2: Open Firmware options supported */
700 34 - 1, /* length */
701 OV2_REAL_MODE,
702 0, 0,
703 W(0xffffffff), /* real_base */
704 W(0xffffffff), /* real_size */
705 W(0xffffffff), /* virt_base */
706 W(0xffffffff), /* virt_size */
707 W(0xffffffff), /* load_base */
708 W(64), /* 128MB min RMA */
709 W(0xffffffff), /* full client load */
710 0, /* min RMA percentage of total RAM */
711 48, /* max log_2(hash table size) */
712
713 /* option vector 3: processor options supported */
714 3 - 1, /* length */
715 0, /* don't ignore, don't halt */
716 OV3_FP | OV3_VMX,
717
718 /* option vector 4: IBM PAPR implementation */
719 2 - 1, /* length */
720 0, /* don't halt */
721
722 /* option vector 5: PAPR/OF options */
723 3 - 1, /* length */
724 0, /* don't ignore, don't halt */
725 OV5_LPAR | OV5_SPLPAR | OV5_LARGE_PAGES,
726};
727
728/* Old method - ELF header with PT_NOTE sections */
643static struct fake_elf { 729static struct fake_elf {
644 Elf32_Ehdr elfhdr; 730 Elf32_Ehdr elfhdr;
645 Elf32_Phdr phdr[2]; 731 Elf32_Phdr phdr[2];
@@ -728,8 +814,26 @@ static struct fake_elf {
728 814
729static void __init prom_send_capabilities(void) 815static void __init prom_send_capabilities(void)
730{ 816{
731 ihandle elfloader; 817 ihandle elfloader, root;
818 prom_arg_t ret;
819
820 root = call_prom("open", 1, 1, ADDR("/"));
821 if (root != 0) {
822 /* try calling the ibm,client-architecture-support method */
823 if (call_prom_ret("call-method", 3, 2, &ret,
824 ADDR("ibm,client-architecture-support"),
825 ADDR(ibm_architecture_vec)) == 0) {
826 /* the call exists... */
827 if (ret)
828 prom_printf("WARNING: ibm,client-architecture"
829 "-support call FAILED!\n");
830 call_prom("close", 1, 0, root);
831 return;
832 }
833 call_prom("close", 1, 0, root);
834 }
732 835
836 /* no ibm,client-architecture-support call, try the old way */
733 elfloader = call_prom("open", 1, 1, ADDR("/packages/elf-loader")); 837 elfloader = call_prom("open", 1, 1, ADDR("/packages/elf-loader"));
734 if (elfloader == 0) { 838 if (elfloader == 0) {
735 prom_printf("couldn't open /packages/elf-loader\n"); 839 prom_printf("couldn't open /packages/elf-loader\n");
diff --git a/arch/powerpc/kernel/setup-common.c b/arch/powerpc/kernel/setup-common.c
index 1d93e73a7003..684ab1d49c65 100644
--- a/arch/powerpc/kernel/setup-common.c
+++ b/arch/powerpc/kernel/setup-common.c
@@ -516,3 +516,11 @@ void probe_machine(void)
516 516
517 printk(KERN_INFO "Using %s machine description\n", ppc_md.name); 517 printk(KERN_INFO "Using %s machine description\n", ppc_md.name);
518} 518}
519
520int check_legacy_ioport(unsigned long base_port)
521{
522 if (ppc_md.check_legacy_ioport == NULL)
523 return 0;
524 return ppc_md.check_legacy_ioport(base_port);
525}
526EXPORT_SYMBOL(check_legacy_ioport);
diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c
index 13e91c4d70a8..4467c49903b6 100644
--- a/arch/powerpc/kernel/setup_64.c
+++ b/arch/powerpc/kernel/setup_64.c
@@ -594,14 +594,6 @@ void ppc64_terminate_msg(unsigned int src, const char *msg)
594 printk("[terminate]%04x %s\n", src, msg); 594 printk("[terminate]%04x %s\n", src, msg);
595} 595}
596 596
597int check_legacy_ioport(unsigned long base_port)
598{
599 if (ppc_md.check_legacy_ioport == NULL)
600 return 0;
601 return ppc_md.check_legacy_ioport(base_port);
602}
603EXPORT_SYMBOL(check_legacy_ioport);
604
605void cpu_die(void) 597void cpu_die(void)
606{ 598{
607 if (ppc_md.cpu_die) 599 if (ppc_md.cpu_die)
diff --git a/arch/powerpc/kernel/systbl.S b/arch/powerpc/kernel/systbl.S
index 0b98eea73c5e..cf56a1d499ff 100644
--- a/arch/powerpc/kernel/systbl.S
+++ b/arch/powerpc/kernel/systbl.S
@@ -325,6 +325,19 @@ SYSCALL(unshare)
325SYSCALL(splice) 325SYSCALL(splice)
326SYSCALL(tee) 326SYSCALL(tee)
327SYSCALL(vmsplice) 327SYSCALL(vmsplice)
328COMPAT_SYS(openat)
329SYSCALL(mkdirat)
330SYSCALL(mknodat)
331SYSCALL(fchownat)
332COMPAT_SYS(futimesat)
333SYSX(sys_newfstatat, sys_fstatat64, sys_fstatat64)
334SYSCALL(unlinkat)
335SYSCALL(renameat)
336SYSCALL(linkat)
337SYSCALL(symlinkat)
338SYSCALL(readlinkat)
339SYSCALL(fchmodat)
340SYSCALL(faccessat)
328 341
329/* 342/*
330 * please add new calls to arch/powerpc/platforms/cell/spu_callbacks.c 343 * please add new calls to arch/powerpc/platforms/cell/spu_callbacks.c
diff --git a/arch/powerpc/mm/hugetlbpage.c b/arch/powerpc/mm/hugetlbpage.c
index 7370f9f33e29..266b8b2ceac9 100644
--- a/arch/powerpc/mm/hugetlbpage.c
+++ b/arch/powerpc/mm/hugetlbpage.c
@@ -30,13 +30,66 @@
30#define NUM_LOW_AREAS (0x100000000UL >> SID_SHIFT) 30#define NUM_LOW_AREAS (0x100000000UL >> SID_SHIFT)
31#define NUM_HIGH_AREAS (PGTABLE_RANGE >> HTLB_AREA_SHIFT) 31#define NUM_HIGH_AREAS (PGTABLE_RANGE >> HTLB_AREA_SHIFT)
32 32
33#ifdef CONFIG_PPC_64K_PAGES
34#define HUGEPTE_INDEX_SIZE (PMD_SHIFT-HPAGE_SHIFT)
35#else
36#define HUGEPTE_INDEX_SIZE (PUD_SHIFT-HPAGE_SHIFT)
37#endif
38#define PTRS_PER_HUGEPTE (1 << HUGEPTE_INDEX_SIZE)
39#define HUGEPTE_TABLE_SIZE (sizeof(pte_t) << HUGEPTE_INDEX_SIZE)
40
41#define HUGEPD_SHIFT (HPAGE_SHIFT + HUGEPTE_INDEX_SIZE)
42#define HUGEPD_SIZE (1UL << HUGEPD_SHIFT)
43#define HUGEPD_MASK (~(HUGEPD_SIZE-1))
44
45#define huge_pgtable_cache (pgtable_cache[HUGEPTE_CACHE_NUM])
46
47/* Flag to mark huge PD pointers. This means pmd_bad() and pud_bad()
48 * will choke on pointers to hugepte tables, which is handy for
49 * catching screwups early. */
50#define HUGEPD_OK 0x1
51
52typedef struct { unsigned long pd; } hugepd_t;
53
54#define hugepd_none(hpd) ((hpd).pd == 0)
55
56static inline pte_t *hugepd_page(hugepd_t hpd)
57{
58 BUG_ON(!(hpd.pd & HUGEPD_OK));
59 return (pte_t *)(hpd.pd & ~HUGEPD_OK);
60}
61
62static inline pte_t *hugepte_offset(hugepd_t *hpdp, unsigned long addr)
63{
64 unsigned long idx = ((addr >> HPAGE_SHIFT) & (PTRS_PER_HUGEPTE-1));
65 pte_t *dir = hugepd_page(*hpdp);
66
67 return dir + idx;
68}
69
70static int __hugepte_alloc(struct mm_struct *mm, hugepd_t *hpdp,
71 unsigned long address)
72{
73 pte_t *new = kmem_cache_alloc(huge_pgtable_cache,
74 GFP_KERNEL|__GFP_REPEAT);
75
76 if (! new)
77 return -ENOMEM;
78
79 spin_lock(&mm->page_table_lock);
80 if (!hugepd_none(*hpdp))
81 kmem_cache_free(huge_pgtable_cache, new);
82 else
83 hpdp->pd = (unsigned long)new | HUGEPD_OK;
84 spin_unlock(&mm->page_table_lock);
85 return 0;
86}
87
33/* Modelled after find_linux_pte() */ 88/* Modelled after find_linux_pte() */
34pte_t *huge_pte_offset(struct mm_struct *mm, unsigned long addr) 89pte_t *huge_pte_offset(struct mm_struct *mm, unsigned long addr)
35{ 90{
36 pgd_t *pg; 91 pgd_t *pg;
37 pud_t *pu; 92 pud_t *pu;
38 pmd_t *pm;
39 pte_t *pt;
40 93
41 BUG_ON(! in_hugepage_area(mm->context, addr)); 94 BUG_ON(! in_hugepage_area(mm->context, addr));
42 95
@@ -46,26 +99,14 @@ pte_t *huge_pte_offset(struct mm_struct *mm, unsigned long addr)
46 if (!pgd_none(*pg)) { 99 if (!pgd_none(*pg)) {
47 pu = pud_offset(pg, addr); 100 pu = pud_offset(pg, addr);
48 if (!pud_none(*pu)) { 101 if (!pud_none(*pu)) {
49 pm = pmd_offset(pu, addr);
50#ifdef CONFIG_PPC_64K_PAGES 102#ifdef CONFIG_PPC_64K_PAGES
51 /* Currently, we use the normal PTE offset within full 103 pmd_t *pm;
52 * size PTE pages, thus our huge PTEs are scattered in 104 pm = pmd_offset(pu, addr);
53 * the PTE page and we do waste some. We may change 105 if (!pmd_none(*pm))
54 * that in the future, but the current mecanism keeps 106 return hugepte_offset((hugepd_t *)pm, addr);
55 * things much simpler 107#else
56 */ 108 return hugepte_offset((hugepd_t *)pu, addr);
57 if (!pmd_none(*pm)) { 109#endif
58 /* Note: pte_offset_* are all equivalent on
59 * ppc64 as we don't have HIGHMEM
60 */
61 pt = pte_offset_kernel(pm, addr);
62 return pt;
63 }
64#else /* CONFIG_PPC_64K_PAGES */
65 /* On 4k pages, we put huge PTEs in the PMD page */
66 pt = (pte_t *)pm;
67 return pt;
68#endif /* CONFIG_PPC_64K_PAGES */
69 } 110 }
70 } 111 }
71 112
@@ -76,8 +117,7 @@ pte_t *huge_pte_alloc(struct mm_struct *mm, unsigned long addr)
76{ 117{
77 pgd_t *pg; 118 pgd_t *pg;
78 pud_t *pu; 119 pud_t *pu;
79 pmd_t *pm; 120 hugepd_t *hpdp = NULL;
80 pte_t *pt;
81 121
82 BUG_ON(! in_hugepage_area(mm->context, addr)); 122 BUG_ON(! in_hugepage_area(mm->context, addr));
83 123
@@ -87,23 +127,182 @@ pte_t *huge_pte_alloc(struct mm_struct *mm, unsigned long addr)
87 pu = pud_alloc(mm, pg, addr); 127 pu = pud_alloc(mm, pg, addr);
88 128
89 if (pu) { 129 if (pu) {
130#ifdef CONFIG_PPC_64K_PAGES
131 pmd_t *pm;
90 pm = pmd_alloc(mm, pu, addr); 132 pm = pmd_alloc(mm, pu, addr);
91 if (pm) { 133 if (pm)
134 hpdp = (hugepd_t *)pm;
135#else
136 hpdp = (hugepd_t *)pu;
137#endif
138 }
139
140 if (! hpdp)
141 return NULL;
142
143 if (hugepd_none(*hpdp) && __hugepte_alloc(mm, hpdp, addr))
144 return NULL;
145
146 return hugepte_offset(hpdp, addr);
147}
148
149static void free_hugepte_range(struct mmu_gather *tlb, hugepd_t *hpdp)
150{
151 pte_t *hugepte = hugepd_page(*hpdp);
152
153 hpdp->pd = 0;
154 tlb->need_flush = 1;
155 pgtable_free_tlb(tlb, pgtable_free_cache(hugepte, HUGEPTE_CACHE_NUM,
156 HUGEPTE_TABLE_SIZE-1));
157}
158
92#ifdef CONFIG_PPC_64K_PAGES 159#ifdef CONFIG_PPC_64K_PAGES
93 /* See comment in huge_pte_offset. Note that if we ever 160static void hugetlb_free_pmd_range(struct mmu_gather *tlb, pud_t *pud,
94 * want to put the page size in the PMD, we would have 161 unsigned long addr, unsigned long end,
95 * to open code our own pte_alloc* function in order 162 unsigned long floor, unsigned long ceiling)
96 * to populate and set the size atomically 163{
97 */ 164 pmd_t *pmd;
98 pt = pte_alloc_map(mm, pm, addr); 165 unsigned long next;
99#else /* CONFIG_PPC_64K_PAGES */ 166 unsigned long start;
100 pt = (pte_t *)pm; 167
101#endif /* CONFIG_PPC_64K_PAGES */ 168 start = addr;
102 return pt; 169 pmd = pmd_offset(pud, addr);
103 } 170 do {
171 next = pmd_addr_end(addr, end);
172 if (pmd_none(*pmd))
173 continue;
174 free_hugepte_range(tlb, (hugepd_t *)pmd);
175 } while (pmd++, addr = next, addr != end);
176
177 start &= PUD_MASK;
178 if (start < floor)
179 return;
180 if (ceiling) {
181 ceiling &= PUD_MASK;
182 if (!ceiling)
183 return;
104 } 184 }
185 if (end - 1 > ceiling - 1)
186 return;
105 187
106 return NULL; 188 pmd = pmd_offset(pud, start);
189 pud_clear(pud);
190 pmd_free_tlb(tlb, pmd);
191}
192#endif
193
194static void hugetlb_free_pud_range(struct mmu_gather *tlb, pgd_t *pgd,
195 unsigned long addr, unsigned long end,
196 unsigned long floor, unsigned long ceiling)
197{
198 pud_t *pud;
199 unsigned long next;
200 unsigned long start;
201
202 start = addr;
203 pud = pud_offset(pgd, addr);
204 do {
205 next = pud_addr_end(addr, end);
206#ifdef CONFIG_PPC_64K_PAGES
207 if (pud_none_or_clear_bad(pud))
208 continue;
209 hugetlb_free_pmd_range(tlb, pud, addr, next, floor, ceiling);
210#else
211 if (pud_none(*pud))
212 continue;
213 free_hugepte_range(tlb, (hugepd_t *)pud);
214#endif
215 } while (pud++, addr = next, addr != end);
216
217 start &= PGDIR_MASK;
218 if (start < floor)
219 return;
220 if (ceiling) {
221 ceiling &= PGDIR_MASK;
222 if (!ceiling)
223 return;
224 }
225 if (end - 1 > ceiling - 1)
226 return;
227
228 pud = pud_offset(pgd, start);
229 pgd_clear(pgd);
230 pud_free_tlb(tlb, pud);
231}
232
233/*
234 * This function frees user-level page tables of a process.
235 *
236 * Must be called with pagetable lock held.
237 */
238void hugetlb_free_pgd_range(struct mmu_gather **tlb,
239 unsigned long addr, unsigned long end,
240 unsigned long floor, unsigned long ceiling)
241{
242 pgd_t *pgd;
243 unsigned long next;
244 unsigned long start;
245
246 /*
247 * Comments below take from the normal free_pgd_range(). They
248 * apply here too. The tests against HUGEPD_MASK below are
249 * essential, because we *don't* test for this at the bottom
250 * level. Without them we'll attempt to free a hugepte table
251 * when we unmap just part of it, even if there are other
252 * active mappings using it.
253 *
254 * The next few lines have given us lots of grief...
255 *
256 * Why are we testing HUGEPD* at this top level? Because
257 * often there will be no work to do at all, and we'd prefer
258 * not to go all the way down to the bottom just to discover
259 * that.
260 *
261 * Why all these "- 1"s? Because 0 represents both the bottom
262 * of the address space and the top of it (using -1 for the
263 * top wouldn't help much: the masks would do the wrong thing).
264 * The rule is that addr 0 and floor 0 refer to the bottom of
265 * the address space, but end 0 and ceiling 0 refer to the top
266 * Comparisons need to use "end - 1" and "ceiling - 1" (though
267 * that end 0 case should be mythical).
268 *
269 * Wherever addr is brought up or ceiling brought down, we
270 * must be careful to reject "the opposite 0" before it
271 * confuses the subsequent tests. But what about where end is
272 * brought down by HUGEPD_SIZE below? no, end can't go down to
273 * 0 there.
274 *
275 * Whereas we round start (addr) and ceiling down, by different
276 * masks at different levels, in order to test whether a table
277 * now has no other vmas using it, so can be freed, we don't
278 * bother to round floor or end up - the tests don't need that.
279 */
280
281 addr &= HUGEPD_MASK;
282 if (addr < floor) {
283 addr += HUGEPD_SIZE;
284 if (!addr)
285 return;
286 }
287 if (ceiling) {
288 ceiling &= HUGEPD_MASK;
289 if (!ceiling)
290 return;
291 }
292 if (end - 1 > ceiling - 1)
293 end -= HUGEPD_SIZE;
294 if (addr > end - 1)
295 return;
296
297 start = addr;
298 pgd = pgd_offset((*tlb)->mm, addr);
299 do {
300 BUG_ON(! in_hugepage_area((*tlb)->mm->context, addr));
301 next = pgd_addr_end(addr, end);
302 if (pgd_none_or_clear_bad(pgd))
303 continue;
304 hugetlb_free_pud_range(*tlb, pgd, addr, next, floor, ceiling);
305 } while (pgd++, addr = next, addr != end);
107} 306}
108 307
109void set_huge_pte_at(struct mm_struct *mm, unsigned long addr, 308void set_huge_pte_at(struct mm_struct *mm, unsigned long addr,
@@ -841,3 +1040,27 @@ repeat:
841 out: 1040 out:
842 return err; 1041 return err;
843} 1042}
1043
1044static void zero_ctor(void *addr, kmem_cache_t *cache, unsigned long flags)
1045{
1046 memset(addr, 0, kmem_cache_size(cache));
1047}
1048
1049static int __init hugetlbpage_init(void)
1050{
1051 if (!cpu_has_feature(CPU_FTR_16M_PAGE))
1052 return -ENODEV;
1053
1054 huge_pgtable_cache = kmem_cache_create("hugepte_cache",
1055 HUGEPTE_TABLE_SIZE,
1056 HUGEPTE_TABLE_SIZE,
1057 SLAB_HWCACHE_ALIGN |
1058 SLAB_MUST_HWCACHE_ALIGN,
1059 zero_ctor, NULL);
1060 if (! huge_pgtable_cache)
1061 panic("hugetlbpage_init(): could not create hugepte cache\n");
1062
1063 return 0;
1064}
1065
1066module_init(hugetlbpage_init);
diff --git a/arch/powerpc/mm/init_64.c b/arch/powerpc/mm/init_64.c
index babebd15bdc4..9e30f968c184 100644
--- a/arch/powerpc/mm/init_64.c
+++ b/arch/powerpc/mm/init_64.c
@@ -162,7 +162,14 @@ static const char *pgtable_cache_name[ARRAY_SIZE(pgtable_cache_size)] = {
162}; 162};
163#endif /* CONFIG_PPC_64K_PAGES */ 163#endif /* CONFIG_PPC_64K_PAGES */
164 164
165#ifdef CONFIG_HUGETLB_PAGE
166/* Hugepages need one extra cache, initialized in hugetlbpage.c. We
167 * can't put into the tables above, because HPAGE_SHIFT is not compile
168 * time constant. */
169kmem_cache_t *pgtable_cache[ARRAY_SIZE(pgtable_cache_size)+1];
170#else
165kmem_cache_t *pgtable_cache[ARRAY_SIZE(pgtable_cache_size)]; 171kmem_cache_t *pgtable_cache[ARRAY_SIZE(pgtable_cache_size)];
172#endif
166 173
167void pgtable_cache_init(void) 174void pgtable_cache_init(void)
168{ 175{
diff --git a/arch/powerpc/platforms/cell/spu_base.c b/arch/powerpc/platforms/cell/spu_base.c
index 269dda4fd0b4..ef47a6239d48 100644
--- a/arch/powerpc/platforms/cell/spu_base.c
+++ b/arch/powerpc/platforms/cell/spu_base.c
@@ -306,19 +306,19 @@ spu_request_irqs(struct spu *spu)
306 306
307 snprintf(spu->irq_c0, sizeof (spu->irq_c0), "spe%02d.0", spu->number); 307 snprintf(spu->irq_c0, sizeof (spu->irq_c0), "spe%02d.0", spu->number);
308 ret = request_irq(irq_base + spu->isrc, 308 ret = request_irq(irq_base + spu->isrc,
309 spu_irq_class_0, 0, spu->irq_c0, spu); 309 spu_irq_class_0, SA_INTERRUPT, spu->irq_c0, spu);
310 if (ret) 310 if (ret)
311 goto out; 311 goto out;
312 312
313 snprintf(spu->irq_c1, sizeof (spu->irq_c1), "spe%02d.1", spu->number); 313 snprintf(spu->irq_c1, sizeof (spu->irq_c1), "spe%02d.1", spu->number);
314 ret = request_irq(irq_base + IIC_CLASS_STRIDE + spu->isrc, 314 ret = request_irq(irq_base + IIC_CLASS_STRIDE + spu->isrc,
315 spu_irq_class_1, 0, spu->irq_c1, spu); 315 spu_irq_class_1, SA_INTERRUPT, spu->irq_c1, spu);
316 if (ret) 316 if (ret)
317 goto out1; 317 goto out1;
318 318
319 snprintf(spu->irq_c2, sizeof (spu->irq_c2), "spe%02d.2", spu->number); 319 snprintf(spu->irq_c2, sizeof (spu->irq_c2), "spe%02d.2", spu->number);
320 ret = request_irq(irq_base + 2*IIC_CLASS_STRIDE + spu->isrc, 320 ret = request_irq(irq_base + 2*IIC_CLASS_STRIDE + spu->isrc,
321 spu_irq_class_2, 0, spu->irq_c2, spu); 321 spu_irq_class_2, SA_INTERRUPT, spu->irq_c2, spu);
322 if (ret) 322 if (ret)
323 goto out2; 323 goto out2;
324 goto out; 324 goto out;
@@ -487,10 +487,14 @@ int spu_irq_class_1_bottom(struct spu *spu)
487 ea = spu->dar; 487 ea = spu->dar;
488 dsisr = spu->dsisr; 488 dsisr = spu->dsisr;
489 if (dsisr & (MFC_DSISR_PTE_NOT_FOUND | MFC_DSISR_ACCESS_DENIED)) { 489 if (dsisr & (MFC_DSISR_PTE_NOT_FOUND | MFC_DSISR_ACCESS_DENIED)) {
490 u64 flags;
491
490 access = (_PAGE_PRESENT | _PAGE_USER); 492 access = (_PAGE_PRESENT | _PAGE_USER);
491 access |= (dsisr & MFC_DSISR_ACCESS_PUT) ? _PAGE_RW : 0UL; 493 access |= (dsisr & MFC_DSISR_ACCESS_PUT) ? _PAGE_RW : 0UL;
494 local_irq_save(flags);
492 if (hash_page(ea, access, 0x300) != 0) 495 if (hash_page(ea, access, 0x300) != 0)
493 error |= CLASS1_ENABLE_STORAGE_FAULT_INTR; 496 error |= CLASS1_ENABLE_STORAGE_FAULT_INTR;
497 local_irq_restore(flags);
494 } 498 }
495 if (error & CLASS1_ENABLE_STORAGE_FAULT_INTR) { 499 if (error & CLASS1_ENABLE_STORAGE_FAULT_INTR) {
496 if ((ret = spu_handle_mm_fault(spu)) != 0) 500 if ((ret = spu_handle_mm_fault(spu)) != 0)
diff --git a/arch/powerpc/platforms/cell/spu_callbacks.c b/arch/powerpc/platforms/cell/spu_callbacks.c
index b283380a2a18..95b36430aa0f 100644
--- a/arch/powerpc/platforms/cell/spu_callbacks.c
+++ b/arch/powerpc/platforms/cell/spu_callbacks.c
@@ -319,6 +319,19 @@ void *spu_syscall_table[] = {
319 [__NR_splice] sys_splice, 319 [__NR_splice] sys_splice,
320 [__NR_tee] sys_tee, 320 [__NR_tee] sys_tee,
321 [__NR_vmsplice] sys_vmsplice, 321 [__NR_vmsplice] sys_vmsplice,
322 [__NR_openat] sys_openat,
323 [__NR_mkdirat] sys_mkdirat,
324 [__NR_mknodat] sys_mknodat,
325 [__NR_fchownat] sys_fchownat,
326 [__NR_futimesat] sys_futimesat,
327 [__NR_newfstatat] sys_newfstatat,
328 [__NR_unlinkat] sys_unlinkat,
329 [__NR_renameat] sys_renameat,
330 [__NR_linkat] sys_linkat,
331 [__NR_symlinkat] sys_symlinkat,
332 [__NR_readlinkat] sys_readlinkat,
333 [__NR_fchmodat] sys_fchmodat,
334 [__NR_faccessat] sys_faccessat,
322}; 335};
323 336
324long spu_sys_callback(struct spu_syscall_block *s) 337long spu_sys_callback(struct spu_syscall_block *s)
diff --git a/arch/ppc/platforms/4xx/ocotea.c b/arch/ppc/platforms/4xx/ocotea.c
index f841972f1fa9..554776d4b8ac 100644
--- a/arch/ppc/platforms/4xx/ocotea.c
+++ b/arch/ppc/platforms/4xx/ocotea.c
@@ -331,7 +331,7 @@ static void __init ocotea_init(void)
331void __init platform_init(unsigned long r3, unsigned long r4, 331void __init platform_init(unsigned long r3, unsigned long r4,
332 unsigned long r5, unsigned long r6, unsigned long r7) 332 unsigned long r5, unsigned long r6, unsigned long r7)
333{ 333{
334 ibm44x_platform_init(r3, r4, r5, r6, r7); 334 ibm440gx_platform_init(r3, r4, r5, r6, r7);
335 335
336 ppc_md.setup_arch = ocotea_setup_arch; 336 ppc_md.setup_arch = ocotea_setup_arch;
337 ppc_md.show_cpuinfo = ocotea_show_cpuinfo; 337 ppc_md.show_cpuinfo = ocotea_show_cpuinfo;
diff --git a/arch/ppc/platforms/mpc8272ads_setup.c b/arch/ppc/platforms/mpc8272ads_setup.c
index bc9b94f77e39..e62b75707f7a 100644
--- a/arch/ppc/platforms/mpc8272ads_setup.c
+++ b/arch/ppc/platforms/mpc8272ads_setup.c
@@ -26,11 +26,35 @@
26#include <asm/irq.h> 26#include <asm/irq.h>
27#include <asm/ppc_sys.h> 27#include <asm/ppc_sys.h>
28#include <asm/ppcboot.h> 28#include <asm/ppcboot.h>
29#include <linux/fs_uart_pd.h>
29 30
30#include "pq2ads_pd.h" 31#include "pq2ads_pd.h"
31 32
32static void init_fcc1_ioports(void); 33static void init_fcc1_ioports(void);
33static void init_fcc2_ioports(void); 34static void init_fcc2_ioports(void);
35static void init_scc1_uart_ioports(void);
36static void init_scc4_uart_ioports(void);
37
38static struct fs_uart_platform_info mpc8272_uart_pdata[] = {
39 [fsid_scc1_uart] = {
40 .init_ioports = init_scc1_uart_ioports,
41 .fs_no = fsid_scc1_uart,
42 .brg = 1,
43 .tx_num_fifo = 4,
44 .tx_buf_size = 32,
45 .rx_num_fifo = 4,
46 .rx_buf_size = 32,
47 },
48 [fsid_scc4_uart] = {
49 .init_ioports = init_scc4_uart_ioports,
50 .fs_no = fsid_scc4_uart,
51 .brg = 4,
52 .tx_num_fifo = 4,
53 .tx_buf_size = 32,
54 .rx_num_fifo = 4,
55 .rx_buf_size = 32,
56 },
57};
34 58
35static struct fs_mii_bus_info mii_bus_info = { 59static struct fs_mii_bus_info mii_bus_info = {
36 .method = fsmii_bitbang, 60 .method = fsmii_bitbang,
@@ -201,6 +225,55 @@ static void __init mpc8272ads_fixup_enet_pdata(struct platform_device *pdev,
201 } 225 }
202} 226}
203 227
228static void mpc8272ads_fixup_uart_pdata(struct platform_device *pdev,
229 int idx)
230{
231 bd_t *bd = (bd_t *) __res;
232 struct fs_uart_platform_info *pinfo;
233 int num = ARRAY_SIZE(mpc8272_uart_pdata);
234 int id = fs_uart_id_scc2fsid(idx);
235
236 /* no need to alter anything if console */
237 if ((id <= num) && (!pdev->dev.platform_data)) {
238 pinfo = &mpc8272_uart_pdata[id];
239 pinfo->uart_clk = bd->bi_intfreq;
240 pdev->dev.platform_data = pinfo;
241 }
242}
243
244static void init_scc1_uart_ioports(void)
245{
246 cpm2_map_t* immap = ioremap(CPM_MAP_ADDR, sizeof(cpm2_map_t));
247
248 /* SCC1 is only on port D */
249 setbits32(&immap->im_ioport.iop_ppard,0x00000003);
250 clrbits32(&immap->im_ioport.iop_psord,0x00000001);
251 setbits32(&immap->im_ioport.iop_psord,0x00000002);
252 clrbits32(&immap->im_ioport.iop_pdird,0x00000001);
253 setbits32(&immap->im_ioport.iop_pdird,0x00000002);
254
255 /* Wire BRG1 to SCC1 */
256 clrbits32(&immap->im_cpmux.cmx_scr,0x00ffffff);
257
258 iounmap(immap);
259}
260
261static void init_scc4_uart_ioports(void)
262{
263 cpm2_map_t* immap = ioremap(CPM_MAP_ADDR, sizeof(cpm2_map_t));
264
265 setbits32(&immap->im_ioport.iop_ppard,0x00000600);
266 clrbits32(&immap->im_ioport.iop_psord,0x00000600);
267 clrbits32(&immap->im_ioport.iop_pdird,0x00000200);
268 setbits32(&immap->im_ioport.iop_pdird,0x00000400);
269
270 /* Wire BRG4 to SCC4 */
271 clrbits32(&immap->im_cpmux.cmx_scr,0x000000ff);
272 setbits32(&immap->im_cpmux.cmx_scr,0x0000001b);
273
274 iounmap(immap);
275}
276
204static int mpc8272ads_platform_notify(struct device *dev) 277static int mpc8272ads_platform_notify(struct device *dev)
205{ 278{
206 static const struct platform_notify_dev_map dev_map[] = { 279 static const struct platform_notify_dev_map dev_map[] = {
@@ -209,6 +282,10 @@ static int mpc8272ads_platform_notify(struct device *dev)
209 .rtn = mpc8272ads_fixup_enet_pdata 282 .rtn = mpc8272ads_fixup_enet_pdata
210 }, 283 },
211 { 284 {
285 .bus_id = "fsl-cpm-scc:uart",
286 .rtn = mpc
287 },
288 {
212 .bus_id = NULL 289 .bus_id = NULL
213 } 290 }
214 }; 291 };
@@ -230,7 +307,44 @@ int __init mpc8272ads_init(void)
230 ppc_sys_device_enable(MPC82xx_CPM_FCC1); 307 ppc_sys_device_enable(MPC82xx_CPM_FCC1);
231 ppc_sys_device_enable(MPC82xx_CPM_FCC2); 308 ppc_sys_device_enable(MPC82xx_CPM_FCC2);
232 309
310 /* to be ready for console, let's attach pdata here */
311#ifdef CONFIG_SERIAL_CPM_SCC1
312 ppc_sys_device_setfunc(MPC82xx_CPM_SCC1, PPC_SYS_FUNC_UART);
313 ppc_sys_device_enable(MPC82xx_CPM_SCC1);
314
315#endif
316
317#ifdef CONFIG_SERIAL_CPM_SCC4
318 ppc_sys_device_setfunc(MPC82xx_CPM_SCC4, PPC_SYS_FUNC_UART);
319 ppc_sys_device_enable(MPC82xx_CPM_SCC4);
320#endif
321
322
233 return 0; 323 return 0;
234} 324}
235 325
326/*
327 To prevent confusion, console selection is gross:
328 by 0 assumed SCC1 and by 1 assumed SCC4
329 */
330struct platform_device* early_uart_get_pdev(int index)
331{
332 bd_t *bd = (bd_t *) __res;
333 struct fs_uart_platform_info *pinfo;
334
335 struct platform_device* pdev = NULL;
336 if(index) { /*assume SCC4 here*/
337 pdev = &ppc_sys_platform_devices[MPC82xx_CPM_SCC4];
338 pinfo = &mpc8272<F12>_uart_pdata[1];
339 } else { /*over SCC1*/
340 pdev = &ppc_sys_platform_devices[MPC82xx_CPM_SCC1];
341 pinfo = &mpc8272_uart_pdata[0];
342 }
343
344 pinfo->uart_clk = bd->bi_intfreq;
345 pdev->dev.platform_data = pinfo;
346 ppc_sys_fixup_mem_resource(pdev, IMAP_ADDR);
347 return NULL;
348}
349
236arch_initcall(mpc8272ads_init); 350arch_initcall(mpc8272ads_init);
diff --git a/arch/ppc/platforms/mpc866ads_setup.c b/arch/ppc/platforms/mpc866ads_setup.c
index ac8fcc68afeb..6ce3b842defe 100644
--- a/arch/ppc/platforms/mpc866ads_setup.c
+++ b/arch/ppc/platforms/mpc866ads_setup.c
@@ -20,6 +20,7 @@
20#include <linux/device.h> 20#include <linux/device.h>
21 21
22#include <linux/fs_enet_pd.h> 22#include <linux/fs_enet_pd.h>
23#include <linux/fs_uart_pd.h>
23#include <linux/mii.h> 24#include <linux/mii.h>
24 25
25#include <asm/delay.h> 26#include <asm/delay.h>
@@ -37,6 +38,11 @@
37 38
38extern unsigned char __res[]; 39extern unsigned char __res[];
39 40
41static void setup_fec1_ioports(void);
42static void setup_scc1_ioports(void);
43static void setup_smc1_ioports(void);
44static void setup_smc2_ioports(void);
45
40static struct fs_mii_bus_info fec_mii_bus_info = { 46static struct fs_mii_bus_info fec_mii_bus_info = {
41 .method = fsmii_fec, 47 .method = fsmii_fec,
42 .id = 0, 48 .id = 0,
@@ -79,6 +85,28 @@ static struct fs_platform_info mpc8xx_scc_pdata = {
79 .phy_irq = -1, 85 .phy_irq = -1,
80 86
81 .bus_info = &scc_mii_bus_info, 87 .bus_info = &scc_mii_bus_info,
88
89};
90
91static struct fs_uart_platform_info mpc866_uart_pdata[] = {
92 [fsid_smc1_uart] = {
93 .brg = 1,
94 .fs_no = fsid_smc1_uart,
95 .init_ioports = setup_smc1_ioports,
96 .tx_num_fifo = 4,
97 .tx_buf_size = 32,
98 .rx_num_fifo = 4,
99 .rx_buf_size = 32,
100 },
101 [fsid_smc2_uart] = {
102 .brg = 2,
103 .fs_no = fsid_smc2_uart,
104 .init_ioports = setup_smc2_ioports,
105 .tx_num_fifo = 4,
106 .tx_buf_size = 32,
107 .rx_num_fifo = 4,
108 .rx_buf_size = 32,
109 },
82}; 110};
83 111
84void __init board_init(void) 112void __init board_init(void)
@@ -92,9 +120,12 @@ void __init board_init(void)
92 printk(KERN_CRIT "Could not remap BCSR1\n"); 120 printk(KERN_CRIT "Could not remap BCSR1\n");
93 return; 121 return;
94 } 122 }
123
95#ifdef CONFIG_SERIAL_CPM_SMC1 124#ifdef CONFIG_SERIAL_CPM_SMC1
96 cp->cp_simode &= ~(0xe0000000 >> 17); /* brg1 */ 125 cp->cp_simode &= ~(0xe0000000 >> 17); /* brg1 */
97 clrbits32(bcsr_io,(0x80000000 >> 7)); 126 clrbits32(bcsr_io,(0x80000000 >> 7));
127 cp->cp_smc[0].smc_smcm |= (SMCM_RX | SMCM_TX);
128 cp->cp_smc[0].smc_smcmr &= ~(SMCMR_REN | SMCMR_TEN);
98#else 129#else
99 setbits32(bcsr_io,(0x80000000 >> 7)); 130 setbits32(bcsr_io,(0x80000000 >> 7));
100 131
@@ -108,6 +139,8 @@ void __init board_init(void)
108 cp->cp_simode &= ~(0xe0000000 >> 1); 139 cp->cp_simode &= ~(0xe0000000 >> 1);
109 cp->cp_simode |= (0x20000000 >> 1); /* brg2 */ 140 cp->cp_simode |= (0x20000000 >> 1); /* brg2 */
110 clrbits32(bcsr_io,(0x80000000 >> 13)); 141 clrbits32(bcsr_io,(0x80000000 >> 13));
142 cp->cp_smc[1].smc_smcm |= (SMCM_RX | SMCM_TX);
143 cp->cp_smc[1].smc_smcmr &= ~(SMCMR_REN | SMCMR_TEN);
111#else 144#else
112 clrbits32(bcsr_io,(0x80000000 >> 13)); 145 clrbits32(bcsr_io,(0x80000000 >> 13));
113 cp->cp_pbpar &= ~(0x00000c00); 146 cp->cp_pbpar &= ~(0x00000c00);
@@ -232,6 +265,74 @@ static void mpc866ads_fixup_scc_enet_pdata(struct platform_device *pdev,
232 mpc866ads_fixup_enet_pdata(pdev, fsid_scc1 + pdev->id - 1); 265 mpc866ads_fixup_enet_pdata(pdev, fsid_scc1 + pdev->id - 1);
233} 266}
234 267
268static void setup_smc1_ioports(void)
269{
270 immap_t *immap = (immap_t *) IMAP_ADDR;
271 unsigned *bcsr_io;
272 unsigned int iobits = 0x000000c0;
273
274 bcsr_io = ioremap(BCSR1, sizeof(unsigned long));
275
276 if (bcsr_io == NULL) {
277 printk(KERN_CRIT "Could not remap BCSR1\n");
278 return;
279 }
280
281 clrbits32(bcsr_io,BCSR1_RS232EN_1);
282 iounmap(bcsr_io);
283
284 setbits32(&immap->im_cpm.cp_pbpar, iobits);
285 clrbits32(&immap->im_cpm.cp_pbdir, iobits);
286 clrbits16(&immap->im_cpm.cp_pbodr, iobits);
287
288}
289
290static void setup_smc2_ioports(void)
291{
292 immap_t *immap = (immap_t *) IMAP_ADDR;
293 unsigned *bcsr_io;
294 unsigned int iobits = 0x00000c00;
295
296 bcsr_io = ioremap(BCSR1, sizeof(unsigned long));
297
298 if (bcsr_io == NULL) {
299 printk(KERN_CRIT "Could not remap BCSR1\n");
300 return;
301 }
302
303 clrbits32(bcsr_io,BCSR1_RS232EN_2);
304
305 iounmap(bcsr_io);
306
307#ifndef CONFIG_SERIAL_CPM_ALT_SMC2
308 setbits32(&immap->im_cpm.cp_pbpar, iobits);
309 clrbits32(&immap->im_cpm.cp_pbdir, iobits);
310 clrbits16(&immap->im_cpm.cp_pbodr, iobits);
311#else
312 setbits16(&immap->im_ioport.iop_papar, iobits);
313 clrbits16(&immap->im_ioport.iop_padir, iobits);
314 clrbits16(&immap->im_ioport.iop_paodr, iobits);
315#endif
316
317}
318
319static void __init mpc866ads_fixup_uart_pdata(struct platform_device *pdev,
320 int idx)
321{
322 bd_t *bd = (bd_t *) __res;
323 struct fs_uart_platform_info *pinfo;
324 int num = ARRAY_SIZE(mpc866_uart_pdata);
325
326 int id = fs_uart_id_smc2fsid(idx);
327
328 /* no need to alter anything if console */
329 if ((id <= num) && (!pdev->dev.platform_data)) {
330 pinfo = &mpc866_uart_pdata[id];
331 pinfo->uart_clk = bd->bi_intfreq;
332 pdev->dev.platform_data = pinfo;
333 }
334}
335
235static int mpc866ads_platform_notify(struct device *dev) 336static int mpc866ads_platform_notify(struct device *dev)
236{ 337{
237 static const struct platform_notify_dev_map dev_map[] = { 338 static const struct platform_notify_dev_map dev_map[] = {
@@ -244,6 +345,10 @@ static int mpc866ads_platform_notify(struct device *dev)
244 .rtn = mpc866ads_fixup_scc_enet_pdata, 345 .rtn = mpc866ads_fixup_scc_enet_pdata,
245 }, 346 },
246 { 347 {
348 .bus_id = "fsl-cpm-smc:uart",
349 .rtn = mpc866ads_fixup_uart_pdata
350 },
351 {
247 .bus_id = NULL 352 .bus_id = NULL
248 } 353 }
249 }; 354 };
@@ -267,7 +372,42 @@ int __init mpc866ads_init(void)
267#endif 372#endif
268 ppc_sys_device_enable(MPC8xx_CPM_FEC1); 373 ppc_sys_device_enable(MPC8xx_CPM_FEC1);
269 374
375/* Since either of the uarts could be used as console, they need to ready */
376#ifdef CONFIG_SERIAL_CPM_SMC1
377 ppc_sys_device_enable(MPC8xx_CPM_SMC1);
378 ppc_sys_device_setfunc(MPC8xx_CPM_SMC1, PPC_SYS_FUNC_UART);
379#endif
380
381#ifdef CONFIG_SERIAL_CPM_SMCer
382 ppc_sys_device_enable(MPC8xx_CPM_SMC2);
383 ppc_sys_device_setfunc(MPC8xx_CPM_SMC2, PPC_SYS_FUNC_UART);
384#endif
385
270 return 0; 386 return 0;
271} 387}
272 388
389/*
390 To prevent confusion, console selection is gross:
391 by 0 assumed SMC1 and by 1 assumed SMC2
392 */
393struct platform_device* early_uart_get_pdev(int index)
394{
395 bd_t *bd = (bd_t *) __res;
396 struct fs_uart_platform_info *pinfo;
397
398 struct platform_device* pdev = NULL;
399 if(index) { /*assume SMC2 here*/
400 pdev = &ppc_sys_platform_devices[MPC8xx_CPM_SMC2];
401 pinfo = &mpc866_uart_pdata[1];
402 } else { /*over SMC1*/
403 pdev = &ppc_sys_platform_devices[MPC8xx_CPM_SMC1];
404 pinfo = &mpc866_uart_pdata[0];
405 }
406
407 pinfo->uart_clk = bd->bi_intfreq;
408 pdev->dev.platform_data = pinfo;
409 ppc_sys_fixup_mem_resource(pdev, IMAP_ADDR);
410 return NULL;
411}
412
273arch_initcall(mpc866ads_init); 413arch_initcall(mpc866ads_init);
diff --git a/arch/ppc/platforms/mpc885ads_setup.c b/arch/ppc/platforms/mpc885ads_setup.c
index 50a99e5f7c68..4b88679cd31c 100644
--- a/arch/ppc/platforms/mpc885ads_setup.c
+++ b/arch/ppc/platforms/mpc885ads_setup.c
@@ -20,6 +20,7 @@
20#include <linux/device.h> 20#include <linux/device.h>
21 21
22#include <linux/fs_enet_pd.h> 22#include <linux/fs_enet_pd.h>
23#include <linux/fs_uart_pd.h>
23#include <linux/mii.h> 24#include <linux/mii.h>
24 25
25#include <asm/delay.h> 26#include <asm/delay.h>
@@ -35,9 +36,32 @@
35#include <asm/ppc_sys.h> 36#include <asm/ppc_sys.h>
36 37
37extern unsigned char __res[]; 38extern unsigned char __res[];
39static void setup_smc1_ioports(void);
40static void setup_smc2_ioports(void);
38 41
39static void __init mpc885ads_scc_phy_init(char); 42static void __init mpc885ads_scc_phy_init(char);
40 43
44static struct fs_uart_platform_info mpc885_uart_pdata[] = {
45 [fsid_smc1_uart] = {
46 .brg = 1,
47 .fs_no = fsid_smc1_uart,
48 .init_ioports = setup_smc1_ioports,
49 .tx_num_fifo = 4,
50 .tx_buf_size = 32,
51 .rx_num_fifo = 4,
52 .rx_buf_size = 32,
53 },
54 [fsid_smc2_uart] = {
55 .brg = 2,
56 .fs_no = fsid_smc2_uart,
57 .init_ioports = setup_smc2_ioports,
58 .tx_num_fifo = 4,
59 .tx_buf_size = 32,
60 .rx_num_fifo = 4,
61 .rx_buf_size = 32,
62 },
63};
64
41static struct fs_mii_bus_info fec_mii_bus_info = { 65static struct fs_mii_bus_info fec_mii_bus_info = {
42 .method = fsmii_fec, 66 .method = fsmii_fec,
43 .id = 0, 67 .id = 0,
@@ -116,6 +140,8 @@ void __init board_init(void)
116#ifdef CONFIG_SERIAL_CPM_SMC1 140#ifdef CONFIG_SERIAL_CPM_SMC1
117 cp->cp_simode &= ~(0xe0000000 >> 17); /* brg1 */ 141 cp->cp_simode &= ~(0xe0000000 >> 17); /* brg1 */
118 clrbits32(bcsr_io, BCSR1_RS232EN_1); 142 clrbits32(bcsr_io, BCSR1_RS232EN_1);
143 cp->cp_smc[0].smc_smcm |= (SMCM_RX | SMCM_TX);
144 cp->cp_smc[0].smc_smcmr &= ~(SMCMR_REN | SMCMR_TEN);
119#else 145#else
120 setbits32(bcsr_io,BCSR1_RS232EN_1); 146 setbits32(bcsr_io,BCSR1_RS232EN_1);
121 cp->cp_smc[0].smc_smcmr = 0; 147 cp->cp_smc[0].smc_smcmr = 0;
@@ -126,6 +152,8 @@ void __init board_init(void)
126 cp->cp_simode &= ~(0xe0000000 >> 1); 152 cp->cp_simode &= ~(0xe0000000 >> 1);
127 cp->cp_simode |= (0x20000000 >> 1); /* brg2 */ 153 cp->cp_simode |= (0x20000000 >> 1); /* brg2 */
128 clrbits32(bcsr_io,BCSR1_RS232EN_2); 154 clrbits32(bcsr_io,BCSR1_RS232EN_2);
155 cp->cp_smc[1].smc_smcm |= (SMCM_RX | SMCM_TX);
156 cp->cp_smc[1].smc_smcmr &= ~(SMCMR_REN | SMCMR_TEN);
129#else 157#else
130 setbits32(bcsr_io,BCSR1_RS232EN_2); 158 setbits32(bcsr_io,BCSR1_RS232EN_2);
131 cp->cp_smc[1].smc_smcmr = 0; 159 cp->cp_smc[1].smc_smcmr = 0;
@@ -343,6 +371,70 @@ static void mpc885ads_scc_phy_init(char phy_addr)
343 out_be32(&fecp->fec_mii_speed, 0); 371 out_be32(&fecp->fec_mii_speed, 0);
344} 372}
345 373
374static void setup_smc1_ioports(void)
375{
376 immap_t *immap = (immap_t *) IMAP_ADDR;
377 unsigned *bcsr_io;
378 unsigned int iobits = 0x000000c0;
379
380 bcsr_io = ioremap(BCSR1, sizeof(unsigned long));
381
382 if (bcsr_io == NULL) {
383 printk(KERN_CRIT "Could not remap BCSR1\n");
384 return;
385 }
386 clrbits32(bcsr_io,BCSR1_RS232EN_1);
387 iounmap(bcsr_io);
388
389 setbits32(&immap->im_cpm.cp_pbpar, iobits);
390 clrbits32(&immap->im_cpm.cp_pbdir, iobits);
391 clrbits16(&immap->im_cpm.cp_pbodr, iobits);
392}
393
394static void setup_smc2_ioports(void)
395{
396 immap_t *immap = (immap_t *) IMAP_ADDR;
397 unsigned *bcsr_io;
398 unsigned int iobits = 0x00000c00;
399
400 bcsr_io = ioremap(BCSR1, sizeof(unsigned long));
401
402 if (bcsr_io == NULL) {
403 printk(KERN_CRIT "Could not remap BCSR1\n");
404 return;
405 }
406 clrbits32(bcsr_io,BCSR1_RS232EN_2);
407 iounmap(bcsr_io);
408
409#ifndef CONFIG_SERIAL_CPM_ALT_SMC2
410 setbits32(&immap->im_cpm.cp_pbpar, iobits);
411 clrbits32(&immap->im_cpm.cp_pbdir, iobits);
412 clrbits16(&immap->im_cpm.cp_pbodr, iobits);
413#else
414 setbits16(&immap->im_ioport.iop_papar, iobits);
415 clrbits16(&immap->im_ioport.iop_padir, iobits);
416 clrbits16(&immap->im_ioport.iop_paodr, iobits);
417#endif
418}
419
420static void __init mpc885ads_fixup_uart_pdata(struct platform_device *pdev,
421 int idx)
422{
423 bd_t *bd = (bd_t *) __res;
424 struct fs_uart_platform_info *pinfo;
425 int num = ARRAY_SIZE(mpc885_uart_pdata);
426
427 int id = fs_uart_id_smc2fsid(idx);
428
429 /* no need to alter anything if console */
430 if ((id <= num) && (!pdev->dev.platform_data)) {
431 pinfo = &mpc885_uart_pdata[id];
432 pinfo->uart_clk = bd->bi_intfreq;
433 pdev->dev.platform_data = pinfo;
434 }
435}
436
437
346static int mpc885ads_platform_notify(struct device *dev) 438static int mpc885ads_platform_notify(struct device *dev)
347{ 439{
348 440
@@ -356,12 +448,17 @@ static int mpc885ads_platform_notify(struct device *dev)
356 .rtn = mpc885ads_fixup_scc_enet_pdata, 448 .rtn = mpc885ads_fixup_scc_enet_pdata,
357 }, 449 },
358 { 450 {
451 .bus_id = "fsl-cpm-smc:uart",
452 .rtn = mpc885ads_fixup_uart_pdata
453 },
454 {
359 .bus_id = NULL 455 .bus_id = NULL
360 } 456 }
361 }; 457 };
362 458
363 platform_notify_map(dev_map,dev); 459 platform_notify_map(dev_map,dev);
364 460
461 return 0;
365} 462}
366 463
367int __init mpc885ads_init(void) 464int __init mpc885ads_init(void)
@@ -383,7 +480,41 @@ int __init mpc885ads_init(void)
383 ppc_sys_device_enable(MPC8xx_CPM_FEC2); 480 ppc_sys_device_enable(MPC8xx_CPM_FEC2);
384#endif 481#endif
385 482
483#ifdef CONFIG_SERIAL_CPM_SMC1
484 ppc_sys_device_enable(MPC8xx_CPM_SMC1);
485 ppc_sys_device_setfunc(MPC8xx_CPM_SMC1, PPC_SYS_FUNC_UART);
486#endif
487
488#ifdef CONFIG_SERIAL_CPM_SMC2
489 ppc_sys_device_enable(MPC8xx_CPM_SMC2);
490 ppc_sys_device_setfunc(MPC8xx_CPM_SMC2, PPC_SYS_FUNC_UART);
491#endif
386 return 0; 492 return 0;
387} 493}
388 494
389arch_initcall(mpc885ads_init); 495arch_initcall(mpc885ads_init);
496
497/*
498 To prevent confusion, console selection is gross:
499 by 0 assumed SMC1 and by 1 assumed SMC2
500 */
501struct platform_device* early_uart_get_pdev(int index)
502{
503 bd_t *bd = (bd_t *) __res;
504 struct fs_uart_platform_info *pinfo;
505
506 struct platform_device* pdev = NULL;
507 if(index) { /*assume SMC2 here*/
508 pdev = &ppc_sys_platform_devices[MPC8xx_CPM_SMC2];
509 pinfo = &mpc885_uart_pdata[1];
510 } else { /*over SMC1*/
511 pdev = &ppc_sys_platform_devices[MPC8xx_CPM_SMC1];
512 pinfo = &mpc885_uart_pdata[0];
513 }
514
515 pinfo->uart_clk = bd->bi_intfreq;
516 pdev->dev.platform_data = pinfo;
517 ppc_sys_fixup_mem_resource(pdev, IMAP_ADDR);
518 return NULL;
519}
520
diff --git a/arch/ppc/platforms/pq2ads.c b/arch/ppc/platforms/pq2ads.c
index 3365fd788a7a..7fc2e02f5246 100644
--- a/arch/ppc/platforms/pq2ads.c
+++ b/arch/ppc/platforms/pq2ads.c
@@ -14,11 +14,40 @@
14 14
15#include <linux/init.h> 15#include <linux/init.h>
16 16
17#include <asm/io.h>
17#include <asm/mpc8260.h> 18#include <asm/mpc8260.h>
19#include <asm/cpm2.h>
20#include <asm/immap_cpm2.h>
18 21
19void __init 22void __init
20m82xx_board_setup(void) 23m82xx_board_setup(void)
21{ 24{
25 cpm2_map_t* immap = ioremap(CPM_MAP_ADDR, sizeof(cpm2_map_t));
26 u32 *bcsr = ioremap(BCSR_ADDR+4, sizeof(u32));
27
22 /* Enable the 2nd UART port */ 28 /* Enable the 2nd UART port */
23 *(volatile uint *)(BCSR_ADDR + 4) &= ~BCSR1_RS232_EN2; 29 clrbits32(bcsr, BCSR1_RS232_EN2);
30
31#ifdef CONFIG_SERIAL_CPM_SCC1
32 clrbits32((u32*)&immap->im_scc[0].scc_sccm, UART_SCCM_TX | UART_SCCM_RX);
33 clrbits32((u32*)&immap->im_scc[0].scc_gsmrl, SCC_GSMRL_ENR | SCC_GSMRL_ENT);
34#endif
35
36#ifdef CONFIG_SERIAL_CPM_SCC2
37 clrbits32((u32*)&immap->im_scc[1].scc_sccm, UART_SCCM_TX | UART_SCCM_RX);
38 clrbits32((u32*)&immap->im_scc[1].scc_gsmrl, SCC_GSMRL_ENR | SCC_GSMRL_ENT);
39#endif
40
41#ifdef CONFIG_SERIAL_CPM_SCC3
42 clrbits32((u32*)&immap->im_scc[2].scc_sccm, UART_SCCM_TX | UART_SCCM_RX);
43 clrbits32((u32*)&immap->im_scc[2].scc_gsmrl, SCC_GSMRL_ENR | SCC_GSMRL_ENT);
44#endif
45
46#ifdef CONFIG_SERIAL_CPM_SCC4
47 clrbits32((u32*)&immap->im_scc[3].scc_sccm, UART_SCCM_TX | UART_SCCM_RX);
48 clrbits32((u32*)&immap->im_scc[3].scc_gsmrl, SCC_GSMRL_ENR | SCC_GSMRL_ENT);
49#endif
50
51 iounmap(bcsr);
52 iounmap(immap);
24} 53}
diff --git a/arch/ppc/syslib/ibm440gx_common.c b/arch/ppc/syslib/ibm440gx_common.c
index a7dd55f1c63e..f6cc16888527 100644
--- a/arch/ppc/syslib/ibm440gx_common.c
+++ b/arch/ppc/syslib/ibm440gx_common.c
@@ -2,7 +2,7 @@
2 * PPC440GX system library 2 * PPC440GX system library
3 * 3 *
4 * Eugene Surovegin <eugene.surovegin@zultys.com> or <ebs@ebshome.net> 4 * Eugene Surovegin <eugene.surovegin@zultys.com> or <ebs@ebshome.net>
5 * Copyright (c) 2003, 2004 Zultys Technologies 5 * Copyright (c) 2003 - 2006 Zultys Technologies
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify it 7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the 8 * under the terms of the GNU General Public License as published by the
@@ -282,3 +282,14 @@ int ibm440gx_show_cpuinfo(struct seq_file *m){
282 return 0; 282 return 0;
283} 283}
284 284
285void __init ibm440gx_platform_init(unsigned long r3, unsigned long r4,
286 unsigned long r5, unsigned long r6,
287 unsigned long r7)
288{
289 /* Erratum 440_43 workaround, disable L1 cache parity checking */
290 if (!strcmp(cur_cpu_spec->cpu_name, "440GX Rev. C") ||
291 !strcmp(cur_cpu_spec->cpu_name, "440GX Rev. F"))
292 mtspr(SPRN_CCR1, mfspr(SPRN_CCR1) | CCR1_DPC);
293
294 ibm44x_platform_init(r3, r4, r5, r6, r7);
295}
diff --git a/arch/ppc/syslib/ibm440gx_common.h b/arch/ppc/syslib/ibm440gx_common.h
index a2ab9fab8e34..a03ec6022e8f 100644
--- a/arch/ppc/syslib/ibm440gx_common.h
+++ b/arch/ppc/syslib/ibm440gx_common.h
@@ -29,6 +29,10 @@
29void ibm440gx_get_clocks(struct ibm44x_clocks*, unsigned int sys_clk, 29void ibm440gx_get_clocks(struct ibm44x_clocks*, unsigned int sys_clk,
30 unsigned int ser_clk) __init; 30 unsigned int ser_clk) __init;
31 31
32/* common 440GX platform init */
33void ibm440gx_platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
34 unsigned long r6, unsigned long r7) __init;
35
32/* Enable L2 cache */ 36/* Enable L2 cache */
33void ibm440gx_l2c_enable(void) __init; 37void ibm440gx_l2c_enable(void) __init;
34 38
diff --git a/arch/ppc/syslib/mpc8xx_devices.c b/arch/ppc/syslib/mpc8xx_devices.c
index bd41ed83beb3..6f536383866e 100644
--- a/arch/ppc/syslib/mpc8xx_devices.c
+++ b/arch/ppc/syslib/mpc8xx_devices.c
@@ -170,12 +170,18 @@ struct platform_device ppc_sys_platform_devices[] = {
170 [MPC8xx_CPM_SMC1] = { 170 [MPC8xx_CPM_SMC1] = {
171 .name = "fsl-cpm-smc", 171 .name = "fsl-cpm-smc",
172 .id = 1, 172 .id = 1,
173 .num_resources = 2, 173 .num_resources = 3,
174 .resource = (struct resource[]) { 174 .resource = (struct resource[]) {
175 { 175 {
176 .name = "regs", 176 .name = "regs",
177 .start = 0xa82, 177 .start = 0xa80,
178 .end = 0xa91, 178 .end = 0xa8f,
179 .flags = IORESOURCE_MEM,
180 },
181 {
182 .name = "pram",
183 .start = 0x3e80,
184 .end = 0x3ebf,
179 .flags = IORESOURCE_MEM, 185 .flags = IORESOURCE_MEM,
180 }, 186 },
181 { 187 {
@@ -189,15 +195,22 @@ struct platform_device ppc_sys_platform_devices[] = {
189 [MPC8xx_CPM_SMC2] = { 195 [MPC8xx_CPM_SMC2] = {
190 .name = "fsl-cpm-smc", 196 .name = "fsl-cpm-smc",
191 .id = 2, 197 .id = 2,
192 .num_resources = 2, 198 .num_resources = 3,
193 .resource = (struct resource[]) { 199 .resource = (struct resource[]) {
194 { 200 {
195 .name = "regs", 201 .name = "regs",
196 .start = 0xa92, 202 .start = 0xa90,
197 .end = 0xaa1, 203 .end = 0xa9f,
198 .flags = IORESOURCE_MEM, 204 .flags = IORESOURCE_MEM,
199 }, 205 },
200 { 206 {
207 .name = "pram",
208 .start = 0x3f80,
209 .end = 0x3fbf,
210 .flags = IORESOURCE_MEM,
211
212 },
213 {
201 .name = "interrupt", 214 .name = "interrupt",
202 .start = MPC8xx_INT_SMC2, 215 .start = MPC8xx_INT_SMC2,
203 .end = MPC8xx_INT_SMC2, 216 .end = MPC8xx_INT_SMC2,
diff --git a/arch/ppc/syslib/ppc_sys.c b/arch/ppc/syslib/ppc_sys.c
index 7662c4e6e7d6..2d48018b71d9 100644
--- a/arch/ppc/syslib/ppc_sys.c
+++ b/arch/ppc/syslib/ppc_sys.c
@@ -109,9 +109,11 @@ ppc_sys_fixup_mem_resource(struct platform_device *pdev, phys_addr_t paddr)
109 int i; 109 int i;
110 for (i = 0; i < pdev->num_resources; i++) { 110 for (i = 0; i < pdev->num_resources; i++) {
111 struct resource *r = &pdev->resource[i]; 111 struct resource *r = &pdev->resource[i];
112 if ((r->flags & IORESOURCE_MEM) == IORESOURCE_MEM) { 112 if (((r->flags & IORESOURCE_MEM) == IORESOURCE_MEM) &&
113 ((r->flags & PPC_SYS_IORESOURCE_FIXUPPED) != PPC_SYS_IORESOURCE_FIXUPPED)) {
113 r->start += paddr; 114 r->start += paddr;
114 r->end += paddr; 115 r->end += paddr;
116 r->flags |= PPC_SYS_IORESOURCE_FIXUPPED;
115 } 117 }
116 } 118 }
117} 119}
diff --git a/arch/ppc/syslib/pq2_sys.c b/arch/ppc/syslib/pq2_sys.c
index 75e64f1c144d..433b0fa203e1 100644
--- a/arch/ppc/syslib/pq2_sys.c
+++ b/arch/ppc/syslib/pq2_sys.c
@@ -113,13 +113,13 @@ struct ppc_sys_spec ppc_sys_specs[] = {
113 .ppc_sys_name = "8248", 113 .ppc_sys_name = "8248",
114 .mask = 0x0000ff00, 114 .mask = 0x0000ff00,
115 .value = 0x00000c00, 115 .value = 0x00000c00,
116 .num_devices = 11, 116 .num_devices = 12,
117 .device_list = (enum ppc_sys_devices[]) 117 .device_list = (enum ppc_sys_devices[])
118 { 118 {
119 MPC82xx_CPM_FCC1, MPC82xx_CPM_FCC2, MPC82xx_CPM_SCC1, 119 MPC82xx_CPM_FCC1, MPC82xx_CPM_FCC2, MPC82xx_CPM_SCC1,
120 MPC82xx_CPM_SCC2, MPC82xx_CPM_SCC3, MPC82xx_CPM_SMC1, 120 MPC82xx_CPM_SCC2, MPC82xx_CPM_SCC3, MPC82xx_CPM_SCC4,
121 MPC82xx_CPM_SMC2, MPC82xx_CPM_SPI, MPC82xx_CPM_I2C, 121 MPC82xx_CPM_SMC1, MPC82xx_CPM_SMC2, MPC82xx_CPM_SPI,
122 MPC82xx_CPM_USB, MPC82xx_SEC1, 122 MPC82xx_CPM_I2C, MPC82xx_CPM_USB, MPC82xx_SEC1,
123 }, 123 },
124 }, 124 },
125 { 125 {
diff --git a/drivers/block/floppy.c b/drivers/block/floppy.c
index bedb689b051f..dff1e67b1dd4 100644
--- a/drivers/block/floppy.c
+++ b/drivers/block/floppy.c
@@ -4301,7 +4301,7 @@ static int __init floppy_init(void)
4301 } 4301 }
4302 4302
4303 use_virtual_dma = can_use_virtual_dma & 1; 4303 use_virtual_dma = can_use_virtual_dma & 1;
4304#if defined(CONFIG_PPC64) 4304#if defined(CONFIG_PPC_MERGE)
4305 if (check_legacy_ioport(FDC1)) { 4305 if (check_legacy_ioport(FDC1)) {
4306 del_timer(&fd_timeout); 4306 del_timer(&fd_timeout);
4307 err = -ENODEV; 4307 err = -ENODEV;
diff --git a/drivers/input/serio/i8042-io.h b/drivers/input/serio/i8042-io.h
index 9a9221644250..cc21914fbc72 100644
--- a/drivers/input/serio/i8042-io.h
+++ b/drivers/input/serio/i8042-io.h
@@ -67,14 +67,14 @@ static inline int i8042_platform_init(void)
67 * On some platforms touching the i8042 data register region can do really 67 * On some platforms touching the i8042 data register region can do really
68 * bad things. Because of this the region is always reserved on such boxes. 68 * bad things. Because of this the region is always reserved on such boxes.
69 */ 69 */
70#if !defined(__sh__) && !defined(__alpha__) && !defined(__mips__) && !defined(CONFIG_PPC64) 70#if !defined(__sh__) && !defined(__alpha__) && !defined(__mips__) && !defined(CONFIG_PPC_MERGE)
71 if (!request_region(I8042_DATA_REG, 16, "i8042")) 71 if (!request_region(I8042_DATA_REG, 16, "i8042"))
72 return -EBUSY; 72 return -EBUSY;
73#endif 73#endif
74 74
75 i8042_reset = 1; 75 i8042_reset = 1;
76 76
77#if defined(CONFIG_PPC64) 77#if defined(CONFIG_PPC_MERGE)
78 if (check_legacy_ioport(I8042_DATA_REG)) 78 if (check_legacy_ioport(I8042_DATA_REG))
79 return -EBUSY; 79 return -EBUSY;
80 if (!request_region(I8042_DATA_REG, 16, "i8042")) 80 if (!request_region(I8042_DATA_REG, 16, "i8042"))
diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig
index 3e7302692dbe..a480a3742d47 100644
--- a/drivers/scsi/Kconfig
+++ b/drivers/scsi/Kconfig
@@ -446,7 +446,9 @@ config SCSI_DPT_I2O
446 446
447config SCSI_ADVANSYS 447config SCSI_ADVANSYS
448 tristate "AdvanSys SCSI support" 448 tristate "AdvanSys SCSI support"
449 depends on (ISA || EISA || PCI) && SCSI && BROKEN 449 depends on SCSI
450 depends on ISA || EISA || PCI
451 depends on BROKEN || X86_32
450 help 452 help
451 This is a driver for all SCSI host adapters manufactured by 453 This is a driver for all SCSI host adapters manufactured by
452 AdvanSys. It is documented in the kernel source in 454 AdvanSys. It is documented in the kernel source in
diff --git a/drivers/scsi/advansys.c b/drivers/scsi/advansys.c
index 28b93057b607..2a419634b256 100644
--- a/drivers/scsi/advansys.c
+++ b/drivers/scsi/advansys.c
@@ -2051,7 +2051,7 @@ STATIC ASC_DCNT AscGetMaxDmaCount(ushort);
2051#define ADV_VADDR_TO_U32 virt_to_bus 2051#define ADV_VADDR_TO_U32 virt_to_bus
2052#define ADV_U32_TO_VADDR bus_to_virt 2052#define ADV_U32_TO_VADDR bus_to_virt
2053 2053
2054#define AdvPortAddr ulong /* Virtual memory address size */ 2054#define AdvPortAddr void __iomem * /* Virtual memory address size */
2055 2055
2056/* 2056/*
2057 * Define Adv Library required memory access macros. 2057 * Define Adv Library required memory access macros.
diff --git a/drivers/serial/cpm_uart/cpm_uart.h b/drivers/serial/cpm_uart/cpm_uart.h
index 73c8a088c160..aa5eb7ddeda9 100644
--- a/drivers/serial/cpm_uart/cpm_uart.h
+++ b/drivers/serial/cpm_uart/cpm_uart.h
@@ -10,6 +10,8 @@
10#define CPM_UART_H 10#define CPM_UART_H
11 11
12#include <linux/config.h> 12#include <linux/config.h>
13#include <linux/platform_device.h>
14#include <linux/fs_uart_pd.h>
13 15
14#if defined(CONFIG_CPM2) 16#if defined(CONFIG_CPM2)
15#include "cpm_uart_cpm2.h" 17#include "cpm_uart_cpm2.h"
@@ -26,14 +28,14 @@
26#define FLAG_SMC 0x00000002 28#define FLAG_SMC 0x00000002
27#define FLAG_CONSOLE 0x00000001 29#define FLAG_CONSOLE 0x00000001
28 30
29#define UART_SMC1 0 31#define UART_SMC1 fsid_smc1_uart
30#define UART_SMC2 1 32#define UART_SMC2 fsid_smc2_uart
31#define UART_SCC1 2 33#define UART_SCC1 fsid_scc1_uart
32#define UART_SCC2 3 34#define UART_SCC2 fsid_scc2_uart
33#define UART_SCC3 4 35#define UART_SCC3 fsid_scc3_uart
34#define UART_SCC4 5 36#define UART_SCC4 fsid_scc4_uart
35 37
36#define UART_NR 6 38#define UART_NR fs_uart_nr
37 39
38#define RX_NUM_FIFO 4 40#define RX_NUM_FIFO 4
39#define RX_BUF_SIZE 32 41#define RX_BUF_SIZE 32
@@ -64,6 +66,7 @@ struct uart_cpm_port {
64 uint dp_addr; 66 uint dp_addr;
65 void *mem_addr; 67 void *mem_addr;
66 dma_addr_t dma_addr; 68 dma_addr_t dma_addr;
69 u32 mem_size;
67 /* helpers */ 70 /* helpers */
68 int baud; 71 int baud;
69 int bits; 72 int bits;
@@ -90,4 +93,36 @@ void scc2_lineif(struct uart_cpm_port *pinfo);
90void scc3_lineif(struct uart_cpm_port *pinfo); 93void scc3_lineif(struct uart_cpm_port *pinfo);
91void scc4_lineif(struct uart_cpm_port *pinfo); 94void scc4_lineif(struct uart_cpm_port *pinfo);
92 95
96/*
97 virtual to phys transtalion
98*/
99static inline unsigned long cpu2cpm_addr(void* addr, struct uart_cpm_port *pinfo)
100{
101 int offset;
102 u32 val = (u32)addr;
103 /* sane check */
104 if ((val >= (u32)pinfo->mem_addr) &&
105 (val<((u32)pinfo->mem_addr + pinfo->mem_size))) {
106 offset = val - (u32)pinfo->mem_addr;
107 return pinfo->dma_addr+offset;
108 }
109 printk("%s(): address %x to translate out of range!\n", __FUNCTION__, val);
110 return 0;
111}
112
113static inline void *cpm2cpu_addr(unsigned long addr, struct uart_cpm_port *pinfo)
114{
115 int offset;
116 u32 val = addr;
117 /* sane check */
118 if ((val >= pinfo->dma_addr) &&
119 (val<(pinfo->dma_addr + pinfo->mem_size))) {
120 offset = val - (u32)pinfo->dma_addr;
121 return (void*)(pinfo->mem_addr+offset);
122 }
123 printk("%s(): address %x to translate out of range!\n", __FUNCTION__, val);
124 return 0;
125}
126
127
93#endif /* CPM_UART_H */ 128#endif /* CPM_UART_H */
diff --git a/drivers/serial/cpm_uart/cpm_uart_core.c b/drivers/serial/cpm_uart/cpm_uart_core.c
index b7bf4c698a47..ced193bf9e1e 100644
--- a/drivers/serial/cpm_uart/cpm_uart_core.c
+++ b/drivers/serial/cpm_uart/cpm_uart_core.c
@@ -41,6 +41,7 @@
41#include <linux/device.h> 41#include <linux/device.h>
42#include <linux/bootmem.h> 42#include <linux/bootmem.h>
43#include <linux/dma-mapping.h> 43#include <linux/dma-mapping.h>
44#include <linux/fs_uart_pd.h>
44 45
45#include <asm/io.h> 46#include <asm/io.h>
46#include <asm/irq.h> 47#include <asm/irq.h>
@@ -60,7 +61,7 @@
60/* Track which ports are configured as uarts */ 61/* Track which ports are configured as uarts */
61int cpm_uart_port_map[UART_NR]; 62int cpm_uart_port_map[UART_NR];
62/* How many ports did we config as uarts */ 63/* How many ports did we config as uarts */
63int cpm_uart_nr; 64int cpm_uart_nr = 0;
64 65
65/**************************************************************/ 66/**************************************************************/
66 67
@@ -71,18 +72,36 @@ static void cpm_uart_initbd(struct uart_cpm_port *pinfo);
71 72
72/**************************************************************/ 73/**************************************************************/
73 74
74static inline unsigned long cpu2cpm_addr(void *addr) 75
76/* Place-holder for board-specific stuff */
77struct platform_device* __attribute__ ((weak)) __init
78early_uart_get_pdev(int index)
75{ 79{
76 if ((unsigned long)addr >= CPM_ADDR) 80 return NULL;
77 return (unsigned long)addr;
78 return virt_to_bus(addr);
79} 81}
80 82
81static inline void *cpm2cpu_addr(unsigned long addr) 83
84void cpm_uart_count(void)
82{ 85{
83 if (addr >= CPM_ADDR) 86 cpm_uart_nr = 0;
84 return (void *)addr; 87#ifdef CONFIG_SERIAL_CPM_SMC1
85 return bus_to_virt(addr); 88 cpm_uart_port_map[cpm_uart_nr++] = UART_SMC1;
89#endif
90#ifdef CONFIG_SERIAL_CPM_SMC2
91 cpm_uart_port_map[cpm_uart_nr++] = UART_SMC2;
92#endif
93#ifdef CONFIG_SERIAL_CPM_SCC1
94 cpm_uart_port_map[cpm_uart_nr++] = UART_SCC1;
95#endif
96#ifdef CONFIG_SERIAL_CPM_SCC2
97 cpm_uart_port_map[cpm_uart_nr++] = UART_SCC2;
98#endif
99#ifdef CONFIG_SERIAL_CPM_SCC3
100 cpm_uart_port_map[cpm_uart_nr++] = UART_SCC3;
101#endif
102#ifdef CONFIG_SERIAL_CPM_SCC4
103 cpm_uart_port_map[cpm_uart_nr++] = UART_SCC4;
104#endif
86} 105}
87 106
88/* 107/*
@@ -258,7 +277,7 @@ static void cpm_uart_int_rx(struct uart_port *port, struct pt_regs *regs)
258 } 277 }
259 278
260 /* get pointer */ 279 /* get pointer */
261 cp = cpm2cpu_addr(bdp->cbd_bufaddr); 280 cp = cpm2cpu_addr(bdp->cbd_bufaddr, pinfo);
262 281
263 /* loop through the buffer */ 282 /* loop through the buffer */
264 while (i-- > 0) { 283 while (i-- > 0) {
@@ -601,7 +620,7 @@ static int cpm_uart_tx_pump(struct uart_port *port)
601 /* Pick next descriptor and fill from buffer */ 620 /* Pick next descriptor and fill from buffer */
602 bdp = pinfo->tx_cur; 621 bdp = pinfo->tx_cur;
603 622
604 p = cpm2cpu_addr(bdp->cbd_bufaddr); 623 p = cpm2cpu_addr(bdp->cbd_bufaddr, pinfo);
605 624
606 *p++ = port->x_char; 625 *p++ = port->x_char;
607 bdp->cbd_datlen = 1; 626 bdp->cbd_datlen = 1;
@@ -628,7 +647,7 @@ static int cpm_uart_tx_pump(struct uart_port *port)
628 647
629 while (!(bdp->cbd_sc & BD_SC_READY) && (xmit->tail != xmit->head)) { 648 while (!(bdp->cbd_sc & BD_SC_READY) && (xmit->tail != xmit->head)) {
630 count = 0; 649 count = 0;
631 p = cpm2cpu_addr(bdp->cbd_bufaddr); 650 p = cpm2cpu_addr(bdp->cbd_bufaddr, pinfo);
632 while (count < pinfo->tx_fifosize) { 651 while (count < pinfo->tx_fifosize) {
633 *p++ = xmit->buf[xmit->tail]; 652 *p++ = xmit->buf[xmit->tail];
634 xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); 653 xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
@@ -677,12 +696,12 @@ static void cpm_uart_initbd(struct uart_cpm_port *pinfo)
677 mem_addr = pinfo->mem_addr; 696 mem_addr = pinfo->mem_addr;
678 bdp = pinfo->rx_cur = pinfo->rx_bd_base; 697 bdp = pinfo->rx_cur = pinfo->rx_bd_base;
679 for (i = 0; i < (pinfo->rx_nrfifos - 1); i++, bdp++) { 698 for (i = 0; i < (pinfo->rx_nrfifos - 1); i++, bdp++) {
680 bdp->cbd_bufaddr = cpu2cpm_addr(mem_addr); 699 bdp->cbd_bufaddr = cpu2cpm_addr(mem_addr, pinfo);
681 bdp->cbd_sc = BD_SC_EMPTY | BD_SC_INTRPT; 700 bdp->cbd_sc = BD_SC_EMPTY | BD_SC_INTRPT;
682 mem_addr += pinfo->rx_fifosize; 701 mem_addr += pinfo->rx_fifosize;
683 } 702 }
684 703
685 bdp->cbd_bufaddr = cpu2cpm_addr(mem_addr); 704 bdp->cbd_bufaddr = cpu2cpm_addr(mem_addr, pinfo);
686 bdp->cbd_sc = BD_SC_WRAP | BD_SC_EMPTY | BD_SC_INTRPT; 705 bdp->cbd_sc = BD_SC_WRAP | BD_SC_EMPTY | BD_SC_INTRPT;
687 706
688 /* Set the physical address of the host memory 707 /* Set the physical address of the host memory
@@ -692,12 +711,12 @@ static void cpm_uart_initbd(struct uart_cpm_port *pinfo)
692 mem_addr = pinfo->mem_addr + L1_CACHE_ALIGN(pinfo->rx_nrfifos * pinfo->rx_fifosize); 711 mem_addr = pinfo->mem_addr + L1_CACHE_ALIGN(pinfo->rx_nrfifos * pinfo->rx_fifosize);
693 bdp = pinfo->tx_cur = pinfo->tx_bd_base; 712 bdp = pinfo->tx_cur = pinfo->tx_bd_base;
694 for (i = 0; i < (pinfo->tx_nrfifos - 1); i++, bdp++) { 713 for (i = 0; i < (pinfo->tx_nrfifos - 1); i++, bdp++) {
695 bdp->cbd_bufaddr = cpu2cpm_addr(mem_addr); 714 bdp->cbd_bufaddr = cpu2cpm_addr(mem_addr, pinfo);
696 bdp->cbd_sc = BD_SC_INTRPT; 715 bdp->cbd_sc = BD_SC_INTRPT;
697 mem_addr += pinfo->tx_fifosize; 716 mem_addr += pinfo->tx_fifosize;
698 } 717 }
699 718
700 bdp->cbd_bufaddr = cpu2cpm_addr(mem_addr); 719 bdp->cbd_bufaddr = cpu2cpm_addr(mem_addr, pinfo);
701 bdp->cbd_sc = BD_SC_WRAP | BD_SC_INTRPT; 720 bdp->cbd_sc = BD_SC_WRAP | BD_SC_INTRPT;
702} 721}
703 722
@@ -829,14 +848,6 @@ static int cpm_uart_request_port(struct uart_port *port)
829 if (pinfo->flags & FLAG_CONSOLE) 848 if (pinfo->flags & FLAG_CONSOLE)
830 return 0; 849 return 0;
831 850
832 /*
833 * Setup any port IO, connect any baud rate generators,
834 * etc. This is expected to be handled by board
835 * dependant code
836 */
837 if (pinfo->set_lineif)
838 pinfo->set_lineif(pinfo);
839
840 if (IS_SMC(pinfo)) { 851 if (IS_SMC(pinfo)) {
841 pinfo->smcp->smc_smcm &= ~(SMCM_RX | SMCM_TX); 852 pinfo->smcp->smc_smcm &= ~(SMCM_RX | SMCM_TX);
842 pinfo->smcp->smc_smcmr &= ~(SMCMR_REN | SMCMR_TEN); 853 pinfo->smcp->smc_smcmr &= ~(SMCMR_REN | SMCMR_TEN);
@@ -988,6 +999,54 @@ struct uart_cpm_port cpm_uart_ports[UART_NR] = {
988 }, 999 },
989}; 1000};
990 1001
1002int cpm_uart_drv_get_platform_data(struct platform_device *pdev, int is_con)
1003{
1004 struct resource *r;
1005 struct fs_uart_platform_info *pdata = pdev->dev.platform_data;
1006 int idx = pdata->fs_no; /* It is UART_SMCx or UART_SCCx index */
1007 struct uart_cpm_port *pinfo;
1008 int line;
1009 u32 mem, pram;
1010
1011 for (line=0; line<UART_NR && cpm_uart_port_map[line]!=pdata->fs_no; line++);
1012
1013 pinfo = (struct uart_cpm_port *) &cpm_uart_ports[idx];
1014
1015 pinfo->brg = pdata->brg;
1016
1017 if (!is_con) {
1018 pinfo->port.line = line;
1019 pinfo->port.flags = UPF_BOOT_AUTOCONF;
1020 }
1021
1022 if (!(r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "regs")))
1023 return -EINVAL;
1024 mem = r->start;
1025
1026 if (!(r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "pram")))
1027 return -EINVAL;
1028 pram = r->start;
1029
1030 if(idx > fsid_smc2_uart) {
1031 pinfo->sccp = (scc_t *)mem;
1032 pinfo->sccup = (scc_uart_t *)pram;
1033 } else {
1034 pinfo->smcp = (smc_t *)mem;
1035 pinfo->smcup = (smc_uart_t *)pram;
1036 }
1037 pinfo->tx_nrfifos = pdata->tx_num_fifo;
1038 pinfo->tx_fifosize = pdata->tx_buf_size;
1039
1040 pinfo->rx_nrfifos = pdata->rx_num_fifo;
1041 pinfo->rx_fifosize = pdata->rx_buf_size;
1042
1043 pinfo->port.uartclk = pdata->uart_clk;
1044 pinfo->port.mapbase = (unsigned long)mem;
1045 pinfo->port.irq = platform_get_irq(pdev, 0);
1046
1047 return 0;
1048}
1049
991#ifdef CONFIG_SERIAL_CPM_CONSOLE 1050#ifdef CONFIG_SERIAL_CPM_CONSOLE
992/* 1051/*
993 * Print a string to the serial port trying not to disturb 1052 * Print a string to the serial port trying not to disturb
@@ -1027,7 +1086,7 @@ static void cpm_uart_console_write(struct console *co, const char *s,
1027 * If the buffer address is in the CPM DPRAM, don't 1086 * If the buffer address is in the CPM DPRAM, don't
1028 * convert it. 1087 * convert it.
1029 */ 1088 */
1030 cp = cpm2cpu_addr(bdp->cbd_bufaddr); 1089 cp = cpm2cpu_addr(bdp->cbd_bufaddr, pinfo);
1031 1090
1032 *cp = *s; 1091 *cp = *s;
1033 1092
@@ -1044,7 +1103,7 @@ static void cpm_uart_console_write(struct console *co, const char *s,
1044 while ((bdp->cbd_sc & BD_SC_READY) != 0) 1103 while ((bdp->cbd_sc & BD_SC_READY) != 0)
1045 ; 1104 ;
1046 1105
1047 cp = cpm2cpu_addr(bdp->cbd_bufaddr); 1106 cp = cpm2cpu_addr(bdp->cbd_bufaddr, pinfo);
1048 1107
1049 *cp = 13; 1108 *cp = 13;
1050 bdp->cbd_datlen = 1; 1109 bdp->cbd_datlen = 1;
@@ -1067,9 +1126,7 @@ static void cpm_uart_console_write(struct console *co, const char *s,
1067 pinfo->tx_cur = (volatile cbd_t *) bdp; 1126 pinfo->tx_cur = (volatile cbd_t *) bdp;
1068} 1127}
1069 1128
1070/* 1129
1071 * Setup console. Be careful is called early !
1072 */
1073static int __init cpm_uart_console_setup(struct console *co, char *options) 1130static int __init cpm_uart_console_setup(struct console *co, char *options)
1074{ 1131{
1075 struct uart_port *port; 1132 struct uart_port *port;
@@ -1080,9 +1137,27 @@ static int __init cpm_uart_console_setup(struct console *co, char *options)
1080 int flow = 'n'; 1137 int flow = 'n';
1081 int ret; 1138 int ret;
1082 1139
1140 struct fs_uart_platform_info *pdata;
1141 struct platform_device* pdev = early_uart_get_pdev(co->index);
1142
1083 port = 1143 port =
1084 (struct uart_port *)&cpm_uart_ports[cpm_uart_port_map[co->index]]; 1144 (struct uart_port *)&cpm_uart_ports[cpm_uart_port_map[co->index]];
1085 pinfo = (struct uart_cpm_port *)port; 1145 pinfo = (struct uart_cpm_port *)port;
1146 if (!pdev) {
1147 pr_info("cpm_uart: console: compat mode\n");
1148 /* compatibility - will be cleaned up */
1149 cpm_uart_init_portdesc();
1150
1151 if (pinfo->set_lineif)
1152 pinfo->set_lineif(pinfo);
1153 } else {
1154 pdata = pdev->dev.platform_data;
1155 if (pdata)
1156 if (pdata->init_ioports)
1157 pdata->init_ioports();
1158
1159 cpm_uart_drv_get_platform_data(pdev, 1);
1160 }
1086 1161
1087 pinfo->flags |= FLAG_CONSOLE; 1162 pinfo->flags |= FLAG_CONSOLE;
1088 1163
@@ -1097,14 +1172,6 @@ static int __init cpm_uart_console_setup(struct console *co, char *options)
1097 baud = 9600; 1172 baud = 9600;
1098 } 1173 }
1099 1174
1100 /*
1101 * Setup any port IO, connect any baud rate generators,
1102 * etc. This is expected to be handled by board
1103 * dependant code
1104 */
1105 if (pinfo->set_lineif)
1106 pinfo->set_lineif(pinfo);
1107
1108 if (IS_SMC(pinfo)) { 1175 if (IS_SMC(pinfo)) {
1109 pinfo->smcp->smc_smcm &= ~(SMCM_RX | SMCM_TX); 1176 pinfo->smcp->smc_smcm &= ~(SMCM_RX | SMCM_TX);
1110 pinfo->smcp->smc_smcmr &= ~(SMCMR_REN | SMCMR_TEN); 1177 pinfo->smcp->smc_smcmr &= ~(SMCMR_REN | SMCMR_TEN);
@@ -1143,11 +1210,8 @@ static struct console cpm_scc_uart_console = {
1143 1210
1144int __init cpm_uart_console_init(void) 1211int __init cpm_uart_console_init(void)
1145{ 1212{
1146 int ret = cpm_uart_init_portdesc(); 1213 register_console(&cpm_scc_uart_console);
1147 1214 return 0;
1148 if (!ret)
1149 register_console(&cpm_scc_uart_console);
1150 return ret;
1151} 1215}
1152 1216
1153console_initcall(cpm_uart_console_init); 1217console_initcall(cpm_uart_console_init);
@@ -1165,44 +1229,130 @@ static struct uart_driver cpm_reg = {
1165 .minor = SERIAL_CPM_MINOR, 1229 .minor = SERIAL_CPM_MINOR,
1166 .cons = CPM_UART_CONSOLE, 1230 .cons = CPM_UART_CONSOLE,
1167}; 1231};
1168 1232static int cpm_uart_drv_probe(struct device *dev)
1169static int __init cpm_uart_init(void)
1170{ 1233{
1171 int ret, i; 1234 struct platform_device *pdev = to_platform_device(dev);
1172 1235 struct fs_uart_platform_info *pdata;
1173 printk(KERN_INFO "Serial: CPM driver $Revision: 0.01 $\n"); 1236 int ret = -ENODEV;
1174 1237
1175#ifndef CONFIG_SERIAL_CPM_CONSOLE 1238 if(!pdev) {
1176 ret = cpm_uart_init_portdesc(); 1239 printk(KERN_ERR"CPM UART: platform data missing!\n");
1177 if (ret)
1178 return ret; 1240 return ret;
1179#endif 1241 }
1180 1242
1181 cpm_reg.nr = cpm_uart_nr; 1243 pdata = pdev->dev.platform_data;
1182 ret = uart_register_driver(&cpm_reg); 1244 pr_debug("cpm_uart_drv_probe: Adding CPM UART %d\n",
1245 cpm_uart_port_map[pdata->fs_no]);
1183 1246
1184 if (ret) 1247 if ((ret = cpm_uart_drv_get_platform_data(pdev, 0)))
1185 return ret; 1248 return ret;
1186 1249
1187 for (i = 0; i < cpm_uart_nr; i++) { 1250 if (pdata->init_ioports)
1188 int con = cpm_uart_port_map[i]; 1251 pdata->init_ioports();
1189 cpm_uart_ports[con].port.line = i;
1190 cpm_uart_ports[con].port.flags = UPF_BOOT_AUTOCONF;
1191 uart_add_one_port(&cpm_reg, &cpm_uart_ports[con].port);
1192 }
1193 1252
1194 return ret; 1253 ret = uart_add_one_port(&cpm_reg, &cpm_uart_ports[pdata->fs_no].port);
1254
1255 return ret;
1195} 1256}
1196 1257
1197static void __exit cpm_uart_exit(void) 1258static int cpm_uart_drv_remove(struct device *dev)
1259{
1260 struct platform_device *pdev = to_platform_device(dev);
1261 struct fs_uart_platform_info *pdata = pdev->dev.platform_data;
1262
1263 pr_debug("cpm_uart_drv_remove: Removing CPM UART %d\n",
1264 cpm_uart_port_map[pdata->fs_no]);
1265
1266 uart_remove_one_port(&cpm_reg, &cpm_uart_ports[pdata->fs_no].port);
1267 return 0;
1268}
1269
1270static struct device_driver cpm_smc_uart_driver = {
1271 .name = "fsl-cpm-smc:uart",
1272 .bus = &platform_bus_type,
1273 .probe = cpm_uart_drv_probe,
1274 .remove = cpm_uart_drv_remove,
1275};
1276
1277static struct device_driver cpm_scc_uart_driver = {
1278 .name = "fsl-cpm-scc:uart",
1279 .bus = &platform_bus_type,
1280 .probe = cpm_uart_drv_probe,
1281 .remove = cpm_uart_drv_remove,
1282};
1283
1284/*
1285 This is supposed to match uart devices on platform bus,
1286 */
1287static int match_is_uart (struct device* dev, void* data)
1198{ 1288{
1289 struct platform_device* pdev = container_of(dev, struct platform_device, dev);
1290 int ret = 0;
1291 /* this was setfunc as uart */
1292 if(strstr(pdev->name,":uart")) {
1293 ret = 1;
1294 }
1295 return ret;
1296}
1297
1298
1299static int cpm_uart_init(void) {
1300
1301 int ret;
1199 int i; 1302 int i;
1303 struct device *dev;
1304 printk(KERN_INFO "Serial: CPM driver $Revision: 0.02 $\n");
1305
1306 /* lookup the bus for uart devices */
1307 dev = bus_find_device(&platform_bus_type, NULL, 0, match_is_uart);
1308
1309 /* There are devices on the bus - all should be OK */
1310 if (dev) {
1311 cpm_uart_count();
1312 cpm_reg.nr = cpm_uart_nr;
1313
1314 if (!(ret = uart_register_driver(&cpm_reg))) {
1315 if ((ret = driver_register(&cpm_smc_uart_driver))) {
1316 uart_unregister_driver(&cpm_reg);
1317 return ret;
1318 }
1319 if ((ret = driver_register(&cpm_scc_uart_driver))) {
1320 driver_unregister(&cpm_scc_uart_driver);
1321 uart_unregister_driver(&cpm_reg);
1322 }
1323 }
1324 } else {
1325 /* No capable platform devices found - falling back to legacy mode */
1326 pr_info("cpm_uart: WARNING: no UART devices found on platform bus!\n");
1327 pr_info(
1328 "cpm_uart: the driver will guess configuration, but this mode is no longer supported.\n");
1329#ifndef CONFIG_SERIAL_CPM_CONSOLE
1330 ret = cpm_uart_init_portdesc();
1331 if (ret)
1332 return ret;
1333#endif
1334
1335 cpm_reg.nr = cpm_uart_nr;
1336 ret = uart_register_driver(&cpm_reg);
1337
1338 if (ret)
1339 return ret;
1340
1341 for (i = 0; i < cpm_uart_nr; i++) {
1342 int con = cpm_uart_port_map[i];
1343 cpm_uart_ports[con].port.line = i;
1344 cpm_uart_ports[con].port.flags = UPF_BOOT_AUTOCONF;
1345 uart_add_one_port(&cpm_reg, &cpm_uart_ports[con].port);
1346 }
1200 1347
1201 for (i = 0; i < cpm_uart_nr; i++) {
1202 int con = cpm_uart_port_map[i];
1203 uart_remove_one_port(&cpm_reg, &cpm_uart_ports[con].port);
1204 } 1348 }
1349 return ret;
1350}
1205 1351
1352static void __exit cpm_uart_exit(void)
1353{
1354 driver_unregister(&cpm_scc_uart_driver);
1355 driver_unregister(&cpm_smc_uart_driver);
1206 uart_unregister_driver(&cpm_reg); 1356 uart_unregister_driver(&cpm_reg);
1207} 1357}
1208 1358
diff --git a/drivers/serial/cpm_uart/cpm_uart_cpm1.c b/drivers/serial/cpm_uart/cpm_uart_cpm1.c
index d789ee55cbb7..a5a30622637a 100644
--- a/drivers/serial/cpm_uart/cpm_uart_cpm1.c
+++ b/drivers/serial/cpm_uart/cpm_uart_cpm1.c
@@ -81,58 +81,11 @@ void cpm_line_cr_cmd(int line, int cmd)
81 81
82void smc1_lineif(struct uart_cpm_port *pinfo) 82void smc1_lineif(struct uart_cpm_port *pinfo)
83{ 83{
84 volatile cpm8xx_t *cp = cpmp;
85
86 (void)cp; /* fix warning */
87#if defined (CONFIG_MPC885ADS)
88 /* Enable SMC1 transceivers */
89 {
90 cp->cp_pepar |= 0x000000c0;
91 cp->cp_pedir &= ~0x000000c0;
92 cp->cp_peso &= ~0x00000040;
93 cp->cp_peso |= 0x00000080;
94 }
95#elif defined (CONFIG_MPC86XADS)
96 unsigned int iobits = 0x000000c0;
97
98 if (!pinfo->is_portb) {
99 cp->cp_pbpar |= iobits;
100 cp->cp_pbdir &= ~iobits;
101 cp->cp_pbodr &= ~iobits;
102 } else {
103 ((immap_t *)IMAP_ADDR)->im_ioport.iop_papar |= iobits;
104 ((immap_t *)IMAP_ADDR)->im_ioport.iop_padir &= ~iobits;
105 ((immap_t *)IMAP_ADDR)->im_ioport.iop_paodr &= ~iobits;
106 }
107#endif
108 pinfo->brg = 1; 84 pinfo->brg = 1;
109} 85}
110 86
111void smc2_lineif(struct uart_cpm_port *pinfo) 87void smc2_lineif(struct uart_cpm_port *pinfo)
112{ 88{
113 volatile cpm8xx_t *cp = cpmp;
114
115 (void)cp; /* fix warning */
116#if defined (CONFIG_MPC885ADS)
117 cp->cp_pepar |= 0x00000c00;
118 cp->cp_pedir &= ~0x00000c00;
119 cp->cp_peso &= ~0x00000400;
120 cp->cp_peso |= 0x00000800;
121#elif defined (CONFIG_MPC86XADS)
122 unsigned int iobits = 0x00000c00;
123
124 if (!pinfo->is_portb) {
125 cp->cp_pbpar |= iobits;
126 cp->cp_pbdir &= ~iobits;
127 cp->cp_pbodr &= ~iobits;
128 } else {
129 ((immap_t *)IMAP_ADDR)->im_ioport.iop_papar |= iobits;
130 ((immap_t *)IMAP_ADDR)->im_ioport.iop_padir &= ~iobits;
131 ((immap_t *)IMAP_ADDR)->im_ioport.iop_paodr &= ~iobits;
132 }
133
134#endif
135
136 pinfo->brg = 2; 89 pinfo->brg = 2;
137} 90}
138 91
@@ -191,7 +144,7 @@ int cpm_uart_allocbuf(struct uart_cpm_port *pinfo, unsigned int is_con)
191 /* was hostalloc but changed cause it blows away the */ 144 /* was hostalloc but changed cause it blows away the */
192 /* large tlb mapping when pinning the kernel area */ 145 /* large tlb mapping when pinning the kernel area */
193 mem_addr = (u8 *) cpm_dpram_addr(cpm_dpalloc(memsz, 8)); 146 mem_addr = (u8 *) cpm_dpram_addr(cpm_dpalloc(memsz, 8));
194 dma_addr = 0; 147 dma_addr = (u32)mem_addr;
195 } else 148 } else
196 mem_addr = dma_alloc_coherent(NULL, memsz, &dma_addr, 149 mem_addr = dma_alloc_coherent(NULL, memsz, &dma_addr,
197 GFP_KERNEL); 150 GFP_KERNEL);
@@ -204,8 +157,9 @@ int cpm_uart_allocbuf(struct uart_cpm_port *pinfo, unsigned int is_con)
204 } 157 }
205 158
206 pinfo->dp_addr = dp_offset; 159 pinfo->dp_addr = dp_offset;
207 pinfo->mem_addr = mem_addr; 160 pinfo->mem_addr = mem_addr; /* virtual address*/
208 pinfo->dma_addr = dma_addr; 161 pinfo->dma_addr = dma_addr; /* physical address*/
162 pinfo->mem_size = memsz;
209 163
210 pinfo->rx_buf = mem_addr; 164 pinfo->rx_buf = mem_addr;
211 pinfo->tx_buf = pinfo->rx_buf + L1_CACHE_ALIGN(pinfo->rx_nrfifos 165 pinfo->tx_buf = pinfo->rx_buf + L1_CACHE_ALIGN(pinfo->rx_nrfifos
diff --git a/drivers/serial/cpm_uart/cpm_uart_cpm2.c b/drivers/serial/cpm_uart/cpm_uart_cpm2.c
index fd9e53ed3feb..7c6b07aeea92 100644
--- a/drivers/serial/cpm_uart/cpm_uart_cpm2.c
+++ b/drivers/serial/cpm_uart/cpm_uart_cpm2.c
@@ -142,14 +142,6 @@ void scc2_lineif(struct uart_cpm_port *pinfo)
142 * be supported in a sane fashion. 142 * be supported in a sane fashion.
143 */ 143 */
144#ifndef CONFIG_STX_GP3 144#ifndef CONFIG_STX_GP3
145#ifdef CONFIG_MPC8560_ADS
146 volatile iop_cpm2_t *io = &cpm2_immr->im_ioport;
147 io->iop_ppard |= 0x00000018;
148 io->iop_psord &= ~0x00000008; /* Rx */
149 io->iop_psord &= ~0x00000010; /* Tx */
150 io->iop_pdird &= ~0x00000008; /* Rx */
151 io->iop_pdird |= 0x00000010; /* Tx */
152#else
153 volatile iop_cpm2_t *io = &cpm2_immr->im_ioport; 145 volatile iop_cpm2_t *io = &cpm2_immr->im_ioport;
154 io->iop_pparb |= 0x008b0000; 146 io->iop_pparb |= 0x008b0000;
155 io->iop_pdirb |= 0x00880000; 147 io->iop_pdirb |= 0x00880000;
@@ -157,7 +149,6 @@ void scc2_lineif(struct uart_cpm_port *pinfo)
157 io->iop_pdirb &= ~0x00030000; 149 io->iop_pdirb &= ~0x00030000;
158 io->iop_psorb &= ~0x00030000; 150 io->iop_psorb &= ~0x00030000;
159#endif 151#endif
160#endif
161 cpm2_immr->im_cpmux.cmx_scr &= 0xff00ffff; 152 cpm2_immr->im_cpmux.cmx_scr &= 0xff00ffff;
162 cpm2_immr->im_cpmux.cmx_scr |= 0x00090000; 153 cpm2_immr->im_cpmux.cmx_scr |= 0x00090000;
163 pinfo->brg = 2; 154 pinfo->brg = 2;
@@ -218,8 +209,10 @@ int cpm_uart_allocbuf(struct uart_cpm_port *pinfo, unsigned int is_con)
218 209
219 memsz = L1_CACHE_ALIGN(pinfo->rx_nrfifos * pinfo->rx_fifosize) + 210 memsz = L1_CACHE_ALIGN(pinfo->rx_nrfifos * pinfo->rx_fifosize) +
220 L1_CACHE_ALIGN(pinfo->tx_nrfifos * pinfo->tx_fifosize); 211 L1_CACHE_ALIGN(pinfo->tx_nrfifos * pinfo->tx_fifosize);
221 if (is_con) 212 if (is_con) {
222 mem_addr = alloc_bootmem(memsz); 213 mem_addr = alloc_bootmem(memsz);
214 dma_addr = mem_addr;
215 }
223 else 216 else
224 mem_addr = dma_alloc_coherent(NULL, memsz, &dma_addr, 217 mem_addr = dma_alloc_coherent(NULL, memsz, &dma_addr,
225 GFP_KERNEL); 218 GFP_KERNEL);
@@ -234,6 +227,7 @@ int cpm_uart_allocbuf(struct uart_cpm_port *pinfo, unsigned int is_con)
234 pinfo->dp_addr = dp_offset; 227 pinfo->dp_addr = dp_offset;
235 pinfo->mem_addr = mem_addr; 228 pinfo->mem_addr = mem_addr;
236 pinfo->dma_addr = dma_addr; 229 pinfo->dma_addr = dma_addr;
230 pinfo->mem_size = memsz;
237 231
238 pinfo->rx_buf = mem_addr; 232 pinfo->rx_buf = mem_addr;
239 pinfo->tx_buf = pinfo->rx_buf + L1_CACHE_ALIGN(pinfo->rx_nrfifos 233 pinfo->tx_buf = pinfo->rx_buf + L1_CACHE_ALIGN(pinfo->rx_nrfifos
diff --git a/drivers/video/au1200fb.c b/drivers/video/au1200fb.c
index b367de30b98c..600d3e0e08b7 100644
--- a/drivers/video/au1200fb.c
+++ b/drivers/video/au1200fb.c
@@ -1920,1925 +1920,3 @@ module_exit(au1200fb_cleanup);
1920 1920
1921MODULE_DESCRIPTION(DRIVER_DESC); 1921MODULE_DESCRIPTION(DRIVER_DESC);
1922MODULE_LICENSE("GPL"); 1922MODULE_LICENSE("GPL");
1923/*
1924 * BRIEF MODULE DESCRIPTION
1925 * Au1200 LCD Driver.
1926 *
1927 * Copyright 2004-2005 AMD
1928 * Author: AMD
1929 *
1930 * Based on:
1931 * linux/drivers/video/skeletonfb.c -- Skeleton for a frame buffer device
1932 * Created 28 Dec 1997 by Geert Uytterhoeven
1933 *
1934 * This program is free software; you can redistribute it and/or modify it
1935 * under the terms of the GNU General Public License as published by the
1936 * Free Software Foundation; either version 2 of the License, or (at your
1937 * option) any later version.
1938 *
1939 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
1940 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
1941 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
1942 * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
1943 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
1944 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
1945 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
1946 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
1947 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
1948 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1949 *
1950 * You should have received a copy of the GNU General Public License along
1951 * with this program; if not, write to the Free Software Foundation, Inc.,
1952 * 675 Mass Ave, Cambridge, MA 02139, USA.
1953 */
1954
1955#include <linux/module.h>
1956#include <linux/platform_device.h>
1957#include <linux/kernel.h>
1958#include <linux/errno.h>
1959#include <linux/string.h>
1960#include <linux/mm.h>
1961#include <linux/fb.h>
1962#include <linux/init.h>
1963#include <linux/interrupt.h>
1964#include <linux/ctype.h>
1965#include <linux/dma-mapping.h>
1966
1967#include <asm/mach-au1x00/au1000.h>
1968#include "au1200fb.h"
1969
1970#ifdef CONFIG_PM
1971#include <asm/mach-au1x00/au1xxx_pm.h>
1972#endif
1973
1974#ifndef CONFIG_FB_AU1200_DEVS
1975#define CONFIG_FB_AU1200_DEVS 4
1976#endif
1977
1978#define DRIVER_NAME "au1200fb"
1979#define DRIVER_DESC "LCD controller driver for AU1200 processors"
1980
1981#define DEBUG 1
1982
1983#define print_err(f, arg...) printk(KERN_ERR DRIVER_NAME ": " f "\n", ## arg)
1984#define print_warn(f, arg...) printk(KERN_WARNING DRIVER_NAME ": " f "\n", ## arg)
1985#define print_info(f, arg...) printk(KERN_INFO DRIVER_NAME ": " f "\n", ## arg)
1986
1987#if DEBUG
1988#define print_dbg(f, arg...) printk(KERN_DEBUG __FILE__ ": " f "\n", ## arg)
1989#else
1990#define print_dbg(f, arg...) do {} while (0)
1991#endif
1992
1993
1994#define AU1200_LCD_FB_IOCTL 0x46FF
1995
1996#define AU1200_LCD_SET_SCREEN 1
1997#define AU1200_LCD_GET_SCREEN 2
1998#define AU1200_LCD_SET_WINDOW 3
1999#define AU1200_LCD_GET_WINDOW 4
2000#define AU1200_LCD_SET_PANEL 5
2001#define AU1200_LCD_GET_PANEL 6
2002
2003#define SCREEN_SIZE (1<< 1)
2004#define SCREEN_BACKCOLOR (1<< 2)
2005#define SCREEN_BRIGHTNESS (1<< 3)
2006#define SCREEN_COLORKEY (1<< 4)
2007#define SCREEN_MASK (1<< 5)
2008
2009struct au1200_lcd_global_regs_t {
2010 unsigned int flags;
2011 unsigned int xsize;
2012 unsigned int ysize;
2013 unsigned int backcolor;
2014 unsigned int brightness;
2015 unsigned int colorkey;
2016 unsigned int mask;
2017 unsigned int panel_choice;
2018 char panel_desc[80];
2019
2020};
2021
2022#define WIN_POSITION (1<< 0)
2023#define WIN_ALPHA_COLOR (1<< 1)
2024#define WIN_ALPHA_MODE (1<< 2)
2025#define WIN_PRIORITY (1<< 3)
2026#define WIN_CHANNEL (1<< 4)
2027#define WIN_BUFFER_FORMAT (1<< 5)
2028#define WIN_COLOR_ORDER (1<< 6)
2029#define WIN_PIXEL_ORDER (1<< 7)
2030#define WIN_SIZE (1<< 8)
2031#define WIN_COLORKEY_MODE (1<< 9)
2032#define WIN_DOUBLE_BUFFER_MODE (1<< 10)
2033#define WIN_RAM_ARRAY_MODE (1<< 11)
2034#define WIN_BUFFER_SCALE (1<< 12)
2035#define WIN_ENABLE (1<< 13)
2036
2037struct au1200_lcd_window_regs_t {
2038 unsigned int flags;
2039 unsigned int xpos;
2040 unsigned int ypos;
2041 unsigned int alpha_color;
2042 unsigned int alpha_mode;
2043 unsigned int priority;
2044 unsigned int channel;
2045 unsigned int buffer_format;
2046 unsigned int color_order;
2047 unsigned int pixel_order;
2048 unsigned int xsize;
2049 unsigned int ysize;
2050 unsigned int colorkey_mode;
2051 unsigned int double_buffer_mode;
2052 unsigned int ram_array_mode;
2053 unsigned int xscale;
2054 unsigned int yscale;
2055 unsigned int enable;
2056};
2057
2058
2059struct au1200_lcd_iodata_t {
2060 unsigned int subcmd;
2061 struct au1200_lcd_global_regs_t global;
2062 struct au1200_lcd_window_regs_t window;
2063};
2064
2065#if defined(__BIG_ENDIAN)
2066#define LCD_CONTROL_DEFAULT_PO LCD_CONTROL_PO_11
2067#else
2068#define LCD_CONTROL_DEFAULT_PO LCD_CONTROL_PO_00
2069#endif
2070#define LCD_CONTROL_DEFAULT_SBPPF LCD_CONTROL_SBPPF_565
2071
2072/* Private, per-framebuffer management information (independent of the panel itself) */
2073struct au1200fb_device {
2074 struct fb_info fb_info; /* FB driver info record */
2075
2076 int plane;
2077 unsigned char* fb_mem; /* FrameBuffer memory map */
2078 unsigned int fb_len;
2079 dma_addr_t fb_phys;
2080};
2081
2082static struct au1200fb_device _au1200fb_devices[CONFIG_FB_AU1200_DEVS];
2083/********************************************************************/
2084
2085/* LCD controller restrictions */
2086#define AU1200_LCD_MAX_XRES 1280
2087#define AU1200_LCD_MAX_YRES 1024
2088#define AU1200_LCD_MAX_BPP 32
2089#define AU1200_LCD_MAX_CLK 96000000 /* fixme: this needs to go away ? */
2090#define AU1200_LCD_NBR_PALETTE_ENTRIES 256
2091
2092/* Default number of visible screen buffer to allocate */
2093#define AU1200FB_NBR_VIDEO_BUFFERS 1
2094
2095/********************************************************************/
2096
2097static struct au1200_lcd *lcd = (struct au1200_lcd *) AU1200_LCD_ADDR;
2098static int window_index = 2; /* default is zero */
2099static int panel_index = 2; /* default is zero */
2100static struct window_settings *win;
2101static struct panel_settings *panel;
2102static int noblanking = 1;
2103static int nohwcursor = 0;
2104
2105struct window_settings {
2106 unsigned char name[64];
2107 uint32 mode_backcolor;
2108 uint32 mode_colorkey;
2109 uint32 mode_colorkeymsk;
2110 struct {
2111 int xres;
2112 int yres;
2113 int xpos;
2114 int ypos;
2115 uint32 mode_winctrl1; /* winctrl1[FRM,CCO,PO,PIPE] */
2116 uint32 mode_winenable;
2117 } w[4];
2118};
2119
2120#if defined(__BIG_ENDIAN)
2121#define LCD_WINCTRL1_PO_16BPP LCD_WINCTRL1_PO_00
2122#else
2123#define LCD_WINCTRL1_PO_16BPP LCD_WINCTRL1_PO_01
2124#endif
2125
2126extern int board_au1200fb_panel_init (void);
2127extern int board_au1200fb_panel_shutdown (void);
2128
2129#ifdef CONFIG_PM
2130int au1200fb_pm_callback(au1xxx_power_dev_t *dev,
2131 au1xxx_request_t request, void *data);
2132au1xxx_power_dev_t *LCD_pm_dev;
2133#endif
2134
2135/*
2136 * Default window configurations
2137 */
2138static struct window_settings windows[] = {
2139 { /* Index 0 */
2140 "0-FS gfx, 1-video, 2-ovly gfx, 3-ovly gfx",
2141 /* mode_backcolor */ 0x006600ff,
2142 /* mode_colorkey,msk*/ 0, 0,
2143 {
2144 {
2145 /* xres, yres, xpos, ypos */ 0, 0, 0, 0,
2146 /* mode_winctrl1 */ LCD_WINCTRL1_FRM_16BPP565 |
2147 LCD_WINCTRL1_PO_16BPP,
2148 /* mode_winenable*/ LCD_WINENABLE_WEN0,
2149 },
2150 {
2151 /* xres, yres, xpos, ypos */ 100, 100, 100, 100,
2152 /* mode_winctrl1 */ LCD_WINCTRL1_FRM_16BPP565 |
2153 LCD_WINCTRL1_PO_16BPP |
2154 LCD_WINCTRL1_PIPE,
2155 /* mode_winenable*/ LCD_WINENABLE_WEN1,
2156 },
2157 {
2158 /* xres, yres, xpos, ypos */ 0, 0, 0, 0,
2159 /* mode_winctrl1 */ LCD_WINCTRL1_FRM_16BPP565 |
2160 LCD_WINCTRL1_PO_16BPP,
2161 /* mode_winenable*/ 0,
2162 },
2163 {
2164 /* xres, yres, xpos, ypos */ 0, 0, 0, 0,
2165 /* mode_winctrl1 */ LCD_WINCTRL1_FRM_16BPP565 |
2166 LCD_WINCTRL1_PO_16BPP |
2167 LCD_WINCTRL1_PIPE,
2168 /* mode_winenable*/ 0,
2169 },
2170 },
2171 },
2172
2173 { /* Index 1 */
2174 "0-FS gfx, 1-video, 2-ovly gfx, 3-ovly gfx",
2175 /* mode_backcolor */ 0x006600ff,
2176 /* mode_colorkey,msk*/ 0, 0,
2177 {
2178 {
2179 /* xres, yres, xpos, ypos */ 320, 240, 5, 5,
2180 /* mode_winctrl1 */ LCD_WINCTRL1_FRM_24BPP |
2181 LCD_WINCTRL1_PO_00,
2182 /* mode_winenable*/ LCD_WINENABLE_WEN0,
2183 },
2184 {
2185 /* xres, yres, xpos, ypos */ 0, 0, 0, 0,
2186 /* mode_winctrl1 */ LCD_WINCTRL1_FRM_16BPP565
2187 | LCD_WINCTRL1_PO_16BPP,
2188 /* mode_winenable*/ 0,
2189 },
2190 {
2191 /* xres, yres, xpos, ypos */ 100, 100, 0, 0,
2192 /* mode_winctrl1 */ LCD_WINCTRL1_FRM_16BPP565 |
2193 LCD_WINCTRL1_PO_16BPP |
2194 LCD_WINCTRL1_PIPE,
2195 /* mode_winenable*/ 0/*LCD_WINENABLE_WEN2*/,
2196 },
2197 {
2198 /* xres, yres, xpos, ypos */ 200, 25, 0, 0,
2199 /* mode_winctrl1 */ LCD_WINCTRL1_FRM_16BPP565 |
2200 LCD_WINCTRL1_PO_16BPP |
2201 LCD_WINCTRL1_PIPE,
2202 /* mode_winenable*/ 0,
2203 },
2204 },
2205 },
2206 { /* Index 2 */
2207 "0-FS gfx, 1-video, 2-ovly gfx, 3-ovly gfx",
2208 /* mode_backcolor */ 0x006600ff,
2209 /* mode_colorkey,msk*/ 0, 0,
2210 {
2211 {
2212 /* xres, yres, xpos, ypos */ 0, 0, 0, 0,
2213 /* mode_winctrl1 */ LCD_WINCTRL1_FRM_16BPP565 |
2214 LCD_WINCTRL1_PO_16BPP,
2215 /* mode_winenable*/ LCD_WINENABLE_WEN0,
2216 },
2217 {
2218 /* xres, yres, xpos, ypos */ 0, 0, 0, 0,
2219 /* mode_winctrl1 */ LCD_WINCTRL1_FRM_16BPP565 |
2220 LCD_WINCTRL1_PO_16BPP,
2221 /* mode_winenable*/ 0,
2222 },
2223 {
2224 /* xres, yres, xpos, ypos */ 0, 0, 0, 0,
2225 /* mode_winctrl1 */ LCD_WINCTRL1_FRM_32BPP |
2226 LCD_WINCTRL1_PO_00|LCD_WINCTRL1_PIPE,
2227 /* mode_winenable*/ 0/*LCD_WINENABLE_WEN2*/,
2228 },
2229 {
2230 /* xres, yres, xpos, ypos */ 0, 0, 0, 0,
2231 /* mode_winctrl1 */ LCD_WINCTRL1_FRM_16BPP565 |
2232 LCD_WINCTRL1_PO_16BPP |
2233 LCD_WINCTRL1_PIPE,
2234 /* mode_winenable*/ 0,
2235 },
2236 },
2237 },
2238 /* Need VGA 640 @ 24bpp, @ 32bpp */
2239 /* Need VGA 800 @ 24bpp, @ 32bpp */
2240 /* Need VGA 1024 @ 24bpp, @ 32bpp */
2241};
2242
2243/*
2244 * Controller configurations for various panels.
2245 */
2246
2247struct panel_settings
2248{
2249 const char name[25]; /* Full name <vendor>_<model> */
2250
2251 struct fb_monspecs monspecs; /* FB monitor specs */
2252
2253 /* panel timings */
2254 uint32 mode_screen;
2255 uint32 mode_horztiming;
2256 uint32 mode_verttiming;
2257 uint32 mode_clkcontrol;
2258 uint32 mode_pwmdiv;
2259 uint32 mode_pwmhi;
2260 uint32 mode_outmask;
2261 uint32 mode_fifoctrl;
2262 uint32 mode_toyclksrc;
2263 uint32 mode_backlight;
2264 uint32 mode_auxpll;
2265 int (*device_init)(void);
2266 int (*device_shutdown)(void);
2267#define Xres min_xres
2268#define Yres min_yres
2269 u32 min_xres; /* Minimum horizontal resolution */
2270 u32 max_xres; /* Maximum horizontal resolution */
2271 u32 min_yres; /* Minimum vertical resolution */
2272 u32 max_yres; /* Maximum vertical resolution */
2273};
2274
2275/********************************************************************/
2276/* fixme: Maybe a modedb for the CRT ? otherwise panels should be as-is */
2277
2278/* List of panels known to work with the AU1200 LCD controller.
2279 * To add a new panel, enter the same specifications as the
2280 * Generic_TFT one, and MAKE SURE that it doesn't conflicts
2281 * with the controller restrictions. Restrictions are:
2282 *
2283 * STN color panels: max_bpp <= 12
2284 * STN mono panels: max_bpp <= 4
2285 * TFT panels: max_bpp <= 16
2286 * max_xres <= 800
2287 * max_yres <= 600
2288 */
2289static struct panel_settings known_lcd_panels[] =
2290{
2291 [0] = { /* QVGA 320x240 H:33.3kHz V:110Hz */
2292 .name = "QVGA_320x240",
2293 .monspecs = {
2294 .modedb = NULL,
2295 .modedb_len = 0,
2296 .hfmin = 30000,
2297 .hfmax = 70000,
2298 .vfmin = 60,
2299 .vfmax = 60,
2300 .dclkmin = 6000000,
2301 .dclkmax = 28000000,
2302 .input = FB_DISP_RGB,
2303 },
2304 .mode_screen = LCD_SCREEN_SX_N(320) |
2305 LCD_SCREEN_SY_N(240),
2306 .mode_horztiming = 0x00c4623b,
2307 .mode_verttiming = 0x00502814,
2308 .mode_clkcontrol = 0x00020002, /* /4=24Mhz */
2309 .mode_pwmdiv = 0x00000000,
2310 .mode_pwmhi = 0x00000000,
2311 .mode_outmask = 0x00FFFFFF,
2312 .mode_fifoctrl = 0x2f2f2f2f,
2313 .mode_toyclksrc = 0x00000004, /* AUXPLL directly */
2314 .mode_backlight = 0x00000000,
2315 .mode_auxpll = 8, /* 96MHz AUXPLL */
2316 .device_init = NULL,
2317 .device_shutdown = NULL,
2318 320, 320,
2319 240, 240,
2320 },
2321
2322 [1] = { /* VGA 640x480 H:30.3kHz V:58Hz */
2323 .name = "VGA_640x480",
2324 .monspecs = {
2325 .modedb = NULL,
2326 .modedb_len = 0,
2327 .hfmin = 30000,
2328 .hfmax = 70000,
2329 .vfmin = 60,
2330 .vfmax = 60,
2331 .dclkmin = 6000000,
2332 .dclkmax = 28000000,
2333 .input = FB_DISP_RGB,
2334 },
2335 .mode_screen = 0x13f9df80,
2336 .mode_horztiming = 0x003c5859,
2337 .mode_verttiming = 0x00741201,
2338 .mode_clkcontrol = 0x00020001, /* /4=24Mhz */
2339 .mode_pwmdiv = 0x00000000,
2340 .mode_pwmhi = 0x00000000,
2341 .mode_outmask = 0x00FFFFFF,
2342 .mode_fifoctrl = 0x2f2f2f2f,
2343 .mode_toyclksrc = 0x00000004, /* AUXPLL directly */
2344 .mode_backlight = 0x00000000,
2345 .mode_auxpll = 8, /* 96MHz AUXPLL */
2346 .device_init = NULL,
2347 .device_shutdown = NULL,
2348 640, 480,
2349 640, 480,
2350 },
2351
2352 [2] = { /* SVGA 800x600 H:46.1kHz V:69Hz */
2353 .name = "SVGA_800x600",
2354 .monspecs = {
2355 .modedb = NULL,
2356 .modedb_len = 0,
2357 .hfmin = 30000,
2358 .hfmax = 70000,
2359 .vfmin = 60,
2360 .vfmax = 60,
2361 .dclkmin = 6000000,
2362 .dclkmax = 28000000,
2363 .input = FB_DISP_RGB,
2364 },
2365 .mode_screen = 0x18fa5780,
2366 .mode_horztiming = 0x00dc7e77,
2367 .mode_verttiming = 0x00584805,
2368 .mode_clkcontrol = 0x00020000, /* /2=48Mhz */
2369 .mode_pwmdiv = 0x00000000,
2370 .mode_pwmhi = 0x00000000,
2371 .mode_outmask = 0x00FFFFFF,
2372 .mode_fifoctrl = 0x2f2f2f2f,
2373 .mode_toyclksrc = 0x00000004, /* AUXPLL directly */
2374 .mode_backlight = 0x00000000,
2375 .mode_auxpll = 8, /* 96MHz AUXPLL */
2376 .device_init = NULL,
2377 .device_shutdown = NULL,
2378 800, 800,
2379 600, 600,
2380 },
2381
2382 [3] = { /* XVGA 1024x768 H:56.2kHz V:70Hz */
2383 .name = "XVGA_1024x768",
2384 .monspecs = {
2385 .modedb = NULL,
2386 .modedb_len = 0,
2387 .hfmin = 30000,
2388 .hfmax = 70000,
2389 .vfmin = 60,
2390 .vfmax = 60,
2391 .dclkmin = 6000000,
2392 .dclkmax = 28000000,
2393 .input = FB_DISP_RGB,
2394 },
2395 .mode_screen = 0x1ffaff80,
2396 .mode_horztiming = 0x007d0e57,
2397 .mode_verttiming = 0x00740a01,
2398 .mode_clkcontrol = 0x000A0000, /* /1 */
2399 .mode_pwmdiv = 0x00000000,
2400 .mode_pwmhi = 0x00000000,
2401 .mode_outmask = 0x00FFFFFF,
2402 .mode_fifoctrl = 0x2f2f2f2f,
2403 .mode_toyclksrc = 0x00000004, /* AUXPLL directly */
2404 .mode_backlight = 0x00000000,
2405 .mode_auxpll = 6, /* 72MHz AUXPLL */
2406 .device_init = NULL,
2407 .device_shutdown = NULL,
2408 1024, 1024,
2409 768, 768,
2410 },
2411
2412 [4] = { /* XVGA XVGA 1280x1024 H:68.5kHz V:65Hz */
2413 .name = "XVGA_1280x1024",
2414 .monspecs = {
2415 .modedb = NULL,
2416 .modedb_len = 0,
2417 .hfmin = 30000,
2418 .hfmax = 70000,
2419 .vfmin = 60,
2420 .vfmax = 60,
2421 .dclkmin = 6000000,
2422 .dclkmax = 28000000,
2423 .input = FB_DISP_RGB,
2424 },
2425 .mode_screen = 0x27fbff80,
2426 .mode_horztiming = 0x00cdb2c7,
2427 .mode_verttiming = 0x00600002,
2428 .mode_clkcontrol = 0x000A0000, /* /1 */
2429 .mode_pwmdiv = 0x00000000,
2430 .mode_pwmhi = 0x00000000,
2431 .mode_outmask = 0x00FFFFFF,
2432 .mode_fifoctrl = 0x2f2f2f2f,
2433 .mode_toyclksrc = 0x00000004, /* AUXPLL directly */
2434 .mode_backlight = 0x00000000,
2435 .mode_auxpll = 10, /* 120MHz AUXPLL */
2436 .device_init = NULL,
2437 .device_shutdown = NULL,
2438 1280, 1280,
2439 1024, 1024,
2440 },
2441
2442 [5] = { /* Samsung 1024x768 TFT */
2443 .name = "Samsung_1024x768_TFT",
2444 .monspecs = {
2445 .modedb = NULL,
2446 .modedb_len = 0,
2447 .hfmin = 30000,
2448 .hfmax = 70000,
2449 .vfmin = 60,
2450 .vfmax = 60,
2451 .dclkmin = 6000000,
2452 .dclkmax = 28000000,
2453 .input = FB_DISP_RGB,
2454 },
2455 .mode_screen = 0x1ffaff80,
2456 .mode_horztiming = 0x018cc677,
2457 .mode_verttiming = 0x00241217,
2458 .mode_clkcontrol = 0x00000000, /* SCB 0x1 /4=24Mhz */
2459 .mode_pwmdiv = 0x8000063f, /* SCB 0x0 */
2460 .mode_pwmhi = 0x03400000, /* SCB 0x0 */
2461 .mode_outmask = 0x00FFFFFF,
2462 .mode_fifoctrl = 0x2f2f2f2f,
2463 .mode_toyclksrc = 0x00000004, /* AUXPLL directly */
2464 .mode_backlight = 0x00000000,
2465 .mode_auxpll = 8, /* 96MHz AUXPLL */
2466 .device_init = board_au1200fb_panel_init,
2467 .device_shutdown = board_au1200fb_panel_shutdown,
2468 1024, 1024,
2469 768, 768,
2470 },
2471
2472 [6] = { /* Toshiba 640x480 TFT */
2473 .name = "Toshiba_640x480_TFT",
2474 .monspecs = {
2475 .modedb = NULL,
2476 .modedb_len = 0,
2477 .hfmin = 30000,
2478 .hfmax = 70000,
2479 .vfmin = 60,
2480 .vfmax = 60,
2481 .dclkmin = 6000000,
2482 .dclkmax = 28000000,
2483 .input = FB_DISP_RGB,
2484 },
2485 .mode_screen = LCD_SCREEN_SX_N(640) |
2486 LCD_SCREEN_SY_N(480),
2487 .mode_horztiming = LCD_HORZTIMING_HPW_N(96) |
2488 LCD_HORZTIMING_HND1_N(13) | LCD_HORZTIMING_HND2_N(51),
2489 .mode_verttiming = LCD_VERTTIMING_VPW_N(2) |
2490 LCD_VERTTIMING_VND1_N(11) | LCD_VERTTIMING_VND2_N(32),
2491 .mode_clkcontrol = 0x00000000, /* /4=24Mhz */
2492 .mode_pwmdiv = 0x8000063f,
2493 .mode_pwmhi = 0x03400000,
2494 .mode_outmask = 0x00fcfcfc,
2495 .mode_fifoctrl = 0x2f2f2f2f,
2496 .mode_toyclksrc = 0x00000004, /* AUXPLL directly */
2497 .mode_backlight = 0x00000000,
2498 .mode_auxpll = 8, /* 96MHz AUXPLL */
2499 .device_init = board_au1200fb_panel_init,
2500 .device_shutdown = board_au1200fb_panel_shutdown,
2501 640, 480,
2502 640, 480,
2503 },
2504
2505 [7] = { /* Sharp 320x240 TFT */
2506 .name = "Sharp_320x240_TFT",
2507 .monspecs = {
2508 .modedb = NULL,
2509 .modedb_len = 0,
2510 .hfmin = 12500,
2511 .hfmax = 20000,
2512 .vfmin = 38,
2513 .vfmax = 81,
2514 .dclkmin = 4500000,
2515 .dclkmax = 6800000,
2516 .input = FB_DISP_RGB,
2517 },
2518 .mode_screen = LCD_SCREEN_SX_N(320) |
2519 LCD_SCREEN_SY_N(240),
2520 .mode_horztiming = LCD_HORZTIMING_HPW_N(60) |
2521 LCD_HORZTIMING_HND1_N(13) | LCD_HORZTIMING_HND2_N(2),
2522 .mode_verttiming = LCD_VERTTIMING_VPW_N(2) |
2523 LCD_VERTTIMING_VND1_N(2) | LCD_VERTTIMING_VND2_N(5),
2524 .mode_clkcontrol = LCD_CLKCONTROL_PCD_N(7), /*16=6Mhz*/
2525 .mode_pwmdiv = 0x8000063f,
2526 .mode_pwmhi = 0x03400000,
2527 .mode_outmask = 0x00fcfcfc,
2528 .mode_fifoctrl = 0x2f2f2f2f,
2529 .mode_toyclksrc = 0x00000004, /* AUXPLL directly */
2530 .mode_backlight = 0x00000000,
2531 .mode_auxpll = 8, /* 96MHz AUXPLL */
2532 .device_init = board_au1200fb_panel_init,
2533 .device_shutdown = board_au1200fb_panel_shutdown,
2534 320, 320,
2535 240, 240,
2536 },
2537
2538 [8] = { /* Toppoly TD070WGCB2 7" 856x480 TFT */
2539 .name = "Toppoly_TD070WGCB2",
2540 .monspecs = {
2541 .modedb = NULL,
2542 .modedb_len = 0,
2543 .hfmin = 30000,
2544 .hfmax = 70000,
2545 .vfmin = 60,
2546 .vfmax = 60,
2547 .dclkmin = 6000000,
2548 .dclkmax = 28000000,
2549 .input = FB_DISP_RGB,
2550 },
2551 .mode_screen = LCD_SCREEN_SX_N(856) |
2552 LCD_SCREEN_SY_N(480),
2553 .mode_horztiming = LCD_HORZTIMING_HND2_N(43) |
2554 LCD_HORZTIMING_HND1_N(43) | LCD_HORZTIMING_HPW_N(114),
2555 .mode_verttiming = LCD_VERTTIMING_VND2_N(20) |
2556 LCD_VERTTIMING_VND1_N(21) | LCD_VERTTIMING_VPW_N(4),
2557 .mode_clkcontrol = 0x00020001, /* /4=24Mhz */
2558 .mode_pwmdiv = 0x8000063f,
2559 .mode_pwmhi = 0x03400000,
2560 .mode_outmask = 0x00fcfcfc,
2561 .mode_fifoctrl = 0x2f2f2f2f,
2562 .mode_toyclksrc = 0x00000004, /* AUXPLL directly */
2563 .mode_backlight = 0x00000000,
2564 .mode_auxpll = 8, /* 96MHz AUXPLL */
2565 .device_init = board_au1200fb_panel_init,
2566 .device_shutdown = board_au1200fb_panel_shutdown,
2567 856, 856,
2568 480, 480,
2569 },
2570};
2571
2572#define NUM_PANELS (ARRAY_SIZE(known_lcd_panels))
2573
2574/********************************************************************/
2575
2576#ifdef CONFIG_PM
2577static int set_brightness(unsigned int brightness)
2578{
2579 unsigned int hi1, divider;
2580
2581 /* limit brightness pwm duty to >= 30/1600 */
2582 if (brightness < 30) {
2583 brightness = 30;
2584 }
2585 divider = (lcd->pwmdiv & 0x3FFFF) + 1;
2586 hi1 = (lcd->pwmhi >> 16) + 1;
2587 hi1 = (((brightness & 0xFF) + 1) * divider >> 8);
2588 lcd->pwmhi &= 0xFFFF;
2589 lcd->pwmhi |= (hi1 << 16);
2590
2591 return brightness;
2592}
2593#endif /* CONFIG_PM */
2594
2595static int winbpp (unsigned int winctrl1)
2596{
2597 int bits = 0;
2598
2599 /* how many bits are needed for each pixel format */
2600 switch (winctrl1 & LCD_WINCTRL1_FRM) {
2601 case LCD_WINCTRL1_FRM_1BPP:
2602 bits = 1;
2603 break;
2604 case LCD_WINCTRL1_FRM_2BPP:
2605 bits = 2;
2606 break;
2607 case LCD_WINCTRL1_FRM_4BPP:
2608 bits = 4;
2609 break;
2610 case LCD_WINCTRL1_FRM_8BPP:
2611 bits = 8;
2612 break;
2613 case LCD_WINCTRL1_FRM_12BPP:
2614 case LCD_WINCTRL1_FRM_16BPP655:
2615 case LCD_WINCTRL1_FRM_16BPP565:
2616 case LCD_WINCTRL1_FRM_16BPP556:
2617 case LCD_WINCTRL1_FRM_16BPPI1555:
2618 case LCD_WINCTRL1_FRM_16BPPI5551:
2619 case LCD_WINCTRL1_FRM_16BPPA1555:
2620 case LCD_WINCTRL1_FRM_16BPPA5551:
2621 bits = 16;
2622 break;
2623 case LCD_WINCTRL1_FRM_24BPP:
2624 case LCD_WINCTRL1_FRM_32BPP:
2625 bits = 32;
2626 break;
2627 }
2628
2629 return bits;
2630}
2631
2632static int fbinfo2index (struct fb_info *fb_info)
2633{
2634 int i;
2635
2636 for (i = 0; i < CONFIG_FB_AU1200_DEVS; ++i) {
2637 if (fb_info == (struct fb_info *)(&_au1200fb_devices[i].fb_info))
2638 return i;
2639 }
2640 printk("au1200fb: ERROR: fbinfo2index failed!\n");
2641 return -1;
2642}
2643
2644static int au1200_setlocation (struct au1200fb_device *fbdev, int plane,
2645 int xpos, int ypos)
2646{
2647 uint32 winctrl0, winctrl1, winenable, fb_offset = 0;
2648 int xsz, ysz;
2649
2650 /* FIX!!! NOT CHECKING FOR COMPLETE OFFSCREEN YET */
2651
2652 winctrl0 = lcd->window[plane].winctrl0;
2653 winctrl1 = lcd->window[plane].winctrl1;
2654 winctrl0 &= (LCD_WINCTRL0_A | LCD_WINCTRL0_AEN);
2655 winctrl1 &= ~(LCD_WINCTRL1_SZX | LCD_WINCTRL1_SZY);
2656
2657 /* Check for off-screen adjustments */
2658 xsz = win->w[plane].xres;
2659 ysz = win->w[plane].yres;
2660 if ((xpos + win->w[plane].xres) > panel->Xres) {
2661 /* Off-screen to the right */
2662 xsz = panel->Xres - xpos; /* off by 1 ??? */
2663 /*printk("off screen right\n");*/
2664 }
2665
2666 if ((ypos + win->w[plane].yres) > panel->Yres) {
2667 /* Off-screen to the bottom */
2668 ysz = panel->Yres - ypos; /* off by 1 ??? */
2669 /*printk("off screen bottom\n");*/
2670 }
2671
2672 if (xpos < 0) {
2673 /* Off-screen to the left */
2674 xsz = win->w[plane].xres + xpos;
2675 fb_offset += (((0 - xpos) * winbpp(lcd->window[plane].winctrl1))/8);
2676 xpos = 0;
2677 /*printk("off screen left\n");*/
2678 }
2679
2680 if (ypos < 0) {
2681 /* Off-screen to the top */
2682 ysz = win->w[plane].yres + ypos;
2683 /* fixme: fb_offset += ((0-ypos)*fb_pars[plane].line_length); */
2684 ypos = 0;
2685 /*printk("off screen top\n");*/
2686 }
2687
2688 /* record settings */
2689 win->w[plane].xpos = xpos;
2690 win->w[plane].ypos = ypos;
2691
2692 xsz -= 1;
2693 ysz -= 1;
2694 winctrl0 |= (xpos << 21);
2695 winctrl0 |= (ypos << 10);
2696 winctrl1 |= (xsz << 11);
2697 winctrl1 |= (ysz << 0);
2698
2699 /* Disable the window while making changes, then restore WINEN */
2700 winenable = lcd->winenable & (1 << plane);
2701 au_sync();
2702 lcd->winenable &= ~(1 << plane);
2703 lcd->window[plane].winctrl0 = winctrl0;
2704 lcd->window[plane].winctrl1 = winctrl1;
2705 lcd->window[plane].winbuf0 =
2706 lcd->window[plane].winbuf1 = fbdev->fb_phys;
2707 lcd->window[plane].winbufctrl = 0; /* select winbuf0 */
2708 lcd->winenable |= winenable;
2709 au_sync();
2710
2711 return 0;
2712}
2713
2714static void au1200_setpanel (struct panel_settings *newpanel)
2715{
2716 /*
2717 * Perform global setup/init of LCD controller
2718 */
2719 uint32 winenable;
2720
2721 /* Make sure all windows disabled */
2722 winenable = lcd->winenable;
2723 lcd->winenable = 0;
2724 au_sync();
2725 /*
2726 * Ensure everything is disabled before reconfiguring
2727 */
2728 if (lcd->screen & LCD_SCREEN_SEN) {
2729 /* Wait for vertical sync period */
2730 lcd->intstatus = LCD_INT_SS;
2731 while ((lcd->intstatus & LCD_INT_SS) == 0) {
2732 au_sync();
2733 }
2734
2735 lcd->screen &= ~LCD_SCREEN_SEN; /*disable the controller*/
2736
2737 do {
2738 lcd->intstatus = lcd->intstatus; /*clear interrupts*/
2739 au_sync();
2740 /*wait for controller to shut down*/
2741 } while ((lcd->intstatus & LCD_INT_SD) == 0);
2742
2743 /* Call shutdown of current panel (if up) */
2744 /* this must occur last, because if an external clock is driving
2745 the controller, the clock cannot be turned off before first
2746 shutting down the controller.
2747 */
2748 if (panel->device_shutdown != NULL)
2749 panel->device_shutdown();
2750 }
2751
2752 /* Newpanel == NULL indicates a shutdown operation only */
2753 if (newpanel == NULL)
2754 return;
2755
2756 panel = newpanel;
2757
2758 printk("Panel(%s), %dx%d\n", panel->name, panel->Xres, panel->Yres);
2759
2760 /*
2761 * Setup clocking if internal LCD clock source (assumes sys_auxpll valid)
2762 */
2763 if (!(panel->mode_clkcontrol & LCD_CLKCONTROL_EXT))
2764 {
2765 uint32 sys_clksrc;
2766 au_writel(panel->mode_auxpll, SYS_AUXPLL);
2767 sys_clksrc = au_readl(SYS_CLKSRC) & ~0x0000001f;
2768 sys_clksrc |= panel->mode_toyclksrc;
2769 au_writel(sys_clksrc, SYS_CLKSRC);
2770 }
2771
2772 /*
2773 * Configure panel timings
2774 */
2775 lcd->screen = panel->mode_screen;
2776 lcd->horztiming = panel->mode_horztiming;
2777 lcd->verttiming = panel->mode_verttiming;
2778 lcd->clkcontrol = panel->mode_clkcontrol;
2779 lcd->pwmdiv = panel->mode_pwmdiv;
2780 lcd->pwmhi = panel->mode_pwmhi;
2781 lcd->outmask = panel->mode_outmask;
2782 lcd->fifoctrl = panel->mode_fifoctrl;
2783 au_sync();
2784
2785 /* fixme: Check window settings to make sure still valid
2786 * for new geometry */
2787#if 0
2788 au1200_setlocation(fbdev, 0, win->w[0].xpos, win->w[0].ypos);
2789 au1200_setlocation(fbdev, 1, win->w[1].xpos, win->w[1].ypos);
2790 au1200_setlocation(fbdev, 2, win->w[2].xpos, win->w[2].ypos);
2791 au1200_setlocation(fbdev, 3, win->w[3].xpos, win->w[3].ypos);
2792#endif
2793 lcd->winenable = winenable;
2794
2795 /*
2796 * Re-enable screen now that it is configured
2797 */
2798 lcd->screen |= LCD_SCREEN_SEN;
2799 au_sync();
2800
2801 /* Call init of panel */
2802 if (panel->device_init != NULL) panel->device_init();
2803
2804 /* FIX!!!! not appropriate on panel change!!! Global setup/init */
2805 lcd->intenable = 0;
2806 lcd->intstatus = ~0;
2807 lcd->backcolor = win->mode_backcolor;
2808
2809 /* Setup Color Key - FIX!!! */
2810 lcd->colorkey = win->mode_colorkey;
2811 lcd->colorkeymsk = win->mode_colorkeymsk;
2812
2813 /* Setup HWCursor - FIX!!! Need to support this eventually */
2814 lcd->hwc.cursorctrl = 0;
2815 lcd->hwc.cursorpos = 0;
2816 lcd->hwc.cursorcolor0 = 0;
2817 lcd->hwc.cursorcolor1 = 0;
2818 lcd->hwc.cursorcolor2 = 0;
2819 lcd->hwc.cursorcolor3 = 0;
2820
2821
2822#if 0
2823#define D(X) printk("%25s: %08X\n", #X, X)
2824 D(lcd->screen);
2825 D(lcd->horztiming);
2826 D(lcd->verttiming);
2827 D(lcd->clkcontrol);
2828 D(lcd->pwmdiv);
2829 D(lcd->pwmhi);
2830 D(lcd->outmask);
2831 D(lcd->fifoctrl);
2832 D(lcd->window[0].winctrl0);
2833 D(lcd->window[0].winctrl1);
2834 D(lcd->window[0].winctrl2);
2835 D(lcd->window[0].winbuf0);
2836 D(lcd->window[0].winbuf1);
2837 D(lcd->window[0].winbufctrl);
2838 D(lcd->window[1].winctrl0);
2839 D(lcd->window[1].winctrl1);
2840 D(lcd->window[1].winctrl2);
2841 D(lcd->window[1].winbuf0);
2842 D(lcd->window[1].winbuf1);
2843 D(lcd->window[1].winbufctrl);
2844 D(lcd->window[2].winctrl0);
2845 D(lcd->window[2].winctrl1);
2846 D(lcd->window[2].winctrl2);
2847 D(lcd->window[2].winbuf0);
2848 D(lcd->window[2].winbuf1);
2849 D(lcd->window[2].winbufctrl);
2850 D(lcd->window[3].winctrl0);
2851 D(lcd->window[3].winctrl1);
2852 D(lcd->window[3].winctrl2);
2853 D(lcd->window[3].winbuf0);
2854 D(lcd->window[3].winbuf1);
2855 D(lcd->window[3].winbufctrl);
2856 D(lcd->winenable);
2857 D(lcd->intenable);
2858 D(lcd->intstatus);
2859 D(lcd->backcolor);
2860 D(lcd->winenable);
2861 D(lcd->colorkey);
2862 D(lcd->colorkeymsk);
2863 D(lcd->hwc.cursorctrl);
2864 D(lcd->hwc.cursorpos);
2865 D(lcd->hwc.cursorcolor0);
2866 D(lcd->hwc.cursorcolor1);
2867 D(lcd->hwc.cursorcolor2);
2868 D(lcd->hwc.cursorcolor3);
2869#endif
2870}
2871
2872static void au1200_setmode(struct au1200fb_device *fbdev)
2873{
2874 int plane = fbdev->plane;
2875 /* Window/plane setup */
2876 lcd->window[plane].winctrl1 = ( 0
2877 | LCD_WINCTRL1_PRI_N(plane)
2878 | win->w[plane].mode_winctrl1 /* FRM,CCO,PO,PIPE */
2879 ) ;
2880
2881 au1200_setlocation(fbdev, plane, win->w[plane].xpos, win->w[plane].ypos);
2882
2883 lcd->window[plane].winctrl2 = ( 0
2884 | LCD_WINCTRL2_CKMODE_00
2885 | LCD_WINCTRL2_DBM
2886 | LCD_WINCTRL2_BX_N( fbdev->fb_info.fix.line_length)
2887 | LCD_WINCTRL2_SCX_1
2888 | LCD_WINCTRL2_SCY_1
2889 ) ;
2890 lcd->winenable |= win->w[plane].mode_winenable;
2891 au_sync();
2892}
2893
2894
2895/* Inline helpers */
2896
2897/*#define panel_is_dual(panel) ((panel->mode_screen & LCD_SCREEN_PT) == LCD_SCREEN_PT_010)*/
2898/*#define panel_is_active(panel)((panel->mode_screen & LCD_SCREEN_PT) == LCD_SCREEN_PT_010)*/
2899
2900#define panel_is_color(panel) ((panel->mode_screen & LCD_SCREEN_PT) <= LCD_SCREEN_PT_CDSTN)
2901
2902/* Bitfields format supported by the controller. */
2903static struct fb_bitfield rgb_bitfields[][4] = {
2904 /* Red, Green, Blue, Transp */
2905 [LCD_WINCTRL1_FRM_16BPP655 >> 25] =
2906 { { 10, 6, 0 }, { 5, 5, 0 }, { 0, 5, 0 }, { 0, 0, 0 } },
2907
2908 [LCD_WINCTRL1_FRM_16BPP565 >> 25] =
2909 { { 11, 5, 0 }, { 5, 6, 0 }, { 0, 5, 0 }, { 0, 0, 0 } },
2910
2911 [LCD_WINCTRL1_FRM_16BPP556 >> 25] =
2912 { { 11, 5, 0 }, { 6, 5, 0 }, { 0, 6, 0 }, { 0, 0, 0 } },
2913
2914 [LCD_WINCTRL1_FRM_16BPPI1555 >> 25] =
2915 { { 10, 5, 0 }, { 5, 5, 0 }, { 0, 5, 0 }, { 0, 0, 0 } },
2916
2917 [LCD_WINCTRL1_FRM_16BPPI5551 >> 25] =
2918 { { 11, 5, 0 }, { 6, 5, 0 }, { 1, 5, 0 }, { 0, 0, 0 } },
2919
2920 [LCD_WINCTRL1_FRM_16BPPA1555 >> 25] =
2921 { { 10, 5, 0 }, { 5, 5, 0 }, { 0, 5, 0 }, { 15, 1, 0 } },
2922
2923 [LCD_WINCTRL1_FRM_16BPPA5551 >> 25] =
2924 { { 11, 5, 0 }, { 6, 5, 0 }, { 1, 5, 0 }, { 0, 1, 0 } },
2925
2926 [LCD_WINCTRL1_FRM_24BPP >> 25] =
2927 { { 16, 8, 0 }, { 8, 8, 0 }, { 0, 8, 0 }, { 0, 0, 0 } },
2928
2929 [LCD_WINCTRL1_FRM_32BPP >> 25] =
2930 { { 16, 8, 0 }, { 8, 8, 0 }, { 0, 8, 0 }, { 24, 0, 0 } },
2931};
2932
2933/*-------------------------------------------------------------------------*/
2934
2935/* Helpers */
2936
2937static void au1200fb_update_fbinfo(struct fb_info *fbi)
2938{
2939 /* FIX!!!! This also needs to take the window pixel format into account!!! */
2940
2941 /* Update var-dependent FB info */
2942 if (panel_is_color(panel)) {
2943 if (fbi->var.bits_per_pixel <= 8) {
2944 /* palettized */
2945 fbi->fix.visual = FB_VISUAL_PSEUDOCOLOR;
2946 fbi->fix.line_length = fbi->var.xres_virtual /
2947 (8/fbi->var.bits_per_pixel);
2948 } else {
2949 /* non-palettized */
2950 fbi->fix.visual = FB_VISUAL_TRUECOLOR;
2951 fbi->fix.line_length = fbi->var.xres_virtual * (fbi->var.bits_per_pixel / 8);
2952 }
2953 } else {
2954 /* mono FIX!!! mono 8 and 4 bits */
2955 fbi->fix.visual = FB_VISUAL_MONO10;
2956 fbi->fix.line_length = fbi->var.xres_virtual / 8;
2957 }
2958
2959 fbi->screen_size = fbi->fix.line_length * fbi->var.yres_virtual;
2960 print_dbg("line length: %d\n", fbi->fix.line_length);
2961 print_dbg("bits_per_pixel: %d\n", fbi->var.bits_per_pixel);
2962}
2963
2964/*-------------------------------------------------------------------------*/
2965
2966/* AU1200 framebuffer driver */
2967
2968/* fb_check_var
2969 * Validate var settings with hardware restrictions and modify it if necessary
2970 */
2971static int au1200fb_fb_check_var(struct fb_var_screeninfo *var,
2972 struct fb_info *fbi)
2973{
2974 struct au1200fb_device *fbdev = (struct au1200fb_device *)fbi;
2975 u32 pixclock;
2976 int screen_size, plane;
2977
2978 plane = fbdev->plane;
2979
2980 /* Make sure that the mode respect all LCD controller and
2981 * panel restrictions. */
2982 var->xres = win->w[plane].xres;
2983 var->yres = win->w[plane].yres;
2984
2985 /* No need for virtual resolution support */
2986 var->xres_virtual = var->xres;
2987 var->yres_virtual = var->yres;
2988
2989 var->bits_per_pixel = winbpp(win->w[plane].mode_winctrl1);
2990
2991 screen_size = var->xres_virtual * var->yres_virtual;
2992 if (var->bits_per_pixel > 8) screen_size *= (var->bits_per_pixel / 8);
2993 else screen_size /= (8/var->bits_per_pixel);
2994
2995 if (fbdev->fb_len < screen_size)
2996 return -EINVAL; /* Virtual screen is to big, abort */
2997
2998 /* FIX!!!! what are the implicaitons of ignoring this for windows ??? */
2999 /* The max LCD clock is fixed to 48MHz (value of AUX_CLK). The pixel
3000 * clock can only be obtain by dividing this value by an even integer.
3001 * Fallback to a slower pixel clock if necessary. */
3002 pixclock = max((u32)(PICOS2KHZ(var->pixclock) * 1000), fbi->monspecs.dclkmin);
3003 pixclock = min(pixclock, min(fbi->monspecs.dclkmax, (u32)AU1200_LCD_MAX_CLK/2));
3004
3005 if (AU1200_LCD_MAX_CLK % pixclock) {
3006 int diff = AU1200_LCD_MAX_CLK % pixclock;
3007 pixclock -= diff;
3008 }
3009
3010 var->pixclock = KHZ2PICOS(pixclock/1000);
3011#if 0
3012 if (!panel_is_active(panel)) {
3013 int pcd = AU1200_LCD_MAX_CLK / (pixclock * 2) - 1;
3014
3015 if (!panel_is_color(panel)
3016 && (panel->control_base & LCD_CONTROL_MPI) && (pcd < 3)) {
3017 /* STN 8bit mono panel support is up to 6MHz pixclock */
3018 var->pixclock = KHZ2PICOS(6000);
3019 } else if (!pcd) {
3020 /* Other STN panel support is up to 12MHz */
3021 var->pixclock = KHZ2PICOS(12000);
3022 }
3023 }
3024#endif
3025 /* Set bitfield accordingly */
3026 switch (var->bits_per_pixel) {
3027 case 16:
3028 {
3029 /* 16bpp True color.
3030 * These must be set to MATCH WINCTRL[FORM] */
3031 int idx;
3032 idx = (win->w[0].mode_winctrl1 & LCD_WINCTRL1_FRM) >> 25;
3033 var->red = rgb_bitfields[idx][0];
3034 var->green = rgb_bitfields[idx][1];
3035 var->blue = rgb_bitfields[idx][2];
3036 var->transp = rgb_bitfields[idx][3];
3037 break;
3038 }
3039
3040 case 32:
3041 {
3042 /* 32bpp True color.
3043 * These must be set to MATCH WINCTRL[FORM] */
3044 int idx;
3045 idx = (win->w[0].mode_winctrl1 & LCD_WINCTRL1_FRM) >> 25;
3046 var->red = rgb_bitfields[idx][0];
3047 var->green = rgb_bitfields[idx][1];
3048 var->blue = rgb_bitfields[idx][2];
3049 var->transp = rgb_bitfields[idx][3];
3050 break;
3051 }
3052 default:
3053 print_dbg("Unsupported depth %dbpp", var->bits_per_pixel);
3054 return -EINVAL;
3055 }
3056
3057 return 0;
3058}
3059
3060/* fb_set_par
3061 * Set hardware with var settings. This will enable the controller with a
3062 * specific mode, normally validated with the fb_check_var method
3063 */
3064static int au1200fb_fb_set_par(struct fb_info *fbi)
3065{
3066 struct au1200fb_device *fbdev = (struct au1200fb_device *)fbi;
3067
3068 au1200fb_update_fbinfo(fbi);
3069 au1200_setmode(fbdev);
3070
3071 return 0;
3072}
3073
3074/* fb_setcolreg
3075 * Set color in LCD palette.
3076 */
3077static int au1200fb_fb_setcolreg(unsigned regno, unsigned red, unsigned green,
3078 unsigned blue, unsigned transp, struct fb_info *fbi)
3079{
3080 volatile u32 *palette = lcd->palette;
3081 u32 value;
3082
3083 if (regno > (AU1200_LCD_NBR_PALETTE_ENTRIES - 1))
3084 return -EINVAL;
3085
3086 if (fbi->var.grayscale) {
3087 /* Convert color to grayscale */
3088 red = green = blue =
3089 (19595 * red + 38470 * green + 7471 * blue) >> 16;
3090 }
3091
3092 if (fbi->fix.visual == FB_VISUAL_TRUECOLOR) {
3093 /* Place color in the pseudopalette */
3094 if (regno > 16)
3095 return -EINVAL;
3096
3097 palette = (u32*) fbi->pseudo_palette;
3098
3099 red >>= (16 - fbi->var.red.length);
3100 green >>= (16 - fbi->var.green.length);
3101 blue >>= (16 - fbi->var.blue.length);
3102
3103 value = (red << fbi->var.red.offset) |
3104 (green << fbi->var.green.offset)|
3105 (blue << fbi->var.blue.offset);
3106 value &= 0xFFFF;
3107
3108 } else if (1 /*FIX!!! panel_is_active(fbdev->panel)*/) {
3109 /* COLOR TFT PALLETTIZED (use RGB 565) */
3110 value = (red & 0xF800)|((green >> 5) &
3111 0x07E0)|((blue >> 11) & 0x001F);
3112 value &= 0xFFFF;
3113
3114 } else if (0 /*panel_is_color(fbdev->panel)*/) {
3115 /* COLOR STN MODE */
3116 value = 0x1234;
3117 value &= 0xFFF;
3118 } else {
3119 /* MONOCHROME MODE */
3120 value = (green >> 12) & 0x000F;
3121 value &= 0xF;
3122 }
3123
3124 palette[regno] = value;
3125
3126 return 0;
3127}
3128
3129/* fb_blank
3130 * Blank the screen. Depending on the mode, the screen will be
3131 * activated with the backlight color, or desactivated
3132 */
3133static int au1200fb_fb_blank(int blank_mode, struct fb_info *fbi)
3134{
3135 /* Short-circuit screen blanking */
3136 if (noblanking)
3137 return 0;
3138
3139 switch (blank_mode) {
3140
3141 case FB_BLANK_UNBLANK:
3142 case FB_BLANK_NORMAL:
3143 /* printk("turn on panel\n"); */
3144 au1200_setpanel(panel);
3145 break;
3146 case FB_BLANK_VSYNC_SUSPEND:
3147 case FB_BLANK_HSYNC_SUSPEND:
3148 case FB_BLANK_POWERDOWN:
3149 /* printk("turn off panel\n"); */
3150 au1200_setpanel(NULL);
3151 break;
3152 default:
3153 break;
3154
3155 }
3156
3157 /* FB_BLANK_NORMAL is a soft blank */
3158 return (blank_mode == FB_BLANK_NORMAL) ? -EINVAL : 0;
3159}
3160
3161/* fb_mmap
3162 * Map video memory in user space. We don't use the generic fb_mmap
3163 * method mainly to allow the use of the TLB streaming flag (CCA=6)
3164 */
3165static int au1200fb_fb_mmap(struct fb_info *info, struct vm_area_struct *vma)
3166
3167{
3168 unsigned int len;
3169 unsigned long start=0, off;
3170 struct au1200fb_device *fbdev = (struct au1200fb_device *) info;
3171
3172#ifdef CONFIG_PM
3173 au1xxx_pm_access(LCD_pm_dev);
3174#endif
3175
3176 if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT)) {
3177 return -EINVAL;
3178 }
3179
3180 start = fbdev->fb_phys & PAGE_MASK;
3181 len = PAGE_ALIGN((start & ~PAGE_MASK) + fbdev->fb_len);
3182
3183 off = vma->vm_pgoff << PAGE_SHIFT;
3184
3185 if ((vma->vm_end - vma->vm_start + off) > len) {
3186 return -EINVAL;
3187 }
3188
3189 off += start;
3190 vma->vm_pgoff = off >> PAGE_SHIFT;
3191
3192 vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
3193 pgprot_val(vma->vm_page_prot) |= _CACHE_MASK; /* CCA=7 */
3194
3195 vma->vm_flags |= VM_IO;
3196
3197 return io_remap_pfn_range(vma, vma->vm_start, off >> PAGE_SHIFT,
3198 vma->vm_end - vma->vm_start,
3199 vma->vm_page_prot);
3200
3201 return 0;
3202}
3203
3204static void set_global(u_int cmd, struct au1200_lcd_global_regs_t *pdata)
3205{
3206
3207 unsigned int hi1, divider;
3208
3209 /* SCREEN_SIZE: user cannot reset size, must switch panel choice */
3210
3211 if (pdata->flags & SCREEN_BACKCOLOR)
3212 lcd->backcolor = pdata->backcolor;
3213
3214 if (pdata->flags & SCREEN_BRIGHTNESS) {
3215
3216 // limit brightness pwm duty to >= 30/1600
3217 if (pdata->brightness < 30) {
3218 pdata->brightness = 30;
3219 }
3220 divider = (lcd->pwmdiv & 0x3FFFF) + 1;
3221 hi1 = (lcd->pwmhi >> 16) + 1;
3222 hi1 = (((pdata->brightness & 0xFF)+1) * divider >> 8);
3223 lcd->pwmhi &= 0xFFFF;
3224 lcd->pwmhi |= (hi1 << 16);
3225 }
3226
3227 if (pdata->flags & SCREEN_COLORKEY)
3228 lcd->colorkey = pdata->colorkey;
3229
3230 if (pdata->flags & SCREEN_MASK)
3231 lcd->colorkeymsk = pdata->mask;
3232 au_sync();
3233}
3234
3235static void get_global(u_int cmd, struct au1200_lcd_global_regs_t *pdata)
3236{
3237 unsigned int hi1, divider;
3238
3239 pdata->xsize = ((lcd->screen & LCD_SCREEN_SX) >> 19) + 1;
3240 pdata->ysize = ((lcd->screen & LCD_SCREEN_SY) >> 8) + 1;
3241
3242 pdata->backcolor = lcd->backcolor;
3243 pdata->colorkey = lcd->colorkey;
3244 pdata->mask = lcd->colorkeymsk;
3245
3246 // brightness
3247 hi1 = (lcd->pwmhi >> 16) + 1;
3248 divider = (lcd->pwmdiv & 0x3FFFF) + 1;
3249 pdata->brightness = ((hi1 << 8) / divider) - 1;
3250 au_sync();
3251}
3252
3253static void set_window(unsigned int plane,
3254 struct au1200_lcd_window_regs_t *pdata)
3255{
3256 unsigned int val, bpp;
3257
3258 /* Window control register 0 */
3259 if (pdata->flags & WIN_POSITION) {
3260 val = lcd->window[plane].winctrl0 & ~(LCD_WINCTRL0_OX |
3261 LCD_WINCTRL0_OY);
3262 val |= ((pdata->xpos << 21) & LCD_WINCTRL0_OX);
3263 val |= ((pdata->ypos << 10) & LCD_WINCTRL0_OY);
3264 lcd->window[plane].winctrl0 = val;
3265 }
3266 if (pdata->flags & WIN_ALPHA_COLOR) {
3267 val = lcd->window[plane].winctrl0 & ~(LCD_WINCTRL0_A);
3268 val |= ((pdata->alpha_color << 2) & LCD_WINCTRL0_A);
3269 lcd->window[plane].winctrl0 = val;
3270 }
3271 if (pdata->flags & WIN_ALPHA_MODE) {
3272 val = lcd->window[plane].winctrl0 & ~(LCD_WINCTRL0_AEN);
3273 val |= ((pdata->alpha_mode << 1) & LCD_WINCTRL0_AEN);
3274 lcd->window[plane].winctrl0 = val;
3275 }
3276
3277 /* Window control register 1 */
3278 if (pdata->flags & WIN_PRIORITY) {
3279 val = lcd->window[plane].winctrl1 & ~(LCD_WINCTRL1_PRI);
3280 val |= ((pdata->priority << 30) & LCD_WINCTRL1_PRI);
3281 lcd->window[plane].winctrl1 = val;
3282 }
3283 if (pdata->flags & WIN_CHANNEL) {
3284 val = lcd->window[plane].winctrl1 & ~(LCD_WINCTRL1_PIPE);
3285 val |= ((pdata->channel << 29) & LCD_WINCTRL1_PIPE);
3286 lcd->window[plane].winctrl1 = val;
3287 }
3288 if (pdata->flags & WIN_BUFFER_FORMAT) {
3289 val = lcd->window[plane].winctrl1 & ~(LCD_WINCTRL1_FRM);
3290 val |= ((pdata->buffer_format << 25) & LCD_WINCTRL1_FRM);
3291 lcd->window[plane].winctrl1 = val;
3292 }
3293 if (pdata->flags & WIN_COLOR_ORDER) {
3294 val = lcd->window[plane].winctrl1 & ~(LCD_WINCTRL1_CCO);
3295 val |= ((pdata->color_order << 24) & LCD_WINCTRL1_CCO);
3296 lcd->window[plane].winctrl1 = val;
3297 }
3298 if (pdata->flags & WIN_PIXEL_ORDER) {
3299 val = lcd->window[plane].winctrl1 & ~(LCD_WINCTRL1_PO);
3300 val |= ((pdata->pixel_order << 22) & LCD_WINCTRL1_PO);
3301 lcd->window[plane].winctrl1 = val;
3302 }
3303 if (pdata->flags & WIN_SIZE) {
3304 val = lcd->window[plane].winctrl1 & ~(LCD_WINCTRL1_SZX |
3305 LCD_WINCTRL1_SZY);
3306 val |= (((pdata->xsize << 11) - 1) & LCD_WINCTRL1_SZX);
3307 val |= (((pdata->ysize) - 1) & LCD_WINCTRL1_SZY);
3308 lcd->window[plane].winctrl1 = val;
3309 /* program buffer line width */
3310 bpp = winbpp(val) / 8;
3311 val = lcd->window[plane].winctrl2 & ~(LCD_WINCTRL2_BX);
3312 val |= (((pdata->xsize * bpp) << 8) & LCD_WINCTRL2_BX);
3313 lcd->window[plane].winctrl2 = val;
3314 }
3315
3316 /* Window control register 2 */
3317 if (pdata->flags & WIN_COLORKEY_MODE) {
3318 val = lcd->window[plane].winctrl2 & ~(LCD_WINCTRL2_CKMODE);
3319 val |= ((pdata->colorkey_mode << 24) & LCD_WINCTRL2_CKMODE);
3320 lcd->window[plane].winctrl2 = val;
3321 }
3322 if (pdata->flags & WIN_DOUBLE_BUFFER_MODE) {
3323 val = lcd->window[plane].winctrl2 & ~(LCD_WINCTRL2_DBM);
3324 val |= ((pdata->double_buffer_mode << 23) & LCD_WINCTRL2_DBM);
3325 lcd->window[plane].winctrl2 = val;
3326 }
3327 if (pdata->flags & WIN_RAM_ARRAY_MODE) {
3328 val = lcd->window[plane].winctrl2 & ~(LCD_WINCTRL2_RAM);
3329 val |= ((pdata->ram_array_mode << 21) & LCD_WINCTRL2_RAM);
3330 lcd->window[plane].winctrl2 = val;
3331 }
3332
3333 /* Buffer line width programmed with WIN_SIZE */
3334
3335 if (pdata->flags & WIN_BUFFER_SCALE) {
3336 val = lcd->window[plane].winctrl2 & ~(LCD_WINCTRL2_SCX |
3337 LCD_WINCTRL2_SCY);
3338 val |= ((pdata->xsize << 11) & LCD_WINCTRL2_SCX);
3339 val |= ((pdata->ysize) & LCD_WINCTRL2_SCY);
3340 lcd->window[plane].winctrl2 = val;
3341 }
3342
3343 if (pdata->flags & WIN_ENABLE) {
3344 val = lcd->winenable;
3345 val &= ~(1<<plane);
3346 val |= (pdata->enable & 1) << plane;
3347 lcd->winenable = val;
3348 }
3349 au_sync();
3350}
3351
3352static void get_window(unsigned int plane,
3353 struct au1200_lcd_window_regs_t *pdata)
3354{
3355 /* Window control register 0 */
3356 pdata->xpos = (lcd->window[plane].winctrl0 & LCD_WINCTRL0_OX) >> 21;
3357 pdata->ypos = (lcd->window[plane].winctrl0 & LCD_WINCTRL0_OY) >> 10;
3358 pdata->alpha_color = (lcd->window[plane].winctrl0 & LCD_WINCTRL0_A) >> 2;
3359 pdata->alpha_mode = (lcd->window[plane].winctrl0 & LCD_WINCTRL0_AEN) >> 1;
3360
3361 /* Window control register 1 */
3362 pdata->priority = (lcd->window[plane].winctrl1& LCD_WINCTRL1_PRI) >> 30;
3363 pdata->channel = (lcd->window[plane].winctrl1 & LCD_WINCTRL1_PIPE) >> 29;
3364 pdata->buffer_format = (lcd->window[plane].winctrl1 & LCD_WINCTRL1_FRM) >> 25;
3365 pdata->color_order = (lcd->window[plane].winctrl1 & LCD_WINCTRL1_CCO) >> 24;
3366 pdata->pixel_order = (lcd->window[plane].winctrl1 & LCD_WINCTRL1_PO) >> 22;
3367 pdata->xsize = ((lcd->window[plane].winctrl1 & LCD_WINCTRL1_SZX) >> 11) + 1;
3368 pdata->ysize = (lcd->window[plane].winctrl1 & LCD_WINCTRL1_SZY) + 1;
3369
3370 /* Window control register 2 */
3371 pdata->colorkey_mode = (lcd->window[plane].winctrl2 & LCD_WINCTRL2_CKMODE) >> 24;
3372 pdata->double_buffer_mode = (lcd->window[plane].winctrl2 & LCD_WINCTRL2_DBM) >> 23;
3373 pdata->ram_array_mode = (lcd->window[plane].winctrl2 & LCD_WINCTRL2_RAM) >> 21;
3374
3375 pdata->enable = (lcd->winenable >> plane) & 1;
3376 au_sync();
3377}
3378
3379static int au1200fb_ioctl(struct fb_info *info, unsigned int cmd,
3380 unsigned long arg)
3381{
3382 int plane;
3383 int val;
3384
3385#ifdef CONFIG_PM
3386 au1xxx_pm_access(LCD_pm_dev);
3387#endif
3388
3389 plane = fbinfo2index(info);
3390 print_dbg("au1200fb: ioctl %d on plane %d\n", cmd, plane);
3391
3392 if (cmd == AU1200_LCD_FB_IOCTL) {
3393 struct au1200_lcd_iodata_t iodata;
3394
3395 if (copy_from_user(&iodata, (void __user *) arg, sizeof(iodata)))
3396 return -EFAULT;
3397
3398 print_dbg("FB IOCTL called\n");
3399
3400 switch (iodata.subcmd) {
3401 case AU1200_LCD_SET_SCREEN:
3402 print_dbg("AU1200_LCD_SET_SCREEN\n");
3403 set_global(cmd, &iodata.global);
3404 break;
3405
3406 case AU1200_LCD_GET_SCREEN:
3407 print_dbg("AU1200_LCD_GET_SCREEN\n");
3408 get_global(cmd, &iodata.global);
3409 break;
3410
3411 case AU1200_LCD_SET_WINDOW:
3412 print_dbg("AU1200_LCD_SET_WINDOW\n");
3413 set_window(plane, &iodata.window);
3414 break;
3415
3416 case AU1200_LCD_GET_WINDOW:
3417 print_dbg("AU1200_LCD_GET_WINDOW\n");
3418 get_window(plane, &iodata.window);
3419 break;
3420
3421 case AU1200_LCD_SET_PANEL:
3422 print_dbg("AU1200_LCD_SET_PANEL\n");
3423 if ((iodata.global.panel_choice >= 0) &&
3424 (iodata.global.panel_choice <
3425 NUM_PANELS))
3426 {
3427 struct panel_settings *newpanel;
3428 panel_index = iodata.global.panel_choice;
3429 newpanel = &known_lcd_panels[panel_index];
3430 au1200_setpanel(newpanel);
3431 }
3432 break;
3433
3434 case AU1200_LCD_GET_PANEL:
3435 print_dbg("AU1200_LCD_GET_PANEL\n");
3436 iodata.global.panel_choice = panel_index;
3437 break;
3438
3439 default:
3440 return -EINVAL;
3441 }
3442
3443 val = copy_to_user((void __user *) arg, &iodata, sizeof(iodata));
3444 if (val) {
3445 print_dbg("error: could not copy %d bytes\n", val);
3446 return -EFAULT;
3447 }
3448 }
3449
3450 return 0;
3451}
3452
3453
3454static struct fb_ops au1200fb_fb_ops = {
3455 .owner = THIS_MODULE,
3456 .fb_check_var = au1200fb_fb_check_var,
3457 .fb_set_par = au1200fb_fb_set_par,
3458 .fb_setcolreg = au1200fb_fb_setcolreg,
3459 .fb_blank = au1200fb_fb_blank,
3460 .fb_fillrect = cfb_fillrect,
3461 .fb_copyarea = cfb_copyarea,
3462 .fb_imageblit = cfb_imageblit,
3463 .fb_sync = NULL,
3464 .fb_ioctl = au1200fb_ioctl,
3465 .fb_mmap = au1200fb_fb_mmap,
3466};
3467
3468/*-------------------------------------------------------------------------*/
3469
3470static irqreturn_t au1200fb_handle_irq(int irq, void* dev_id, struct pt_regs *regs)
3471{
3472 /* Nothing to do for now, just clear any pending interrupt */
3473 lcd->intstatus = lcd->intstatus;
3474 au_sync();
3475
3476 return IRQ_HANDLED;
3477}
3478
3479/*-------------------------------------------------------------------------*/
3480
3481/* AU1200 LCD device probe helpers */
3482
3483static int au1200fb_init_fbinfo(struct au1200fb_device *fbdev)
3484{
3485 struct fb_info *fbi = &fbdev->fb_info;
3486 int bpp;
3487
3488 memset(fbi, 0, sizeof(struct fb_info));
3489 fbi->fbops = &au1200fb_fb_ops;
3490
3491 bpp = winbpp(win->w[fbdev->plane].mode_winctrl1);
3492
3493 /* Copy monitor specs from panel data */
3494 /* fixme: we're setting up LCD controller windows, so these dont give a
3495 damn as to what the monitor specs are (the panel itself does, but that
3496 isnt done here...so maybe need a generic catchall monitor setting??? */
3497 memcpy(&fbi->monspecs, &panel->monspecs, sizeof(struct fb_monspecs));
3498
3499 /* We first try the user mode passed in argument. If that failed,
3500 * or if no one has been specified, we default to the first mode of the
3501 * panel list. Note that after this call, var data will be set */
3502 if (!fb_find_mode(&fbi->var,
3503 fbi,
3504 NULL, /* drv_info.opt_mode, */
3505 fbi->monspecs.modedb,
3506 fbi->monspecs.modedb_len,
3507 fbi->monspecs.modedb,
3508 bpp)) {
3509
3510 print_err("Cannot find valid mode for panel %s", panel->name);
3511 return -EFAULT;
3512 }
3513
3514 fbi->pseudo_palette = kmalloc(sizeof(u32) * 16, GFP_KERNEL);
3515 if (!fbi->pseudo_palette) {
3516 return -ENOMEM;
3517 }
3518 memset(fbi->pseudo_palette, 0, sizeof(u32) * 16);
3519
3520 if (fb_alloc_cmap(&fbi->cmap, AU1200_LCD_NBR_PALETTE_ENTRIES, 0) < 0) {
3521 print_err("Fail to allocate colormap (%d entries)",
3522 AU1200_LCD_NBR_PALETTE_ENTRIES);
3523 kfree(fbi->pseudo_palette);
3524 return -EFAULT;
3525 }
3526
3527 strncpy(fbi->fix.id, "AU1200", sizeof(fbi->fix.id));
3528 fbi->fix.smem_start = fbdev->fb_phys;
3529 fbi->fix.smem_len = fbdev->fb_len;
3530 fbi->fix.type = FB_TYPE_PACKED_PIXELS;
3531 fbi->fix.xpanstep = 0;
3532 fbi->fix.ypanstep = 0;
3533 fbi->fix.mmio_start = 0;
3534 fbi->fix.mmio_len = 0;
3535 fbi->fix.accel = FB_ACCEL_NONE;
3536
3537 fbi->screen_base = (char __iomem *) fbdev->fb_mem;
3538
3539 au1200fb_update_fbinfo(fbi);
3540
3541 return 0;
3542}
3543
3544/*-------------------------------------------------------------------------*/
3545
3546/* AU1200 LCD controller device driver */
3547
3548static int au1200fb_drv_probe(struct device *dev)
3549{
3550 struct au1200fb_device *fbdev;
3551 unsigned long page;
3552 int bpp, plane, ret;
3553
3554 if (!dev)
3555 return -EINVAL;
3556
3557 for (plane = 0; plane < CONFIG_FB_AU1200_DEVS; ++plane) {
3558 bpp = winbpp(win->w[plane].mode_winctrl1);
3559 if (win->w[plane].xres == 0)
3560 win->w[plane].xres = panel->Xres;
3561 if (win->w[plane].yres == 0)
3562 win->w[plane].yres = panel->Yres;
3563
3564 fbdev = &_au1200fb_devices[plane];
3565 memset(fbdev, 0, sizeof(struct au1200fb_device));
3566 fbdev->plane = plane;
3567
3568 /* Allocate the framebuffer to the maximum screen size */
3569 fbdev->fb_len = (win->w[plane].xres * win->w[plane].yres * bpp) / 8;
3570
3571 fbdev->fb_mem = dma_alloc_noncoherent(dev,
3572 PAGE_ALIGN(fbdev->fb_len),
3573 &fbdev->fb_phys, GFP_KERNEL);
3574 if (!fbdev->fb_mem) {
3575 print_err("fail to allocate frambuffer (size: %dK))",
3576 fbdev->fb_len / 1024);
3577 return -ENOMEM;
3578 }
3579
3580 /*
3581 * Set page reserved so that mmap will work. This is necessary
3582 * since we'll be remapping normal memory.
3583 */
3584 for (page = (unsigned long)fbdev->fb_phys;
3585 page < PAGE_ALIGN((unsigned long)fbdev->fb_phys +
3586 fbdev->fb_len);
3587 page += PAGE_SIZE) {
3588 SetPageReserved(pfn_to_page(page >> PAGE_SHIFT)); /* LCD DMA is NOT coherent on Au1200 */
3589 }
3590 print_dbg("Framebuffer memory map at %p", fbdev->fb_mem);
3591 print_dbg("phys=0x%08x, size=%dK", fbdev->fb_phys, fbdev->fb_len / 1024);
3592
3593 /* Init FB data */
3594 if ((ret = au1200fb_init_fbinfo(fbdev)) < 0)
3595 goto failed;
3596
3597 /* Register new framebuffer */
3598 if ((ret = register_framebuffer(&fbdev->fb_info)) < 0) {
3599 print_err("cannot register new framebuffer");
3600 goto failed;
3601 }
3602
3603 au1200fb_fb_set_par(&fbdev->fb_info);
3604
3605#if !defined(CONFIG_FRAMEBUFFER_CONSOLE) && defined(CONFIG_LOGO)
3606 if (plane == 0)
3607 if (fb_prepare_logo(&fbdev->fb_info, FB_ROTATE_UR)) {
3608 /* Start display and show logo on boot */
3609 fb_set_cmap(&fbdev->fb_info.cmap,
3610 &fbdev->fb_info);
3611
3612 fb_show_logo(&fbdev->fb_info, FB_ROTATE_UR);
3613 }
3614#endif
3615 }
3616
3617 /* Now hook interrupt too */
3618 if ((ret = request_irq(AU1200_LCD_INT, au1200fb_handle_irq,
3619 SA_INTERRUPT | SA_SHIRQ, "lcd", (void *)dev)) < 0) {
3620 print_err("fail to request interrupt line %d (err: %d)",
3621 AU1200_LCD_INT, ret);
3622 goto failed;
3623 }
3624
3625 return 0;
3626
3627failed:
3628 /* NOTE: This only does the current plane/window that failed; others are still active */
3629 if (fbdev->fb_mem)
3630 dma_free_noncoherent(dev, PAGE_ALIGN(fbdev->fb_len),
3631 fbdev->fb_mem, fbdev->fb_phys);
3632 if (fbdev->fb_info.cmap.len != 0)
3633 fb_dealloc_cmap(&fbdev->fb_info.cmap);
3634 if (fbdev->fb_info.pseudo_palette)
3635 kfree(fbdev->fb_info.pseudo_palette);
3636 if (plane == 0)
3637 free_irq(AU1200_LCD_INT, (void*)dev);
3638 return ret;
3639}
3640
3641static int au1200fb_drv_remove(struct device *dev)
3642{
3643 struct au1200fb_device *fbdev;
3644 int plane;
3645
3646 if (!dev)
3647 return -ENODEV;
3648
3649 /* Turn off the panel */
3650 au1200_setpanel(NULL);
3651
3652 for (plane = 0; plane < CONFIG_FB_AU1200_DEVS; ++plane)
3653 {
3654 fbdev = &_au1200fb_devices[plane];
3655
3656 /* Clean up all probe data */
3657 unregister_framebuffer(&fbdev->fb_info);
3658 if (fbdev->fb_mem)
3659 dma_free_noncoherent(dev, PAGE_ALIGN(fbdev->fb_len),
3660 fbdev->fb_mem, fbdev->fb_phys);
3661 if (fbdev->fb_info.cmap.len != 0)
3662 fb_dealloc_cmap(&fbdev->fb_info.cmap);
3663 if (fbdev->fb_info.pseudo_palette)
3664 kfree(fbdev->fb_info.pseudo_palette);
3665 }
3666
3667 free_irq(AU1200_LCD_INT, (void *)dev);
3668
3669 return 0;
3670}
3671
3672#ifdef CONFIG_PM
3673static int au1200fb_drv_suspend(struct device *dev, u32 state, u32 level)
3674{
3675 /* TODO */
3676 return 0;
3677}
3678
3679static int au1200fb_drv_resume(struct device *dev, u32 level)
3680{
3681 /* TODO */
3682 return 0;
3683}
3684#endif /* CONFIG_PM */
3685
3686static struct device_driver au1200fb_driver = {
3687 .name = "au1200-lcd",
3688 .bus = &platform_bus_type,
3689 .probe = au1200fb_drv_probe,
3690 .remove = au1200fb_drv_remove,
3691#ifdef CONFIG_PM
3692 .suspend = au1200fb_drv_suspend,
3693 .resume = au1200fb_drv_resume,
3694#endif
3695};
3696
3697/*-------------------------------------------------------------------------*/
3698
3699/* Kernel driver */
3700
3701static void au1200fb_setup(void)
3702{
3703 char* options = NULL;
3704 char* this_opt;
3705 int num_panels = ARRAY_SIZE(known_lcd_panels);
3706 int panel_idx = -1;
3707
3708 fb_get_options(DRIVER_NAME, &options);
3709
3710 if (options) {
3711 while ((this_opt = strsep(&options,",")) != NULL) {
3712 /* Panel option - can be panel name,
3713 * "bs" for board-switch, or number/index */
3714 if (!strncmp(this_opt, "panel:", 6)) {
3715 int i;
3716 long int li;
3717 char *endptr;
3718 this_opt += 6;
3719 /* First check for index, which allows
3720 * to short circuit this mess */
3721 li = simple_strtol(this_opt, &endptr, 0);
3722 if (*endptr == '\0') {
3723 panel_idx = (int)li;
3724 }
3725 else if (strcmp(this_opt, "bs") == 0) {
3726 extern int board_au1200fb_panel(void);
3727 panel_idx = board_au1200fb_panel();
3728 }
3729
3730 else
3731 for (i = 0; i < num_panels; i++) {
3732 if (!strcmp(this_opt, known_lcd_panels[i].name)) {
3733 panel_idx = i;
3734 break;
3735 }
3736 }
3737
3738 if ((panel_idx < 0) || (panel_idx >= num_panels)) {
3739 print_warn("Panel %s not supported!", this_opt);
3740 }
3741 else
3742 panel_index = panel_idx;
3743 }
3744
3745 else if (strncmp(this_opt, "nohwcursor", 10) == 0) {
3746 nohwcursor = 1;
3747 }
3748
3749 /* Unsupported option */
3750 else {
3751 print_warn("Unsupported option \"%s\"", this_opt);
3752 }
3753 }
3754 }
3755}
3756
3757#ifdef CONFIG_PM
3758static int au1200fb_pm_callback(au1xxx_power_dev_t *dev,
3759 au1xxx_request_t request, void *data) {
3760 int retval = -1;
3761 unsigned int d = 0;
3762 unsigned int brightness = 0;
3763
3764 if (request == AU1XXX_PM_SLEEP) {
3765 board_au1200fb_panel_shutdown();
3766 }
3767 else if (request == AU1XXX_PM_WAKEUP) {
3768 if(dev->prev_state == SLEEP_STATE)
3769 {
3770 int plane;
3771 au1200_setpanel(panel);
3772 for (plane = 0; plane < CONFIG_FB_AU1200_DEVS; ++plane) {
3773 struct au1200fb_device *fbdev;
3774 fbdev = &_au1200fb_devices[plane];
3775 au1200fb_fb_set_par(&fbdev->fb_info);
3776 }
3777 }
3778
3779 d = *((unsigned int*)data);
3780 if(d <=10) brightness = 26;
3781 else if(d<=20) brightness = 51;
3782 else if(d<=30) brightness = 77;
3783 else if(d<=40) brightness = 102;
3784 else if(d<=50) brightness = 128;
3785 else if(d<=60) brightness = 153;
3786 else if(d<=70) brightness = 179;
3787 else if(d<=80) brightness = 204;
3788 else if(d<=90) brightness = 230;
3789 else brightness = 255;
3790 set_brightness(brightness);
3791 } else if (request == AU1XXX_PM_GETSTATUS) {
3792 return dev->cur_state;
3793 } else if (request == AU1XXX_PM_ACCESS) {
3794 if (dev->cur_state != SLEEP_STATE)
3795 return retval;
3796 else {
3797 au1200_setpanel(panel);
3798 }
3799 } else if (request == AU1XXX_PM_IDLE) {
3800 } else if (request == AU1XXX_PM_CLEANUP) {
3801 }
3802
3803 return retval;
3804}
3805#endif
3806
3807static int __init au1200fb_init(void)
3808{
3809 print_info("" DRIVER_DESC "");
3810
3811 /* Setup driver with options */
3812 au1200fb_setup();
3813
3814 /* Point to the panel selected */
3815 panel = &known_lcd_panels[panel_index];
3816 win = &windows[window_index];
3817
3818 printk(DRIVER_NAME ": Panel %d %s\n", panel_index, panel->name);
3819 printk(DRIVER_NAME ": Win %d %s\n", window_index, win->name);
3820
3821 /* Kickstart the panel, the framebuffers/windows come soon enough */
3822 au1200_setpanel(panel);
3823
3824 #ifdef CONFIG_PM
3825 LCD_pm_dev = new_au1xxx_power_device("LCD", &au1200fb_pm_callback, NULL);
3826 if ( LCD_pm_dev == NULL)
3827 printk(KERN_INFO "Unable to create a power management device entry for the au1200fb.\n");
3828 else
3829 printk(KERN_INFO "Power management device entry for the au1200fb loaded.\n");
3830 #endif
3831
3832 return driver_register(&au1200fb_driver);
3833}
3834
3835static void __exit au1200fb_cleanup(void)
3836{
3837 driver_unregister(&au1200fb_driver);
3838}
3839
3840module_init(au1200fb_init);
3841module_exit(au1200fb_cleanup);
3842
3843MODULE_DESCRIPTION(DRIVER_DESC);
3844MODULE_LICENSE("GPL");
diff --git a/fs/stat.c b/fs/stat.c
index 9948cc1685a4..0f282face322 100644
--- a/fs/stat.c
+++ b/fs/stat.c
@@ -261,7 +261,7 @@ asmlinkage long sys_newlstat(char __user *filename, struct stat __user *statbuf)
261 return error; 261 return error;
262} 262}
263 263
264#ifndef __ARCH_WANT_STAT64 264#if !defined(__ARCH_WANT_STAT64) || defined(__ARCH_WANT_SYS_NEWFSTATAT)
265asmlinkage long sys_newfstatat(int dfd, char __user *filename, 265asmlinkage long sys_newfstatat(int dfd, char __user *filename,
266 struct stat __user *statbuf, int flag) 266 struct stat __user *statbuf, int flag)
267{ 267{
diff --git a/include/asm-i386/i387.h b/include/asm-i386/i387.h
index 7b1f01191e70..bc1d6edae1ed 100644
--- a/include/asm-i386/i387.h
+++ b/include/asm-i386/i387.h
@@ -58,13 +58,13 @@ static inline void __save_init_fpu( struct task_struct *tsk )
58 alternative_input( 58 alternative_input(
59 "fnsave %[fx] ;fwait;" GENERIC_NOP8 GENERIC_NOP4, 59 "fnsave %[fx] ;fwait;" GENERIC_NOP8 GENERIC_NOP4,
60 "fxsave %[fx]\n" 60 "fxsave %[fx]\n"
61 "bt $7,%[fsw] ; jc 1f ; fnclex\n1:", 61 "bt $7,%[fsw] ; jnc 1f ; fnclex\n1:",
62 X86_FEATURE_FXSR, 62 X86_FEATURE_FXSR,
63 [fx] "m" (tsk->thread.i387.fxsave), 63 [fx] "m" (tsk->thread.i387.fxsave),
64 [fsw] "m" (tsk->thread.i387.fxsave.swd) : "memory"); 64 [fsw] "m" (tsk->thread.i387.fxsave.swd) : "memory");
65 /* AMD K7/K8 CPUs don't save/restore FDP/FIP/FOP unless an exception 65 /* AMD K7/K8 CPUs don't save/restore FDP/FIP/FOP unless an exception
66 is pending. Clear the x87 state here by setting it to fixed 66 is pending. Clear the x87 state here by setting it to fixed
67 values. __per_cpu_offset[0] is a random variable that should be in L1 */ 67 values. safe_address is a random variable that should be in L1 */
68 alternative_input( 68 alternative_input(
69 GENERIC_NOP8 GENERIC_NOP2, 69 GENERIC_NOP8 GENERIC_NOP2,
70 "emms\n\t" /* clear stack tags */ 70 "emms\n\t" /* clear stack tags */
diff --git a/include/asm-powerpc/cputable.h b/include/asm-powerpc/cputable.h
index 4321483cce51..9fcf0162d859 100644
--- a/include/asm-powerpc/cputable.h
+++ b/include/asm-powerpc/cputable.h
@@ -22,6 +22,7 @@
22#define PPC_FEATURE_BOOKE 0x00008000 22#define PPC_FEATURE_BOOKE 0x00008000
23#define PPC_FEATURE_SMT 0x00004000 23#define PPC_FEATURE_SMT 0x00004000
24#define PPC_FEATURE_ICACHE_SNOOP 0x00002000 24#define PPC_FEATURE_ICACHE_SNOOP 0x00002000
25#define PPC_FEATURE_ARCH_2_05 0x00001000
25 26
26#ifdef __KERNEL__ 27#ifdef __KERNEL__
27#ifndef __ASSEMBLY__ 28#ifndef __ASSEMBLY__
@@ -320,6 +321,11 @@ extern void do_cpu_ftr_fixups(unsigned long offset);
320 CPU_FTR_MMCRA | CPU_FTR_SMT | \ 321 CPU_FTR_MMCRA | CPU_FTR_SMT | \
321 CPU_FTR_COHERENT_ICACHE | CPU_FTR_LOCKLESS_TLBIE | \ 322 CPU_FTR_COHERENT_ICACHE | CPU_FTR_LOCKLESS_TLBIE | \
322 CPU_FTR_MMCRA_SIHV | CPU_FTR_PURR) 323 CPU_FTR_MMCRA_SIHV | CPU_FTR_PURR)
324#define CPU_FTRS_POWER6 (CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | \
325 CPU_FTR_HPTE_TABLE | CPU_FTR_PPCAS_ARCH_V2 | \
326 CPU_FTR_MMCRA | CPU_FTR_SMT | \
327 CPU_FTR_COHERENT_ICACHE | CPU_FTR_LOCKLESS_TLBIE | \
328 CPU_FTR_PURR | CPU_FTR_CI_LARGE_PAGE)
323#define CPU_FTRS_CELL (CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | \ 329#define CPU_FTRS_CELL (CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | \
324 CPU_FTR_HPTE_TABLE | CPU_FTR_PPCAS_ARCH_V2 | \ 330 CPU_FTR_HPTE_TABLE | CPU_FTR_PPCAS_ARCH_V2 | \
325 CPU_FTR_ALTIVEC_COMP | CPU_FTR_MMCRA | CPU_FTR_SMT | \ 331 CPU_FTR_ALTIVEC_COMP | CPU_FTR_MMCRA | CPU_FTR_SMT | \
@@ -331,8 +337,8 @@ extern void do_cpu_ftr_fixups(unsigned long offset);
331#ifdef __powerpc64__ 337#ifdef __powerpc64__
332#define CPU_FTRS_POSSIBLE \ 338#define CPU_FTRS_POSSIBLE \
333 (CPU_FTRS_POWER3 | CPU_FTRS_RS64 | CPU_FTRS_POWER4 | \ 339 (CPU_FTRS_POWER3 | CPU_FTRS_RS64 | CPU_FTRS_POWER4 | \
334 CPU_FTRS_PPC970 | CPU_FTRS_POWER5 | CPU_FTRS_CELL | \ 340 CPU_FTRS_PPC970 | CPU_FTRS_POWER5 | CPU_FTRS_POWER6 | \
335 CPU_FTR_CI_LARGE_PAGE) 341 CPU_FTRS_CELL | CPU_FTR_CI_LARGE_PAGE)
336#else 342#else
337enum { 343enum {
338 CPU_FTRS_POSSIBLE = 344 CPU_FTRS_POSSIBLE =
@@ -376,8 +382,8 @@ enum {
376#ifdef __powerpc64__ 382#ifdef __powerpc64__
377#define CPU_FTRS_ALWAYS \ 383#define CPU_FTRS_ALWAYS \
378 (CPU_FTRS_POWER3 & CPU_FTRS_RS64 & CPU_FTRS_POWER4 & \ 384 (CPU_FTRS_POWER3 & CPU_FTRS_RS64 & CPU_FTRS_POWER4 & \
379 CPU_FTRS_PPC970 & CPU_FTRS_POWER5 & CPU_FTRS_CELL & \ 385 CPU_FTRS_PPC970 & CPU_FTRS_POWER5 & CPU_FTRS_POWER6 & \
380 CPU_FTRS_POSSIBLE) 386 CPU_FTRS_CELL & CPU_FTRS_POSSIBLE)
381#else 387#else
382enum { 388enum {
383 CPU_FTRS_ALWAYS = 389 CPU_FTRS_ALWAYS =
diff --git a/include/asm-powerpc/io.h b/include/asm-powerpc/io.h
index 68efbea379c9..f1c2469b8844 100644
--- a/include/asm-powerpc/io.h
+++ b/include/asm-powerpc/io.h
@@ -9,6 +9,9 @@
9 * 2 of the License, or (at your option) any later version. 9 * 2 of the License, or (at your option) any later version.
10 */ 10 */
11 11
12/* Check of existence of legacy devices */
13extern int check_legacy_ioport(unsigned long base_port);
14
12#ifndef CONFIG_PPC64 15#ifndef CONFIG_PPC64
13#include <asm-ppc/io.h> 16#include <asm-ppc/io.h>
14#else 17#else
@@ -437,9 +440,6 @@ out:
437#define dma_cache_wback(_start,_size) do { } while (0) 440#define dma_cache_wback(_start,_size) do { } while (0)
438#define dma_cache_wback_inv(_start,_size) do { } while (0) 441#define dma_cache_wback_inv(_start,_size) do { } while (0)
439 442
440/* Check of existence of legacy devices */
441extern int check_legacy_ioport(unsigned long base_port);
442
443 443
444/* 444/*
445 * Convert a physical pointer to a virtual kernel pointer for /dev/mem 445 * Convert a physical pointer to a virtual kernel pointer for /dev/mem
diff --git a/include/asm-powerpc/page_64.h b/include/asm-powerpc/page_64.h
index 3fb061bab9ec..eab779c21995 100644
--- a/include/asm-powerpc/page_64.h
+++ b/include/asm-powerpc/page_64.h
@@ -101,6 +101,7 @@ extern unsigned int HPAGE_SHIFT;
101 - (1U << GET_HTLB_AREA(addr))) & 0xffff) 101 - (1U << GET_HTLB_AREA(addr))) & 0xffff)
102 102
103#define ARCH_HAS_HUGEPAGE_ONLY_RANGE 103#define ARCH_HAS_HUGEPAGE_ONLY_RANGE
104#define ARCH_HAS_HUGETLB_FREE_PGD_RANGE
104#define ARCH_HAS_PREPARE_HUGEPAGE_RANGE 105#define ARCH_HAS_PREPARE_HUGEPAGE_RANGE
105#define ARCH_HAS_SETCLEAR_HUGE_PTE 106#define ARCH_HAS_SETCLEAR_HUGE_PTE
106 107
diff --git a/include/asm-powerpc/pgalloc.h b/include/asm-powerpc/pgalloc.h
index a00ee002cd11..9f0917c68659 100644
--- a/include/asm-powerpc/pgalloc.h
+++ b/include/asm-powerpc/pgalloc.h
@@ -17,11 +17,13 @@ extern kmem_cache_t *pgtable_cache[];
17#define PTE_CACHE_NUM 0 17#define PTE_CACHE_NUM 0
18#define PMD_CACHE_NUM 1 18#define PMD_CACHE_NUM 1
19#define PGD_CACHE_NUM 2 19#define PGD_CACHE_NUM 2
20#define HUGEPTE_CACHE_NUM 3
20#else 21#else
21#define PTE_CACHE_NUM 0 22#define PTE_CACHE_NUM 0
22#define PMD_CACHE_NUM 1 23#define PMD_CACHE_NUM 1
23#define PUD_CACHE_NUM 1 24#define PUD_CACHE_NUM 1
24#define PGD_CACHE_NUM 0 25#define PGD_CACHE_NUM 0
26#define HUGEPTE_CACHE_NUM 2
25#endif 27#endif
26 28
27/* 29/*
diff --git a/include/asm-powerpc/unistd.h b/include/asm-powerpc/unistd.h
index bd3c6b6cc50e..9e2c9e1c1239 100644
--- a/include/asm-powerpc/unistd.h
+++ b/include/asm-powerpc/unistd.h
@@ -304,10 +304,27 @@
304#define __NR_splice 283 304#define __NR_splice 283
305#define __NR_tee 284 305#define __NR_tee 284
306#define __NR_vmsplice 285 306#define __NR_vmsplice 285
307#define __NR_openat 286
308#define __NR_mkdirat 287
309#define __NR_mknodat 288
310#define __NR_fchownat 289
311#define __NR_futimesat 290
312#ifdef __powerpc64__
313#define __NR_newfstatat 291
314#else
315#define __NR_fstatat64 291
316#endif
317#define __NR_unlinkat 292
318#define __NR_renameat 293
319#define __NR_linkat 294
320#define __NR_symlinkat 295
321#define __NR_readlinkat 296
322#define __NR_fchmodat 297
323#define __NR_faccessat 298
307 324
308#ifdef __KERNEL__ 325#ifdef __KERNEL__
309 326
310#define __NR_syscalls 286 327#define __NR_syscalls 299
311 328
312#define __NR__exit __NR_exit 329#define __NR__exit __NR_exit
313#define NR_syscalls __NR_syscalls 330#define NR_syscalls __NR_syscalls
@@ -456,6 +473,7 @@ type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5, type6 arg6
456#ifdef CONFIG_PPC64 473#ifdef CONFIG_PPC64
457#define __ARCH_WANT_COMPAT_SYS_TIME 474#define __ARCH_WANT_COMPAT_SYS_TIME
458#define __ARCH_WANT_COMPAT_SYS_RT_SIGSUSPEND 475#define __ARCH_WANT_COMPAT_SYS_RT_SIGSUSPEND
476#define __ARCH_WANT_SYS_NEWFSTATAT
459#endif 477#endif
460 478
461/* 479/*
diff --git a/include/asm-ppc/ppc_sys.h b/include/asm-ppc/ppc_sys.h
index 4b94f7059ebe..40f197af6508 100644
--- a/include/asm-ppc/ppc_sys.h
+++ b/include/asm-ppc/ppc_sys.h
@@ -39,6 +39,8 @@
39#error "need definition of ppc_sys_devices" 39#error "need definition of ppc_sys_devices"
40#endif 40#endif
41 41
42#define PPC_SYS_IORESOURCE_FIXUPPED 0x00000001
43
42struct ppc_sys_spec { 44struct ppc_sys_spec {
43 /* PPC sys is matched via (ID & mask) == value, id could be 45 /* PPC sys is matched via (ID & mask) == value, id could be
44 * PVR, SVR, IMMR, * etc. */ 46 * PVR, SVR, IMMR, * etc. */
diff --git a/include/asm-ppc/reg_booke.h b/include/asm-ppc/reg_booke.h
index 00ad9c754c78..4944c0fb8bea 100644
--- a/include/asm-ppc/reg_booke.h
+++ b/include/asm-ppc/reg_booke.h
@@ -237,6 +237,7 @@ do { \
237#endif 237#endif
238 238
239/* Bit definitions for CCR1. */ 239/* Bit definitions for CCR1. */
240#define CCR1_DPC 0x00000100 /* Disable L1 I-Cache/D-Cache parity checking */
240#define CCR1_TCS 0x00000080 /* Timer Clock Select */ 241#define CCR1_TCS 0x00000080 /* Timer Clock Select */
241 242
242/* Bit definitions for the MCSR. */ 243/* Bit definitions for the MCSR. */
diff --git a/sound/ppc/toonie.c b/sound/ppc/toonie.c
index 4e595172e423..1ac7c8552f50 100644
--- a/sound/ppc/toonie.c
+++ b/sound/ppc/toonie.c
@@ -335,7 +335,7 @@ static void toonie_cleanup(struct snd_pmac *chip)
335 chip->mixer_data = NULL; 335 chip->mixer_data = NULL;
336} 336}
337 337
338int snd_pmac_toonie_init(struct snd_pmac *chip) 338int __init snd_pmac_toonie_init(struct snd_pmac *chip)
339{ 339{
340 struct pmac_toonie *mix; 340 struct pmac_toonie *mix;
341 341