aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/acpi/sleep/main.c42
-rw-r--r--drivers/acpi/system.c1
-rw-r--r--drivers/atm/fore200e.c15
-rw-r--r--drivers/auxdisplay/cfag12864b.c13
-rw-r--r--drivers/base/memory.c19
-rw-r--r--drivers/char/Kconfig7
-rw-r--r--drivers/char/Makefile1
-rw-r--r--drivers/char/lcd.c516
-rw-r--r--drivers/char/lcd.h154
-rw-r--r--drivers/char/mem.c5
-rw-r--r--drivers/char/mspec.c23
-rw-r--r--drivers/char/random.c1
-rw-r--r--drivers/char/rtc.c19
-rw-r--r--drivers/char/stallion.c1
-rw-r--r--drivers/char/tty_io.c13
-rw-r--r--drivers/char/vt.c6
-rw-r--r--drivers/ieee1394/iso.c1
-rw-r--r--drivers/isdn/gigaset/asyncdata.c3
-rw-r--r--drivers/isdn/gigaset/bas-gigaset.c12
-rw-r--r--drivers/isdn/gigaset/common.c2
-rw-r--r--drivers/isdn/gigaset/gigaset.h3
-rw-r--r--drivers/isdn/gigaset/i4l.c56
-rw-r--r--drivers/isdn/gigaset/interface.c25
-rw-r--r--drivers/isdn/gigaset/usb-gigaset.c7
-rw-r--r--drivers/leds/Kconfig16
-rw-r--r--drivers/leds/Makefile2
-rw-r--r--drivers/leds/led-triggers.c3
-rw-r--r--drivers/leds/leds-atmel-pwm.c2
-rw-r--r--drivers/leds/leds-h1940.c9
-rw-r--r--drivers/leds/leds-pca9532.c337
-rw-r--r--drivers/leds/leds-pca955x.c384
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-dvb.c1
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-ioread.c1
-rw-r--r--drivers/media/video/uvc/uvc_queue.c1
-rw-r--r--drivers/media/video/videobuf-core.c1
-rw-r--r--drivers/message/i2o/device.c54
-rw-r--r--drivers/misc/atmel_pwm.c3
-rw-r--r--drivers/mtd/maps/uclinux.c1
-rw-r--r--drivers/net/e1000e/netdev.c2
-rw-r--r--drivers/net/fec.c54
-rw-r--r--drivers/net/mlx4/eq.c1
-rw-r--r--drivers/net/sky2.c5
-rw-r--r--drivers/pcmcia/electra_cf.c1
-rw-r--r--drivers/rtc/Kconfig19
-rw-r--r--drivers/rtc/Makefile2
-rw-r--r--drivers/rtc/rtc-at91rm9200.c16
-rw-r--r--drivers/rtc/rtc-cmos.c294
-rw-r--r--drivers/rtc/rtc-dev.c58
-rw-r--r--drivers/rtc/rtc-ds1305.c847
-rw-r--r--drivers/rtc/rtc-m41t80.c20
-rw-r--r--drivers/rtc/rtc-m41t94.c173
-rw-r--r--drivers/rtc/rtc-omap.c21
-rw-r--r--drivers/rtc/rtc-pcf8583.c129
-rw-r--r--drivers/rtc/rtc-s3c.c89
-rw-r--r--drivers/rtc/rtc-vr41xx.c65
-rw-r--r--drivers/scsi/sun_esp.c1
-rw-r--r--drivers/serial/8250.c17
-rw-r--r--drivers/serial/8250_gsc.c2
-rw-r--r--drivers/serial/8250_pci.c17
-rw-r--r--drivers/serial/Kconfig16
-rw-r--r--drivers/serial/cpm_uart/cpm_uart_core.c21
-rw-r--r--drivers/serial/dz.c24
-rw-r--r--drivers/serial/zs.c21
-rw-r--r--drivers/spi/Kconfig45
-rw-r--r--drivers/spi/au1550_spi.c207
-rw-r--r--drivers/spi/spi.c4
-rw-r--r--drivers/spi/spi_mpc83xx.c29
-rw-r--r--drivers/spi/spidev.c19
-rw-r--r--drivers/spi/xilinx_spi.c5
-rw-r--r--drivers/video/Kconfig53
-rw-r--r--drivers/video/Makefile5
-rw-r--r--drivers/video/acornfb.c1
-rw-r--r--drivers/video/amifb.c24
-rw-r--r--drivers/video/atafb.c7
-rw-r--r--drivers/video/atmel_lcdfb.c92
-rw-r--r--drivers/video/aty/aty128fb.c6
-rw-r--r--drivers/video/aty/atyfb_base.c100
-rw-r--r--drivers/video/aty/radeon_base.c20
-rw-r--r--drivers/video/backlight/Kconfig45
-rw-r--r--drivers/video/backlight/Makefile8
-rw-r--r--drivers/video/backlight/atmel-pwm-bl.c244
-rw-r--r--drivers/video/backlight/backlight.c1
-rw-r--r--drivers/video/backlight/ili9320.c330
-rw-r--r--drivers/video/backlight/ili9320.h80
-rw-r--r--drivers/video/backlight/lcd.c2
-rw-r--r--drivers/video/backlight/mbp_nvidia_bl.c116
-rw-r--r--drivers/video/backlight/platform_lcd.c172
-rw-r--r--drivers/video/backlight/vgg2432a4.c284
-rw-r--r--drivers/video/bf54x-lq043fb.c2
-rw-r--r--drivers/video/bfin-t350mcqb-fb.c2
-rw-r--r--drivers/video/carminefb.c790
-rw-r--r--drivers/video/carminefb.h64
-rw-r--r--drivers/video/carminefb_regs.h159
-rw-r--r--drivers/video/cobalt_lcdfb.c371
-rw-r--r--drivers/video/console/fbcon.c5
-rw-r--r--drivers/video/console/fbcon.h8
-rw-r--r--drivers/video/console/mdacon.c4
-rw-r--r--drivers/video/fbmem.c10
-rw-r--r--drivers/video/fbmon.c2
-rw-r--r--drivers/video/fsl-diu-fb.c60
-rw-r--r--drivers/video/geode/lxfb.h2
-rw-r--r--drivers/video/geode/lxfb_ops.c28
-rw-r--r--drivers/video/hgafb.c36
-rw-r--r--drivers/video/imxfb.c1
-rw-r--r--drivers/video/neofb.c215
-rw-r--r--drivers/video/omap/dispc.c1
-rw-r--r--drivers/video/omap/omapfb_main.c1
-rw-r--r--drivers/video/pxafb.c8
-rw-r--r--drivers/video/pxafb.h2
-rw-r--r--drivers/video/sa1100fb.c8
-rw-r--r--drivers/video/sa1100fb.h2
-rw-r--r--drivers/video/sh7760fb.c658
-rw-r--r--drivers/video/sh_mobile_lcdcfb.c725
-rw-r--r--drivers/video/sis/init.h1
-rw-r--r--drivers/video/sis/init301.h1
-rw-r--r--drivers/video/sis/initextlfb.c1
-rw-r--r--drivers/video/sis/osdef.h1
-rw-r--r--drivers/video/sis/sis.h22
-rw-r--r--drivers/video/sis/sis_accel.c1
-rw-r--r--drivers/video/sis/sis_main.c44
-rw-r--r--drivers/video/sis/sis_main.h4
-rw-r--r--drivers/video/sis/vgatypes.h4
-rw-r--r--drivers/video/skeletonfb.c37
-rw-r--r--drivers/video/sm501fb.c329
-rw-r--r--drivers/video/tdfxfb.c8
-rw-r--r--drivers/video/tridentfb.c1350
-rw-r--r--drivers/video/uvesafb.c4
-rw-r--r--drivers/video/vfb.c14
-rw-r--r--drivers/video/vga16fb.c122
-rw-r--r--drivers/watchdog/Kconfig2
-rw-r--r--drivers/watchdog/Makefile2
-rw-r--r--drivers/zorro/zorro-sysfs.c1
132 files changed, 8154 insertions, 2532 deletions
diff --git a/drivers/acpi/sleep/main.c b/drivers/acpi/sleep/main.c
index 0489a7d1d42c..d13194a031bf 100644
--- a/drivers/acpi/sleep/main.c
+++ b/drivers/acpi/sleep/main.c
@@ -280,9 +280,36 @@ static struct platform_suspend_ops acpi_suspend_ops_old = {
280 .end = acpi_pm_end, 280 .end = acpi_pm_end,
281 .recover = acpi_pm_finish, 281 .recover = acpi_pm_finish,
282}; 282};
283
284static int __init init_old_suspend_ordering(const struct dmi_system_id *d)
285{
286 old_suspend_ordering = true;
287 return 0;
288}
289
290static struct dmi_system_id __initdata acpisleep_dmi_table[] = {
291 {
292 .callback = init_old_suspend_ordering,
293 .ident = "Abit KN9 (nForce4 variant)",
294 .matches = {
295 DMI_MATCH(DMI_BOARD_VENDOR, "http://www.abit.com.tw/"),
296 DMI_MATCH(DMI_BOARD_NAME, "KN9 Series(NF-CK804)"),
297 },
298 },
299 {},
300};
283#endif /* CONFIG_SUSPEND */ 301#endif /* CONFIG_SUSPEND */
284 302
285#ifdef CONFIG_HIBERNATION 303#ifdef CONFIG_HIBERNATION
304static unsigned long s4_hardware_signature;
305static struct acpi_table_facs *facs;
306static bool nosigcheck;
307
308void __init acpi_no_s4_hw_signature(void)
309{
310 nosigcheck = true;
311}
312
286static int acpi_hibernation_begin(void) 313static int acpi_hibernation_begin(void)
287{ 314{
288 acpi_target_sleep_state = ACPI_STATE_S4; 315 acpi_target_sleep_state = ACPI_STATE_S4;
@@ -316,6 +343,12 @@ static void acpi_hibernation_leave(void)
316 acpi_enable(); 343 acpi_enable();
317 /* Reprogram control registers and execute _BFS */ 344 /* Reprogram control registers and execute _BFS */
318 acpi_leave_sleep_state_prep(ACPI_STATE_S4); 345 acpi_leave_sleep_state_prep(ACPI_STATE_S4);
346 /* Check the hardware signature */
347 if (facs && s4_hardware_signature != facs->hardware_signature) {
348 printk(KERN_EMERG "ACPI: Hardware changed while hibernated, "
349 "cannot resume!\n");
350 panic("ACPI S4 hardware signature mismatch");
351 }
319} 352}
320 353
321static void acpi_pm_enable_gpes(void) 354static void acpi_pm_enable_gpes(void)
@@ -516,6 +549,8 @@ int __init acpi_sleep_init(void)
516 u8 type_a, type_b; 549 u8 type_a, type_b;
517#ifdef CONFIG_SUSPEND 550#ifdef CONFIG_SUSPEND
518 int i = 0; 551 int i = 0;
552
553 dmi_check_system(acpisleep_dmi_table);
519#endif 554#endif
520 555
521 if (acpi_disabled) 556 if (acpi_disabled)
@@ -544,6 +579,13 @@ int __init acpi_sleep_init(void)
544 &acpi_hibernation_ops_old : &acpi_hibernation_ops); 579 &acpi_hibernation_ops_old : &acpi_hibernation_ops);
545 sleep_states[ACPI_STATE_S4] = 1; 580 sleep_states[ACPI_STATE_S4] = 1;
546 printk(" S4"); 581 printk(" S4");
582 if (!nosigcheck) {
583 acpi_get_table_by_index(ACPI_TABLE_INDEX_FACS,
584 (struct acpi_table_header **)&facs);
585 if (facs)
586 s4_hardware_signature =
587 facs->hardware_signature;
588 }
547 } 589 }
548#endif 590#endif
549 status = acpi_get_sleep_type_data(ACPI_STATE_S5, &type_a, &type_b); 591 status = acpi_get_sleep_type_data(ACPI_STATE_S5, &type_a, &type_b);
diff --git a/drivers/acpi/system.c b/drivers/acpi/system.c
index d8e3f153b295..91dec448b3ed 100644
--- a/drivers/acpi/system.c
+++ b/drivers/acpi/system.c
@@ -26,6 +26,7 @@
26#include <linux/proc_fs.h> 26#include <linux/proc_fs.h>
27#include <linux/seq_file.h> 27#include <linux/seq_file.h>
28#include <linux/init.h> 28#include <linux/init.h>
29#include <linux/string.h>
29#include <asm/uaccess.h> 30#include <asm/uaccess.h>
30 31
31#include <acpi/acpi_drivers.h> 32#include <acpi/acpi_drivers.h>
diff --git a/drivers/atm/fore200e.c b/drivers/atm/fore200e.c
index d5c1bbfbe79d..73338d231db9 100644
--- a/drivers/atm/fore200e.c
+++ b/drivers/atm/fore200e.c
@@ -2562,7 +2562,8 @@ fore200e_load_and_start_fw(struct fore200e* fore200e)
2562 const struct firmware *firmware; 2562 const struct firmware *firmware;
2563 struct device *device; 2563 struct device *device;
2564 struct fw_header *fw_header; 2564 struct fw_header *fw_header;
2565 u32 *fw_data, fw_size; 2565 const __le32 *fw_data;
2566 u32 fw_size;
2566 u32 __iomem *load_addr; 2567 u32 __iomem *load_addr;
2567 char buf[48]; 2568 char buf[48];
2568 int err = -ENODEV; 2569 int err = -ENODEV;
@@ -2582,7 +2583,7 @@ fore200e_load_and_start_fw(struct fore200e* fore200e)
2582 return err; 2583 return err;
2583 } 2584 }
2584 2585
2585 fw_data = (u32 *) firmware->data; 2586 fw_data = (__le32 *) firmware->data;
2586 fw_size = firmware->size / sizeof(u32); 2587 fw_size = firmware->size / sizeof(u32);
2587 fw_header = (struct fw_header *) firmware->data; 2588 fw_header = (struct fw_header *) firmware->data;
2588 load_addr = fore200e->virt_base + le32_to_cpu(fw_header->load_offset); 2589 load_addr = fore200e->virt_base + le32_to_cpu(fw_header->load_offset);
@@ -3199,6 +3200,14 @@ static const struct fore200e_bus fore200e_bus[] = {
3199 {} 3200 {}
3200}; 3201};
3201 3202
3202#ifdef MODULE_LICENSE
3203MODULE_LICENSE("GPL"); 3203MODULE_LICENSE("GPL");
3204#ifdef CONFIG_PCI
3205#ifdef __LITTLE_ENDIAN__
3206MODULE_FIRMWARE("pca200e.bin");
3207#else
3208MODULE_FIRMWARE("pca200e_ecd.bin2");
3209#endif
3210#endif /* CONFIG_PCI */
3211#ifdef CONFIG_SBUS
3212MODULE_FIRMWARE("sba200e_ecd.bin2");
3204#endif 3213#endif
diff --git a/drivers/auxdisplay/cfag12864b.c b/drivers/auxdisplay/cfag12864b.c
index 683509f013ab..eacb175f6bd3 100644
--- a/drivers/auxdisplay/cfag12864b.c
+++ b/drivers/auxdisplay/cfag12864b.c
@@ -336,16 +336,9 @@ static int __init cfag12864b_init(void)
336 "ks0108 is not initialized\n"); 336 "ks0108 is not initialized\n");
337 goto none; 337 goto none;
338 } 338 }
339 BUILD_BUG_ON(PAGE_SIZE < CFAG12864B_SIZE);
339 340
340 if (PAGE_SIZE < CFAG12864B_SIZE) { 341 cfag12864b_buffer = (unsigned char *) get_zeroed_page(GFP_KERNEL);
341 printk(KERN_ERR CFAG12864B_NAME ": ERROR: "
342 "page size (%i) < cfag12864b size (%i)\n",
343 (unsigned int)PAGE_SIZE, CFAG12864B_SIZE);
344 ret = -ENOMEM;
345 goto none;
346 }
347
348 cfag12864b_buffer = (unsigned char *) __get_free_page(GFP_KERNEL);
349 if (cfag12864b_buffer == NULL) { 342 if (cfag12864b_buffer == NULL) {
350 printk(KERN_ERR CFAG12864B_NAME ": ERROR: " 343 printk(KERN_ERR CFAG12864B_NAME ": ERROR: "
351 "can't get a free page\n"); 344 "can't get a free page\n");
@@ -367,8 +360,6 @@ static int __init cfag12864b_init(void)
367 if (cfag12864b_workqueue == NULL) 360 if (cfag12864b_workqueue == NULL)
368 goto cachealloced; 361 goto cachealloced;
369 362
370 memset(cfag12864b_buffer, 0, CFAG12864B_SIZE);
371
372 cfag12864b_clear(); 363 cfag12864b_clear();
373 cfag12864b_on(); 364 cfag12864b_on();
374 365
diff --git a/drivers/base/memory.c b/drivers/base/memory.c
index 4d4e0e7b6e92..855ed1a9f97b 100644
--- a/drivers/base/memory.c
+++ b/drivers/base/memory.c
@@ -101,6 +101,21 @@ static ssize_t show_mem_phys_index(struct sys_device *dev,
101} 101}
102 102
103/* 103/*
104 * Show whether the section of memory is likely to be hot-removable
105 */
106static ssize_t show_mem_removable(struct sys_device *dev, char *buf)
107{
108 unsigned long start_pfn;
109 int ret;
110 struct memory_block *mem =
111 container_of(dev, struct memory_block, sysdev);
112
113 start_pfn = section_nr_to_pfn(mem->phys_index);
114 ret = is_mem_section_removable(start_pfn, PAGES_PER_SECTION);
115 return sprintf(buf, "%d\n", ret);
116}
117
118/*
104 * online, offline, going offline, etc. 119 * online, offline, going offline, etc.
105 */ 120 */
106static ssize_t show_mem_state(struct sys_device *dev, 121static ssize_t show_mem_state(struct sys_device *dev,
@@ -262,6 +277,7 @@ static ssize_t show_phys_device(struct sys_device *dev,
262static SYSDEV_ATTR(phys_index, 0444, show_mem_phys_index, NULL); 277static SYSDEV_ATTR(phys_index, 0444, show_mem_phys_index, NULL);
263static SYSDEV_ATTR(state, 0644, show_mem_state, store_mem_state); 278static SYSDEV_ATTR(state, 0644, show_mem_state, store_mem_state);
264static SYSDEV_ATTR(phys_device, 0444, show_phys_device, NULL); 279static SYSDEV_ATTR(phys_device, 0444, show_phys_device, NULL);
280static SYSDEV_ATTR(removable, 0444, show_mem_removable, NULL);
265 281
266#define mem_create_simple_file(mem, attr_name) \ 282#define mem_create_simple_file(mem, attr_name) \
267 sysdev_create_file(&mem->sysdev, &attr_##attr_name) 283 sysdev_create_file(&mem->sysdev, &attr_##attr_name)
@@ -350,6 +366,8 @@ static int add_memory_block(unsigned long node_id, struct mem_section *section,
350 ret = mem_create_simple_file(mem, state); 366 ret = mem_create_simple_file(mem, state);
351 if (!ret) 367 if (!ret)
352 ret = mem_create_simple_file(mem, phys_device); 368 ret = mem_create_simple_file(mem, phys_device);
369 if (!ret)
370 ret = mem_create_simple_file(mem, removable);
353 371
354 return ret; 372 return ret;
355} 373}
@@ -394,6 +412,7 @@ int remove_memory_block(unsigned long node_id, struct mem_section *section,
394 mem_remove_simple_file(mem, phys_index); 412 mem_remove_simple_file(mem, phys_index);
395 mem_remove_simple_file(mem, state); 413 mem_remove_simple_file(mem, state);
396 mem_remove_simple_file(mem, phys_device); 414 mem_remove_simple_file(mem, phys_device);
415 mem_remove_simple_file(mem, removable);
397 unregister_memory(mem, section); 416 unregister_memory(mem, section);
398 417
399 return 0; 418 return 0;
diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig
index e0bbbfb6a36b..67b07576f8bf 100644
--- a/drivers/char/Kconfig
+++ b/drivers/char/Kconfig
@@ -857,13 +857,6 @@ config DS1302
857 857
858endif # RTC_LIB 858endif # RTC_LIB
859 859
860config COBALT_LCD
861 bool "Support for Cobalt LCD"
862 depends on MIPS_COBALT
863 help
864 This option enables support for the LCD display and buttons found
865 on Cobalt systems through a misc device.
866
867config DTLK 860config DTLK
868 tristate "Double Talk PC internal speech card support" 861 tristate "Double Talk PC internal speech card support"
869 depends on ISA 862 depends on ISA
diff --git a/drivers/char/Makefile b/drivers/char/Makefile
index dc5a327d72d5..4b6e736cfa02 100644
--- a/drivers/char/Makefile
+++ b/drivers/char/Makefile
@@ -88,7 +88,6 @@ obj-$(CONFIG_TOSHIBA) += toshiba.o
88obj-$(CONFIG_I8K) += i8k.o 88obj-$(CONFIG_I8K) += i8k.o
89obj-$(CONFIG_DS1620) += ds1620.o 89obj-$(CONFIG_DS1620) += ds1620.o
90obj-$(CONFIG_HW_RANDOM) += hw_random/ 90obj-$(CONFIG_HW_RANDOM) += hw_random/
91obj-$(CONFIG_COBALT_LCD) += lcd.o
92obj-$(CONFIG_PPDEV) += ppdev.o 91obj-$(CONFIG_PPDEV) += ppdev.o
93obj-$(CONFIG_NWBUTTON) += nwbutton.o 92obj-$(CONFIG_NWBUTTON) += nwbutton.o
94obj-$(CONFIG_NWFLASH) += nwflash.o 93obj-$(CONFIG_NWFLASH) += nwflash.o
diff --git a/drivers/char/lcd.c b/drivers/char/lcd.c
deleted file mode 100644
index 1c29b20e4f4c..000000000000
--- a/drivers/char/lcd.c
+++ /dev/null
@@ -1,516 +0,0 @@
1/*
2 * LCD, LED and Button interface for Cobalt
3 *
4 * This file is subject to the terms and conditions of the GNU General Public
5 * License. See the file "COPYING" in the main directory of this archive
6 * for more details.
7 *
8 * Copyright (C) 1996, 1997 by Andrew Bose
9 *
10 * Linux kernel version history:
11 * March 2001: Ported from 2.0.34 by Liam Davies
12 *
13 */
14#include <linux/types.h>
15#include <linux/errno.h>
16#include <linux/miscdevice.h>
17#include <linux/slab.h>
18#include <linux/ioport.h>
19#include <linux/fcntl.h>
20#include <linux/mc146818rtc.h>
21#include <linux/netdevice.h>
22#include <linux/sched.h>
23#include <linux/smp_lock.h>
24#include <linux/delay.h>
25
26#include <asm/io.h>
27#include <asm/uaccess.h>
28#include <asm/system.h>
29
30#include "lcd.h"
31
32static int lcd_ioctl(struct inode *inode, struct file *file,
33 unsigned int cmd, unsigned long arg);
34
35static unsigned int lcd_present = 1;
36
37/* used in arch/mips/cobalt/reset.c */
38int led_state = 0;
39
40#if defined(CONFIG_TULIP) && 0
41
42#define MAX_INTERFACES 8
43static linkcheck_func_t linkcheck_callbacks[MAX_INTERFACES];
44static void *linkcheck_cookies[MAX_INTERFACES];
45
46int lcd_register_linkcheck_func(int iface_num, void *func, void *cookie)
47{
48 if (iface_num < 0 ||
49 iface_num >= MAX_INTERFACES ||
50 linkcheck_callbacks[iface_num] != NULL)
51 return -1;
52 linkcheck_callbacks[iface_num] = (linkcheck_func_t) func;
53 linkcheck_cookies[iface_num] = cookie;
54 return 0;
55}
56#endif
57
58static int lcd_ioctl(struct inode *inode, struct file *file,
59 unsigned int cmd, unsigned long arg)
60{
61 struct lcd_display button_display;
62 unsigned long address, a;
63
64 switch (cmd) {
65 case LCD_On:
66 udelay(150);
67 BusyCheck();
68 LCDWriteInst(0x0F);
69 break;
70
71 case LCD_Off:
72 udelay(150);
73 BusyCheck();
74 LCDWriteInst(0x08);
75 break;
76
77 case LCD_Reset:
78 udelay(150);
79 LCDWriteInst(0x3F);
80 udelay(150);
81 LCDWriteInst(0x3F);
82 udelay(150);
83 LCDWriteInst(0x3F);
84 udelay(150);
85 LCDWriteInst(0x3F);
86 udelay(150);
87 LCDWriteInst(0x01);
88 udelay(150);
89 LCDWriteInst(0x06);
90 break;
91
92 case LCD_Clear:
93 udelay(150);
94 BusyCheck();
95 LCDWriteInst(0x01);
96 break;
97
98 case LCD_Cursor_Left:
99 udelay(150);
100 BusyCheck();
101 LCDWriteInst(0x10);
102 break;
103
104 case LCD_Cursor_Right:
105 udelay(150);
106 BusyCheck();
107 LCDWriteInst(0x14);
108 break;
109
110 case LCD_Cursor_Off:
111 udelay(150);
112 BusyCheck();
113 LCDWriteInst(0x0C);
114 break;
115
116 case LCD_Cursor_On:
117 udelay(150);
118 BusyCheck();
119 LCDWriteInst(0x0F);
120 break;
121
122 case LCD_Blink_Off:
123 udelay(150);
124 BusyCheck();
125 LCDWriteInst(0x0E);
126 break;
127
128 case LCD_Get_Cursor_Pos:{
129 struct lcd_display display;
130
131 udelay(150);
132 BusyCheck();
133 display.cursor_address = (LCDReadInst);
134 display.cursor_address =
135 (display.cursor_address & 0x07F);
136 if (copy_to_user
137 ((struct lcd_display *) arg, &display,
138 sizeof(struct lcd_display)))
139 return -EFAULT;
140
141 break;
142 }
143
144
145 case LCD_Set_Cursor_Pos:{
146 struct lcd_display display;
147
148 if (copy_from_user
149 (&display, (struct lcd_display *) arg,
150 sizeof(struct lcd_display)))
151 return -EFAULT;
152
153 a = (display.cursor_address | kLCD_Addr);
154
155 udelay(150);
156 BusyCheck();
157 LCDWriteInst(a);
158
159 break;
160 }
161
162 case LCD_Get_Cursor:{
163 struct lcd_display display;
164
165 udelay(150);
166 BusyCheck();
167 display.character = LCDReadData;
168
169 if (copy_to_user
170 ((struct lcd_display *) arg, &display,
171 sizeof(struct lcd_display)))
172 return -EFAULT;
173 udelay(150);
174 BusyCheck();
175 LCDWriteInst(0x10);
176
177 break;
178 }
179
180 case LCD_Set_Cursor:{
181 struct lcd_display display;
182
183 if (copy_from_user
184 (&display, (struct lcd_display *) arg,
185 sizeof(struct lcd_display)))
186 return -EFAULT;
187
188 udelay(150);
189 BusyCheck();
190 LCDWriteData(display.character);
191 udelay(150);
192 BusyCheck();
193 LCDWriteInst(0x10);
194
195 break;
196 }
197
198
199 case LCD_Disp_Left:
200 udelay(150);
201 BusyCheck();
202 LCDWriteInst(0x18);
203 break;
204
205 case LCD_Disp_Right:
206 udelay(150);
207 BusyCheck();
208 LCDWriteInst(0x1C);
209 break;
210
211 case LCD_Home:
212 udelay(150);
213 BusyCheck();
214 LCDWriteInst(0x02);
215 break;
216
217 case LCD_Write:{
218 struct lcd_display display;
219 unsigned int index;
220
221
222 if (copy_from_user
223 (&display, (struct lcd_display *) arg,
224 sizeof(struct lcd_display)))
225 return -EFAULT;
226
227 udelay(150);
228 BusyCheck();
229 LCDWriteInst(0x80);
230 udelay(150);
231 BusyCheck();
232
233 for (index = 0; index < (display.size1); index++) {
234 udelay(150);
235 BusyCheck();
236 LCDWriteData(display.line1[index]);
237 BusyCheck();
238 }
239
240 udelay(150);
241 BusyCheck();
242 LCDWriteInst(0xC0);
243 udelay(150);
244 BusyCheck();
245 for (index = 0; index < (display.size2); index++) {
246 udelay(150);
247 BusyCheck();
248 LCDWriteData(display.line2[index]);
249 }
250
251 break;
252 }
253
254 case LCD_Read:{
255 struct lcd_display display;
256
257 BusyCheck();
258 for (address = kDD_R00; address <= kDD_R01;
259 address++) {
260 a = (address | kLCD_Addr);
261
262 udelay(150);
263 BusyCheck();
264 LCDWriteInst(a);
265 udelay(150);
266 BusyCheck();
267 display.line1[address] = LCDReadData;
268 }
269
270 display.line1[0x27] = '\0';
271
272 for (address = kDD_R10; address <= kDD_R11;
273 address++) {
274 a = (address | kLCD_Addr);
275
276 udelay(150);
277 BusyCheck();
278 LCDWriteInst(a);
279
280 udelay(150);
281 BusyCheck();
282 display.line2[address - 0x40] =
283 LCDReadData;
284 }
285
286 display.line2[0x27] = '\0';
287
288 if (copy_to_user
289 ((struct lcd_display *) arg, &display,
290 sizeof(struct lcd_display)))
291 return -EFAULT;
292 break;
293 }
294
295// set all GPIO leds to led_display.leds
296
297 case LED_Set:{
298 struct lcd_display led_display;
299
300
301 if (copy_from_user
302 (&led_display, (struct lcd_display *) arg,
303 sizeof(struct lcd_display)))
304 return -EFAULT;
305
306 led_state = led_display.leds;
307 LEDSet(led_state);
308
309 break;
310 }
311
312
313// set only bit led_display.leds
314
315 case LED_Bit_Set:{
316 unsigned int i;
317 int bit = 1;
318 struct lcd_display led_display;
319
320
321 if (copy_from_user
322 (&led_display, (struct lcd_display *) arg,
323 sizeof(struct lcd_display)))
324 return -EFAULT;
325
326 for (i = 0; i < (int) led_display.leds; i++) {
327 bit = 2 * bit;
328 }
329
330 led_state = led_state | bit;
331 LEDSet(led_state);
332 break;
333 }
334
335// clear only bit led_display.leds
336
337 case LED_Bit_Clear:{
338 unsigned int i;
339 int bit = 1;
340 struct lcd_display led_display;
341
342
343 if (copy_from_user
344 (&led_display, (struct lcd_display *) arg,
345 sizeof(struct lcd_display)))
346 return -EFAULT;
347
348 for (i = 0; i < (int) led_display.leds; i++) {
349 bit = 2 * bit;
350 }
351
352 led_state = led_state & ~bit;
353 LEDSet(led_state);
354 break;
355 }
356
357
358 case BUTTON_Read:{
359 button_display.buttons = GPIRead;
360 if (copy_to_user
361 ((struct lcd_display *) arg, &button_display,
362 sizeof(struct lcd_display)))
363 return -EFAULT;
364 break;
365 }
366
367 case LINK_Check:{
368 button_display.buttons =
369 *((volatile unsigned long *) (0xB0100060));
370 if (copy_to_user
371 ((struct lcd_display *) arg, &button_display,
372 sizeof(struct lcd_display)))
373 return -EFAULT;
374 break;
375 }
376
377 case LINK_Check_2:{
378 int iface_num;
379
380 /* panel-utils should pass in the desired interface status is wanted for
381 * in "buttons" of the structure. We will set this to non-zero if the
382 * link is in fact up for the requested interface. --DaveM
383 */
384 if (copy_from_user
385 (&button_display, (struct lcd_display *) arg,
386 sizeof(button_display)))
387 return -EFAULT;
388 iface_num = button_display.buttons;
389#if defined(CONFIG_TULIP) && 0
390 if (iface_num >= 0 &&
391 iface_num < MAX_INTERFACES &&
392 linkcheck_callbacks[iface_num] != NULL) {
393 button_display.buttons =
394 linkcheck_callbacks[iface_num]
395 (linkcheck_cookies[iface_num]);
396 } else
397#endif
398 button_display.buttons = 0;
399
400 if (__copy_to_user
401 ((struct lcd_display *) arg, &button_display,
402 sizeof(struct lcd_display)))
403 return -EFAULT;
404 break;
405 }
406
407 default:
408 return -EINVAL;
409
410 }
411
412 return 0;
413
414}
415
416static int lcd_open(struct inode *inode, struct file *file)
417{
418 cycle_kernel_lock();
419
420 if (!lcd_present)
421 return -ENXIO;
422 else
423 return 0;
424}
425
426/* Only RESET or NEXT counts as button pressed */
427
428static inline int button_pressed(void)
429{
430 unsigned long buttons = GPIRead;
431
432 if ((buttons == BUTTON_Next) || (buttons == BUTTON_Next_B)
433 || (buttons == BUTTON_Reset_B))
434 return buttons;
435 return 0;
436}
437
438/* LED daemon sits on this and we wake him up once a key is pressed. */
439
440static int lcd_waiters = 0;
441
442static ssize_t lcd_read(struct file *file, char *buf,
443 size_t count, loff_t *ofs)
444{
445 long buttons_now;
446
447 if (lcd_waiters > 0)
448 return -EINVAL;
449
450 lcd_waiters++;
451 while (((buttons_now = (long) button_pressed()) == 0) &&
452 !(signal_pending(current))) {
453 msleep_interruptible(2000);
454 }
455 lcd_waiters--;
456
457 if (signal_pending(current))
458 return -ERESTARTSYS;
459 return buttons_now;
460}
461
462/*
463 * The various file operations we support.
464 */
465
466static const struct file_operations lcd_fops = {
467 .read = lcd_read,
468 .ioctl = lcd_ioctl,
469 .open = lcd_open,
470};
471
472static struct miscdevice lcd_dev = {
473 MISC_DYNAMIC_MINOR,
474 "lcd",
475 &lcd_fops
476};
477
478static int lcd_init(void)
479{
480 int ret;
481 unsigned long data;
482
483 pr_info("%s\n", LCD_DRIVER);
484 ret = misc_register(&lcd_dev);
485 if (ret) {
486 printk(KERN_WARNING LCD "Unable to register misc device.\n");
487 return ret;
488 }
489
490 /* Check region? Naaah! Just snarf it up. */
491/* request_region(RTC_PORT(0), RTC_IO_EXTENT, "lcd");*/
492
493 udelay(150);
494 data = LCDReadData;
495 if ((data & 0x000000FF) == (0x00)) {
496 lcd_present = 0;
497 pr_info(LCD "LCD Not Present\n");
498 } else {
499 lcd_present = 1;
500 WRITE_GAL(kGal_DevBank2PReg, kGal_DevBank2Cfg);
501 WRITE_GAL(kGal_DevBank3PReg, kGal_DevBank3Cfg);
502 }
503
504 return 0;
505}
506
507static void __exit lcd_exit(void)
508{
509 misc_deregister(&lcd_dev);
510}
511
512module_init(lcd_init);
513module_exit(lcd_exit);
514
515MODULE_AUTHOR("Andrew Bose");
516MODULE_LICENSE("GPL");
diff --git a/drivers/char/lcd.h b/drivers/char/lcd.h
deleted file mode 100644
index 290b3ff23b03..000000000000
--- a/drivers/char/lcd.h
+++ /dev/null
@@ -1,154 +0,0 @@
1/*
2 * LED, LCD and Button panel driver for Cobalt
3 *
4 * This file is subject to the terms and conditions of the GNU General Public
5 * License. See the file "COPYING" in the main directory of this archive
6 * for more details.
7 *
8 * Copyright (C) 1996, 1997 by Andrew Bose
9 *
10 * Linux kernel version history:
11 * March 2001: Ported from 2.0.34 by Liam Davies
12 *
13 */
14
15// function headers
16
17#define LCD_CHARS_PER_LINE 40
18#define MAX_IDLE_TIME 120
19
20struct lcd_display {
21 unsigned buttons;
22 int size1;
23 int size2;
24 unsigned char line1[LCD_CHARS_PER_LINE];
25 unsigned char line2[LCD_CHARS_PER_LINE];
26 unsigned char cursor_address;
27 unsigned char character;
28 unsigned char leds;
29 unsigned char *RomImage;
30};
31
32
33
34#define LCD_DRIVER "Cobalt LCD Driver v2.10"
35
36#define LCD "lcd: "
37
38#define kLCD_IR 0x0F000000
39#define kLCD_DR 0x0F000010
40#define kGPI 0x0D000000
41#define kLED 0x0C000000
42
43#define kDD_R00 0x00
44#define kDD_R01 0x27
45#define kDD_R10 0x40
46#define kDD_R11 0x67
47
48#define kLCD_Addr 0x00000080
49
50#define LCDTimeoutValue 0xfff
51
52
53// Macros
54
55#define LCDWriteData(x) outl((x << 24), kLCD_DR)
56#define LCDWriteInst(x) outl((x << 24), kLCD_IR)
57
58#define LCDReadData (inl(kLCD_DR) >> 24)
59#define LCDReadInst (inl(kLCD_IR) >> 24)
60
61#define GPIRead (inl(kGPI) >> 24)
62
63#define LEDSet(x) outb((char)x, kLED)
64
65#define WRITE_GAL(x,y) outl(y, 0x04000000 | (x))
66#define BusyCheck() while ((LCDReadInst & 0x80) == 0x80)
67
68
69
70/*
71 * Function command codes for io_ctl.
72 */
73#define LCD_On 1
74#define LCD_Off 2
75#define LCD_Clear 3
76#define LCD_Reset 4
77#define LCD_Cursor_Left 5
78#define LCD_Cursor_Right 6
79#define LCD_Disp_Left 7
80#define LCD_Disp_Right 8
81#define LCD_Get_Cursor 9
82#define LCD_Set_Cursor 10
83#define LCD_Home 11
84#define LCD_Read 12
85#define LCD_Write 13
86#define LCD_Cursor_Off 14
87#define LCD_Cursor_On 15
88#define LCD_Get_Cursor_Pos 16
89#define LCD_Set_Cursor_Pos 17
90#define LCD_Blink_Off 18
91
92#define LED_Set 40
93#define LED_Bit_Set 41
94#define LED_Bit_Clear 42
95
96
97// Button defs
98#define BUTTON_Read 50
99
100
101// Ethernet LINK check hackaroo
102#define LINK_Check 90
103#define LINK_Check_2 91
104
105// Button patterns _B - single layer lcd boards
106
107#define BUTTON_NONE 0x3F
108#define BUTTON_NONE_B 0xFE
109
110#define BUTTON_Left 0x3B
111#define BUTTON_Left_B 0xFA
112
113#define BUTTON_Right 0x37
114#define BUTTON_Right_B 0xDE
115
116#define BUTTON_Up 0x2F
117#define BUTTON_Up_B 0xF6
118
119#define BUTTON_Down 0x1F
120#define BUTTON_Down_B 0xEE
121
122#define BUTTON_Next 0x3D
123#define BUTTON_Next_B 0x7E
124
125#define BUTTON_Enter 0x3E
126#define BUTTON_Enter_B 0xBE
127
128#define BUTTON_Reset_B 0xFC
129
130
131// debounce constants
132
133#define BUTTON_SENSE 160000
134#define BUTTON_DEBOUNCE 5000
135
136
137// Galileo register stuff
138
139#define kGal_DevBank2Cfg 0x1466DB33
140#define kGal_DevBank2PReg 0x464
141#define kGal_DevBank3Cfg 0x146FDFFB
142#define kGal_DevBank3PReg 0x468
143
144// Network
145
146#define kIPADDR 1
147#define kNETMASK 2
148#define kGATEWAY 3
149#define kDNS 4
150
151#define kClassA 5
152#define kClassB 6
153#define kClassC 7
154
diff --git a/drivers/char/mem.c b/drivers/char/mem.c
index c2dba82eb5f7..672b08e694d0 100644
--- a/drivers/char/mem.c
+++ b/drivers/char/mem.c
@@ -327,7 +327,10 @@ static void mmap_mem_close(struct vm_area_struct *vma)
327 327
328static struct vm_operations_struct mmap_mem_ops = { 328static struct vm_operations_struct mmap_mem_ops = {
329 .open = mmap_mem_open, 329 .open = mmap_mem_open,
330 .close = mmap_mem_close 330 .close = mmap_mem_close,
331#ifdef CONFIG_HAVE_IOREMAP_PROT
332 .access = generic_access_phys
333#endif
331}; 334};
332 335
333static int mmap_mem(struct file * file, struct vm_area_struct * vma) 336static int mmap_mem(struct file * file, struct vm_area_struct * vma)
diff --git a/drivers/char/mspec.c b/drivers/char/mspec.c
index fe2a95b5d3c0..30f095a8c2d4 100644
--- a/drivers/char/mspec.c
+++ b/drivers/char/mspec.c
@@ -193,25 +193,23 @@ mspec_close(struct vm_area_struct *vma)
193} 193}
194 194
195/* 195/*
196 * mspec_nopfn 196 * mspec_fault
197 * 197 *
198 * Creates a mspec page and maps it to user space. 198 * Creates a mspec page and maps it to user space.
199 */ 199 */
200static unsigned long 200static int
201mspec_nopfn(struct vm_area_struct *vma, unsigned long address) 201mspec_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
202{ 202{
203 unsigned long paddr, maddr; 203 unsigned long paddr, maddr;
204 unsigned long pfn; 204 unsigned long pfn;
205 int index; 205 pgoff_t index = vmf->pgoff;
206 struct vma_data *vdata = vma->vm_private_data; 206 struct vma_data *vdata = vma->vm_private_data;
207 207
208 BUG_ON(address < vdata->vm_start || address >= vdata->vm_end);
209 index = (address - vdata->vm_start) >> PAGE_SHIFT;
210 maddr = (volatile unsigned long) vdata->maddr[index]; 208 maddr = (volatile unsigned long) vdata->maddr[index];
211 if (maddr == 0) { 209 if (maddr == 0) {
212 maddr = uncached_alloc_page(numa_node_id(), 1); 210 maddr = uncached_alloc_page(numa_node_id(), 1);
213 if (maddr == 0) 211 if (maddr == 0)
214 return NOPFN_OOM; 212 return VM_FAULT_OOM;
215 213
216 spin_lock(&vdata->lock); 214 spin_lock(&vdata->lock);
217 if (vdata->maddr[index] == 0) { 215 if (vdata->maddr[index] == 0) {
@@ -231,13 +229,20 @@ mspec_nopfn(struct vm_area_struct *vma, unsigned long address)
231 229
232 pfn = paddr >> PAGE_SHIFT; 230 pfn = paddr >> PAGE_SHIFT;
233 231
234 return pfn; 232 /*
233 * vm_insert_pfn can fail with -EBUSY, but in that case it will
234 * be because another thread has installed the pte first, so it
235 * is no problem.
236 */
237 vm_insert_pfn(vma, (unsigned long)vmf->virtual_address, pfn);
238
239 return VM_FAULT_NOPAGE;
235} 240}
236 241
237static struct vm_operations_struct mspec_vm_ops = { 242static struct vm_operations_struct mspec_vm_ops = {
238 .open = mspec_open, 243 .open = mspec_open,
239 .close = mspec_close, 244 .close = mspec_close,
240 .nopfn = mspec_nopfn 245 .fault = mspec_fault,
241}; 246};
242 247
243/* 248/*
diff --git a/drivers/char/random.c b/drivers/char/random.c
index 0cf98bd4f2d2..e0d0e371909c 100644
--- a/drivers/char/random.c
+++ b/drivers/char/random.c
@@ -236,6 +236,7 @@
236#include <linux/fs.h> 236#include <linux/fs.h>
237#include <linux/genhd.h> 237#include <linux/genhd.h>
238#include <linux/interrupt.h> 238#include <linux/interrupt.h>
239#include <linux/mm.h>
239#include <linux/spinlock.h> 240#include <linux/spinlock.h>
240#include <linux/percpu.h> 241#include <linux/percpu.h>
241#include <linux/cryptohash.h> 242#include <linux/cryptohash.h>
diff --git a/drivers/char/rtc.c b/drivers/char/rtc.c
index fa92a8af5a5a..dbefbb30ed44 100644
--- a/drivers/char/rtc.c
+++ b/drivers/char/rtc.c
@@ -78,9 +78,10 @@
78#include <linux/wait.h> 78#include <linux/wait.h>
79#include <linux/bcd.h> 79#include <linux/bcd.h>
80#include <linux/delay.h> 80#include <linux/delay.h>
81#include <linux/smp_lock.h>
82#include <linux/uaccess.h>
81 83
82#include <asm/current.h> 84#include <asm/current.h>
83#include <asm/uaccess.h>
84#include <asm/system.h> 85#include <asm/system.h>
85 86
86#ifdef CONFIG_X86 87#ifdef CONFIG_X86
@@ -120,8 +121,6 @@ static irqreturn_t hpet_rtc_interrupt(int irq, void *dev_id)
120 return 0; 121 return 0;
121} 122}
122#endif 123#endif
123#else
124extern irqreturn_t hpet_rtc_interrupt(int irq, void *dev_id);
125#endif 124#endif
126 125
127/* 126/*
@@ -144,8 +143,7 @@ static DEFINE_TIMER(rtc_irq_timer, rtc_dropped_irq, 0, 0);
144static ssize_t rtc_read(struct file *file, char __user *buf, 143static ssize_t rtc_read(struct file *file, char __user *buf,
145 size_t count, loff_t *ppos); 144 size_t count, loff_t *ppos);
146 145
147static int rtc_ioctl(struct inode *inode, struct file *file, 146static long rtc_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
148 unsigned int cmd, unsigned long arg);
149 147
150#ifdef RTC_IRQ 148#ifdef RTC_IRQ
151static unsigned int rtc_poll(struct file *file, poll_table *wait); 149static unsigned int rtc_poll(struct file *file, poll_table *wait);
@@ -719,10 +717,13 @@ static int rtc_do_ioctl(unsigned int cmd, unsigned long arg, int kernel)
719 &wtime, sizeof wtime) ? -EFAULT : 0; 717 &wtime, sizeof wtime) ? -EFAULT : 0;
720} 718}
721 719
722static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd, 720static long rtc_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
723 unsigned long arg)
724{ 721{
725 return rtc_do_ioctl(cmd, arg, 0); 722 long ret;
723 lock_kernel();
724 ret = rtc_do_ioctl(cmd, arg, 0);
725 unlock_kernel();
726 return ret;
726} 727}
727 728
728/* 729/*
@@ -915,7 +916,7 @@ static const struct file_operations rtc_fops = {
915#ifdef RTC_IRQ 916#ifdef RTC_IRQ
916 .poll = rtc_poll, 917 .poll = rtc_poll,
917#endif 918#endif
918 .ioctl = rtc_ioctl, 919 .unlocked_ioctl = rtc_ioctl,
919 .open = rtc_open, 920 .open = rtc_open,
920 .release = rtc_release, 921 .release = rtc_release,
921 .fasync = rtc_fasync, 922 .fasync = rtc_fasync,
diff --git a/drivers/char/stallion.c b/drivers/char/stallion.c
index b976248e1072..19db1eb87c26 100644
--- a/drivers/char/stallion.c
+++ b/drivers/char/stallion.c
@@ -1256,7 +1256,6 @@ static int stl_tiocmset(struct tty_struct *tty, struct file *file,
1256static int stl_ioctl(struct tty_struct *tty, struct file *file, unsigned int cmd, unsigned long arg) 1256static int stl_ioctl(struct tty_struct *tty, struct file *file, unsigned int cmd, unsigned long arg)
1257{ 1257{
1258 struct stlport *portp; 1258 struct stlport *portp;
1259 unsigned int ival;
1260 int rc; 1259 int rc;
1261 void __user *argp = (void __user *)arg; 1260 void __user *argp = (void __user *)arg;
1262 1261
diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c
index fa48dba5ba5e..6f4d856df987 100644
--- a/drivers/char/tty_io.c
+++ b/drivers/char/tty_io.c
@@ -1119,19 +1119,6 @@ int tty_hung_up_p(struct file *filp)
1119 1119
1120EXPORT_SYMBOL(tty_hung_up_p); 1120EXPORT_SYMBOL(tty_hung_up_p);
1121 1121
1122/**
1123 * is_tty - checker whether file is a TTY
1124 * @filp: file handle that may be a tty
1125 *
1126 * Check if the file handle is a tty handle.
1127 */
1128
1129int is_tty(struct file *filp)
1130{
1131 return filp->f_op->read == tty_read
1132 || filp->f_op->read == hung_up_tty_read;
1133}
1134
1135static void session_clear_tty(struct pid *session) 1122static void session_clear_tty(struct pid *session)
1136{ 1123{
1137 struct task_struct *p; 1124 struct task_struct *p;
diff --git a/drivers/char/vt.c b/drivers/char/vt.c
index e32a076d5f1f..cb8c90da3934 100644
--- a/drivers/char/vt.c
+++ b/drivers/char/vt.c
@@ -261,7 +261,7 @@ static void notify_update(struct vc_data *vc)
261#ifdef VT_BUF_VRAM_ONLY 261#ifdef VT_BUF_VRAM_ONLY
262#define DO_UPDATE(vc) 0 262#define DO_UPDATE(vc) 0
263#else 263#else
264#define DO_UPDATE(vc) CON_IS_VISIBLE(vc) 264#define DO_UPDATE(vc) (CON_IS_VISIBLE(vc) && !console_blanked)
265#endif 265#endif
266 266
267static inline unsigned short *screenpos(struct vc_data *vc, int offset, int viewed) 267static inline unsigned short *screenpos(struct vc_data *vc, int offset, int viewed)
@@ -2749,8 +2749,8 @@ static int con_open(struct tty_struct *tty, struct file *filp)
2749 tty->termios->c_iflag |= IUTF8; 2749 tty->termios->c_iflag |= IUTF8;
2750 else 2750 else
2751 tty->termios->c_iflag &= ~IUTF8; 2751 tty->termios->c_iflag &= ~IUTF8;
2752 release_console_sem();
2753 vcs_make_sysfs(tty); 2752 vcs_make_sysfs(tty);
2753 release_console_sem();
2754 return ret; 2754 return ret;
2755 } 2755 }
2756 } 2756 }
@@ -2775,8 +2775,8 @@ static void con_close(struct tty_struct *tty, struct file *filp)
2775 if (vc) 2775 if (vc)
2776 vc->vc_tty = NULL; 2776 vc->vc_tty = NULL;
2777 tty->driver_data = NULL; 2777 tty->driver_data = NULL;
2778 release_console_sem();
2779 vcs_remove_sysfs(tty); 2778 vcs_remove_sysfs(tty);
2779 release_console_sem();
2780 mutex_unlock(&tty_mutex); 2780 mutex_unlock(&tty_mutex);
2781 /* 2781 /*
2782 * tty_mutex is released, but we still hold BKL, so there is 2782 * tty_mutex is released, but we still hold BKL, so there is
diff --git a/drivers/ieee1394/iso.c b/drivers/ieee1394/iso.c
index 07ca35c98f96..1cf6487b65ba 100644
--- a/drivers/ieee1394/iso.c
+++ b/drivers/ieee1394/iso.c
@@ -11,6 +11,7 @@
11 11
12#include <linux/pci.h> 12#include <linux/pci.h>
13#include <linux/sched.h> 13#include <linux/sched.h>
14#include <linux/mm.h>
14#include <linux/slab.h> 15#include <linux/slab.h>
15 16
16#include "hosts.h" 17#include "hosts.h"
diff --git a/drivers/isdn/gigaset/asyncdata.c b/drivers/isdn/gigaset/asyncdata.c
index 091deb9d1c47..c2bd97d29273 100644
--- a/drivers/isdn/gigaset/asyncdata.c
+++ b/drivers/isdn/gigaset/asyncdata.c
@@ -575,7 +575,8 @@ int gigaset_m10x_send_skb(struct bc_state *bcs, struct sk_buff *skb)
575 else 575 else
576 skb = iraw_encode(skb, HW_HDR_LEN, 0); 576 skb = iraw_encode(skb, HW_HDR_LEN, 0);
577 if (!skb) { 577 if (!skb) {
578 err("unable to allocate memory for encoding!\n"); 578 dev_err(bcs->cs->dev,
579 "unable to allocate memory for encoding!\n");
579 return -ENOMEM; 580 return -ENOMEM;
580 } 581 }
581 582
diff --git a/drivers/isdn/gigaset/bas-gigaset.c b/drivers/isdn/gigaset/bas-gigaset.c
index 5255b5e20e13..3f11910c7ccd 100644
--- a/drivers/isdn/gigaset/bas-gigaset.c
+++ b/drivers/isdn/gigaset/bas-gigaset.c
@@ -1050,10 +1050,9 @@ static int submit_iso_write_urb(struct isow_urbctx_t *ucx)
1050 } 1050 }
1051 1051
1052 /* retrieve block of data to send */ 1052 /* retrieve block of data to send */
1053 ifd->offset = gigaset_isowbuf_getbytes(ubc->isooutbuf, 1053 rc = gigaset_isowbuf_getbytes(ubc->isooutbuf, ifd->length);
1054 ifd->length); 1054 if (rc < 0) {
1055 if (ifd->offset < 0) { 1055 if (rc == -EBUSY) {
1056 if (ifd->offset == -EBUSY) {
1057 gig_dbg(DEBUG_ISO, 1056 gig_dbg(DEBUG_ISO,
1058 "%s: buffer busy at frame %d", 1057 "%s: buffer busy at frame %d",
1059 __func__, nframe); 1058 __func__, nframe);
@@ -1062,11 +1061,12 @@ static int submit_iso_write_urb(struct isow_urbctx_t *ucx)
1062 } else { 1061 } else {
1063 dev_err(ucx->bcs->cs->dev, 1062 dev_err(ucx->bcs->cs->dev,
1064 "%s: buffer error %d at frame %d\n", 1063 "%s: buffer error %d at frame %d\n",
1065 __func__, ifd->offset, nframe); 1064 __func__, rc, nframe);
1066 return ifd->offset; 1065 return rc;
1067 } 1066 }
1068 break; 1067 break;
1069 } 1068 }
1069 ifd->offset = rc;
1070 ucx->limit = ubc->isooutbuf->nextread; 1070 ucx->limit = ubc->isooutbuf->nextread;
1071 ifd->status = 0; 1071 ifd->status = 0;
1072 ifd->actual_length = 0; 1072 ifd->actual_length = 0;
diff --git a/drivers/isdn/gigaset/common.c b/drivers/isdn/gigaset/common.c
index 827c32c16795..9d3ce7718e58 100644
--- a/drivers/isdn/gigaset/common.c
+++ b/drivers/isdn/gigaset/common.c
@@ -287,7 +287,7 @@ struct event_t *gigaset_add_event(struct cardstate *cs,
287 tail = cs->ev_tail; 287 tail = cs->ev_tail;
288 next = (tail + 1) % MAX_EVENTS; 288 next = (tail + 1) % MAX_EVENTS;
289 if (unlikely(next == cs->ev_head)) 289 if (unlikely(next == cs->ev_head))
290 err("event queue full"); 290 dev_err(cs->dev, "event queue full\n");
291 else { 291 else {
292 event = cs->events + tail; 292 event = cs->events + tail;
293 event->type = type; 293 event->type = type;
diff --git a/drivers/isdn/gigaset/gigaset.h b/drivers/isdn/gigaset/gigaset.h
index f365993161fc..003752954993 100644
--- a/drivers/isdn/gigaset/gigaset.h
+++ b/drivers/isdn/gigaset/gigaset.h
@@ -106,7 +106,6 @@ enum debuglevel {
106#undef err 106#undef err
107#undef info 107#undef info
108#undef warn 108#undef warn
109#undef notice
110 109
111#define err(format, arg...) printk(KERN_ERR KBUILD_MODNAME ": " \ 110#define err(format, arg...) printk(KERN_ERR KBUILD_MODNAME ": " \
112 format "\n" , ## arg) 111 format "\n" , ## arg)
@@ -114,8 +113,6 @@ enum debuglevel {
114 format "\n" , ## arg) 113 format "\n" , ## arg)
115#define warn(format, arg...) printk(KERN_WARNING KBUILD_MODNAME ": " \ 114#define warn(format, arg...) printk(KERN_WARNING KBUILD_MODNAME ": " \
116 format "\n" , ## arg) 115 format "\n" , ## arg)
117#define notice(format, arg...) printk(KERN_NOTICE KBUILD_MODNAME ": " \
118 format "\n" , ## arg)
119 116
120#ifdef CONFIG_GIGASET_DEBUG 117#ifdef CONFIG_GIGASET_DEBUG
121 118
diff --git a/drivers/isdn/gigaset/i4l.c b/drivers/isdn/gigaset/i4l.c
index 9e089f06a942..3c127a8cbaf2 100644
--- a/drivers/isdn/gigaset/i4l.c
+++ b/drivers/isdn/gigaset/i4l.c
@@ -46,7 +46,8 @@ static int writebuf_from_LL(int driverID, int channel, int ack,
46 return -ENODEV; 46 return -ENODEV;
47 } 47 }
48 if (channel < 0 || channel >= cs->channels) { 48 if (channel < 0 || channel >= cs->channels) {
49 err("%s: invalid channel ID (%d)", __func__, channel); 49 dev_err(cs->dev, "%s: invalid channel ID (%d)\n",
50 __func__, channel);
50 return -ENODEV; 51 return -ENODEV;
51 } 52 }
52 bcs = &cs->bcs[channel]; 53 bcs = &cs->bcs[channel];
@@ -58,11 +59,13 @@ static int writebuf_from_LL(int driverID, int channel, int ack,
58 59
59 if (!len) { 60 if (!len) {
60 if (ack) 61 if (ack)
61 notice("%s: not ACKing empty packet", __func__); 62 dev_notice(cs->dev, "%s: not ACKing empty packet\n",
63 __func__);
62 return 0; 64 return 0;
63 } 65 }
64 if (len > MAX_BUF_SIZE) { 66 if (len > MAX_BUF_SIZE) {
65 err("%s: packet too large (%d bytes)", __func__, len); 67 dev_err(cs->dev, "%s: packet too large (%d bytes)\n",
68 __func__, len);
66 return -EINVAL; 69 return -EINVAL;
67 } 70 }
68 71
@@ -116,8 +119,7 @@ static int command_from_LL(isdn_ctrl *cntrl)
116 gigaset_debugdrivers(); 119 gigaset_debugdrivers();
117 120
118 if (!cs) { 121 if (!cs) {
119 warn("LL tried to access unknown device with nr. %d", 122 err("%s: invalid driver ID (%d)", __func__, cntrl->driver);
120 cntrl->driver);
121 return -ENODEV; 123 return -ENODEV;
122 } 124 }
123 125
@@ -126,7 +128,7 @@ static int command_from_LL(isdn_ctrl *cntrl)
126 gig_dbg(DEBUG_ANY, "ISDN_CMD_IOCTL (driver: %d, arg: %ld)", 128 gig_dbg(DEBUG_ANY, "ISDN_CMD_IOCTL (driver: %d, arg: %ld)",
127 cntrl->driver, cntrl->arg); 129 cntrl->driver, cntrl->arg);
128 130
129 warn("ISDN_CMD_IOCTL is not supported."); 131 dev_warn(cs->dev, "ISDN_CMD_IOCTL not supported\n");
130 return -EINVAL; 132 return -EINVAL;
131 133
132 case ISDN_CMD_DIAL: 134 case ISDN_CMD_DIAL:
@@ -138,22 +140,23 @@ static int command_from_LL(isdn_ctrl *cntrl)
138 cntrl->parm.setup.si1, cntrl->parm.setup.si2); 140 cntrl->parm.setup.si1, cntrl->parm.setup.si2);
139 141
140 if (cntrl->arg >= cs->channels) { 142 if (cntrl->arg >= cs->channels) {
141 err("ISDN_CMD_DIAL: invalid channel (%d)", 143 dev_err(cs->dev,
142 (int) cntrl->arg); 144 "ISDN_CMD_DIAL: invalid channel (%d)\n",
145 (int) cntrl->arg);
143 return -EINVAL; 146 return -EINVAL;
144 } 147 }
145 148
146 bcs = cs->bcs + cntrl->arg; 149 bcs = cs->bcs + cntrl->arg;
147 150
148 if (!gigaset_get_channel(bcs)) { 151 if (!gigaset_get_channel(bcs)) {
149 err("ISDN_CMD_DIAL: channel not free"); 152 dev_err(cs->dev, "ISDN_CMD_DIAL: channel not free\n");
150 return -EBUSY; 153 return -EBUSY;
151 } 154 }
152 155
153 sp = kmalloc(sizeof *sp, GFP_ATOMIC); 156 sp = kmalloc(sizeof *sp, GFP_ATOMIC);
154 if (!sp) { 157 if (!sp) {
155 gigaset_free_channel(bcs); 158 gigaset_free_channel(bcs);
156 err("ISDN_CMD_DIAL: out of memory"); 159 dev_err(cs->dev, "ISDN_CMD_DIAL: out of memory\n");
157 return -ENOMEM; 160 return -ENOMEM;
158 } 161 }
159 *sp = cntrl->parm.setup; 162 *sp = cntrl->parm.setup;
@@ -173,8 +176,9 @@ static int command_from_LL(isdn_ctrl *cntrl)
173 gig_dbg(DEBUG_ANY, "ISDN_CMD_ACCEPTD"); 176 gig_dbg(DEBUG_ANY, "ISDN_CMD_ACCEPTD");
174 177
175 if (cntrl->arg >= cs->channels) { 178 if (cntrl->arg >= cs->channels) {
176 err("ISDN_CMD_ACCEPTD: invalid channel (%d)", 179 dev_err(cs->dev,
177 (int) cntrl->arg); 180 "ISDN_CMD_ACCEPTD: invalid channel (%d)\n",
181 (int) cntrl->arg);
178 return -EINVAL; 182 return -EINVAL;
179 } 183 }
180 184
@@ -196,8 +200,9 @@ static int command_from_LL(isdn_ctrl *cntrl)
196 (int) cntrl->arg); 200 (int) cntrl->arg);
197 201
198 if (cntrl->arg >= cs->channels) { 202 if (cntrl->arg >= cs->channels) {
199 err("ISDN_CMD_HANGUP: invalid channel (%u)", 203 dev_err(cs->dev,
200 (unsigned) cntrl->arg); 204 "ISDN_CMD_HANGUP: invalid channel (%d)\n",
205 (int) cntrl->arg);
201 return -EINVAL; 206 return -EINVAL;
202 } 207 }
203 208
@@ -224,8 +229,9 @@ static int command_from_LL(isdn_ctrl *cntrl)
224 cntrl->arg & 0xff, (cntrl->arg >> 8)); 229 cntrl->arg & 0xff, (cntrl->arg >> 8));
225 230
226 if ((cntrl->arg & 0xff) >= cs->channels) { 231 if ((cntrl->arg & 0xff) >= cs->channels) {
227 err("ISDN_CMD_SETL2: invalid channel (%u)", 232 dev_err(cs->dev,
228 (unsigned) cntrl->arg & 0xff); 233 "ISDN_CMD_SETL2: invalid channel (%d)\n",
234 (int) cntrl->arg & 0xff);
229 return -EINVAL; 235 return -EINVAL;
230 } 236 }
231 237
@@ -244,14 +250,16 @@ static int command_from_LL(isdn_ctrl *cntrl)
244 cntrl->arg & 0xff, (cntrl->arg >> 8)); 250 cntrl->arg & 0xff, (cntrl->arg >> 8));
245 251
246 if ((cntrl->arg & 0xff) >= cs->channels) { 252 if ((cntrl->arg & 0xff) >= cs->channels) {
247 err("ISDN_CMD_SETL3: invalid channel (%u)", 253 dev_err(cs->dev,
248 (unsigned) cntrl->arg & 0xff); 254 "ISDN_CMD_SETL3: invalid channel (%d)\n",
255 (int) cntrl->arg & 0xff);
249 return -EINVAL; 256 return -EINVAL;
250 } 257 }
251 258
252 if (cntrl->arg >> 8 != ISDN_PROTO_L3_TRANS) { 259 if (cntrl->arg >> 8 != ISDN_PROTO_L3_TRANS) {
253 err("ISDN_CMD_SETL3: invalid protocol %lu", 260 dev_err(cs->dev,
254 cntrl->arg >> 8); 261 "ISDN_CMD_SETL3: invalid protocol %lu\n",
262 cntrl->arg >> 8);
255 return -EINVAL; 263 return -EINVAL;
256 } 264 }
257 265
@@ -262,8 +270,9 @@ static int command_from_LL(isdn_ctrl *cntrl)
262 case ISDN_CMD_ALERT: 270 case ISDN_CMD_ALERT:
263 gig_dbg(DEBUG_ANY, "ISDN_CMD_ALERT"); //FIXME 271 gig_dbg(DEBUG_ANY, "ISDN_CMD_ALERT"); //FIXME
264 if (cntrl->arg >= cs->channels) { 272 if (cntrl->arg >= cs->channels) {
265 err("ISDN_CMD_ALERT: invalid channel (%d)", 273 dev_err(cs->dev,
266 (int) cntrl->arg); 274 "ISDN_CMD_ALERT: invalid channel (%d)\n",
275 (int) cntrl->arg);
267 return -EINVAL; 276 return -EINVAL;
268 } 277 }
269 //bcs = cs->bcs + cntrl->arg; 278 //bcs = cs->bcs + cntrl->arg;
@@ -295,7 +304,8 @@ static int command_from_LL(isdn_ctrl *cntrl)
295 gig_dbg(DEBUG_ANY, "ISDN_CMD_GETSIL"); 304 gig_dbg(DEBUG_ANY, "ISDN_CMD_GETSIL");
296 break; 305 break;
297 default: 306 default:
298 err("unknown command %d from LL", cntrl->command); 307 dev_err(cs->dev, "unknown command %d from LL\n",
308 cntrl->command);
299 return -EINVAL; 309 return -EINVAL;
300 } 310 }
301 311
diff --git a/drivers/isdn/gigaset/interface.c b/drivers/isdn/gigaset/interface.c
index af195b07c191..521951a898ec 100644
--- a/drivers/isdn/gigaset/interface.c
+++ b/drivers/isdn/gigaset/interface.c
@@ -197,7 +197,7 @@ static void if_close(struct tty_struct *tty, struct file *filp)
197 mutex_lock(&cs->mutex); 197 mutex_lock(&cs->mutex);
198 198
199 if (!cs->open_count) 199 if (!cs->open_count)
200 warn("%s: device not opened", __func__); 200 dev_warn(cs->dev, "%s: device not opened\n", __func__);
201 else { 201 else {
202 if (!--cs->open_count) { 202 if (!--cs->open_count) {
203 spin_lock_irqsave(&cs->lock, flags); 203 spin_lock_irqsave(&cs->lock, flags);
@@ -232,7 +232,7 @@ static int if_ioctl(struct tty_struct *tty, struct file *file,
232 return -ERESTARTSYS; // FIXME -EINTR? 232 return -ERESTARTSYS; // FIXME -EINTR?
233 233
234 if (!cs->open_count) 234 if (!cs->open_count)
235 warn("%s: device not opened", __func__); 235 dev_warn(cs->dev, "%s: device not opened\n", __func__);
236 else { 236 else {
237 retval = 0; 237 retval = 0;
238 switch (cmd) { 238 switch (cmd) {
@@ -364,9 +364,9 @@ static int if_write(struct tty_struct *tty, const unsigned char *buf, int count)
364 return -ERESTARTSYS; // FIXME -EINTR? 364 return -ERESTARTSYS; // FIXME -EINTR?
365 365
366 if (!cs->open_count) 366 if (!cs->open_count)
367 warn("%s: device not opened", __func__); 367 dev_warn(cs->dev, "%s: device not opened\n", __func__);
368 else if (cs->mstate != MS_LOCKED) { 368 else if (cs->mstate != MS_LOCKED) {
369 warn("can't write to unlocked device"); 369 dev_warn(cs->dev, "can't write to unlocked device\n");
370 retval = -EBUSY; 370 retval = -EBUSY;
371 } else if (!cs->connected) { 371 } else if (!cs->connected) {
372 gig_dbg(DEBUG_ANY, "can't write to unplugged device"); 372 gig_dbg(DEBUG_ANY, "can't write to unplugged device");
@@ -398,9 +398,9 @@ static int if_write_room(struct tty_struct *tty)
398 return -ERESTARTSYS; // FIXME -EINTR? 398 return -ERESTARTSYS; // FIXME -EINTR?
399 399
400 if (!cs->open_count) 400 if (!cs->open_count)
401 warn("%s: device not opened", __func__); 401 dev_warn(cs->dev, "%s: device not opened\n", __func__);
402 else if (cs->mstate != MS_LOCKED) { 402 else if (cs->mstate != MS_LOCKED) {
403 warn("can't write to unlocked device"); 403 dev_warn(cs->dev, "can't write to unlocked device\n");
404 retval = -EBUSY; 404 retval = -EBUSY;
405 } else if (!cs->connected) { 405 } else if (!cs->connected) {
406 gig_dbg(DEBUG_ANY, "can't write to unplugged device"); 406 gig_dbg(DEBUG_ANY, "can't write to unplugged device");
@@ -430,9 +430,9 @@ static int if_chars_in_buffer(struct tty_struct *tty)
430 return -ERESTARTSYS; // FIXME -EINTR? 430 return -ERESTARTSYS; // FIXME -EINTR?
431 431
432 if (!cs->open_count) 432 if (!cs->open_count)
433 warn("%s: device not opened", __func__); 433 dev_warn(cs->dev, "%s: device not opened\n", __func__);
434 else if (cs->mstate != MS_LOCKED) { 434 else if (cs->mstate != MS_LOCKED) {
435 warn("can't write to unlocked device"); 435 dev_warn(cs->dev, "can't write to unlocked device\n");
436 retval = -EBUSY; 436 retval = -EBUSY;
437 } else if (!cs->connected) { 437 } else if (!cs->connected) {
438 gig_dbg(DEBUG_ANY, "can't write to unplugged device"); 438 gig_dbg(DEBUG_ANY, "can't write to unplugged device");
@@ -460,7 +460,7 @@ static void if_throttle(struct tty_struct *tty)
460 mutex_lock(&cs->mutex); 460 mutex_lock(&cs->mutex);
461 461
462 if (!cs->open_count) 462 if (!cs->open_count)
463 warn("%s: device not opened", __func__); 463 dev_warn(cs->dev, "%s: device not opened\n", __func__);
464 else { 464 else {
465 //FIXME 465 //FIXME
466 } 466 }
@@ -483,7 +483,7 @@ static void if_unthrottle(struct tty_struct *tty)
483 mutex_lock(&cs->mutex); 483 mutex_lock(&cs->mutex);
484 484
485 if (!cs->open_count) 485 if (!cs->open_count)
486 warn("%s: device not opened", __func__); 486 dev_warn(cs->dev, "%s: device not opened\n", __func__);
487 else { 487 else {
488 //FIXME 488 //FIXME
489 } 489 }
@@ -510,7 +510,7 @@ static void if_set_termios(struct tty_struct *tty, struct ktermios *old)
510 mutex_lock(&cs->mutex); 510 mutex_lock(&cs->mutex);
511 511
512 if (!cs->open_count) { 512 if (!cs->open_count) {
513 warn("%s: device not opened", __func__); 513 dev_warn(cs->dev, "%s: device not opened\n", __func__);
514 goto out; 514 goto out;
515 } 515 }
516 516
@@ -623,7 +623,8 @@ void gigaset_if_init(struct cardstate *cs)
623 if (!IS_ERR(cs->tty_dev)) 623 if (!IS_ERR(cs->tty_dev))
624 dev_set_drvdata(cs->tty_dev, cs); 624 dev_set_drvdata(cs->tty_dev, cs);
625 else { 625 else {
626 warn("could not register device to the tty subsystem"); 626 dev_warn(cs->dev,
627 "could not register device to the tty subsystem\n");
627 cs->tty_dev = NULL; 628 cs->tty_dev = NULL;
628 } 629 }
629 mutex_unlock(&cs->mutex); 630 mutex_unlock(&cs->mutex);
diff --git a/drivers/isdn/gigaset/usb-gigaset.c b/drivers/isdn/gigaset/usb-gigaset.c
index 77d20ab0cd4d..4661830a49db 100644
--- a/drivers/isdn/gigaset/usb-gigaset.c
+++ b/drivers/isdn/gigaset/usb-gigaset.c
@@ -498,8 +498,9 @@ static int send_cb(struct cardstate *cs, struct cmdbuf_t *cb)
498 498
499 if (status) { 499 if (status) {
500 ucs->busy = 0; 500 ucs->busy = 0;
501 err("could not submit urb (error %d)\n", 501 dev_err(cs->dev,
502 -status); 502 "could not submit urb (error %d)\n",
503 -status);
503 cb->len = 0; /* skip urb => remove cb+wakeup 504 cb->len = 0; /* skip urb => remove cb+wakeup
504 in next loop cycle */ 505 in next loop cycle */
505 } 506 }
@@ -670,7 +671,7 @@ static int write_modem(struct cardstate *cs)
670 spin_unlock_irqrestore(&cs->lock, flags); 671 spin_unlock_irqrestore(&cs->lock, flags);
671 672
672 if (ret) { 673 if (ret) {
673 err("could not submit urb (error %d)\n", -ret); 674 dev_err(cs->dev, "could not submit urb (error %d)\n", -ret);
674 ucs->busy = 0; 675 ucs->busy = 0;
675 } 676 }
676 677
diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig
index 86a369bc57d6..9556262dda5a 100644
--- a/drivers/leds/Kconfig
+++ b/drivers/leds/Kconfig
@@ -103,6 +103,14 @@ config LEDS_HP6XX
103 This option enables led support for the handheld 103 This option enables led support for the handheld
104 HP Jornada 620/660/680/690. 104 HP Jornada 620/660/680/690.
105 105
106config LEDS_PCA9532
107 tristate "LED driver for PCA9532 dimmer"
108 depends on LEDS_CLASS && I2C && INPUT && EXPERIMENTAL
109 help
110 This option enables support for NXP pca9532
111 led controller. It is generally only usefull
112 as a platform driver
113
106config LEDS_GPIO 114config LEDS_GPIO
107 tristate "LED Support for GPIO connected LEDs" 115 tristate "LED Support for GPIO connected LEDs"
108 depends on LEDS_CLASS && GENERIC_GPIO 116 depends on LEDS_CLASS && GENERIC_GPIO
@@ -147,6 +155,14 @@ config LEDS_CLEVO_MAIL
147 To compile this driver as a module, choose M here: the 155 To compile this driver as a module, choose M here: the
148 module will be called leds-clevo-mail. 156 module will be called leds-clevo-mail.
149 157
158config LEDS_PCA955X
159 tristate "LED Support for PCA955x I2C chips"
160 depends on LEDS_CLASS && I2C
161 help
162 This option enables support for LEDs connected to PCA955x
163 LED driver chips accessed via the I2C bus. Supported
164 devices include PCA9550, PCA9551, PCA9552, and PCA9553.
165
150comment "LED Triggers" 166comment "LED Triggers"
151 167
152config LEDS_TRIGGERS 168config LEDS_TRIGGERS
diff --git a/drivers/leds/Makefile b/drivers/leds/Makefile
index 973d626f5f4a..ff7982b44565 100644
--- a/drivers/leds/Makefile
+++ b/drivers/leds/Makefile
@@ -16,11 +16,13 @@ obj-$(CONFIG_LEDS_WRAP) += leds-wrap.o
16obj-$(CONFIG_LEDS_H1940) += leds-h1940.o 16obj-$(CONFIG_LEDS_H1940) += leds-h1940.o
17obj-$(CONFIG_LEDS_COBALT_QUBE) += leds-cobalt-qube.o 17obj-$(CONFIG_LEDS_COBALT_QUBE) += leds-cobalt-qube.o
18obj-$(CONFIG_LEDS_COBALT_RAQ) += leds-cobalt-raq.o 18obj-$(CONFIG_LEDS_COBALT_RAQ) += leds-cobalt-raq.o
19obj-$(CONFIG_LEDS_PCA9532) += leds-pca9532.o
19obj-$(CONFIG_LEDS_GPIO) += leds-gpio.o 20obj-$(CONFIG_LEDS_GPIO) += leds-gpio.o
20obj-$(CONFIG_LEDS_CM_X270) += leds-cm-x270.o 21obj-$(CONFIG_LEDS_CM_X270) += leds-cm-x270.o
21obj-$(CONFIG_LEDS_CLEVO_MAIL) += leds-clevo-mail.o 22obj-$(CONFIG_LEDS_CLEVO_MAIL) += leds-clevo-mail.o
22obj-$(CONFIG_LEDS_HP6XX) += leds-hp6xx.o 23obj-$(CONFIG_LEDS_HP6XX) += leds-hp6xx.o
23obj-$(CONFIG_LEDS_FSG) += leds-fsg.o 24obj-$(CONFIG_LEDS_FSG) += leds-fsg.o
25obj-$(CONFIG_LEDS_PCA955X) += leds-pca955x.o
24 26
25# LED Triggers 27# LED Triggers
26obj-$(CONFIG_LEDS_TRIGGER_TIMER) += ledtrig-timer.o 28obj-$(CONFIG_LEDS_TRIGGER_TIMER) += ledtrig-timer.o
diff --git a/drivers/leds/led-triggers.c b/drivers/leds/led-triggers.c
index 0f242b3f09b6..f910eaffe3a6 100644
--- a/drivers/leds/led-triggers.c
+++ b/drivers/leds/led-triggers.c
@@ -111,16 +111,17 @@ void led_trigger_set(struct led_classdev *led_cdev, struct led_trigger *trigger)
111 flags); 111 flags);
112 if (led_cdev->trigger->deactivate) 112 if (led_cdev->trigger->deactivate)
113 led_cdev->trigger->deactivate(led_cdev); 113 led_cdev->trigger->deactivate(led_cdev);
114 led_cdev->trigger = NULL;
114 led_set_brightness(led_cdev, LED_OFF); 115 led_set_brightness(led_cdev, LED_OFF);
115 } 116 }
116 if (trigger) { 117 if (trigger) {
117 write_lock_irqsave(&trigger->leddev_list_lock, flags); 118 write_lock_irqsave(&trigger->leddev_list_lock, flags);
118 list_add_tail(&led_cdev->trig_list, &trigger->led_cdevs); 119 list_add_tail(&led_cdev->trig_list, &trigger->led_cdevs);
119 write_unlock_irqrestore(&trigger->leddev_list_lock, flags); 120 write_unlock_irqrestore(&trigger->leddev_list_lock, flags);
121 led_cdev->trigger = trigger;
120 if (trigger->activate) 122 if (trigger->activate)
121 trigger->activate(led_cdev); 123 trigger->activate(led_cdev);
122 } 124 }
123 led_cdev->trigger = trigger;
124} 125}
125EXPORT_SYMBOL_GPL(led_trigger_set); 126EXPORT_SYMBOL_GPL(led_trigger_set);
126 127
diff --git a/drivers/leds/leds-atmel-pwm.c b/drivers/leds/leds-atmel-pwm.c
index 28db6c1444ed..52297c3ab246 100644
--- a/drivers/leds/leds-atmel-pwm.c
+++ b/drivers/leds/leds-atmel-pwm.c
@@ -37,7 +37,7 @@ static int __init pwmled_probe(struct platform_device *pdev)
37{ 37{
38 const struct gpio_led_platform_data *pdata; 38 const struct gpio_led_platform_data *pdata;
39 struct pwmled *leds; 39 struct pwmled *leds;
40 unsigned i; 40 int i;
41 int status; 41 int status;
42 42
43 pdata = pdev->dev.platform_data; 43 pdata = pdev->dev.platform_data;
diff --git a/drivers/leds/leds-h1940.c b/drivers/leds/leds-h1940.c
index bcec42230389..73c705021686 100644
--- a/drivers/leds/leds-h1940.c
+++ b/drivers/leds/leds-h1940.c
@@ -23,7 +23,8 @@
23/* 23/*
24 * Green led. 24 * Green led.
25 */ 25 */
26void h1940_greenled_set(struct led_classdev *led_dev, enum led_brightness value) 26static void h1940_greenled_set(struct led_classdev *led_dev,
27 enum led_brightness value)
27{ 28{
28 switch (value) { 29 switch (value) {
29 case LED_HALF: 30 case LED_HALF:
@@ -52,7 +53,8 @@ static struct led_classdev h1940_greenled = {
52/* 53/*
53 * Red led. 54 * Red led.
54 */ 55 */
55void h1940_redled_set(struct led_classdev *led_dev, enum led_brightness value) 56static void h1940_redled_set(struct led_classdev *led_dev,
57 enum led_brightness value)
56{ 58{
57 switch (value) { 59 switch (value) {
58 case LED_HALF: 60 case LED_HALF:
@@ -82,7 +84,8 @@ static struct led_classdev h1940_redled = {
82 * Blue led. 84 * Blue led.
83 * (it can only be blue flashing led) 85 * (it can only be blue flashing led)
84 */ 86 */
85void h1940_blueled_set(struct led_classdev *led_dev, enum led_brightness value) 87static void h1940_blueled_set(struct led_classdev *led_dev,
88 enum led_brightness value)
86{ 89{
87 if (value) { 90 if (value) {
88 /* flashing Blue */ 91 /* flashing Blue */
diff --git a/drivers/leds/leds-pca9532.c b/drivers/leds/leds-pca9532.c
new file mode 100644
index 000000000000..4064d4f6b33b
--- /dev/null
+++ b/drivers/leds/leds-pca9532.c
@@ -0,0 +1,337 @@
1/*
2 * pca9532.c - 16-bit Led dimmer
3 *
4 * Copyright (C) 2008 Riku Voipio <riku.voipio@movial.fi>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 2 of the License.
9 *
10 * Datasheet: http://www.nxp.com/acrobat/datasheets/PCA9532_3.pdf
11 *
12 */
13
14#include <linux/module.h>
15#include <linux/i2c.h>
16#include <linux/leds.h>
17#include <linux/input.h>
18#include <linux/mutex.h>
19#include <linux/leds-pca9532.h>
20
21static const unsigned short normal_i2c[] = { /*0x60,*/ I2C_CLIENT_END};
22I2C_CLIENT_INSMOD_1(pca9532);
23
24#define PCA9532_REG_PSC(i) (0x2+(i)*2)
25#define PCA9532_REG_PWM(i) (0x3+(i)*2)
26#define PCA9532_REG_LS0 0x6
27#define LED_REG(led) ((led>>2)+PCA9532_REG_LS0)
28#define LED_NUM(led) (led & 0x3)
29
30#define ldev_to_led(c) container_of(c, struct pca9532_led, ldev)
31
32struct pca9532_data {
33 struct i2c_client *client;
34 struct pca9532_led leds[16];
35 struct mutex update_lock;
36 struct input_dev *idev;
37 u8 pwm[2];
38 u8 psc[2];
39};
40
41static int pca9532_probe(struct i2c_client *client,
42 const struct i2c_device_id *id);
43static int pca9532_remove(struct i2c_client *client);
44
45static const struct i2c_device_id pca9532_id[] = {
46 { "pca9532", 0 },
47 { }
48};
49
50MODULE_DEVICE_TABLE(i2c, pca9532_id);
51
52static struct i2c_driver pca9532_driver = {
53 .driver = {
54 .name = "pca9532",
55 },
56 .probe = pca9532_probe,
57 .remove = pca9532_remove,
58 .id_table = pca9532_id,
59};
60
61/* We have two pwm/blinkers, but 16 possible leds to drive. Additionaly,
62 * the clever Thecus people are using one pwm to drive the beeper. So,
63 * as a compromise we average one pwm to the values requested by all
64 * leds that are not ON/OFF.
65 * */
66static int pca9532_setpwm(struct i2c_client *client, int pwm, int blink,
67 enum led_brightness value)
68{
69 int a = 0, b = 0, i = 0;
70 struct pca9532_data *data = i2c_get_clientdata(client);
71 for (i = 0; i < 16; i++) {
72 if (data->leds[i].type == PCA9532_TYPE_LED &&
73 data->leds[i].state == PCA9532_PWM0+pwm) {
74 a++;
75 b += data->leds[i].ldev.brightness;
76 }
77 }
78 if (a == 0) {
79 dev_err(&client->dev,
80 "fear of division by zero %d/%d, wanted %d\n",
81 b, a, value);
82 return -EINVAL;
83 }
84 b = b/a;
85 if (b > 0xFF)
86 return -EINVAL;
87 mutex_lock(&data->update_lock);
88 data->pwm[pwm] = b;
89 i2c_smbus_write_byte_data(client, PCA9532_REG_PWM(pwm),
90 data->pwm[pwm]);
91 data->psc[pwm] = blink;
92 i2c_smbus_write_byte_data(client, PCA9532_REG_PSC(pwm),
93 data->psc[pwm]);
94 mutex_unlock(&data->update_lock);
95 return 0;
96}
97
98/* Set LED routing */
99static void pca9532_setled(struct pca9532_led *led)
100{
101 struct i2c_client *client = led->client;
102 struct pca9532_data *data = i2c_get_clientdata(client);
103 char reg;
104
105 mutex_lock(&data->update_lock);
106 reg = i2c_smbus_read_byte_data(client, LED_REG(led->id));
107 /* zero led bits */
108 reg = reg & ~(0x3<<LED_NUM(led->id)*2);
109 /* set the new value */
110 reg = reg | (led->state << LED_NUM(led->id)*2);
111 i2c_smbus_write_byte_data(client, LED_REG(led->id), reg);
112 mutex_unlock(&data->update_lock);
113}
114
115static void pca9532_set_brightness(struct led_classdev *led_cdev,
116 enum led_brightness value)
117{
118 int err = 0;
119 struct pca9532_led *led = ldev_to_led(led_cdev);
120
121 if (value == LED_OFF)
122 led->state = PCA9532_OFF;
123 else if (value == LED_FULL)
124 led->state = PCA9532_ON;
125 else {
126 led->state = PCA9532_PWM0; /* Thecus: hardcode one pwm */
127 err = pca9532_setpwm(led->client, 0, 0, value);
128 if (err)
129 return; /* XXX: led api doesn't allow error code? */
130 }
131 pca9532_setled(led);
132}
133
134static int pca9532_set_blink(struct led_classdev *led_cdev,
135 unsigned long *delay_on, unsigned long *delay_off)
136{
137 struct pca9532_led *led = ldev_to_led(led_cdev);
138 struct i2c_client *client = led->client;
139 int psc;
140
141 if (*delay_on == 0 && *delay_off == 0) {
142 /* led subsystem ask us for a blink rate */
143 *delay_on = 1000;
144 *delay_off = 1000;
145 }
146 if (*delay_on != *delay_off || *delay_on > 1690 || *delay_on < 6)
147 return -EINVAL;
148
149 /* Thecus specific: only use PSC/PWM 0 */
150 psc = (*delay_on * 152-1)/1000;
151 return pca9532_setpwm(client, 0, psc, led_cdev->brightness);
152}
153
154int pca9532_event(struct input_dev *dev, unsigned int type, unsigned int code,
155 int value)
156{
157 struct pca9532_data *data = input_get_drvdata(dev);
158
159 if (type != EV_SND && (code != SND_BELL || code != SND_TONE))
160 return -1;
161
162 /* XXX: allow different kind of beeps with psc/pwm modifications */
163 if (value > 1 && value < 32767)
164 data->pwm[1] = 127;
165 else
166 data->pwm[1] = 0;
167
168 dev_info(&dev->dev, "setting beep to %d \n", data->pwm[1]);
169 mutex_lock(&data->update_lock);
170 i2c_smbus_write_byte_data(data->client, PCA9532_REG_PWM(1),
171 data->pwm[1]);
172 mutex_unlock(&data->update_lock);
173
174 return 0;
175}
176
177static int pca9532_configure(struct i2c_client *client,
178 struct pca9532_data *data, struct pca9532_platform_data *pdata)
179{
180 int i, err = 0;
181
182 for (i = 0; i < 2; i++) {
183 data->pwm[i] = pdata->pwm[i];
184 data->psc[i] = pdata->psc[i];
185 i2c_smbus_write_byte_data(client, PCA9532_REG_PWM(i),
186 data->pwm[i]);
187 i2c_smbus_write_byte_data(client, PCA9532_REG_PSC(i),
188 data->psc[i]);
189 }
190
191 for (i = 0; i < 16; i++) {
192 struct pca9532_led *led = &data->leds[i];
193 struct pca9532_led *pled = &pdata->leds[i];
194 led->client = client;
195 led->id = i;
196 led->type = pled->type;
197 switch (led->type) {
198 case PCA9532_TYPE_NONE:
199 break;
200 case PCA9532_TYPE_LED:
201 led->state = pled->state;
202 led->name = pled->name;
203 led->ldev.name = led->name;
204 led->ldev.brightness = LED_OFF;
205 led->ldev.brightness_set = pca9532_set_brightness;
206 led->ldev.blink_set = pca9532_set_blink;
207 if (led_classdev_register(&client->dev,
208 &led->ldev) < 0) {
209 dev_err(&client->dev,
210 "couldn't register LED %s\n",
211 led->name);
212 goto exit;
213 }
214 pca9532_setled(led);
215 break;
216 case PCA9532_TYPE_N2100_BEEP:
217 BUG_ON(data->idev);
218 led->state = PCA9532_PWM1;
219 pca9532_setled(led);
220 data->idev = input_allocate_device();
221 if (data->idev == NULL) {
222 err = -ENOMEM;
223 goto exit;
224 }
225 data->idev->name = pled->name;
226 data->idev->phys = "i2c/pca9532";
227 data->idev->id.bustype = BUS_HOST;
228 data->idev->id.vendor = 0x001f;
229 data->idev->id.product = 0x0001;
230 data->idev->id.version = 0x0100;
231 data->idev->evbit[0] = BIT_MASK(EV_SND);
232 data->idev->sndbit[0] = BIT_MASK(SND_BELL) |
233 BIT_MASK(SND_TONE);
234 data->idev->event = pca9532_event;
235 input_set_drvdata(data->idev, data);
236 err = input_register_device(data->idev);
237 if (err) {
238 input_free_device(data->idev);
239 data->idev = NULL;
240 goto exit;
241 }
242 break;
243 }
244 }
245 return 0;
246
247exit:
248 if (i > 0)
249 for (i = i - 1; i >= 0; i--)
250 switch (data->leds[i].type) {
251 case PCA9532_TYPE_NONE:
252 break;
253 case PCA9532_TYPE_LED:
254 led_classdev_unregister(&data->leds[i].ldev);
255 break;
256 case PCA9532_TYPE_N2100_BEEP:
257 if (data->idev != NULL) {
258 input_unregister_device(data->idev);
259 input_free_device(data->idev);
260 data->idev = NULL;
261 }
262 break;
263 }
264
265 return err;
266
267}
268
269static int pca9532_probe(struct i2c_client *client,
270 const struct i2c_device_id *id)
271{
272 struct pca9532_data *data = i2c_get_clientdata(client);
273 struct pca9532_platform_data *pca9532_pdata = client->dev.platform_data;
274
275 if (!i2c_check_functionality(client->adapter,
276 I2C_FUNC_SMBUS_BYTE_DATA))
277 return -EIO;
278
279 data = kzalloc(sizeof(struct pca9532_data), GFP_KERNEL);
280 if (!data)
281 return -ENOMEM;
282
283 dev_info(&client->dev, "setting platform data\n");
284 i2c_set_clientdata(client, data);
285 data->client = client;
286 mutex_init(&data->update_lock);
287
288 if (pca9532_pdata == NULL)
289 return -EIO;
290
291 pca9532_configure(client, data, pca9532_pdata);
292 return 0;
293
294}
295
296static int pca9532_remove(struct i2c_client *client)
297{
298 struct pca9532_data *data = i2c_get_clientdata(client);
299 int i;
300 for (i = 0; i < 16; i++)
301 switch (data->leds[i].type) {
302 case PCA9532_TYPE_NONE:
303 break;
304 case PCA9532_TYPE_LED:
305 led_classdev_unregister(&data->leds[i].ldev);
306 break;
307 case PCA9532_TYPE_N2100_BEEP:
308 if (data->idev != NULL) {
309 input_unregister_device(data->idev);
310 input_free_device(data->idev);
311 data->idev = NULL;
312 }
313 break;
314 }
315
316 kfree(data);
317 i2c_set_clientdata(client, NULL);
318 return 0;
319}
320
321static int __init pca9532_init(void)
322{
323 return i2c_add_driver(&pca9532_driver);
324}
325
326static void __exit pca9532_exit(void)
327{
328 i2c_del_driver(&pca9532_driver);
329}
330
331MODULE_AUTHOR("Riku Voipio <riku.voipio@movial.fi>");
332MODULE_LICENSE("GPL");
333MODULE_DESCRIPTION("PCA 9532 LED dimmer");
334
335module_init(pca9532_init);
336module_exit(pca9532_exit);
337
diff --git a/drivers/leds/leds-pca955x.c b/drivers/leds/leds-pca955x.c
new file mode 100644
index 000000000000..146c06972863
--- /dev/null
+++ b/drivers/leds/leds-pca955x.c
@@ -0,0 +1,384 @@
1/*
2 * Copyright 2007-2008 Extreme Engineering Solutions, Inc.
3 *
4 * Author: Nate Case <ncase@xes-inc.com>
5 *
6 * This file is subject to the terms and conditions of version 2 of
7 * the GNU General Public License. See the file COPYING in the main
8 * directory of this archive for more details.
9 *
10 * LED driver for various PCA955x I2C LED drivers
11 *
12 * Supported devices:
13 *
14 * Device Description 7-bit slave address
15 * ------ ----------- -------------------
16 * PCA9550 2-bit driver 0x60 .. 0x61
17 * PCA9551 8-bit driver 0x60 .. 0x67
18 * PCA9552 16-bit driver 0x60 .. 0x67
19 * PCA9553/01 4-bit driver 0x62
20 * PCA9553/02 4-bit driver 0x63
21 *
22 * Philips PCA955x LED driver chips follow a register map as shown below:
23 *
24 * Control Register Description
25 * ---------------- -----------
26 * 0x0 Input register 0
27 * ..
28 * NUM_INPUT_REGS - 1 Last Input register X
29 *
30 * NUM_INPUT_REGS Frequency prescaler 0
31 * NUM_INPUT_REGS + 1 PWM register 0
32 * NUM_INPUT_REGS + 2 Frequency prescaler 1
33 * NUM_INPUT_REGS + 3 PWM register 1
34 *
35 * NUM_INPUT_REGS + 4 LED selector 0
36 * NUM_INPUT_REGS + 4
37 * + NUM_LED_REGS - 1 Last LED selector
38 *
39 * where NUM_INPUT_REGS and NUM_LED_REGS vary depending on how many
40 * bits the chip supports.
41 */
42
43#include <linux/module.h>
44#include <linux/delay.h>
45#include <linux/string.h>
46#include <linux/ctype.h>
47#include <linux/leds.h>
48#include <linux/err.h>
49#include <linux/i2c.h>
50#include <linux/workqueue.h>
51
52/* LED select registers determine the source that drives LED outputs */
53#define PCA955X_LS_LED_ON 0x0 /* Output LOW */
54#define PCA955X_LS_LED_OFF 0x1 /* Output HI-Z */
55#define PCA955X_LS_BLINK0 0x2 /* Blink at PWM0 rate */
56#define PCA955X_LS_BLINK1 0x3 /* Blink at PWM1 rate */
57
58enum pca955x_type {
59 pca9550,
60 pca9551,
61 pca9552,
62 pca9553,
63};
64
65struct pca955x_chipdef {
66 int bits;
67 u8 slv_addr; /* 7-bit slave address mask */
68 int slv_addr_shift; /* Number of bits to ignore */
69};
70
71static struct pca955x_chipdef pca955x_chipdefs[] = {
72 [pca9550] = {
73 .bits = 2,
74 .slv_addr = /* 110000x */ 0x60,
75 .slv_addr_shift = 1,
76 },
77 [pca9551] = {
78 .bits = 8,
79 .slv_addr = /* 1100xxx */ 0x60,
80 .slv_addr_shift = 3,
81 },
82 [pca9552] = {
83 .bits = 16,
84 .slv_addr = /* 1100xxx */ 0x60,
85 .slv_addr_shift = 3,
86 },
87 [pca9553] = {
88 .bits = 4,
89 .slv_addr = /* 110001x */ 0x62,
90 .slv_addr_shift = 1,
91 },
92};
93
94static const struct i2c_device_id pca955x_id[] = {
95 { "pca9550", pca9550 },
96 { "pca9551", pca9551 },
97 { "pca9552", pca9552 },
98 { "pca9553", pca9553 },
99 { }
100};
101MODULE_DEVICE_TABLE(i2c, pca955x_id);
102
103struct pca955x_led {
104 struct pca955x_chipdef *chipdef;
105 struct i2c_client *client;
106 struct work_struct work;
107 spinlock_t lock;
108 enum led_brightness brightness;
109 struct led_classdev led_cdev;
110 int led_num; /* 0 .. 15 potentially */
111 char name[32];
112};
113
114/* 8 bits per input register */
115static inline int pca95xx_num_input_regs(int bits)
116{
117 return (bits + 7) / 8;
118}
119
120/* 4 bits per LED selector register */
121static inline int pca95xx_num_led_regs(int bits)
122{
123 return (bits + 3) / 4;
124}
125
126/*
127 * Return an LED selector register value based on an existing one, with
128 * the appropriate 2-bit state value set for the given LED number (0-3).
129 */
130static inline u8 pca955x_ledsel(u8 oldval, int led_num, int state)
131{
132 return (oldval & (~(0x3 << (led_num << 1)))) |
133 ((state & 0x3) << (led_num << 1));
134}
135
136/*
137 * Write to frequency prescaler register, used to program the
138 * period of the PWM output. period = (PSCx + 1) / 38
139 */
140static void pca955x_write_psc(struct i2c_client *client, int n, u8 val)
141{
142 struct pca955x_led *pca955x = i2c_get_clientdata(client);
143
144 i2c_smbus_write_byte_data(client,
145 pca95xx_num_input_regs(pca955x->chipdef->bits) + 2*n,
146 val);
147}
148
149/*
150 * Write to PWM register, which determines the duty cycle of the
151 * output. LED is OFF when the count is less than the value of this
152 * register, and ON when it is greater. If PWMx == 0, LED is always OFF.
153 *
154 * Duty cycle is (256 - PWMx) / 256
155 */
156static void pca955x_write_pwm(struct i2c_client *client, int n, u8 val)
157{
158 struct pca955x_led *pca955x = i2c_get_clientdata(client);
159
160 i2c_smbus_write_byte_data(client,
161 pca95xx_num_input_regs(pca955x->chipdef->bits) + 1 + 2*n,
162 val);
163}
164
165/*
166 * Write to LED selector register, which determines the source that
167 * drives the LED output.
168 */
169static void pca955x_write_ls(struct i2c_client *client, int n, u8 val)
170{
171 struct pca955x_led *pca955x = i2c_get_clientdata(client);
172
173 i2c_smbus_write_byte_data(client,
174 pca95xx_num_input_regs(pca955x->chipdef->bits) + 4 + n,
175 val);
176}
177
178/*
179 * Read the LED selector register, which determines the source that
180 * drives the LED output.
181 */
182static u8 pca955x_read_ls(struct i2c_client *client, int n)
183{
184 struct pca955x_led *pca955x = i2c_get_clientdata(client);
185
186 return (u8) i2c_smbus_read_byte_data(client,
187 pca95xx_num_input_regs(pca955x->chipdef->bits) + 4 + n);
188}
189
190static void pca955x_led_work(struct work_struct *work)
191{
192 struct pca955x_led *pca955x;
193 u8 ls;
194 int chip_ls; /* which LSx to use (0-3 potentially) */
195 int ls_led; /* which set of bits within LSx to use (0-3) */
196
197 pca955x = container_of(work, struct pca955x_led, work);
198 chip_ls = pca955x->led_num / 4;
199 ls_led = pca955x->led_num % 4;
200
201 ls = pca955x_read_ls(pca955x->client, chip_ls);
202
203 switch (pca955x->brightness) {
204 case LED_FULL:
205 ls = pca955x_ledsel(ls, ls_led, PCA955X_LS_LED_ON);
206 break;
207 case LED_OFF:
208 ls = pca955x_ledsel(ls, ls_led, PCA955X_LS_LED_OFF);
209 break;
210 case LED_HALF:
211 ls = pca955x_ledsel(ls, ls_led, PCA955X_LS_BLINK0);
212 break;
213 default:
214 /*
215 * Use PWM1 for all other values. This has the unwanted
216 * side effect of making all LEDs on the chip share the
217 * same brightness level if set to a value other than
218 * OFF, HALF, or FULL. But, this is probably better than
219 * just turning off for all other values.
220 */
221 pca955x_write_pwm(pca955x->client, 1, 255-pca955x->brightness);
222 ls = pca955x_ledsel(ls, ls_led, PCA955X_LS_BLINK1);
223 break;
224 }
225
226 pca955x_write_ls(pca955x->client, chip_ls, ls);
227}
228
229void pca955x_led_set(struct led_classdev *led_cdev, enum led_brightness value)
230{
231 struct pca955x_led *pca955x;
232
233 pca955x = container_of(led_cdev, struct pca955x_led, led_cdev);
234
235 spin_lock(&pca955x->lock);
236 pca955x->brightness = value;
237
238 /*
239 * Must use workqueue for the actual I/O since I2C operations
240 * can sleep.
241 */
242 schedule_work(&pca955x->work);
243
244 spin_unlock(&pca955x->lock);
245}
246
247static int __devinit pca955x_probe(struct i2c_client *client,
248 const struct i2c_device_id *id)
249{
250 struct pca955x_led *pca955x;
251 int i;
252 int err = -ENODEV;
253 struct pca955x_chipdef *chip;
254 struct i2c_adapter *adapter;
255 struct led_platform_data *pdata;
256
257 chip = &pca955x_chipdefs[id->driver_data];
258 adapter = to_i2c_adapter(client->dev.parent);
259 pdata = client->dev.platform_data;
260
261 /* Make sure the slave address / chip type combo given is possible */
262 if ((client->addr & ~((1 << chip->slv_addr_shift) - 1)) !=
263 chip->slv_addr) {
264 dev_err(&client->dev, "invalid slave address %02x\n",
265 client->addr);
266 return -ENODEV;
267 }
268
269 printk(KERN_INFO "leds-pca955x: Using %s %d-bit LED driver at "
270 "slave address 0x%02x\n",
271 id->name, chip->bits, client->addr);
272
273 if (!i2c_check_functionality(adapter, I2C_FUNC_I2C))
274 return -EIO;
275
276 if (pdata) {
277 if (pdata->num_leds != chip->bits) {
278 dev_err(&client->dev, "board info claims %d LEDs"
279 " on a %d-bit chip\n",
280 pdata->num_leds, chip->bits);
281 return -ENODEV;
282 }
283 }
284
285 for (i = 0; i < chip->bits; i++) {
286 pca955x = kzalloc(sizeof(struct pca955x_led), GFP_KERNEL);
287 if (!pca955x) {
288 err = -ENOMEM;
289 goto exit;
290 }
291
292 pca955x->chipdef = chip;
293 pca955x->client = client;
294 pca955x->led_num = i;
295 /* Platform data can specify LED names and default triggers */
296 if (pdata) {
297 if (pdata->leds[i].name)
298 snprintf(pca955x->name, 32, "pca955x:%s",
299 pdata->leds[i].name);
300 if (pdata->leds[i].default_trigger)
301 pca955x->led_cdev.default_trigger =
302 pdata->leds[i].default_trigger;
303 } else {
304 snprintf(pca955x->name, 32, "pca955x:%d", i);
305 }
306 spin_lock_init(&pca955x->lock);
307
308 pca955x->led_cdev.name = pca955x->name;
309 pca955x->led_cdev.brightness_set =
310 pca955x_led_set;
311
312 /*
313 * Client data is a pointer to the _first_ pca955x_led
314 * struct
315 */
316 if (i == 0)
317 i2c_set_clientdata(client, pca955x);
318
319 INIT_WORK(&(pca955x->work), pca955x_led_work);
320
321 led_classdev_register(&client->dev, &(pca955x->led_cdev));
322 }
323
324 /* Turn off LEDs */
325 for (i = 0; i < pca95xx_num_led_regs(chip->bits); i++)
326 pca955x_write_ls(client, i, 0x55);
327
328 /* PWM0 is used for half brightness or 50% duty cycle */
329 pca955x_write_pwm(client, 0, 255-LED_HALF);
330
331 /* PWM1 is used for variable brightness, default to OFF */
332 pca955x_write_pwm(client, 1, 0);
333
334 /* Set to fast frequency so we do not see flashing */
335 pca955x_write_psc(client, 0, 0);
336 pca955x_write_psc(client, 1, 0);
337
338 return 0;
339exit:
340 return err;
341}
342
343static int __devexit pca955x_remove(struct i2c_client *client)
344{
345 struct pca955x_led *pca955x = i2c_get_clientdata(client);
346 int leds = pca955x->chipdef->bits;
347 int i;
348
349 for (i = 0; i < leds; i++) {
350 led_classdev_unregister(&(pca955x->led_cdev));
351 cancel_work_sync(&(pca955x->work));
352 kfree(pca955x);
353 pca955x = pca955x + 1;
354 }
355
356 return 0;
357}
358
359static struct i2c_driver pca955x_driver = {
360 .driver = {
361 .name = "leds-pca955x",
362 .owner = THIS_MODULE,
363 },
364 .probe = pca955x_probe,
365 .remove = __devexit_p(pca955x_remove),
366 .id_table = pca955x_id,
367};
368
369static int __init pca955x_leds_init(void)
370{
371 return i2c_add_driver(&pca955x_driver);
372}
373
374static void __exit pca955x_leds_exit(void)
375{
376 i2c_del_driver(&pca955x_driver);
377}
378
379module_init(pca955x_leds_init);
380module_exit(pca955x_leds_exit);
381
382MODULE_AUTHOR("Nate Case <ncase@xes-inc.com>");
383MODULE_DESCRIPTION("PCA955x LED driver");
384MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/video/pvrusb2/pvrusb2-dvb.c b/drivers/media/video/pvrusb2/pvrusb2-dvb.c
index 6ec4bf81fc7f..77b3c3385066 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-dvb.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-dvb.c
@@ -20,6 +20,7 @@
20 20
21#include <linux/kthread.h> 21#include <linux/kthread.h>
22#include <linux/freezer.h> 22#include <linux/freezer.h>
23#include <linux/mm.h>
23#include "dvbdev.h" 24#include "dvbdev.h"
24#include "pvrusb2-debug.h" 25#include "pvrusb2-debug.h"
25#include "pvrusb2-hdw-internal.h" 26#include "pvrusb2-hdw-internal.h"
diff --git a/drivers/media/video/pvrusb2/pvrusb2-ioread.c b/drivers/media/video/pvrusb2/pvrusb2-ioread.c
index 05a1376405e7..b4824782d858 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-ioread.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-ioread.c
@@ -22,6 +22,7 @@
22#include "pvrusb2-debug.h" 22#include "pvrusb2-debug.h"
23#include <linux/errno.h> 23#include <linux/errno.h>
24#include <linux/string.h> 24#include <linux/string.h>
25#include <linux/mm.h>
25#include <linux/slab.h> 26#include <linux/slab.h>
26#include <linux/mutex.h> 27#include <linux/mutex.h>
27#include <asm/uaccess.h> 28#include <asm/uaccess.h>
diff --git a/drivers/media/video/uvc/uvc_queue.c b/drivers/media/video/uvc/uvc_queue.c
index 7388d0cee3d4..5646a6a32939 100644
--- a/drivers/media/video/uvc/uvc_queue.c
+++ b/drivers/media/video/uvc/uvc_queue.c
@@ -13,6 +13,7 @@
13 13
14#include <linux/kernel.h> 14#include <linux/kernel.h>
15#include <linux/version.h> 15#include <linux/version.h>
16#include <linux/mm.h>
16#include <linux/list.h> 17#include <linux/list.h>
17#include <linux/module.h> 18#include <linux/module.h>
18#include <linux/usb.h> 19#include <linux/usb.h>
diff --git a/drivers/media/video/videobuf-core.c b/drivers/media/video/videobuf-core.c
index 0a88c44ace00..b7b05842cf28 100644
--- a/drivers/media/video/videobuf-core.c
+++ b/drivers/media/video/videobuf-core.c
@@ -16,6 +16,7 @@
16#include <linux/init.h> 16#include <linux/init.h>
17#include <linux/module.h> 17#include <linux/module.h>
18#include <linux/moduleparam.h> 18#include <linux/moduleparam.h>
19#include <linux/mm.h>
19#include <linux/slab.h> 20#include <linux/slab.h>
20#include <linux/interrupt.h> 21#include <linux/interrupt.h>
21 22
diff --git a/drivers/message/i2o/device.c b/drivers/message/i2o/device.c
index 489d7c5c4965..8774c670e668 100644
--- a/drivers/message/i2o/device.c
+++ b/drivers/message/i2o/device.c
@@ -243,29 +243,41 @@ static int i2o_device_add(struct i2o_controller *c, i2o_lct_entry *entry)
243 243
244 /* create user entries for this device */ 244 /* create user entries for this device */
245 tmp = i2o_iop_find_device(i2o_dev->iop, i2o_dev->lct_data.user_tid); 245 tmp = i2o_iop_find_device(i2o_dev->iop, i2o_dev->lct_data.user_tid);
246 if (tmp && (tmp != i2o_dev)) 246 if (tmp && (tmp != i2o_dev)) {
247 sysfs_create_link(&i2o_dev->device.kobj, &tmp->device.kobj, 247 rc = sysfs_create_link(&i2o_dev->device.kobj,
248 "user"); 248 &tmp->device.kobj, "user");
249 if (rc)
250 goto unreg_dev;
251 }
249 252
250 /* create user entries refering to this device */ 253 /* create user entries refering to this device */
251 list_for_each_entry(tmp, &c->devices, list) 254 list_for_each_entry(tmp, &c->devices, list)
252 if ((tmp->lct_data.user_tid == i2o_dev->lct_data.tid) 255 if ((tmp->lct_data.user_tid == i2o_dev->lct_data.tid)
253 && (tmp != i2o_dev)) 256 && (tmp != i2o_dev)) {
254 sysfs_create_link(&tmp->device.kobj, 257 rc = sysfs_create_link(&tmp->device.kobj,
255 &i2o_dev->device.kobj, "user"); 258 &i2o_dev->device.kobj, "user");
259 if (rc)
260 goto rmlink1;
261 }
256 262
257 /* create parent entries for this device */ 263 /* create parent entries for this device */
258 tmp = i2o_iop_find_device(i2o_dev->iop, i2o_dev->lct_data.parent_tid); 264 tmp = i2o_iop_find_device(i2o_dev->iop, i2o_dev->lct_data.parent_tid);
259 if (tmp && (tmp != i2o_dev)) 265 if (tmp && (tmp != i2o_dev)) {
260 sysfs_create_link(&i2o_dev->device.kobj, &tmp->device.kobj, 266 rc = sysfs_create_link(&i2o_dev->device.kobj,
261 "parent"); 267 &tmp->device.kobj, "parent");
268 if (rc)
269 goto rmlink1;
270 }
262 271
263 /* create parent entries refering to this device */ 272 /* create parent entries refering to this device */
264 list_for_each_entry(tmp, &c->devices, list) 273 list_for_each_entry(tmp, &c->devices, list)
265 if ((tmp->lct_data.parent_tid == i2o_dev->lct_data.tid) 274 if ((tmp->lct_data.parent_tid == i2o_dev->lct_data.tid)
266 && (tmp != i2o_dev)) 275 && (tmp != i2o_dev)) {
267 sysfs_create_link(&tmp->device.kobj, 276 rc = sysfs_create_link(&tmp->device.kobj,
268 &i2o_dev->device.kobj, "parent"); 277 &i2o_dev->device.kobj, "parent");
278 if (rc)
279 goto rmlink2;
280 }
269 281
270 i2o_driver_notify_device_add_all(i2o_dev); 282 i2o_driver_notify_device_add_all(i2o_dev);
271 283
@@ -273,6 +285,24 @@ static int i2o_device_add(struct i2o_controller *c, i2o_lct_entry *entry)
273 285
274 return 0; 286 return 0;
275 287
288rmlink2:
289 /* If link creating failed halfway, we loop whole list to cleanup.
290 * And we don't care wrong removing of link, because sysfs_remove_link
291 * will take care of it.
292 */
293 list_for_each_entry(tmp, &c->devices, list) {
294 if (tmp->lct_data.parent_tid == i2o_dev->lct_data.tid)
295 sysfs_remove_link(&tmp->device.kobj, "parent");
296 }
297 sysfs_remove_link(&i2o_dev->device.kobj, "parent");
298rmlink1:
299 list_for_each_entry(tmp, &c->devices, list)
300 if (tmp->lct_data.user_tid == i2o_dev->lct_data.tid)
301 sysfs_remove_link(&tmp->device.kobj, "user");
302 sysfs_remove_link(&i2o_dev->device.kobj, "user");
303unreg_dev:
304 list_del(&i2o_dev->list);
305 device_unregister(&i2o_dev->device);
276err: 306err:
277 kfree(i2o_dev); 307 kfree(i2o_dev);
278 return rc; 308 return rc;
diff --git a/drivers/misc/atmel_pwm.c b/drivers/misc/atmel_pwm.c
index 5b5a14dab3d3..6aa5294dfec4 100644
--- a/drivers/misc/atmel_pwm.c
+++ b/drivers/misc/atmel_pwm.c
@@ -211,8 +211,7 @@ int pwm_clk_alloc(unsigned prescale, unsigned div)
211 if ((mr & 0xffff) == 0) { 211 if ((mr & 0xffff) == 0) {
212 mr |= val; 212 mr |= val;
213 ret = PWM_CPR_CLKA; 213 ret = PWM_CPR_CLKA;
214 } 214 } else if ((mr & (0xffff << 16)) == 0) {
215 if ((mr & (0xffff << 16)) == 0) {
216 mr |= val << 16; 215 mr |= val << 16;
217 ret = PWM_CPR_CLKB; 216 ret = PWM_CPR_CLKB;
218 } 217 }
diff --git a/drivers/mtd/maps/uclinux.c b/drivers/mtd/maps/uclinux.c
index c42f4b83f686..3fcf92130aa4 100644
--- a/drivers/mtd/maps/uclinux.c
+++ b/drivers/mtd/maps/uclinux.c
@@ -15,6 +15,7 @@
15#include <linux/init.h> 15#include <linux/init.h>
16#include <linux/kernel.h> 16#include <linux/kernel.h>
17#include <linux/fs.h> 17#include <linux/fs.h>
18#include <linux/mm.h>
18#include <linux/major.h> 19#include <linux/major.h>
19#include <linux/mtd/mtd.h> 20#include <linux/mtd/mtd.h>
20#include <linux/mtd/map.h> 21#include <linux/mtd/map.h>
diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c
index 869544b8c05c..9c0f56b3c518 100644
--- a/drivers/net/e1000e/netdev.c
+++ b/drivers/net/e1000e/netdev.c
@@ -4067,8 +4067,6 @@ static void e1000_netpoll(struct net_device *netdev)
4067 disable_irq(adapter->pdev->irq); 4067 disable_irq(adapter->pdev->irq);
4068 e1000_intr(adapter->pdev->irq, netdev); 4068 e1000_intr(adapter->pdev->irq, netdev);
4069 4069
4070 e1000_clean_tx_irq(adapter);
4071
4072 enable_irq(adapter->pdev->irq); 4070 enable_irq(adapter->pdev->irq);
4073} 4071}
4074#endif 4072#endif
diff --git a/drivers/net/fec.c b/drivers/net/fec.c
index 32a4f17d35fc..ecd5c71a7a8a 100644
--- a/drivers/net/fec.c
+++ b/drivers/net/fec.c
@@ -2,12 +2,6 @@
2 * Fast Ethernet Controller (FEC) driver for Motorola MPC8xx. 2 * Fast Ethernet Controller (FEC) driver for Motorola MPC8xx.
3 * Copyright (c) 1997 Dan Malek (dmalek@jlc.net) 3 * Copyright (c) 1997 Dan Malek (dmalek@jlc.net)
4 * 4 *
5 * This version of the driver is specific to the FADS implementation,
6 * since the board contains control registers external to the processor
7 * for the control of the LevelOne LXT970 transceiver. The MPC860T manual
8 * describes connections using the internal parallel port I/O, which
9 * is basically all of Port D.
10 *
11 * Right now, I am very wasteful with the buffers. I allocate memory 5 * Right now, I am very wasteful with the buffers. I allocate memory
12 * pages and then divide them into 2K frame buffers. This way I know I 6 * pages and then divide them into 2K frame buffers. This way I know I
13 * have buffers large enough to hold one frame within one buffer descriptor. 7 * have buffers large enough to hold one frame within one buffer descriptor.
@@ -49,17 +43,9 @@
49#include <asm/pgtable.h> 43#include <asm/pgtable.h>
50#include <asm/cacheflush.h> 44#include <asm/cacheflush.h>
51 45
52#if defined(CONFIG_M523x) || defined(CONFIG_M527x) || \
53 defined(CONFIG_M5272) || defined(CONFIG_M528x) || \
54 defined(CONFIG_M520x) || defined(CONFIG_M532x)
55#include <asm/coldfire.h> 46#include <asm/coldfire.h>
56#include <asm/mcfsim.h> 47#include <asm/mcfsim.h>
57#include "fec.h" 48#include "fec.h"
58#else
59#include <asm/8xx_immap.h>
60#include <asm/mpc8xx.h>
61#include "commproc.h"
62#endif
63 49
64#if defined(CONFIG_FEC2) 50#if defined(CONFIG_FEC2)
65#define FEC_MAX_PORTS 2 51#define FEC_MAX_PORTS 2
@@ -67,7 +53,7 @@
67#define FEC_MAX_PORTS 1 53#define FEC_MAX_PORTS 1
68#endif 54#endif
69 55
70#if defined(CONFIG_FADS) || defined(CONFIG_RPXCLASSIC) || defined(CONFIG_M5272) 56#if defined(CONFIG_M5272)
71#define HAVE_mii_link_interrupt 57#define HAVE_mii_link_interrupt
72#endif 58#endif
73 59
@@ -1235,14 +1221,9 @@ static phy_info_t const * const phy_info[] = {
1235 1221
1236/* ------------------------------------------------------------------------- */ 1222/* ------------------------------------------------------------------------- */
1237#ifdef HAVE_mii_link_interrupt 1223#ifdef HAVE_mii_link_interrupt
1238#ifdef CONFIG_RPXCLASSIC
1239static void
1240mii_link_interrupt(void *dev_id);
1241#else
1242static irqreturn_t 1224static irqreturn_t
1243mii_link_interrupt(int irq, void * dev_id); 1225mii_link_interrupt(int irq, void * dev_id);
1244#endif 1226#endif
1245#endif
1246 1227
1247#if defined(CONFIG_M5272) 1228#if defined(CONFIG_M5272)
1248/* 1229/*
@@ -1795,24 +1776,6 @@ static void __inline__ fec_request_intrs(struct net_device *dev)
1795 1776
1796 if (request_8xxirq(FEC_INTERRUPT, fec_enet_interrupt, 0, "fec", dev) != 0) 1777 if (request_8xxirq(FEC_INTERRUPT, fec_enet_interrupt, 0, "fec", dev) != 0)
1797 panic("Could not allocate FEC IRQ!"); 1778 panic("Could not allocate FEC IRQ!");
1798
1799#ifdef CONFIG_RPXCLASSIC
1800 /* Make Port C, bit 15 an input that causes interrupts.
1801 */
1802 immap->im_ioport.iop_pcpar &= ~0x0001;
1803 immap->im_ioport.iop_pcdir &= ~0x0001;
1804 immap->im_ioport.iop_pcso &= ~0x0001;
1805 immap->im_ioport.iop_pcint |= 0x0001;
1806 cpm_install_handler(CPMVEC_PIO_PC15, mii_link_interrupt, dev);
1807
1808 /* Make LEDS reflect Link status.
1809 */
1810 *((uint *) RPX_CSR_ADDR) &= ~BCSR2_FETHLEDMODE;
1811#endif
1812#ifdef CONFIG_FADS
1813 if (request_8xxirq(SIU_IRQ2, mii_link_interrupt, 0, "mii", dev) != 0)
1814 panic("Could not allocate MII IRQ!");
1815#endif
1816} 1779}
1817 1780
1818static void __inline__ fec_get_mac(struct net_device *dev) 1781static void __inline__ fec_get_mac(struct net_device *dev)
@@ -1821,16 +1784,6 @@ static void __inline__ fec_get_mac(struct net_device *dev)
1821 1784
1822 bd = (bd_t *)__res; 1785 bd = (bd_t *)__res;
1823 memcpy(dev->dev_addr, bd->bi_enetaddr, ETH_ALEN); 1786 memcpy(dev->dev_addr, bd->bi_enetaddr, ETH_ALEN);
1824
1825#ifdef CONFIG_RPXCLASSIC
1826 /* The Embedded Planet boards have only one MAC address in
1827 * the EEPROM, but can have two Ethernet ports. For the
1828 * FEC port, we create another address by setting one of
1829 * the address bits above something that would have (up to
1830 * now) been allocated.
1831 */
1832 dev->dev_adrd[3] |= 0x80;
1833#endif
1834} 1787}
1835 1788
1836static void __inline__ fec_set_mii(struct net_device *dev, struct fec_enet_private *fep) 1789static void __inline__ fec_set_mii(struct net_device *dev, struct fec_enet_private *fep)
@@ -2109,13 +2062,8 @@ mii_discover_phy(uint mii_reg, struct net_device *dev)
2109/* This interrupt occurs when the PHY detects a link change. 2062/* This interrupt occurs when the PHY detects a link change.
2110*/ 2063*/
2111#ifdef HAVE_mii_link_interrupt 2064#ifdef HAVE_mii_link_interrupt
2112#ifdef CONFIG_RPXCLASSIC
2113static void
2114mii_link_interrupt(void *dev_id)
2115#else
2116static irqreturn_t 2065static irqreturn_t
2117mii_link_interrupt(int irq, void * dev_id) 2066mii_link_interrupt(int irq, void * dev_id)
2118#endif
2119{ 2067{
2120 struct net_device *dev = dev_id; 2068 struct net_device *dev = dev_id;
2121 struct fec_enet_private *fep = netdev_priv(dev); 2069 struct fec_enet_private *fep = netdev_priv(dev);
diff --git a/drivers/net/mlx4/eq.c b/drivers/net/mlx4/eq.c
index e141a1513f07..ea3a09aaa844 100644
--- a/drivers/net/mlx4/eq.c
+++ b/drivers/net/mlx4/eq.c
@@ -33,6 +33,7 @@
33 33
34#include <linux/init.h> 34#include <linux/init.h>
35#include <linux/interrupt.h> 35#include <linux/interrupt.h>
36#include <linux/mm.h>
36#include <linux/dma-mapping.h> 37#include <linux/dma-mapping.h>
37 38
38#include <linux/mlx4/cmd.h> 39#include <linux/mlx4/cmd.h>
diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c
index 711e4a8948e0..5257cf464f1a 100644
--- a/drivers/net/sky2.c
+++ b/drivers/net/sky2.c
@@ -1829,9 +1829,6 @@ static int sky2_down(struct net_device *dev)
1829 if (netif_msg_ifdown(sky2)) 1829 if (netif_msg_ifdown(sky2))
1830 printk(KERN_INFO PFX "%s: disabling interface\n", dev->name); 1830 printk(KERN_INFO PFX "%s: disabling interface\n", dev->name);
1831 1831
1832 /* Stop more packets from being queued */
1833 netif_stop_queue(dev);
1834
1835 /* Disable port IRQ */ 1832 /* Disable port IRQ */
1836 imask = sky2_read32(hw, B0_IMSK); 1833 imask = sky2_read32(hw, B0_IMSK);
1837 imask &= ~portirq_msk[port]; 1834 imask &= ~portirq_msk[port];
@@ -1887,8 +1884,6 @@ static int sky2_down(struct net_device *dev)
1887 1884
1888 sky2_phy_power_down(hw, port); 1885 sky2_phy_power_down(hw, port);
1889 1886
1890 netif_carrier_off(dev);
1891
1892 /* turn off LED's */ 1887 /* turn off LED's */
1893 sky2_write16(hw, B0_Y2LED, LED_STAT_OFF); 1888 sky2_write16(hw, B0_Y2LED, LED_STAT_OFF);
1894 1889
diff --git a/drivers/pcmcia/electra_cf.c b/drivers/pcmcia/electra_cf.c
index c21f9a9c3e3f..a34284b1482a 100644
--- a/drivers/pcmcia/electra_cf.c
+++ b/drivers/pcmcia/electra_cf.c
@@ -28,6 +28,7 @@
28#include <linux/init.h> 28#include <linux/init.h>
29#include <linux/delay.h> 29#include <linux/delay.h>
30#include <linux/interrupt.h> 30#include <linux/interrupt.h>
31#include <linux/mm.h>
31#include <linux/vmalloc.h> 32#include <linux/vmalloc.h>
32#include <linux/of_platform.h> 33#include <linux/of_platform.h>
33 34
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
index fc85bf2e4a97..90ab73825401 100644
--- a/drivers/rtc/Kconfig
+++ b/drivers/rtc/Kconfig
@@ -273,6 +273,25 @@ comment "SPI RTC drivers"
273 273
274if SPI_MASTER 274if SPI_MASTER
275 275
276config RTC_DRV_M41T94
277 tristate "ST M41T94"
278 help
279 If you say yes here you will get support for the
280 ST M41T94 SPI RTC chip.
281
282 This driver can also be built as a module. If so, the module
283 will be called rtc-m41t94.
284
285config RTC_DRV_DS1305
286 tristate "Dallas/Maxim DS1305/DS1306"
287 help
288 Select this driver to get support for the Dallas/Maxim DS1305
289 and DS1306 real time clock chips. These support a trickle
290 charger, alarms, and NVRAM in addition to the clock.
291
292 This driver can also be built as a module. If so, the module
293 will be called rtc-ds1305.
294
276config RTC_DRV_MAX6902 295config RTC_DRV_MAX6902
277 tristate "Maxim MAX6902" 296 tristate "Maxim MAX6902"
278 help 297 help
diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile
index b5d9d67df887..18622ef84cab 100644
--- a/drivers/rtc/Makefile
+++ b/drivers/rtc/Makefile
@@ -24,6 +24,7 @@ obj-$(CONFIG_RTC_DRV_BFIN) += rtc-bfin.o
24obj-$(CONFIG_RTC_DRV_CMOS) += rtc-cmos.o 24obj-$(CONFIG_RTC_DRV_CMOS) += rtc-cmos.o
25obj-$(CONFIG_RTC_DRV_DS1216) += rtc-ds1216.o 25obj-$(CONFIG_RTC_DRV_DS1216) += rtc-ds1216.o
26obj-$(CONFIG_RTC_DRV_DS1302) += rtc-ds1302.o 26obj-$(CONFIG_RTC_DRV_DS1302) += rtc-ds1302.o
27obj-$(CONFIG_RTC_DRV_DS1305) += rtc-ds1305.o
27obj-$(CONFIG_RTC_DRV_DS1307) += rtc-ds1307.o 28obj-$(CONFIG_RTC_DRV_DS1307) += rtc-ds1307.o
28obj-$(CONFIG_RTC_DRV_DS1374) += rtc-ds1374.o 29obj-$(CONFIG_RTC_DRV_DS1374) += rtc-ds1374.o
29obj-$(CONFIG_RTC_DRV_DS1511) += rtc-ds1511.o 30obj-$(CONFIG_RTC_DRV_DS1511) += rtc-ds1511.o
@@ -34,6 +35,7 @@ obj-$(CONFIG_RTC_DRV_EP93XX) += rtc-ep93xx.o
34obj-$(CONFIG_RTC_DRV_FM3130) += rtc-fm3130.o 35obj-$(CONFIG_RTC_DRV_FM3130) += rtc-fm3130.o
35obj-$(CONFIG_RTC_DRV_ISL1208) += rtc-isl1208.o 36obj-$(CONFIG_RTC_DRV_ISL1208) += rtc-isl1208.o
36obj-$(CONFIG_RTC_DRV_M41T80) += rtc-m41t80.o 37obj-$(CONFIG_RTC_DRV_M41T80) += rtc-m41t80.o
38obj-$(CONFIG_RTC_DRV_M41T94) += rtc-m41t94.o
37obj-$(CONFIG_RTC_DRV_M48T59) += rtc-m48t59.o 39obj-$(CONFIG_RTC_DRV_M48T59) += rtc-m48t59.o
38obj-$(CONFIG_RTC_DRV_M48T86) += rtc-m48t86.o 40obj-$(CONFIG_RTC_DRV_M48T86) += rtc-m48t86.o
39obj-$(CONFIG_RTC_DRV_MAX6900) += rtc-max6900.o 41obj-$(CONFIG_RTC_DRV_MAX6900) += rtc-max6900.o
diff --git a/drivers/rtc/rtc-at91rm9200.c b/drivers/rtc/rtc-at91rm9200.c
index 9c3db934cc24..cd32d05db773 100644
--- a/drivers/rtc/rtc-at91rm9200.c
+++ b/drivers/rtc/rtc-at91rm9200.c
@@ -171,8 +171,10 @@ static int at91_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm)
171 | BIN2BCD(tm.tm_mday) << 24 171 | BIN2BCD(tm.tm_mday) << 24
172 | AT91_RTC_DATEEN | AT91_RTC_MTHEN); 172 | AT91_RTC_DATEEN | AT91_RTC_MTHEN);
173 173
174 if (alrm->enabled) 174 if (alrm->enabled) {
175 at91_sys_write(AT91_RTC_SCCR, AT91_RTC_ALARM);
175 at91_sys_write(AT91_RTC_IER, AT91_RTC_ALARM); 176 at91_sys_write(AT91_RTC_IER, AT91_RTC_ALARM);
177 }
176 178
177 pr_debug("%s(): %4d-%02d-%02d %02d:%02d:%02d\n", __func__, 179 pr_debug("%s(): %4d-%02d-%02d %02d:%02d:%02d\n", __func__,
178 at91_alarm_year, tm.tm_mon, tm.tm_mday, tm.tm_hour, 180 at91_alarm_year, tm.tm_mon, tm.tm_mday, tm.tm_hour,
@@ -191,28 +193,22 @@ static int at91_rtc_ioctl(struct device *dev, unsigned int cmd,
191 193
192 pr_debug("%s(): cmd=%08x, arg=%08lx.\n", __func__, cmd, arg); 194 pr_debug("%s(): cmd=%08x, arg=%08lx.\n", __func__, cmd, arg);
193 195
196 /* important: scrub old status before enabling IRQs */
194 switch (cmd) { 197 switch (cmd) {
195 case RTC_AIE_OFF: /* alarm off */ 198 case RTC_AIE_OFF: /* alarm off */
196 at91_sys_write(AT91_RTC_IDR, AT91_RTC_ALARM); 199 at91_sys_write(AT91_RTC_IDR, AT91_RTC_ALARM);
197 break; 200 break;
198 case RTC_AIE_ON: /* alarm on */ 201 case RTC_AIE_ON: /* alarm on */
202 at91_sys_write(AT91_RTC_SCCR, AT91_RTC_ALARM);
199 at91_sys_write(AT91_RTC_IER, AT91_RTC_ALARM); 203 at91_sys_write(AT91_RTC_IER, AT91_RTC_ALARM);
200 break; 204 break;
201 case RTC_UIE_OFF: /* update off */ 205 case RTC_UIE_OFF: /* update off */
202 case RTC_PIE_OFF: /* periodic off */
203 at91_sys_write(AT91_RTC_IDR, AT91_RTC_SECEV); 206 at91_sys_write(AT91_RTC_IDR, AT91_RTC_SECEV);
204 break; 207 break;
205 case RTC_UIE_ON: /* update on */ 208 case RTC_UIE_ON: /* update on */
206 case RTC_PIE_ON: /* periodic on */ 209 at91_sys_write(AT91_RTC_SCCR, AT91_RTC_SECEV);
207 at91_sys_write(AT91_RTC_IER, AT91_RTC_SECEV); 210 at91_sys_write(AT91_RTC_IER, AT91_RTC_SECEV);
208 break; 211 break;
209 case RTC_IRQP_READ: /* read periodic alarm frequency */
210 ret = put_user(AT91_RTC_FREQ, (unsigned long *) arg);
211 break;
212 case RTC_IRQP_SET: /* set periodic alarm frequency */
213 if (arg != AT91_RTC_FREQ)
214 ret = -EINVAL;
215 break;
216 default: 212 default:
217 ret = -ENOIOCTLCMD; 213 ret = -ENOIOCTLCMD;
218 break; 214 break;
diff --git a/drivers/rtc/rtc-cmos.c b/drivers/rtc/rtc-cmos.c
index d7bb9bac71df..6ea349aba3ba 100644
--- a/drivers/rtc/rtc-cmos.c
+++ b/drivers/rtc/rtc-cmos.c
@@ -36,25 +36,9 @@
36#include <linux/platform_device.h> 36#include <linux/platform_device.h>
37#include <linux/mod_devicetable.h> 37#include <linux/mod_devicetable.h>
38 38
39#ifdef CONFIG_HPET_EMULATE_RTC
40#include <asm/hpet.h>
41#endif
42
43/* this is for "generic access to PC-style RTC" using CMOS_READ/CMOS_WRITE */ 39/* this is for "generic access to PC-style RTC" using CMOS_READ/CMOS_WRITE */
44#include <asm-generic/rtc.h> 40#include <asm-generic/rtc.h>
45 41
46#ifndef CONFIG_HPET_EMULATE_RTC
47#define is_hpet_enabled() 0
48#define hpet_set_alarm_time(hrs, min, sec) do { } while (0)
49#define hpet_set_periodic_freq(arg) 0
50#define hpet_mask_rtc_irq_bit(arg) do { } while (0)
51#define hpet_set_rtc_irq_bit(arg) do { } while (0)
52#define hpet_rtc_timer_init() do { } while (0)
53#define hpet_register_irq_handler(h) 0
54#define hpet_unregister_irq_handler(h) do { } while (0)
55extern irqreturn_t hpet_rtc_interrupt(int irq, void *dev_id);
56#endif
57
58struct cmos_rtc { 42struct cmos_rtc {
59 struct rtc_device *rtc; 43 struct rtc_device *rtc;
60 struct device *dev; 44 struct device *dev;
@@ -93,6 +77,72 @@ static inline int is_intr(u8 rtc_intr)
93 77
94/*----------------------------------------------------------------*/ 78/*----------------------------------------------------------------*/
95 79
80/* Much modern x86 hardware has HPETs (10+ MHz timers) which, because
81 * many BIOS programmers don't set up "sane mode" IRQ routing, are mostly
82 * used in a broken "legacy replacement" mode. The breakage includes
83 * HPET #1 hijacking the IRQ for this RTC, and being unavailable for
84 * other (better) use.
85 *
86 * When that broken mode is in use, platform glue provides a partial
87 * emulation of hardware RTC IRQ facilities using HPET #1. We don't
88 * want to use HPET for anything except those IRQs though...
89 */
90#ifdef CONFIG_HPET_EMULATE_RTC
91#include <asm/hpet.h>
92#else
93
94static inline int is_hpet_enabled(void)
95{
96 return 0;
97}
98
99static inline int hpet_mask_rtc_irq_bit(unsigned long mask)
100{
101 return 0;
102}
103
104static inline int hpet_set_rtc_irq_bit(unsigned long mask)
105{
106 return 0;
107}
108
109static inline int
110hpet_set_alarm_time(unsigned char hrs, unsigned char min, unsigned char sec)
111{
112 return 0;
113}
114
115static inline int hpet_set_periodic_freq(unsigned long freq)
116{
117 return 0;
118}
119
120static inline int hpet_rtc_dropped_irq(void)
121{
122 return 0;
123}
124
125static inline int hpet_rtc_timer_init(void)
126{
127 return 0;
128}
129
130extern irq_handler_t hpet_rtc_interrupt;
131
132static inline int hpet_register_irq_handler(irq_handler_t handler)
133{
134 return 0;
135}
136
137static inline int hpet_unregister_irq_handler(irq_handler_t handler)
138{
139 return 0;
140}
141
142#endif
143
144/*----------------------------------------------------------------*/
145
96static int cmos_read_time(struct device *dev, struct rtc_time *t) 146static int cmos_read_time(struct device *dev, struct rtc_time *t)
97{ 147{
98 /* REVISIT: if the clock has a "century" register, use 148 /* REVISIT: if the clock has a "century" register, use
@@ -185,11 +235,56 @@ static int cmos_read_alarm(struct device *dev, struct rtc_wkalrm *t)
185 return 0; 235 return 0;
186} 236}
187 237
238static void cmos_checkintr(struct cmos_rtc *cmos, unsigned char rtc_control)
239{
240 unsigned char rtc_intr;
241
242 /* NOTE after changing RTC_xIE bits we always read INTR_FLAGS;
243 * allegedly some older rtcs need that to handle irqs properly
244 */
245 rtc_intr = CMOS_READ(RTC_INTR_FLAGS);
246
247 if (is_hpet_enabled())
248 return;
249
250 rtc_intr &= (rtc_control & RTC_IRQMASK) | RTC_IRQF;
251 if (is_intr(rtc_intr))
252 rtc_update_irq(cmos->rtc, 1, rtc_intr);
253}
254
255static void cmos_irq_enable(struct cmos_rtc *cmos, unsigned char mask)
256{
257 unsigned char rtc_control;
258
259 /* flush any pending IRQ status, notably for update irqs,
260 * before we enable new IRQs
261 */
262 rtc_control = CMOS_READ(RTC_CONTROL);
263 cmos_checkintr(cmos, rtc_control);
264
265 rtc_control |= mask;
266 CMOS_WRITE(rtc_control, RTC_CONTROL);
267 hpet_set_rtc_irq_bit(mask);
268
269 cmos_checkintr(cmos, rtc_control);
270}
271
272static void cmos_irq_disable(struct cmos_rtc *cmos, unsigned char mask)
273{
274 unsigned char rtc_control;
275
276 rtc_control = CMOS_READ(RTC_CONTROL);
277 rtc_control &= ~mask;
278 CMOS_WRITE(rtc_control, RTC_CONTROL);
279 hpet_mask_rtc_irq_bit(mask);
280
281 cmos_checkintr(cmos, rtc_control);
282}
283
188static int cmos_set_alarm(struct device *dev, struct rtc_wkalrm *t) 284static int cmos_set_alarm(struct device *dev, struct rtc_wkalrm *t)
189{ 285{
190 struct cmos_rtc *cmos = dev_get_drvdata(dev); 286 struct cmos_rtc *cmos = dev_get_drvdata(dev);
191 unsigned char mon, mday, hrs, min, sec; 287 unsigned char mon, mday, hrs, min, sec;
192 unsigned char rtc_control, rtc_intr;
193 288
194 if (!is_valid_irq(cmos->irq)) 289 if (!is_valid_irq(cmos->irq))
195 return -EIO; 290 return -EIO;
@@ -213,17 +308,10 @@ static int cmos_set_alarm(struct device *dev, struct rtc_wkalrm *t)
213 sec = t->time.tm_sec; 308 sec = t->time.tm_sec;
214 sec = (sec < 60) ? BIN2BCD(sec) : 0xff; 309 sec = (sec < 60) ? BIN2BCD(sec) : 0xff;
215 310
216 hpet_set_alarm_time(t->time.tm_hour, t->time.tm_min, t->time.tm_sec);
217 spin_lock_irq(&rtc_lock); 311 spin_lock_irq(&rtc_lock);
218 312
219 /* next rtc irq must not be from previous alarm setting */ 313 /* next rtc irq must not be from previous alarm setting */
220 rtc_control = CMOS_READ(RTC_CONTROL); 314 cmos_irq_disable(cmos, RTC_AIE);
221 rtc_control &= ~RTC_AIE;
222 CMOS_WRITE(rtc_control, RTC_CONTROL);
223 rtc_intr = CMOS_READ(RTC_INTR_FLAGS);
224 rtc_intr &= (rtc_control & RTC_IRQMASK) | RTC_IRQF;
225 if (is_intr(rtc_intr))
226 rtc_update_irq(cmos->rtc, 1, rtc_intr);
227 315
228 /* update alarm */ 316 /* update alarm */
229 CMOS_WRITE(hrs, RTC_HOURS_ALARM); 317 CMOS_WRITE(hrs, RTC_HOURS_ALARM);
@@ -237,14 +325,13 @@ static int cmos_set_alarm(struct device *dev, struct rtc_wkalrm *t)
237 CMOS_WRITE(mon, cmos->mon_alrm); 325 CMOS_WRITE(mon, cmos->mon_alrm);
238 } 326 }
239 327
240 if (t->enabled) { 328 /* FIXME the HPET alarm glue currently ignores day_alrm
241 rtc_control |= RTC_AIE; 329 * and mon_alrm ...
242 CMOS_WRITE(rtc_control, RTC_CONTROL); 330 */
243 rtc_intr = CMOS_READ(RTC_INTR_FLAGS); 331 hpet_set_alarm_time(t->time.tm_hour, t->time.tm_min, t->time.tm_sec);
244 rtc_intr &= (rtc_control & RTC_IRQMASK) | RTC_IRQF; 332
245 if (is_intr(rtc_intr)) 333 if (t->enabled)
246 rtc_update_irq(cmos->rtc, 1, rtc_intr); 334 cmos_irq_enable(cmos, RTC_AIE);
247 }
248 335
249 spin_unlock_irq(&rtc_lock); 336 spin_unlock_irq(&rtc_lock);
250 337
@@ -267,8 +354,8 @@ static int cmos_irq_set_freq(struct device *dev, int freq)
267 f = 16 - f; 354 f = 16 - f;
268 355
269 spin_lock_irqsave(&rtc_lock, flags); 356 spin_lock_irqsave(&rtc_lock, flags);
270 if (!hpet_set_periodic_freq(freq)) 357 hpet_set_periodic_freq(freq);
271 CMOS_WRITE(RTC_REF_CLCK_32KHZ | f, RTC_FREQ_SELECT); 358 CMOS_WRITE(RTC_REF_CLCK_32KHZ | f, RTC_FREQ_SELECT);
272 spin_unlock_irqrestore(&rtc_lock, flags); 359 spin_unlock_irqrestore(&rtc_lock, flags);
273 360
274 return 0; 361 return 0;
@@ -277,26 +364,17 @@ static int cmos_irq_set_freq(struct device *dev, int freq)
277static int cmos_irq_set_state(struct device *dev, int enabled) 364static int cmos_irq_set_state(struct device *dev, int enabled)
278{ 365{
279 struct cmos_rtc *cmos = dev_get_drvdata(dev); 366 struct cmos_rtc *cmos = dev_get_drvdata(dev);
280 unsigned char rtc_control, rtc_intr;
281 unsigned long flags; 367 unsigned long flags;
282 368
283 if (!is_valid_irq(cmos->irq)) 369 if (!is_valid_irq(cmos->irq))
284 return -ENXIO; 370 return -ENXIO;
285 371
286 spin_lock_irqsave(&rtc_lock, flags); 372 spin_lock_irqsave(&rtc_lock, flags);
287 rtc_control = CMOS_READ(RTC_CONTROL);
288 373
289 if (enabled) 374 if (enabled)
290 rtc_control |= RTC_PIE; 375 cmos_irq_enable(cmos, RTC_PIE);
291 else 376 else
292 rtc_control &= ~RTC_PIE; 377 cmos_irq_disable(cmos, RTC_PIE);
293
294 CMOS_WRITE(rtc_control, RTC_CONTROL);
295
296 rtc_intr = CMOS_READ(RTC_INTR_FLAGS);
297 rtc_intr &= (rtc_control & RTC_IRQMASK) | RTC_IRQF;
298 if (is_intr(rtc_intr))
299 rtc_update_irq(cmos->rtc, 1, rtc_intr);
300 378
301 spin_unlock_irqrestore(&rtc_lock, flags); 379 spin_unlock_irqrestore(&rtc_lock, flags);
302 return 0; 380 return 0;
@@ -308,7 +386,6 @@ static int
308cmos_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg) 386cmos_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
309{ 387{
310 struct cmos_rtc *cmos = dev_get_drvdata(dev); 388 struct cmos_rtc *cmos = dev_get_drvdata(dev);
311 unsigned char rtc_control, rtc_intr;
312 unsigned long flags; 389 unsigned long flags;
313 390
314 switch (cmd) { 391 switch (cmd) {
@@ -316,51 +393,29 @@ cmos_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
316 case RTC_AIE_ON: 393 case RTC_AIE_ON:
317 case RTC_UIE_OFF: 394 case RTC_UIE_OFF:
318 case RTC_UIE_ON: 395 case RTC_UIE_ON:
319 case RTC_PIE_OFF:
320 case RTC_PIE_ON:
321 if (!is_valid_irq(cmos->irq)) 396 if (!is_valid_irq(cmos->irq))
322 return -EINVAL; 397 return -EINVAL;
323 break; 398 break;
399 /* PIE ON/OFF is handled by cmos_irq_set_state() */
324 default: 400 default:
325 return -ENOIOCTLCMD; 401 return -ENOIOCTLCMD;
326 } 402 }
327 403
328 spin_lock_irqsave(&rtc_lock, flags); 404 spin_lock_irqsave(&rtc_lock, flags);
329 rtc_control = CMOS_READ(RTC_CONTROL);
330 switch (cmd) { 405 switch (cmd) {
331 case RTC_AIE_OFF: /* alarm off */ 406 case RTC_AIE_OFF: /* alarm off */
332 rtc_control &= ~RTC_AIE; 407 cmos_irq_disable(cmos, RTC_AIE);
333 hpet_mask_rtc_irq_bit(RTC_AIE);
334 break; 408 break;
335 case RTC_AIE_ON: /* alarm on */ 409 case RTC_AIE_ON: /* alarm on */
336 rtc_control |= RTC_AIE; 410 cmos_irq_enable(cmos, RTC_AIE);
337 hpet_set_rtc_irq_bit(RTC_AIE);
338 break; 411 break;
339 case RTC_UIE_OFF: /* update off */ 412 case RTC_UIE_OFF: /* update off */
340 rtc_control &= ~RTC_UIE; 413 cmos_irq_disable(cmos, RTC_UIE);
341 hpet_mask_rtc_irq_bit(RTC_UIE);
342 break; 414 break;
343 case RTC_UIE_ON: /* update on */ 415 case RTC_UIE_ON: /* update on */
344 rtc_control |= RTC_UIE; 416 cmos_irq_enable(cmos, RTC_UIE);
345 hpet_set_rtc_irq_bit(RTC_UIE);
346 break;
347 case RTC_PIE_OFF: /* periodic off */
348 rtc_control &= ~RTC_PIE;
349 hpet_mask_rtc_irq_bit(RTC_PIE);
350 break;
351 case RTC_PIE_ON: /* periodic on */
352 rtc_control |= RTC_PIE;
353 hpet_set_rtc_irq_bit(RTC_PIE);
354 break; 417 break;
355 } 418 }
356 if (!is_hpet_enabled())
357 CMOS_WRITE(rtc_control, RTC_CONTROL);
358
359 rtc_intr = CMOS_READ(RTC_INTR_FLAGS);
360 rtc_intr &= (rtc_control & RTC_IRQMASK) | RTC_IRQF;
361 if (is_intr(rtc_intr))
362 rtc_update_irq(cmos->rtc, 1, rtc_intr);
363
364 spin_unlock_irqrestore(&rtc_lock, flags); 419 spin_unlock_irqrestore(&rtc_lock, flags);
365 return 0; 420 return 0;
366} 421}
@@ -502,27 +557,29 @@ static irqreturn_t cmos_interrupt(int irq, void *p)
502 u8 rtc_control; 557 u8 rtc_control;
503 558
504 spin_lock(&rtc_lock); 559 spin_lock(&rtc_lock);
505 /* 560
506 * In this case it is HPET RTC interrupt handler 561 /* When the HPET interrupt handler calls us, the interrupt
507 * calling us, with the interrupt information 562 * status is passed as arg1 instead of the irq number. But
508 * passed as arg1, instead of irq. 563 * always clear irq status, even when HPET is in the way.
564 *
565 * Note that HPET and RTC are almost certainly out of phase,
566 * giving different IRQ status ...
509 */ 567 */
568 irqstat = CMOS_READ(RTC_INTR_FLAGS);
569 rtc_control = CMOS_READ(RTC_CONTROL);
510 if (is_hpet_enabled()) 570 if (is_hpet_enabled())
511 irqstat = (unsigned long)irq & 0xF0; 571 irqstat = (unsigned long)irq & 0xF0;
512 else { 572 irqstat &= (rtc_control & RTC_IRQMASK) | RTC_IRQF;
513 irqstat = CMOS_READ(RTC_INTR_FLAGS);
514 rtc_control = CMOS_READ(RTC_CONTROL);
515 irqstat &= (rtc_control & RTC_IRQMASK) | RTC_IRQF;
516 }
517 573
518 /* All Linux RTC alarms should be treated as if they were oneshot. 574 /* All Linux RTC alarms should be treated as if they were oneshot.
519 * Similar code may be needed in system wakeup paths, in case the 575 * Similar code may be needed in system wakeup paths, in case the
520 * alarm woke the system. 576 * alarm woke the system.
521 */ 577 */
522 if (irqstat & RTC_AIE) { 578 if (irqstat & RTC_AIE) {
523 rtc_control = CMOS_READ(RTC_CONTROL);
524 rtc_control &= ~RTC_AIE; 579 rtc_control &= ~RTC_AIE;
525 CMOS_WRITE(rtc_control, RTC_CONTROL); 580 CMOS_WRITE(rtc_control, RTC_CONTROL);
581 hpet_mask_rtc_irq_bit(RTC_AIE);
582
526 CMOS_READ(RTC_INTR_FLAGS); 583 CMOS_READ(RTC_INTR_FLAGS);
527 } 584 }
528 spin_unlock(&rtc_lock); 585 spin_unlock(&rtc_lock);
@@ -629,18 +686,13 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq)
629 * do something about other clock frequencies. 686 * do something about other clock frequencies.
630 */ 687 */
631 cmos_rtc.rtc->irq_freq = 1024; 688 cmos_rtc.rtc->irq_freq = 1024;
632 if (!hpet_set_periodic_freq(cmos_rtc.rtc->irq_freq)) 689 hpet_set_periodic_freq(cmos_rtc.rtc->irq_freq);
633 CMOS_WRITE(RTC_REF_CLCK_32KHZ | 0x06, RTC_FREQ_SELECT); 690 CMOS_WRITE(RTC_REF_CLCK_32KHZ | 0x06, RTC_FREQ_SELECT);
691
692 /* disable irqs */
693 cmos_irq_disable(&cmos_rtc, RTC_PIE | RTC_AIE | RTC_UIE);
634 694
635 /* disable irqs.
636 *
637 * NOTE after changing RTC_xIE bits we always read INTR_FLAGS;
638 * allegedly some older rtcs need that to handle irqs properly
639 */
640 rtc_control = CMOS_READ(RTC_CONTROL); 695 rtc_control = CMOS_READ(RTC_CONTROL);
641 rtc_control &= ~(RTC_PIE | RTC_AIE | RTC_UIE);
642 CMOS_WRITE(rtc_control, RTC_CONTROL);
643 CMOS_READ(RTC_INTR_FLAGS);
644 696
645 spin_unlock_irq(&rtc_lock); 697 spin_unlock_irq(&rtc_lock);
646 698
@@ -687,7 +739,7 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq)
687 goto cleanup2; 739 goto cleanup2;
688 } 740 }
689 741
690 pr_info("%s: alarms up to one %s%s\n", 742 pr_info("%s: alarms up to one %s%s%s\n",
691 cmos_rtc.rtc->dev.bus_id, 743 cmos_rtc.rtc->dev.bus_id,
692 is_valid_irq(rtc_irq) 744 is_valid_irq(rtc_irq)
693 ? (cmos_rtc.mon_alrm 745 ? (cmos_rtc.mon_alrm
@@ -695,8 +747,8 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq)
695 : (cmos_rtc.day_alrm 747 : (cmos_rtc.day_alrm
696 ? "month" : "day")) 748 ? "month" : "day"))
697 : "no", 749 : "no",
698 cmos_rtc.century ? ", y3k" : "" 750 cmos_rtc.century ? ", y3k" : "",
699 ); 751 is_hpet_enabled() ? ", hpet irqs" : "");
700 752
701 return 0; 753 return 0;
702 754
@@ -713,13 +765,8 @@ cleanup0:
713 765
714static void cmos_do_shutdown(void) 766static void cmos_do_shutdown(void)
715{ 767{
716 unsigned char rtc_control;
717
718 spin_lock_irq(&rtc_lock); 768 spin_lock_irq(&rtc_lock);
719 rtc_control = CMOS_READ(RTC_CONTROL); 769 cmos_irq_disable(&cmos_rtc, RTC_IRQMASK);
720 rtc_control &= ~(RTC_PIE|RTC_AIE|RTC_UIE);
721 CMOS_WRITE(rtc_control, RTC_CONTROL);
722 CMOS_READ(RTC_INTR_FLAGS);
723 spin_unlock_irq(&rtc_lock); 770 spin_unlock_irq(&rtc_lock);
724} 771}
725 772
@@ -760,17 +807,17 @@ static int cmos_suspend(struct device *dev, pm_message_t mesg)
760 spin_lock_irq(&rtc_lock); 807 spin_lock_irq(&rtc_lock);
761 cmos->suspend_ctrl = tmp = CMOS_READ(RTC_CONTROL); 808 cmos->suspend_ctrl = tmp = CMOS_READ(RTC_CONTROL);
762 if (tmp & (RTC_PIE|RTC_AIE|RTC_UIE)) { 809 if (tmp & (RTC_PIE|RTC_AIE|RTC_UIE)) {
763 unsigned char irqstat; 810 unsigned char mask;
764 811
765 if (do_wake) 812 if (do_wake)
766 tmp &= ~(RTC_PIE|RTC_UIE); 813 mask = RTC_IRQMASK & ~RTC_AIE;
767 else 814 else
768 tmp &= ~(RTC_PIE|RTC_AIE|RTC_UIE); 815 mask = RTC_IRQMASK;
816 tmp &= ~mask;
769 CMOS_WRITE(tmp, RTC_CONTROL); 817 CMOS_WRITE(tmp, RTC_CONTROL);
770 irqstat = CMOS_READ(RTC_INTR_FLAGS); 818 hpet_mask_rtc_irq_bit(mask);
771 irqstat &= (tmp & RTC_IRQMASK) | RTC_IRQF; 819
772 if (is_intr(irqstat)) 820 cmos_checkintr(cmos, tmp);
773 rtc_update_irq(cmos->rtc, 1, irqstat);
774 } 821 }
775 spin_unlock_irq(&rtc_lock); 822 spin_unlock_irq(&rtc_lock);
776 823
@@ -796,7 +843,8 @@ static int cmos_resume(struct device *dev)
796 unsigned char tmp = cmos->suspend_ctrl; 843 unsigned char tmp = cmos->suspend_ctrl;
797 844
798 /* re-enable any irqs previously active */ 845 /* re-enable any irqs previously active */
799 if (tmp & (RTC_PIE|RTC_AIE|RTC_UIE)) { 846 if (tmp & RTC_IRQMASK) {
847 unsigned char mask;
800 848
801 if (cmos->enabled_wake) { 849 if (cmos->enabled_wake) {
802 if (cmos->wake_off) 850 if (cmos->wake_off)
@@ -807,18 +855,28 @@ static int cmos_resume(struct device *dev)
807 } 855 }
808 856
809 spin_lock_irq(&rtc_lock); 857 spin_lock_irq(&rtc_lock);
810 CMOS_WRITE(tmp, RTC_CONTROL); 858 do {
811 tmp = CMOS_READ(RTC_INTR_FLAGS); 859 CMOS_WRITE(tmp, RTC_CONTROL);
812 tmp &= (cmos->suspend_ctrl & RTC_IRQMASK) | RTC_IRQF; 860 hpet_set_rtc_irq_bit(tmp & RTC_IRQMASK);
813 if (is_intr(tmp)) 861
814 rtc_update_irq(cmos->rtc, 1, tmp); 862 mask = CMOS_READ(RTC_INTR_FLAGS);
863 mask &= (tmp & RTC_IRQMASK) | RTC_IRQF;
864 if (!is_hpet_enabled() || !is_intr(mask))
865 break;
866
867 /* force one-shot behavior if HPET blocked
868 * the wake alarm's irq
869 */
870 rtc_update_irq(cmos->rtc, 1, mask);
871 tmp &= ~RTC_AIE;
872 hpet_mask_rtc_irq_bit(RTC_AIE);
873 } while (mask & RTC_AIE);
815 spin_unlock_irq(&rtc_lock); 874 spin_unlock_irq(&rtc_lock);
816 } 875 }
817 876
818 pr_debug("%s: resume, ctrl %02x\n", 877 pr_debug("%s: resume, ctrl %02x\n",
819 cmos_rtc.rtc->dev.bus_id, 878 cmos_rtc.rtc->dev.bus_id,
820 cmos->suspend_ctrl); 879 tmp);
821
822 880
823 return 0; 881 return 0;
824} 882}
diff --git a/drivers/rtc/rtc-dev.c b/drivers/rtc/rtc-dev.c
index 0114a78b7cbb..0a870b7e5c32 100644
--- a/drivers/rtc/rtc-dev.c
+++ b/drivers/rtc/rtc-dev.c
@@ -209,7 +209,7 @@ static unsigned int rtc_dev_poll(struct file *file, poll_table *wait)
209 return (data != 0) ? (POLLIN | POLLRDNORM) : 0; 209 return (data != 0) ? (POLLIN | POLLRDNORM) : 0;
210} 210}
211 211
212static int rtc_dev_ioctl(struct inode *inode, struct file *file, 212static long rtc_dev_ioctl(struct file *file,
213 unsigned int cmd, unsigned long arg) 213 unsigned int cmd, unsigned long arg)
214{ 214{
215 int err = 0; 215 int err = 0;
@@ -219,6 +219,10 @@ static int rtc_dev_ioctl(struct inode *inode, struct file *file,
219 struct rtc_wkalrm alarm; 219 struct rtc_wkalrm alarm;
220 void __user *uarg = (void __user *) arg; 220 void __user *uarg = (void __user *) arg;
221 221
222 err = mutex_lock_interruptible(&rtc->ops_lock);
223 if (err)
224 return -EBUSY;
225
222 /* check that the calling task has appropriate permissions 226 /* check that the calling task has appropriate permissions
223 * for certain ioctls. doing this check here is useful 227 * for certain ioctls. doing this check here is useful
224 * to avoid duplicate code in each driver. 228 * to avoid duplicate code in each driver.
@@ -227,26 +231,31 @@ static int rtc_dev_ioctl(struct inode *inode, struct file *file,
227 case RTC_EPOCH_SET: 231 case RTC_EPOCH_SET:
228 case RTC_SET_TIME: 232 case RTC_SET_TIME:
229 if (!capable(CAP_SYS_TIME)) 233 if (!capable(CAP_SYS_TIME))
230 return -EACCES; 234 err = -EACCES;
231 break; 235 break;
232 236
233 case RTC_IRQP_SET: 237 case RTC_IRQP_SET:
234 if (arg > rtc->max_user_freq && !capable(CAP_SYS_RESOURCE)) 238 if (arg > rtc->max_user_freq && !capable(CAP_SYS_RESOURCE))
235 return -EACCES; 239 err = -EACCES;
236 break; 240 break;
237 241
238 case RTC_PIE_ON: 242 case RTC_PIE_ON:
239 if (rtc->irq_freq > rtc->max_user_freq && 243 if (rtc->irq_freq > rtc->max_user_freq &&
240 !capable(CAP_SYS_RESOURCE)) 244 !capable(CAP_SYS_RESOURCE))
241 return -EACCES; 245 err = -EACCES;
242 break; 246 break;
243 } 247 }
244 248
249 if (err)
250 goto done;
251
245 /* try the driver's ioctl interface */ 252 /* try the driver's ioctl interface */
246 if (ops->ioctl) { 253 if (ops->ioctl) {
247 err = ops->ioctl(rtc->dev.parent, cmd, arg); 254 err = ops->ioctl(rtc->dev.parent, cmd, arg);
248 if (err != -ENOIOCTLCMD) 255 if (err != -ENOIOCTLCMD) {
256 mutex_unlock(&rtc->ops_lock);
249 return err; 257 return err;
258 }
250 } 259 }
251 260
252 /* if the driver does not provide the ioctl interface 261 /* if the driver does not provide the ioctl interface
@@ -265,15 +274,19 @@ static int rtc_dev_ioctl(struct inode *inode, struct file *file,
265 274
266 switch (cmd) { 275 switch (cmd) {
267 case RTC_ALM_READ: 276 case RTC_ALM_READ:
277 mutex_unlock(&rtc->ops_lock);
278
268 err = rtc_read_alarm(rtc, &alarm); 279 err = rtc_read_alarm(rtc, &alarm);
269 if (err < 0) 280 if (err < 0)
270 return err; 281 return err;
271 282
272 if (copy_to_user(uarg, &alarm.time, sizeof(tm))) 283 if (copy_to_user(uarg, &alarm.time, sizeof(tm)))
273 return -EFAULT; 284 err = -EFAULT;
274 break; 285 return err;
275 286
276 case RTC_ALM_SET: 287 case RTC_ALM_SET:
288 mutex_unlock(&rtc->ops_lock);
289
277 if (copy_from_user(&alarm.time, uarg, sizeof(tm))) 290 if (copy_from_user(&alarm.time, uarg, sizeof(tm)))
278 return -EFAULT; 291 return -EFAULT;
279 292
@@ -321,24 +334,26 @@ static int rtc_dev_ioctl(struct inode *inode, struct file *file,
321 } 334 }
322 } 335 }
323 336
324 err = rtc_set_alarm(rtc, &alarm); 337 return rtc_set_alarm(rtc, &alarm);
325 break;
326 338
327 case RTC_RD_TIME: 339 case RTC_RD_TIME:
340 mutex_unlock(&rtc->ops_lock);
341
328 err = rtc_read_time(rtc, &tm); 342 err = rtc_read_time(rtc, &tm);
329 if (err < 0) 343 if (err < 0)
330 return err; 344 return err;
331 345
332 if (copy_to_user(uarg, &tm, sizeof(tm))) 346 if (copy_to_user(uarg, &tm, sizeof(tm)))
333 return -EFAULT; 347 err = -EFAULT;
334 break; 348 return err;
335 349
336 case RTC_SET_TIME: 350 case RTC_SET_TIME:
351 mutex_unlock(&rtc->ops_lock);
352
337 if (copy_from_user(&tm, uarg, sizeof(tm))) 353 if (copy_from_user(&tm, uarg, sizeof(tm)))
338 return -EFAULT; 354 return -EFAULT;
339 355
340 err = rtc_set_time(rtc, &tm); 356 return rtc_set_time(rtc, &tm);
341 break;
342 357
343 case RTC_PIE_ON: 358 case RTC_PIE_ON:
344 err = rtc_irq_set_state(rtc, NULL, 1); 359 err = rtc_irq_set_state(rtc, NULL, 1);
@@ -376,34 +391,37 @@ static int rtc_dev_ioctl(struct inode *inode, struct file *file,
376 break; 391 break;
377#endif 392#endif
378 case RTC_WKALM_SET: 393 case RTC_WKALM_SET:
394 mutex_unlock(&rtc->ops_lock);
379 if (copy_from_user(&alarm, uarg, sizeof(alarm))) 395 if (copy_from_user(&alarm, uarg, sizeof(alarm)))
380 return -EFAULT; 396 return -EFAULT;
381 397
382 err = rtc_set_alarm(rtc, &alarm); 398 return rtc_set_alarm(rtc, &alarm);
383 break;
384 399
385 case RTC_WKALM_RD: 400 case RTC_WKALM_RD:
401 mutex_unlock(&rtc->ops_lock);
386 err = rtc_read_alarm(rtc, &alarm); 402 err = rtc_read_alarm(rtc, &alarm);
387 if (err < 0) 403 if (err < 0)
388 return err; 404 return err;
389 405
390 if (copy_to_user(uarg, &alarm, sizeof(alarm))) 406 if (copy_to_user(uarg, &alarm, sizeof(alarm)))
391 return -EFAULT; 407 err = -EFAULT;
392 break; 408 return err;
393 409
394#ifdef CONFIG_RTC_INTF_DEV_UIE_EMUL 410#ifdef CONFIG_RTC_INTF_DEV_UIE_EMUL
395 case RTC_UIE_OFF: 411 case RTC_UIE_OFF:
396 clear_uie(rtc); 412 clear_uie(rtc);
397 return 0; 413 break;
398 414
399 case RTC_UIE_ON: 415 case RTC_UIE_ON:
400 return set_uie(rtc); 416 err = set_uie(rtc);
401#endif 417#endif
402 default: 418 default:
403 err = -ENOTTY; 419 err = -ENOTTY;
404 break; 420 break;
405 } 421 }
406 422
423done:
424 mutex_unlock(&rtc->ops_lock);
407 return err; 425 return err;
408} 426}
409 427
@@ -432,7 +450,7 @@ static const struct file_operations rtc_dev_fops = {
432 .llseek = no_llseek, 450 .llseek = no_llseek,
433 .read = rtc_dev_read, 451 .read = rtc_dev_read,
434 .poll = rtc_dev_poll, 452 .poll = rtc_dev_poll,
435 .ioctl = rtc_dev_ioctl, 453 .unlocked_ioctl = rtc_dev_ioctl,
436 .open = rtc_dev_open, 454 .open = rtc_dev_open,
437 .release = rtc_dev_release, 455 .release = rtc_dev_release,
438 .fasync = rtc_dev_fasync, 456 .fasync = rtc_dev_fasync,
diff --git a/drivers/rtc/rtc-ds1305.c b/drivers/rtc/rtc-ds1305.c
new file mode 100644
index 000000000000..b91d02a3ace9
--- /dev/null
+++ b/drivers/rtc/rtc-ds1305.c
@@ -0,0 +1,847 @@
1/*
2 * rtc-ds1305.c -- driver for DS1305 and DS1306 SPI RTC chips
3 *
4 * Copyright (C) 2008 David Brownell
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 */
11#include <linux/kernel.h>
12#include <linux/init.h>
13#include <linux/bcd.h>
14#include <linux/rtc.h>
15#include <linux/workqueue.h>
16
17#include <linux/spi/spi.h>
18#include <linux/spi/ds1305.h>
19
20
21/*
22 * Registers ... mask DS1305_WRITE into register address to write,
23 * otherwise you're reading it. All non-bitmask values are BCD.
24 */
25#define DS1305_WRITE 0x80
26
27
28/* RTC date/time ... the main special cases are that we:
29 * - Need fancy "hours" encoding in 12hour mode
30 * - Don't rely on the "day-of-week" field (or tm_wday)
31 * - Are a 21st-century clock (2000 <= year < 2100)
32 */
33#define DS1305_RTC_LEN 7 /* bytes for RTC regs */
34
35#define DS1305_SEC 0x00 /* register addresses */
36#define DS1305_MIN 0x01
37#define DS1305_HOUR 0x02
38# define DS1305_HR_12 0x40 /* set == 12 hr mode */
39# define DS1305_HR_PM 0x20 /* set == PM (12hr mode) */
40#define DS1305_WDAY 0x03
41#define DS1305_MDAY 0x04
42#define DS1305_MON 0x05
43#define DS1305_YEAR 0x06
44
45
46/* The two alarms have only sec/min/hour/wday fields (ALM_LEN).
47 * DS1305_ALM_DISABLE disables a match field (some combos are bad).
48 *
49 * NOTE that since we don't use WDAY, we limit ourselves to alarms
50 * only one day into the future (vs potentially up to a week).
51 *
52 * NOTE ALSO that while we could generate once-a-second IRQs (UIE), we
53 * don't currently support them. We'd either need to do it only when
54 * no alarm is pending (not the standard model), or to use the second
55 * alarm (implying that this is a DS1305 not DS1306, *and* that either
56 * it's wired up a second IRQ we know, or that INTCN is set)
57 */
58#define DS1305_ALM_LEN 4 /* bytes for ALM regs */
59#define DS1305_ALM_DISABLE 0x80
60
61#define DS1305_ALM0(r) (0x07 + (r)) /* register addresses */
62#define DS1305_ALM1(r) (0x0b + (r))
63
64
65/* three control registers */
66#define DS1305_CONTROL_LEN 3 /* bytes of control regs */
67
68#define DS1305_CONTROL 0x0f /* register addresses */
69# define DS1305_nEOSC 0x80 /* low enables oscillator */
70# define DS1305_WP 0x40 /* write protect */
71# define DS1305_INTCN 0x04 /* clear == only int0 used */
72# define DS1306_1HZ 0x04 /* enable 1Hz output */
73# define DS1305_AEI1 0x02 /* enable ALM1 IRQ */
74# define DS1305_AEI0 0x01 /* enable ALM0 IRQ */
75#define DS1305_STATUS 0x10
76/* status has just AEIx bits, mirrored as IRQFx */
77#define DS1305_TRICKLE 0x11
78/* trickle bits are defined in <linux/spi/ds1305.h> */
79
80/* a bunch of NVRAM */
81#define DS1305_NVRAM_LEN 96 /* bytes of NVRAM */
82
83#define DS1305_NVRAM 0x20 /* register addresses */
84
85
86struct ds1305 {
87 struct spi_device *spi;
88 struct rtc_device *rtc;
89
90 struct work_struct work;
91
92 unsigned long flags;
93#define FLAG_EXITING 0
94
95 bool hr12;
96 u8 ctrl[DS1305_CONTROL_LEN];
97};
98
99
100/*----------------------------------------------------------------------*/
101
102/*
103 * Utilities ... tolerate 12-hour AM/PM notation in case of non-Linux
104 * software (like a bootloader) which may require it.
105 */
106
107static unsigned bcd2hour(u8 bcd)
108{
109 if (bcd & DS1305_HR_12) {
110 unsigned hour = 0;
111
112 bcd &= ~DS1305_HR_12;
113 if (bcd & DS1305_HR_PM) {
114 hour = 12;
115 bcd &= ~DS1305_HR_PM;
116 }
117 hour += BCD2BIN(bcd);
118 return hour - 1;
119 }
120 return BCD2BIN(bcd);
121}
122
123static u8 hour2bcd(bool hr12, int hour)
124{
125 if (hr12) {
126 hour++;
127 if (hour <= 12)
128 return DS1305_HR_12 | BIN2BCD(hour);
129 hour -= 12;
130 return DS1305_HR_12 | DS1305_HR_PM | BIN2BCD(hour);
131 }
132 return BIN2BCD(hour);
133}
134
135/*----------------------------------------------------------------------*/
136
137/*
138 * Interface to RTC framework
139 */
140
141#ifdef CONFIG_RTC_INTF_DEV
142
143/*
144 * Context: caller holds rtc->ops_lock (to protect ds1305->ctrl)
145 */
146static int ds1305_ioctl(struct device *dev, unsigned cmd, unsigned long arg)
147{
148 struct ds1305 *ds1305 = dev_get_drvdata(dev);
149 u8 buf[2];
150 int status = -ENOIOCTLCMD;
151
152 buf[0] = DS1305_WRITE | DS1305_CONTROL;
153 buf[1] = ds1305->ctrl[0];
154
155 switch (cmd) {
156 case RTC_AIE_OFF:
157 status = 0;
158 if (!(buf[1] & DS1305_AEI0))
159 goto done;
160 buf[1] &= ~DS1305_AEI0;
161 break;
162
163 case RTC_AIE_ON:
164 status = 0;
165 if (ds1305->ctrl[0] & DS1305_AEI0)
166 goto done;
167 buf[1] |= DS1305_AEI0;
168 break;
169 }
170 if (status == 0) {
171 status = spi_write_then_read(ds1305->spi, buf, sizeof buf,
172 NULL, 0);
173 if (status >= 0)
174 ds1305->ctrl[0] = buf[1];
175 }
176
177done:
178 return status;
179}
180
181#else
182#define ds1305_ioctl NULL
183#endif
184
185/*
186 * Get/set of date and time is pretty normal.
187 */
188
189static int ds1305_get_time(struct device *dev, struct rtc_time *time)
190{
191 struct ds1305 *ds1305 = dev_get_drvdata(dev);
192 u8 addr = DS1305_SEC;
193 u8 buf[DS1305_RTC_LEN];
194 int status;
195
196 /* Use write-then-read to get all the date/time registers
197 * since dma from stack is nonportable
198 */
199 status = spi_write_then_read(ds1305->spi, &addr, sizeof addr,
200 buf, sizeof buf);
201 if (status < 0)
202 return status;
203
204 dev_vdbg(dev, "%s: %02x %02x %02x, %02x %02x %02x %02x\n",
205 "read", buf[0], buf[1], buf[2], buf[3],
206 buf[4], buf[5], buf[6]);
207
208 /* Decode the registers */
209 time->tm_sec = BCD2BIN(buf[DS1305_SEC]);
210 time->tm_min = BCD2BIN(buf[DS1305_MIN]);
211 time->tm_hour = bcd2hour(buf[DS1305_HOUR]);
212 time->tm_wday = buf[DS1305_WDAY] - 1;
213 time->tm_mday = BCD2BIN(buf[DS1305_MDAY]);
214 time->tm_mon = BCD2BIN(buf[DS1305_MON]) - 1;
215 time->tm_year = BCD2BIN(buf[DS1305_YEAR]) + 100;
216
217 dev_vdbg(dev, "%s secs=%d, mins=%d, "
218 "hours=%d, mday=%d, mon=%d, year=%d, wday=%d\n",
219 "read", time->tm_sec, time->tm_min,
220 time->tm_hour, time->tm_mday,
221 time->tm_mon, time->tm_year, time->tm_wday);
222
223 /* Time may not be set */
224 return rtc_valid_tm(time);
225}
226
227static int ds1305_set_time(struct device *dev, struct rtc_time *time)
228{
229 struct ds1305 *ds1305 = dev_get_drvdata(dev);
230 u8 buf[1 + DS1305_RTC_LEN];
231 u8 *bp = buf;
232
233 dev_vdbg(dev, "%s secs=%d, mins=%d, "
234 "hours=%d, mday=%d, mon=%d, year=%d, wday=%d\n",
235 "write", time->tm_sec, time->tm_min,
236 time->tm_hour, time->tm_mday,
237 time->tm_mon, time->tm_year, time->tm_wday);
238
239 /* Write registers starting at the first time/date address. */
240 *bp++ = DS1305_WRITE | DS1305_SEC;
241
242 *bp++ = BIN2BCD(time->tm_sec);
243 *bp++ = BIN2BCD(time->tm_min);
244 *bp++ = hour2bcd(ds1305->hr12, time->tm_hour);
245 *bp++ = (time->tm_wday < 7) ? (time->tm_wday + 1) : 1;
246 *bp++ = BIN2BCD(time->tm_mday);
247 *bp++ = BIN2BCD(time->tm_mon + 1);
248 *bp++ = BIN2BCD(time->tm_year - 100);
249
250 dev_dbg(dev, "%s: %02x %02x %02x, %02x %02x %02x %02x\n",
251 "write", buf[1], buf[2], buf[3],
252 buf[4], buf[5], buf[6], buf[7]);
253
254 /* use write-then-read since dma from stack is nonportable */
255 return spi_write_then_read(ds1305->spi, buf, sizeof buf,
256 NULL, 0);
257}
258
259/*
260 * Get/set of alarm is a bit funky:
261 *
262 * - First there's the inherent raciness of getting the (partitioned)
263 * status of an alarm that could trigger while we're reading parts
264 * of that status.
265 *
266 * - Second there's its limited range (we could increase it a bit by
267 * relying on WDAY), which means it will easily roll over.
268 *
269 * - Third there's the choice of two alarms and alarm signals.
270 * Here we use ALM0 and expect that nINT0 (open drain) is used;
271 * that's the only real option for DS1306 runtime alarms, and is
272 * natural on DS1305.
273 *
274 * - Fourth, there's also ALM1, and a second interrupt signal:
275 * + On DS1305 ALM1 uses nINT1 (when INTCN=1) else nINT0;
276 * + On DS1306 ALM1 only uses INT1 (an active high pulse)
277 * and it won't work when VCC1 is active.
278 *
279 * So to be most general, we should probably set both alarms to the
280 * same value, letting ALM1 be the wakeup event source on DS1306
281 * and handling several wiring options on DS1305.
282 *
283 * - Fifth, we support the polled mode (as well as possible; why not?)
284 * even when no interrupt line is wired to an IRQ.
285 */
286
287/*
288 * Context: caller holds rtc->ops_lock (to protect ds1305->ctrl)
289 */
290static int ds1305_get_alarm(struct device *dev, struct rtc_wkalrm *alm)
291{
292 struct ds1305 *ds1305 = dev_get_drvdata(dev);
293 struct spi_device *spi = ds1305->spi;
294 u8 addr;
295 int status;
296 u8 buf[DS1305_ALM_LEN];
297
298 /* Refresh control register cache BEFORE reading ALM0 registers,
299 * since reading alarm registers acks any pending IRQ. That
300 * makes returning "pending" status a bit of a lie, but that bit
301 * of EFI status is at best fragile anyway (given IRQ handlers).
302 */
303 addr = DS1305_CONTROL;
304 status = spi_write_then_read(spi, &addr, sizeof addr,
305 ds1305->ctrl, sizeof ds1305->ctrl);
306 if (status < 0)
307 return status;
308
309 alm->enabled = !!(ds1305->ctrl[0] & DS1305_AEI0);
310 alm->pending = !!(ds1305->ctrl[1] & DS1305_AEI0);
311
312 /* get and check ALM0 registers */
313 addr = DS1305_ALM0(DS1305_SEC);
314 status = spi_write_then_read(spi, &addr, sizeof addr,
315 buf, sizeof buf);
316 if (status < 0)
317 return status;
318
319 dev_vdbg(dev, "%s: %02x %02x %02x %02x\n",
320 "alm0 read", buf[DS1305_SEC], buf[DS1305_MIN],
321 buf[DS1305_HOUR], buf[DS1305_WDAY]);
322
323 if ((DS1305_ALM_DISABLE & buf[DS1305_SEC])
324 || (DS1305_ALM_DISABLE & buf[DS1305_MIN])
325 || (DS1305_ALM_DISABLE & buf[DS1305_HOUR]))
326 return -EIO;
327
328 /* Stuff these values into alm->time and let RTC framework code
329 * fill in the rest ... and also handle rollover to tomorrow when
330 * that's needed.
331 */
332 alm->time.tm_sec = BCD2BIN(buf[DS1305_SEC]);
333 alm->time.tm_min = BCD2BIN(buf[DS1305_MIN]);
334 alm->time.tm_hour = bcd2hour(buf[DS1305_HOUR]);
335 alm->time.tm_mday = -1;
336 alm->time.tm_mon = -1;
337 alm->time.tm_year = -1;
338 /* next three fields are unused by Linux */
339 alm->time.tm_wday = -1;
340 alm->time.tm_mday = -1;
341 alm->time.tm_isdst = -1;
342
343 return 0;
344}
345
346/*
347 * Context: caller holds rtc->ops_lock (to protect ds1305->ctrl)
348 */
349static int ds1305_set_alarm(struct device *dev, struct rtc_wkalrm *alm)
350{
351 struct ds1305 *ds1305 = dev_get_drvdata(dev);
352 struct spi_device *spi = ds1305->spi;
353 unsigned long now, later;
354 struct rtc_time tm;
355 int status;
356 u8 buf[1 + DS1305_ALM_LEN];
357
358 /* convert desired alarm to time_t */
359 status = rtc_tm_to_time(&alm->time, &later);
360 if (status < 0)
361 return status;
362
363 /* Read current time as time_t */
364 status = ds1305_get_time(dev, &tm);
365 if (status < 0)
366 return status;
367 status = rtc_tm_to_time(&tm, &now);
368 if (status < 0)
369 return status;
370
371 /* make sure alarm fires within the next 24 hours */
372 if (later <= now)
373 return -EINVAL;
374 if ((later - now) > 24 * 60 * 60)
375 return -EDOM;
376
377 /* disable alarm if needed */
378 if (ds1305->ctrl[0] & DS1305_AEI0) {
379 ds1305->ctrl[0] &= ~DS1305_AEI0;
380
381 buf[0] = DS1305_WRITE | DS1305_CONTROL;
382 buf[1] = ds1305->ctrl[0];
383 status = spi_write_then_read(ds1305->spi, buf, 2, NULL, 0);
384 if (status < 0)
385 return status;
386 }
387
388 /* write alarm */
389 buf[0] = DS1305_WRITE | DS1305_ALM0(DS1305_SEC);
390 buf[1 + DS1305_SEC] = BIN2BCD(alm->time.tm_sec);
391 buf[1 + DS1305_MIN] = BIN2BCD(alm->time.tm_min);
392 buf[1 + DS1305_HOUR] = hour2bcd(ds1305->hr12, alm->time.tm_hour);
393 buf[1 + DS1305_WDAY] = DS1305_ALM_DISABLE;
394
395 dev_dbg(dev, "%s: %02x %02x %02x %02x\n",
396 "alm0 write", buf[1 + DS1305_SEC], buf[1 + DS1305_MIN],
397 buf[1 + DS1305_HOUR], buf[1 + DS1305_WDAY]);
398
399 status = spi_write_then_read(spi, buf, sizeof buf, NULL, 0);
400 if (status < 0)
401 return status;
402
403 /* enable alarm if requested */
404 if (alm->enabled) {
405 ds1305->ctrl[0] |= DS1305_AEI0;
406
407 buf[0] = DS1305_WRITE | DS1305_CONTROL;
408 buf[1] = ds1305->ctrl[0];
409 status = spi_write_then_read(ds1305->spi, buf, 2, NULL, 0);
410 }
411
412 return status;
413}
414
415#ifdef CONFIG_PROC_FS
416
417static int ds1305_proc(struct device *dev, struct seq_file *seq)
418{
419 struct ds1305 *ds1305 = dev_get_drvdata(dev);
420 char *diodes = "no";
421 char *resistors = "";
422
423 /* ctrl[2] is treated as read-only; no locking needed */
424 if ((ds1305->ctrl[2] & 0xf0) == DS1305_TRICKLE_MAGIC) {
425 switch (ds1305->ctrl[2] & 0x0c) {
426 case DS1305_TRICKLE_DS2:
427 diodes = "2 diodes, ";
428 break;
429 case DS1305_TRICKLE_DS1:
430 diodes = "1 diode, ";
431 break;
432 default:
433 goto done;
434 }
435 switch (ds1305->ctrl[2] & 0x03) {
436 case DS1305_TRICKLE_2K:
437 resistors = "2k Ohm";
438 break;
439 case DS1305_TRICKLE_4K:
440 resistors = "4k Ohm";
441 break;
442 case DS1305_TRICKLE_8K:
443 resistors = "8k Ohm";
444 break;
445 default:
446 diodes = "no";
447 break;
448 }
449 }
450
451done:
452 return seq_printf(seq,
453 "trickle_charge\t: %s%s\n",
454 diodes, resistors);
455}
456
457#else
458#define ds1305_proc NULL
459#endif
460
461static const struct rtc_class_ops ds1305_ops = {
462 .ioctl = ds1305_ioctl,
463 .read_time = ds1305_get_time,
464 .set_time = ds1305_set_time,
465 .read_alarm = ds1305_get_alarm,
466 .set_alarm = ds1305_set_alarm,
467 .proc = ds1305_proc,
468};
469
470static void ds1305_work(struct work_struct *work)
471{
472 struct ds1305 *ds1305 = container_of(work, struct ds1305, work);
473 struct mutex *lock = &ds1305->rtc->ops_lock;
474 struct spi_device *spi = ds1305->spi;
475 u8 buf[3];
476 int status;
477
478 /* lock to protect ds1305->ctrl */
479 mutex_lock(lock);
480
481 /* Disable the IRQ, and clear its status ... for now, we "know"
482 * that if more than one alarm is active, they're in sync.
483 * Note that reading ALM data registers also clears IRQ status.
484 */
485 ds1305->ctrl[0] &= ~(DS1305_AEI1 | DS1305_AEI0);
486 ds1305->ctrl[1] = 0;
487
488 buf[0] = DS1305_WRITE | DS1305_CONTROL;
489 buf[1] = ds1305->ctrl[0];
490 buf[2] = 0;
491
492 status = spi_write_then_read(spi, buf, sizeof buf,
493 NULL, 0);
494 if (status < 0)
495 dev_dbg(&spi->dev, "clear irq --> %d\n", status);
496
497 mutex_unlock(lock);
498
499 if (!test_bit(FLAG_EXITING, &ds1305->flags))
500 enable_irq(spi->irq);
501
502 /* rtc_update_irq() requires an IRQ-disabled context */
503 local_irq_disable();
504 rtc_update_irq(ds1305->rtc, 1, RTC_AF | RTC_IRQF);
505 local_irq_enable();
506}
507
508/*
509 * This "real" IRQ handler hands off to a workqueue mostly to allow
510 * mutex locking for ds1305->ctrl ... unlike I2C, we could issue async
511 * I/O requests in IRQ context (to clear the IRQ status).
512 */
513static irqreturn_t ds1305_irq(int irq, void *p)
514{
515 struct ds1305 *ds1305 = p;
516
517 disable_irq(irq);
518 schedule_work(&ds1305->work);
519 return IRQ_HANDLED;
520}
521
522/*----------------------------------------------------------------------*/
523
524/*
525 * Interface for NVRAM
526 */
527
528static void msg_init(struct spi_message *m, struct spi_transfer *x,
529 u8 *addr, size_t count, char *tx, char *rx)
530{
531 spi_message_init(m);
532 memset(x, 0, 2 * sizeof(*x));
533
534 x->tx_buf = addr;
535 x->len = 1;
536 spi_message_add_tail(x, m);
537
538 x++;
539
540 x->tx_buf = tx;
541 x->rx_buf = rx;
542 x->len = count;
543 spi_message_add_tail(x, m);
544}
545
546static ssize_t
547ds1305_nvram_read(struct kobject *kobj, struct bin_attribute *attr,
548 char *buf, loff_t off, size_t count)
549{
550 struct spi_device *spi;
551 u8 addr;
552 struct spi_message m;
553 struct spi_transfer x[2];
554 int status;
555
556 spi = container_of(kobj, struct spi_device, dev.kobj);
557
558 if (unlikely(off >= DS1305_NVRAM_LEN))
559 return 0;
560 if (count >= DS1305_NVRAM_LEN)
561 count = DS1305_NVRAM_LEN;
562 if ((off + count) > DS1305_NVRAM_LEN)
563 count = DS1305_NVRAM_LEN - off;
564 if (unlikely(!count))
565 return count;
566
567 addr = DS1305_NVRAM + off;
568 msg_init(&m, x, &addr, count, NULL, buf);
569
570 status = spi_sync(spi, &m);
571 if (status < 0)
572 dev_err(&spi->dev, "nvram %s error %d\n", "read", status);
573 return (status < 0) ? status : count;
574}
575
576static ssize_t
577ds1305_nvram_write(struct kobject *kobj, struct bin_attribute *attr,
578 char *buf, loff_t off, size_t count)
579{
580 struct spi_device *spi;
581 u8 addr;
582 struct spi_message m;
583 struct spi_transfer x[2];
584 int status;
585
586 spi = container_of(kobj, struct spi_device, dev.kobj);
587
588 if (unlikely(off >= DS1305_NVRAM_LEN))
589 return -EFBIG;
590 if (count >= DS1305_NVRAM_LEN)
591 count = DS1305_NVRAM_LEN;
592 if ((off + count) > DS1305_NVRAM_LEN)
593 count = DS1305_NVRAM_LEN - off;
594 if (unlikely(!count))
595 return count;
596
597 addr = (DS1305_WRITE | DS1305_NVRAM) + off;
598 msg_init(&m, x, &addr, count, buf, NULL);
599
600 status = spi_sync(spi, &m);
601 if (status < 0)
602 dev_err(&spi->dev, "nvram %s error %d\n", "write", status);
603 return (status < 0) ? status : count;
604}
605
606static struct bin_attribute nvram = {
607 .attr.name = "nvram",
608 .attr.mode = S_IRUGO | S_IWUSR,
609 .attr.owner = THIS_MODULE,
610 .read = ds1305_nvram_read,
611 .write = ds1305_nvram_write,
612 .size = DS1305_NVRAM_LEN,
613};
614
615/*----------------------------------------------------------------------*/
616
617/*
618 * Interface to SPI stack
619 */
620
621static int __devinit ds1305_probe(struct spi_device *spi)
622{
623 struct ds1305 *ds1305;
624 struct rtc_device *rtc;
625 int status;
626 u8 addr, value;
627 struct ds1305_platform_data *pdata = spi->dev.platform_data;
628 bool write_ctrl = false;
629
630 /* Sanity check board setup data. This may be hooked up
631 * in 3wire mode, but we don't care. Note that unless
632 * there's an inverter in place, this needs SPI_CS_HIGH!
633 */
634 if ((spi->bits_per_word && spi->bits_per_word != 8)
635 || (spi->max_speed_hz > 2000000)
636 || !(spi->mode & SPI_CPHA))
637 return -EINVAL;
638
639 /* set up driver data */
640 ds1305 = kzalloc(sizeof *ds1305, GFP_KERNEL);
641 if (!ds1305)
642 return -ENOMEM;
643 ds1305->spi = spi;
644 spi_set_drvdata(spi, ds1305);
645
646 /* read and cache control registers */
647 addr = DS1305_CONTROL;
648 status = spi_write_then_read(spi, &addr, sizeof addr,
649 ds1305->ctrl, sizeof ds1305->ctrl);
650 if (status < 0) {
651 dev_dbg(&spi->dev, "can't %s, %d\n",
652 "read", status);
653 goto fail0;
654 }
655
656 dev_dbg(&spi->dev, "ctrl %s: %02x %02x %02x\n",
657 "read", ds1305->ctrl[0],
658 ds1305->ctrl[1], ds1305->ctrl[2]);
659
660 /* Sanity check register values ... partially compensating for the
661 * fact that SPI has no device handshake. A pullup on MISO would
662 * make these tests fail; but not all systems will have one. If
663 * some register is neither 0x00 nor 0xff, a chip is likely there.
664 */
665 if ((ds1305->ctrl[0] & 0x38) != 0 || (ds1305->ctrl[1] & 0xfc) != 0) {
666 dev_dbg(&spi->dev, "RTC chip is not present\n");
667 status = -ENODEV;
668 goto fail0;
669 }
670 if (ds1305->ctrl[2] == 0)
671 dev_dbg(&spi->dev, "chip may not be present\n");
672
673 /* enable writes if needed ... if we were paranoid it would
674 * make sense to enable them only when absolutely necessary.
675 */
676 if (ds1305->ctrl[0] & DS1305_WP) {
677 u8 buf[2];
678
679 ds1305->ctrl[0] &= ~DS1305_WP;
680
681 buf[0] = DS1305_WRITE | DS1305_CONTROL;
682 buf[1] = ds1305->ctrl[0];
683 status = spi_write_then_read(spi, buf, sizeof buf, NULL, 0);
684
685 dev_dbg(&spi->dev, "clear WP --> %d\n", status);
686 if (status < 0)
687 goto fail0;
688 }
689
690 /* on DS1305, maybe start oscillator; like most low power
691 * oscillators, it may take a second to stabilize
692 */
693 if (ds1305->ctrl[0] & DS1305_nEOSC) {
694 ds1305->ctrl[0] &= ~DS1305_nEOSC;
695 write_ctrl = true;
696 dev_warn(&spi->dev, "SET TIME!\n");
697 }
698
699 /* ack any pending IRQs */
700 if (ds1305->ctrl[1]) {
701 ds1305->ctrl[1] = 0;
702 write_ctrl = true;
703 }
704
705 /* this may need one-time (re)init */
706 if (pdata) {
707 /* maybe enable trickle charge */
708 if (((ds1305->ctrl[2] & 0xf0) != DS1305_TRICKLE_MAGIC)) {
709 ds1305->ctrl[2] = DS1305_TRICKLE_MAGIC
710 | pdata->trickle;
711 write_ctrl = true;
712 }
713
714 /* on DS1306, configure 1 Hz signal */
715 if (pdata->is_ds1306) {
716 if (pdata->en_1hz) {
717 if (!(ds1305->ctrl[0] & DS1306_1HZ)) {
718 ds1305->ctrl[0] |= DS1306_1HZ;
719 write_ctrl = true;
720 }
721 } else {
722 if (ds1305->ctrl[0] & DS1306_1HZ) {
723 ds1305->ctrl[0] &= ~DS1306_1HZ;
724 write_ctrl = true;
725 }
726 }
727 }
728 }
729
730 if (write_ctrl) {
731 u8 buf[4];
732
733 buf[0] = DS1305_WRITE | DS1305_CONTROL;
734 buf[1] = ds1305->ctrl[0];
735 buf[2] = ds1305->ctrl[1];
736 buf[3] = ds1305->ctrl[2];
737 status = spi_write_then_read(spi, buf, sizeof buf, NULL, 0);
738 if (status < 0) {
739 dev_dbg(&spi->dev, "can't %s, %d\n",
740 "write", status);
741 goto fail0;
742 }
743
744 dev_dbg(&spi->dev, "ctrl %s: %02x %02x %02x\n",
745 "write", ds1305->ctrl[0],
746 ds1305->ctrl[1], ds1305->ctrl[2]);
747 }
748
749 /* see if non-Linux software set up AM/PM mode */
750 addr = DS1305_HOUR;
751 status = spi_write_then_read(spi, &addr, sizeof addr,
752 &value, sizeof value);
753 if (status < 0) {
754 dev_dbg(&spi->dev, "read HOUR --> %d\n", status);
755 goto fail0;
756 }
757
758 ds1305->hr12 = (DS1305_HR_12 & value) != 0;
759 if (ds1305->hr12)
760 dev_dbg(&spi->dev, "AM/PM\n");
761
762 /* register RTC ... from here on, ds1305->ctrl needs locking */
763 rtc = rtc_device_register("ds1305", &spi->dev,
764 &ds1305_ops, THIS_MODULE);
765 if (IS_ERR(rtc)) {
766 status = PTR_ERR(rtc);
767 dev_dbg(&spi->dev, "register rtc --> %d\n", status);
768 goto fail0;
769 }
770 ds1305->rtc = rtc;
771
772 /* Maybe set up alarm IRQ; be ready to handle it triggering right
773 * away. NOTE that we don't share this. The signal is active low,
774 * and we can't ack it before a SPI message delay. We temporarily
775 * disable the IRQ until it's acked, which lets us work with more
776 * IRQ trigger modes (not all IRQ controllers can do falling edge).
777 */
778 if (spi->irq) {
779 INIT_WORK(&ds1305->work, ds1305_work);
780 status = request_irq(spi->irq, ds1305_irq,
781 0, dev_name(&rtc->dev), ds1305);
782 if (status < 0) {
783 dev_dbg(&spi->dev, "request_irq %d --> %d\n",
784 spi->irq, status);
785 goto fail1;
786 }
787 }
788
789 /* export NVRAM */
790 status = sysfs_create_bin_file(&spi->dev.kobj, &nvram);
791 if (status < 0) {
792 dev_dbg(&spi->dev, "register nvram --> %d\n", status);
793 goto fail2;
794 }
795
796 return 0;
797
798fail2:
799 free_irq(spi->irq, ds1305);
800fail1:
801 rtc_device_unregister(rtc);
802fail0:
803 kfree(ds1305);
804 return status;
805}
806
807static int __devexit ds1305_remove(struct spi_device *spi)
808{
809 struct ds1305 *ds1305 = spi_get_drvdata(spi);
810
811 sysfs_remove_bin_file(&spi->dev.kobj, &nvram);
812
813 /* carefully shut down irq and workqueue, if present */
814 if (spi->irq) {
815 set_bit(FLAG_EXITING, &ds1305->flags);
816 free_irq(spi->irq, ds1305);
817 flush_scheduled_work();
818 }
819
820 rtc_device_unregister(ds1305->rtc);
821 spi_set_drvdata(spi, NULL);
822 kfree(ds1305);
823 return 0;
824}
825
826static struct spi_driver ds1305_driver = {
827 .driver.name = "rtc-ds1305",
828 .driver.owner = THIS_MODULE,
829 .probe = ds1305_probe,
830 .remove = __devexit_p(ds1305_remove),
831 /* REVISIT add suspend/resume */
832};
833
834static int __init ds1305_init(void)
835{
836 return spi_register_driver(&ds1305_driver);
837}
838module_init(ds1305_init);
839
840static void __exit ds1305_exit(void)
841{
842 spi_unregister_driver(&ds1305_driver);
843}
844module_exit(ds1305_exit);
845
846MODULE_DESCRIPTION("RTC driver for DS1305 and DS1306 chips");
847MODULE_LICENSE("GPL");
diff --git a/drivers/rtc/rtc-m41t80.c b/drivers/rtc/rtc-m41t80.c
index 0a19c06019be..24bc1689fc74 100644
--- a/drivers/rtc/rtc-m41t80.c
+++ b/drivers/rtc/rtc-m41t80.c
@@ -13,21 +13,21 @@
13 * 13 *
14 */ 14 */
15 15
16#include <linux/module.h> 16#include <linux/bcd.h>
17#include <linux/i2c.h>
17#include <linux/init.h> 18#include <linux/init.h>
18#include <linux/kernel.h> 19#include <linux/kernel.h>
20#include <linux/module.h>
21#include <linux/rtc.h>
19#include <linux/slab.h> 22#include <linux/slab.h>
20#include <linux/smp_lock.h> 23#include <linux/smp_lock.h>
21#include <linux/string.h> 24#include <linux/string.h>
22#include <linux/i2c.h>
23#include <linux/rtc.h>
24#include <linux/bcd.h>
25#ifdef CONFIG_RTC_DRV_M41T80_WDT 25#ifdef CONFIG_RTC_DRV_M41T80_WDT
26#include <linux/miscdevice.h>
27#include <linux/watchdog.h>
28#include <linux/reboot.h>
29#include <linux/fs.h> 26#include <linux/fs.h>
30#include <linux/ioctl.h> 27#include <linux/ioctl.h>
28#include <linux/miscdevice.h>
29#include <linux/reboot.h>
30#include <linux/watchdog.h>
31#endif 31#endif
32 32
33#define M41T80_REG_SSEC 0 33#define M41T80_REG_SSEC 0
@@ -631,14 +631,12 @@ static int wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
631 return -EFAULT; 631 return -EFAULT;
632 632
633 if (rv & WDIOS_DISABLECARD) { 633 if (rv & WDIOS_DISABLECARD) {
634 printk(KERN_INFO 634 pr_info("rtc-m41t80: disable watchdog\n");
635 "rtc-m41t80: disable watchdog\n");
636 wdt_disable(); 635 wdt_disable();
637 } 636 }
638 637
639 if (rv & WDIOS_ENABLECARD) { 638 if (rv & WDIOS_ENABLECARD) {
640 printk(KERN_INFO 639 pr_info("rtc-m41t80: enable watchdog\n");
641 "rtc-m41t80: enable watchdog\n");
642 wdt_ping(); 640 wdt_ping();
643 } 641 }
644 642
diff --git a/drivers/rtc/rtc-m41t94.c b/drivers/rtc/rtc-m41t94.c
new file mode 100644
index 000000000000..9b19499c829e
--- /dev/null
+++ b/drivers/rtc/rtc-m41t94.c
@@ -0,0 +1,173 @@
1/*
2 * Driver for ST M41T94 SPI RTC
3 *
4 * Copyright (C) 2008 Kim B. Heino
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10
11#include <linux/module.h>
12#include <linux/kernel.h>
13#include <linux/platform_device.h>
14#include <linux/rtc.h>
15#include <linux/spi/spi.h>
16#include <linux/bcd.h>
17
18#define M41T94_REG_SECONDS 0x01
19#define M41T94_REG_MINUTES 0x02
20#define M41T94_REG_HOURS 0x03
21#define M41T94_REG_WDAY 0x04
22#define M41T94_REG_DAY 0x05
23#define M41T94_REG_MONTH 0x06
24#define M41T94_REG_YEAR 0x07
25#define M41T94_REG_HT 0x0c
26
27#define M41T94_BIT_HALT 0x40
28#define M41T94_BIT_STOP 0x80
29#define M41T94_BIT_CB 0x40
30#define M41T94_BIT_CEB 0x80
31
32static int m41t94_set_time(struct device *dev, struct rtc_time *tm)
33{
34 struct spi_device *spi = to_spi_device(dev);
35 u8 buf[8]; /* write cmd + 7 registers */
36
37 dev_dbg(dev, "%s secs=%d, mins=%d, "
38 "hours=%d, mday=%d, mon=%d, year=%d, wday=%d\n",
39 "write", tm->tm_sec, tm->tm_min,
40 tm->tm_hour, tm->tm_mday,
41 tm->tm_mon, tm->tm_year, tm->tm_wday);
42
43 buf[0] = 0x80 | M41T94_REG_SECONDS; /* write time + date */
44 buf[M41T94_REG_SECONDS] = BIN2BCD(tm->tm_sec);
45 buf[M41T94_REG_MINUTES] = BIN2BCD(tm->tm_min);
46 buf[M41T94_REG_HOURS] = BIN2BCD(tm->tm_hour);
47 buf[M41T94_REG_WDAY] = BIN2BCD(tm->tm_wday + 1);
48 buf[M41T94_REG_DAY] = BIN2BCD(tm->tm_mday);
49 buf[M41T94_REG_MONTH] = BIN2BCD(tm->tm_mon + 1);
50
51 buf[M41T94_REG_HOURS] |= M41T94_BIT_CEB;
52 if (tm->tm_year >= 100)
53 buf[M41T94_REG_HOURS] |= M41T94_BIT_CB;
54 buf[M41T94_REG_YEAR] = BIN2BCD(tm->tm_year % 100);
55
56 return spi_write(spi, buf, 8);
57}
58
59static int m41t94_read_time(struct device *dev, struct rtc_time *tm)
60{
61 struct spi_device *spi = to_spi_device(dev);
62 u8 buf[2];
63 int ret, hour;
64
65 /* clear halt update bit */
66 ret = spi_w8r8(spi, M41T94_REG_HT);
67 if (ret < 0)
68 return ret;
69 if (ret & M41T94_BIT_HALT) {
70 buf[0] = 0x80 | M41T94_REG_HT;
71 buf[1] = ret & ~M41T94_BIT_HALT;
72 spi_write(spi, buf, 2);
73 }
74
75 /* clear stop bit */
76 ret = spi_w8r8(spi, M41T94_REG_SECONDS);
77 if (ret < 0)
78 return ret;
79 if (ret & M41T94_BIT_STOP) {
80 buf[0] = 0x80 | M41T94_REG_SECONDS;
81 buf[1] = ret & ~M41T94_BIT_STOP;
82 spi_write(spi, buf, 2);
83 }
84
85 tm->tm_sec = BCD2BIN(spi_w8r8(spi, M41T94_REG_SECONDS));
86 tm->tm_min = BCD2BIN(spi_w8r8(spi, M41T94_REG_MINUTES));
87 hour = spi_w8r8(spi, M41T94_REG_HOURS);
88 tm->tm_hour = BCD2BIN(hour & 0x3f);
89 tm->tm_wday = BCD2BIN(spi_w8r8(spi, M41T94_REG_WDAY)) - 1;
90 tm->tm_mday = BCD2BIN(spi_w8r8(spi, M41T94_REG_DAY));
91 tm->tm_mon = BCD2BIN(spi_w8r8(spi, M41T94_REG_MONTH)) - 1;
92 tm->tm_year = BCD2BIN(spi_w8r8(spi, M41T94_REG_YEAR));
93 if ((hour & M41T94_BIT_CB) || !(hour & M41T94_BIT_CEB))
94 tm->tm_year += 100;
95
96 dev_dbg(dev, "%s secs=%d, mins=%d, "
97 "hours=%d, mday=%d, mon=%d, year=%d, wday=%d\n",
98 "read", tm->tm_sec, tm->tm_min,
99 tm->tm_hour, tm->tm_mday,
100 tm->tm_mon, tm->tm_year, tm->tm_wday);
101
102 /* initial clock setting can be undefined */
103 return rtc_valid_tm(tm);
104}
105
106static const struct rtc_class_ops m41t94_rtc_ops = {
107 .read_time = m41t94_read_time,
108 .set_time = m41t94_set_time,
109};
110
111static struct spi_driver m41t94_driver;
112
113static int __devinit m41t94_probe(struct spi_device *spi)
114{
115 struct rtc_device *rtc;
116 int res;
117
118 spi->bits_per_word = 8;
119 spi_setup(spi);
120
121 res = spi_w8r8(spi, M41T94_REG_SECONDS);
122 if (res < 0) {
123 dev_err(&spi->dev, "not found.\n");
124 return res;
125 }
126
127 rtc = rtc_device_register(m41t94_driver.driver.name,
128 &spi->dev, &m41t94_rtc_ops, THIS_MODULE);
129 if (IS_ERR(rtc))
130 return PTR_ERR(rtc);
131
132 dev_set_drvdata(&spi->dev, rtc);
133
134 return 0;
135}
136
137static int __devexit m41t94_remove(struct spi_device *spi)
138{
139 struct rtc_device *rtc = platform_get_drvdata(spi);
140
141 if (rtc)
142 rtc_device_unregister(rtc);
143
144 return 0;
145}
146
147static struct spi_driver m41t94_driver = {
148 .driver = {
149 .name = "rtc-m41t94",
150 .bus = &spi_bus_type,
151 .owner = THIS_MODULE,
152 },
153 .probe = m41t94_probe,
154 .remove = __devexit_p(m41t94_remove),
155};
156
157static __init int m41t94_init(void)
158{
159 return spi_register_driver(&m41t94_driver);
160}
161
162module_init(m41t94_init);
163
164static __exit void m41t94_exit(void)
165{
166 spi_unregister_driver(&m41t94_driver);
167}
168
169module_exit(m41t94_exit);
170
171MODULE_AUTHOR("Kim B. Heino <Kim.Heino@bluegiga.com>");
172MODULE_DESCRIPTION("Driver for ST M41T94 SPI RTC");
173MODULE_LICENSE("GPL");
diff --git a/drivers/rtc/rtc-omap.c b/drivers/rtc/rtc-omap.c
index eb23d8423f42..8876605d4d4b 100644
--- a/drivers/rtc/rtc-omap.c
+++ b/drivers/rtc/rtc-omap.c
@@ -92,18 +92,6 @@
92#define rtc_write(val, addr) omap_writeb(val, OMAP_RTC_BASE + (addr)) 92#define rtc_write(val, addr) omap_writeb(val, OMAP_RTC_BASE + (addr))
93 93
94 94
95/* platform_bus isn't hotpluggable, so for static linkage it'd be safe
96 * to get rid of probe() and remove() code ... too bad the driver struct
97 * remembers probe(), that's about 25% of the runtime footprint!!
98 */
99#ifndef MODULE
100#undef __devexit
101#undef __devexit_p
102#define __devexit __exit
103#define __devexit_p __exit_p
104#endif
105
106
107/* we rely on the rtc framework to handle locking (rtc->ops_lock), 95/* we rely on the rtc framework to handle locking (rtc->ops_lock),
108 * so the only other requirement is that register accesses which 96 * so the only other requirement is that register accesses which
109 * require BUSY to be clear are made with IRQs locally disabled 97 * require BUSY to be clear are made with IRQs locally disabled
@@ -324,7 +312,7 @@ static struct rtc_class_ops omap_rtc_ops = {
324static int omap_rtc_alarm; 312static int omap_rtc_alarm;
325static int omap_rtc_timer; 313static int omap_rtc_timer;
326 314
327static int __devinit omap_rtc_probe(struct platform_device *pdev) 315static int __init omap_rtc_probe(struct platform_device *pdev)
328{ 316{
329 struct resource *res, *mem; 317 struct resource *res, *mem;
330 struct rtc_device *rtc; 318 struct rtc_device *rtc;
@@ -440,7 +428,7 @@ fail:
440 return -EIO; 428 return -EIO;
441} 429}
442 430
443static int __devexit omap_rtc_remove(struct platform_device *pdev) 431static int __exit omap_rtc_remove(struct platform_device *pdev)
444{ 432{
445 struct rtc_device *rtc = platform_get_drvdata(pdev);; 433 struct rtc_device *rtc = platform_get_drvdata(pdev);;
446 434
@@ -498,8 +486,7 @@ static void omap_rtc_shutdown(struct platform_device *pdev)
498 486
499MODULE_ALIAS("platform:omap_rtc"); 487MODULE_ALIAS("platform:omap_rtc");
500static struct platform_driver omap_rtc_driver = { 488static struct platform_driver omap_rtc_driver = {
501 .probe = omap_rtc_probe, 489 .remove = __exit_p(omap_rtc_remove),
502 .remove = __devexit_p(omap_rtc_remove),
503 .suspend = omap_rtc_suspend, 490 .suspend = omap_rtc_suspend,
504 .resume = omap_rtc_resume, 491 .resume = omap_rtc_resume,
505 .shutdown = omap_rtc_shutdown, 492 .shutdown = omap_rtc_shutdown,
@@ -511,7 +498,7 @@ static struct platform_driver omap_rtc_driver = {
511 498
512static int __init rtc_init(void) 499static int __init rtc_init(void)
513{ 500{
514 return platform_driver_register(&omap_rtc_driver); 501 return platform_driver_probe(&omap_rtc_driver, omap_rtc_probe);
515} 502}
516module_init(rtc_init); 503module_init(rtc_init);
517 504
diff --git a/drivers/rtc/rtc-pcf8583.c b/drivers/rtc/rtc-pcf8583.c
index 3d09d8f0b1f0..d388c662bf4b 100644
--- a/drivers/rtc/rtc-pcf8583.c
+++ b/drivers/rtc/rtc-pcf8583.c
@@ -2,6 +2,7 @@
2 * drivers/rtc/rtc-pcf8583.c 2 * drivers/rtc/rtc-pcf8583.c
3 * 3 *
4 * Copyright (C) 2000 Russell King 4 * Copyright (C) 2000 Russell King
5 * Copyright (C) 2008 Wolfram Sang & Juergen Beisert, Pengutronix
5 * 6 *
6 * This program is free software; you can redistribute it and/or modify 7 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as 8 * it under the terms of the GNU General Public License version 2 as
@@ -14,7 +15,6 @@
14#include <linux/module.h> 15#include <linux/module.h>
15#include <linux/i2c.h> 16#include <linux/i2c.h>
16#include <linux/slab.h> 17#include <linux/slab.h>
17#include <linux/string.h>
18#include <linux/rtc.h> 18#include <linux/rtc.h>
19#include <linux/init.h> 19#include <linux/init.h>
20#include <linux/errno.h> 20#include <linux/errno.h>
@@ -27,7 +27,6 @@ struct rtc_mem {
27}; 27};
28 28
29struct pcf8583 { 29struct pcf8583 {
30 struct i2c_client client;
31 struct rtc_device *rtc; 30 struct rtc_device *rtc;
32 unsigned char ctrl; 31 unsigned char ctrl;
33}; 32};
@@ -40,10 +39,6 @@ struct pcf8583 {
40#define CTRL_ALARM 0x02 39#define CTRL_ALARM 0x02
41#define CTRL_TIMER 0x01 40#define CTRL_TIMER 0x01
42 41
43static const unsigned short normal_i2c[] = { 0x50, I2C_CLIENT_END };
44
45/* Module parameters */
46I2C_CLIENT_INSMOD;
47 42
48static struct i2c_driver pcf8583_driver; 43static struct i2c_driver pcf8583_driver;
49 44
@@ -269,106 +264,60 @@ static const struct rtc_class_ops pcf8583_rtc_ops = {
269 .set_time = pcf8583_rtc_set_time, 264 .set_time = pcf8583_rtc_set_time,
270}; 265};
271 266
272static int pcf8583_probe(struct i2c_adapter *adap, int addr, int kind); 267static int pcf8583_probe(struct i2c_client *client,
273 268 const struct i2c_device_id *id)
274static int pcf8583_attach(struct i2c_adapter *adap)
275{
276 return i2c_probe(adap, &addr_data, pcf8583_probe);
277}
278
279static int pcf8583_detach(struct i2c_client *client)
280{
281 int err;
282 struct pcf8583 *pcf = i2c_get_clientdata(client);
283 struct rtc_device *rtc = pcf->rtc;
284
285 if (rtc)
286 rtc_device_unregister(rtc);
287
288 if ((err = i2c_detach_client(client)))
289 return err;
290
291 kfree(pcf);
292 return 0;
293}
294
295static struct i2c_driver pcf8583_driver = {
296 .driver = {
297 .name = "pcf8583",
298 },
299 .id = I2C_DRIVERID_PCF8583,
300 .attach_adapter = pcf8583_attach,
301 .detach_client = pcf8583_detach,
302};
303
304static int pcf8583_probe(struct i2c_adapter *adap, int addr, int kind)
305{ 269{
306 struct pcf8583 *pcf; 270 struct pcf8583 *pcf8583;
307 struct i2c_client *client;
308 struct rtc_device *rtc;
309 unsigned char buf[1], ad[1] = { 0 };
310 int err; 271 int err;
311 struct i2c_msg msgs[2] = {
312 {
313 .addr = addr,
314 .flags = 0,
315 .len = 1,
316 .buf = ad,
317 }, {
318 .addr = addr,
319 .flags = I2C_M_RD,
320 .len = 1,
321 .buf = buf,
322 }
323 };
324 272
325 if (!i2c_check_functionality(adap, I2C_FUNC_I2C)) 273 if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C))
326 return 0; 274 return -ENODEV;
327 275
328 pcf = kzalloc(sizeof(*pcf), GFP_KERNEL); 276 pcf8583 = kzalloc(sizeof(struct pcf8583), GFP_KERNEL);
329 if (!pcf) 277 if (!pcf8583)
330 return -ENOMEM; 278 return -ENOMEM;
331 279
332 client = &pcf->client; 280 pcf8583->rtc = rtc_device_register(pcf8583_driver.driver.name,
281 &client->dev, &pcf8583_rtc_ops, THIS_MODULE);
333 282
334 client->addr = addr; 283 if (IS_ERR(pcf8583->rtc)) {
335 client->adapter = adap; 284 err = PTR_ERR(pcf8583->rtc);
336 client->driver = &pcf8583_driver;
337
338 strlcpy(client->name, pcf8583_driver.driver.name, I2C_NAME_SIZE);
339
340 if (i2c_transfer(client->adapter, msgs, 2) != 2) {
341 err = -EIO;
342 goto exit_kfree; 285 goto exit_kfree;
343 } 286 }
344 287
345 err = i2c_attach_client(client); 288 i2c_set_clientdata(client, pcf8583);
346 289 return 0;
347 if (err)
348 goto exit_kfree;
349
350 rtc = rtc_device_register(pcf8583_driver.driver.name, &client->dev,
351 &pcf8583_rtc_ops, THIS_MODULE);
352 290
353 if (IS_ERR(rtc)) { 291exit_kfree:
354 err = PTR_ERR(rtc); 292 kfree(pcf8583);
355 goto exit_detach; 293 return err;
356 } 294}
357 295
358 pcf->rtc = rtc; 296static int __devexit pcf8583_remove(struct i2c_client *client)
359 i2c_set_clientdata(client, pcf); 297{
360 set_ctrl(client, buf[0]); 298 struct pcf8583 *pcf8583 = i2c_get_clientdata(client);
361 299
300 if (pcf8583->rtc)
301 rtc_device_unregister(pcf8583->rtc);
302 kfree(pcf8583);
362 return 0; 303 return 0;
304}
363 305
364exit_detach: 306static const struct i2c_device_id pcf8583_id[] = {
365 i2c_detach_client(client); 307 { "pcf8583", 0 },
366 308 { }
367exit_kfree: 309};
368 kfree(pcf); 310MODULE_DEVICE_TABLE(i2c, pcf8583_id);
369 311
370 return err; 312static struct i2c_driver pcf8583_driver = {
371} 313 .driver = {
314 .name = "pcf8583",
315 .owner = THIS_MODULE,
316 },
317 .probe = pcf8583_probe,
318 .remove = __devexit_p(pcf8583_remove),
319 .id_table = pcf8583_id,
320};
372 321
373static __init int pcf8583_init(void) 322static __init int pcf8583_init(void)
374{ 323{
diff --git a/drivers/rtc/rtc-s3c.c b/drivers/rtc/rtc-s3c.c
index fed86e507fdf..54b1ebb01502 100644
--- a/drivers/rtc/rtc-s3c.c
+++ b/drivers/rtc/rtc-s3c.c
@@ -36,10 +36,8 @@ static struct resource *s3c_rtc_mem;
36static void __iomem *s3c_rtc_base; 36static void __iomem *s3c_rtc_base;
37static int s3c_rtc_alarmno = NO_IRQ; 37static int s3c_rtc_alarmno = NO_IRQ;
38static int s3c_rtc_tickno = NO_IRQ; 38static int s3c_rtc_tickno = NO_IRQ;
39static int s3c_rtc_freq = 1;
40 39
41static DEFINE_SPINLOCK(s3c_rtc_pie_lock); 40static DEFINE_SPINLOCK(s3c_rtc_pie_lock);
42static unsigned int tick_count;
43 41
44/* IRQ Handlers */ 42/* IRQ Handlers */
45 43
@@ -55,7 +53,7 @@ static irqreturn_t s3c_rtc_tickirq(int irq, void *id)
55{ 53{
56 struct rtc_device *rdev = id; 54 struct rtc_device *rdev = id;
57 55
58 rtc_update_irq(rdev, tick_count++, RTC_PF | RTC_IRQF); 56 rtc_update_irq(rdev, 1, RTC_PF | RTC_IRQF);
59 return IRQ_HANDLED; 57 return IRQ_HANDLED;
60} 58}
61 59
@@ -74,35 +72,37 @@ static void s3c_rtc_setaie(int to)
74 writeb(tmp, s3c_rtc_base + S3C2410_RTCALM); 72 writeb(tmp, s3c_rtc_base + S3C2410_RTCALM);
75} 73}
76 74
77static void s3c_rtc_setpie(int to) 75static int s3c_rtc_setpie(struct device *dev, int enabled)
78{ 76{
79 unsigned int tmp; 77 unsigned int tmp;
80 78
81 pr_debug("%s: pie=%d\n", __func__, to); 79 pr_debug("%s: pie=%d\n", __func__, enabled);
82 80
83 spin_lock_irq(&s3c_rtc_pie_lock); 81 spin_lock_irq(&s3c_rtc_pie_lock);
84 tmp = readb(s3c_rtc_base + S3C2410_TICNT) & ~S3C2410_TICNT_ENABLE; 82 tmp = readb(s3c_rtc_base + S3C2410_TICNT) & ~S3C2410_TICNT_ENABLE;
85 83
86 if (to) 84 if (enabled)
87 tmp |= S3C2410_TICNT_ENABLE; 85 tmp |= S3C2410_TICNT_ENABLE;
88 86
89 writeb(tmp, s3c_rtc_base + S3C2410_TICNT); 87 writeb(tmp, s3c_rtc_base + S3C2410_TICNT);
90 spin_unlock_irq(&s3c_rtc_pie_lock); 88 spin_unlock_irq(&s3c_rtc_pie_lock);
89
90 return 0;
91} 91}
92 92
93static void s3c_rtc_setfreq(int freq) 93static int s3c_rtc_setfreq(struct device *dev, int freq)
94{ 94{
95 unsigned int tmp; 95 unsigned int tmp;
96 96
97 spin_lock_irq(&s3c_rtc_pie_lock); 97 spin_lock_irq(&s3c_rtc_pie_lock);
98 tmp = readb(s3c_rtc_base + S3C2410_TICNT) & S3C2410_TICNT_ENABLE;
99
100 s3c_rtc_freq = freq;
101 98
99 tmp = readb(s3c_rtc_base + S3C2410_TICNT) & S3C2410_TICNT_ENABLE;
102 tmp |= (128 / freq)-1; 100 tmp |= (128 / freq)-1;
103 101
104 writeb(tmp, s3c_rtc_base + S3C2410_TICNT); 102 writeb(tmp, s3c_rtc_base + S3C2410_TICNT);
105 spin_unlock_irq(&s3c_rtc_pie_lock); 103 spin_unlock_irq(&s3c_rtc_pie_lock);
104
105 return 0;
106} 106}
107 107
108/* Time read/write */ 108/* Time read/write */
@@ -267,12 +267,7 @@ static int s3c_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm)
267 267
268 writeb(alrm_en, base + S3C2410_RTCALM); 268 writeb(alrm_en, base + S3C2410_RTCALM);
269 269
270 if (0) { 270 s3c_rtc_setaie(alrm->enabled);
271 alrm_en = readb(base + S3C2410_RTCALM);
272 alrm_en &= ~S3C2410_RTCALM_ALMEN;
273 writeb(alrm_en, base + S3C2410_RTCALM);
274 disable_irq_wake(s3c_rtc_alarmno);
275 }
276 271
277 if (alrm->enabled) 272 if (alrm->enabled)
278 enable_irq_wake(s3c_rtc_alarmno); 273 enable_irq_wake(s3c_rtc_alarmno);
@@ -282,59 +277,12 @@ static int s3c_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm)
282 return 0; 277 return 0;
283} 278}
284 279
285static int s3c_rtc_ioctl(struct device *dev,
286 unsigned int cmd, unsigned long arg)
287{
288 unsigned int ret = -ENOIOCTLCMD;
289
290 switch (cmd) {
291 case RTC_AIE_OFF:
292 case RTC_AIE_ON:
293 s3c_rtc_setaie((cmd == RTC_AIE_ON) ? 1 : 0);
294 ret = 0;
295 break;
296
297 case RTC_PIE_OFF:
298 case RTC_PIE_ON:
299 tick_count = 0;
300 s3c_rtc_setpie((cmd == RTC_PIE_ON) ? 1 : 0);
301 ret = 0;
302 break;
303
304 case RTC_IRQP_READ:
305 ret = put_user(s3c_rtc_freq, (unsigned long __user *)arg);
306 break;
307
308 case RTC_IRQP_SET:
309 if (!is_power_of_2(arg)) {
310 ret = -EINVAL;
311 goto exit;
312 }
313
314 pr_debug("s3c2410_rtc: setting frequency %ld\n", arg);
315
316 s3c_rtc_setfreq(arg);
317 ret = 0;
318 break;
319
320 case RTC_UIE_ON:
321 case RTC_UIE_OFF:
322 ret = -EINVAL;
323 }
324
325 exit:
326 return ret;
327}
328
329static int s3c_rtc_proc(struct device *dev, struct seq_file *seq) 280static int s3c_rtc_proc(struct device *dev, struct seq_file *seq)
330{ 281{
331 unsigned int ticnt = readb(s3c_rtc_base + S3C2410_TICNT); 282 unsigned int ticnt = readb(s3c_rtc_base + S3C2410_TICNT);
332 283
333 seq_printf(seq, "periodic_IRQ\t: %s\n", 284 seq_printf(seq, "periodic_IRQ\t: %s\n",
334 (ticnt & S3C2410_TICNT_ENABLE) ? "yes" : "no" ); 285 (ticnt & S3C2410_TICNT_ENABLE) ? "yes" : "no" );
335
336 seq_printf(seq, "periodic_freq\t: %d\n", s3c_rtc_freq);
337
338 return 0; 286 return 0;
339} 287}
340 288
@@ -374,7 +322,7 @@ static void s3c_rtc_release(struct device *dev)
374 322
375 /* do not clear AIE here, it may be needed for wake */ 323 /* do not clear AIE here, it may be needed for wake */
376 324
377 s3c_rtc_setpie(0); 325 s3c_rtc_setpie(dev, 0);
378 free_irq(s3c_rtc_alarmno, rtc_dev); 326 free_irq(s3c_rtc_alarmno, rtc_dev);
379 free_irq(s3c_rtc_tickno, rtc_dev); 327 free_irq(s3c_rtc_tickno, rtc_dev);
380} 328}
@@ -382,11 +330,12 @@ static void s3c_rtc_release(struct device *dev)
382static const struct rtc_class_ops s3c_rtcops = { 330static const struct rtc_class_ops s3c_rtcops = {
383 .open = s3c_rtc_open, 331 .open = s3c_rtc_open,
384 .release = s3c_rtc_release, 332 .release = s3c_rtc_release,
385 .ioctl = s3c_rtc_ioctl,
386 .read_time = s3c_rtc_gettime, 333 .read_time = s3c_rtc_gettime,
387 .set_time = s3c_rtc_settime, 334 .set_time = s3c_rtc_settime,
388 .read_alarm = s3c_rtc_getalarm, 335 .read_alarm = s3c_rtc_getalarm,
389 .set_alarm = s3c_rtc_setalarm, 336 .set_alarm = s3c_rtc_setalarm,
337 .irq_set_freq = s3c_rtc_setfreq,
338 .irq_set_state = s3c_rtc_setpie,
390 .proc = s3c_rtc_proc, 339 .proc = s3c_rtc_proc,
391}; 340};
392 341
@@ -430,14 +379,14 @@ static void s3c_rtc_enable(struct platform_device *pdev, int en)
430 } 379 }
431} 380}
432 381
433static int s3c_rtc_remove(struct platform_device *dev) 382static int __devexit s3c_rtc_remove(struct platform_device *dev)
434{ 383{
435 struct rtc_device *rtc = platform_get_drvdata(dev); 384 struct rtc_device *rtc = platform_get_drvdata(dev);
436 385
437 platform_set_drvdata(dev, NULL); 386 platform_set_drvdata(dev, NULL);
438 rtc_device_unregister(rtc); 387 rtc_device_unregister(rtc);
439 388
440 s3c_rtc_setpie(0); 389 s3c_rtc_setpie(&dev->dev, 0);
441 s3c_rtc_setaie(0); 390 s3c_rtc_setaie(0);
442 391
443 iounmap(s3c_rtc_base); 392 iounmap(s3c_rtc_base);
@@ -447,7 +396,7 @@ static int s3c_rtc_remove(struct platform_device *dev)
447 return 0; 396 return 0;
448} 397}
449 398
450static int s3c_rtc_probe(struct platform_device *pdev) 399static int __devinit s3c_rtc_probe(struct platform_device *pdev)
451{ 400{
452 struct rtc_device *rtc; 401 struct rtc_device *rtc;
453 struct resource *res; 402 struct resource *res;
@@ -504,7 +453,7 @@ static int s3c_rtc_probe(struct platform_device *pdev)
504 pr_debug("s3c2410_rtc: RTCCON=%02x\n", 453 pr_debug("s3c2410_rtc: RTCCON=%02x\n",
505 readb(s3c_rtc_base + S3C2410_RTCCON)); 454 readb(s3c_rtc_base + S3C2410_RTCCON));
506 455
507 s3c_rtc_setfreq(s3c_rtc_freq); 456 s3c_rtc_setfreq(&pdev->dev, 1);
508 457
509 /* register RTC and exit */ 458 /* register RTC and exit */
510 459
@@ -560,7 +509,7 @@ static int s3c_rtc_resume(struct platform_device *pdev)
560 509
561static struct platform_driver s3c2410_rtcdrv = { 510static struct platform_driver s3c2410_rtcdrv = {
562 .probe = s3c_rtc_probe, 511 .probe = s3c_rtc_probe,
563 .remove = s3c_rtc_remove, 512 .remove = __devexit_p(s3c_rtc_remove),
564 .suspend = s3c_rtc_suspend, 513 .suspend = s3c_rtc_suspend,
565 .resume = s3c_rtc_resume, 514 .resume = s3c_rtc_resume,
566 .driver = { 515 .driver = {
diff --git a/drivers/rtc/rtc-vr41xx.c b/drivers/rtc/rtc-vr41xx.c
index be9c70d0b193..884b635f028b 100644
--- a/drivers/rtc/rtc-vr41xx.c
+++ b/drivers/rtc/rtc-vr41xx.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * Driver for NEC VR4100 series Real Time Clock unit. 2 * Driver for NEC VR4100 series Real Time Clock unit.
3 * 3 *
4 * Copyright (C) 2003-2006 Yoichi Yuasa <yoichi_yuasa@tripeaks.co.jp> 4 * Copyright (C) 2003-2008 Yoichi Yuasa <yoichi_yuasa@tripeaks.co.jp>
5 * 5 *
6 * This program is free software; you can redistribute it and/or modify 6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by 7 * it under the terms of the GNU General Public License as published by
@@ -34,7 +34,7 @@
34 34
35MODULE_AUTHOR("Yoichi Yuasa <yoichi_yuasa@tripeaks.co.jp>"); 35MODULE_AUTHOR("Yoichi Yuasa <yoichi_yuasa@tripeaks.co.jp>");
36MODULE_DESCRIPTION("NEC VR4100 series RTC driver"); 36MODULE_DESCRIPTION("NEC VR4100 series RTC driver");
37MODULE_LICENSE("GPL"); 37MODULE_LICENSE("GPL v2");
38 38
39/* RTC 1 registers */ 39/* RTC 1 registers */
40#define ETIMELREG 0x00 40#define ETIMELREG 0x00
@@ -82,7 +82,6 @@ static unsigned long epoch = 1970; /* Jan 1 1970 00:00:00 */
82 82
83static DEFINE_SPINLOCK(rtc_lock); 83static DEFINE_SPINLOCK(rtc_lock);
84static char rtc_name[] = "RTC"; 84static char rtc_name[] = "RTC";
85static unsigned long periodic_frequency;
86static unsigned long periodic_count; 85static unsigned long periodic_count;
87static unsigned int alarm_enabled; 86static unsigned int alarm_enabled;
88static int aie_irq = -1; 87static int aie_irq = -1;
@@ -207,10 +206,37 @@ static int vr41xx_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *wkalrm)
207 return 0; 206 return 0;
208} 207}
209 208
210static int vr41xx_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg) 209static int vr41xx_rtc_irq_set_freq(struct device *dev, int freq)
211{ 210{
212 unsigned long count; 211 unsigned long count;
213 212
213 count = RTC_FREQUENCY;
214 do_div(count, freq);
215
216 periodic_count = count;
217
218 spin_lock_irq(&rtc_lock);
219
220 rtc1_write(RTCL1LREG, count);
221 rtc1_write(RTCL1HREG, count >> 16);
222
223 spin_unlock_irq(&rtc_lock);
224
225 return 0;
226}
227
228static int vr41xx_rtc_irq_set_state(struct device *dev, int enabled)
229{
230 if (enabled)
231 enable_irq(pie_irq);
232 else
233 disable_irq(pie_irq);
234
235 return 0;
236}
237
238static int vr41xx_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
239{
214 switch (cmd) { 240 switch (cmd) {
215 case RTC_AIE_ON: 241 case RTC_AIE_ON:
216 spin_lock_irq(&rtc_lock); 242 spin_lock_irq(&rtc_lock);
@@ -232,33 +258,6 @@ static int vr41xx_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long
232 258
233 spin_unlock_irq(&rtc_lock); 259 spin_unlock_irq(&rtc_lock);
234 break; 260 break;
235 case RTC_PIE_ON:
236 enable_irq(pie_irq);
237 break;
238 case RTC_PIE_OFF:
239 disable_irq(pie_irq);
240 break;
241 case RTC_IRQP_READ:
242 return put_user(periodic_frequency, (unsigned long __user *)arg);
243 break;
244 case RTC_IRQP_SET:
245 if (arg > MAX_PERIODIC_RATE)
246 return -EINVAL;
247
248 periodic_frequency = arg;
249
250 count = RTC_FREQUENCY;
251 do_div(count, arg);
252
253 periodic_count = count;
254
255 spin_lock_irq(&rtc_lock);
256
257 rtc1_write(RTCL1LREG, count);
258 rtc1_write(RTCL1HREG, count >> 16);
259
260 spin_unlock_irq(&rtc_lock);
261 break;
262 case RTC_EPOCH_READ: 261 case RTC_EPOCH_READ:
263 return put_user(epoch, (unsigned long __user *)arg); 262 return put_user(epoch, (unsigned long __user *)arg);
264 case RTC_EPOCH_SET: 263 case RTC_EPOCH_SET:
@@ -309,6 +308,8 @@ static const struct rtc_class_ops vr41xx_rtc_ops = {
309 .set_time = vr41xx_rtc_set_time, 308 .set_time = vr41xx_rtc_set_time,
310 .read_alarm = vr41xx_rtc_read_alarm, 309 .read_alarm = vr41xx_rtc_read_alarm,
311 .set_alarm = vr41xx_rtc_set_alarm, 310 .set_alarm = vr41xx_rtc_set_alarm,
311 .irq_set_freq = vr41xx_rtc_irq_set_freq,
312 .irq_set_state = vr41xx_rtc_irq_set_state,
312}; 313};
313 314
314static int __devinit rtc_probe(struct platform_device *pdev) 315static int __devinit rtc_probe(struct platform_device *pdev)
@@ -346,6 +347,8 @@ static int __devinit rtc_probe(struct platform_device *pdev)
346 goto err_iounmap_all; 347 goto err_iounmap_all;
347 } 348 }
348 349
350 rtc->max_user_freq = MAX_PERIODIC_RATE;
351
349 spin_lock_irq(&rtc_lock); 352 spin_lock_irq(&rtc_lock);
350 353
351 rtc1_write(ECMPLREG, 0); 354 rtc1_write(ECMPLREG, 0);
diff --git a/drivers/scsi/sun_esp.c b/drivers/scsi/sun_esp.c
index 2c87db98cdfb..f9cf70151366 100644
--- a/drivers/scsi/sun_esp.c
+++ b/drivers/scsi/sun_esp.c
@@ -7,6 +7,7 @@
7#include <linux/types.h> 7#include <linux/types.h>
8#include <linux/delay.h> 8#include <linux/delay.h>
9#include <linux/module.h> 9#include <linux/module.h>
10#include <linux/mm.h>
10#include <linux/init.h> 11#include <linux/init.h>
11 12
12#include <asm/irq.h> 13#include <asm/irq.h>
diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c
index 27f34a9f9cb7..a97f1ae11f78 100644
--- a/drivers/serial/8250.c
+++ b/drivers/serial/8250.c
@@ -1293,7 +1293,18 @@ receive_chars(struct uart_8250_port *up, unsigned int *status)
1293 char flag; 1293 char flag;
1294 1294
1295 do { 1295 do {
1296 ch = serial_inp(up, UART_RX); 1296 if (likely(lsr & UART_LSR_DR))
1297 ch = serial_inp(up, UART_RX);
1298 else
1299 /*
1300 * Intel 82571 has a Serial Over Lan device that will
1301 * set UART_LSR_BI without setting UART_LSR_DR when
1302 * it receives a break. To avoid reading from the
1303 * receive buffer without UART_LSR_DR bit set, we
1304 * just force the read character to be 0
1305 */
1306 ch = 0;
1307
1297 flag = TTY_NORMAL; 1308 flag = TTY_NORMAL;
1298 up->port.icount.rx++; 1309 up->port.icount.rx++;
1299 1310
@@ -1342,7 +1353,7 @@ receive_chars(struct uart_8250_port *up, unsigned int *status)
1342 1353
1343ignore_char: 1354ignore_char:
1344 lsr = serial_inp(up, UART_LSR); 1355 lsr = serial_inp(up, UART_LSR);
1345 } while ((lsr & UART_LSR_DR) && (max_count-- > 0)); 1356 } while ((lsr & (UART_LSR_DR | UART_LSR_BI)) && (max_count-- > 0));
1346 spin_unlock(&up->port.lock); 1357 spin_unlock(&up->port.lock);
1347 tty_flip_buffer_push(tty); 1358 tty_flip_buffer_push(tty);
1348 spin_lock(&up->port.lock); 1359 spin_lock(&up->port.lock);
@@ -1425,7 +1436,7 @@ serial8250_handle_port(struct uart_8250_port *up)
1425 1436
1426 DEBUG_INTR("status = %x...", status); 1437 DEBUG_INTR("status = %x...", status);
1427 1438
1428 if (status & UART_LSR_DR) 1439 if (status & (UART_LSR_DR | UART_LSR_BI))
1429 receive_chars(up, &status); 1440 receive_chars(up, &status);
1430 check_modem_status(up); 1441 check_modem_status(up);
1431 if (status & UART_LSR_THRE) 1442 if (status & UART_LSR_THRE)
diff --git a/drivers/serial/8250_gsc.c b/drivers/serial/8250_gsc.c
index 4eb7437a404a..0416ad3bc127 100644
--- a/drivers/serial/8250_gsc.c
+++ b/drivers/serial/8250_gsc.c
@@ -119,3 +119,5 @@ int __init probe_serial_gsc(void)
119} 119}
120 120
121module_init(probe_serial_gsc); 121module_init(probe_serial_gsc);
122
123MODULE_LICENSE("GPL");
diff --git a/drivers/serial/8250_pci.c b/drivers/serial/8250_pci.c
index 1b36087665a2..c2f23933155b 100644
--- a/drivers/serial/8250_pci.c
+++ b/drivers/serial/8250_pci.c
@@ -767,6 +767,9 @@ pci_default_setup(struct serial_private *priv, struct pciserial_board *board,
767#define PCI_SUBDEVICE_ID_POCTAL232 0x0308 767#define PCI_SUBDEVICE_ID_POCTAL232 0x0308
768#define PCI_SUBDEVICE_ID_POCTAL422 0x0408 768#define PCI_SUBDEVICE_ID_POCTAL422 0x0408
769 769
770/* Unknown vendors/cards - this should not be in linux/pci_ids.h */
771#define PCI_SUBDEVICE_ID_UNKNOWN_0x1584 0x1584
772
770/* 773/*
771 * Master list of serial port init/setup/exit quirks. 774 * Master list of serial port init/setup/exit quirks.
772 * This does not describe the general nature of the port. 775 * This does not describe the general nature of the port.
@@ -882,6 +885,15 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = {
882 }, 885 },
883 { 886 {
884 .vendor = PCI_VENDOR_ID_PLX, 887 .vendor = PCI_VENDOR_ID_PLX,
888 .device = PCI_DEVICE_ID_PLX_9050,
889 .subvendor = PCI_VENDOR_ID_PLX,
890 .subdevice = PCI_SUBDEVICE_ID_UNKNOWN_0x1584,
891 .init = pci_plx9050_init,
892 .setup = pci_default_setup,
893 .exit = __devexit_p(pci_plx9050_exit),
894 },
895 {
896 .vendor = PCI_VENDOR_ID_PLX,
885 .device = PCI_DEVICE_ID_PLX_ROMULUS, 897 .device = PCI_DEVICE_ID_PLX_ROMULUS,
886 .subvendor = PCI_VENDOR_ID_PLX, 898 .subvendor = PCI_VENDOR_ID_PLX,
887 .subdevice = PCI_DEVICE_ID_PLX_ROMULUS, 899 .subdevice = PCI_DEVICE_ID_PLX_ROMULUS,
@@ -2197,6 +2209,11 @@ static struct pci_device_id serial_pci_tbl[] = {
2197 { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_1077, 2209 { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_1077,
2198 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 2210 PCI_ANY_ID, PCI_ANY_ID, 0, 0,
2199 pbn_b2_4_921600 }, 2211 pbn_b2_4_921600 },
2212 /* Unknown card - subdevice 0x1584 */
2213 { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050,
2214 PCI_VENDOR_ID_PLX,
2215 PCI_SUBDEVICE_ID_UNKNOWN_0x1584, 0, 0,
2216 pbn_b0_4_115200 },
2200 { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050, 2217 { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050,
2201 PCI_SUBVENDOR_ID_KEYSPAN, 2218 PCI_SUBVENDOR_ID_KEYSPAN,
2202 PCI_SUBDEVICE_ID_KEYSPAN_SX2, 0, 0, 2219 PCI_SUBDEVICE_ID_KEYSPAN_SX2, 0, 0,
diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig
index 8fc7451c0049..3b4a14e355c1 100644
--- a/drivers/serial/Kconfig
+++ b/drivers/serial/Kconfig
@@ -942,22 +942,6 @@ config SERIAL_IP22_ZILOG_CONSOLE
942 depends on SERIAL_IP22_ZILOG=y 942 depends on SERIAL_IP22_ZILOG=y
943 select SERIAL_CORE_CONSOLE 943 select SERIAL_CORE_CONSOLE
944 944
945config V850E_UART
946 bool "NEC V850E on-chip UART support"
947 depends on V850E_MA1 || V850E_ME2 || V850E_TEG || V850E2_ANNA || V850E_AS85EP1
948 select SERIAL_CORE
949 default y
950
951config V850E_UARTB
952 bool
953 depends on V850E_UART && V850E_ME2
954 default y
955
956config V850E_UART_CONSOLE
957 bool "Use NEC V850E on-chip UART for console"
958 depends on V850E_UART
959 select SERIAL_CORE_CONSOLE
960
961config SERIAL_SH_SCI 945config SERIAL_SH_SCI
962 tristate "SuperH SCI(F) serial port support" 946 tristate "SuperH SCI(F) serial port support"
963 depends on SUPERH || H8300 947 depends on SUPERH || H8300
diff --git a/drivers/serial/cpm_uart/cpm_uart_core.c b/drivers/serial/cpm_uart/cpm_uart_core.c
index 1ff80de177db..a4f86927a74b 100644
--- a/drivers/serial/cpm_uart/cpm_uart_core.c
+++ b/drivers/serial/cpm_uart/cpm_uart_core.c
@@ -435,10 +435,13 @@ static void cpm_uart_shutdown(struct uart_port *port)
435 } 435 }
436 436
437 /* Shut them really down and reinit buffer descriptors */ 437 /* Shut them really down and reinit buffer descriptors */
438 if (IS_SMC(pinfo)) 438 if (IS_SMC(pinfo)) {
439 out_be16(&pinfo->smcup->smc_brkcr, 0);
439 cpm_line_cr_cmd(pinfo, CPM_CR_STOP_TX); 440 cpm_line_cr_cmd(pinfo, CPM_CR_STOP_TX);
440 else 441 } else {
442 out_be16(&pinfo->sccup->scc_brkcr, 0);
441 cpm_line_cr_cmd(pinfo, CPM_CR_GRA_STOP_TX); 443 cpm_line_cr_cmd(pinfo, CPM_CR_GRA_STOP_TX);
444 }
442 445
443 cpm_uart_initbd(pinfo); 446 cpm_uart_initbd(pinfo);
444 } 447 }
@@ -554,9 +557,11 @@ static void cpm_uart_set_termios(struct uart_port *port,
554 * enables, because we want to put them back if they were 557 * enables, because we want to put them back if they were
555 * present. 558 * present.
556 */ 559 */
557 prev_mode = in_be16(&smcp->smc_smcmr); 560 prev_mode = in_be16(&smcp->smc_smcmr) & (SMCMR_REN | SMCMR_TEN);
558 out_be16(&smcp->smc_smcmr, smcr_mk_clen(bits) | cval | SMCMR_SM_UART); 561 /* Output in *one* operation, so we don't interrupt RX/TX if they
559 setbits16(&smcp->smc_smcmr, (prev_mode & (SMCMR_REN | SMCMR_TEN))); 562 * were already enabled. */
563 out_be16(&smcp->smc_smcmr, smcr_mk_clen(bits) | cval |
564 SMCMR_SM_UART | prev_mode);
560 } else { 565 } else {
561 out_be16(&sccp->scc_psmr, (sbits << 12) | scval); 566 out_be16(&sccp->scc_psmr, (sbits << 12) | scval);
562 } 567 }
@@ -1198,12 +1203,14 @@ static int __init cpm_uart_console_setup(struct console *co, char *options)
1198 udbg_putc = NULL; 1203 udbg_putc = NULL;
1199#endif 1204#endif
1200 1205
1201 cpm_line_cr_cmd(pinfo, CPM_CR_STOP_TX);
1202
1203 if (IS_SMC(pinfo)) { 1206 if (IS_SMC(pinfo)) {
1207 out_be16(&pinfo->smcup->smc_brkcr, 0);
1208 cpm_line_cr_cmd(pinfo, CPM_CR_STOP_TX);
1204 clrbits8(&pinfo->smcp->smc_smcm, SMCM_RX | SMCM_TX); 1209 clrbits8(&pinfo->smcp->smc_smcm, SMCM_RX | SMCM_TX);
1205 clrbits16(&pinfo->smcp->smc_smcmr, SMCMR_REN | SMCMR_TEN); 1210 clrbits16(&pinfo->smcp->smc_smcmr, SMCMR_REN | SMCMR_TEN);
1206 } else { 1211 } else {
1212 out_be16(&pinfo->sccup->scc_brkcr, 0);
1213 cpm_line_cr_cmd(pinfo, CPM_CR_GRA_STOP_TX);
1207 clrbits16(&pinfo->sccp->scc_sccm, UART_SCCM_TX | UART_SCCM_RX); 1214 clrbits16(&pinfo->sccp->scc_sccm, UART_SCCM_TX | UART_SCCM_RX);
1208 clrbits32(&pinfo->sccp->scc_gsmrl, SCC_GSMRL_ENR | SCC_GSMRL_ENT); 1215 clrbits32(&pinfo->sccp->scc_gsmrl, SCC_GSMRL_ENR | SCC_GSMRL_ENT);
1209 } 1216 }
diff --git a/drivers/serial/dz.c b/drivers/serial/dz.c
index a81d2c2ff8a2..6042b87797a1 100644
--- a/drivers/serial/dz.c
+++ b/drivers/serial/dz.c
@@ -642,6 +642,26 @@ static void dz_set_termios(struct uart_port *uport, struct ktermios *termios,
642 spin_unlock_irqrestore(&dport->port.lock, flags); 642 spin_unlock_irqrestore(&dport->port.lock, flags);
643} 643}
644 644
645/*
646 * Hack alert!
647 * Required solely so that the initial PROM-based console
648 * works undisturbed in parallel with this one.
649 */
650static void dz_pm(struct uart_port *uport, unsigned int state,
651 unsigned int oldstate)
652{
653 struct dz_port *dport = to_dport(uport);
654 unsigned long flags;
655
656 spin_lock_irqsave(&dport->port.lock, flags);
657 if (state < 3)
658 dz_start_tx(&dport->port);
659 else
660 dz_stop_tx(&dport->port);
661 spin_unlock_irqrestore(&dport->port.lock, flags);
662}
663
664
645static const char *dz_type(struct uart_port *uport) 665static const char *dz_type(struct uart_port *uport)
646{ 666{
647 return "DZ"; 667 return "DZ";
@@ -738,6 +758,7 @@ static struct uart_ops dz_ops = {
738 .startup = dz_startup, 758 .startup = dz_startup,
739 .shutdown = dz_shutdown, 759 .shutdown = dz_shutdown,
740 .set_termios = dz_set_termios, 760 .set_termios = dz_set_termios,
761 .pm = dz_pm,
741 .type = dz_type, 762 .type = dz_type,
742 .release_port = dz_release_port, 763 .release_port = dz_release_port,
743 .request_port = dz_request_port, 764 .request_port = dz_request_port,
@@ -861,7 +882,10 @@ static int __init dz_console_setup(struct console *co, char *options)
861 if (ret) 882 if (ret)
862 return ret; 883 return ret;
863 884
885 spin_lock_init(&dport->port.lock); /* For dz_pm(). */
886
864 dz_reset(dport); 887 dz_reset(dport);
888 dz_pm(uport, 0, -1);
865 889
866 if (options) 890 if (options)
867 uart_parse_options(options, &baud, &parity, &bits, &flow); 891 uart_parse_options(options, &baud, &parity, &bits, &flow);
diff --git a/drivers/serial/zs.c b/drivers/serial/zs.c
index bd45b6230fd8..9e6a873f8203 100644
--- a/drivers/serial/zs.c
+++ b/drivers/serial/zs.c
@@ -787,7 +787,6 @@ static int zs_startup(struct uart_port *uport)
787 zport->regs[1] &= ~RxINT_MASK; 787 zport->regs[1] &= ~RxINT_MASK;
788 zport->regs[1] |= RxINT_ALL | TxINT_ENAB | EXT_INT_ENAB; 788 zport->regs[1] |= RxINT_ALL | TxINT_ENAB | EXT_INT_ENAB;
789 zport->regs[3] |= RxENABLE; 789 zport->regs[3] |= RxENABLE;
790 zport->regs[5] |= TxENAB;
791 zport->regs[15] |= BRKIE; 790 zport->regs[15] |= BRKIE;
792 write_zsreg(zport, R1, zport->regs[1]); 791 write_zsreg(zport, R1, zport->regs[1]);
793 write_zsreg(zport, R3, zport->regs[3]); 792 write_zsreg(zport, R3, zport->regs[3]);
@@ -814,7 +813,6 @@ static void zs_shutdown(struct uart_port *uport)
814 813
815 spin_lock_irqsave(&scc->zlock, flags); 814 spin_lock_irqsave(&scc->zlock, flags);
816 815
817 zport->regs[5] &= ~TxENAB;
818 zport->regs[3] &= ~RxENABLE; 816 zport->regs[3] &= ~RxENABLE;
819 write_zsreg(zport, R5, zport->regs[5]); 817 write_zsreg(zport, R5, zport->regs[5]);
820 write_zsreg(zport, R3, zport->regs[3]); 818 write_zsreg(zport, R3, zport->regs[3]);
@@ -959,6 +957,23 @@ static void zs_set_termios(struct uart_port *uport, struct ktermios *termios,
959 spin_unlock_irqrestore(&scc->zlock, flags); 957 spin_unlock_irqrestore(&scc->zlock, flags);
960} 958}
961 959
960/*
961 * Hack alert!
962 * Required solely so that the initial PROM-based console
963 * works undisturbed in parallel with this one.
964 */
965static void zs_pm(struct uart_port *uport, unsigned int state,
966 unsigned int oldstate)
967{
968 struct zs_port *zport = to_zport(uport);
969
970 if (state < 3)
971 zport->regs[5] |= TxENAB;
972 else
973 zport->regs[5] &= ~TxENAB;
974 write_zsreg(zport, R5, zport->regs[5]);
975}
976
962 977
963static const char *zs_type(struct uart_port *uport) 978static const char *zs_type(struct uart_port *uport)
964{ 979{
@@ -1041,6 +1056,7 @@ static struct uart_ops zs_ops = {
1041 .startup = zs_startup, 1056 .startup = zs_startup,
1042 .shutdown = zs_shutdown, 1057 .shutdown = zs_shutdown,
1043 .set_termios = zs_set_termios, 1058 .set_termios = zs_set_termios,
1059 .pm = zs_pm,
1044 .type = zs_type, 1060 .type = zs_type,
1045 .release_port = zs_release_port, 1061 .release_port = zs_release_port,
1046 .request_port = zs_request_port, 1062 .request_port = zs_request_port,
@@ -1190,6 +1206,7 @@ static int __init zs_console_setup(struct console *co, char *options)
1190 return ret; 1206 return ret;
1191 1207
1192 zs_reset(zport); 1208 zs_reset(zport);
1209 zs_pm(uport, 0, -1);
1193 1210
1194 if (options) 1211 if (options)
1195 uart_parse_options(options, &baud, &parity, &bits, &flow); 1212 uart_parse_options(options, &baud, &parity, &bits, &flow);
diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
index 66ec5d8808de..2303521b4f09 100644
--- a/drivers/spi/Kconfig
+++ b/drivers/spi/Kconfig
@@ -49,25 +49,26 @@ config SPI_MASTER
49 controller and the protocol drivers for the SPI slave chips 49 controller and the protocol drivers for the SPI slave chips
50 that are connected. 50 that are connected.
51 51
52if SPI_MASTER
53
52comment "SPI Master Controller Drivers" 54comment "SPI Master Controller Drivers"
53 depends on SPI_MASTER
54 55
55config SPI_ATMEL 56config SPI_ATMEL
56 tristate "Atmel SPI Controller" 57 tristate "Atmel SPI Controller"
57 depends on (ARCH_AT91 || AVR32) && SPI_MASTER 58 depends on (ARCH_AT91 || AVR32)
58 help 59 help
59 This selects a driver for the Atmel SPI Controller, present on 60 This selects a driver for the Atmel SPI Controller, present on
60 many AT32 (AVR32) and AT91 (ARM) chips. 61 many AT32 (AVR32) and AT91 (ARM) chips.
61 62
62config SPI_BFIN 63config SPI_BFIN
63 tristate "SPI controller driver for ADI Blackfin5xx" 64 tristate "SPI controller driver for ADI Blackfin5xx"
64 depends on SPI_MASTER && BLACKFIN 65 depends on BLACKFIN
65 help 66 help
66 This is the SPI controller master driver for Blackfin 5xx processor. 67 This is the SPI controller master driver for Blackfin 5xx processor.
67 68
68config SPI_AU1550 69config SPI_AU1550
69 tristate "Au1550/Au12x0 SPI Controller" 70 tristate "Au1550/Au12x0 SPI Controller"
70 depends on SPI_MASTER && (SOC_AU1550 || SOC_AU1200) && EXPERIMENTAL 71 depends on (SOC_AU1550 || SOC_AU1200) && EXPERIMENTAL
71 select SPI_BITBANG 72 select SPI_BITBANG
72 help 73 help
73 If you say yes to this option, support will be included for the 74 If you say yes to this option, support will be included for the
@@ -78,7 +79,6 @@ config SPI_AU1550
78 79
79config SPI_BITBANG 80config SPI_BITBANG
80 tristate "Bitbanging SPI master" 81 tristate "Bitbanging SPI master"
81 depends on SPI_MASTER && EXPERIMENTAL
82 help 82 help
83 With a few GPIO pins, your system can bitbang the SPI protocol. 83 With a few GPIO pins, your system can bitbang the SPI protocol.
84 Select this to get SPI support through I/O pins (GPIO, parallel 84 Select this to get SPI support through I/O pins (GPIO, parallel
@@ -92,7 +92,7 @@ config SPI_BITBANG
92 92
93config SPI_BUTTERFLY 93config SPI_BUTTERFLY
94 tristate "Parallel port adapter for AVR Butterfly (DEVELOPMENT)" 94 tristate "Parallel port adapter for AVR Butterfly (DEVELOPMENT)"
95 depends on SPI_MASTER && PARPORT && EXPERIMENTAL 95 depends on PARPORT
96 select SPI_BITBANG 96 select SPI_BITBANG
97 help 97 help
98 This uses a custom parallel port cable to connect to an AVR 98 This uses a custom parallel port cable to connect to an AVR
@@ -102,14 +102,14 @@ config SPI_BUTTERFLY
102 102
103config SPI_IMX 103config SPI_IMX
104 tristate "Freescale iMX SPI controller" 104 tristate "Freescale iMX SPI controller"
105 depends on SPI_MASTER && ARCH_IMX && EXPERIMENTAL 105 depends on ARCH_IMX && EXPERIMENTAL
106 help 106 help
107 This enables using the Freescale iMX SPI controller in master 107 This enables using the Freescale iMX SPI controller in master
108 mode. 108 mode.
109 109
110config SPI_LM70_LLP 110config SPI_LM70_LLP
111 tristate "Parallel port adapter for LM70 eval board (DEVELOPMENT)" 111 tristate "Parallel port adapter for LM70 eval board (DEVELOPMENT)"
112 depends on SPI_MASTER && PARPORT && EXPERIMENTAL 112 depends on PARPORT && EXPERIMENTAL
113 select SPI_BITBANG 113 select SPI_BITBANG
114 help 114 help
115 This driver supports the NS LM70 LLP Evaluation Board, 115 This driver supports the NS LM70 LLP Evaluation Board,
@@ -118,14 +118,14 @@ config SPI_LM70_LLP
118 118
119config SPI_MPC52xx_PSC 119config SPI_MPC52xx_PSC
120 tristate "Freescale MPC52xx PSC SPI controller" 120 tristate "Freescale MPC52xx PSC SPI controller"
121 depends on SPI_MASTER && PPC_MPC52xx && EXPERIMENTAL 121 depends on PPC_MPC52xx && EXPERIMENTAL
122 help 122 help
123 This enables using the Freescale MPC52xx Programmable Serial 123 This enables using the Freescale MPC52xx Programmable Serial
124 Controller in master SPI mode. 124 Controller in master SPI mode.
125 125
126config SPI_MPC83xx 126config SPI_MPC83xx
127 tristate "Freescale MPC83xx/QUICC Engine SPI controller" 127 tristate "Freescale MPC83xx/QUICC Engine SPI controller"
128 depends on SPI_MASTER && (PPC_83xx || QUICC_ENGINE) && EXPERIMENTAL 128 depends on (PPC_83xx || QUICC_ENGINE) && EXPERIMENTAL
129 help 129 help
130 This enables using the Freescale MPC83xx and QUICC Engine SPI 130 This enables using the Freescale MPC83xx and QUICC Engine SPI
131 controllers in master mode. 131 controllers in master mode.
@@ -137,21 +137,21 @@ config SPI_MPC83xx
137 137
138config SPI_OMAP_UWIRE 138config SPI_OMAP_UWIRE
139 tristate "OMAP1 MicroWire" 139 tristate "OMAP1 MicroWire"
140 depends on SPI_MASTER && ARCH_OMAP1 140 depends on ARCH_OMAP1
141 select SPI_BITBANG 141 select SPI_BITBANG
142 help 142 help
143 This hooks up to the MicroWire controller on OMAP1 chips. 143 This hooks up to the MicroWire controller on OMAP1 chips.
144 144
145config SPI_OMAP24XX 145config SPI_OMAP24XX
146 tristate "McSPI driver for OMAP24xx/OMAP34xx" 146 tristate "McSPI driver for OMAP24xx/OMAP34xx"
147 depends on SPI_MASTER && (ARCH_OMAP24XX || ARCH_OMAP34XX) 147 depends on ARCH_OMAP24XX || ARCH_OMAP34XX
148 help 148 help
149 SPI master controller for OMAP24xx/OMAP34xx Multichannel SPI 149 SPI master controller for OMAP24xx/OMAP34xx Multichannel SPI
150 (McSPI) modules. 150 (McSPI) modules.
151 151
152config SPI_PXA2XX 152config SPI_PXA2XX
153 tristate "PXA2xx SSP SPI master" 153 tristate "PXA2xx SSP SPI master"
154 depends on SPI_MASTER && ARCH_PXA && EXPERIMENTAL 154 depends on ARCH_PXA && EXPERIMENTAL
155 select PXA_SSP 155 select PXA_SSP
156 help 156 help
157 This enables using a PXA2xx SSP port as a SPI master controller. 157 This enables using a PXA2xx SSP port as a SPI master controller.
@@ -160,14 +160,14 @@ config SPI_PXA2XX
160 160
161config SPI_S3C24XX 161config SPI_S3C24XX
162 tristate "Samsung S3C24XX series SPI" 162 tristate "Samsung S3C24XX series SPI"
163 depends on SPI_MASTER && ARCH_S3C2410 && EXPERIMENTAL 163 depends on ARCH_S3C2410 && EXPERIMENTAL
164 select SPI_BITBANG 164 select SPI_BITBANG
165 help 165 help
166 SPI driver for Samsung S3C24XX series ARM SoCs 166 SPI driver for Samsung S3C24XX series ARM SoCs
167 167
168config SPI_S3C24XX_GPIO 168config SPI_S3C24XX_GPIO
169 tristate "Samsung S3C24XX series SPI by GPIO" 169 tristate "Samsung S3C24XX series SPI by GPIO"
170 depends on SPI_MASTER && ARCH_S3C2410 && EXPERIMENTAL 170 depends on ARCH_S3C2410 && EXPERIMENTAL
171 select SPI_BITBANG 171 select SPI_BITBANG
172 help 172 help
173 SPI driver for Samsung S3C24XX series ARM SoCs using 173 SPI driver for Samsung S3C24XX series ARM SoCs using
@@ -177,20 +177,20 @@ config SPI_S3C24XX_GPIO
177 177
178config SPI_SH_SCI 178config SPI_SH_SCI
179 tristate "SuperH SCI SPI controller" 179 tristate "SuperH SCI SPI controller"
180 depends on SPI_MASTER && SUPERH 180 depends on SUPERH
181 select SPI_BITBANG 181 select SPI_BITBANG
182 help 182 help
183 SPI driver for SuperH SCI blocks. 183 SPI driver for SuperH SCI blocks.
184 184
185config SPI_TXX9 185config SPI_TXX9
186 tristate "Toshiba TXx9 SPI controller" 186 tristate "Toshiba TXx9 SPI controller"
187 depends on SPI_MASTER && GENERIC_GPIO && CPU_TX49XX 187 depends on GENERIC_GPIO && CPU_TX49XX
188 help 188 help
189 SPI driver for Toshiba TXx9 MIPS SoCs 189 SPI driver for Toshiba TXx9 MIPS SoCs
190 190
191config SPI_XILINX 191config SPI_XILINX
192 tristate "Xilinx SPI controller" 192 tristate "Xilinx SPI controller"
193 depends on SPI_MASTER && XILINX_VIRTEX && EXPERIMENTAL 193 depends on XILINX_VIRTEX && EXPERIMENTAL
194 select SPI_BITBANG 194 select SPI_BITBANG
195 help 195 help
196 This exposes the SPI controller IP from the Xilinx EDK. 196 This exposes the SPI controller IP from the Xilinx EDK.
@@ -207,11 +207,10 @@ config SPI_XILINX
207# being probably the most widely used ones. 207# being probably the most widely used ones.
208# 208#
209comment "SPI Protocol Masters" 209comment "SPI Protocol Masters"
210 depends on SPI_MASTER
211 210
212config SPI_AT25 211config SPI_AT25
213 tristate "SPI EEPROMs from most vendors" 212 tristate "SPI EEPROMs from most vendors"
214 depends on SPI_MASTER && SYSFS 213 depends on SYSFS
215 help 214 help
216 Enable this driver to get read/write support to most SPI EEPROMs, 215 Enable this driver to get read/write support to most SPI EEPROMs,
217 after you configure the board init code to know about each eeprom 216 after you configure the board init code to know about each eeprom
@@ -222,7 +221,7 @@ config SPI_AT25
222 221
223config SPI_SPIDEV 222config SPI_SPIDEV
224 tristate "User mode SPI device driver support" 223 tristate "User mode SPI device driver support"
225 depends on SPI_MASTER && EXPERIMENTAL 224 depends on EXPERIMENTAL
226 help 225 help
227 This supports user mode SPI protocol drivers. 226 This supports user mode SPI protocol drivers.
228 227
@@ -231,7 +230,7 @@ config SPI_SPIDEV
231 230
232config SPI_TLE62X0 231config SPI_TLE62X0
233 tristate "Infineon TLE62X0 (for power switching)" 232 tristate "Infineon TLE62X0 (for power switching)"
234 depends on SPI_MASTER && SYSFS 233 depends on SYSFS
235 help 234 help
236 SPI driver for Infineon TLE62X0 series line driver chips, 235 SPI driver for Infineon TLE62X0 series line driver chips,
237 such as the TLE6220, TLE6230 and TLE6240. This provides a 236 such as the TLE6220, TLE6230 and TLE6240. This provides a
@@ -242,6 +241,8 @@ config SPI_TLE62X0
242# Add new SPI protocol masters in alphabetical order above this line 241# Add new SPI protocol masters in alphabetical order above this line
243# 242#
244 243
244endif # SPI_MASTER
245
245# (slave support would go here) 246# (slave support would go here)
246 247
247endif # SPI 248endif # SPI
diff --git a/drivers/spi/au1550_spi.c b/drivers/spi/au1550_spi.c
index 072c4a595334..9149689c79d9 100644
--- a/drivers/spi/au1550_spi.c
+++ b/drivers/spi/au1550_spi.c
@@ -26,6 +26,7 @@
26#include <linux/errno.h> 26#include <linux/errno.h>
27#include <linux/device.h> 27#include <linux/device.h>
28#include <linux/platform_device.h> 28#include <linux/platform_device.h>
29#include <linux/resource.h>
29#include <linux/spi/spi.h> 30#include <linux/spi/spi.h>
30#include <linux/spi/spi_bitbang.h> 31#include <linux/spi/spi_bitbang.h>
31#include <linux/dma-mapping.h> 32#include <linux/dma-mapping.h>
@@ -81,6 +82,7 @@ struct au1550_spi {
81 struct spi_master *master; 82 struct spi_master *master;
82 struct device *dev; 83 struct device *dev;
83 struct au1550_spi_info *pdata; 84 struct au1550_spi_info *pdata;
85 struct resource *ioarea;
84}; 86};
85 87
86 88
@@ -96,6 +98,8 @@ static dbdev_tab_t au1550_spi_mem_dbdev =
96 .dev_intpolarity = 0 98 .dev_intpolarity = 0
97}; 99};
98 100
101static int ddma_memid; /* id to above mem dma device */
102
99static void au1550_spi_bits_handlers_set(struct au1550_spi *hw, int bpw); 103static void au1550_spi_bits_handlers_set(struct au1550_spi *hw, int bpw);
100 104
101 105
@@ -480,9 +484,13 @@ static irqreturn_t au1550_spi_dma_irq_callback(struct au1550_spi *hw)
480 au1xxx_dbdma_reset(hw->dma_tx_ch); 484 au1xxx_dbdma_reset(hw->dma_tx_ch);
481 au1550_spi_reset_fifos(hw); 485 au1550_spi_reset_fifos(hw);
482 486
483 dev_err(hw->dev, 487 if (evnt == PSC_SPIEVNT_RO)
484 "Unexpected SPI error: event=0x%x stat=0x%x!\n", 488 dev_err(hw->dev,
485 evnt, stat); 489 "dma transfer: receive FIFO overflow!\n");
490 else
491 dev_err(hw->dev,
492 "dma transfer: unexpected SPI error "
493 "(event=0x%x stat=0x%x)!\n", evnt, stat);
486 494
487 complete(&hw->master_done); 495 complete(&hw->master_done);
488 return IRQ_HANDLED; 496 return IRQ_HANDLED;
@@ -592,17 +600,17 @@ static irqreturn_t au1550_spi_pio_irq_callback(struct au1550_spi *hw)
592 600
593 if ((evnt & (PSC_SPIEVNT_MM | PSC_SPIEVNT_RO 601 if ((evnt & (PSC_SPIEVNT_MM | PSC_SPIEVNT_RO
594 | PSC_SPIEVNT_RU | PSC_SPIEVNT_TO 602 | PSC_SPIEVNT_RU | PSC_SPIEVNT_TO
595 | PSC_SPIEVNT_TU | PSC_SPIEVNT_SD)) 603 | PSC_SPIEVNT_SD))
596 != 0) { 604 != 0) {
597 dev_err(hw->dev,
598 "Unexpected SPI error: event=0x%x stat=0x%x!\n",
599 evnt, stat);
600 /* 605 /*
601 * due to an error we consider transfer as done, 606 * due to an error we consider transfer as done,
602 * so mask all events until before next transfer start 607 * so mask all events until before next transfer start
603 */ 608 */
604 au1550_spi_mask_ack_all(hw); 609 au1550_spi_mask_ack_all(hw);
605 au1550_spi_reset_fifos(hw); 610 au1550_spi_reset_fifos(hw);
611 dev_err(hw->dev,
612 "pio transfer: unexpected SPI error "
613 "(event=0x%x stat=0x%x)!\n", evnt, stat);
606 complete(&hw->master_done); 614 complete(&hw->master_done);
607 return IRQ_HANDLED; 615 return IRQ_HANDLED;
608 } 616 }
@@ -616,27 +624,50 @@ static irqreturn_t au1550_spi_pio_irq_callback(struct au1550_spi *hw)
616 stat = hw->regs->psc_spistat; 624 stat = hw->regs->psc_spistat;
617 au_sync(); 625 au_sync();
618 626
619 if ((stat & PSC_SPISTAT_RE) == 0 && hw->rx_count < hw->len) { 627 /*
628 * Take care to not let the Rx FIFO overflow.
629 *
630 * We only write a byte if we have read one at least. Initially,
631 * the write fifo is full, so we should read from the read fifo
632 * first.
633 * In case we miss a word from the read fifo, we should get a
634 * RO event and should back out.
635 */
636 if (!(stat & PSC_SPISTAT_RE) && hw->rx_count < hw->len) {
620 hw->rx_word(hw); 637 hw->rx_word(hw);
621 /* ack the receive request event */
622 hw->regs->psc_spievent = PSC_SPIEVNT_RR;
623 au_sync();
624 busy = 1; 638 busy = 1;
625 }
626 639
627 if ((stat & PSC_SPISTAT_TF) == 0 && hw->tx_count < hw->len) { 640 if (!(stat & PSC_SPISTAT_TF) && hw->tx_count < hw->len)
628 hw->tx_word(hw); 641 hw->tx_word(hw);
629 /* ack the transmit request event */
630 hw->regs->psc_spievent = PSC_SPIEVNT_TR;
631 au_sync();
632 busy = 1;
633 } 642 }
634 } while (busy); 643 } while (busy);
635 644
636 evnt = hw->regs->psc_spievent; 645 hw->regs->psc_spievent = PSC_SPIEVNT_RR | PSC_SPIEVNT_TR;
637 au_sync(); 646 au_sync();
638 647
639 if (hw->rx_count >= hw->len || (evnt & PSC_SPIEVNT_MD) != 0) { 648 /*
649 * Restart the SPI transmission in case of a transmit underflow.
650 * This seems to work despite the notes in the Au1550 data book
651 * of Figure 8-4 with flowchart for SPI master operation:
652 *
653 * """Note 1: An XFR Error Interrupt occurs, unless masked,
654 * for any of the following events: Tx FIFO Underflow,
655 * Rx FIFO Overflow, or Multiple-master Error
656 * Note 2: In case of a Tx Underflow Error, all zeroes are
657 * transmitted."""
658 *
659 * By simply restarting the spi transfer on Tx Underflow Error,
660 * we assume that spi transfer was paused instead of zeroes
661 * transmittion mentioned in the Note 2 of Au1550 data book.
662 */
663 if (evnt & PSC_SPIEVNT_TU) {
664 hw->regs->psc_spievent = PSC_SPIEVNT_TU | PSC_SPIEVNT_MD;
665 au_sync();
666 hw->regs->psc_spipcr = PSC_SPIPCR_MS;
667 au_sync();
668 }
669
670 if (hw->rx_count >= hw->len) {
640 /* transfer completed successfully */ 671 /* transfer completed successfully */
641 au1550_spi_mask_ack_all(hw); 672 au1550_spi_mask_ack_all(hw);
642 complete(&hw->master_done); 673 complete(&hw->master_done);
@@ -725,6 +756,8 @@ static void __init au1550_spi_setup_psc_as_spi(struct au1550_spi *hw)
725 stat = hw->regs->psc_spistat; 756 stat = hw->regs->psc_spistat;
726 au_sync(); 757 au_sync();
727 } while ((stat & PSC_SPISTAT_DR) == 0); 758 } while ((stat & PSC_SPISTAT_DR) == 0);
759
760 au1550_spi_reset_fifos(hw);
728} 761}
729 762
730 763
@@ -732,6 +765,7 @@ static int __init au1550_spi_probe(struct platform_device *pdev)
732{ 765{
733 struct au1550_spi *hw; 766 struct au1550_spi *hw;
734 struct spi_master *master; 767 struct spi_master *master;
768 struct resource *r;
735 int err = 0; 769 int err = 0;
736 770
737 master = spi_alloc_master(&pdev->dev, sizeof(struct au1550_spi)); 771 master = spi_alloc_master(&pdev->dev, sizeof(struct au1550_spi));
@@ -753,76 +787,64 @@ static int __init au1550_spi_probe(struct platform_device *pdev)
753 goto err_no_pdata; 787 goto err_no_pdata;
754 } 788 }
755 789
756 platform_set_drvdata(pdev, hw); 790 r = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
757 791 if (!r) {
758 init_completion(&hw->master_done); 792 dev_err(&pdev->dev, "no IRQ\n");
759 793 err = -ENODEV;
760 hw->bitbang.master = hw->master; 794 goto err_no_iores;
761 hw->bitbang.setup_transfer = au1550_spi_setupxfer; 795 }
762 hw->bitbang.chipselect = au1550_spi_chipsel; 796 hw->irq = r->start;
763 hw->bitbang.master->setup = au1550_spi_setup; 797
764 hw->bitbang.txrx_bufs = au1550_spi_txrx_bufs; 798 hw->usedma = 0;
799 r = platform_get_resource(pdev, IORESOURCE_DMA, 0);
800 if (r) {
801 hw->dma_tx_id = r->start;
802 r = platform_get_resource(pdev, IORESOURCE_DMA, 1);
803 if (r) {
804 hw->dma_rx_id = r->start;
805 if (usedma && ddma_memid) {
806 if (pdev->dev.dma_mask == NULL)
807 dev_warn(&pdev->dev, "no dma mask\n");
808 else
809 hw->usedma = 1;
810 }
811 }
812 }
765 813
766 switch (hw->pdata->bus_num) { 814 r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
767 case 0: 815 if (!r) {
768 hw->irq = AU1550_PSC0_INT; 816 dev_err(&pdev->dev, "no mmio resource\n");
769 hw->regs = (volatile psc_spi_t *)PSC0_BASE_ADDR; 817 err = -ENODEV;
770 hw->dma_rx_id = DSCR_CMD0_PSC0_RX; 818 goto err_no_iores;
771 hw->dma_tx_id = DSCR_CMD0_PSC0_TX;
772 break;
773 case 1:
774 hw->irq = AU1550_PSC1_INT;
775 hw->regs = (volatile psc_spi_t *)PSC1_BASE_ADDR;
776 hw->dma_rx_id = DSCR_CMD0_PSC1_RX;
777 hw->dma_tx_id = DSCR_CMD0_PSC1_TX;
778 break;
779 case 2:
780 hw->irq = AU1550_PSC2_INT;
781 hw->regs = (volatile psc_spi_t *)PSC2_BASE_ADDR;
782 hw->dma_rx_id = DSCR_CMD0_PSC2_RX;
783 hw->dma_tx_id = DSCR_CMD0_PSC2_TX;
784 break;
785 case 3:
786 hw->irq = AU1550_PSC3_INT;
787 hw->regs = (volatile psc_spi_t *)PSC3_BASE_ADDR;
788 hw->dma_rx_id = DSCR_CMD0_PSC3_RX;
789 hw->dma_tx_id = DSCR_CMD0_PSC3_TX;
790 break;
791 default:
792 dev_err(&pdev->dev, "Wrong bus_num of SPI\n");
793 err = -ENOENT;
794 goto err_no_pdata;
795 } 819 }
796 820
797 if (request_mem_region((unsigned long)hw->regs, sizeof(psc_spi_t), 821 hw->ioarea = request_mem_region(r->start, sizeof(psc_spi_t),
798 pdev->name) == NULL) { 822 pdev->name);
823 if (!hw->ioarea) {
799 dev_err(&pdev->dev, "Cannot reserve iomem region\n"); 824 dev_err(&pdev->dev, "Cannot reserve iomem region\n");
800 err = -ENXIO; 825 err = -ENXIO;
801 goto err_no_iores; 826 goto err_no_iores;
802 } 827 }
803 828
804 829 hw->regs = (psc_spi_t __iomem *)ioremap(r->start, sizeof(psc_spi_t));
805 if (usedma) { 830 if (!hw->regs) {
806 if (pdev->dev.dma_mask == NULL) 831 dev_err(&pdev->dev, "cannot ioremap\n");
807 dev_warn(&pdev->dev, "no dma mask\n"); 832 err = -ENXIO;
808 else 833 goto err_ioremap;
809 hw->usedma = 1;
810 } 834 }
811 835
812 if (hw->usedma) { 836 platform_set_drvdata(pdev, hw);
813 /* 837
814 * create memory device with 8 bits dev_devwidth 838 init_completion(&hw->master_done);
815 * needed for proper byte ordering to spi fifo 839
816 */ 840 hw->bitbang.master = hw->master;
817 int memid = au1xxx_ddma_add_device(&au1550_spi_mem_dbdev); 841 hw->bitbang.setup_transfer = au1550_spi_setupxfer;
818 if (!memid) { 842 hw->bitbang.chipselect = au1550_spi_chipsel;
819 dev_err(&pdev->dev, 843 hw->bitbang.master->setup = au1550_spi_setup;
820 "Cannot create dma 8 bit mem device\n"); 844 hw->bitbang.txrx_bufs = au1550_spi_txrx_bufs;
821 err = -ENXIO;
822 goto err_dma_add_dev;
823 }
824 845
825 hw->dma_tx_ch = au1xxx_dbdma_chan_alloc(memid, 846 if (hw->usedma) {
847 hw->dma_tx_ch = au1xxx_dbdma_chan_alloc(ddma_memid,
826 hw->dma_tx_id, NULL, (void *)hw); 848 hw->dma_tx_id, NULL, (void *)hw);
827 if (hw->dma_tx_ch == 0) { 849 if (hw->dma_tx_ch == 0) {
828 dev_err(&pdev->dev, 850 dev_err(&pdev->dev,
@@ -841,7 +863,7 @@ static int __init au1550_spi_probe(struct platform_device *pdev)
841 863
842 864
843 hw->dma_rx_ch = au1xxx_dbdma_chan_alloc(hw->dma_rx_id, 865 hw->dma_rx_ch = au1xxx_dbdma_chan_alloc(hw->dma_rx_id,
844 memid, NULL, (void *)hw); 866 ddma_memid, NULL, (void *)hw);
845 if (hw->dma_rx_ch == 0) { 867 if (hw->dma_rx_ch == 0) {
846 dev_err(&pdev->dev, 868 dev_err(&pdev->dev,
847 "Cannot allocate rx dma channel\n"); 869 "Cannot allocate rx dma channel\n");
@@ -874,7 +896,7 @@ static int __init au1550_spi_probe(struct platform_device *pdev)
874 goto err_no_irq; 896 goto err_no_irq;
875 } 897 }
876 898
877 master->bus_num = hw->pdata->bus_num; 899 master->bus_num = pdev->id;
878 master->num_chipselect = hw->pdata->num_chipselect; 900 master->num_chipselect = hw->pdata->num_chipselect;
879 901
880 /* 902 /*
@@ -924,8 +946,11 @@ err_no_txdma_descr:
924 au1xxx_dbdma_chan_free(hw->dma_tx_ch); 946 au1xxx_dbdma_chan_free(hw->dma_tx_ch);
925 947
926err_no_txdma: 948err_no_txdma:
927err_dma_add_dev: 949 iounmap((void __iomem *)hw->regs);
928 release_mem_region((unsigned long)hw->regs, sizeof(psc_spi_t)); 950
951err_ioremap:
952 release_resource(hw->ioarea);
953 kfree(hw->ioarea);
929 954
930err_no_iores: 955err_no_iores:
931err_no_pdata: 956err_no_pdata:
@@ -944,7 +969,9 @@ static int __exit au1550_spi_remove(struct platform_device *pdev)
944 969
945 spi_bitbang_stop(&hw->bitbang); 970 spi_bitbang_stop(&hw->bitbang);
946 free_irq(hw->irq, hw); 971 free_irq(hw->irq, hw);
947 release_mem_region((unsigned long)hw->regs, sizeof(psc_spi_t)); 972 iounmap((void __iomem *)hw->regs);
973 release_resource(hw->ioarea);
974 kfree(hw->ioarea);
948 975
949 if (hw->usedma) { 976 if (hw->usedma) {
950 au1550_spi_dma_rxtmp_free(hw); 977 au1550_spi_dma_rxtmp_free(hw);
@@ -971,12 +998,24 @@ static struct platform_driver au1550_spi_drv = {
971 998
972static int __init au1550_spi_init(void) 999static int __init au1550_spi_init(void)
973{ 1000{
1001 /*
1002 * create memory device with 8 bits dev_devwidth
1003 * needed for proper byte ordering to spi fifo
1004 */
1005 if (usedma) {
1006 ddma_memid = au1xxx_ddma_add_device(&au1550_spi_mem_dbdev);
1007 if (!ddma_memid)
1008 printk(KERN_ERR "au1550-spi: cannot add memory"
1009 "dbdma device\n");
1010 }
974 return platform_driver_probe(&au1550_spi_drv, au1550_spi_probe); 1011 return platform_driver_probe(&au1550_spi_drv, au1550_spi_probe);
975} 1012}
976module_init(au1550_spi_init); 1013module_init(au1550_spi_init);
977 1014
978static void __exit au1550_spi_exit(void) 1015static void __exit au1550_spi_exit(void)
979{ 1016{
1017 if (usedma && ddma_memid)
1018 au1xxx_ddma_del_device(ddma_memid);
980 platform_driver_unregister(&au1550_spi_drv); 1019 platform_driver_unregister(&au1550_spi_drv);
981} 1020}
982module_exit(au1550_spi_exit); 1021module_exit(au1550_spi_exit);
diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c
index 1771b2456bfa..ecca4a6a6f94 100644
--- a/drivers/spi/spi.c
+++ b/drivers/spi/spi.c
@@ -218,6 +218,8 @@ struct spi_device *spi_new_device(struct spi_master *master,
218 if (!spi_master_get(master)) 218 if (!spi_master_get(master))
219 return NULL; 219 return NULL;
220 220
221 WARN_ON(strlen(chip->modalias) >= sizeof(proxy->modalias));
222
221 proxy = kzalloc(sizeof *proxy, GFP_KERNEL); 223 proxy = kzalloc(sizeof *proxy, GFP_KERNEL);
222 if (!proxy) { 224 if (!proxy) {
223 dev_err(dev, "can't alloc dev for cs%d\n", 225 dev_err(dev, "can't alloc dev for cs%d\n",
@@ -229,7 +231,7 @@ struct spi_device *spi_new_device(struct spi_master *master,
229 proxy->max_speed_hz = chip->max_speed_hz; 231 proxy->max_speed_hz = chip->max_speed_hz;
230 proxy->mode = chip->mode; 232 proxy->mode = chip->mode;
231 proxy->irq = chip->irq; 233 proxy->irq = chip->irq;
232 proxy->modalias = chip->modalias; 234 strlcpy(proxy->modalias, chip->modalias, sizeof(proxy->modalias));
233 235
234 snprintf(proxy->dev.bus_id, sizeof proxy->dev.bus_id, 236 snprintf(proxy->dev.bus_id, sizeof proxy->dev.bus_id,
235 "%s.%u", master->dev.bus_id, 237 "%s.%u", master->dev.bus_id,
diff --git a/drivers/spi/spi_mpc83xx.c b/drivers/spi/spi_mpc83xx.c
index 6832da6f7109..070c6219e2d6 100644
--- a/drivers/spi/spi_mpc83xx.c
+++ b/drivers/spi/spi_mpc83xx.c
@@ -266,21 +266,24 @@ int mpc83xx_spi_setup_transfer(struct spi_device *spi, struct spi_transfer *t)
266 266
267 cs->hw_mode |= SPMODE_LEN(bits_per_word); 267 cs->hw_mode |= SPMODE_LEN(bits_per_word);
268 268
269 if ((mpc83xx_spi->spibrg / hz) >= 64) { 269 if ((mpc83xx_spi->spibrg / hz) > 64) {
270 pm = mpc83xx_spi->spibrg / (hz * 64) - 1; 270 pm = mpc83xx_spi->spibrg / (hz * 64);
271 if (pm > 0x0f) { 271 if (pm > 16) {
272 dev_err(&spi->dev, "Requested speed is too " 272 cs->hw_mode |= SPMODE_DIV16;
273 "low: %d Hz. Will use %d Hz instead.\n", 273 pm /= 16;
274 hz, mpc83xx_spi->spibrg / 1024); 274 if (pm > 16) {
275 pm = 0x0f; 275 dev_err(&spi->dev, "Requested speed is too "
276 "low: %d Hz. Will use %d Hz instead.\n",
277 hz, mpc83xx_spi->spibrg / 1024);
278 pm = 16;
279 }
276 } 280 }
277 cs->hw_mode |= SPMODE_PM(pm) | SPMODE_DIV16; 281 } else
278 } else {
279 pm = mpc83xx_spi->spibrg / (hz * 4); 282 pm = mpc83xx_spi->spibrg / (hz * 4);
280 if (pm) 283 if (pm)
281 pm--; 284 pm--;
282 cs->hw_mode |= SPMODE_PM(pm); 285
283 } 286 cs->hw_mode |= SPMODE_PM(pm);
284 regval = mpc83xx_spi_read_reg(&mpc83xx_spi->base->mode); 287 regval = mpc83xx_spi_read_reg(&mpc83xx_spi->base->mode);
285 if (cs->hw_mode != regval) { 288 if (cs->hw_mode != regval) {
286 unsigned long flags; 289 unsigned long flags;
diff --git a/drivers/spi/spidev.c b/drivers/spi/spidev.c
index 2833fd772a24..e5e0cfed5e3b 100644
--- a/drivers/spi/spidev.c
+++ b/drivers/spi/spidev.c
@@ -228,7 +228,6 @@ static int spidev_message(struct spidev_data *spidev,
228 * We walk the array of user-provided transfers, using each one 228 * We walk the array of user-provided transfers, using each one
229 * to initialize a kernel version of the same transfer. 229 * to initialize a kernel version of the same transfer.
230 */ 230 */
231 mutex_lock(&spidev->buf_lock);
232 buf = spidev->buffer; 231 buf = spidev->buffer;
233 total = 0; 232 total = 0;
234 for (n = n_xfers, k_tmp = k_xfers, u_tmp = u_xfers; 233 for (n = n_xfers, k_tmp = k_xfers, u_tmp = u_xfers;
@@ -296,14 +295,12 @@ static int spidev_message(struct spidev_data *spidev,
296 status = total; 295 status = total;
297 296
298done: 297done:
299 mutex_unlock(&spidev->buf_lock);
300 kfree(k_xfers); 298 kfree(k_xfers);
301 return status; 299 return status;
302} 300}
303 301
304static int 302static long
305spidev_ioctl(struct inode *inode, struct file *filp, 303spidev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
306 unsigned int cmd, unsigned long arg)
307{ 304{
308 int err = 0; 305 int err = 0;
309 int retval = 0; 306 int retval = 0;
@@ -341,6 +338,14 @@ spidev_ioctl(struct inode *inode, struct file *filp,
341 if (spi == NULL) 338 if (spi == NULL)
342 return -ESHUTDOWN; 339 return -ESHUTDOWN;
343 340
341 /* use the buffer lock here for triple duty:
342 * - prevent I/O (from us) so calling spi_setup() is safe;
343 * - prevent concurrent SPI_IOC_WR_* from morphing
344 * data fields while SPI_IOC_RD_* reads them;
345 * - SPI_IOC_MESSAGE needs the buffer locked "normally".
346 */
347 mutex_lock(&spidev->buf_lock);
348
344 switch (cmd) { 349 switch (cmd) {
345 /* read requests */ 350 /* read requests */
346 case SPI_IOC_RD_MODE: 351 case SPI_IOC_RD_MODE:
@@ -456,6 +461,8 @@ spidev_ioctl(struct inode *inode, struct file *filp,
456 kfree(ioc); 461 kfree(ioc);
457 break; 462 break;
458 } 463 }
464
465 mutex_unlock(&spidev->buf_lock);
459 spi_dev_put(spi); 466 spi_dev_put(spi);
460 return retval; 467 return retval;
461} 468}
@@ -533,7 +540,7 @@ static struct file_operations spidev_fops = {
533 */ 540 */
534 .write = spidev_write, 541 .write = spidev_write,
535 .read = spidev_read, 542 .read = spidev_read,
536 .ioctl = spidev_ioctl, 543 .unlocked_ioctl = spidev_ioctl,
537 .open = spidev_open, 544 .open = spidev_open,
538 .release = spidev_release, 545 .release = spidev_release,
539}; 546};
diff --git a/drivers/spi/xilinx_spi.c b/drivers/spi/xilinx_spi.c
index 113a0468ffcb..68d6f4988fb5 100644
--- a/drivers/spi/xilinx_spi.c
+++ b/drivers/spi/xilinx_spi.c
@@ -353,11 +353,12 @@ static int __init xilinx_spi_probe(struct platform_device *dev)
353 goto put_master; 353 goto put_master;
354 } 354 }
355 355
356 xspi->irq = platform_get_irq(dev, 0); 356 ret = platform_get_irq(dev, 0);
357 if (xspi->irq < 0) { 357 if (ret < 0) {
358 ret = -ENXIO; 358 ret = -ENXIO;
359 goto unmap_io; 359 goto unmap_io;
360 } 360 }
361 xspi->irq = ret;
361 362
362 master->bus_num = pdata->bus_num; 363 master->bus_num = pdata->bus_num;
363 master->num_chipselect = pdata->num_chipselect; 364 master->num_chipselect = pdata->num_chipselect;
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index 9b887ef64ff1..70d135e0cc47 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -1658,6 +1658,32 @@ config FB_PM3
1658 similar boards, 3DLabs Permedia3 Create!, Appian Jeronimo 2000 1658 similar boards, 3DLabs Permedia3 Create!, Appian Jeronimo 2000
1659 and maybe other boards. 1659 and maybe other boards.
1660 1660
1661config FB_CARMINE
1662 tristate "Fujitsu carmine frame buffer support"
1663 depends on FB && PCI
1664 select FB_CFB_FILLRECT
1665 select FB_CFB_COPYAREA
1666 select FB_CFB_IMAGEBLIT
1667 help
1668 This is the frame buffer device driver for the Fujitsu Carmine chip.
1669 The driver provides two independent frame buffer devices.
1670
1671choice
1672 depends on FB_CARMINE
1673 prompt "DRAM timing"
1674 default FB_CARMINE_DRAM_EVAL
1675
1676config FB_CARMINE_DRAM_EVAL
1677 bool "Eval board timings"
1678 help
1679 Use timings which work on the eval card.
1680
1681config CARMINE_DRAM_CUSTOM
1682 bool "Custom board timings"
1683 help
1684 Use custom board timings.
1685endchoice
1686
1661config FB_AU1100 1687config FB_AU1100
1662 bool "Au1100 LCD Driver" 1688 bool "Au1100 LCD Driver"
1663 depends on (FB = y) && MIPS && SOC_AU1100 1689 depends on (FB = y) && MIPS && SOC_AU1100
@@ -1840,6 +1866,16 @@ config FB_W100
1840 1866
1841 If unsure, say N. 1867 If unsure, say N.
1842 1868
1869config FB_SH_MOBILE_LCDC
1870 tristate "SuperH Mobile LCDC framebuffer support"
1871 depends on FB && SUPERH
1872 select FB_CFB_FILLRECT
1873 select FB_CFB_COPYAREA
1874 select FB_CFB_IMAGEBLIT
1875 default m
1876 ---help---
1877 Frame buffer driver for the on-chip SH-Mobile LCD controller.
1878
1843config FB_S3C2410 1879config FB_S3C2410
1844 tristate "S3C2410 LCD framebuffer support" 1880 tristate "S3C2410 LCD framebuffer support"
1845 depends on FB && ARCH_S3C2410 1881 depends on FB && ARCH_S3C2410
@@ -1951,6 +1987,23 @@ config FB_AM200EPD
1951 This enables support for the Metronome display controller used on 1987 This enables support for the Metronome display controller used on
1952 the E-Ink AM-200 EPD devkit. 1988 the E-Ink AM-200 EPD devkit.
1953 1989
1990config FB_COBALT
1991 tristate "Cobalt server LCD frame buffer support"
1992 depends on FB && MIPS_COBALT
1993
1994config FB_SH7760
1995 bool "SH7760/SH7763 LCDC support"
1996 depends on FB && (CPU_SUBTYPE_SH7760 || CPU_SUBTYPE_SH7763)
1997 select FB_CFB_FILLRECT
1998 select FB_CFB_COPYAREA
1999 select FB_CFB_IMAGEBLIT
2000 help
2001 Support for the SH7760/SH7763 integrated (D)STN/TFT LCD Controller.
2002 Supports display resolutions up to 1024x1024 pixel, grayscale and
2003 color operation, with depths ranging from 1 bpp to 8 bpp monochrome
2004 and 8, 15 or 16 bpp color; 90 degrees clockwise display rotation for
2005 panels <= 320 pixel horizontal resolution.
2006
1954config FB_VIRTUAL 2007config FB_VIRTUAL
1955 tristate "Virtual Frame Buffer support (ONLY FOR TESTING!)" 2008 tristate "Virtual Frame Buffer support (ONLY FOR TESTING!)"
1956 depends on FB 2009 depends on FB
diff --git a/drivers/video/Makefile b/drivers/video/Makefile
index 04bca35403ff..0ebc1bfd2514 100644
--- a/drivers/video/Makefile
+++ b/drivers/video/Makefile
@@ -106,17 +106,22 @@ obj-$(CONFIG_FB_PMAGB_B) += pmagb-b-fb.o
106obj-$(CONFIG_FB_MAXINE) += maxinefb.o 106obj-$(CONFIG_FB_MAXINE) += maxinefb.o
107obj-$(CONFIG_FB_METRONOME) += metronomefb.o 107obj-$(CONFIG_FB_METRONOME) += metronomefb.o
108obj-$(CONFIG_FB_S1D13XXX) += s1d13xxxfb.o 108obj-$(CONFIG_FB_S1D13XXX) += s1d13xxxfb.o
109obj-$(CONFIG_FB_SH7760) += sh7760fb.o
109obj-$(CONFIG_FB_IMX) += imxfb.o 110obj-$(CONFIG_FB_IMX) += imxfb.o
110obj-$(CONFIG_FB_S3C2410) += s3c2410fb.o 111obj-$(CONFIG_FB_S3C2410) += s3c2410fb.o
111obj-$(CONFIG_FB_FSL_DIU) += fsl-diu-fb.o 112obj-$(CONFIG_FB_FSL_DIU) += fsl-diu-fb.o
113obj-$(CONFIG_FB_COBALT) += cobalt_lcdfb.o
112obj-$(CONFIG_FB_PNX4008_DUM) += pnx4008/ 114obj-$(CONFIG_FB_PNX4008_DUM) += pnx4008/
113obj-$(CONFIG_FB_PNX4008_DUM_RGB) += pnx4008/ 115obj-$(CONFIG_FB_PNX4008_DUM_RGB) += pnx4008/
114obj-$(CONFIG_FB_IBM_GXT4500) += gxt4500.o 116obj-$(CONFIG_FB_IBM_GXT4500) += gxt4500.o
115obj-$(CONFIG_FB_PS3) += ps3fb.o 117obj-$(CONFIG_FB_PS3) += ps3fb.o
116obj-$(CONFIG_FB_SM501) += sm501fb.o 118obj-$(CONFIG_FB_SM501) += sm501fb.o
117obj-$(CONFIG_FB_XILINX) += xilinxfb.o 119obj-$(CONFIG_FB_XILINX) += xilinxfb.o
120obj-$(CONFIG_FB_SH_MOBILE_LCDC) += sh_mobile_lcdcfb.o
121obj-$(CONFIG_FB_SH7343VOU) += sh7343_voufb.o
118obj-$(CONFIG_FB_OMAP) += omap/ 122obj-$(CONFIG_FB_OMAP) += omap/
119obj-$(CONFIG_XEN_FBDEV_FRONTEND) += xen-fbfront.o 123obj-$(CONFIG_XEN_FBDEV_FRONTEND) += xen-fbfront.o
124obj-$(CONFIG_FB_CARMINE) += carminefb.o
120 125
121# Platform or fallback drivers go here 126# Platform or fallback drivers go here
122obj-$(CONFIG_FB_UVESA) += uvesafb.o 127obj-$(CONFIG_FB_UVESA) += uvesafb.o
diff --git a/drivers/video/acornfb.c b/drivers/video/acornfb.c
index eedb8285e32f..017233d0c481 100644
--- a/drivers/video/acornfb.c
+++ b/drivers/video/acornfb.c
@@ -23,6 +23,7 @@
23#include <linux/string.h> 23#include <linux/string.h>
24#include <linux/ctype.h> 24#include <linux/ctype.h>
25#include <linux/slab.h> 25#include <linux/slab.h>
26#include <linux/mm.h>
26#include <linux/init.h> 27#include <linux/init.h>
27#include <linux/fb.h> 28#include <linux/fb.h>
28#include <linux/platform_device.h> 29#include <linux/platform_device.h>
diff --git a/drivers/video/amifb.c b/drivers/video/amifb.c
index 45c154ade9ca..b8e9a8682f2d 100644
--- a/drivers/video/amifb.c
+++ b/drivers/video/amifb.c
@@ -1136,7 +1136,6 @@ static int amifb_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg
1136 * Interface to the low level console driver 1136 * Interface to the low level console driver
1137 */ 1137 */
1138 1138
1139int amifb_init(void);
1140static void amifb_deinit(void); 1139static void amifb_deinit(void);
1141 1140
1142 /* 1141 /*
@@ -2048,13 +2047,16 @@ static void amifb_copyarea(struct fb_info *info,
2048 width = x2 - dx; 2047 width = x2 - dx;
2049 height = y2 - dy; 2048 height = y2 - dy;
2050 2049
2050 if (area->sx + dx < area->dx || area->sy + dy < area->dy)
2051 return;
2052
2051 /* update sx,sy */ 2053 /* update sx,sy */
2052 sx = area->sx + (dx - area->dx); 2054 sx = area->sx + (dx - area->dx);
2053 sy = area->sy + (dy - area->dy); 2055 sy = area->sy + (dy - area->dy);
2054 2056
2055 /* the source must be completely inside the virtual screen */ 2057 /* the source must be completely inside the virtual screen */
2056 if (sx < 0 || sy < 0 || (sx + width) > info->var.xres_virtual || 2058 if (sx + width > info->var.xres_virtual ||
2057 (sy + height) > info->var.yres_virtual) 2059 sy + height > info->var.yres_virtual)
2058 return; 2060 return;
2059 2061
2060 if (dy > sy || (dy == sy && dx > sx)) { 2062 if (dy > sy || (dy == sy && dx > sx)) {
@@ -2245,7 +2247,7 @@ static inline void chipfree(void)
2245 * Initialisation 2247 * Initialisation
2246 */ 2248 */
2247 2249
2248int __init amifb_init(void) 2250static int __init amifb_init(void)
2249{ 2251{
2250 int tag, i, err = 0; 2252 int tag, i, err = 0;
2251 u_long chipptr; 2253 u_long chipptr;
@@ -3790,16 +3792,14 @@ static void ami_rebuild_copper(void)
3790 } 3792 }
3791} 3793}
3792 3794
3793 3795static void __exit amifb_exit(void)
3794module_init(amifb_init);
3795
3796#ifdef MODULE
3797MODULE_LICENSE("GPL");
3798
3799void cleanup_module(void)
3800{ 3796{
3801 unregister_framebuffer(&fb_info); 3797 unregister_framebuffer(&fb_info);
3802 amifb_deinit(); 3798 amifb_deinit();
3803 amifb_video_off(); 3799 amifb_video_off();
3804} 3800}
3805#endif /* MODULE */ 3801
3802module_init(amifb_init);
3803module_exit(amifb_exit);
3804
3805MODULE_LICENSE("GPL");
diff --git a/drivers/video/atafb.c b/drivers/video/atafb.c
index fa55d356b535..77eb8b34fbfa 100644
--- a/drivers/video/atafb.c
+++ b/drivers/video/atafb.c
@@ -2593,13 +2593,16 @@ static void atafb_copyarea(struct fb_info *info, const struct fb_copyarea *area)
2593 width = x2 - dx; 2593 width = x2 - dx;
2594 height = y2 - dy; 2594 height = y2 - dy;
2595 2595
2596 if (area->sx + dx < area->dx || area->sy + dy < area->dy)
2597 return;
2598
2596 /* update sx,sy */ 2599 /* update sx,sy */
2597 sx = area->sx + (dx - area->dx); 2600 sx = area->sx + (dx - area->dx);
2598 sy = area->sy + (dy - area->dy); 2601 sy = area->sy + (dy - area->dy);
2599 2602
2600 /* the source must be completely inside the virtual screen */ 2603 /* the source must be completely inside the virtual screen */
2601 if (sx < 0 || sy < 0 || (sx + width) > info->var.xres_virtual || 2604 if (sx + width > info->var.xres_virtual ||
2602 (sy + height) > info->var.yres_virtual) 2605 sy + height > info->var.yres_virtual)
2603 return; 2606 return;
2604 2607
2605 if (dy > sy || (dy == sy && dx > sx)) { 2608 if (dy > sy || (dy == sy && dx > sx)) {
diff --git a/drivers/video/atmel_lcdfb.c b/drivers/video/atmel_lcdfb.c
index b004036d4087..5b3a15dffb5f 100644
--- a/drivers/video/atmel_lcdfb.c
+++ b/drivers/video/atmel_lcdfb.c
@@ -256,6 +256,20 @@ static int atmel_lcdfb_alloc_video_memory(struct atmel_lcdfb_info *sinfo)
256 return 0; 256 return 0;
257} 257}
258 258
259static const struct fb_videomode *atmel_lcdfb_choose_mode(struct fb_var_screeninfo *var,
260 struct fb_info *info)
261{
262 struct fb_videomode varfbmode;
263 const struct fb_videomode *fbmode = NULL;
264
265 fb_var_to_videomode(&varfbmode, var);
266 fbmode = fb_find_nearest_mode(&varfbmode, &info->modelist);
267 if (fbmode)
268 fb_videomode_to_var(var, fbmode);
269 return fbmode;
270}
271
272
259/** 273/**
260 * atmel_lcdfb_check_var - Validates a var passed in. 274 * atmel_lcdfb_check_var - Validates a var passed in.
261 * @var: frame buffer variable screen structure 275 * @var: frame buffer variable screen structure
@@ -289,6 +303,15 @@ static int atmel_lcdfb_check_var(struct fb_var_screeninfo *var,
289 clk_value_khz = clk_get_rate(sinfo->lcdc_clk) / 1000; 303 clk_value_khz = clk_get_rate(sinfo->lcdc_clk) / 1000;
290 304
291 dev_dbg(dev, "%s:\n", __func__); 305 dev_dbg(dev, "%s:\n", __func__);
306
307 if (!(var->pixclock && var->bits_per_pixel)) {
308 /* choose a suitable mode if possible */
309 if (!atmel_lcdfb_choose_mode(var, info)) {
310 dev_err(dev, "needed value not specified\n");
311 return -EINVAL;
312 }
313 }
314
292 dev_dbg(dev, " resolution: %ux%u\n", var->xres, var->yres); 315 dev_dbg(dev, " resolution: %ux%u\n", var->xres, var->yres);
293 dev_dbg(dev, " pixclk: %lu KHz\n", PICOS2KHZ(var->pixclock)); 316 dev_dbg(dev, " pixclk: %lu KHz\n", PICOS2KHZ(var->pixclock));
294 dev_dbg(dev, " bpp: %u\n", var->bits_per_pixel); 317 dev_dbg(dev, " bpp: %u\n", var->bits_per_pixel);
@@ -299,6 +322,13 @@ static int atmel_lcdfb_check_var(struct fb_var_screeninfo *var,
299 return -EINVAL; 322 return -EINVAL;
300 } 323 }
301 324
325 /* Do not allow to have real resoulution larger than virtual */
326 if (var->xres > var->xres_virtual)
327 var->xres_virtual = var->xres;
328
329 if (var->yres > var->yres_virtual)
330 var->yres_virtual = var->yres;
331
302 /* Force same alignment for each line */ 332 /* Force same alignment for each line */
303 var->xres = (var->xres + 3) & ~3UL; 333 var->xres = (var->xres + 3) & ~3UL;
304 var->xres_virtual = (var->xres_virtual + 3) & ~3UL; 334 var->xres_virtual = (var->xres_virtual + 3) & ~3UL;
@@ -379,6 +409,35 @@ static int atmel_lcdfb_check_var(struct fb_var_screeninfo *var,
379 return 0; 409 return 0;
380} 410}
381 411
412/*
413 * LCD reset sequence
414 */
415static void atmel_lcdfb_reset(struct atmel_lcdfb_info *sinfo)
416{
417 might_sleep();
418
419 /* LCD power off */
420 lcdc_writel(sinfo, ATMEL_LCDC_PWRCON, sinfo->guard_time << ATMEL_LCDC_GUARDT_OFFSET);
421
422 /* wait for the LCDC core to become idle */
423 while (lcdc_readl(sinfo, ATMEL_LCDC_PWRCON) & ATMEL_LCDC_BUSY)
424 msleep(10);
425
426 /* DMA disable */
427 lcdc_writel(sinfo, ATMEL_LCDC_DMACON, 0);
428
429 /* wait for DMA engine to become idle */
430 while (lcdc_readl(sinfo, ATMEL_LCDC_DMACON) & ATMEL_LCDC_DMABUSY)
431 msleep(10);
432
433 /* LCD power on */
434 lcdc_writel(sinfo, ATMEL_LCDC_PWRCON,
435 (sinfo->guard_time << ATMEL_LCDC_GUARDT_OFFSET) | ATMEL_LCDC_PWR);
436
437 /* DMA enable */
438 lcdc_writel(sinfo, ATMEL_LCDC_DMACON, sinfo->default_dmacon);
439}
440
382/** 441/**
383 * atmel_lcdfb_set_par - Alters the hardware state. 442 * atmel_lcdfb_set_par - Alters the hardware state.
384 * @info: frame buffer structure that represents a single frame buffer 443 * @info: frame buffer structure that represents a single frame buffer
@@ -401,6 +460,8 @@ static int atmel_lcdfb_set_par(struct fb_info *info)
401 unsigned long clk_value_khz; 460 unsigned long clk_value_khz;
402 unsigned long bits_per_line; 461 unsigned long bits_per_line;
403 462
463 might_sleep();
464
404 dev_dbg(info->device, "%s:\n", __func__); 465 dev_dbg(info->device, "%s:\n", __func__);
405 dev_dbg(info->device, " * resolution: %ux%u (%ux%u virtual)\n", 466 dev_dbg(info->device, " * resolution: %ux%u (%ux%u virtual)\n",
406 info->var.xres, info->var.yres, 467 info->var.xres, info->var.yres,
@@ -511,6 +572,8 @@ static int atmel_lcdfb_set_par(struct fb_info *info)
511 572
512 /* Disable all interrupts */ 573 /* Disable all interrupts */
513 lcdc_writel(sinfo, ATMEL_LCDC_IDR, ~0UL); 574 lcdc_writel(sinfo, ATMEL_LCDC_IDR, ~0UL);
575 /* Enable FIFO & DMA errors */
576 lcdc_writel(sinfo, ATMEL_LCDC_IER, ATMEL_LCDC_UFLWI | ATMEL_LCDC_OWRI | ATMEL_LCDC_MERI);
514 577
515 /* ...wait for DMA engine to become idle... */ 578 /* ...wait for DMA engine to become idle... */
516 while (lcdc_readl(sinfo, ATMEL_LCDC_DMACON) & ATMEL_LCDC_DMABUSY) 579 while (lcdc_readl(sinfo, ATMEL_LCDC_DMACON) & ATMEL_LCDC_DMABUSY)
@@ -645,10 +708,26 @@ static irqreturn_t atmel_lcdfb_interrupt(int irq, void *dev_id)
645 u32 status; 708 u32 status;
646 709
647 status = lcdc_readl(sinfo, ATMEL_LCDC_ISR); 710 status = lcdc_readl(sinfo, ATMEL_LCDC_ISR);
648 lcdc_writel(sinfo, ATMEL_LCDC_IDR, status); 711 if (status & ATMEL_LCDC_UFLWI) {
712 dev_warn(info->device, "FIFO underflow %#x\n", status);
713 /* reset DMA and FIFO to avoid screen shifting */
714 schedule_work(&sinfo->task);
715 }
716 lcdc_writel(sinfo, ATMEL_LCDC_ICR, status);
649 return IRQ_HANDLED; 717 return IRQ_HANDLED;
650} 718}
651 719
720/*
721 * LCD controller task (to reset the LCD)
722 */
723static void atmel_lcdfb_task(struct work_struct *work)
724{
725 struct atmel_lcdfb_info *sinfo =
726 container_of(work, struct atmel_lcdfb_info, task);
727
728 atmel_lcdfb_reset(sinfo);
729}
730
652static int __init atmel_lcdfb_init_fbinfo(struct atmel_lcdfb_info *sinfo) 731static int __init atmel_lcdfb_init_fbinfo(struct atmel_lcdfb_info *sinfo)
653{ 732{
654 struct fb_info *info = sinfo->info; 733 struct fb_info *info = sinfo->info;
@@ -691,6 +770,7 @@ static int __init atmel_lcdfb_probe(struct platform_device *pdev)
691 struct fb_info *info; 770 struct fb_info *info;
692 struct atmel_lcdfb_info *sinfo; 771 struct atmel_lcdfb_info *sinfo;
693 struct atmel_lcdfb_info *pdata_sinfo; 772 struct atmel_lcdfb_info *pdata_sinfo;
773 struct fb_videomode fbmode;
694 struct resource *regs = NULL; 774 struct resource *regs = NULL;
695 struct resource *map = NULL; 775 struct resource *map = NULL;
696 int ret; 776 int ret;
@@ -824,6 +904,10 @@ static int __init atmel_lcdfb_probe(struct platform_device *pdev)
824 goto unmap_mmio; 904 goto unmap_mmio;
825 } 905 }
826 906
907 /* Some operations on the LCDC might sleep and
908 * require a preemptible task context */
909 INIT_WORK(&sinfo->task, atmel_lcdfb_task);
910
827 ret = atmel_lcdfb_init_fbinfo(sinfo); 911 ret = atmel_lcdfb_init_fbinfo(sinfo);
828 if (ret < 0) { 912 if (ret < 0) {
829 dev_err(dev, "init fbinfo failed: %d\n", ret); 913 dev_err(dev, "init fbinfo failed: %d\n", ret);
@@ -853,6 +937,10 @@ static int __init atmel_lcdfb_probe(struct platform_device *pdev)
853 goto free_cmap; 937 goto free_cmap;
854 } 938 }
855 939
940 /* add selected videomode to modelist */
941 fb_var_to_videomode(&fbmode, &info->var);
942 fb_add_videomode(&fbmode, &info->modelist);
943
856 /* Power up the LCDC screen */ 944 /* Power up the LCDC screen */
857 if (sinfo->atmel_lcdfb_power_control) 945 if (sinfo->atmel_lcdfb_power_control)
858 sinfo->atmel_lcdfb_power_control(1); 946 sinfo->atmel_lcdfb_power_control(1);
@@ -866,6 +954,7 @@ static int __init atmel_lcdfb_probe(struct platform_device *pdev)
866free_cmap: 954free_cmap:
867 fb_dealloc_cmap(&info->cmap); 955 fb_dealloc_cmap(&info->cmap);
868unregister_irqs: 956unregister_irqs:
957 cancel_work_sync(&sinfo->task);
869 free_irq(sinfo->irq_base, info); 958 free_irq(sinfo->irq_base, info);
870unmap_mmio: 959unmap_mmio:
871 exit_backlight(sinfo); 960 exit_backlight(sinfo);
@@ -903,6 +992,7 @@ static int __exit atmel_lcdfb_remove(struct platform_device *pdev)
903 if (!sinfo) 992 if (!sinfo)
904 return 0; 993 return 0;
905 994
995 cancel_work_sync(&sinfo->task);
906 exit_backlight(sinfo); 996 exit_backlight(sinfo);
907 if (sinfo->atmel_lcdfb_power_control) 997 if (sinfo->atmel_lcdfb_power_control)
908 sinfo->atmel_lcdfb_power_control(0); 998 sinfo->atmel_lcdfb_power_control(0);
diff --git a/drivers/video/aty/aty128fb.c b/drivers/video/aty/aty128fb.c
index 07b6addbb3c1..243ea4ab20c8 100644
--- a/drivers/video/aty/aty128fb.c
+++ b/drivers/video/aty/aty128fb.c
@@ -1339,10 +1339,8 @@ static int aty128_var_to_pll(u32 period_in_ps, struct aty128_pll *pll,
1339 if (vclk * 12 < c.ppll_min) 1339 if (vclk * 12 < c.ppll_min)
1340 vclk = c.ppll_min/12; 1340 vclk = c.ppll_min/12;
1341 1341
1342 pll->post_divider = -1;
1343
1344 /* now, find an acceptable divider */ 1342 /* now, find an acceptable divider */
1345 for (i = 0; i < sizeof(post_dividers); i++) { 1343 for (i = 0; i < ARRAY_SIZE(post_dividers); i++) {
1346 output_freq = post_dividers[i] * vclk; 1344 output_freq = post_dividers[i] * vclk;
1347 if (output_freq >= c.ppll_min && output_freq <= c.ppll_max) { 1345 if (output_freq >= c.ppll_min && output_freq <= c.ppll_max) {
1348 pll->post_divider = post_dividers[i]; 1346 pll->post_divider = post_dividers[i];
@@ -1350,7 +1348,7 @@ static int aty128_var_to_pll(u32 period_in_ps, struct aty128_pll *pll,
1350 } 1348 }
1351 } 1349 }
1352 1350
1353 if (pll->post_divider < 0) 1351 if (i == ARRAY_SIZE(post_dividers))
1354 return -EINVAL; 1352 return -EINVAL;
1355 1353
1356 /* calculate feedback divider */ 1354 /* calculate feedback divider */
diff --git a/drivers/video/aty/atyfb_base.c b/drivers/video/aty/atyfb_base.c
index bd4ac0bafecb..620ba8120368 100644
--- a/drivers/video/aty/atyfb_base.c
+++ b/drivers/video/aty/atyfb_base.c
@@ -424,7 +424,6 @@ static struct {
424#endif /* CONFIG_FB_ATY_CT */ 424#endif /* CONFIG_FB_ATY_CT */
425}; 425};
426 426
427/* can not fail */
428static int __devinit correct_chipset(struct atyfb_par *par) 427static int __devinit correct_chipset(struct atyfb_par *par)
429{ 428{
430 u8 rev; 429 u8 rev;
@@ -437,6 +436,9 @@ static int __devinit correct_chipset(struct atyfb_par *par)
437 if (par->pci_id == aty_chips[i].pci_id) 436 if (par->pci_id == aty_chips[i].pci_id)
438 break; 437 break;
439 438
439 if (i < 0)
440 return -ENODEV;
441
440 name = aty_chips[i].name; 442 name = aty_chips[i].name;
441 par->pll_limits.pll_max = aty_chips[i].pll; 443 par->pll_limits.pll_max = aty_chips[i].pll;
442 par->pll_limits.mclk = aty_chips[i].mclk; 444 par->pll_limits.mclk = aty_chips[i].mclk;
@@ -2229,6 +2231,7 @@ static int __devinit aty_init(struct fb_info *info)
2229 const char *ramname = NULL, *xtal; 2231 const char *ramname = NULL, *xtal;
2230 int gtb_memsize, has_var = 0; 2232 int gtb_memsize, has_var = 0;
2231 struct fb_var_screeninfo var; 2233 struct fb_var_screeninfo var;
2234 int ret;
2232 2235
2233 init_waitqueue_head(&par->vblank.wait); 2236 init_waitqueue_head(&par->vblank.wait);
2234 spin_lock_init(&par->int_lock); 2237 spin_lock_init(&par->int_lock);
@@ -2610,7 +2613,8 @@ static int __devinit aty_init(struct fb_info *info)
2610 var.yres_virtual = var.yres; 2613 var.yres_virtual = var.yres;
2611 } 2614 }
2612 2615
2613 if (atyfb_check_var(&var, info)) { 2616 ret = atyfb_check_var(&var, info);
2617 if (ret) {
2614 PRINTKE("can't set default video mode\n"); 2618 PRINTKE("can't set default video mode\n");
2615 goto aty_init_exit; 2619 goto aty_init_exit;
2616 } 2620 }
@@ -2621,10 +2625,12 @@ static int __devinit aty_init(struct fb_info *info)
2621#endif /* CONFIG_FB_ATY_CT */ 2625#endif /* CONFIG_FB_ATY_CT */
2622 info->var = var; 2626 info->var = var;
2623 2627
2624 if (fb_alloc_cmap(&info->cmap, 256, 0) < 0) 2628 ret = fb_alloc_cmap(&info->cmap, 256, 0);
2629 if (ret < 0)
2625 goto aty_init_exit; 2630 goto aty_init_exit;
2626 2631
2627 if (register_framebuffer(info) < 0) { 2632 ret = register_framebuffer(info);
2633 if (ret < 0) {
2628 fb_dealloc_cmap(&info->cmap); 2634 fb_dealloc_cmap(&info->cmap);
2629 goto aty_init_exit; 2635 goto aty_init_exit;
2630 } 2636 }
@@ -2650,7 +2656,7 @@ aty_init_exit:
2650 par->mtrr_aper = -1; 2656 par->mtrr_aper = -1;
2651 } 2657 }
2652#endif 2658#endif
2653 return -1; 2659 return ret;
2654} 2660}
2655 2661
2656static void aty_resume_chip(struct fb_info *info) 2662static void aty_resume_chip(struct fb_info *info)
@@ -2709,8 +2715,7 @@ static int atyfb_blank(int blank, struct fb_info *info)
2709 if (par->lock_blank || par->asleep) 2715 if (par->lock_blank || par->asleep)
2710 return 0; 2716 return 0;
2711 2717
2712#ifdef CONFIG_FB_ATY_BACKLIGHT 2718#ifdef CONFIG_FB_ATY_GENERIC_LCD
2713#elif defined(CONFIG_FB_ATY_GENERIC_LCD)
2714 if (par->lcd_table && blank > FB_BLANK_NORMAL && 2719 if (par->lcd_table && blank > FB_BLANK_NORMAL &&
2715 (aty_ld_lcd(LCD_GEN_CNTL, par) & LCD_ON)) { 2720 (aty_ld_lcd(LCD_GEN_CNTL, par) & LCD_ON)) {
2716 u32 pm = aty_ld_lcd(POWER_MANAGEMENT, par); 2721 u32 pm = aty_ld_lcd(POWER_MANAGEMENT, par);
@@ -2739,8 +2744,7 @@ static int atyfb_blank(int blank, struct fb_info *info)
2739 } 2744 }
2740 aty_st_le32(CRTC_GEN_CNTL, gen_cntl, par); 2745 aty_st_le32(CRTC_GEN_CNTL, gen_cntl, par);
2741 2746
2742#ifdef CONFIG_FB_ATY_BACKLIGHT 2747#ifdef CONFIG_FB_ATY_GENERIC_LCD
2743#elif defined(CONFIG_FB_ATY_GENERIC_LCD)
2744 if (par->lcd_table && blank <= FB_BLANK_NORMAL && 2748 if (par->lcd_table && blank <= FB_BLANK_NORMAL &&
2745 (aty_ld_lcd(LCD_GEN_CNTL, par) & LCD_ON)) { 2749 (aty_ld_lcd(LCD_GEN_CNTL, par) & LCD_ON)) {
2746 u32 pm = aty_ld_lcd(POWER_MANAGEMENT, par); 2750 u32 pm = aty_ld_lcd(POWER_MANAGEMENT, par);
@@ -3331,7 +3335,7 @@ static int __devinit init_from_bios(struct atyfb_par *par)
3331 PRINTKE("no BIOS frequency table found, use parameters\n"); 3335 PRINTKE("no BIOS frequency table found, use parameters\n");
3332 ret = -ENXIO; 3336 ret = -ENXIO;
3333 } 3337 }
3334 iounmap((void* __iomem )bios_base); 3338 iounmap((void __iomem *)bios_base);
3335 3339
3336 return ret; 3340 return ret;
3337} 3341}
@@ -3418,14 +3422,7 @@ static int __devinit atyfb_pci_probe(struct pci_dev *pdev, const struct pci_devi
3418 struct fb_info *info; 3422 struct fb_info *info;
3419 struct resource *rp; 3423 struct resource *rp;
3420 struct atyfb_par *par; 3424 struct atyfb_par *par;
3421 int i, rc = -ENOMEM; 3425 int rc = -ENOMEM;
3422
3423 for (i = ARRAY_SIZE(aty_chips) - 1; i >= 0; i--)
3424 if (pdev->device == aty_chips[i].pci_id)
3425 break;
3426
3427 if (i < 0)
3428 return -ENODEV;
3429 3426
3430 /* Enable device in PCI config */ 3427 /* Enable device in PCI config */
3431 if (pci_enable_device(pdev)) { 3428 if (pci_enable_device(pdev)) {
@@ -3456,7 +3453,7 @@ static int __devinit atyfb_pci_probe(struct pci_dev *pdev, const struct pci_devi
3456 par = info->par; 3453 par = info->par;
3457 info->fix = atyfb_fix; 3454 info->fix = atyfb_fix;
3458 info->device = &pdev->dev; 3455 info->device = &pdev->dev;
3459 par->pci_id = aty_chips[i].pci_id; 3456 par->pci_id = pdev->device;
3460 par->res_start = res_start; 3457 par->res_start = res_start;
3461 par->res_size = res_size; 3458 par->res_size = res_size;
3462 par->irq = pdev->irq; 3459 par->irq = pdev->irq;
@@ -3474,7 +3471,8 @@ static int __devinit atyfb_pci_probe(struct pci_dev *pdev, const struct pci_devi
3474 pci_set_drvdata(pdev, info); 3471 pci_set_drvdata(pdev, info);
3475 3472
3476 /* Init chip & register framebuffer */ 3473 /* Init chip & register framebuffer */
3477 if (aty_init(info)) 3474 rc = aty_init(info);
3475 if (rc)
3478 goto err_release_io; 3476 goto err_release_io;
3479 3477
3480#ifdef __sparc__ 3478#ifdef __sparc__
@@ -3655,18 +3653,62 @@ static void __devexit atyfb_pci_remove(struct pci_dev *pdev)
3655 atyfb_remove(info); 3653 atyfb_remove(info);
3656} 3654}
3657 3655
3658/*
3659 * This driver uses its own matching table. That will be more difficult
3660 * to fix, so for now, we just match against any ATI ID and let the
3661 * probe() function find out what's up. That also mean we don't have
3662 * a module ID table though.
3663 */
3664static struct pci_device_id atyfb_pci_tbl[] = { 3656static struct pci_device_id atyfb_pci_tbl[] = {
3665 { PCI_VENDOR_ID_ATI, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, 3657#ifdef CONFIG_FB_ATY_GX
3666 PCI_BASE_CLASS_DISPLAY << 16, 0xff0000, 0 }, 3658 { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_CHIP_MACH64GX) },
3667 { 0, } 3659 { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_CHIP_MACH64CX) },
3660#endif /* CONFIG_FB_ATY_GX */
3661
3662#ifdef CONFIG_FB_ATY_CT
3663 { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_CHIP_MACH64CT) },
3664 { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_CHIP_MACH64ET) },
3665
3666 { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_CHIP_MACH64LT) },
3667
3668 { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_CHIP_MACH64VT) },
3669 { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_CHIP_MACH64GT) },
3670
3671 { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_CHIP_MACH64VU) },
3672 { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_CHIP_MACH64GU) },
3673
3674 { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_CHIP_MACH64LG) },
3675
3676 { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_CHIP_MACH64VV) },
3677
3678 { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_CHIP_MACH64GV) },
3679 { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_CHIP_MACH64GW) },
3680 { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_CHIP_MACH64GY) },
3681 { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_CHIP_MACH64GZ) },
3682
3683 { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_CHIP_MACH64GB) },
3684 { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_CHIP_MACH64GD) },
3685 { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_CHIP_MACH64GI) },
3686 { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_CHIP_MACH64GP) },
3687 { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_CHIP_MACH64GQ) },
3688
3689 { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_CHIP_MACH64LB) },
3690 { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_CHIP_MACH64LD) },
3691 { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_CHIP_MACH64LI) },
3692 { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_CHIP_MACH64LP) },
3693 { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_CHIP_MACH64LQ) },
3694
3695 { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_CHIP_MACH64GM) },
3696 { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_CHIP_MACH64GN) },
3697 { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_CHIP_MACH64GO) },
3698 { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_CHIP_MACH64GL) },
3699 { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_CHIP_MACH64GR) },
3700 { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_CHIP_MACH64GS) },
3701
3702 { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_CHIP_MACH64LM) },
3703 { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_CHIP_MACH64LN) },
3704 { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_CHIP_MACH64LR) },
3705 { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_CHIP_MACH64LS) },
3706#endif /* CONFIG_FB_ATY_CT */
3707 { }
3668}; 3708};
3669 3709
3710MODULE_DEVICE_TABLE(pci, atyfb_pci_tbl);
3711
3670static struct pci_driver atyfb_driver = { 3712static struct pci_driver atyfb_driver = {
3671 .name = "atyfb", 3713 .name = "atyfb",
3672 .id_table = atyfb_pci_tbl, 3714 .id_table = atyfb_pci_tbl,
diff --git a/drivers/video/aty/radeon_base.c b/drivers/video/aty/radeon_base.c
index 400e9264e456..652273e9f5f9 100644
--- a/drivers/video/aty/radeon_base.c
+++ b/drivers/video/aty/radeon_base.c
@@ -2098,15 +2098,7 @@ static void radeon_identify_vram(struct radeonfb_info *rinfo)
2098 2098
2099static ssize_t radeon_show_one_edid(char *buf, loff_t off, size_t count, const u8 *edid) 2099static ssize_t radeon_show_one_edid(char *buf, loff_t off, size_t count, const u8 *edid)
2100{ 2100{
2101 if (off > EDID_LENGTH) 2101 return memory_read_from_buffer(buf, count, &off, edid, EDID_LENGTH);
2102 return 0;
2103
2104 if (off + count > EDID_LENGTH)
2105 count = EDID_LENGTH - off;
2106
2107 memcpy(buf, edid + off, count);
2108
2109 return count;
2110} 2102}
2111 2103
2112 2104
@@ -2161,6 +2153,7 @@ static int __devinit radeonfb_pci_register (struct pci_dev *pdev,
2161 struct radeonfb_info *rinfo; 2153 struct radeonfb_info *rinfo;
2162 int ret; 2154 int ret;
2163 unsigned char c1, c2; 2155 unsigned char c1, c2;
2156 int err = 0;
2164 2157
2165 pr_debug("radeonfb_pci_register BEGIN\n"); 2158 pr_debug("radeonfb_pci_register BEGIN\n");
2166 2159
@@ -2340,9 +2333,14 @@ static int __devinit radeonfb_pci_register (struct pci_dev *pdev,
2340 2333
2341 /* Register some sysfs stuff (should be done better) */ 2334 /* Register some sysfs stuff (should be done better) */
2342 if (rinfo->mon1_EDID) 2335 if (rinfo->mon1_EDID)
2343 sysfs_create_bin_file(&rinfo->pdev->dev.kobj, &edid1_attr); 2336 err |= sysfs_create_bin_file(&rinfo->pdev->dev.kobj,
2337 &edid1_attr);
2344 if (rinfo->mon2_EDID) 2338 if (rinfo->mon2_EDID)
2345 sysfs_create_bin_file(&rinfo->pdev->dev.kobj, &edid2_attr); 2339 err |= sysfs_create_bin_file(&rinfo->pdev->dev.kobj,
2340 &edid2_attr);
2341 if (err)
2342 pr_warning("%s() Creating sysfs files failed, continuing\n",
2343 __func__);
2346 2344
2347 /* save current mode regs before we switch into the new one 2345 /* save current mode regs before we switch into the new one
2348 * so we can restore this upon __exit 2346 * so we can restore this upon __exit
diff --git a/drivers/video/backlight/Kconfig b/drivers/video/backlight/Kconfig
index 30bf7f2f1635..452b770d8cc9 100644
--- a/drivers/video/backlight/Kconfig
+++ b/drivers/video/backlight/Kconfig
@@ -36,6 +36,30 @@ config LCD_LTV350QV
36 36
37 The LTV350QV panel is present on all ATSTK1000 boards. 37 The LTV350QV panel is present on all ATSTK1000 boards.
38 38
39config LCD_ILI9320
40 tristate
41 depends on LCD_CLASS_DEVICE && BACKLIGHT_LCD_SUPPORT
42 default n
43 help
44 If you have a panel based on the ILI9320 controller chip
45 then say y to include a power driver for it.
46
47config LCD_VGG2432A4
48 tristate "VGG2432A4 LCM device support"
49 depends on BACKLIGHT_LCD_SUPPORT && LCD_CLASS_DEVICE && SPI_MASTER
50 select LCD_ILI9320
51 default n
52 help
53 If you have a VGG2432A4 panel based on the ILI9320 controller chip
54 then say y to include a power driver for it.
55
56config LCD_PLATFORM
57 tristate "Platform LCD controls"
58 depends on LCD_CLASS_DEVICE
59 help
60 This driver provides a platform-device registered LCD power
61 control interface.
62
39# 63#
40# Backlight 64# Backlight
41# 65#
@@ -63,6 +87,18 @@ config BACKLIGHT_ATMEL_LCDC
63 If in doubt, it's safe to enable this option; it doesn't kick 87 If in doubt, it's safe to enable this option; it doesn't kick
64 in unless the board's description says it's wired that way. 88 in unless the board's description says it's wired that way.
65 89
90config BACKLIGHT_ATMEL_PWM
91 tristate "Atmel PWM backlight control"
92 depends on BACKLIGHT_CLASS_DEVICE && ATMEL_PWM
93 default n
94 help
95 Say Y here if you want to use the PWM peripheral in Atmel AT91 and
96 AVR32 devices. This driver will need additional platform data to know
97 which PWM instance to use and how to configure it.
98
99 To compile this driver as a module, choose M here: the module will be
100 called atmel-pwm-bl.
101
66config BACKLIGHT_CORGI 102config BACKLIGHT_CORGI
67 tristate "Generic (aka Sharp Corgi) Backlight Driver" 103 tristate "Generic (aka Sharp Corgi) Backlight Driver"
68 depends on BACKLIGHT_CLASS_DEVICE 104 depends on BACKLIGHT_CLASS_DEVICE
@@ -119,3 +155,12 @@ config BACKLIGHT_PWM
119 help 155 help
120 If you have a LCD backlight adjustable by PWM, say Y to enable 156 If you have a LCD backlight adjustable by PWM, say Y to enable
121 this driver. 157 this driver.
158
159config BACKLIGHT_MBP_NVIDIA
160 tristate "MacBook Pro Nvidia Backlight Driver"
161 depends on BACKLIGHT_CLASS_DEVICE && X86
162 default n
163 help
164 If you have an Apple Macbook Pro with Nvidia graphics hardware say Y
165 to enable a driver for its backlight
166
diff --git a/drivers/video/backlight/Makefile b/drivers/video/backlight/Makefile
index b51a7cd12500..b405aace803f 100644
--- a/drivers/video/backlight/Makefile
+++ b/drivers/video/backlight/Makefile
@@ -1,9 +1,13 @@
1# Backlight & LCD drivers 1# Backlight & LCD drivers
2 2
3obj-$(CONFIG_LCD_CLASS_DEVICE) += lcd.o 3obj-$(CONFIG_LCD_CLASS_DEVICE) += lcd.o
4obj-$(CONFIG_LCD_LTV350QV) += ltv350qv.o 4obj-$(CONFIG_LCD_LTV350QV) += ltv350qv.o
5obj-$(CONFIG_LCD_ILI9320) += ili9320.o
6obj-$(CONFIG_LCD_PLATFORM) += platform_lcd.o
7obj-$(CONFIG_LCD_VGG2432A4) += vgg2432a4.o
5 8
6obj-$(CONFIG_BACKLIGHT_CLASS_DEVICE) += backlight.o 9obj-$(CONFIG_BACKLIGHT_CLASS_DEVICE) += backlight.o
10obj-$(CONFIG_BACKLIGHT_ATMEL_PWM) += atmel-pwm-bl.o
7obj-$(CONFIG_BACKLIGHT_CORGI) += corgi_bl.o 11obj-$(CONFIG_BACKLIGHT_CORGI) += corgi_bl.o
8obj-$(CONFIG_BACKLIGHT_HP680) += hp680_bl.o 12obj-$(CONFIG_BACKLIGHT_HP680) += hp680_bl.o
9obj-$(CONFIG_BACKLIGHT_LOCOMO) += locomolcd.o 13obj-$(CONFIG_BACKLIGHT_LOCOMO) += locomolcd.o
@@ -11,3 +15,5 @@ obj-$(CONFIG_BACKLIGHT_OMAP1) += omap1_bl.o
11obj-$(CONFIG_BACKLIGHT_PROGEAR) += progear_bl.o 15obj-$(CONFIG_BACKLIGHT_PROGEAR) += progear_bl.o
12obj-$(CONFIG_BACKLIGHT_CARILLO_RANCH) += cr_bllcd.o 16obj-$(CONFIG_BACKLIGHT_CARILLO_RANCH) += cr_bllcd.o
13obj-$(CONFIG_BACKLIGHT_PWM) += pwm_bl.o 17obj-$(CONFIG_BACKLIGHT_PWM) += pwm_bl.o
18obj-$(CONFIG_BACKLIGHT_MBP_NVIDIA) += mbp_nvidia_bl.o
19
diff --git a/drivers/video/backlight/atmel-pwm-bl.c b/drivers/video/backlight/atmel-pwm-bl.c
new file mode 100644
index 000000000000..505c0823a105
--- /dev/null
+++ b/drivers/video/backlight/atmel-pwm-bl.c
@@ -0,0 +1,244 @@
1/*
2 * Copyright (C) 2008 Atmel Corporation
3 *
4 * Backlight driver using Atmel PWM peripheral.
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License version 2 as published by
8 * the Free Software Foundation.
9 */
10#include <linux/init.h>
11#include <linux/kernel.h>
12#include <linux/module.h>
13#include <linux/platform_device.h>
14#include <linux/fb.h>
15#include <linux/clk.h>
16#include <linux/gpio.h>
17#include <linux/backlight.h>
18#include <linux/atmel_pwm.h>
19#include <linux/atmel-pwm-bl.h>
20
21struct atmel_pwm_bl {
22 const struct atmel_pwm_bl_platform_data *pdata;
23 struct backlight_device *bldev;
24 struct platform_device *pdev;
25 struct pwm_channel pwmc;
26 int gpio_on;
27};
28
29static int atmel_pwm_bl_set_intensity(struct backlight_device *bd)
30{
31 struct atmel_pwm_bl *pwmbl = bl_get_data(bd);
32 int intensity = bd->props.brightness;
33 int pwm_duty;
34
35 if (bd->props.power != FB_BLANK_UNBLANK)
36 intensity = 0;
37 if (bd->props.fb_blank != FB_BLANK_UNBLANK)
38 intensity = 0;
39
40 if (pwmbl->pdata->pwm_active_low)
41 pwm_duty = pwmbl->pdata->pwm_duty_min + intensity;
42 else
43 pwm_duty = pwmbl->pdata->pwm_duty_max - intensity;
44
45 if (pwm_duty > pwmbl->pdata->pwm_duty_max)
46 pwm_duty = pwmbl->pdata->pwm_duty_max;
47 if (pwm_duty < pwmbl->pdata->pwm_duty_min)
48 pwm_duty = pwmbl->pdata->pwm_duty_min;
49
50 if (!intensity) {
51 if (pwmbl->gpio_on != -1) {
52 gpio_set_value(pwmbl->gpio_on,
53 0 ^ pwmbl->pdata->on_active_low);
54 }
55 pwm_channel_writel(&pwmbl->pwmc, PWM_CUPD, pwm_duty);
56 pwm_channel_disable(&pwmbl->pwmc);
57 } else {
58 pwm_channel_enable(&pwmbl->pwmc);
59 pwm_channel_writel(&pwmbl->pwmc, PWM_CUPD, pwm_duty);
60 if (pwmbl->gpio_on != -1) {
61 gpio_set_value(pwmbl->gpio_on,
62 1 ^ pwmbl->pdata->on_active_low);
63 }
64 }
65
66 return 0;
67}
68
69static int atmel_pwm_bl_get_intensity(struct backlight_device *bd)
70{
71 struct atmel_pwm_bl *pwmbl = bl_get_data(bd);
72 u8 intensity;
73
74 if (pwmbl->pdata->pwm_active_low) {
75 intensity = pwm_channel_readl(&pwmbl->pwmc, PWM_CDTY) -
76 pwmbl->pdata->pwm_duty_min;
77 } else {
78 intensity = pwmbl->pdata->pwm_duty_max -
79 pwm_channel_readl(&pwmbl->pwmc, PWM_CDTY);
80 }
81
82 return intensity;
83}
84
85static int atmel_pwm_bl_init_pwm(struct atmel_pwm_bl *pwmbl)
86{
87 unsigned long pwm_rate = pwmbl->pwmc.mck;
88 unsigned long prescale = DIV_ROUND_UP(pwm_rate,
89 (pwmbl->pdata->pwm_frequency *
90 pwmbl->pdata->pwm_compare_max)) - 1;
91
92 /*
93 * Prescale must be power of two and maximum 0xf in size because of
94 * hardware limit. PWM speed will be:
95 * PWM module clock speed / (2 ^ prescale).
96 */
97 prescale = fls(prescale);
98 if (prescale > 0xf)
99 prescale = 0xf;
100
101 pwm_channel_writel(&pwmbl->pwmc, PWM_CMR, prescale);
102 pwm_channel_writel(&pwmbl->pwmc, PWM_CDTY,
103 pwmbl->pdata->pwm_duty_min +
104 pwmbl->bldev->props.brightness);
105 pwm_channel_writel(&pwmbl->pwmc, PWM_CPRD,
106 pwmbl->pdata->pwm_compare_max);
107
108 dev_info(&pwmbl->pdev->dev, "Atmel PWM backlight driver "
109 "(%lu Hz)\n", pwmbl->pwmc.mck /
110 pwmbl->pdata->pwm_compare_max /
111 (1 << prescale));
112
113 return pwm_channel_enable(&pwmbl->pwmc);
114}
115
116static struct backlight_ops atmel_pwm_bl_ops = {
117 .get_brightness = atmel_pwm_bl_get_intensity,
118 .update_status = atmel_pwm_bl_set_intensity,
119};
120
121static int atmel_pwm_bl_probe(struct platform_device *pdev)
122{
123 const struct atmel_pwm_bl_platform_data *pdata;
124 struct backlight_device *bldev;
125 struct atmel_pwm_bl *pwmbl;
126 int retval;
127
128 pwmbl = kzalloc(sizeof(struct atmel_pwm_bl), GFP_KERNEL);
129 if (!pwmbl)
130 return -ENOMEM;
131
132 pwmbl->pdev = pdev;
133
134 pdata = pdev->dev.platform_data;
135 if (!pdata) {
136 retval = -ENODEV;
137 goto err_free_mem;
138 }
139
140 if (pdata->pwm_compare_max < pdata->pwm_duty_max ||
141 pdata->pwm_duty_min > pdata->pwm_duty_max ||
142 pdata->pwm_frequency == 0) {
143 retval = -EINVAL;
144 goto err_free_mem;
145 }
146
147 pwmbl->pdata = pdata;
148 pwmbl->gpio_on = pdata->gpio_on;
149
150 retval = pwm_channel_alloc(pdata->pwm_channel, &pwmbl->pwmc);
151 if (retval)
152 goto err_free_mem;
153
154 if (pwmbl->gpio_on != -1) {
155 retval = gpio_request(pwmbl->gpio_on, "gpio_atmel_pwm_bl");
156 if (retval) {
157 pwmbl->gpio_on = -1;
158 goto err_free_pwm;
159 }
160
161 /* Turn display off by defatult. */
162 retval = gpio_direction_output(pwmbl->gpio_on,
163 0 ^ pdata->on_active_low);
164 if (retval)
165 goto err_free_gpio;
166 }
167
168 bldev = backlight_device_register("atmel-pwm-bl",
169 &pdev->dev, pwmbl, &atmel_pwm_bl_ops);
170 if (IS_ERR(bldev)) {
171 retval = PTR_ERR(bldev);
172 goto err_free_gpio;
173 }
174
175 pwmbl->bldev = bldev;
176
177 platform_set_drvdata(pdev, pwmbl);
178
179 /* Power up the backlight by default at middle intesity. */
180 bldev->props.power = FB_BLANK_UNBLANK;
181 bldev->props.max_brightness = pdata->pwm_duty_max - pdata->pwm_duty_min;
182 bldev->props.brightness = bldev->props.max_brightness / 2;
183
184 retval = atmel_pwm_bl_init_pwm(pwmbl);
185 if (retval)
186 goto err_free_bl_dev;
187
188 atmel_pwm_bl_set_intensity(bldev);
189
190 return 0;
191
192err_free_bl_dev:
193 platform_set_drvdata(pdev, NULL);
194 backlight_device_unregister(bldev);
195err_free_gpio:
196 if (pwmbl->gpio_on != -1)
197 gpio_free(pwmbl->gpio_on);
198err_free_pwm:
199 pwm_channel_free(&pwmbl->pwmc);
200err_free_mem:
201 kfree(pwmbl);
202 return retval;
203}
204
205static int __exit atmel_pwm_bl_remove(struct platform_device *pdev)
206{
207 struct atmel_pwm_bl *pwmbl = platform_get_drvdata(pdev);
208
209 if (pwmbl->gpio_on != -1) {
210 gpio_set_value(pwmbl->gpio_on, 0);
211 gpio_free(pwmbl->gpio_on);
212 }
213 pwm_channel_disable(&pwmbl->pwmc);
214 pwm_channel_free(&pwmbl->pwmc);
215 backlight_device_unregister(pwmbl->bldev);
216 platform_set_drvdata(pdev, NULL);
217 kfree(pwmbl);
218
219 return 0;
220}
221
222static struct platform_driver atmel_pwm_bl_driver = {
223 .driver = {
224 .name = "atmel-pwm-bl",
225 },
226 /* REVISIT add suspend() and resume() */
227 .remove = __exit_p(atmel_pwm_bl_remove),
228};
229
230static int __init atmel_pwm_bl_init(void)
231{
232 return platform_driver_probe(&atmel_pwm_bl_driver, atmel_pwm_bl_probe);
233}
234module_init(atmel_pwm_bl_init);
235
236static void __exit atmel_pwm_bl_exit(void)
237{
238 platform_driver_unregister(&atmel_pwm_bl_driver);
239}
240module_exit(atmel_pwm_bl_exit);
241
242MODULE_AUTHOR("Hans-Christian egtvedt <hans-christian.egtvedt@atmel.com>");
243MODULE_DESCRIPTION("Atmel PWM backlight driver");
244MODULE_LICENSE("GPL");
diff --git a/drivers/video/backlight/backlight.c b/drivers/video/backlight/backlight.c
index 39394757679c..fab0bc874b58 100644
--- a/drivers/video/backlight/backlight.c
+++ b/drivers/video/backlight/backlight.c
@@ -191,6 +191,7 @@ static struct device_attribute bl_device_attributes[] = {
191 * backlight_device class. 191 * backlight_device class.
192 * @name: the name of the new object(must be the same as the name of the 192 * @name: the name of the new object(must be the same as the name of the
193 * respective framebuffer device). 193 * respective framebuffer device).
194 * @parent: a pointer to the parent device
194 * @devdata: an optional pointer to be stored for private driver use. The 195 * @devdata: an optional pointer to be stored for private driver use. The
195 * methods may retrieve it by using bl_get_data(bd). 196 * methods may retrieve it by using bl_get_data(bd).
196 * @ops: the backlight operations structure. 197 * @ops: the backlight operations structure.
diff --git a/drivers/video/backlight/ili9320.c b/drivers/video/backlight/ili9320.c
new file mode 100644
index 000000000000..ba89b41b639c
--- /dev/null
+++ b/drivers/video/backlight/ili9320.c
@@ -0,0 +1,330 @@
1/* drivers/video/backlight/ili9320.c
2 *
3 * ILI9320 LCD controller driver core.
4 *
5 * Copyright 2007 Simtec Electronics
6 * http://armlinux.simtec.co.uk/
7 * Ben Dooks <ben@simtec.co.uk>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12*/
13
14#include <linux/delay.h>
15#include <linux/err.h>
16#include <linux/fb.h>
17#include <linux/init.h>
18#include <linux/lcd.h>
19#include <linux/module.h>
20
21#include <linux/spi/spi.h>
22
23#include <video/ili9320.h>
24
25#include "ili9320.h"
26
27
28static inline int ili9320_write_spi(struct ili9320 *ili,
29 unsigned int reg,
30 unsigned int value)
31{
32 struct ili9320_spi *spi = &ili->access.spi;
33 unsigned char *addr = spi->buffer_addr;
34 unsigned char *data = spi->buffer_data;
35
36 /* spi message consits of:
37 * first byte: ID and operation
38 */
39
40 addr[0] = spi->id | ILI9320_SPI_INDEX | ILI9320_SPI_WRITE;
41 addr[1] = reg >> 8;
42 addr[2] = reg;
43
44 /* second message is the data to transfer */
45
46 data[0] = spi->id | ILI9320_SPI_DATA | ILI9320_SPI_WRITE;
47 data[1] = value >> 8;
48 data[2] = value;
49
50 return spi_sync(spi->dev, &spi->message);
51}
52
53int ili9320_write(struct ili9320 *ili, unsigned int reg, unsigned int value)
54{
55 dev_dbg(ili->dev, "write: reg=%02x, val=%04x\n", reg, value);
56 return ili->write(ili, reg, value);
57}
58
59EXPORT_SYMBOL_GPL(ili9320_write);
60
61int ili9320_write_regs(struct ili9320 *ili,
62 struct ili9320_reg *values,
63 int nr_values)
64{
65 int index;
66 int ret;
67
68 for (index = 0; index < nr_values; index++, values++) {
69 ret = ili9320_write(ili, values->address, values->value);
70 if (ret != 0)
71 return ret;
72 }
73
74 return 0;
75}
76
77EXPORT_SYMBOL_GPL(ili9320_write_regs);
78
79static void ili9320_reset(struct ili9320 *lcd)
80{
81 struct ili9320_platdata *cfg = lcd->platdata;
82
83 cfg->reset(1);
84 mdelay(50);
85
86 cfg->reset(0);
87 mdelay(50);
88
89 cfg->reset(1);
90 mdelay(100);
91}
92
93static inline int ili9320_init_chip(struct ili9320 *lcd)
94{
95 int ret;
96
97 ili9320_reset(lcd);
98
99 ret = lcd->client->init(lcd, lcd->platdata);
100 if (ret != 0) {
101 dev_err(lcd->dev, "failed to initialise display\n");
102 return ret;
103 }
104
105 lcd->initialised = 1;
106 return 0;
107}
108
109static inline int ili9320_power_on(struct ili9320 *lcd)
110{
111 if (!lcd->initialised)
112 ili9320_init_chip(lcd);
113
114 lcd->display1 |= (ILI9320_DISPLAY1_D(3) | ILI9320_DISPLAY1_BASEE);
115 ili9320_write(lcd, ILI9320_DISPLAY1, lcd->display1);
116
117 return 0;
118}
119
120static inline int ili9320_power_off(struct ili9320 *lcd)
121{
122 lcd->display1 &= ~(ILI9320_DISPLAY1_D(3) | ILI9320_DISPLAY1_BASEE);
123 ili9320_write(lcd, ILI9320_DISPLAY1, lcd->display1);
124
125 return 0;
126}
127
128#define POWER_IS_ON(pwr) ((pwr) <= FB_BLANK_NORMAL)
129
130static int ili9320_power(struct ili9320 *lcd, int power)
131{
132 int ret = 0;
133
134 dev_dbg(lcd->dev, "power %d => %d\n", lcd->power, power);
135
136 if (POWER_IS_ON(power) && !POWER_IS_ON(lcd->power))
137 ret = ili9320_power_on(lcd);
138 else if (!POWER_IS_ON(power) && POWER_IS_ON(lcd->power))
139 ret = ili9320_power_off(lcd);
140
141 if (ret == 0)
142 lcd->power = power;
143 else
144 dev_warn(lcd->dev, "failed to set power mode %d\n", power);
145
146 return ret;
147}
148
149static inline struct ili9320 *to_our_lcd(struct lcd_device *lcd)
150{
151 return lcd_get_data(lcd);
152}
153
154static int ili9320_set_power(struct lcd_device *ld, int power)
155{
156 struct ili9320 *lcd = to_our_lcd(ld);
157
158 return ili9320_power(lcd, power);
159}
160
161static int ili9320_get_power(struct lcd_device *ld)
162{
163 struct ili9320 *lcd = to_our_lcd(ld);
164
165 return lcd->power;
166}
167
168static struct lcd_ops ili9320_ops = {
169 .get_power = ili9320_get_power,
170 .set_power = ili9320_set_power,
171};
172
173static void __devinit ili9320_setup_spi(struct ili9320 *ili,
174 struct spi_device *dev)
175{
176 struct ili9320_spi *spi = &ili->access.spi;
177
178 ili->write = ili9320_write_spi;
179 spi->dev = dev;
180
181 /* fill the two messages we are going to use to send the data
182 * with, the first the address followed by the data. The datasheet
183 * says they should be done as two distinct cycles of the SPI CS line.
184 */
185
186 spi->xfer[0].tx_buf = spi->buffer_addr;
187 spi->xfer[1].tx_buf = spi->buffer_data;
188 spi->xfer[0].len = 3;
189 spi->xfer[1].len = 3;
190 spi->xfer[0].bits_per_word = 8;
191 spi->xfer[1].bits_per_word = 8;
192 spi->xfer[0].cs_change = 1;
193
194 spi_message_init(&spi->message);
195 spi_message_add_tail(&spi->xfer[0], &spi->message);
196 spi_message_add_tail(&spi->xfer[1], &spi->message);
197}
198
199int __devinit ili9320_probe_spi(struct spi_device *spi,
200 struct ili9320_client *client)
201{
202 struct ili9320_platdata *cfg = spi->dev.platform_data;
203 struct device *dev = &spi->dev;
204 struct ili9320 *ili;
205 struct lcd_device *lcd;
206 int ret = 0;
207
208 /* verify we where given some information */
209
210 if (cfg == NULL) {
211 dev_err(dev, "no platform data supplied\n");
212 return -EINVAL;
213 }
214
215 if (cfg->hsize <= 0 || cfg->vsize <= 0 || cfg->reset == NULL) {
216 dev_err(dev, "invalid platform data supplied\n");
217 return -EINVAL;
218 }
219
220 /* allocate and initialse our state */
221
222 ili = kzalloc(sizeof(struct ili9320), GFP_KERNEL);
223 if (ili == NULL) {
224 dev_err(dev, "no memory for device\n");
225 return -ENOMEM;
226 }
227
228 ili->access.spi.id = ILI9320_SPI_IDCODE | ILI9320_SPI_ID(1);
229
230 ili->dev = dev;
231 ili->client = client;
232 ili->power = FB_BLANK_POWERDOWN;
233 ili->platdata = cfg;
234
235 dev_set_drvdata(&spi->dev, ili);
236
237 ili9320_setup_spi(ili, spi);
238
239 lcd = lcd_device_register("ili9320", dev, ili, &ili9320_ops);
240 if (IS_ERR(lcd)) {
241 dev_err(dev, "failed to register lcd device\n");
242 ret = PTR_ERR(lcd);
243 goto err_free;
244 }
245
246 ili->lcd = lcd;
247
248 dev_info(dev, "initialising %s\n", client->name);
249
250 ret = ili9320_power(ili, FB_BLANK_UNBLANK);
251 if (ret != 0) {
252 dev_err(dev, "failed to set lcd power state\n");
253 goto err_unregister;
254 }
255
256 return 0;
257
258 err_unregister:
259 lcd_device_unregister(lcd);
260
261 err_free:
262 kfree(ili);
263
264 return ret;
265}
266
267EXPORT_SYMBOL_GPL(ili9320_probe_spi);
268
269int __devexit ili9320_remove(struct ili9320 *ili)
270{
271 ili9320_power(ili, FB_BLANK_POWERDOWN);
272
273 lcd_device_unregister(ili->lcd);
274 kfree(ili);
275
276 return 0;
277}
278
279EXPORT_SYMBOL_GPL(ili9320_remove);
280
281#ifdef CONFIG_PM
282int ili9320_suspend(struct ili9320 *lcd, pm_message_t state)
283{
284 int ret;
285
286 dev_dbg(lcd->dev, "%s: event %d\n", __func__, state.event);
287
288 if (state.event == PM_EVENT_SUSPEND) {
289 ret = ili9320_power(lcd, FB_BLANK_POWERDOWN);
290
291 if (lcd->platdata->suspend == ILI9320_SUSPEND_DEEP) {
292 ili9320_write(lcd, ILI9320_POWER1, lcd->power1 |
293 ILI9320_POWER1_SLP |
294 ILI9320_POWER1_DSTB);
295 lcd->initialised = 0;
296 }
297
298 return ret;
299 }
300
301 return 0;
302}
303
304EXPORT_SYMBOL_GPL(ili9320_suspend);
305
306int ili9320_resume(struct ili9320 *lcd)
307{
308 dev_info(lcd->dev, "resuming from power state %d\n", lcd->power);
309
310 if (lcd->platdata->suspend == ILI9320_SUSPEND_DEEP) {
311 ili9320_write(lcd, ILI9320_POWER1, 0x00);
312 }
313
314 return ili9320_power(lcd, FB_BLANK_UNBLANK);
315}
316
317EXPORT_SYMBOL_GPL(ili9320_resume);
318#endif
319
320/* Power down all displays on reboot, poweroff or halt */
321void ili9320_shutdown(struct ili9320 *lcd)
322{
323 ili9320_power(lcd, FB_BLANK_POWERDOWN);
324}
325
326EXPORT_SYMBOL_GPL(ili9320_shutdown);
327
328MODULE_AUTHOR("Ben Dooks <ben-linux@fluff.org>");
329MODULE_DESCRIPTION("ILI9320 LCD Driver");
330MODULE_LICENSE("GPL v2");
diff --git a/drivers/video/backlight/ili9320.h b/drivers/video/backlight/ili9320.h
new file mode 100644
index 000000000000..e388eca7cac5
--- /dev/null
+++ b/drivers/video/backlight/ili9320.h
@@ -0,0 +1,80 @@
1/* drivers/video/backlight/ili9320.h
2 *
3 * ILI9320 LCD controller driver core.
4 *
5 * Copyright 2007 Simtec Electronics
6 * Ben Dooks <ben@simtec.co.uk>
7 *
8 * http://armlinux.simtec.co.uk/
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13*/
14
15/* Holder for register and value pairs. */
16struct ili9320_reg {
17 unsigned short address;
18 unsigned short value;
19};
20
21struct ili9320;
22
23struct ili9320_client {
24 const char *name;
25 int (*init)(struct ili9320 *ili, struct ili9320_platdata *cfg);
26
27};
28/* Device attached via an SPI bus. */
29struct ili9320_spi {
30 struct spi_device *dev;
31 struct spi_message message;
32 struct spi_transfer xfer[2];
33
34 unsigned char id;
35 unsigned char buffer_addr[4];
36 unsigned char buffer_data[4];
37};
38
39/* ILI9320 device state. */
40struct ili9320 {
41 union {
42 struct ili9320_spi spi; /* SPI attachged device. */
43 } access; /* Register access method. */
44
45 struct device *dev;
46 struct lcd_device *lcd; /* LCD device we created. */
47 struct ili9320_client *client;
48 struct ili9320_platdata *platdata;
49
50 int power; /* current power state. */
51 int initialised;
52
53 unsigned short display1;
54 unsigned short power1;
55
56 int (*write)(struct ili9320 *ili, unsigned int reg, unsigned int val);
57};
58
59
60/* ILI9320 register access routines */
61
62extern int ili9320_write(struct ili9320 *ili,
63 unsigned int reg, unsigned int value);
64
65extern int ili9320_write_regs(struct ili9320 *ili,
66 struct ili9320_reg *values,
67 int nr_values);
68
69/* Device probe */
70
71extern int ili9320_probe_spi(struct spi_device *spi,
72 struct ili9320_client *cli);
73
74extern int ili9320_remove(struct ili9320 *lcd);
75extern void ili9320_shutdown(struct ili9320 *lcd);
76
77/* PM */
78
79extern int ili9320_suspend(struct ili9320 *lcd, pm_message_t state);
80extern int ili9320_resume(struct ili9320 *lcd);
diff --git a/drivers/video/backlight/lcd.c b/drivers/video/backlight/lcd.c
index 299fd318dd45..b15b2b84a6f7 100644
--- a/drivers/video/backlight/lcd.c
+++ b/drivers/video/backlight/lcd.c
@@ -33,7 +33,7 @@ static int fb_notifier_callback(struct notifier_block *self,
33 ld = container_of(self, struct lcd_device, fb_notif); 33 ld = container_of(self, struct lcd_device, fb_notif);
34 mutex_lock(&ld->ops_lock); 34 mutex_lock(&ld->ops_lock);
35 if (ld->ops) 35 if (ld->ops)
36 if (!ld->ops->check_fb || ld->ops->check_fb(evdata->info)) 36 if (!ld->ops->check_fb || ld->ops->check_fb(ld, evdata->info))
37 ld->ops->set_power(ld, *(int *)evdata->data); 37 ld->ops->set_power(ld, *(int *)evdata->data);
38 mutex_unlock(&ld->ops_lock); 38 mutex_unlock(&ld->ops_lock);
39 return 0; 39 return 0;
diff --git a/drivers/video/backlight/mbp_nvidia_bl.c b/drivers/video/backlight/mbp_nvidia_bl.c
new file mode 100644
index 000000000000..385cba40ea87
--- /dev/null
+++ b/drivers/video/backlight/mbp_nvidia_bl.c
@@ -0,0 +1,116 @@
1/*
2 * Backlight Driver for Nvidia 8600 in Macbook Pro
3 *
4 * Copyright (c) Red Hat <mjg@redhat.com>
5 * Based on code from Pommed:
6 * Copyright (C) 2006 Nicolas Boichat <nicolas @boichat.ch>
7 * Copyright (C) 2006 Felipe Alfaro Solana <felipe_alfaro @linuxmail.org>
8 * Copyright (C) 2007 Julien BLACHE <jb@jblache.org>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13 *
14 * This driver triggers SMIs which cause the firmware to change the
15 * backlight brightness. This is icky in many ways, but it's impractical to
16 * get at the firmware code in order to figure out what it's actually doing.
17 */
18
19#include <linux/module.h>
20#include <linux/kernel.h>
21#include <linux/init.h>
22#include <linux/platform_device.h>
23#include <linux/backlight.h>
24#include <linux/err.h>
25#include <linux/dmi.h>
26#include <linux/io.h>
27
28static struct backlight_device *mbp_backlight_device;
29
30static struct dmi_system_id __initdata mbp_device_table[] = {
31 {
32 .ident = "3,1",
33 .matches = {
34 DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."),
35 DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro3,1"),
36 },
37 },
38 {
39 .ident = "3,2",
40 .matches = {
41 DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."),
42 DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro3,2"),
43 },
44 },
45 {
46 .ident = "4,1",
47 .matches = {
48 DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."),
49 DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro4,1"),
50 },
51 },
52 { }
53};
54
55static int mbp_send_intensity(struct backlight_device *bd)
56{
57 int intensity = bd->props.brightness;
58
59 outb(0x04 | (intensity << 4), 0xb3);
60 outb(0xbf, 0xb2);
61
62 return 0;
63}
64
65static int mbp_get_intensity(struct backlight_device *bd)
66{
67 outb(0x03, 0xb3);
68 outb(0xbf, 0xb2);
69 return inb(0xb3) >> 4;
70}
71
72static struct backlight_ops mbp_ops = {
73 .get_brightness = mbp_get_intensity,
74 .update_status = mbp_send_intensity,
75};
76
77static int __init mbp_init(void)
78{
79 if (!dmi_check_system(mbp_device_table))
80 return -ENODEV;
81
82 if (!request_region(0xb2, 2, "Macbook Pro backlight"))
83 return -ENXIO;
84
85 mbp_backlight_device = backlight_device_register("mbp_backlight",
86 NULL, NULL,
87 &mbp_ops);
88 if (IS_ERR(mbp_backlight_device)) {
89 release_region(0xb2, 2);
90 return PTR_ERR(mbp_backlight_device);
91 }
92
93 mbp_backlight_device->props.max_brightness = 15;
94 mbp_backlight_device->props.brightness =
95 mbp_get_intensity(mbp_backlight_device);
96 backlight_update_status(mbp_backlight_device);
97
98 return 0;
99}
100
101static void __exit mbp_exit(void)
102{
103 backlight_device_unregister(mbp_backlight_device);
104
105 release_region(0xb2, 2);
106}
107
108module_init(mbp_init);
109module_exit(mbp_exit);
110
111MODULE_AUTHOR("Matthew Garrett <mjg@redhat.com>");
112MODULE_DESCRIPTION("Nvidia-based Macbook Pro Backlight Driver");
113MODULE_LICENSE("GPL");
114MODULE_ALIAS("svnAppleInc.:pnMacBookPro3,1");
115MODULE_ALIAS("svnAppleInc.:pnMacBookPro3,2");
116MODULE_ALIAS("svnAppleInc.:pnMacBookPro4,1");
diff --git a/drivers/video/backlight/platform_lcd.c b/drivers/video/backlight/platform_lcd.c
new file mode 100644
index 000000000000..72d44dbfce82
--- /dev/null
+++ b/drivers/video/backlight/platform_lcd.c
@@ -0,0 +1,172 @@
1/* drivers/video/backlight/platform_lcd.c
2 *
3 * Copyright 2008 Simtec Electronics
4 * Ben Dooks <ben@simtec.co.uk>
5 *
6 * Generic platform-device LCD power control interface.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 *
12*/
13
14#include <linux/module.h>
15#include <linux/platform_device.h>
16#include <linux/fb.h>
17#include <linux/backlight.h>
18#include <linux/lcd.h>
19
20#include <video/platform_lcd.h>
21
22struct platform_lcd {
23 struct device *us;
24 struct lcd_device *lcd;
25 struct plat_lcd_data *pdata;
26
27 unsigned int power;
28 unsigned int suspended : 1;
29};
30
31static inline struct platform_lcd *to_our_lcd(struct lcd_device *lcd)
32{
33 return lcd_get_data(lcd);
34}
35
36static int platform_lcd_get_power(struct lcd_device *lcd)
37{
38 struct platform_lcd *plcd = to_our_lcd(lcd);
39
40 return plcd->power;
41}
42
43static int platform_lcd_set_power(struct lcd_device *lcd, int power)
44{
45 struct platform_lcd *plcd = to_our_lcd(lcd);
46 int lcd_power = 1;
47
48 if (power == FB_BLANK_POWERDOWN || plcd->suspended)
49 lcd_power = 0;
50
51 plcd->pdata->set_power(plcd->pdata, lcd_power);
52 plcd->power = power;
53
54 return 0;
55}
56
57static int platform_lcd_match(struct lcd_device *lcd, struct fb_info *info)
58{
59 struct platform_lcd *plcd = to_our_lcd(lcd);
60 struct plat_lcd_data *pdata = plcd->pdata;
61
62 if (pdata->match_fb)
63 return pdata->match_fb(pdata, info);
64
65 return plcd->us->parent == info->device;
66}
67
68static struct lcd_ops platform_lcd_ops = {
69 .get_power = platform_lcd_get_power,
70 .set_power = platform_lcd_set_power,
71 .check_fb = platform_lcd_match,
72};
73
74static int __devinit platform_lcd_probe(struct platform_device *pdev)
75{
76 struct plat_lcd_data *pdata;
77 struct platform_lcd *plcd;
78 struct device *dev = &pdev->dev;
79 int err;
80
81 pdata = pdev->dev.platform_data;
82 if (!pdata) {
83 dev_err(dev, "no platform data supplied\n");
84 return -EINVAL;
85 }
86
87 plcd = kzalloc(sizeof(struct platform_lcd), GFP_KERNEL);
88 if (!plcd) {
89 dev_err(dev, "no memory for state\n");
90 return -ENOMEM;
91 }
92
93 plcd->us = dev;
94 plcd->pdata = pdata;
95 plcd->lcd = lcd_device_register("platform-lcd", dev,
96 plcd, &platform_lcd_ops);
97 if (IS_ERR(plcd->lcd)) {
98 dev_err(dev, "cannot register lcd device\n");
99 err = PTR_ERR(plcd->lcd);
100 goto err_mem;
101 }
102
103 platform_set_drvdata(pdev, plcd);
104 return 0;
105
106 err_mem:
107 kfree(plcd);
108 return err;
109}
110
111static int __devexit platform_lcd_remove(struct platform_device *pdev)
112{
113 struct platform_lcd *plcd = platform_get_drvdata(pdev);
114
115 lcd_device_unregister(plcd->lcd);
116 kfree(plcd);
117
118 return 0;
119}
120
121#ifdef CONFIG_PM
122static int platform_lcd_suspend(struct platform_device *pdev, pm_message_t st)
123{
124 struct platform_lcd *plcd = platform_get_drvdata(pdev);
125
126 plcd->suspended = 1;
127 platform_lcd_set_power(plcd->lcd, plcd->power);
128
129 return 0;
130}
131
132static int platform_lcd_resume(struct platform_device *pdev)
133{
134 struct platform_lcd *plcd = platform_get_drvdata(pdev);
135
136 plcd->suspended = 0;
137 platform_lcd_set_power(plcd->lcd, plcd->power);
138
139 return 0;
140}
141#else
142#define platform_lcd_suspend NULL
143#define platform_lcd_resume NULL
144#endif
145
146static struct platform_driver platform_lcd_driver = {
147 .driver = {
148 .name = "platform-lcd",
149 .owner = THIS_MODULE,
150 },
151 .probe = platform_lcd_probe,
152 .remove = __devexit_p(platform_lcd_remove),
153 .suspend = platform_lcd_suspend,
154 .resume = platform_lcd_resume,
155};
156
157static int __init platform_lcd_init(void)
158{
159 return platform_driver_register(&platform_lcd_driver);
160}
161
162static void __exit platform_lcd_cleanup(void)
163{
164 platform_driver_unregister(&platform_lcd_driver);
165}
166
167module_init(platform_lcd_init);
168module_exit(platform_lcd_cleanup);
169
170MODULE_AUTHOR("Ben Dooks <ben-linux@fluff.org>");
171MODULE_LICENSE("GPL v2");
172MODULE_ALIAS("platform:platform-lcd");
diff --git a/drivers/video/backlight/vgg2432a4.c b/drivers/video/backlight/vgg2432a4.c
new file mode 100644
index 000000000000..593c7687d54a
--- /dev/null
+++ b/drivers/video/backlight/vgg2432a4.c
@@ -0,0 +1,284 @@
1/* drivers/video/backlight/vgg2432a4.c
2 *
3 * VGG2432A4 (ILI9320) LCD controller driver.
4 *
5 * Copyright 2007 Simtec Electronics
6 * http://armlinux.simtec.co.uk/
7 * Ben Dooks <ben@simtec.co.uk>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12*/
13
14#include <linux/delay.h>
15#include <linux/err.h>
16#include <linux/fb.h>
17#include <linux/init.h>
18#include <linux/lcd.h>
19#include <linux/module.h>
20
21#include <linux/spi/spi.h>
22
23#include <video/ili9320.h>
24
25#include "ili9320.h"
26
27/* Device initialisation sequences */
28
29static struct ili9320_reg vgg_init1[] = {
30 {
31 .address = ILI9320_POWER1,
32 .value = ILI9320_POWER1_AP(0) | ILI9320_POWER1_BT(0),
33 }, {
34 .address = ILI9320_POWER2,
35 .value = (ILI9320_POWER2_VC(7) |
36 ILI9320_POWER2_DC0(0) | ILI9320_POWER2_DC1(0)),
37 }, {
38 .address = ILI9320_POWER3,
39 .value = ILI9320_POWER3_VRH(0),
40 }, {
41 .address = ILI9320_POWER4,
42 .value = ILI9320_POWER4_VREOUT(0),
43 },
44};
45
46static struct ili9320_reg vgg_init2[] = {
47 {
48 .address = ILI9320_POWER1,
49 .value = (ILI9320_POWER1_AP(3) | ILI9320_POWER1_APE |
50 ILI9320_POWER1_BT(7) | ILI9320_POWER1_SAP),
51 }, {
52 .address = ILI9320_POWER2,
53 .value = ILI9320_POWER2_VC(7) | ILI9320_POWER2_DC0(3),
54 }
55};
56
57static struct ili9320_reg vgg_gamma[] = {
58 {
59 .address = ILI9320_GAMMA1,
60 .value = 0x0000,
61 }, {
62 .address = ILI9320_GAMMA2,
63 .value = 0x0505,
64 }, {
65 .address = ILI9320_GAMMA3,
66 .value = 0x0004,
67 }, {
68 .address = ILI9320_GAMMA4,
69 .value = 0x0006,
70 }, {
71 .address = ILI9320_GAMMA5,
72 .value = 0x0707,
73 }, {
74 .address = ILI9320_GAMMA6,
75 .value = 0x0105,
76 }, {
77 .address = ILI9320_GAMMA7,
78 .value = 0x0002,
79 }, {
80 .address = ILI9320_GAMMA8,
81 .value = 0x0707,
82 }, {
83 .address = ILI9320_GAMMA9,
84 .value = 0x0704,
85 }, {
86 .address = ILI9320_GAMMA10,
87 .value = 0x807,
88 }
89
90};
91
92static struct ili9320_reg vgg_init0[] = {
93 [0] = {
94 /* set direction and scan mode gate */
95 .address = ILI9320_DRIVER,
96 .value = ILI9320_DRIVER_SS,
97 }, {
98 .address = ILI9320_DRIVEWAVE,
99 .value = (ILI9320_DRIVEWAVE_MUSTSET |
100 ILI9320_DRIVEWAVE_EOR | ILI9320_DRIVEWAVE_BC),
101 }, {
102 .address = ILI9320_ENTRYMODE,
103 .value = ILI9320_ENTRYMODE_ID(3) | ILI9320_ENTRYMODE_BGR,
104 }, {
105 .address = ILI9320_RESIZING,
106 .value = 0x0,
107 },
108};
109
110
111static int vgg2432a4_lcd_init(struct ili9320 *lcd,
112 struct ili9320_platdata *cfg)
113{
114 unsigned int addr;
115 int ret;
116
117 /* Set VCore before anything else (VGG243237-6UFLWA) */
118 ret = ili9320_write(lcd, 0x00e5, 0x8000);
119 if (ret)
120 goto err_initial;
121
122 /* Start the oscillator up before we can do anything else. */
123 ret = ili9320_write(lcd, ILI9320_OSCILATION, ILI9320_OSCILATION_OSC);
124 if (ret)
125 goto err_initial;
126
127 /* must wait at-lesat 10ms after starting */
128 mdelay(15);
129
130 ret = ili9320_write_regs(lcd, vgg_init0, ARRAY_SIZE(vgg_init0));
131 if (ret != 0)
132 goto err_initial;
133
134 ili9320_write(lcd, ILI9320_DISPLAY2, cfg->display2);
135 ili9320_write(lcd, ILI9320_DISPLAY3, cfg->display3);
136 ili9320_write(lcd, ILI9320_DISPLAY4, cfg->display4);
137
138 ili9320_write(lcd, ILI9320_RGB_IF1, cfg->rgb_if1);
139 ili9320_write(lcd, ILI9320_FRAMEMAKER, 0x0);
140 ili9320_write(lcd, ILI9320_RGB_IF2, ILI9320_RGBIF2_DPL);
141
142 ret = ili9320_write_regs(lcd, vgg_init1, ARRAY_SIZE(vgg_init1));
143 if (ret != 0)
144 goto err_vgg;
145
146 mdelay(300);
147
148 ret = ili9320_write_regs(lcd, vgg_init2, ARRAY_SIZE(vgg_init2));
149 if (ret != 0)
150 goto err_vgg2;
151
152 mdelay(100);
153
154 ili9320_write(lcd, ILI9320_POWER3, 0x13c);
155
156 mdelay(100);
157
158 ili9320_write(lcd, ILI9320_POWER4, 0x1c00);
159 ili9320_write(lcd, ILI9320_POWER7, 0x000e);
160
161 mdelay(100);
162
163 ili9320_write(lcd, ILI9320_GRAM_HORIZ_ADDR, 0x00);
164 ili9320_write(lcd, ILI9320_GRAM_VERT_ADD, 0x00);
165
166 ret = ili9320_write_regs(lcd, vgg_gamma, ARRAY_SIZE(vgg_gamma));
167 if (ret != 0)
168 goto err_vgg3;
169
170 ili9320_write(lcd, ILI9320_HORIZ_START, 0x0);
171 ili9320_write(lcd, ILI9320_HORIZ_END, cfg->hsize - 1);
172 ili9320_write(lcd, ILI9320_VERT_START, 0x0);
173 ili9320_write(lcd, ILI9320_VERT_END, cfg->vsize - 1);
174
175 ili9320_write(lcd, ILI9320_DRIVER2,
176 ILI9320_DRIVER2_NL(((cfg->vsize - 240) / 8) + 0x1D));
177
178 ili9320_write(lcd, ILI9320_BASE_IMAGE, 0x1);
179 ili9320_write(lcd, ILI9320_VERT_SCROLL, 0x00);
180
181 for (addr = ILI9320_PARTIAL1_POSITION; addr <= ILI9320_PARTIAL2_END;
182 addr++) {
183 ili9320_write(lcd, addr, 0x0);
184 }
185
186 ili9320_write(lcd, ILI9320_INTERFACE1, 0x10);
187 ili9320_write(lcd, ILI9320_INTERFACE2, cfg->interface2);
188 ili9320_write(lcd, ILI9320_INTERFACE3, cfg->interface3);
189 ili9320_write(lcd, ILI9320_INTERFACE4, cfg->interface4);
190 ili9320_write(lcd, ILI9320_INTERFACE5, cfg->interface5);
191 ili9320_write(lcd, ILI9320_INTERFACE6, cfg->interface6);
192
193 lcd->display1 = (ILI9320_DISPLAY1_D(3) | ILI9320_DISPLAY1_DTE |
194 ILI9320_DISPLAY1_GON | ILI9320_DISPLAY1_BASEE |
195 0x40);
196
197 ili9320_write(lcd, ILI9320_DISPLAY1, lcd->display1);
198
199 return 0;
200
201 err_vgg3:
202 err_vgg2:
203 err_vgg:
204 err_initial:
205 return ret;
206}
207
208#ifdef CONFIG_PM
209static int vgg2432a4_suspend(struct spi_device *spi, pm_message_t state)
210{
211 return ili9320_suspend(dev_get_drvdata(&spi->dev), state);
212}
213
214static int vgg2432a4_resume(struct spi_device *spi)
215{
216 return ili9320_resume(dev_get_drvdata(&spi->dev));
217}
218#else
219#define vgg2432a4_suspend NULL
220#define vgg2432a4_resume NULL
221#endif
222
223static struct ili9320_client vgg2432a4_client = {
224 .name = "VGG2432A4",
225 .init = vgg2432a4_lcd_init,
226};
227
228/* Device probe */
229
230static int __devinit vgg2432a4_probe(struct spi_device *spi)
231{
232 int ret;
233
234 ret = ili9320_probe_spi(spi, &vgg2432a4_client);
235 if (ret != 0) {
236 dev_err(&spi->dev, "failed to initialise ili9320\n");
237 return ret;
238 }
239
240 return 0;
241}
242
243static int __devexit vgg2432a4_remove(struct spi_device *spi)
244{
245 return ili9320_remove(dev_get_drvdata(&spi->dev));
246}
247
248static void vgg2432a4_shutdown(struct spi_device *spi)
249{
250 ili9320_shutdown(dev_get_drvdata(&spi->dev));
251}
252
253static struct spi_driver vgg2432a4_driver = {
254 .driver = {
255 .name = "VGG2432A4",
256 .owner = THIS_MODULE,
257 },
258 .probe = vgg2432a4_probe,
259 .remove = __devexit_p(vgg2432a4_remove),
260 .shutdown = vgg2432a4_shutdown,
261 .suspend = vgg2432a4_suspend,
262 .resume = vgg2432a4_resume,
263};
264
265/* Device driver initialisation */
266
267static int __init vgg2432a4_init(void)
268{
269 return spi_register_driver(&vgg2432a4_driver);
270}
271
272static void __exit vgg2432a4_exit(void)
273{
274 spi_unregister_driver(&vgg2432a4_driver);
275}
276
277module_init(vgg2432a4_init);
278module_exit(vgg2432a4_exit);
279
280MODULE_AUTHOR("Ben Dooks <ben-linux@fluff.org>");
281MODULE_DESCRIPTION("VGG2432A4 LCD Driver");
282MODULE_LICENSE("GPL v2");
283
284
diff --git a/drivers/video/bf54x-lq043fb.c b/drivers/video/bf54x-lq043fb.c
index 49834a67a623..940467aed13f 100644
--- a/drivers/video/bf54x-lq043fb.c
+++ b/drivers/video/bf54x-lq043fb.c
@@ -478,7 +478,7 @@ static int bfin_lcd_set_contrast(struct lcd_device *dev, int contrast)
478 return 0; 478 return 0;
479} 479}
480 480
481static int bfin_lcd_check_fb(struct fb_info *fi) 481static int bfin_lcd_check_fb(struct lcd_device *dev, struct fb_info *fi)
482{ 482{
483 if (!fi || (fi == &bfin_bf54x_fb)) 483 if (!fi || (fi == &bfin_bf54x_fb))
484 return 1; 484 return 1;
diff --git a/drivers/video/bfin-t350mcqb-fb.c b/drivers/video/bfin-t350mcqb-fb.c
index 135d6dd7e672..7d1b819e501c 100644
--- a/drivers/video/bfin-t350mcqb-fb.c
+++ b/drivers/video/bfin-t350mcqb-fb.c
@@ -396,7 +396,7 @@ static int bfin_lcd_set_contrast(struct lcd_device *dev, int contrast)
396 return 0; 396 return 0;
397} 397}
398 398
399static int bfin_lcd_check_fb(struct fb_info *fi) 399static int bfin_lcd_check_fb(struct lcd_device *dev, struct fb_info *fi)
400{ 400{
401 if (!fi || (fi == &bfin_t350mcqb_fb)) 401 if (!fi || (fi == &bfin_t350mcqb_fb))
402 return 1; 402 return 1;
diff --git a/drivers/video/carminefb.c b/drivers/video/carminefb.c
new file mode 100644
index 000000000000..e15bb447440a
--- /dev/null
+++ b/drivers/video/carminefb.c
@@ -0,0 +1,790 @@
1/*
2 * Frame buffer driver for the Carmine GPU.
3 *
4 * The driver configures the GPU as follows
5 * - FB0 is display 0 with unique memory area
6 * - FB1 is display 1 with unique memory area
7 * - both display use 32 bit colors
8 */
9#include <linux/delay.h>
10#include <linux/errno.h>
11#include <linux/fb.h>
12#include <linux/interrupt.h>
13#include <linux/pci.h>
14
15#include "carminefb.h"
16#include "carminefb_regs.h"
17
18#if !defined(__LITTLE_ENDIAN) && !defined(__BIG_ENDIAN)
19#error "The endianness of the target host has not been defined."
20#endif
21
22/*
23 * The initial video mode can be supplied via two different ways:
24 * - as a string that is passed to fb_find_mode() (module option fb_mode_str)
25 * - as an integer that picks the video mode from carmine_modedb[] (module
26 * option fb_mode)
27 *
28 * If nothing is used than the initial video mode will be the
29 * CARMINEFB_DEFAULT_VIDEO_MODE member of the carmine_modedb[].
30 */
31#define CARMINEFB_DEFAULT_VIDEO_MODE 1
32
33static unsigned int fb_mode = CARMINEFB_DEFAULT_VIDEO_MODE;
34module_param(fb_mode, uint, 444);
35MODULE_PARM_DESC(fb_mode, "Initial video mode as integer.");
36
37static char *fb_mode_str;
38module_param(fb_mode_str, charp, 444);
39MODULE_PARM_DESC(fb_mode_str, "Initial video mode in characters.");
40
41/*
42 * Carminefb displays:
43 * 0b000 None
44 * 0b001 Display 0
45 * 0b010 Display 1
46 */
47static int fb_displays = CARMINE_USE_DISPLAY0 | CARMINE_USE_DISPLAY1;
48module_param(fb_displays, int, 444);
49MODULE_PARM_DESC(fb_displays, "Bit mode, which displays are used");
50
51struct carmine_hw {
52 void __iomem *v_regs;
53 void __iomem *screen_mem;
54 struct fb_info *fb[MAX_DISPLAY];
55};
56
57struct carmine_resolution {
58 u32 htp;
59 u32 hsp;
60 u32 hsw;
61 u32 hdp;
62 u32 vtr;
63 u32 vsp;
64 u32 vsw;
65 u32 vdp;
66 u32 disp_mode;
67};
68
69struct carmine_fb {
70 void __iomem *display_reg;
71 void __iomem *screen_base;
72 u32 smem_offset;
73 u32 cur_mode;
74 u32 new_mode;
75 struct carmine_resolution *res;
76 u32 pseudo_palette[16];
77};
78
79static struct fb_fix_screeninfo carminefb_fix __devinitdata = {
80 .id = "Carmine",
81 .type = FB_TYPE_PACKED_PIXELS,
82 .visual = FB_VISUAL_TRUECOLOR,
83 .accel = FB_ACCEL_NONE,
84};
85
86static const struct fb_videomode carmine_modedb[] = {
87 {
88 .name = "640x480",
89 .xres = 640,
90 .yres = 480,
91 }, {
92 .name = "800x600",
93 .xres = 800,
94 .yres = 600,
95 },
96};
97
98static struct carmine_resolution car_modes[] = {
99 {
100 /* 640x480 */
101 .htp = 800,
102 .hsp = 672,
103 .hsw = 96,
104 .hdp = 640,
105 .vtr = 525,
106 .vsp = 490,
107 .vsw = 2,
108 .vdp = 480,
109 .disp_mode = 0x1400,
110 },
111 {
112 /* 800x600 */
113 .htp = 1060,
114 .hsp = 864,
115 .hsw = 72,
116 .hdp = 800,
117 .vtr = 628,
118 .vsp = 601,
119 .vsw = 2,
120 .vdp = 600,
121 .disp_mode = 0x0d00,
122 }
123};
124
125static int carmine_find_mode(const struct fb_var_screeninfo *var)
126{
127 int i;
128
129 for (i = 0; i < ARRAY_SIZE(car_modes); i++)
130 if (car_modes[i].hdp == var->xres &&
131 car_modes[i].vdp == var->yres)
132 return i;
133 return -EINVAL;
134}
135
136static void c_set_disp_reg(const struct carmine_fb *par,
137 u32 offset, u32 val)
138{
139 writel(val, par->display_reg + offset);
140}
141
142static u32 c_get_disp_reg(const struct carmine_fb *par,
143 u32 offset)
144{
145 return readl(par->display_reg + offset);
146}
147
148static void c_set_hw_reg(const struct carmine_hw *hw,
149 u32 offset, u32 val)
150{
151 writel(val, hw->v_regs + offset);
152}
153
154static u32 c_get_hw_reg(const struct carmine_hw *hw,
155 u32 offset)
156{
157 return readl(hw->v_regs + offset);
158}
159
160static int carmine_setcolreg(unsigned regno, unsigned red, unsigned green,
161 unsigned blue, unsigned transp, struct fb_info *info)
162{
163 if (regno >= 16)
164 return 1;
165
166 red >>= 8;
167 green >>= 8;
168 blue >>= 8;
169 transp >>= 8;
170
171 ((u32 *)info->pseudo_palette)[regno] = be32_to_cpu(transp << 24 |
172 red << 0 | green << 8 | blue << 16);
173 return 0;
174}
175
176static int carmine_check_var(struct fb_var_screeninfo *var,
177 struct fb_info *info)
178{
179 int ret;
180
181 ret = carmine_find_mode(var);
182 if (ret < 0)
183 return ret;
184
185 if (var->grayscale || var->rotate || var->nonstd)
186 return -EINVAL;
187
188 var->xres_virtual = var->xres;
189 var->yres_virtual = var->yres;
190
191 var->bits_per_pixel = 32;
192
193#ifdef __BIG_ENDIAN
194 var->transp.offset = 24;
195 var->red.offset = 0;
196 var->green.offset = 8;
197 var->blue.offset = 16;
198#else
199 var->transp.offset = 24;
200 var->red.offset = 16;
201 var->green.offset = 8;
202 var->blue.offset = 0;
203#endif
204
205 var->red.length = 8;
206 var->green.length = 8;
207 var->blue.length = 8;
208 var->transp.length = 8;
209
210 var->red.msb_right = 0;
211 var->green.msb_right = 0;
212 var->blue.msb_right = 0;
213 var->transp.msb_right = 0;
214 return 0;
215}
216
217static void carmine_init_display_param(struct carmine_fb *par)
218{
219 u32 width;
220 u32 height;
221 u32 param;
222 u32 window_size;
223 u32 soffset = par->smem_offset;
224
225 c_set_disp_reg(par, CARMINE_DISP_REG_C_TRANS, 0);
226 c_set_disp_reg(par, CARMINE_DISP_REG_MLMR_TRANS, 0);
227 c_set_disp_reg(par, CARMINE_DISP_REG_CURSOR_MODE,
228 CARMINE_CURSOR0_PRIORITY_MASK |
229 CARMINE_CURSOR1_PRIORITY_MASK |
230 CARMINE_CURSOR_CUTZ_MASK);
231
232 /* Set default cursor position */
233 c_set_disp_reg(par, CARMINE_DISP_REG_CUR1_POS, 0 << 16 | 0);
234 c_set_disp_reg(par, CARMINE_DISP_REG_CUR2_POS, 0 << 16 | 0);
235
236 /* Set default display mode */
237 c_set_disp_reg(par, CARMINE_DISP_REG_L0_EXT_MODE, CARMINE_WINDOW_MODE |
238 CARMINE_EXT_CMODE_DIRECT24_RGBA);
239 c_set_disp_reg(par, CARMINE_DISP_REG_L1_EXT_MODE,
240 CARMINE_EXT_CMODE_DIRECT24_RGBA);
241 c_set_disp_reg(par, CARMINE_DISP_REG_L2_EXT_MODE, CARMINE_EXTEND_MODE |
242 CARMINE_EXT_CMODE_DIRECT24_RGBA);
243 c_set_disp_reg(par, CARMINE_DISP_REG_L3_EXT_MODE, CARMINE_EXTEND_MODE |
244 CARMINE_EXT_CMODE_DIRECT24_RGBA);
245 c_set_disp_reg(par, CARMINE_DISP_REG_L4_EXT_MODE, CARMINE_EXTEND_MODE |
246 CARMINE_EXT_CMODE_DIRECT24_RGBA);
247 c_set_disp_reg(par, CARMINE_DISP_REG_L5_EXT_MODE, CARMINE_EXTEND_MODE |
248 CARMINE_EXT_CMODE_DIRECT24_RGBA);
249 c_set_disp_reg(par, CARMINE_DISP_REG_L6_EXT_MODE, CARMINE_EXTEND_MODE |
250 CARMINE_EXT_CMODE_DIRECT24_RGBA);
251 c_set_disp_reg(par, CARMINE_DISP_REG_L7_EXT_MODE, CARMINE_EXTEND_MODE |
252 CARMINE_EXT_CMODE_DIRECT24_RGBA);
253
254 /* Set default frame size to layer mode register */
255 width = par->res->hdp * 4 / CARMINE_DISP_WIDTH_UNIT;
256 width = width << CARMINE_DISP_WIDTH_SHIFT;
257
258 height = par->res->vdp - 1;
259 param = width | height;
260
261 c_set_disp_reg(par, CARMINE_DISP_REG_L0_MODE_W_H, param);
262 c_set_disp_reg(par, CARMINE_DISP_REG_L1_WIDTH, width);
263 c_set_disp_reg(par, CARMINE_DISP_REG_L2_MODE_W_H, param);
264 c_set_disp_reg(par, CARMINE_DISP_REG_L3_MODE_W_H, param);
265 c_set_disp_reg(par, CARMINE_DISP_REG_L4_MODE_W_H, param);
266 c_set_disp_reg(par, CARMINE_DISP_REG_L5_MODE_W_H, param);
267 c_set_disp_reg(par, CARMINE_DISP_REG_L6_MODE_W_H, param);
268 c_set_disp_reg(par, CARMINE_DISP_REG_L7_MODE_W_H, param);
269
270 /* Set default pos and size */
271 window_size = (par->res->vdp - 1) << CARMINE_DISP_WIN_H_SHIFT;
272 window_size |= par->res->hdp;
273
274 c_set_disp_reg(par, CARMINE_DISP_REG_L0_WIN_POS, 0);
275 c_set_disp_reg(par, CARMINE_DISP_REG_L0_WIN_SIZE, window_size);
276 c_set_disp_reg(par, CARMINE_DISP_REG_L1_WIN_POS, 0);
277 c_set_disp_reg(par, CARMINE_DISP_REG_L1_WIN_SIZE, window_size);
278 c_set_disp_reg(par, CARMINE_DISP_REG_L2_WIN_POS, 0);
279 c_set_disp_reg(par, CARMINE_DISP_REG_L2_WIN_SIZE, window_size);
280 c_set_disp_reg(par, CARMINE_DISP_REG_L3_WIN_POS, 0);
281 c_set_disp_reg(par, CARMINE_DISP_REG_L3_WIN_SIZE, window_size);
282 c_set_disp_reg(par, CARMINE_DISP_REG_L4_WIN_POS, 0);
283 c_set_disp_reg(par, CARMINE_DISP_REG_L4_WIN_SIZE, window_size);
284 c_set_disp_reg(par, CARMINE_DISP_REG_L5_WIN_POS, 0);
285 c_set_disp_reg(par, CARMINE_DISP_REG_L5_WIN_SIZE, window_size);
286 c_set_disp_reg(par, CARMINE_DISP_REG_L6_WIN_POS, 0);
287 c_set_disp_reg(par, CARMINE_DISP_REG_L6_WIN_SIZE, window_size);
288 c_set_disp_reg(par, CARMINE_DISP_REG_L7_WIN_POS, 0);
289 c_set_disp_reg(par, CARMINE_DISP_REG_L7_WIN_SIZE, window_size);
290
291 /* Set default origin address */
292 c_set_disp_reg(par, CARMINE_DISP_REG_L0_ORG_ADR, soffset);
293 c_set_disp_reg(par, CARMINE_DISP_REG_L1_ORG_ADR, soffset);
294 c_set_disp_reg(par, CARMINE_DISP_REG_L2_ORG_ADR1, soffset);
295 c_set_disp_reg(par, CARMINE_DISP_REG_L3_ORG_ADR1, soffset);
296 c_set_disp_reg(par, CARMINE_DISP_REG_L4_ORG_ADR1, soffset);
297 c_set_disp_reg(par, CARMINE_DISP_REG_L5_ORG_ADR1, soffset);
298 c_set_disp_reg(par, CARMINE_DISP_REG_L6_ORG_ADR1, soffset);
299 c_set_disp_reg(par, CARMINE_DISP_REG_L7_ORG_ADR1, soffset);
300
301 /* Set default display address */
302 c_set_disp_reg(par, CARMINE_DISP_REG_L0_DISP_ADR, soffset);
303 c_set_disp_reg(par, CARMINE_DISP_REG_L2_DISP_ADR1, soffset);
304 c_set_disp_reg(par, CARMINE_DISP_REG_L3_DISP_ADR1, soffset);
305 c_set_disp_reg(par, CARMINE_DISP_REG_L4_DISP_ADR1, soffset);
306 c_set_disp_reg(par, CARMINE_DISP_REG_L5_DISP_ADR1, soffset);
307 c_set_disp_reg(par, CARMINE_DISP_REG_L6_DISP_ADR0, soffset);
308 c_set_disp_reg(par, CARMINE_DISP_REG_L7_DISP_ADR0, soffset);
309
310 /* Set default display position */
311 c_set_disp_reg(par, CARMINE_DISP_REG_L0_DISP_POS, 0);
312 c_set_disp_reg(par, CARMINE_DISP_REG_L2_DISP_POS, 0);
313 c_set_disp_reg(par, CARMINE_DISP_REG_L3_DISP_POS, 0);
314 c_set_disp_reg(par, CARMINE_DISP_REG_L4_DISP_POS, 0);
315 c_set_disp_reg(par, CARMINE_DISP_REG_L5_DISP_POS, 0);
316 c_set_disp_reg(par, CARMINE_DISP_REG_L6_DISP_POS, 0);
317 c_set_disp_reg(par, CARMINE_DISP_REG_L7_DISP_POS, 0);
318
319 /* Set default blend mode */
320 c_set_disp_reg(par, CARMINE_DISP_REG_BLEND_MODE_L0, 0);
321 c_set_disp_reg(par, CARMINE_DISP_REG_BLEND_MODE_L1, 0);
322 c_set_disp_reg(par, CARMINE_DISP_REG_BLEND_MODE_L2, 0);
323 c_set_disp_reg(par, CARMINE_DISP_REG_BLEND_MODE_L3, 0);
324 c_set_disp_reg(par, CARMINE_DISP_REG_BLEND_MODE_L4, 0);
325 c_set_disp_reg(par, CARMINE_DISP_REG_BLEND_MODE_L5, 0);
326 c_set_disp_reg(par, CARMINE_DISP_REG_BLEND_MODE_L6, 0);
327 c_set_disp_reg(par, CARMINE_DISP_REG_BLEND_MODE_L7, 0);
328
329 /* default transparency mode */
330 c_set_disp_reg(par, CARMINE_DISP_REG_L0_TRANS, 0);
331 c_set_disp_reg(par, CARMINE_DISP_REG_L1_TRANS, 0);
332 c_set_disp_reg(par, CARMINE_DISP_REG_L2_TRANS, 0);
333 c_set_disp_reg(par, CARMINE_DISP_REG_L3_TRANS, 0);
334 c_set_disp_reg(par, CARMINE_DISP_REG_L4_TRANS, 0);
335 c_set_disp_reg(par, CARMINE_DISP_REG_L5_TRANS, 0);
336 c_set_disp_reg(par, CARMINE_DISP_REG_L6_TRANS, 0);
337 c_set_disp_reg(par, CARMINE_DISP_REG_L7_TRANS, 0);
338
339 /* Set default read skip parameter */
340 c_set_disp_reg(par, CARMINE_DISP_REG_L0RM, 0);
341 c_set_disp_reg(par, CARMINE_DISP_REG_L2RM, 0);
342 c_set_disp_reg(par, CARMINE_DISP_REG_L3RM, 0);
343 c_set_disp_reg(par, CARMINE_DISP_REG_L4RM, 0);
344 c_set_disp_reg(par, CARMINE_DISP_REG_L5RM, 0);
345 c_set_disp_reg(par, CARMINE_DISP_REG_L6RM, 0);
346 c_set_disp_reg(par, CARMINE_DISP_REG_L7RM, 0);
347
348 c_set_disp_reg(par, CARMINE_DISP_REG_L0PX, 0);
349 c_set_disp_reg(par, CARMINE_DISP_REG_L2PX, 0);
350 c_set_disp_reg(par, CARMINE_DISP_REG_L3PX, 0);
351 c_set_disp_reg(par, CARMINE_DISP_REG_L4PX, 0);
352 c_set_disp_reg(par, CARMINE_DISP_REG_L5PX, 0);
353 c_set_disp_reg(par, CARMINE_DISP_REG_L6PX, 0);
354 c_set_disp_reg(par, CARMINE_DISP_REG_L7PX, 0);
355
356 c_set_disp_reg(par, CARMINE_DISP_REG_L0PY, 0);
357 c_set_disp_reg(par, CARMINE_DISP_REG_L2PY, 0);
358 c_set_disp_reg(par, CARMINE_DISP_REG_L3PY, 0);
359 c_set_disp_reg(par, CARMINE_DISP_REG_L4PY, 0);
360 c_set_disp_reg(par, CARMINE_DISP_REG_L5PY, 0);
361 c_set_disp_reg(par, CARMINE_DISP_REG_L6PY, 0);
362 c_set_disp_reg(par, CARMINE_DISP_REG_L7PY, 0);
363}
364
365static void set_display_parameters(struct carmine_fb *par)
366{
367 u32 mode;
368 u32 hdp, vdp, htp, hsp, hsw, vtr, vsp, vsw;
369
370 /*
371 * display timing. Parameters are decreased by one because hardware
372 * spec is 0 to (n - 1)
373 * */
374 hdp = par->res->hdp - 1;
375 vdp = par->res->vdp - 1;
376 htp = par->res->htp - 1;
377 hsp = par->res->hsp - 1;
378 hsw = par->res->hsw - 1;
379 vtr = par->res->vtr - 1;
380 vsp = par->res->vsp - 1;
381 vsw = par->res->vsw - 1;
382
383 c_set_disp_reg(par, CARMINE_DISP_REG_H_TOTAL,
384 htp << CARMINE_DISP_HTP_SHIFT);
385 c_set_disp_reg(par, CARMINE_DISP_REG_H_PERIOD,
386 (hdp << CARMINE_DISP_HDB_SHIFT) | hdp);
387 c_set_disp_reg(par, CARMINE_DISP_REG_V_H_W_H_POS,
388 (vsw << CARMINE_DISP_VSW_SHIFT) |
389 (hsw << CARMINE_DISP_HSW_SHIFT) |
390 (hsp));
391 c_set_disp_reg(par, CARMINE_DISP_REG_V_TOTAL,
392 vtr << CARMINE_DISP_VTR_SHIFT);
393 c_set_disp_reg(par, CARMINE_DISP_REG_V_PERIOD_POS,
394 (vdp << CARMINE_DISP_VDP_SHIFT) | vsp);
395
396 /* clock */
397 mode = c_get_disp_reg(par, CARMINE_DISP_REG_DCM1);
398 mode = (mode & ~CARMINE_DISP_DCM_MASK) |
399 (par->res->disp_mode & CARMINE_DISP_DCM_MASK);
400 /* enable video output and layer 0 */
401 mode |= CARMINE_DEN | CARMINE_L0E;
402 c_set_disp_reg(par, CARMINE_DISP_REG_DCM1, mode);
403}
404
405static int carmine_set_par(struct fb_info *info)
406{
407 struct carmine_fb *par = info->par;
408 int ret;
409
410 ret = carmine_find_mode(&info->var);
411 if (ret < 0)
412 return ret;
413
414 par->new_mode = ret;
415 if (par->cur_mode != par->new_mode) {
416
417 par->cur_mode = par->new_mode;
418 par->res = &car_modes[par->new_mode];
419
420 carmine_init_display_param(par);
421 set_display_parameters(par);
422 }
423
424 info->fix.line_length = info->var.xres * info->var.bits_per_pixel / 8;
425 return 0;
426}
427
428static int init_hardware(struct carmine_hw *hw)
429{
430 u32 flags;
431 u32 loops;
432 u32 ret;
433
434 /* Initalize Carmine */
435 /* Sets internal clock */
436 c_set_hw_reg(hw, CARMINE_CTL_REG + CARMINE_CTL_REG_CLOCK_ENABLE,
437 CARMINE_DFLT_IP_CLOCK_ENABLE);
438
439 /* Video signal output is turned off */
440 c_set_hw_reg(hw, CARMINE_DISP0_REG + CARMINE_DISP_REG_DCM1, 0);
441 c_set_hw_reg(hw, CARMINE_DISP1_REG + CARMINE_DISP_REG_DCM1, 0);
442
443 /* Software reset */
444 c_set_hw_reg(hw, CARMINE_CTL_REG + CARMINE_CTL_REG_SOFTWARE_RESET, 1);
445 c_set_hw_reg(hw, CARMINE_CTL_REG + CARMINE_CTL_REG_SOFTWARE_RESET, 0);
446
447 /* I/O mode settings */
448 flags = CARMINE_DFLT_IP_DCTL_IO_CONT1 << 16 |
449 CARMINE_DFLT_IP_DCTL_IO_CONT0;
450 c_set_hw_reg(hw, CARMINE_DCTL_REG + CARMINE_DCTL_REG_IOCONT1_IOCONT0,
451 flags);
452
453 /* DRAM initial sequence */
454 flags = CARMINE_DFLT_IP_DCTL_MODE << 16 | CARMINE_DFLT_IP_DCTL_ADD;
455 c_set_hw_reg(hw, CARMINE_DCTL_REG + CARMINE_DCTL_REG_MODE_ADD,
456 flags);
457
458 flags = CARMINE_DFLT_IP_DCTL_SET_TIME1 << 16 |
459 CARMINE_DFLT_IP_DCTL_EMODE;
460 c_set_hw_reg(hw, CARMINE_DCTL_REG + CARMINE_DCTL_REG_SETTIME1_EMODE,
461 flags);
462
463 flags = CARMINE_DFLT_IP_DCTL_REFRESH << 16 |
464 CARMINE_DFLT_IP_DCTL_SET_TIME2;
465 c_set_hw_reg(hw, CARMINE_DCTL_REG + CARMINE_DCTL_REG_REFRESH_SETTIME2,
466 flags);
467
468 flags = CARMINE_DFLT_IP_DCTL_RESERVE2 << 16 |
469 CARMINE_DFLT_IP_DCTL_FIFO_DEPTH;
470 c_set_hw_reg(hw, CARMINE_DCTL_REG + CARMINE_DCTL_REG_RSV2_RSV1, flags);
471
472 flags = CARMINE_DFLT_IP_DCTL_DDRIF2 << 16 | CARMINE_DFLT_IP_DCTL_DDRIF1;
473 c_set_hw_reg(hw, CARMINE_DCTL_REG + CARMINE_DCTL_REG_DDRIF2_DDRIF1,
474 flags);
475
476 flags = CARMINE_DFLT_IP_DCTL_RESERVE0 << 16 |
477 CARMINE_DFLT_IP_DCTL_STATES;
478 c_set_hw_reg(hw, CARMINE_DCTL_REG + CARMINE_DCTL_REG_RSV0_STATES,
479 flags);
480
481 /* Executes DLL reset */
482 if (CARMINE_DCTL_DLL_RESET) {
483 for (loops = 0; loops < CARMINE_DCTL_INIT_WAIT_LIMIT; loops++) {
484
485 ret = c_get_hw_reg(hw, CARMINE_DCTL_REG +
486 CARMINE_DCTL_REG_RSV0_STATES);
487 ret &= CARMINE_DCTL_REG_STATES_MASK;
488 if (!ret)
489 break;
490
491 mdelay(CARMINE_DCTL_INIT_WAIT_INTERVAL);
492 }
493
494 if (loops >= CARMINE_DCTL_INIT_WAIT_LIMIT) {
495 printk(KERN_ERR "DRAM init failed\n");
496 return -EIO;
497 }
498 }
499
500 flags = CARMINE_DFLT_IP_DCTL_MODE_AFT_RST << 16 |
501 CARMINE_DFLT_IP_DCTL_ADD;
502 c_set_hw_reg(hw, CARMINE_DCTL_REG + CARMINE_DCTL_REG_MODE_ADD, flags);
503
504 flags = CARMINE_DFLT_IP_DCTL_RESERVE0 << 16 |
505 CARMINE_DFLT_IP_DCTL_STATES_AFT_RST;
506 c_set_hw_reg(hw, CARMINE_DCTL_REG + CARMINE_DCTL_REG_RSV0_STATES,
507 flags);
508
509 /* Initialize the write back register */
510 c_set_hw_reg(hw, CARMINE_WB_REG + CARMINE_WB_REG_WBM,
511 CARMINE_WB_REG_WBM_DEFAULT);
512
513 /* Initialize the Kottos registers */
514 c_set_hw_reg(hw, CARMINE_GRAPH_REG + CARMINE_GRAPH_REG_VRINTM, 0);
515 c_set_hw_reg(hw, CARMINE_GRAPH_REG + CARMINE_GRAPH_REG_VRERRM, 0);
516
517 /* Set DC offsets */
518 c_set_hw_reg(hw, CARMINE_GRAPH_REG + CARMINE_GRAPH_REG_DC_OFFSET_PX, 0);
519 c_set_hw_reg(hw, CARMINE_GRAPH_REG + CARMINE_GRAPH_REG_DC_OFFSET_PY, 0);
520 c_set_hw_reg(hw, CARMINE_GRAPH_REG + CARMINE_GRAPH_REG_DC_OFFSET_LX, 0);
521 c_set_hw_reg(hw, CARMINE_GRAPH_REG + CARMINE_GRAPH_REG_DC_OFFSET_LY, 0);
522 c_set_hw_reg(hw, CARMINE_GRAPH_REG + CARMINE_GRAPH_REG_DC_OFFSET_TX, 0);
523 c_set_hw_reg(hw, CARMINE_GRAPH_REG + CARMINE_GRAPH_REG_DC_OFFSET_TY, 0);
524 return 0;
525}
526
527static struct fb_ops carminefb_ops = {
528 .owner = THIS_MODULE,
529 .fb_fillrect = cfb_fillrect,
530 .fb_copyarea = cfb_copyarea,
531 .fb_imageblit = cfb_imageblit,
532
533 .fb_check_var = carmine_check_var,
534 .fb_set_par = carmine_set_par,
535 .fb_setcolreg = carmine_setcolreg,
536};
537
538static int alloc_carmine_fb(void __iomem *regs, void __iomem *smem_base,
539 int smem_offset, struct device *device, struct fb_info **rinfo)
540{
541 int ret;
542 struct fb_info *info;
543 struct carmine_fb *par;
544
545 info = framebuffer_alloc(sizeof *par, device);
546 if (!info)
547 return -ENOMEM;
548
549 par = info->par;
550 par->display_reg = regs;
551 par->smem_offset = smem_offset;
552
553 info->screen_base = smem_base + smem_offset;
554 info->screen_size = CARMINE_DISPLAY_MEM;
555 info->fbops = &carminefb_ops;
556
557 info->fix = carminefb_fix;
558 info->pseudo_palette = par->pseudo_palette;
559 info->flags = FBINFO_DEFAULT;
560
561 ret = fb_alloc_cmap(&info->cmap, 256, 1);
562 if (ret < 0)
563 goto err_free_fb;
564
565 if (fb_mode > ARRAY_SIZE(carmine_modedb))
566 fb_mode = CARMINEFB_DEFAULT_VIDEO_MODE;
567
568 par->cur_mode = par->new_mode = ~0;
569
570 ret = fb_find_mode(&info->var, info, fb_mode_str, carmine_modedb,
571 ARRAY_SIZE(carmine_modedb),
572 &carmine_modedb[fb_mode], 32);
573 if (!ret || ret == 4) {
574 ret = -EINVAL;
575 goto err_dealloc_cmap;
576 }
577
578 fb_videomode_to_modelist(carmine_modedb, ARRAY_SIZE(carmine_modedb),
579 &info->modelist);
580
581 ret = register_framebuffer(info);
582 if (ret < 0)
583 goto err_dealloc_cmap;
584
585 printk(KERN_INFO "fb%d: %s frame buffer device\n", info->node,
586 info->fix.id);
587
588 *rinfo = info;
589 return 0;
590
591err_dealloc_cmap:
592 fb_dealloc_cmap(&info->cmap);
593err_free_fb:
594 framebuffer_release(info);
595 return ret;
596}
597
598static void cleanup_fb_device(struct fb_info *info)
599{
600 if (info) {
601 unregister_framebuffer(info);
602 fb_dealloc_cmap(&info->cmap);
603 framebuffer_release(info);
604 }
605}
606
607static int __devinit carminefb_probe(struct pci_dev *dev,
608 const struct pci_device_id *ent)
609{
610 struct carmine_hw *hw;
611 struct device *device = &dev->dev;
612 struct fb_info *info;
613 int ret;
614
615 ret = pci_enable_device(dev);
616 if (ret)
617 return ret;
618
619 ret = -ENOMEM;
620 hw = kzalloc(sizeof *hw, GFP_KERNEL);
621 if (!hw)
622 goto err_enable_pci;
623
624 carminefb_fix.mmio_start = pci_resource_start(dev, CARMINE_CONFIG_BAR);
625 carminefb_fix.mmio_len = pci_resource_len(dev, CARMINE_CONFIG_BAR);
626
627 if (!request_mem_region(carminefb_fix.mmio_start,
628 carminefb_fix.mmio_len,
629 "carminefb regbase")) {
630 printk(KERN_ERR "carminefb: Can't reserve regbase.\n");
631 ret = -EBUSY;
632 goto err_free_hw;
633 }
634 hw->v_regs = ioremap_nocache(carminefb_fix.mmio_start,
635 carminefb_fix.mmio_len);
636 if (!hw->v_regs) {
637 printk(KERN_ERR "carminefb: Can't remap %s register.\n",
638 carminefb_fix.id);
639 goto err_free_reg_mmio;
640 }
641
642 carminefb_fix.smem_start = pci_resource_start(dev, CARMINE_MEMORY_BAR);
643 carminefb_fix.smem_len = pci_resource_len(dev, CARMINE_MEMORY_BAR);
644
645 /* The memory area tends to be very large (256 MiB). Remap only what
646 * is required for that largest resolution to avoid remaps at run
647 * time
648 */
649 if (carminefb_fix.smem_len > CARMINE_TOTAL_DIPLAY_MEM)
650 carminefb_fix.smem_len = CARMINE_TOTAL_DIPLAY_MEM;
651
652 else if (carminefb_fix.smem_len < CARMINE_TOTAL_DIPLAY_MEM) {
653 printk(KERN_ERR "carminefb: Memory bar is only %d bytes, %d "
654 "are required.", carminefb_fix.smem_len,
655 CARMINE_TOTAL_DIPLAY_MEM);
656 goto err_free_reg_mmio;
657 }
658
659 if (!request_mem_region(carminefb_fix.smem_start,
660 carminefb_fix.smem_len, "carminefb smem")) {
661 printk(KERN_ERR "carminefb: Can't reserve smem.\n");
662 goto err_unmap_vregs;
663 }
664
665 hw->screen_mem = ioremap_nocache(carminefb_fix.smem_start,
666 carminefb_fix.smem_len);
667 if (!hw->screen_mem) {
668 printk(KERN_ERR "carmine: Can't ioremap smem area.\n");
669 release_mem_region(carminefb_fix.smem_start,
670 carminefb_fix.smem_len);
671 goto err_reg_smem;
672 }
673
674 ret = init_hardware(hw);
675 if (ret)
676 goto err_unmap_screen;
677
678 info = NULL;
679 if (fb_displays & CARMINE_USE_DISPLAY0) {
680 ret = alloc_carmine_fb(hw->v_regs + CARMINE_DISP0_REG,
681 hw->screen_mem, CARMINE_DISPLAY_MEM * 0,
682 device, &info);
683 if (ret)
684 goto err_deinit_hw;
685 }
686
687 hw->fb[0] = info;
688
689 info = NULL;
690 if (fb_displays & CARMINE_USE_DISPLAY1) {
691 ret = alloc_carmine_fb(hw->v_regs + CARMINE_DISP1_REG,
692 hw->screen_mem, CARMINE_DISPLAY_MEM * 1,
693 device, &info);
694 if (ret)
695 goto err_cleanup_fb0;
696 }
697
698 hw->fb[1] = info;
699 info = NULL;
700
701 pci_set_drvdata(dev, hw);
702 return 0;
703
704err_cleanup_fb0:
705 cleanup_fb_device(hw->fb[0]);
706err_deinit_hw:
707 /* disable clock, etc */
708 c_set_hw_reg(hw, CARMINE_CTL_REG + CARMINE_CTL_REG_CLOCK_ENABLE, 0);
709err_unmap_screen:
710 iounmap(hw->screen_mem);
711err_reg_smem:
712 release_mem_region(carminefb_fix.mmio_start, carminefb_fix.mmio_len);
713err_unmap_vregs:
714 iounmap(hw->v_regs);
715err_free_reg_mmio:
716 release_mem_region(carminefb_fix.mmio_start, carminefb_fix.mmio_len);
717err_free_hw:
718 kfree(hw);
719err_enable_pci:
720 pci_disable_device(dev);
721 return ret;
722}
723
724static void __devexit carminefb_remove(struct pci_dev *dev)
725{
726 struct carmine_hw *hw = pci_get_drvdata(dev);
727 struct fb_fix_screeninfo fix;
728 int i;
729
730 /* in case we use only fb1 and not fb1 */
731 if (hw->fb[0])
732 fix = hw->fb[0]->fix;
733 else
734 fix = hw->fb[1]->fix;
735
736 /* deactivate display(s) and switch clocks */
737 c_set_hw_reg(hw, CARMINE_DISP0_REG + CARMINE_DISP_REG_DCM1, 0);
738 c_set_hw_reg(hw, CARMINE_DISP1_REG + CARMINE_DISP_REG_DCM1, 0);
739 c_set_hw_reg(hw, CARMINE_CTL_REG + CARMINE_CTL_REG_CLOCK_ENABLE, 0);
740
741 for (i = 0; i < MAX_DISPLAY; i++)
742 cleanup_fb_device(hw->fb[i]);
743
744 iounmap(hw->screen_mem);
745 release_mem_region(fix.smem_start, fix.smem_len);
746 iounmap(hw->v_regs);
747 release_mem_region(fix.mmio_start, fix.mmio_len);
748
749 pci_set_drvdata(dev, NULL);
750 pci_disable_device(dev);
751 kfree(hw);
752}
753
754#define PCI_VENDOR_ID_FUJITU_LIMITED 0x10cf
755static struct pci_device_id carmine_devices[] __devinitdata = {
756{
757 PCI_DEVICE(PCI_VENDOR_ID_FUJITU_LIMITED, 0x202b)},
758 {0, 0, 0, 0, 0, 0, 0}
759};
760
761MODULE_DEVICE_TABLE(pci, carmine_devices);
762
763static struct pci_driver carmine_pci_driver = {
764 .name = "carminefb",
765 .id_table = carmine_devices,
766 .probe = carminefb_probe,
767 .remove = __devexit_p(carminefb_remove),
768};
769
770static int __init carminefb_init(void)
771{
772 if (!(fb_displays &
773 (CARMINE_USE_DISPLAY0 | CARMINE_USE_DISPLAY1))) {
774 printk(KERN_ERR "If you disable both displays than you don't "
775 "need the driver at all\n");
776 return -EINVAL;
777 }
778 return pci_register_driver(&carmine_pci_driver);
779}
780module_init(carminefb_init);
781
782static void __exit carminefb_cleanup(void)
783{
784 pci_unregister_driver(&carmine_pci_driver);
785}
786module_exit(carminefb_cleanup);
787
788MODULE_AUTHOR("Sebastian Siewior <bigeasy@linutronix.de>");
789MODULE_DESCRIPTION("Framebuffer driver for Fujitsu Carmine based devices");
790MODULE_LICENSE("GPL v2");
diff --git a/drivers/video/carminefb.h b/drivers/video/carminefb.h
new file mode 100644
index 000000000000..05306de0c6b6
--- /dev/null
+++ b/drivers/video/carminefb.h
@@ -0,0 +1,64 @@
1#ifndef CARMINE_CARMINE_H
2#define CARMINE_CARMINE_H
3
4#define CARMINE_MEMORY_BAR 2
5#define CARMINE_CONFIG_BAR 3
6
7#define MAX_DISPLAY 2
8#define CARMINE_DISPLAY_MEM (800 * 600 * 4)
9#define CARMINE_TOTAL_DIPLAY_MEM (CARMINE_DISPLAY_MEM * MAX_DISPLAY)
10
11#define CARMINE_USE_DISPLAY0 (1 << 0)
12#define CARMINE_USE_DISPLAY1 (1 << 1)
13
14/*
15 * This values work on the eval card. Custom boards may use different timings,
16 * here an example :)
17 */
18
19/* DRAM initialization values */
20#ifdef CONFIG_FB_CARMINE_DRAM_EVAL
21
22#define CARMINE_DFLT_IP_CLOCK_ENABLE (0x03ff)
23#define CARMINE_DFLT_IP_DCTL_ADD (0x05c3)
24#define CARMINE_DFLT_IP_DCTL_MODE (0x0121)
25#define CARMINE_DFLT_IP_DCTL_EMODE (0x8000)
26#define CARMINE_DFLT_IP_DCTL_SET_TIME1 (0x4749)
27#define CARMINE_DFLT_IP_DCTL_SET_TIME2 (0x2a22)
28#define CARMINE_DFLT_IP_DCTL_REFRESH (0x0042)
29#define CARMINE_DFLT_IP_DCTL_STATES (0x0003)
30#define CARMINE_DFLT_IP_DCTL_RESERVE0 (0x0020)
31#define CARMINE_DFLT_IP_DCTL_FIFO_DEPTH (0x000f)
32#define CARMINE_DFLT_IP_DCTL_RESERVE2 (0x0000)
33#define CARMINE_DFLT_IP_DCTL_DDRIF1 (0x6646)
34#define CARMINE_DFLT_IP_DCTL_DDRIF2 (0x0055)
35#define CARMINE_DFLT_IP_DCTL_MODE_AFT_RST (0x0021)
36#define CARMINE_DFLT_IP_DCTL_STATES_AFT_RST (0x0002)
37#define CARMINE_DFLT_IP_DCTL_IO_CONT0 (0x0555)
38#define CARMINE_DFLT_IP_DCTL_IO_CONT1 (0x0555)
39#define CARMINE_DCTL_DLL_RESET (1)
40#endif
41
42#ifdef CONFIG_CARMINE_DRAM_CUSTOM
43
44#define CARMINE_DFLT_IP_CLOCK_ENABLE (0x03ff)
45#define CARMINE_DFLT_IP_DCTL_ADD (0x03b2)
46#define CARMINE_DFLT_IP_DCTL_MODE (0x0161)
47#define CARMINE_DFLT_IP_DCTL_EMODE (0x8000)
48#define CARMINE_DFLT_IP_DCTL_SET_TIME1 (0x2628)
49#define CARMINE_DFLT_IP_DCTL_SET_TIME2 (0x1a09)
50#define CARMINE_DFLT_IP_DCTL_REFRESH (0x00fe)
51#define CARMINE_DFLT_IP_DCTL_STATES (0x0003)
52#define CARMINE_DFLT_IP_DCTL_RESERVE0 (0x0020)
53#define CARMINE_DFLT_IP_DCTL_FIFO_DEPTH (0x000f)
54#define CARMINE_DFLT_IP_DCTL_RESERVE2 (0x0000)
55#define CARMINE_DFLT_IP_DCTL_DDRIF1 (0x0646)
56#define CARMINE_DFLT_IP_DCTL_DDRIF2 (0x55aa)
57#define CARMINE_DFLT_IP_DCTL_MODE_AFT_RST (0x0061)
58#define CARMINE_DFLT_IP_DCTL_STATES_AFT_RST (0x0002)
59#define CARMINE_DFLT_IP_DCTL_IO_CONT0 (0x0555)
60#define CARMINE_DFLT_IP_DCTL_IO_CONT1 (0x0555)
61#define CARMINE_DCTL_DLL_RESET (1)
62#endif
63
64#endif
diff --git a/drivers/video/carminefb_regs.h b/drivers/video/carminefb_regs.h
new file mode 100644
index 000000000000..045215600b73
--- /dev/null
+++ b/drivers/video/carminefb_regs.h
@@ -0,0 +1,159 @@
1#ifndef _CARMINEFB_REGS_H
2#define _CARMINEFB_REGS_H
3
4#define CARMINE_OVERLAY_EXT_MODE (0x00000002)
5#define CARMINE_GRAPH_REG (0x00000000)
6#define CARMINE_DISP0_REG (0x00100000)
7#define CARMINE_DISP1_REG (0x00140000)
8#define CARMINE_WB_REG (0x00180000)
9#define CARMINE_DCTL_REG (0x00300000)
10#define CARMINE_CTL_REG (0x00400000)
11#define CARMINE_WINDOW_MODE (0x00000001)
12#define CARMINE_EXTEND_MODE (CARMINE_WINDOW_MODE | \
13 CARMINE_OVERLAY_EXT_MODE)
14#define CARMINE_L0E (1 << 16)
15#define CARMINE_L2E (1 << 18)
16#define CARMINE_DEN (1 << 31)
17
18#define CARMINE_EXT_CMODE_DIRECT24_RGBA (0xC0000000)
19#define CARMINE_DCTL_REG_MODE_ADD (0x00)
20#define CARMINE_DCTL_REG_SETTIME1_EMODE (0x04)
21#define CARMINE_DCTL_REG_REFRESH_SETTIME2 (0x08)
22#define CARMINE_DCTL_REG_RSV0_STATES (0x0C)
23#define CARMINE_DCTL_REG_RSV2_RSV1 (0x10)
24#define CARMINE_DCTL_REG_DDRIF2_DDRIF1 (0x14)
25#define CARMINE_DCTL_REG_IOCONT1_IOCONT0 (0x24)
26#define CARMINE_DCTL_REG_STATES_MASK (0x000F)
27#define CARMINE_DCTL_INIT_WAIT_INTERVAL (1)
28#define CARMINE_DCTL_INIT_WAIT_LIMIT (5000)
29#define CARMINE_WB_REG_WBM_DEFAULT (0x0001c020)
30#define CARMINE_DISP_REG_L0RM (0x1880)
31#define CARMINE_DISP_REG_L0PX (0x1884)
32#define CARMINE_DISP_REG_L0PY (0x1888)
33#define CARMINE_DISP_REG_L2RM (0x18A0)
34#define CARMINE_DISP_REG_L2PX (0x18A4)
35#define CARMINE_DISP_REG_L2PY (0x18A8)
36#define CARMINE_DISP_REG_L3RM (0x18B0)
37#define CARMINE_DISP_REG_L3PX (0x18B4)
38#define CARMINE_DISP_REG_L3PY (0x18B8)
39#define CARMINE_DISP_REG_L4RM (0x18C0)
40#define CARMINE_DISP_REG_L4PX (0x18C4)
41#define CARMINE_DISP_REG_L4PY (0x18C8)
42#define CARMINE_DISP_REG_L5RM (0x18D0)
43#define CARMINE_DISP_REG_L5PX (0x18D4)
44#define CARMINE_DISP_REG_L5PY (0x18D8)
45#define CARMINE_DISP_REG_L6RM (0x1924)
46#define CARMINE_DISP_REG_L6PX (0x1928)
47#define CARMINE_DISP_REG_L6PY (0x192C)
48#define CARMINE_DISP_REG_L7RM (0x1964)
49#define CARMINE_DISP_REG_L7PX (0x1968)
50#define CARMINE_DISP_REG_L7PY (0x196C)
51#define CARMINE_WB_REG_WBM (0x0004)
52#define CARMINE_DISP_HTP_SHIFT (16)
53#define CARMINE_DISP_HDB_SHIFT (16)
54#define CARMINE_DISP_HSW_SHIFT (16)
55#define CARMINE_DISP_VSW_SHIFT (24)
56#define CARMINE_DISP_VTR_SHIFT (16)
57#define CARMINE_DISP_VDP_SHIFT (16)
58#define CARMINE_CURSOR_CUTZ_MASK (0x00000100)
59#define CARMINE_CURSOR0_PRIORITY_MASK (0x00010000)
60#define CARMINE_CURSOR1_PRIORITY_MASK (0x00020000)
61#define CARMINE_DISP_WIDTH_SHIFT (16)
62#define CARMINE_DISP_WIN_H_SHIFT (16)
63#define CARMINE_DISP_REG_H_TOTAL (0x0004)
64#define CARMINE_DISP_REG_H_PERIOD (0x0008)
65#define CARMINE_DISP_REG_V_H_W_H_POS (0x000C)
66#define CARMINE_DISP_REG_V_TOTAL (0x0010)
67#define CARMINE_DISP_REG_V_PERIOD_POS (0x0014)
68#define CARMINE_DISP_REG_L0_MODE_W_H (0x0020)
69#define CARMINE_DISP_REG_L0_ORG_ADR (0x0024)
70#define CARMINE_DISP_REG_L0_DISP_ADR (0x0028)
71#define CARMINE_DISP_REG_L0_DISP_POS (0x002C)
72#define CARMINE_DISP_REG_L1_WIDTH (0x0030)
73#define CARMINE_DISP_REG_L1_ORG_ADR (0x0034)
74#define CARMINE_DISP_REG_L2_MODE_W_H (0x0040)
75#define CARMINE_DISP_REG_L2_ORG_ADR1 (0x0044)
76#define CARMINE_DISP_REG_L2_DISP_ADR1 (0x0048)
77#define CARMINE_DISP_REG_L2_DISP_POS (0x0054)
78#define CARMINE_DISP_REG_L3_MODE_W_H (0x0058)
79#define CARMINE_DISP_REG_L3_ORG_ADR1 (0x005C)
80#define CARMINE_DISP_REG_L3_DISP_ADR1 (0x0060)
81#define CARMINE_DISP_REG_L3_DISP_POS (0x006C)
82#define CARMINE_DISP_REG_L4_MODE_W_H (0x0070)
83#define CARMINE_DISP_REG_L4_ORG_ADR1 (0x0074)
84#define CARMINE_DISP_REG_L4_DISP_ADR1 (0x0078)
85#define CARMINE_DISP_REG_L4_DISP_POS (0x0084)
86#define CARMINE_DISP_REG_L5_MODE_W_H (0x0088)
87#define CARMINE_DISP_REG_L5_ORG_ADR1 (0x008C)
88#define CARMINE_DISP_REG_L5_DISP_ADR1 (0x0090)
89#define CARMINE_DISP_REG_L5_DISP_POS (0x009C)
90#define CARMINE_DISP_REG_CURSOR_MODE (0x00A0)
91#define CARMINE_DISP_REG_CUR1_POS (0x00A8)
92#define CARMINE_DISP_REG_CUR2_POS (0x00B0)
93#define CARMINE_DISP_REG_C_TRANS (0x00BC)
94#define CARMINE_DISP_REG_MLMR_TRANS (0x00C0)
95#define CARMINE_DISP_REG_L0_EXT_MODE (0x0110)
96#define CARMINE_DISP_REG_L0_WIN_POS (0x0114)
97#define CARMINE_DISP_REG_L0_WIN_SIZE (0x0118)
98#define CARMINE_DISP_REG_L1_EXT_MODE (0x0120)
99#define CARMINE_DISP_REG_L1_WIN_POS (0x0124)
100#define CARMINE_DISP_REG_L1_WIN_SIZE (0x0128)
101#define CARMINE_DISP_REG_L2_EXT_MODE (0x0130)
102#define CARMINE_DISP_REG_L2_WIN_POS (0x0134)
103#define CARMINE_DISP_REG_L2_WIN_SIZE (0x0138)
104#define CARMINE_DISP_REG_L3_EXT_MODE (0x0140)
105#define CARMINE_DISP_REG_L3_WIN_POS (0x0144)
106#define CARMINE_DISP_REG_L3_WIN_SIZE (0x0148)
107#define CARMINE_DISP_REG_L4_EXT_MODE (0x0150)
108#define CARMINE_DISP_REG_L4_WIN_POS (0x0154)
109#define CARMINE_DISP_REG_L4_WIN_SIZE (0x0158)
110#define CARMINE_DISP_REG_L5_EXT_MODE (0x0160)
111#define CARMINE_DISP_REG_L5_WIN_POS (0x0164)
112#define CARMINE_DISP_REG_L5_WIN_SIZE (0x0168)
113#define CARMINE_DISP_REG_L6_EXT_MODE (0x1918)
114#define CARMINE_DISP_REG_L6_WIN_POS (0x191c)
115#define CARMINE_DISP_REG_L6_WIN_SIZE (0x1920)
116#define CARMINE_DISP_REG_L7_EXT_MODE (0x1958)
117#define CARMINE_DISP_REG_L7_WIN_POS (0x195c)
118#define CARMINE_DISP_REG_L7_WIN_SIZE (0x1960)
119#define CARMINE_DISP_REG_BLEND_MODE_L0 (0x00B4)
120#define CARMINE_DISP_REG_BLEND_MODE_L1 (0x0188)
121#define CARMINE_DISP_REG_BLEND_MODE_L2 (0x018C)
122#define CARMINE_DISP_REG_BLEND_MODE_L3 (0x0190)
123#define CARMINE_DISP_REG_BLEND_MODE_L4 (0x0194)
124#define CARMINE_DISP_REG_BLEND_MODE_L5 (0x0198)
125#define CARMINE_DISP_REG_BLEND_MODE_L6 (0x1990)
126#define CARMINE_DISP_REG_BLEND_MODE_L7 (0x1994)
127#define CARMINE_DISP_REG_L0_TRANS (0x01A0)
128#define CARMINE_DISP_REG_L1_TRANS (0x01A4)
129#define CARMINE_DISP_REG_L2_TRANS (0x01A8)
130#define CARMINE_DISP_REG_L3_TRANS (0x01AC)
131#define CARMINE_DISP_REG_L4_TRANS (0x01B0)
132#define CARMINE_DISP_REG_L5_TRANS (0x01B4)
133#define CARMINE_DISP_REG_L6_TRANS (0x1998)
134#define CARMINE_DISP_REG_L7_TRANS (0x199c)
135#define CARMINE_EXTEND_MODE_MASK (0x00000003)
136#define CARMINE_DISP_DCM_MASK (0x0000FFFF)
137#define CARMINE_DISP_REG_DCM1 (0x0100)
138#define CARMINE_DISP_WIDTH_UNIT (64)
139#define CARMINE_DISP_REG_L6_MODE_W_H (0x1900)
140#define CARMINE_DISP_REG_L6_ORG_ADR1 (0x1904)
141#define CARMINE_DISP_REG_L6_DISP_ADR0 (0x1908)
142#define CARMINE_DISP_REG_L6_DISP_POS (0x1914)
143#define CARMINE_DISP_REG_L7_MODE_W_H (0x1940)
144#define CARMINE_DISP_REG_L7_ORG_ADR1 (0x1944)
145#define CARMINE_DISP_REG_L7_DISP_ADR0 (0x1948)
146#define CARMINE_DISP_REG_L7_DISP_POS (0x1954)
147#define CARMINE_CTL_REG_CLOCK_ENABLE (0x000C)
148#define CARMINE_CTL_REG_SOFTWARE_RESET (0x0010)
149#define CARMINE_CTL_REG_IST_MASK_ALL (0x07FFFFFF)
150#define CARMINE_GRAPH_REG_VRINTM (0x00028064)
151#define CARMINE_GRAPH_REG_VRERRM (0x0002806C)
152#define CARMINE_GRAPH_REG_DC_OFFSET_PX (0x0004005C)
153#define CARMINE_GRAPH_REG_DC_OFFSET_PY (0x00040060)
154#define CARMINE_GRAPH_REG_DC_OFFSET_LX (0x00040064)
155#define CARMINE_GRAPH_REG_DC_OFFSET_LY (0x00040068)
156#define CARMINE_GRAPH_REG_DC_OFFSET_TX (0x0004006C)
157#define CARMINE_GRAPH_REG_DC_OFFSET_TY (0x00040070)
158
159#endif
diff --git a/drivers/video/cobalt_lcdfb.c b/drivers/video/cobalt_lcdfb.c
new file mode 100644
index 000000000000..7bad24ed04ef
--- /dev/null
+++ b/drivers/video/cobalt_lcdfb.c
@@ -0,0 +1,371 @@
1/*
2 * Cobalt server LCD frame buffer driver.
3 *
4 * Copyright (C) 2008 Yoichi Yuasa <yoichi_yuasa@tripeaks.co.jp>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20#include <linux/delay.h>
21#include <linux/fb.h>
22#include <linux/init.h>
23#include <linux/io.h>
24#include <linux/ioport.h>
25#include <linux/uaccess.h>
26#include <linux/platform_device.h>
27
28/*
29 * Cursor position address
30 * \X 0 1 2 ... 14 15
31 * Y+----+----+----+---+----+----+
32 * 0|0x00|0x01|0x02|...|0x0e|0x0f|
33 * +----+----+----+---+----+----+
34 * 1|0x40|0x41|0x42|...|0x4e|0x4f|
35 * +----+----+----+---+----+----+
36 */
37#define LCD_DATA_REG_OFFSET 0x10
38#define LCD_XRES_MAX 16
39#define LCD_YRES_MAX 2
40#define LCD_CHARS_MAX 32
41
42#define LCD_CLEAR 0x01
43#define LCD_CURSOR_MOVE_HOME 0x02
44#define LCD_RESET 0x06
45#define LCD_OFF 0x08
46#define LCD_CURSOR_OFF 0x0c
47#define LCD_CURSOR_BLINK_OFF 0x0e
48#define LCD_CURSOR_ON 0x0f
49#define LCD_ON LCD_CURSOR_ON
50#define LCD_CURSOR_MOVE_LEFT 0x10
51#define LCD_CURSOR_MOVE_RIGHT 0x14
52#define LCD_DISPLAY_LEFT 0x18
53#define LCD_DISPLAY_RIGHT 0x1c
54#define LCD_PRERESET 0x3f /* execute 4 times continuously */
55#define LCD_BUSY 0x80
56
57#define LCD_GRAPHIC_MODE 0x40
58#define LCD_TEXT_MODE 0x80
59#define LCD_CUR_POS_MASK 0x7f
60
61#define LCD_CUR_POS(x) ((x) & LCD_CUR_POS_MASK)
62#define LCD_TEXT_POS(x) ((x) | LCD_TEXT_MODE)
63
64static inline void lcd_write_control(struct fb_info *info, u8 control)
65{
66 writel((u32)control << 24, info->screen_base);
67}
68
69static inline u8 lcd_read_control(struct fb_info *info)
70{
71 return readl(info->screen_base) >> 24;
72}
73
74static inline void lcd_write_data(struct fb_info *info, u8 data)
75{
76 writel((u32)data << 24, info->screen_base + LCD_DATA_REG_OFFSET);
77}
78
79static inline u8 lcd_read_data(struct fb_info *info)
80{
81 return readl(info->screen_base + LCD_DATA_REG_OFFSET) >> 24;
82}
83
84static int lcd_busy_wait(struct fb_info *info)
85{
86 u8 val = 0;
87 int timeout = 10, retval = 0;
88
89 do {
90 val = lcd_read_control(info);
91 val &= LCD_BUSY;
92 if (val != LCD_BUSY)
93 break;
94
95 if (msleep_interruptible(1))
96 return -EINTR;
97
98 timeout--;
99 } while (timeout);
100
101 if (val == LCD_BUSY)
102 retval = -EBUSY;
103
104 return retval;
105}
106
107static void lcd_clear(struct fb_info *info)
108{
109 int i;
110
111 for (i = 0; i < 4; i++) {
112 udelay(150);
113
114 lcd_write_control(info, LCD_PRERESET);
115 }
116
117 udelay(150);
118
119 lcd_write_control(info, LCD_CLEAR);
120
121 udelay(150);
122
123 lcd_write_control(info, LCD_RESET);
124}
125
126static struct fb_fix_screeninfo cobalt_lcdfb_fix __initdata = {
127 .id = "cobalt-lcd",
128 .type = FB_TYPE_TEXT,
129 .type_aux = FB_AUX_TEXT_MDA,
130 .visual = FB_VISUAL_MONO01,
131 .line_length = LCD_XRES_MAX,
132 .accel = FB_ACCEL_NONE,
133};
134
135static ssize_t cobalt_lcdfb_read(struct fb_info *info, char __user *buf,
136 size_t count, loff_t *ppos)
137{
138 char src[LCD_CHARS_MAX];
139 unsigned long pos;
140 int len, retval = 0;
141
142 pos = *ppos;
143 if (pos >= LCD_CHARS_MAX || count == 0)
144 return 0;
145
146 if (count > LCD_CHARS_MAX)
147 count = LCD_CHARS_MAX;
148
149 if (pos + count > LCD_CHARS_MAX)
150 count = LCD_CHARS_MAX - pos;
151
152 for (len = 0; len < count; len++) {
153 retval = lcd_busy_wait(info);
154 if (retval < 0)
155 break;
156
157 lcd_write_control(info, LCD_TEXT_POS(pos));
158
159 retval = lcd_busy_wait(info);
160 if (retval < 0)
161 break;
162
163 src[len] = lcd_read_data(info);
164 if (pos == 0x0f)
165 pos = 0x40;
166 else
167 pos++;
168 }
169
170 if (retval < 0 && signal_pending(current))
171 return -ERESTARTSYS;
172
173 if (copy_to_user(buf, src, len))
174 return -EFAULT;
175
176 *ppos += len;
177
178 return len;
179}
180
181static ssize_t cobalt_lcdfb_write(struct fb_info *info, const char __user *buf,
182 size_t count, loff_t *ppos)
183{
184 char dst[LCD_CHARS_MAX];
185 unsigned long pos;
186 int len, retval = 0;
187
188 pos = *ppos;
189 if (pos >= LCD_CHARS_MAX || count == 0)
190 return 0;
191
192 if (count > LCD_CHARS_MAX)
193 count = LCD_CHARS_MAX;
194
195 if (pos + count > LCD_CHARS_MAX)
196 count = LCD_CHARS_MAX - pos;
197
198 if (copy_from_user(dst, buf, count))
199 return -EFAULT;
200
201 for (len = 0; len < count; len++) {
202 retval = lcd_busy_wait(info);
203 if (retval < 0)
204 break;
205
206 lcd_write_control(info, LCD_TEXT_POS(pos));
207
208 retval = lcd_busy_wait(info);
209 if (retval < 0)
210 break;
211
212 lcd_write_data(info, dst[len]);
213 if (pos == 0x0f)
214 pos = 0x40;
215 else
216 pos++;
217 }
218
219 if (retval < 0 && signal_pending(current))
220 return -ERESTARTSYS;
221
222 *ppos += len;
223
224 return len;
225}
226
227static int cobalt_lcdfb_blank(int blank_mode, struct fb_info *info)
228{
229 int retval;
230
231 retval = lcd_busy_wait(info);
232 if (retval < 0)
233 return retval;
234
235 switch (blank_mode) {
236 case FB_BLANK_UNBLANK:
237 lcd_write_control(info, LCD_ON);
238 break;
239 default:
240 lcd_write_control(info, LCD_OFF);
241 break;
242 }
243
244 return 0;
245}
246
247static int cobalt_lcdfb_cursor(struct fb_info *info, struct fb_cursor *cursor)
248{
249 u32 x, y;
250 int retval;
251
252 switch (cursor->set) {
253 case FB_CUR_SETPOS:
254 x = cursor->image.dx;
255 y = cursor->image.dy;
256 if (x >= LCD_XRES_MAX || y >= LCD_YRES_MAX)
257 return -EINVAL;
258
259 retval = lcd_busy_wait(info);
260 if (retval < 0)
261 return retval;
262
263 lcd_write_control(info,
264 LCD_TEXT_POS(info->fix.line_length * y + x));
265 break;
266 default:
267 return -EINVAL;
268 }
269
270 retval = lcd_busy_wait(info);
271 if (retval < 0)
272 return retval;
273
274 if (cursor->enable)
275 lcd_write_control(info, LCD_CURSOR_ON);
276 else
277 lcd_write_control(info, LCD_CURSOR_OFF);
278
279 return 0;
280}
281
282static struct fb_ops cobalt_lcd_fbops = {
283 .owner = THIS_MODULE,
284 .fb_read = cobalt_lcdfb_read,
285 .fb_write = cobalt_lcdfb_write,
286 .fb_blank = cobalt_lcdfb_blank,
287 .fb_cursor = cobalt_lcdfb_cursor,
288};
289
290static int __init cobalt_lcdfb_probe(struct platform_device *dev)
291{
292 struct fb_info *info;
293 struct resource *res;
294 int retval;
295
296 info = framebuffer_alloc(0, &dev->dev);
297 if (!info)
298 return -ENOMEM;
299
300 res = platform_get_resource(dev, IORESOURCE_MEM, 0);
301 if (!res) {
302 framebuffer_release(info);
303 return -EBUSY;
304 }
305
306 info->screen_size = res->end - res->start + 1;
307 info->screen_base = ioremap(res->start, info->screen_size);
308 info->fbops = &cobalt_lcd_fbops;
309 info->fix = cobalt_lcdfb_fix;
310 info->fix.smem_start = res->start;
311 info->fix.smem_len = info->screen_size;
312 info->pseudo_palette = NULL;
313 info->par = NULL;
314 info->flags = FBINFO_DEFAULT;
315
316 retval = register_framebuffer(info);
317 if (retval < 0) {
318 iounmap(info->screen_base);
319 framebuffer_release(info);
320 return retval;
321 }
322
323 platform_set_drvdata(dev, info);
324
325 lcd_clear(info);
326
327 printk(KERN_INFO "fb%d: Cobalt server LCD frame buffer device\n",
328 info->node);
329
330 return 0;
331}
332
333static int __devexit cobalt_lcdfb_remove(struct platform_device *dev)
334{
335 struct fb_info *info;
336
337 info = platform_get_drvdata(dev);
338 if (info) {
339 iounmap(info->screen_base);
340 unregister_framebuffer(info);
341 framebuffer_release(info);
342 }
343
344 return 0;
345}
346
347static struct platform_driver cobalt_lcdfb_driver = {
348 .probe = cobalt_lcdfb_probe,
349 .remove = __devexit_p(cobalt_lcdfb_remove),
350 .driver = {
351 .name = "cobalt-lcd",
352 .owner = THIS_MODULE,
353 },
354};
355
356static int __init cobalt_lcdfb_init(void)
357{
358 return platform_driver_register(&cobalt_lcdfb_driver);
359}
360
361static void __exit cobalt_lcdfb_exit(void)
362{
363 platform_driver_unregister(&cobalt_lcdfb_driver);
364}
365
366module_init(cobalt_lcdfb_init);
367module_exit(cobalt_lcdfb_exit);
368
369MODULE_LICENSE("GPL v2");
370MODULE_AUTHOR("Yoichi Yuasa");
371MODULE_DESCRIPTION("Cobalt server LCD frame buffer driver");
diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c
index 4be3b46c069b..3ccfa76d9b2a 100644
--- a/drivers/video/console/fbcon.c
+++ b/drivers/video/console/fbcon.c
@@ -107,9 +107,7 @@ static struct display fb_display[MAX_NR_CONSOLES];
107 107
108static signed char con2fb_map[MAX_NR_CONSOLES]; 108static signed char con2fb_map[MAX_NR_CONSOLES];
109static signed char con2fb_map_boot[MAX_NR_CONSOLES]; 109static signed char con2fb_map_boot[MAX_NR_CONSOLES];
110#ifndef MODULE 110
111static int logo_height;
112#endif
113static int logo_lines; 111static int logo_lines;
114/* logo_shown is an index to vc_cons when >= 0; otherwise follows FBCON_LOGO 112/* logo_shown is an index to vc_cons when >= 0; otherwise follows FBCON_LOGO
115 enums. */ 113 enums. */
@@ -607,6 +605,7 @@ static void fbcon_prepare_logo(struct vc_data *vc, struct fb_info *info,
607 struct fbcon_ops *ops = info->fbcon_par; 605 struct fbcon_ops *ops = info->fbcon_par;
608 int cnt, erase = vc->vc_video_erase_char, step; 606 int cnt, erase = vc->vc_video_erase_char, step;
609 unsigned short *save = NULL, *r, *q; 607 unsigned short *save = NULL, *r, *q;
608 int logo_height;
610 609
611 if (info->flags & FBINFO_MODULE) { 610 if (info->flags & FBINFO_MODULE) {
612 logo_shown = FBCON_LOGO_DONTSHOW; 611 logo_shown = FBCON_LOGO_DONTSHOW;
diff --git a/drivers/video/console/fbcon.h b/drivers/video/console/fbcon.h
index 0135e0395456..de1b1365279b 100644
--- a/drivers/video/console/fbcon.h
+++ b/drivers/video/console/fbcon.h
@@ -92,7 +92,7 @@ struct fbcon_ops {
92#define attr_fgcol(fgshift,s) \ 92#define attr_fgcol(fgshift,s) \
93 (((s) >> (fgshift)) & 0x0f) 93 (((s) >> (fgshift)) & 0x0f)
94#define attr_bgcol(bgshift,s) \ 94#define attr_bgcol(bgshift,s) \
95 (((s) >> (bgshift)) & 0x0f) 95 (((s) >> (bgshift)) & 0x07)
96 96
97/* Monochrome */ 97/* Monochrome */
98#define attr_bold(s) \ 98#define attr_bold(s) \
@@ -146,10 +146,8 @@ static inline int attr_col_ec(int shift, struct vc_data *vc,
146 return is_fg ? fg : bg; 146 return is_fg ? fg : bg;
147} 147}
148 148
149#define attr_bgcol_ec(bgshift,vc,info) \ 149#define attr_bgcol_ec(bgshift, vc, info) attr_col_ec(bgshift, vc, info, 0)
150 attr_col_ec(bgshift,vc,info,0); 150#define attr_fgcol_ec(fgshift, vc, info) attr_col_ec(fgshift, vc, info, 1)
151#define attr_fgcol_ec(fgshift,vc,info) \
152 attr_col_ec(fgshift,vc,info,1);
153 151
154/* Font */ 152/* Font */
155#define REFCOUNT(fd) (((int *)(fd))[-1]) 153#define REFCOUNT(fd) (((int *)(fd))[-1])
diff --git a/drivers/video/console/mdacon.c b/drivers/video/console/mdacon.c
index 38a296bbdfc9..9901064199bd 100644
--- a/drivers/video/console/mdacon.c
+++ b/drivers/video/console/mdacon.c
@@ -71,13 +71,15 @@ static char *mda_type_name;
71 71
72/* console information */ 72/* console information */
73 73
74static int mda_first_vc = 1; 74static int mda_first_vc = 13;
75static int mda_last_vc = 16; 75static int mda_last_vc = 16;
76 76
77static struct vc_data *mda_display_fg = NULL; 77static struct vc_data *mda_display_fg = NULL;
78 78
79module_param(mda_first_vc, int, 0); 79module_param(mda_first_vc, int, 0);
80MODULE_PARM_DESC(mda_first_vc, "First virtual console. Default: 13");
80module_param(mda_last_vc, int, 0); 81module_param(mda_last_vc, int, 0);
82MODULE_PARM_DESC(mda_last_vc, "Last virtual console. Default: 16");
81 83
82/* MDA register values 84/* MDA register values
83 */ 85 */
diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c
index 1cd5071e5362..5d84b3431098 100644
--- a/drivers/video/fbmem.c
+++ b/drivers/video/fbmem.c
@@ -35,6 +35,7 @@
35#include <linux/device.h> 35#include <linux/device.h>
36#include <linux/efi.h> 36#include <linux/efi.h>
37#include <linux/fb.h> 37#include <linux/fb.h>
38#include <linux/major.h>
38 39
39#include <asm/fb.h> 40#include <asm/fb.h>
40 41
@@ -848,9 +849,8 @@ int
848fb_pan_display(struct fb_info *info, struct fb_var_screeninfo *var) 849fb_pan_display(struct fb_info *info, struct fb_var_screeninfo *var)
849{ 850{
850 struct fb_fix_screeninfo *fix = &info->fix; 851 struct fb_fix_screeninfo *fix = &info->fix;
851 int xoffset = var->xoffset; 852 unsigned int yres = info->var.yres;
852 int yoffset = var->yoffset; 853 int err = 0;
853 int err = 0, yres = info->var.yres;
854 854
855 if (var->yoffset > 0) { 855 if (var->yoffset > 0) {
856 if (var->vmode & FB_VMODE_YWRAP) { 856 if (var->vmode & FB_VMODE_YWRAP) {
@@ -866,8 +866,8 @@ fb_pan_display(struct fb_info *info, struct fb_var_screeninfo *var)
866 (var->xoffset % fix->xpanstep))) 866 (var->xoffset % fix->xpanstep)))
867 err = -EINVAL; 867 err = -EINVAL;
868 868
869 if (err || !info->fbops->fb_pan_display || xoffset < 0 || 869 if (err || !info->fbops->fb_pan_display ||
870 yoffset < 0 || var->yoffset + yres > info->var.yres_virtual || 870 var->yoffset + yres > info->var.yres_virtual ||
871 var->xoffset + info->var.xres > info->var.xres_virtual) 871 var->xoffset + info->var.xres > info->var.xres_virtual)
872 return -EINVAL; 872 return -EINVAL;
873 873
diff --git a/drivers/video/fbmon.c b/drivers/video/fbmon.c
index 052e18058498..6a0aa180c266 100644
--- a/drivers/video/fbmon.c
+++ b/drivers/video/fbmon.c
@@ -879,7 +879,7 @@ int fb_parse_edid(unsigned char *edid, struct fb_var_screeninfo *var)
879 if (edid_is_timing_block(block)) { 879 if (edid_is_timing_block(block)) {
880 var->xres = var->xres_virtual = H_ACTIVE; 880 var->xres = var->xres_virtual = H_ACTIVE;
881 var->yres = var->yres_virtual = V_ACTIVE; 881 var->yres = var->yres_virtual = V_ACTIVE;
882 var->height = var->width = -1; 882 var->height = var->width = 0;
883 var->right_margin = H_SYNC_OFFSET; 883 var->right_margin = H_SYNC_OFFSET;
884 var->left_margin = (H_ACTIVE + H_BLANKING) - 884 var->left_margin = (H_ACTIVE + H_BLANKING) -
885 (H_ACTIVE + H_SYNC_OFFSET + H_SYNC_WIDTH); 885 (H_ACTIVE + H_SYNC_OFFSET + H_SYNC_WIDTH);
diff --git a/drivers/video/fsl-diu-fb.c b/drivers/video/fsl-diu-fb.c
index 09d7e22c6fef..9cd36c223d33 100644
--- a/drivers/video/fsl-diu-fb.c
+++ b/drivers/video/fsl-diu-fb.c
@@ -279,58 +279,42 @@ static struct diu_hw dr = {
279 279
280static struct diu_pool pool; 280static struct diu_pool pool;
281 281
282/* To allocate memory for framebuffer. First try __get_free_pages(). If it 282/**
283 * fails, try rh_alloc. The reason is __get_free_pages() cannot allocate 283 * fsl_diu_alloc - allocate memory for the DIU
284 * very large memory (more than 4MB). We don't want to allocate all memory 284 * @size: number of bytes to allocate
285 * in rheap since small memory allocation/deallocation will fragment the 285 * @param: returned physical address of memory
286 * rheap and make the furture large allocation fail. 286 *
287 * This function allocates a physically-contiguous block of memory.
287 */ 288 */
288 289static void *fsl_diu_alloc(size_t size, phys_addr_t *phys)
289static void *fsl_diu_alloc(unsigned long size, phys_addr_t *phys)
290{ 290{
291 void *virt; 291 void *virt;
292 292
293 pr_debug("size=%lu\n", size); 293 pr_debug("size=%zu\n", size);
294 294
295 virt = (void *)__get_free_pages(GFP_DMA | __GFP_ZERO, get_order(size)); 295 virt = alloc_pages_exact(size, GFP_DMA | __GFP_ZERO);
296 if (virt) { 296 if (virt) {
297 *phys = virt_to_phys(virt); 297 *phys = virt_to_phys(virt);
298 pr_debug("virt %p, phys=%llx\n", virt, (uint64_t) *phys); 298 pr_debug("virt=%p phys=%llx\n", virt,
299 return virt; 299 (unsigned long long)*phys);
300 }
301 if (!diu_ops.diu_mem) {
302 printk(KERN_INFO "%s: no diu_mem."
303 " To reserve more memory, put 'diufb=15M' "
304 "in the command line\n", __func__);
305 return NULL;
306 }
307
308 virt = (void *)rh_alloc(&diu_ops.diu_rh_info, size, "DIU");
309 if (virt) {
310 *phys = virt_to_bus(virt);
311 memset(virt, 0, size);
312 } 300 }
313 301
314 pr_debug("rh virt=%p phys=%llx\n", virt, (unsigned long long)*phys);
315
316 return virt; 302 return virt;
317} 303}
318 304
319static void fsl_diu_free(void *p, unsigned long size) 305/**
306 * fsl_diu_free - release DIU memory
307 * @virt: pointer returned by fsl_diu_alloc()
308 * @size: number of bytes allocated by fsl_diu_alloc()
309 *
310 * This function releases memory allocated by fsl_diu_alloc().
311 */
312static void fsl_diu_free(void *virt, size_t size)
320{ 313{
321 pr_debug("p=%p size=%lu\n", p, size); 314 pr_debug("virt=%p size=%zu\n", virt, size);
322 315
323 if (!p) 316 if (virt && size)
324 return; 317 free_pages_exact(virt, size);
325
326 if ((p >= diu_ops.diu_mem) &&
327 (p < (diu_ops.diu_mem + diu_ops.diu_size))) {
328 pr_debug("rh\n");
329 rh_free(&diu_ops.diu_rh_info, (unsigned long) p);
330 } else {
331 pr_debug("dma\n");
332 free_pages((unsigned long)p, get_order(size));
333 }
334} 318}
335 319
336static int fsl_diu_enable_panel(struct fb_info *info) 320static int fsl_diu_enable_panel(struct fb_info *info)
diff --git a/drivers/video/geode/lxfb.h b/drivers/video/geode/lxfb.h
index 3b9416f4ee20..6a51448fd3f7 100644
--- a/drivers/video/geode/lxfb.h
+++ b/drivers/video/geode/lxfb.h
@@ -51,8 +51,6 @@ static inline unsigned int lx_get_pitch(unsigned int xres, int bpp)
51} 51}
52 52
53void lx_set_mode(struct fb_info *); 53void lx_set_mode(struct fb_info *);
54void lx_get_gamma(struct fb_info *, unsigned int *, int);
55void lx_set_gamma(struct fb_info *, unsigned int *, int);
56unsigned int lx_framebuffer_size(void); 54unsigned int lx_framebuffer_size(void);
57int lx_blank_display(struct fb_info *, int); 55int lx_blank_display(struct fb_info *, int);
58void lx_set_palette_reg(struct fb_info *, unsigned int, unsigned int, 56void lx_set_palette_reg(struct fb_info *, unsigned int, unsigned int,
diff --git a/drivers/video/geode/lxfb_ops.c b/drivers/video/geode/lxfb_ops.c
index aaef9165ec9b..b1cd49c99356 100644
--- a/drivers/video/geode/lxfb_ops.c
+++ b/drivers/video/geode/lxfb_ops.c
@@ -517,25 +517,25 @@ void lx_set_palette_reg(struct fb_info *info, unsigned regno,
517int lx_blank_display(struct fb_info *info, int blank_mode) 517int lx_blank_display(struct fb_info *info, int blank_mode)
518{ 518{
519 struct lxfb_par *par = info->par; 519 struct lxfb_par *par = info->par;
520 u32 dcfg, fp_pm; 520 u32 dcfg, misc, fp_pm;
521 int blank, hsync, vsync, crt; 521 int blank, hsync, vsync;
522 522
523 /* CRT power saving modes. */ 523 /* CRT power saving modes. */
524 switch (blank_mode) { 524 switch (blank_mode) {
525 case FB_BLANK_UNBLANK: 525 case FB_BLANK_UNBLANK:
526 blank = 0; hsync = 1; vsync = 1; crt = 1; 526 blank = 0; hsync = 1; vsync = 1;
527 break; 527 break;
528 case FB_BLANK_NORMAL: 528 case FB_BLANK_NORMAL:
529 blank = 1; hsync = 1; vsync = 1; crt = 1; 529 blank = 1; hsync = 1; vsync = 1;
530 break; 530 break;
531 case FB_BLANK_VSYNC_SUSPEND: 531 case FB_BLANK_VSYNC_SUSPEND:
532 blank = 1; hsync = 1; vsync = 0; crt = 1; 532 blank = 1; hsync = 1; vsync = 0;
533 break; 533 break;
534 case FB_BLANK_HSYNC_SUSPEND: 534 case FB_BLANK_HSYNC_SUSPEND:
535 blank = 1; hsync = 0; vsync = 1; crt = 1; 535 blank = 1; hsync = 0; vsync = 1;
536 break; 536 break;
537 case FB_BLANK_POWERDOWN: 537 case FB_BLANK_POWERDOWN:
538 blank = 1; hsync = 0; vsync = 0; crt = 0; 538 blank = 1; hsync = 0; vsync = 0;
539 break; 539 break;
540 default: 540 default:
541 return -EINVAL; 541 return -EINVAL;
@@ -545,15 +545,23 @@ int lx_blank_display(struct fb_info *info, int blank_mode)
545 dcfg &= ~(VP_DCFG_DAC_BL_EN | VP_DCFG_HSYNC_EN | VP_DCFG_VSYNC_EN | 545 dcfg &= ~(VP_DCFG_DAC_BL_EN | VP_DCFG_HSYNC_EN | VP_DCFG_VSYNC_EN |
546 VP_DCFG_CRT_EN); 546 VP_DCFG_CRT_EN);
547 if (!blank) 547 if (!blank)
548 dcfg |= VP_DCFG_DAC_BL_EN; 548 dcfg |= VP_DCFG_DAC_BL_EN | VP_DCFG_CRT_EN;
549 if (hsync) 549 if (hsync)
550 dcfg |= VP_DCFG_HSYNC_EN; 550 dcfg |= VP_DCFG_HSYNC_EN;
551 if (vsync) 551 if (vsync)
552 dcfg |= VP_DCFG_VSYNC_EN; 552 dcfg |= VP_DCFG_VSYNC_EN;
553 if (crt) 553
554 dcfg |= VP_DCFG_CRT_EN;
555 write_vp(par, VP_DCFG, dcfg); 554 write_vp(par, VP_DCFG, dcfg);
556 555
556 misc = read_vp(par, VP_MISC);
557
558 if (vsync && hsync)
559 misc &= ~VP_MISC_DACPWRDN;
560 else
561 misc |= VP_MISC_DACPWRDN;
562
563 write_vp(par, VP_MISC, misc);
564
557 /* Power on/off flat panel */ 565 /* Power on/off flat panel */
558 566
559 if (par->output & OUTPUT_PANEL) { 567 if (par->output & OUTPUT_PANEL) {
diff --git a/drivers/video/hgafb.c b/drivers/video/hgafb.c
index c18880d9db1f..0129c044f6d6 100644
--- a/drivers/video/hgafb.c
+++ b/drivers/video/hgafb.c
@@ -551,7 +551,7 @@ static struct fb_ops hgafb_ops = {
551 * Initialization 551 * Initialization
552 */ 552 */
553 553
554static int __init hgafb_probe(struct device *device) 554static int __init hgafb_probe(struct platform_device *pdev)
555{ 555{
556 struct fb_info *info; 556 struct fb_info *info;
557 557
@@ -565,7 +565,7 @@ static int __init hgafb_probe(struct device *device)
565 printk(KERN_INFO "hgafb: %s with %ldK of memory detected.\n", 565 printk(KERN_INFO "hgafb: %s with %ldK of memory detected.\n",
566 hga_type_name, hga_vram_len/1024); 566 hga_type_name, hga_vram_len/1024);
567 567
568 info = framebuffer_alloc(0, NULL); 568 info = framebuffer_alloc(0, &pdev->dev);
569 if (!info) { 569 if (!info) {
570 iounmap(hga_vram); 570 iounmap(hga_vram);
571 return -ENOMEM; 571 return -ENOMEM;
@@ -593,13 +593,13 @@ static int __init hgafb_probe(struct device *device)
593 593
594 printk(KERN_INFO "fb%d: %s frame buffer device\n", 594 printk(KERN_INFO "fb%d: %s frame buffer device\n",
595 info->node, info->fix.id); 595 info->node, info->fix.id);
596 dev_set_drvdata(device, info); 596 platform_set_drvdata(pdev, info);
597 return 0; 597 return 0;
598} 598}
599 599
600static int hgafb_remove(struct device *device) 600static int hgafb_remove(struct platform_device *pdev)
601{ 601{
602 struct fb_info *info = dev_get_drvdata(device); 602 struct fb_info *info = platform_get_drvdata(pdev);
603 603
604 hga_txt_mode(); 604 hga_txt_mode();
605 hga_clear_screen(); 605 hga_clear_screen();
@@ -620,16 +620,15 @@ static int hgafb_remove(struct device *device)
620 return 0; 620 return 0;
621} 621}
622 622
623static struct device_driver hgafb_driver = { 623static struct platform_driver hgafb_driver = {
624 .name = "hgafb",
625 .bus = &platform_bus_type,
626 .probe = hgafb_probe, 624 .probe = hgafb_probe,
627 .remove = hgafb_remove, 625 .remove = hgafb_remove,
626 .driver = {
627 .name = "hgafb",
628 },
628}; 629};
629 630
630static struct platform_device hgafb_device = { 631static struct platform_device *hgafb_device;
631 .name = "hgafb",
632};
633 632
634static int __init hgafb_init(void) 633static int __init hgafb_init(void)
635{ 634{
@@ -638,12 +637,15 @@ static int __init hgafb_init(void)
638 if (fb_get_options("hgafb", NULL)) 637 if (fb_get_options("hgafb", NULL))
639 return -ENODEV; 638 return -ENODEV;
640 639
641 ret = driver_register(&hgafb_driver); 640 ret = platform_driver_register(&hgafb_driver);
642 641
643 if (!ret) { 642 if (!ret) {
644 ret = platform_device_register(&hgafb_device); 643 hgafb_device = platform_device_register_simple("hgafb", 0, NULL, 0);
645 if (ret) 644
646 driver_unregister(&hgafb_driver); 645 if (IS_ERR(hgafb_device)) {
646 platform_driver_unregister(&hgafb_driver);
647 ret = PTR_ERR(hgafb_device);
648 }
647 } 649 }
648 650
649 return ret; 651 return ret;
@@ -651,8 +653,8 @@ static int __init hgafb_init(void)
651 653
652static void __exit hgafb_exit(void) 654static void __exit hgafb_exit(void)
653{ 655{
654 platform_device_unregister(&hgafb_device); 656 platform_device_unregister(hgafb_device);
655 driver_unregister(&hgafb_driver); 657 platform_driver_unregister(&hgafb_driver);
656} 658}
657 659
658/* ------------------------------------------------------------------------- 660/* -------------------------------------------------------------------------
diff --git a/drivers/video/imxfb.c b/drivers/video/imxfb.c
index 94e4d3ac1a05..0c5a475c1cae 100644
--- a/drivers/video/imxfb.c
+++ b/drivers/video/imxfb.c
@@ -24,6 +24,7 @@
24#include <linux/string.h> 24#include <linux/string.h>
25#include <linux/interrupt.h> 25#include <linux/interrupt.h>
26#include <linux/slab.h> 26#include <linux/slab.h>
27#include <linux/mm.h>
27#include <linux/fb.h> 28#include <linux/fb.h>
28#include <linux/delay.h> 29#include <linux/delay.h>
29#include <linux/init.h> 30#include <linux/init.h>
diff --git a/drivers/video/neofb.c b/drivers/video/neofb.c
index 5246b0402d76..25172b2a2a94 100644
--- a/drivers/video/neofb.c
+++ b/drivers/video/neofb.c
@@ -201,7 +201,6 @@ static int neoFindMode(int xres, int yres, int depth)
201 * 201 *
202 * Determine the closest clock frequency to the one requested. 202 * Determine the closest clock frequency to the one requested.
203 */ 203 */
204#define REF_FREQ 0xe517 /* 14.31818 in 20.12 fixed point */
205#define MAX_N 127 204#define MAX_N 127
206#define MAX_D 31 205#define MAX_D 31
207#define MAX_F 1 206#define MAX_F 1
@@ -211,27 +210,24 @@ static void neoCalcVCLK(const struct fb_info *info,
211{ 210{
212 int n, d, f; 211 int n, d, f;
213 int n_best = 0, d_best = 0, f_best = 0; 212 int n_best = 0, d_best = 0, f_best = 0;
214 long f_best_diff = (0x7ffff << 12); /* 20.12 */ 213 long f_best_diff = 0x7ffff;
215 long f_target = (freq << 12) / 1000; /* 20.12 */
216 214
217 for (f = 0; f <= MAX_F; f++) 215 for (f = 0; f <= MAX_F; f++)
218 for (n = 0; n <= MAX_N; n++) 216 for (d = 0; d <= MAX_D; d++)
219 for (d = 0; d <= MAX_D; d++) { 217 for (n = 0; n <= MAX_N; n++) {
220 long f_out; /* 20.12 */ 218 long f_out;
221 long f_diff; /* 20.12 */ 219 long f_diff;
222 220
223 f_out = 221 f_out = ((14318 * (n + 1)) / (d + 1)) >> f;
224 ((((n + 1) << 12) / ((d + 222 f_diff = abs(f_out - freq);
225 1) * 223 if (f_diff <= f_best_diff) {
226 (1 << f))) >> 12)
227 * REF_FREQ;
228 f_diff = abs(f_out - f_target);
229 if (f_diff < f_best_diff) {
230 f_best_diff = f_diff; 224 f_best_diff = f_diff;
231 n_best = n; 225 n_best = n;
232 d_best = d; 226 d_best = d;
233 f_best = f; 227 f_best = f;
234 } 228 }
229 if (f_out > freq)
230 break;
235 } 231 }
236 232
237 if (info->fix.accel == FB_ACCEL_NEOMAGIC_NM2200 || 233 if (info->fix.accel == FB_ACCEL_NEOMAGIC_NM2200 ||
@@ -248,11 +244,11 @@ static void neoCalcVCLK(const struct fb_info *info,
248 par->VCLK3Denominator = d_best; 244 par->VCLK3Denominator = d_best;
249 245
250#ifdef NEOFB_DEBUG 246#ifdef NEOFB_DEBUG
251 printk("neoVCLK: f:%d NumLow=%d NumHi=%d Den=%d Df=%d\n", 247 printk(KERN_DEBUG "neoVCLK: f:%ld NumLow=%d NumHi=%d Den=%d Df=%ld\n",
252 f_target >> 12, 248 freq,
253 par->VCLK3NumeratorLow, 249 par->VCLK3NumeratorLow,
254 par->VCLK3NumeratorHigh, 250 par->VCLK3NumeratorHigh,
255 par->VCLK3Denominator, f_best_diff >> 12); 251 par->VCLK3Denominator, f_best_diff);
256#endif 252#endif
257} 253}
258 254
@@ -263,15 +259,20 @@ static void neoCalcVCLK(const struct fb_info *info,
263 */ 259 */
264 260
265static int vgaHWInit(const struct fb_var_screeninfo *var, 261static int vgaHWInit(const struct fb_var_screeninfo *var,
266 const struct fb_info *info, 262 struct neofb_par *par)
267 struct neofb_par *par, struct xtimings *timings)
268{ 263{
264 int hsync_end = var->xres + var->right_margin + var->hsync_len;
265 int htotal = (hsync_end + var->left_margin) >> 3;
266 int vsync_start = var->yres + var->lower_margin;
267 int vsync_end = vsync_start + var->vsync_len;
268 int vtotal = vsync_end + var->upper_margin;
269
269 par->MiscOutReg = 0x23; 270 par->MiscOutReg = 0x23;
270 271
271 if (!(timings->sync & FB_SYNC_HOR_HIGH_ACT)) 272 if (!(var->sync & FB_SYNC_HOR_HIGH_ACT))
272 par->MiscOutReg |= 0x40; 273 par->MiscOutReg |= 0x40;
273 274
274 if (!(timings->sync & FB_SYNC_VERT_HIGH_ACT)) 275 if (!(var->sync & FB_SYNC_VERT_HIGH_ACT))
275 par->MiscOutReg |= 0x80; 276 par->MiscOutReg |= 0x80;
276 277
277 /* 278 /*
@@ -286,25 +287,25 @@ static int vgaHWInit(const struct fb_var_screeninfo *var,
286 /* 287 /*
287 * CRTC Controller 288 * CRTC Controller
288 */ 289 */
289 par->CRTC[0] = (timings->HTotal >> 3) - 5; 290 par->CRTC[0] = htotal - 5;
290 par->CRTC[1] = (timings->HDisplay >> 3) - 1; 291 par->CRTC[1] = (var->xres >> 3) - 1;
291 par->CRTC[2] = (timings->HDisplay >> 3) - 1; 292 par->CRTC[2] = (var->xres >> 3) - 1;
292 par->CRTC[3] = (((timings->HTotal >> 3) - 1) & 0x1F) | 0x80; 293 par->CRTC[3] = ((htotal - 1) & 0x1F) | 0x80;
293 par->CRTC[4] = (timings->HSyncStart >> 3); 294 par->CRTC[4] = ((var->xres + var->right_margin) >> 3);
294 par->CRTC[5] = ((((timings->HTotal >> 3) - 1) & 0x20) << 2) 295 par->CRTC[5] = (((htotal - 1) & 0x20) << 2)
295 | (((timings->HSyncEnd >> 3)) & 0x1F); 296 | (((hsync_end >> 3)) & 0x1F);
296 par->CRTC[6] = (timings->VTotal - 2) & 0xFF; 297 par->CRTC[6] = (vtotal - 2) & 0xFF;
297 par->CRTC[7] = (((timings->VTotal - 2) & 0x100) >> 8) 298 par->CRTC[7] = (((vtotal - 2) & 0x100) >> 8)
298 | (((timings->VDisplay - 1) & 0x100) >> 7) 299 | (((var->yres - 1) & 0x100) >> 7)
299 | ((timings->VSyncStart & 0x100) >> 6) 300 | ((vsync_start & 0x100) >> 6)
300 | (((timings->VDisplay - 1) & 0x100) >> 5) 301 | (((var->yres - 1) & 0x100) >> 5)
301 | 0x10 | (((timings->VTotal - 2) & 0x200) >> 4) 302 | 0x10 | (((vtotal - 2) & 0x200) >> 4)
302 | (((timings->VDisplay - 1) & 0x200) >> 3) 303 | (((var->yres - 1) & 0x200) >> 3)
303 | ((timings->VSyncStart & 0x200) >> 2); 304 | ((vsync_start & 0x200) >> 2);
304 par->CRTC[8] = 0x00; 305 par->CRTC[8] = 0x00;
305 par->CRTC[9] = (((timings->VDisplay - 1) & 0x200) >> 4) | 0x40; 306 par->CRTC[9] = (((var->yres - 1) & 0x200) >> 4) | 0x40;
306 307
307 if (timings->dblscan) 308 if (var->vmode & FB_VMODE_DOUBLE)
308 par->CRTC[9] |= 0x80; 309 par->CRTC[9] |= 0x80;
309 310
310 par->CRTC[10] = 0x00; 311 par->CRTC[10] = 0x00;
@@ -313,13 +314,13 @@ static int vgaHWInit(const struct fb_var_screeninfo *var,
313 par->CRTC[13] = 0x00; 314 par->CRTC[13] = 0x00;
314 par->CRTC[14] = 0x00; 315 par->CRTC[14] = 0x00;
315 par->CRTC[15] = 0x00; 316 par->CRTC[15] = 0x00;
316 par->CRTC[16] = timings->VSyncStart & 0xFF; 317 par->CRTC[16] = vsync_start & 0xFF;
317 par->CRTC[17] = (timings->VSyncEnd & 0x0F) | 0x20; 318 par->CRTC[17] = (vsync_end & 0x0F) | 0x20;
318 par->CRTC[18] = (timings->VDisplay - 1) & 0xFF; 319 par->CRTC[18] = (var->yres - 1) & 0xFF;
319 par->CRTC[19] = var->xres_virtual >> 4; 320 par->CRTC[19] = var->xres_virtual >> 4;
320 par->CRTC[20] = 0x00; 321 par->CRTC[20] = 0x00;
321 par->CRTC[21] = (timings->VDisplay - 1) & 0xFF; 322 par->CRTC[21] = (var->yres - 1) & 0xFF;
322 par->CRTC[22] = (timings->VTotal - 1) & 0xFF; 323 par->CRTC[22] = (vtotal - 1) & 0xFF;
323 par->CRTC[23] = 0xC3; 324 par->CRTC[23] = 0xC3;
324 par->CRTC[24] = 0xFF; 325 par->CRTC[24] = 0xFF;
325 326
@@ -483,7 +484,8 @@ static inline int neo2200_sync(struct fb_info *info)
483{ 484{
484 struct neofb_par *par = info->par; 485 struct neofb_par *par = info->par;
485 486
486 while (readl(&par->neo2200->bltStat) & 1); 487 while (readl(&par->neo2200->bltStat) & 1)
488 cpu_relax();
487 return 0; 489 return 0;
488} 490}
489 491
@@ -591,34 +593,14 @@ static int
591neofb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) 593neofb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
592{ 594{
593 struct neofb_par *par = info->par; 595 struct neofb_par *par = info->par;
594 unsigned int pixclock = var->pixclock;
595 struct xtimings timings;
596 int memlen, vramlen; 596 int memlen, vramlen;
597 int mode_ok = 0; 597 int mode_ok = 0;
598 598
599 DBG("neofb_check_var"); 599 DBG("neofb_check_var");
600 600
601 if (!pixclock) 601 if (PICOS2KHZ(var->pixclock) > par->maxClock)
602 pixclock = 10000; /* 10ns = 100MHz */
603 timings.pixclock = 1000000000 / pixclock;
604 if (timings.pixclock < 1)
605 timings.pixclock = 1;
606
607 if (timings.pixclock > par->maxClock)
608 return -EINVAL; 602 return -EINVAL;
609 603
610 timings.dblscan = var->vmode & FB_VMODE_DOUBLE;
611 timings.interlaced = var->vmode & FB_VMODE_INTERLACED;
612 timings.HDisplay = var->xres;
613 timings.HSyncStart = timings.HDisplay + var->right_margin;
614 timings.HSyncEnd = timings.HSyncStart + var->hsync_len;
615 timings.HTotal = timings.HSyncEnd + var->left_margin;
616 timings.VDisplay = var->yres;
617 timings.VSyncStart = timings.VDisplay + var->lower_margin;
618 timings.VSyncEnd = timings.VSyncStart + var->vsync_len;
619 timings.VTotal = timings.VSyncEnd + var->upper_margin;
620 timings.sync = var->sync;
621
622 /* Is the mode larger than the LCD panel? */ 604 /* Is the mode larger than the LCD panel? */
623 if (par->internal_display && 605 if (par->internal_display &&
624 ((var->xres > par->NeoPanelWidth) || 606 ((var->xres > par->NeoPanelWidth) ||
@@ -759,11 +741,11 @@ neofb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
759static int neofb_set_par(struct fb_info *info) 741static int neofb_set_par(struct fb_info *info)
760{ 742{
761 struct neofb_par *par = info->par; 743 struct neofb_par *par = info->par;
762 struct xtimings timings;
763 unsigned char temp; 744 unsigned char temp;
764 int i, clock_hi = 0; 745 int i, clock_hi = 0;
765 int lcd_stretch; 746 int lcd_stretch;
766 int hoffset, voffset; 747 int hoffset, voffset;
748 int vsync_start, vtotal;
767 749
768 DBG("neofb_set_par"); 750 DBG("neofb_set_par");
769 751
@@ -771,28 +753,15 @@ static int neofb_set_par(struct fb_info *info)
771 753
772 vgaHWProtect(1); /* Blank the screen */ 754 vgaHWProtect(1); /* Blank the screen */
773 755
774 timings.dblscan = info->var.vmode & FB_VMODE_DOUBLE; 756 vsync_start = info->var.yres + info->var.lower_margin;
775 timings.interlaced = info->var.vmode & FB_VMODE_INTERLACED; 757 vtotal = vsync_start + info->var.vsync_len + info->var.upper_margin;
776 timings.HDisplay = info->var.xres;
777 timings.HSyncStart = timings.HDisplay + info->var.right_margin;
778 timings.HSyncEnd = timings.HSyncStart + info->var.hsync_len;
779 timings.HTotal = timings.HSyncEnd + info->var.left_margin;
780 timings.VDisplay = info->var.yres;
781 timings.VSyncStart = timings.VDisplay + info->var.lower_margin;
782 timings.VSyncEnd = timings.VSyncStart + info->var.vsync_len;
783 timings.VTotal = timings.VSyncEnd + info->var.upper_margin;
784 timings.sync = info->var.sync;
785 timings.pixclock = PICOS2KHZ(info->var.pixclock);
786
787 if (timings.pixclock < 1)
788 timings.pixclock = 1;
789 758
790 /* 759 /*
791 * This will allocate the datastructure and initialize all of the 760 * This will allocate the datastructure and initialize all of the
792 * generic VGA registers. 761 * generic VGA registers.
793 */ 762 */
794 763
795 if (vgaHWInit(&info->var, info, par, &timings)) 764 if (vgaHWInit(&info->var, par))
796 return -EINVAL; 765 return -EINVAL;
797 766
798 /* 767 /*
@@ -831,10 +800,10 @@ static int neofb_set_par(struct fb_info *info)
831 par->ExtCRTDispAddr = 0x10; 800 par->ExtCRTDispAddr = 0x10;
832 801
833 /* Vertical Extension */ 802 /* Vertical Extension */
834 par->VerticalExt = (((timings.VTotal - 2) & 0x400) >> 10) 803 par->VerticalExt = (((vtotal - 2) & 0x400) >> 10)
835 | (((timings.VDisplay - 1) & 0x400) >> 9) 804 | (((info->var.yres - 1) & 0x400) >> 9)
836 | (((timings.VSyncStart) & 0x400) >> 8) 805 | (((vsync_start) & 0x400) >> 8)
837 | (((timings.VSyncStart) & 0x400) >> 7); 806 | (((vsync_start) & 0x400) >> 7);
838 807
839 /* Fast write bursts on unless disabled. */ 808 /* Fast write bursts on unless disabled. */
840 if (par->pci_burst) 809 if (par->pci_burst)
@@ -995,7 +964,7 @@ static int neofb_set_par(struct fb_info *info)
995 * Calculate the VCLK that most closely matches the requested dot 964 * Calculate the VCLK that most closely matches the requested dot
996 * clock. 965 * clock.
997 */ 966 */
998 neoCalcVCLK(info, par, timings.pixclock); 967 neoCalcVCLK(info, par, PICOS2KHZ(info->var.pixclock));
999 968
1000 /* Since we program the clocks ourselves, always use VCLK3. */ 969 /* Since we program the clocks ourselves, always use VCLK3. */
1001 par->MiscOutReg |= 0x0C; 970 par->MiscOutReg |= 0x0C;
@@ -1927,9 +1896,6 @@ static int __devinit neo_init_hw(struct fb_info *info)
1927 int maxClock = 65000; 1896 int maxClock = 65000;
1928 int CursorMem = 1024; 1897 int CursorMem = 1024;
1929 int CursorOff = 0x100; 1898 int CursorOff = 0x100;
1930 int linearSize = 1024;
1931 int maxWidth = 1024;
1932 int maxHeight = 1024;
1933 1899
1934 DBG("neo_init_hw"); 1900 DBG("neo_init_hw");
1935 1901
@@ -1948,81 +1914,52 @@ static int __devinit neo_init_hw(struct fb_info *info)
1948 case FB_ACCEL_NEOMAGIC_NM2070: 1914 case FB_ACCEL_NEOMAGIC_NM2070:
1949 videoRam = 896; 1915 videoRam = 896;
1950 maxClock = 65000; 1916 maxClock = 65000;
1951 CursorMem = 2048;
1952 CursorOff = 0x100;
1953 linearSize = 1024;
1954 maxWidth = 1024;
1955 maxHeight = 1024;
1956 break; 1917 break;
1957 case FB_ACCEL_NEOMAGIC_NM2090: 1918 case FB_ACCEL_NEOMAGIC_NM2090:
1958 case FB_ACCEL_NEOMAGIC_NM2093: 1919 case FB_ACCEL_NEOMAGIC_NM2093:
1959 videoRam = 1152;
1960 maxClock = 80000;
1961 CursorMem = 2048;
1962 CursorOff = 0x100;
1963 linearSize = 2048;
1964 maxWidth = 1024;
1965 maxHeight = 1024;
1966 break;
1967 case FB_ACCEL_NEOMAGIC_NM2097: 1920 case FB_ACCEL_NEOMAGIC_NM2097:
1968 videoRam = 1152; 1921 videoRam = 1152;
1969 maxClock = 80000; 1922 maxClock = 80000;
1970 CursorMem = 1024;
1971 CursorOff = 0x100;
1972 linearSize = 2048;
1973 maxWidth = 1024;
1974 maxHeight = 1024;
1975 break; 1923 break;
1976 case FB_ACCEL_NEOMAGIC_NM2160: 1924 case FB_ACCEL_NEOMAGIC_NM2160:
1977 videoRam = 2048; 1925 videoRam = 2048;
1978 maxClock = 90000; 1926 maxClock = 90000;
1979 CursorMem = 1024;
1980 CursorOff = 0x100;
1981 linearSize = 2048;
1982 maxWidth = 1024;
1983 maxHeight = 1024;
1984 break; 1927 break;
1985 case FB_ACCEL_NEOMAGIC_NM2200: 1928 case FB_ACCEL_NEOMAGIC_NM2200:
1986 videoRam = 2560; 1929 videoRam = 2560;
1987 maxClock = 110000; 1930 maxClock = 110000;
1988 CursorMem = 1024;
1989 CursorOff = 0x1000;
1990 linearSize = 4096;
1991 maxWidth = 1280;
1992 maxHeight = 1024; /* ???? */
1993
1994 par->neo2200 = (Neo2200 __iomem *) par->mmio_vbase;
1995 break; 1931 break;
1996 case FB_ACCEL_NEOMAGIC_NM2230: 1932 case FB_ACCEL_NEOMAGIC_NM2230:
1997 videoRam = 3008; 1933 videoRam = 3008;
1998 maxClock = 110000; 1934 maxClock = 110000;
1999 CursorMem = 1024;
2000 CursorOff = 0x1000;
2001 linearSize = 4096;
2002 maxWidth = 1280;
2003 maxHeight = 1024; /* ???? */
2004
2005 par->neo2200 = (Neo2200 __iomem *) par->mmio_vbase;
2006 break; 1935 break;
2007 case FB_ACCEL_NEOMAGIC_NM2360: 1936 case FB_ACCEL_NEOMAGIC_NM2360:
2008 videoRam = 4096; 1937 videoRam = 4096;
2009 maxClock = 110000; 1938 maxClock = 110000;
2010 CursorMem = 1024;
2011 CursorOff = 0x1000;
2012 linearSize = 4096;
2013 maxWidth = 1280;
2014 maxHeight = 1024; /* ???? */
2015
2016 par->neo2200 = (Neo2200 __iomem *) par->mmio_vbase;
2017 break; 1939 break;
2018 case FB_ACCEL_NEOMAGIC_NM2380: 1940 case FB_ACCEL_NEOMAGIC_NM2380:
2019 videoRam = 6144; 1941 videoRam = 6144;
2020 maxClock = 110000; 1942 maxClock = 110000;
1943 break;
1944 }
1945 switch (info->fix.accel) {
1946 case FB_ACCEL_NEOMAGIC_NM2070:
1947 case FB_ACCEL_NEOMAGIC_NM2090:
1948 case FB_ACCEL_NEOMAGIC_NM2093:
1949 CursorMem = 2048;
1950 CursorOff = 0x100;
1951 break;
1952 case FB_ACCEL_NEOMAGIC_NM2097:
1953 case FB_ACCEL_NEOMAGIC_NM2160:
1954 CursorMem = 1024;
1955 CursorOff = 0x100;
1956 break;
1957 case FB_ACCEL_NEOMAGIC_NM2200:
1958 case FB_ACCEL_NEOMAGIC_NM2230:
1959 case FB_ACCEL_NEOMAGIC_NM2360:
1960 case FB_ACCEL_NEOMAGIC_NM2380:
2021 CursorMem = 1024; 1961 CursorMem = 1024;
2022 CursorOff = 0x1000; 1962 CursorOff = 0x1000;
2023 linearSize = 8192;
2024 maxWidth = 1280;
2025 maxHeight = 1024; /* ???? */
2026 1963
2027 par->neo2200 = (Neo2200 __iomem *) par->mmio_vbase; 1964 par->neo2200 = (Neo2200 __iomem *) par->mmio_vbase;
2028 break; 1965 break;
@@ -2036,7 +1973,7 @@ static int __devinit neo_init_hw(struct fb_info *info)
2036*/ 1973*/
2037 par->maxClock = maxClock; 1974 par->maxClock = maxClock;
2038 par->cursorOff = CursorOff; 1975 par->cursorOff = CursorOff;
2039 return ((videoRam * 1024)); 1976 return videoRam * 1024;
2040} 1977}
2041 1978
2042 1979
diff --git a/drivers/video/omap/dispc.c b/drivers/video/omap/dispc.c
index ab32ceb06178..ab77c51fe9d6 100644
--- a/drivers/video/omap/dispc.c
+++ b/drivers/video/omap/dispc.c
@@ -20,6 +20,7 @@
20 */ 20 */
21#include <linux/kernel.h> 21#include <linux/kernel.h>
22#include <linux/dma-mapping.h> 22#include <linux/dma-mapping.h>
23#include <linux/mm.h>
23#include <linux/vmalloc.h> 24#include <linux/vmalloc.h>
24#include <linux/clk.h> 25#include <linux/clk.h>
25#include <linux/io.h> 26#include <linux/io.h>
diff --git a/drivers/video/omap/omapfb_main.c b/drivers/video/omap/omapfb_main.c
index 14d0f7a11145..f85af5c4fa68 100644
--- a/drivers/video/omap/omapfb_main.c
+++ b/drivers/video/omap/omapfb_main.c
@@ -25,6 +25,7 @@
25 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 25 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
26 */ 26 */
27#include <linux/platform_device.h> 27#include <linux/platform_device.h>
28#include <linux/mm.h>
28#include <linux/uaccess.h> 29#include <linux/uaccess.h>
29 30
30#include <asm/mach-types.h> 31#include <asm/mach-types.h>
diff --git a/drivers/video/pxafb.c b/drivers/video/pxafb.c
index bb2514369507..2b707a8ce5de 100644
--- a/drivers/video/pxafb.c
+++ b/drivers/video/pxafb.c
@@ -30,6 +30,7 @@
30#include <linux/string.h> 30#include <linux/string.h>
31#include <linux/interrupt.h> 31#include <linux/interrupt.h>
32#include <linux/slab.h> 32#include <linux/slab.h>
33#include <linux/mm.h>
33#include <linux/fb.h> 34#include <linux/fb.h>
34#include <linux/delay.h> 35#include <linux/delay.h>
35#include <linux/init.h> 36#include <linux/init.h>
@@ -40,6 +41,7 @@
40#include <linux/clk.h> 41#include <linux/clk.h>
41#include <linux/err.h> 42#include <linux/err.h>
42#include <linux/completion.h> 43#include <linux/completion.h>
44#include <linux/mutex.h>
43#include <linux/kthread.h> 45#include <linux/kthread.h>
44#include <linux/freezer.h> 46#include <linux/freezer.h>
45 47
@@ -1116,7 +1118,7 @@ static void set_ctrlr_state(struct pxafb_info *fbi, u_int state)
1116{ 1118{
1117 u_int old_state; 1119 u_int old_state;
1118 1120
1119 down(&fbi->ctrlr_sem); 1121 mutex_lock(&fbi->ctrlr_lock);
1120 1122
1121 old_state = fbi->state; 1123 old_state = fbi->state;
1122 1124
@@ -1204,7 +1206,7 @@ static void set_ctrlr_state(struct pxafb_info *fbi, u_int state)
1204 } 1206 }
1205 break; 1207 break;
1206 } 1208 }
1207 up(&fbi->ctrlr_sem); 1209 mutex_unlock(&fbi->ctrlr_lock);
1208} 1210}
1209 1211
1210/* 1212/*
@@ -1457,7 +1459,7 @@ static struct pxafb_info * __devinit pxafb_init_fbinfo(struct device *dev)
1457 1459
1458 init_waitqueue_head(&fbi->ctrlr_wait); 1460 init_waitqueue_head(&fbi->ctrlr_wait);
1459 INIT_WORK(&fbi->task, pxafb_task); 1461 INIT_WORK(&fbi->task, pxafb_task);
1460 init_MUTEX(&fbi->ctrlr_sem); 1462 mutex_init(&fbi->ctrlr_lock);
1461 init_completion(&fbi->disable_done); 1463 init_completion(&fbi->disable_done);
1462#ifdef CONFIG_FB_PXA_SMARTPANEL 1464#ifdef CONFIG_FB_PXA_SMARTPANEL
1463 init_completion(&fbi->command_done); 1465 init_completion(&fbi->command_done);
diff --git a/drivers/video/pxafb.h b/drivers/video/pxafb.h
index 8238dc826429..31541b86f13d 100644
--- a/drivers/video/pxafb.h
+++ b/drivers/video/pxafb.h
@@ -106,7 +106,7 @@ struct pxafb_info {
106 106
107 volatile u_char state; 107 volatile u_char state;
108 volatile u_char task_state; 108 volatile u_char task_state;
109 struct semaphore ctrlr_sem; 109 struct mutex ctrlr_lock;
110 wait_queue_head_t ctrlr_wait; 110 wait_queue_head_t ctrlr_wait;
111 struct work_struct task; 111 struct work_struct task;
112 112
diff --git a/drivers/video/sa1100fb.c b/drivers/video/sa1100fb.c
index ab2b2110478b..78bcdbc3f484 100644
--- a/drivers/video/sa1100fb.c
+++ b/drivers/video/sa1100fb.c
@@ -167,6 +167,7 @@
167#include <linux/string.h> 167#include <linux/string.h>
168#include <linux/interrupt.h> 168#include <linux/interrupt.h>
169#include <linux/slab.h> 169#include <linux/slab.h>
170#include <linux/mm.h>
170#include <linux/fb.h> 171#include <linux/fb.h>
171#include <linux/delay.h> 172#include <linux/delay.h>
172#include <linux/init.h> 173#include <linux/init.h>
@@ -174,6 +175,7 @@
174#include <linux/cpufreq.h> 175#include <linux/cpufreq.h>
175#include <linux/platform_device.h> 176#include <linux/platform_device.h>
176#include <linux/dma-mapping.h> 177#include <linux/dma-mapping.h>
178#include <linux/mutex.h>
177 179
178#include <asm/hardware.h> 180#include <asm/hardware.h>
179#include <asm/io.h> 181#include <asm/io.h>
@@ -1107,7 +1109,7 @@ static void set_ctrlr_state(struct sa1100fb_info *fbi, u_int state)
1107{ 1109{
1108 u_int old_state; 1110 u_int old_state;
1109 1111
1110 down(&fbi->ctrlr_sem); 1112 mutex_lock(&fbi->ctrlr_lock);
1111 1113
1112 old_state = fbi->state; 1114 old_state = fbi->state;
1113 1115
@@ -1192,7 +1194,7 @@ static void set_ctrlr_state(struct sa1100fb_info *fbi, u_int state)
1192 } 1194 }
1193 break; 1195 break;
1194 } 1196 }
1195 up(&fbi->ctrlr_sem); 1197 mutex_unlock(&fbi->ctrlr_lock);
1196} 1198}
1197 1199
1198/* 1200/*
@@ -1444,7 +1446,7 @@ static struct sa1100fb_info * __init sa1100fb_init_fbinfo(struct device *dev)
1444 1446
1445 init_waitqueue_head(&fbi->ctrlr_wait); 1447 init_waitqueue_head(&fbi->ctrlr_wait);
1446 INIT_WORK(&fbi->task, sa1100fb_task); 1448 INIT_WORK(&fbi->task, sa1100fb_task);
1447 init_MUTEX(&fbi->ctrlr_sem); 1449 mutex_init(&fbi->ctrlr_lock);
1448 1450
1449 return fbi; 1451 return fbi;
1450} 1452}
diff --git a/drivers/video/sa1100fb.h b/drivers/video/sa1100fb.h
index f465b27ed860..86831db9a042 100644
--- a/drivers/video/sa1100fb.h
+++ b/drivers/video/sa1100fb.h
@@ -100,7 +100,7 @@ struct sa1100fb_info {
100 100
101 volatile u_char state; 101 volatile u_char state;
102 volatile u_char task_state; 102 volatile u_char task_state;
103 struct semaphore ctrlr_sem; 103 struct mutex ctrlr_lock;
104 wait_queue_head_t ctrlr_wait; 104 wait_queue_head_t ctrlr_wait;
105 struct work_struct task; 105 struct work_struct task;
106 106
diff --git a/drivers/video/sh7760fb.c b/drivers/video/sh7760fb.c
new file mode 100644
index 000000000000..4d0e28c5790b
--- /dev/null
+++ b/drivers/video/sh7760fb.c
@@ -0,0 +1,658 @@
1/*
2 * SH7760/SH7763 LCDC Framebuffer driver.
3 *
4 * (c) 2006-2008 MSC Vertriebsges.m.b.H.,
5 * Manuel Lauss <mano@roarinelk.homelinux.net>
6 * (c) 2008 Nobuhiro Iwamatsu <iwamatsu.nobuhiro@renesas.com>
7 *
8 * This file is subject to the terms and conditions of the GNU General
9 * Public License. See the file COPYING in the main directory of this
10 * archive for more details.
11 *
12 * PLEASE HAVE A LOOK AT Documentation/fb/sh7760fb.txt!
13 *
14 * Thanks to Siegfried Schaefer <s.schaefer at schaefer-edv.de>
15 * for his original source and testing!
16 */
17
18#include <linux/completion.h>
19#include <linux/delay.h>
20#include <linux/dma-mapping.h>
21#include <linux/fb.h>
22#include <linux/interrupt.h>
23#include <linux/io.h>
24#include <linux/kernel.h>
25#include <linux/module.h>
26#include <linux/platform_device.h>
27
28#include <asm/sh7760fb.h>
29
30struct sh7760fb_par {
31 void __iomem *base;
32 int irq;
33
34 struct sh7760fb_platdata *pd; /* display information */
35
36 dma_addr_t fbdma; /* physical address */
37
38 int rot; /* rotation enabled? */
39
40 u32 pseudo_palette[16];
41
42 struct platform_device *dev;
43 struct resource *ioarea;
44 struct completion vsync; /* vsync irq event */
45};
46
47static irqreturn_t sh7760fb_irq(int irq, void *data)
48{
49 struct completion *c = data;
50
51 complete(c);
52
53 return IRQ_HANDLED;
54}
55
56static void sh7760fb_wait_vsync(struct fb_info *info)
57{
58 struct sh7760fb_par *par = info->par;
59
60 if (par->pd->novsync)
61 return;
62
63 iowrite16(ioread16(par->base + LDINTR) & ~VINT_CHECK,
64 par->base + LDINTR);
65
66 if (par->irq < 0) {
67 /* poll for vert. retrace: status bit is sticky */
68 while (!(ioread16(par->base + LDINTR) & VINT_CHECK))
69 cpu_relax();
70 } else {
71 /* a "wait_for_irq_event(par->irq)" would be extremely nice */
72 init_completion(&par->vsync);
73 enable_irq(par->irq);
74 wait_for_completion(&par->vsync);
75 disable_irq_nosync(par->irq);
76 }
77}
78
79/* wait_for_lps - wait until power supply has reached a certain state. */
80static int wait_for_lps(struct sh7760fb_par *par, int val)
81{
82 int i = 100;
83 while (--i && ((ioread16(par->base + LDPMMR) & 3) != val))
84 msleep(1);
85
86 if (i <= 0)
87 return -ETIMEDOUT;
88
89 return 0;
90}
91
92/* en/disable the LCDC */
93static int sh7760fb_blank(int blank, struct fb_info *info)
94{
95 struct sh7760fb_par *par = info->par;
96 struct sh7760fb_platdata *pd = par->pd;
97 unsigned short cntr = ioread16(par->base + LDCNTR);
98 unsigned short intr = ioread16(par->base + LDINTR);
99 int lps;
100
101 if (blank == FB_BLANK_UNBLANK) {
102 intr |= VINT_START;
103 cntr = LDCNTR_DON2 | LDCNTR_DON;
104 lps = 3;
105 } else {
106 intr &= ~VINT_START;
107 cntr = LDCNTR_DON2;
108 lps = 0;
109 }
110
111 if (pd->blank)
112 pd->blank(blank);
113
114 iowrite16(intr, par->base + LDINTR);
115 iowrite16(cntr, par->base + LDCNTR);
116
117 return wait_for_lps(par, lps);
118}
119
120/* set color registers */
121static int sh7760fb_setcmap(struct fb_cmap *cmap, struct fb_info *info)
122{
123 struct sh7760fb_par *par = info->par;
124 u32 s = cmap->start;
125 u32 l = cmap->len;
126 u16 *r = cmap->red;
127 u16 *g = cmap->green;
128 u16 *b = cmap->blue;
129 u32 col, tmo;
130 int ret;
131
132 ret = 0;
133
134 sh7760fb_wait_vsync(info);
135
136 /* request palette access */
137 iowrite16(LDPALCR_PALEN, par->base + LDPALCR);
138
139 /* poll for access grant */
140 tmo = 100;
141 while (!(ioread16(par->base + LDPALCR) & LDPALCR_PALS) && (--tmo))
142 cpu_relax();
143
144 if (!tmo) {
145 ret = 1;
146 dev_dbg(info->dev, "no palette access!\n");
147 goto out;
148 }
149
150 while (l && (s < 256)) {
151 col = ((*r) & 0xff) << 16;
152 col |= ((*g) & 0xff) << 8;
153 col |= ((*b) & 0xff);
154 col &= SH7760FB_PALETTE_MASK;
155
156 if (s < 16)
157 ((u32 *) (info->pseudo_palette))[s] = s;
158
159 s++;
160 l--;
161 r++;
162 g++;
163 b++;
164 }
165out:
166 iowrite16(0, par->base + LDPALCR);
167 return ret;
168}
169
170static void encode_fix(struct fb_fix_screeninfo *fix, struct fb_info *info,
171 unsigned long stride)
172{
173 memset(fix, 0, sizeof(struct fb_fix_screeninfo));
174 strcpy(fix->id, "sh7760-lcdc");
175
176 fix->smem_start = (unsigned long)info->screen_base;
177 fix->smem_len = info->screen_size;
178
179 fix->line_length = stride;
180}
181
182static int sh7760fb_get_color_info(struct device *dev,
183 u16 lddfr, int *bpp, int *gray)
184{
185 int lbpp, lgray;
186
187 lgray = lbpp = 0;
188
189 switch (lddfr & LDDFR_COLOR_MASK) {
190 case LDDFR_1BPP_MONO:
191 lgray = 1;
192 lbpp = 1;
193 break;
194 case LDDFR_2BPP_MONO:
195 lgray = 1;
196 lbpp = 2;
197 break;
198 case LDDFR_4BPP_MONO:
199 lgray = 1;
200 case LDDFR_4BPP:
201 lbpp = 4;
202 break;
203 case LDDFR_6BPP_MONO:
204 lgray = 1;
205 case LDDFR_8BPP:
206 lbpp = 8;
207 break;
208 case LDDFR_16BPP_RGB555:
209 case LDDFR_16BPP_RGB565:
210 lbpp = 16;
211 lgray = 0;
212 break;
213 default:
214 dev_dbg(dev, "unsupported LDDFR bit depth.\n");
215 return -EINVAL;
216 }
217
218 if (bpp)
219 *bpp = lbpp;
220 if (gray)
221 *gray = lgray;
222
223 return 0;
224}
225
226static int sh7760fb_check_var(struct fb_var_screeninfo *var,
227 struct fb_info *info)
228{
229 struct fb_fix_screeninfo *fix = &info->fix;
230 struct sh7760fb_par *par = info->par;
231 int ret, bpp;
232
233 /* get color info from register value */
234 ret = sh7760fb_get_color_info(info->dev, par->pd->lddfr, &bpp, NULL);
235 if (ret)
236 return ret;
237
238 var->bits_per_pixel = bpp;
239
240 if ((var->grayscale) && (var->bits_per_pixel == 1))
241 fix->visual = FB_VISUAL_MONO10;
242 else if (var->bits_per_pixel >= 15)
243 fix->visual = FB_VISUAL_TRUECOLOR;
244 else
245 fix->visual = FB_VISUAL_PSEUDOCOLOR;
246
247 /* TODO: add some more validation here */
248 return 0;
249}
250
251/*
252 * sh7760fb_set_par - set videomode.
253 *
254 * NOTE: The rotation, grayscale and DSTN codepaths are
255 * totally untested!
256 */
257static int sh7760fb_set_par(struct fb_info *info)
258{
259 struct sh7760fb_par *par = info->par;
260 struct fb_videomode *vm = par->pd->def_mode;
261 unsigned long sbase, dstn_off, ldsarl, stride;
262 unsigned short hsynp, hsynw, htcn, hdcn;
263 unsigned short vsynp, vsynw, vtln, vdln;
264 unsigned short lddfr, ldmtr;
265 int ret, bpp, gray;
266
267 par->rot = par->pd->rotate;
268
269 /* rotate only works with xres <= 320 */
270 if (par->rot && (vm->xres > 320)) {
271 dev_dbg(info->dev, "rotation disabled due to display size\n");
272 par->rot = 0;
273 }
274
275 /* calculate LCDC reg vals from display parameters */
276 hsynp = vm->right_margin + vm->xres;
277 hsynw = vm->hsync_len;
278 htcn = vm->left_margin + hsynp + hsynw;
279 hdcn = vm->xres;
280 vsynp = vm->lower_margin + vm->yres;
281 vsynw = vm->vsync_len;
282 vtln = vm->upper_margin + vsynp + vsynw;
283 vdln = vm->yres;
284
285 /* get color info from register value */
286 ret = sh7760fb_get_color_info(info->dev, par->pd->lddfr, &bpp, &gray);
287 if (ret)
288 return ret;
289
290 dev_dbg(info->dev, "%dx%d %dbpp %s (orientation %s)\n", hdcn,
291 vdln, bpp, gray ? "grayscale" : "color",
292 par->rot ? "rotated" : "normal");
293
294#ifdef CONFIG_CPU_LITTLE_ENDIAN
295 lddfr = par->pd->lddfr | (1 << 8);
296#else
297 lddfr = par->pd->lddfr & ~(1 << 8);
298#endif
299
300 ldmtr = par->pd->ldmtr;
301
302 if (!(vm->sync & FB_SYNC_HOR_HIGH_ACT))
303 ldmtr |= LDMTR_CL1POL;
304 if (!(vm->sync & FB_SYNC_VERT_HIGH_ACT))
305 ldmtr |= LDMTR_FLMPOL;
306
307 /* shut down LCDC before changing display parameters */
308 sh7760fb_blank(FB_BLANK_POWERDOWN, info);
309
310 iowrite16(par->pd->ldickr, par->base + LDICKR); /* pixclock */
311 iowrite16(ldmtr, par->base + LDMTR); /* polarities */
312 iowrite16(lddfr, par->base + LDDFR); /* color/depth */
313 iowrite16((par->rot ? 1 << 13 : 0), par->base + LDSMR); /* rotate */
314 iowrite16(par->pd->ldpmmr, par->base + LDPMMR); /* Power Management */
315 iowrite16(par->pd->ldpspr, par->base + LDPSPR); /* Power Supply Ctrl */
316
317 /* display resolution */
318 iowrite16(((htcn >> 3) - 1) | (((hdcn >> 3) - 1) << 8),
319 par->base + LDHCNR);
320 iowrite16(vdln - 1, par->base + LDVDLNR);
321 iowrite16(vtln - 1, par->base + LDVTLNR);
322 /* h/v sync signals */
323 iowrite16((vsynp - 1) | ((vsynw - 1) << 12), par->base + LDVSYNR);
324 iowrite16(((hsynp >> 3) - 1) | (((hsynw >> 3) - 1) << 12),
325 par->base + LDHSYNR);
326 /* AC modulation sig */
327 iowrite16(par->pd->ldaclnr, par->base + LDACLNR);
328
329 stride = (par->rot) ? vtln : hdcn;
330 if (!gray)
331 stride *= (bpp + 7) >> 3;
332 else {
333 if (bpp == 1)
334 stride >>= 3;
335 else if (bpp == 2)
336 stride >>= 2;
337 else if (bpp == 4)
338 stride >>= 1;
339 /* 6 bpp == 8 bpp */
340 }
341
342 /* if rotated, stride must be power of 2 */
343 if (par->rot) {
344 unsigned long bit = 1 << 31;
345 while (bit) {
346 if (stride & bit)
347 break;
348 bit >>= 1;
349 }
350 if (stride & ~bit)
351 stride = bit << 1; /* not P-o-2, round up */
352 }
353 iowrite16(stride, par->base + LDLAOR);
354
355 /* set display mem start address */
356 sbase = (unsigned long)par->fbdma;
357 if (par->rot)
358 sbase += (hdcn - 1) * stride;
359
360 iowrite32(sbase, par->base + LDSARU);
361
362 /*
363 * for DSTN need to set address for lower half.
364 * I (mlau) don't know which address to set it to,
365 * so I guessed at (stride * yres/2).
366 */
367 if (((ldmtr & 0x003f) >= LDMTR_DSTN_MONO_8) &&
368 ((ldmtr & 0x003f) <= LDMTR_DSTN_COLOR_16)) {
369
370 dev_dbg(info->dev, " ***** DSTN untested! *****\n");
371
372 dstn_off = stride;
373 if (par->rot)
374 dstn_off *= hdcn >> 1;
375 else
376 dstn_off *= vdln >> 1;
377
378 ldsarl = sbase + dstn_off;
379 } else
380 ldsarl = 0;
381
382 iowrite32(ldsarl, par->base + LDSARL); /* mem for lower half of DSTN */
383
384 encode_fix(&info->fix, info, stride);
385 sh7760fb_check_var(&info->var, info);
386
387 sh7760fb_blank(FB_BLANK_UNBLANK, info); /* panel on! */
388
389 dev_dbg(info->dev, "hdcn : %6d htcn : %6d\n", hdcn, htcn);
390 dev_dbg(info->dev, "hsynw : %6d hsynp : %6d\n", hsynw, hsynp);
391 dev_dbg(info->dev, "vdln : %6d vtln : %6d\n", vdln, vtln);
392 dev_dbg(info->dev, "vsynw : %6d vsynp : %6d\n", vsynw, vsynp);
393 dev_dbg(info->dev, "clksrc: %6d clkdiv: %6d\n",
394 (par->pd->ldickr >> 12) & 3, par->pd->ldickr & 0x1f);
395 dev_dbg(info->dev, "ldpmmr: 0x%04x ldpspr: 0x%04x\n", par->pd->ldpmmr,
396 par->pd->ldpspr);
397 dev_dbg(info->dev, "ldmtr : 0x%04x lddfr : 0x%04x\n", ldmtr, lddfr);
398 dev_dbg(info->dev, "ldlaor: %ld\n", stride);
399 dev_dbg(info->dev, "ldsaru: 0x%08lx ldsarl: 0x%08lx\n", sbase, ldsarl);
400
401 return 0;
402}
403
404static struct fb_ops sh7760fb_ops = {
405 .owner = THIS_MODULE,
406 .fb_blank = sh7760fb_blank,
407 .fb_check_var = sh7760fb_check_var,
408 .fb_setcmap = sh7760fb_setcmap,
409 .fb_set_par = sh7760fb_set_par,
410 .fb_fillrect = cfb_fillrect,
411 .fb_copyarea = cfb_copyarea,
412 .fb_imageblit = cfb_imageblit,
413};
414
415static void sh7760fb_free_mem(struct fb_info *info)
416{
417 struct sh7760fb_par *par = info->par;
418
419 if (!info->screen_base)
420 return;
421
422 dma_free_coherent(info->dev, info->screen_size,
423 info->screen_base, par->fbdma);
424
425 par->fbdma = 0;
426 info->screen_base = NULL;
427 info->screen_size = 0;
428}
429
430/* allocate the framebuffer memory. This memory must be in Area3,
431 * (dictated by the DMA engine) and contiguous, at a 512 byte boundary.
432 */
433static int sh7760fb_alloc_mem(struct fb_info *info)
434{
435 struct sh7760fb_par *par = info->par;
436 void *fbmem;
437 unsigned long vram;
438 int ret, bpp;
439
440 if (info->screen_base)
441 return 0;
442
443 /* get color info from register value */
444 ret = sh7760fb_get_color_info(info->dev, par->pd->lddfr, &bpp, NULL);
445 if (ret) {
446 printk(KERN_ERR "colinfo\n");
447 return ret;
448 }
449
450 /* min VRAM: xres_min = 16, yres_min = 1, bpp = 1: 2byte -> 1 page
451 max VRAM: xres_max = 1024, yres_max = 1024, bpp = 16: 2MB */
452
453 vram = info->var.xres * info->var.yres;
454 if (info->var.grayscale) {
455 if (bpp == 1)
456 vram >>= 3;
457 else if (bpp == 2)
458 vram >>= 2;
459 else if (bpp == 4)
460 vram >>= 1;
461 } else if (bpp > 8)
462 vram *= 2;
463 if ((vram < 1) || (vram > 1024 * 2048)) {
464 dev_dbg(info->dev, "too much VRAM required. Check settings\n");
465 return -ENODEV;
466 }
467
468 if (vram < PAGE_SIZE)
469 vram = PAGE_SIZE;
470
471 fbmem = dma_alloc_coherent(info->dev, vram, &par->fbdma, GFP_KERNEL);
472
473 if (!fbmem)
474 return -ENOMEM;
475
476 if ((par->fbdma & SH7760FB_DMA_MASK) != SH7760FB_DMA_MASK) {
477 sh7760fb_free_mem(info);
478 dev_err(info->dev, "kernel gave me memory at 0x%08lx, which is"
479 "unusable for the LCDC\n", (unsigned long)par->fbdma);
480 return -ENOMEM;
481 }
482
483 info->screen_base = fbmem;
484 info->screen_size = vram;
485
486 return 0;
487}
488
489static int __devinit sh7760fb_probe(struct platform_device *pdev)
490{
491 struct fb_info *info;
492 struct resource *res;
493 struct sh7760fb_par *par;
494 int ret;
495
496 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
497 if (unlikely(res == NULL)) {
498 dev_err(&pdev->dev, "invalid resource\n");
499 return -EINVAL;
500 }
501
502 info = framebuffer_alloc(sizeof(struct sh7760fb_par), &pdev->dev);
503 if (!info)
504 return -ENOMEM;
505
506 par = info->par;
507 par->dev = pdev;
508
509 par->pd = pdev->dev.platform_data;
510 if (!par->pd) {
511 dev_dbg(info->dev, "no display setup data!\n");
512 ret = -ENODEV;
513 goto out_fb;
514 }
515
516 par->ioarea = request_mem_region(res->start,
517 (res->end - res->start), pdev->name);
518 if (!par->ioarea) {
519 dev_err(&pdev->dev, "mmio area busy\n");
520 ret = -EBUSY;
521 goto out_fb;
522 }
523
524 par->base = ioremap_nocache(res->start, res->end - res->start + 1);
525 if (!par->base) {
526 dev_err(&pdev->dev, "cannot remap\n");
527 ret = -ENODEV;
528 goto out_res;
529 }
530
531 iowrite16(0, par->base + LDINTR); /* disable vsync irq */
532 par->irq = platform_get_irq(pdev, 0);
533 if (par->irq >= 0) {
534 ret = request_irq(par->irq, sh7760fb_irq, 0,
535 "sh7760-lcdc", &par->vsync);
536 if (ret) {
537 dev_err(&pdev->dev, "cannot grab IRQ\n");
538 par->irq = -ENXIO;
539 } else
540 disable_irq_nosync(par->irq);
541 }
542
543 fb_videomode_to_var(&info->var, par->pd->def_mode);
544
545 ret = sh7760fb_alloc_mem(info);
546 if (ret) {
547 dev_dbg(info->dev, "framebuffer memory allocation failed!\n");
548 goto out_unmap;
549 }
550
551 info->pseudo_palette = par->pseudo_palette;
552
553 /* fixup color register bitpositions. These are fixed by hardware */
554 info->var.red.offset = 11;
555 info->var.red.length = 5;
556 info->var.red.msb_right = 0;
557
558 info->var.green.offset = 5;
559 info->var.green.length = 6;
560 info->var.green.msb_right = 0;
561
562 info->var.blue.offset = 0;
563 info->var.blue.length = 5;
564 info->var.blue.msb_right = 0;
565
566 info->var.transp.offset = 0;
567 info->var.transp.length = 0;
568 info->var.transp.msb_right = 0;
569
570 /* set the DON2 bit now, before cmap allocation, as it will randomize
571 * palette memory.
572 */
573 iowrite16(LDCNTR_DON2, par->base + LDCNTR);
574 info->fbops = &sh7760fb_ops;
575
576 ret = fb_alloc_cmap(&info->cmap, 256, 0);
577 if (ret) {
578 dev_dbg(info->dev, "Unable to allocate cmap memory\n");
579 goto out_mem;
580 }
581
582 ret = register_framebuffer(info);
583 if (ret < 0) {
584 dev_dbg(info->dev, "cannot register fb!\n");
585 goto out_cmap;
586 }
587 platform_set_drvdata(pdev, info);
588
589 printk(KERN_INFO "%s: memory at phys 0x%08lx-0x%08lx, size %ld KiB\n",
590 pdev->name,
591 (unsigned long)par->fbdma,
592 (unsigned long)(par->fbdma + info->screen_size - 1),
593 info->screen_size >> 10);
594
595 return 0;
596
597out_cmap:
598 sh7760fb_blank(FB_BLANK_POWERDOWN, info);
599 fb_dealloc_cmap(&info->cmap);
600out_mem:
601 sh7760fb_free_mem(info);
602out_unmap:
603 if (par->irq >= 0)
604 free_irq(par->irq, &par->vsync);
605 iounmap(par->base);
606out_res:
607 release_resource(par->ioarea);
608 kfree(par->ioarea);
609out_fb:
610 framebuffer_release(info);
611 return ret;
612}
613
614static int __devexit sh7760fb_remove(struct platform_device *dev)
615{
616 struct fb_info *info = platform_get_drvdata(dev);
617 struct sh7760fb_par *par = info->par;
618
619 sh7760fb_blank(FB_BLANK_POWERDOWN, info);
620 unregister_framebuffer(info);
621 fb_dealloc_cmap(&info->cmap);
622 sh7760fb_free_mem(info);
623 if (par->irq >= 0)
624 free_irq(par->irq, par);
625 iounmap(par->base);
626 release_resource(par->ioarea);
627 kfree(par->ioarea);
628 framebuffer_release(info);
629 platform_set_drvdata(dev, NULL);
630
631 return 0;
632}
633
634static struct platform_driver sh7760_lcdc_driver = {
635 .driver = {
636 .name = "sh7760-lcdc",
637 .owner = THIS_MODULE,
638 },
639 .probe = sh7760fb_probe,
640 .remove = __devexit_p(sh7760fb_remove),
641};
642
643static int __init sh7760fb_init(void)
644{
645 return platform_driver_register(&sh7760_lcdc_driver);
646}
647
648static void __exit sh7760fb_exit(void)
649{
650 platform_driver_unregister(&sh7760_lcdc_driver);
651}
652
653module_init(sh7760fb_init);
654module_exit(sh7760fb_exit);
655
656MODULE_AUTHOR("Nobuhiro Iwamatsu, Manuel Lauss");
657MODULE_DESCRIPTION("FBdev for SH7760/63 integrated LCD Controller");
658MODULE_LICENSE("GPL");
diff --git a/drivers/video/sh_mobile_lcdcfb.c b/drivers/video/sh_mobile_lcdcfb.c
new file mode 100644
index 000000000000..f6ef6cca73cd
--- /dev/null
+++ b/drivers/video/sh_mobile_lcdcfb.c
@@ -0,0 +1,725 @@
1/*
2 * SuperH Mobile LCDC Framebuffer
3 *
4 * Copyright (c) 2008 Magnus Damm
5 *
6 * This file is subject to the terms and conditions of the GNU General Public
7 * License. See the file "COPYING" in the main directory of this archive
8 * for more details.
9 */
10
11#include <linux/kernel.h>
12#include <linux/init.h>
13#include <linux/delay.h>
14#include <linux/mm.h>
15#include <linux/fb.h>
16#include <linux/clk.h>
17#include <linux/platform_device.h>
18#include <linux/dma-mapping.h>
19#include <asm/sh_mobile_lcdc.h>
20
21#define PALETTE_NR 16
22
23struct sh_mobile_lcdc_priv;
24struct sh_mobile_lcdc_chan {
25 struct sh_mobile_lcdc_priv *lcdc;
26 unsigned long *reg_offs;
27 unsigned long ldmt1r_value;
28 unsigned long enabled; /* ME and SE in LDCNT2R */
29 struct sh_mobile_lcdc_chan_cfg cfg;
30 u32 pseudo_palette[PALETTE_NR];
31 struct fb_info info;
32 dma_addr_t dma_handle;
33};
34
35struct sh_mobile_lcdc_priv {
36 void __iomem *base;
37 struct clk *clk;
38 unsigned long lddckr;
39 struct sh_mobile_lcdc_chan ch[2];
40};
41
42/* shared registers */
43#define _LDDCKR 0x410
44#define _LDDCKSTPR 0x414
45#define _LDINTR 0x468
46#define _LDSR 0x46c
47#define _LDCNT1R 0x470
48#define _LDCNT2R 0x474
49#define _LDDDSR 0x47c
50#define _LDDWD0R 0x800
51#define _LDDRDR 0x840
52#define _LDDWAR 0x900
53#define _LDDRAR 0x904
54
55/* per-channel registers */
56enum { LDDCKPAT1R, LDDCKPAT2R, LDMT1R, LDMT2R, LDMT3R, LDDFR, LDSM1R,
57 LDSA1R, LDMLSR, LDHCNR, LDHSYNR, LDVLNR, LDVSYNR, LDPMR };
58
59static unsigned long lcdc_offs_mainlcd[] = {
60 [LDDCKPAT1R] = 0x400,
61 [LDDCKPAT2R] = 0x404,
62 [LDMT1R] = 0x418,
63 [LDMT2R] = 0x41c,
64 [LDMT3R] = 0x420,
65 [LDDFR] = 0x424,
66 [LDSM1R] = 0x428,
67 [LDSA1R] = 0x430,
68 [LDMLSR] = 0x438,
69 [LDHCNR] = 0x448,
70 [LDHSYNR] = 0x44c,
71 [LDVLNR] = 0x450,
72 [LDVSYNR] = 0x454,
73 [LDPMR] = 0x460,
74};
75
76static unsigned long lcdc_offs_sublcd[] = {
77 [LDDCKPAT1R] = 0x408,
78 [LDDCKPAT2R] = 0x40c,
79 [LDMT1R] = 0x600,
80 [LDMT2R] = 0x604,
81 [LDMT3R] = 0x608,
82 [LDDFR] = 0x60c,
83 [LDSM1R] = 0x610,
84 [LDSA1R] = 0x618,
85 [LDMLSR] = 0x620,
86 [LDHCNR] = 0x624,
87 [LDHSYNR] = 0x628,
88 [LDVLNR] = 0x62c,
89 [LDVSYNR] = 0x630,
90 [LDPMR] = 0x63c,
91};
92
93#define START_LCDC 0x00000001
94#define LCDC_RESET 0x00000100
95#define DISPLAY_BEU 0x00000008
96#define LCDC_ENABLE 0x00000001
97
98static void lcdc_write_chan(struct sh_mobile_lcdc_chan *chan,
99 int reg_nr, unsigned long data)
100{
101 iowrite32(data, chan->lcdc->base + chan->reg_offs[reg_nr]);
102}
103
104static unsigned long lcdc_read_chan(struct sh_mobile_lcdc_chan *chan,
105 int reg_nr)
106{
107 return ioread32(chan->lcdc->base + chan->reg_offs[reg_nr]);
108}
109
110static void lcdc_write(struct sh_mobile_lcdc_priv *priv,
111 unsigned long reg_offs, unsigned long data)
112{
113 iowrite32(data, priv->base + reg_offs);
114}
115
116static unsigned long lcdc_read(struct sh_mobile_lcdc_priv *priv,
117 unsigned long reg_offs)
118{
119 return ioread32(priv->base + reg_offs);
120}
121
122static void lcdc_wait_bit(struct sh_mobile_lcdc_priv *priv,
123 unsigned long reg_offs,
124 unsigned long mask, unsigned long until)
125{
126 while ((lcdc_read(priv, reg_offs) & mask) != until)
127 cpu_relax();
128}
129
130static int lcdc_chan_is_sublcd(struct sh_mobile_lcdc_chan *chan)
131{
132 return chan->cfg.chan == LCDC_CHAN_SUBLCD;
133}
134
135static void lcdc_sys_write_index(void *handle, unsigned long data)
136{
137 struct sh_mobile_lcdc_chan *ch = handle;
138
139 lcdc_write(ch->lcdc, _LDDWD0R, data | 0x10000000);
140 lcdc_wait_bit(ch->lcdc, _LDSR, 2, 0);
141 lcdc_write(ch->lcdc, _LDDWAR, 1 | (lcdc_chan_is_sublcd(ch) ? 2 : 0));
142}
143
144static void lcdc_sys_write_data(void *handle, unsigned long data)
145{
146 struct sh_mobile_lcdc_chan *ch = handle;
147
148 lcdc_write(ch->lcdc, _LDDWD0R, data | 0x11000000);
149 lcdc_wait_bit(ch->lcdc, _LDSR, 2, 0);
150 lcdc_write(ch->lcdc, _LDDWAR, 1 | (lcdc_chan_is_sublcd(ch) ? 2 : 0));
151}
152
153static unsigned long lcdc_sys_read_data(void *handle)
154{
155 struct sh_mobile_lcdc_chan *ch = handle;
156
157 lcdc_write(ch->lcdc, _LDDRDR, 0x01000000);
158 lcdc_wait_bit(ch->lcdc, _LDSR, 2, 0);
159 lcdc_write(ch->lcdc, _LDDRAR, 1 | (lcdc_chan_is_sublcd(ch) ? 2 : 0));
160 udelay(1);
161
162 return lcdc_read(ch->lcdc, _LDDRDR) & 0xffff;
163}
164
165struct sh_mobile_lcdc_sys_bus_ops sh_mobile_lcdc_sys_bus_ops = {
166 lcdc_sys_write_index,
167 lcdc_sys_write_data,
168 lcdc_sys_read_data,
169};
170
171static void sh_mobile_lcdc_start_stop(struct sh_mobile_lcdc_priv *priv,
172 int start)
173{
174 unsigned long tmp = lcdc_read(priv, _LDCNT2R);
175 int k;
176
177 /* start or stop the lcdc */
178 if (start)
179 lcdc_write(priv, _LDCNT2R, tmp | START_LCDC);
180 else
181 lcdc_write(priv, _LDCNT2R, tmp & ~START_LCDC);
182
183 /* wait until power is applied/stopped on all channels */
184 for (k = 0; k < ARRAY_SIZE(priv->ch); k++)
185 if (lcdc_read(priv, _LDCNT2R) & priv->ch[k].enabled)
186 while (1) {
187 tmp = lcdc_read_chan(&priv->ch[k], LDPMR) & 3;
188 if (start && tmp == 3)
189 break;
190 if (!start && tmp == 0)
191 break;
192 cpu_relax();
193 }
194
195 if (!start)
196 lcdc_write(priv, _LDDCKSTPR, 1); /* stop dotclock */
197}
198
199static int sh_mobile_lcdc_start(struct sh_mobile_lcdc_priv *priv)
200{
201 struct sh_mobile_lcdc_chan *ch;
202 struct fb_videomode *lcd_cfg;
203 struct sh_mobile_lcdc_board_cfg *board_cfg;
204 unsigned long tmp;
205 int k, m;
206 int ret = 0;
207
208 /* reset */
209 lcdc_write(priv, _LDCNT2R, lcdc_read(priv, _LDCNT2R) | LCDC_RESET);
210 lcdc_wait_bit(priv, _LDCNT2R, LCDC_RESET, 0);
211
212 /* enable LCDC channels */
213 tmp = lcdc_read(priv, _LDCNT2R);
214 tmp |= priv->ch[0].enabled;
215 tmp |= priv->ch[1].enabled;
216 lcdc_write(priv, _LDCNT2R, tmp);
217
218 /* read data from external memory, avoid using the BEU for now */
219 lcdc_write(priv, _LDCNT2R, lcdc_read(priv, _LDCNT2R) & ~DISPLAY_BEU);
220
221 /* stop the lcdc first */
222 sh_mobile_lcdc_start_stop(priv, 0);
223
224 /* configure clocks */
225 tmp = priv->lddckr;
226 for (k = 0; k < ARRAY_SIZE(priv->ch); k++) {
227 ch = &priv->ch[k];
228
229 if (!priv->ch[k].enabled)
230 continue;
231
232 m = ch->cfg.clock_divider;
233 if (!m)
234 continue;
235
236 if (m == 1)
237 m = 1 << 6;
238 tmp |= m << (lcdc_chan_is_sublcd(ch) ? 8 : 0);
239
240 lcdc_write_chan(ch, LDDCKPAT1R, 0x00000000);
241 lcdc_write_chan(ch, LDDCKPAT2R, (1 << (m/2)) - 1);
242 }
243
244 lcdc_write(priv, _LDDCKR, tmp);
245
246 /* start dotclock again */
247 lcdc_write(priv, _LDDCKSTPR, 0);
248 lcdc_wait_bit(priv, _LDDCKSTPR, ~0, 0);
249
250 /* interrupts are disabled */
251 lcdc_write(priv, _LDINTR, 0);
252
253 for (k = 0; k < ARRAY_SIZE(priv->ch); k++) {
254 ch = &priv->ch[k];
255 lcd_cfg = &ch->cfg.lcd_cfg;
256
257 if (!ch->enabled)
258 continue;
259
260 tmp = ch->ldmt1r_value;
261 tmp |= (lcd_cfg->sync & FB_SYNC_VERT_HIGH_ACT) ? 0 : 1 << 28;
262 tmp |= (lcd_cfg->sync & FB_SYNC_HOR_HIGH_ACT) ? 0 : 1 << 27;
263 lcdc_write_chan(ch, LDMT1R, tmp);
264
265 /* setup SYS bus */
266 lcdc_write_chan(ch, LDMT2R, ch->cfg.sys_bus_cfg.ldmt2r);
267 lcdc_write_chan(ch, LDMT3R, ch->cfg.sys_bus_cfg.ldmt3r);
268
269 /* horizontal configuration */
270 tmp = lcd_cfg->xres + lcd_cfg->hsync_len;
271 tmp += lcd_cfg->left_margin;
272 tmp += lcd_cfg->right_margin;
273 tmp /= 8; /* HTCN */
274 tmp |= (lcd_cfg->xres / 8) << 16; /* HDCN */
275 lcdc_write_chan(ch, LDHCNR, tmp);
276
277 tmp = lcd_cfg->xres;
278 tmp += lcd_cfg->right_margin;
279 tmp /= 8; /* HSYNP */
280 tmp |= (lcd_cfg->hsync_len / 8) << 16; /* HSYNW */
281 lcdc_write_chan(ch, LDHSYNR, tmp);
282
283 /* power supply */
284 lcdc_write_chan(ch, LDPMR, 0);
285
286 /* vertical configuration */
287 tmp = lcd_cfg->yres + lcd_cfg->vsync_len;
288 tmp += lcd_cfg->upper_margin;
289 tmp += lcd_cfg->lower_margin; /* VTLN */
290 tmp |= lcd_cfg->yres << 16; /* VDLN */
291 lcdc_write_chan(ch, LDVLNR, tmp);
292
293 tmp = lcd_cfg->yres;
294 tmp += lcd_cfg->lower_margin; /* VSYNP */
295 tmp |= lcd_cfg->vsync_len << 16; /* VSYNW */
296 lcdc_write_chan(ch, LDVSYNR, tmp);
297
298 board_cfg = &ch->cfg.board_cfg;
299 if (board_cfg->setup_sys)
300 ret = board_cfg->setup_sys(board_cfg->board_data, ch,
301 &sh_mobile_lcdc_sys_bus_ops);
302 if (ret)
303 return ret;
304 }
305
306 /* --- display_lcdc_data() --- */
307 lcdc_write(priv, _LDINTR, 0x00000f00);
308
309 /* word and long word swap */
310 lcdc_write(priv, _LDDDSR, lcdc_read(priv, _LDDDSR) | 6);
311
312 for (k = 0; k < ARRAY_SIZE(priv->ch); k++) {
313 ch = &priv->ch[k];
314
315 if (!priv->ch[k].enabled)
316 continue;
317
318 /* set bpp format in PKF[4:0] */
319 tmp = lcdc_read_chan(ch, LDDFR);
320 tmp &= ~(0x0001001f);
321 tmp |= (priv->ch[k].info.var.bits_per_pixel == 16) ? 3 : 0;
322 lcdc_write_chan(ch, LDDFR, tmp);
323
324 /* point out our frame buffer */
325 lcdc_write_chan(ch, LDSA1R, ch->info.fix.smem_start);
326
327 /* set line size */
328 lcdc_write_chan(ch, LDMLSR, ch->info.fix.line_length);
329
330 /* continuous read mode */
331 lcdc_write_chan(ch, LDSM1R, 0);
332 }
333
334 /* display output */
335 lcdc_write(priv, _LDCNT1R, LCDC_ENABLE);
336
337 /* start the lcdc */
338 sh_mobile_lcdc_start_stop(priv, 1);
339
340 /* tell the board code to enable the panel */
341 for (k = 0; k < ARRAY_SIZE(priv->ch); k++) {
342 ch = &priv->ch[k];
343 board_cfg = &ch->cfg.board_cfg;
344 if (board_cfg->display_on)
345 board_cfg->display_on(board_cfg->board_data);
346 }
347
348 return 0;
349}
350
351static void sh_mobile_lcdc_stop(struct sh_mobile_lcdc_priv *priv)
352{
353 struct sh_mobile_lcdc_chan *ch;
354 struct sh_mobile_lcdc_board_cfg *board_cfg;
355 int k;
356
357 /* tell the board code to disable the panel */
358 for (k = 0; k < ARRAY_SIZE(priv->ch); k++) {
359 ch = &priv->ch[k];
360 board_cfg = &ch->cfg.board_cfg;
361 if (board_cfg->display_off)
362 board_cfg->display_off(board_cfg->board_data);
363 }
364
365 /* stop the lcdc */
366 sh_mobile_lcdc_start_stop(priv, 0);
367}
368
369static int sh_mobile_lcdc_check_interface(struct sh_mobile_lcdc_chan *ch)
370{
371 int ifm, miftyp;
372
373 switch (ch->cfg.interface_type) {
374 case RGB8: ifm = 0; miftyp = 0; break;
375 case RGB9: ifm = 0; miftyp = 4; break;
376 case RGB12A: ifm = 0; miftyp = 5; break;
377 case RGB12B: ifm = 0; miftyp = 6; break;
378 case RGB16: ifm = 0; miftyp = 7; break;
379 case RGB18: ifm = 0; miftyp = 10; break;
380 case RGB24: ifm = 0; miftyp = 11; break;
381 case SYS8A: ifm = 1; miftyp = 0; break;
382 case SYS8B: ifm = 1; miftyp = 1; break;
383 case SYS8C: ifm = 1; miftyp = 2; break;
384 case SYS8D: ifm = 1; miftyp = 3; break;
385 case SYS9: ifm = 1; miftyp = 4; break;
386 case SYS12: ifm = 1; miftyp = 5; break;
387 case SYS16A: ifm = 1; miftyp = 7; break;
388 case SYS16B: ifm = 1; miftyp = 8; break;
389 case SYS16C: ifm = 1; miftyp = 9; break;
390 case SYS18: ifm = 1; miftyp = 10; break;
391 case SYS24: ifm = 1; miftyp = 11; break;
392 default: goto bad;
393 }
394
395 /* SUBLCD only supports SYS interface */
396 if (lcdc_chan_is_sublcd(ch)) {
397 if (ifm == 0)
398 goto bad;
399 else
400 ifm = 0;
401 }
402
403 ch->ldmt1r_value = (ifm << 12) | miftyp;
404 return 0;
405 bad:
406 return -EINVAL;
407}
408
409static int sh_mobile_lcdc_setup_clocks(struct device *dev, int clock_source,
410 struct sh_mobile_lcdc_priv *priv)
411{
412 char *str;
413 int icksel;
414
415 switch (clock_source) {
416 case LCDC_CLK_BUS: str = "bus_clk"; icksel = 0; break;
417 case LCDC_CLK_PERIPHERAL: str = "peripheral_clk"; icksel = 1; break;
418 case LCDC_CLK_EXTERNAL: str = NULL; icksel = 2; break;
419 default:
420 return -EINVAL;
421 }
422
423 priv->lddckr = icksel << 16;
424
425 if (str) {
426 priv->clk = clk_get(dev, str);
427 if (IS_ERR(priv->clk)) {
428 dev_err(dev, "cannot get clock %s\n", str);
429 return PTR_ERR(priv->clk);
430 }
431
432 clk_enable(priv->clk);
433 }
434
435 return 0;
436}
437
438static int sh_mobile_lcdc_setcolreg(u_int regno,
439 u_int red, u_int green, u_int blue,
440 u_int transp, struct fb_info *info)
441{
442 u32 *palette = info->pseudo_palette;
443
444 if (regno >= PALETTE_NR)
445 return -EINVAL;
446
447 /* only FB_VISUAL_TRUECOLOR supported */
448
449 red >>= 16 - info->var.red.length;
450 green >>= 16 - info->var.green.length;
451 blue >>= 16 - info->var.blue.length;
452 transp >>= 16 - info->var.transp.length;
453
454 palette[regno] = (red << info->var.red.offset) |
455 (green << info->var.green.offset) |
456 (blue << info->var.blue.offset) |
457 (transp << info->var.transp.offset);
458
459 return 0;
460}
461
462static struct fb_fix_screeninfo sh_mobile_lcdc_fix = {
463 .id = "SH Mobile LCDC",
464 .type = FB_TYPE_PACKED_PIXELS,
465 .visual = FB_VISUAL_TRUECOLOR,
466 .accel = FB_ACCEL_NONE,
467};
468
469static struct fb_ops sh_mobile_lcdc_ops = {
470 .fb_setcolreg = sh_mobile_lcdc_setcolreg,
471 .fb_fillrect = cfb_fillrect,
472 .fb_copyarea = cfb_copyarea,
473 .fb_imageblit = cfb_imageblit,
474};
475
476static int sh_mobile_lcdc_set_bpp(struct fb_var_screeninfo *var, int bpp)
477{
478 switch (bpp) {
479 case 16: /* PKF[4:0] = 00011 - RGB 565 */
480 var->red.offset = 11;
481 var->red.length = 5;
482 var->green.offset = 5;
483 var->green.length = 6;
484 var->blue.offset = 0;
485 var->blue.length = 5;
486 var->transp.offset = 0;
487 var->transp.length = 0;
488 break;
489
490 case 32: /* PKF[4:0] = 00000 - RGB 888
491 * sh7722 pdf says 00RRGGBB but reality is GGBB00RR
492 * this may be because LDDDSR has word swap enabled..
493 */
494 var->red.offset = 0;
495 var->red.length = 8;
496 var->green.offset = 24;
497 var->green.length = 8;
498 var->blue.offset = 16;
499 var->blue.length = 8;
500 var->transp.offset = 0;
501 var->transp.length = 0;
502 break;
503 default:
504 return -EINVAL;
505 }
506 var->bits_per_pixel = bpp;
507 var->red.msb_right = 0;
508 var->green.msb_right = 0;
509 var->blue.msb_right = 0;
510 var->transp.msb_right = 0;
511 return 0;
512}
513
514static int sh_mobile_lcdc_remove(struct platform_device *pdev);
515
516static int __init sh_mobile_lcdc_probe(struct platform_device *pdev)
517{
518 struct fb_info *info;
519 struct sh_mobile_lcdc_priv *priv;
520 struct sh_mobile_lcdc_info *pdata;
521 struct sh_mobile_lcdc_chan_cfg *cfg;
522 struct resource *res;
523 int error;
524 void *buf;
525 int i, j;
526
527 if (!pdev->dev.platform_data) {
528 dev_err(&pdev->dev, "no platform data defined\n");
529 error = -EINVAL;
530 goto err0;
531 }
532
533 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
534 if (res == NULL) {
535 dev_err(&pdev->dev, "cannot find IO resource\n");
536 error = -ENOENT;
537 goto err0;
538 }
539
540 priv = kzalloc(sizeof(*priv), GFP_KERNEL);
541 if (!priv) {
542 dev_err(&pdev->dev, "cannot allocate device data\n");
543 error = -ENOMEM;
544 goto err0;
545 }
546
547 platform_set_drvdata(pdev, priv);
548 pdata = pdev->dev.platform_data;
549
550 j = 0;
551 for (i = 0; i < ARRAY_SIZE(pdata->ch); i++) {
552 priv->ch[j].lcdc = priv;
553 memcpy(&priv->ch[j].cfg, &pdata->ch[i], sizeof(pdata->ch[i]));
554
555 error = sh_mobile_lcdc_check_interface(&priv->ch[i]);
556 if (error) {
557 dev_err(&pdev->dev, "unsupported interface type\n");
558 goto err1;
559 }
560
561 switch (pdata->ch[i].chan) {
562 case LCDC_CHAN_MAINLCD:
563 priv->ch[j].enabled = 1 << 1;
564 priv->ch[j].reg_offs = lcdc_offs_mainlcd;
565 j++;
566 break;
567 case LCDC_CHAN_SUBLCD:
568 priv->ch[j].enabled = 1 << 2;
569 priv->ch[j].reg_offs = lcdc_offs_sublcd;
570 j++;
571 break;
572 }
573 }
574
575 if (!j) {
576 dev_err(&pdev->dev, "no channels defined\n");
577 error = -EINVAL;
578 goto err1;
579 }
580
581 error = sh_mobile_lcdc_setup_clocks(&pdev->dev,
582 pdata->clock_source, priv);
583 if (error) {
584 dev_err(&pdev->dev, "unable to setup clocks\n");
585 goto err1;
586 }
587
588 priv->lddckr = pdata->lddckr;
589 priv->base = ioremap_nocache(res->start, (res->end - res->start) + 1);
590
591 for (i = 0; i < j; i++) {
592 info = &priv->ch[i].info;
593 cfg = &priv->ch[i].cfg;
594
595 info->fbops = &sh_mobile_lcdc_ops;
596 info->var.xres = info->var.xres_virtual = cfg->lcd_cfg.xres;
597 info->var.yres = info->var.yres_virtual = cfg->lcd_cfg.yres;
598 info->var.activate = FB_ACTIVATE_NOW;
599 error = sh_mobile_lcdc_set_bpp(&info->var, cfg->bpp);
600 if (error)
601 break;
602
603 info->fix = sh_mobile_lcdc_fix;
604 info->fix.line_length = cfg->lcd_cfg.xres * (cfg->bpp / 8);
605 info->fix.smem_len = info->fix.line_length * cfg->lcd_cfg.yres;
606
607 buf = dma_alloc_coherent(&pdev->dev, info->fix.smem_len,
608 &priv->ch[i].dma_handle, GFP_KERNEL);
609 if (!buf) {
610 dev_err(&pdev->dev, "unable to allocate buffer\n");
611 error = -ENOMEM;
612 break;
613 }
614
615 info->pseudo_palette = &priv->ch[i].pseudo_palette;
616 info->flags = FBINFO_FLAG_DEFAULT;
617
618 error = fb_alloc_cmap(&info->cmap, PALETTE_NR, 0);
619 if (error < 0) {
620 dev_err(&pdev->dev, "unable to allocate cmap\n");
621 dma_free_coherent(&pdev->dev, info->fix.smem_len,
622 buf, priv->ch[i].dma_handle);
623 break;
624 }
625
626 memset(buf, 0, info->fix.smem_len);
627 info->fix.smem_start = priv->ch[i].dma_handle;
628 info->screen_base = buf;
629 info->device = &pdev->dev;
630 }
631
632 if (error)
633 goto err1;
634
635 error = sh_mobile_lcdc_start(priv);
636 if (error) {
637 dev_err(&pdev->dev, "unable to start hardware\n");
638 goto err1;
639 }
640
641 for (i = 0; i < j; i++) {
642 error = register_framebuffer(&priv->ch[i].info);
643 if (error < 0)
644 goto err1;
645 }
646
647 for (i = 0; i < j; i++) {
648 info = &priv->ch[i].info;
649 dev_info(info->dev,
650 "registered %s/%s as %dx%d %dbpp.\n",
651 pdev->name,
652 (priv->ch[i].cfg.chan == LCDC_CHAN_MAINLCD) ?
653 "mainlcd" : "sublcd",
654 (int) priv->ch[i].cfg.lcd_cfg.xres,
655 (int) priv->ch[i].cfg.lcd_cfg.yres,
656 priv->ch[i].cfg.bpp);
657 }
658
659 return 0;
660 err1:
661 sh_mobile_lcdc_remove(pdev);
662 err0:
663 return error;
664}
665
666static int sh_mobile_lcdc_remove(struct platform_device *pdev)
667{
668 struct sh_mobile_lcdc_priv *priv = platform_get_drvdata(pdev);
669 struct fb_info *info;
670 int i;
671
672 for (i = 0; i < ARRAY_SIZE(priv->ch); i++)
673 if (priv->ch[i].info.dev)
674 unregister_framebuffer(&priv->ch[i].info);
675
676 sh_mobile_lcdc_stop(priv);
677
678 for (i = 0; i < ARRAY_SIZE(priv->ch); i++) {
679 info = &priv->ch[i].info;
680
681 if (!info->device)
682 continue;
683
684 dma_free_coherent(&pdev->dev, info->fix.smem_len,
685 info->screen_base, priv->ch[i].dma_handle);
686 fb_dealloc_cmap(&info->cmap);
687 }
688
689 if (priv->clk) {
690 clk_disable(priv->clk);
691 clk_put(priv->clk);
692 }
693
694 if (priv->base)
695 iounmap(priv->base);
696
697 kfree(priv);
698 return 0;
699}
700
701static struct platform_driver sh_mobile_lcdc_driver = {
702 .driver = {
703 .name = "sh_mobile_lcdc_fb",
704 .owner = THIS_MODULE,
705 },
706 .probe = sh_mobile_lcdc_probe,
707 .remove = sh_mobile_lcdc_remove,
708};
709
710static int __init sh_mobile_lcdc_init(void)
711{
712 return platform_driver_register(&sh_mobile_lcdc_driver);
713}
714
715static void __exit sh_mobile_lcdc_exit(void)
716{
717 platform_driver_unregister(&sh_mobile_lcdc_driver);
718}
719
720module_init(sh_mobile_lcdc_init);
721module_exit(sh_mobile_lcdc_exit);
722
723MODULE_DESCRIPTION("SuperH Mobile LCDC Framebuffer driver");
724MODULE_AUTHOR("Magnus Damm <damm@opensource.se>");
725MODULE_LICENSE("GPL v2");
diff --git a/drivers/video/sis/init.h b/drivers/video/sis/init.h
index f40a680df86f..b96005c39c67 100644
--- a/drivers/video/sis/init.h
+++ b/drivers/video/sis/init.h
@@ -73,7 +73,6 @@
73#ifdef SIS_CP 73#ifdef SIS_CP
74#undef SIS_CP 74#undef SIS_CP
75#endif 75#endif
76#include <linux/version.h>
77#include <linux/types.h> 76#include <linux/types.h>
78#include <asm/io.h> 77#include <asm/io.h>
79#include <linux/fb.h> 78#include <linux/fb.h>
diff --git a/drivers/video/sis/init301.h b/drivers/video/sis/init301.h
index 7708e1e1d99e..51d99222375d 100644
--- a/drivers/video/sis/init301.h
+++ b/drivers/video/sis/init301.h
@@ -67,7 +67,6 @@
67#ifdef SIS_CP 67#ifdef SIS_CP
68#undef SIS_CP 68#undef SIS_CP
69#endif 69#endif
70#include <linux/version.h>
71#include <linux/types.h> 70#include <linux/types.h>
72#include <asm/io.h> 71#include <asm/io.h>
73#include <linux/fb.h> 72#include <linux/fb.h>
diff --git a/drivers/video/sis/initextlfb.c b/drivers/video/sis/initextlfb.c
index 47a33501549d..99c04a4855d1 100644
--- a/drivers/video/sis/initextlfb.c
+++ b/drivers/video/sis/initextlfb.c
@@ -30,7 +30,6 @@
30#include "vgatypes.h" 30#include "vgatypes.h"
31#include "vstruct.h" 31#include "vstruct.h"
32 32
33#include <linux/version.h>
34#include <linux/types.h> 33#include <linux/types.h>
35#include <linux/fb.h> 34#include <linux/fb.h>
36 35
diff --git a/drivers/video/sis/osdef.h b/drivers/video/sis/osdef.h
index c1492782cb18..6ff8f988a1a7 100644
--- a/drivers/video/sis/osdef.h
+++ b/drivers/video/sis/osdef.h
@@ -87,7 +87,6 @@
87/**********************************************************************/ 87/**********************************************************************/
88 88
89#ifdef SIS_LINUX_KERNEL 89#ifdef SIS_LINUX_KERNEL
90#include <linux/version.h>
91 90
92#ifdef CONFIG_FB_SIS_300 91#ifdef CONFIG_FB_SIS_300
93#define SIS300 92#define SIS300
diff --git a/drivers/video/sis/sis.h b/drivers/video/sis/sis.h
index a14e82211037..7c5710e3fb56 100644
--- a/drivers/video/sis/sis.h
+++ b/drivers/video/sis/sis.h
@@ -24,8 +24,6 @@
24#ifndef _SIS_H_ 24#ifndef _SIS_H_
25#define _SIS_H_ 25#define _SIS_H_
26 26
27#include <linux/version.h>
28
29#include "osdef.h" 27#include "osdef.h"
30#include <video/sisfb.h> 28#include <video/sisfb.h>
31 29
@@ -42,16 +40,6 @@
42#define SIS_NEW_CONFIG_COMPAT 40#define SIS_NEW_CONFIG_COMPAT
43#endif /* CONFIG_COMPAT */ 41#endif /* CONFIG_COMPAT */
44 42
45#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,8)
46#define SIS_IOTYPE1 void __iomem
47#define SIS_IOTYPE2 __iomem
48#define SISINITSTATIC static
49#else
50#define SIS_IOTYPE1 unsigned char
51#define SIS_IOTYPE2
52#define SISINITSTATIC
53#endif
54
55#undef SISFBDEBUG 43#undef SISFBDEBUG
56 44
57#ifdef SISFBDEBUG 45#ifdef SISFBDEBUG
@@ -505,8 +493,8 @@ struct sis_video_info {
505 493
506 unsigned long UMAsize, LFBsize; 494 unsigned long UMAsize, LFBsize;
507 495
508 SIS_IOTYPE1 *video_vbase; 496 void __iomem *video_vbase;
509 SIS_IOTYPE1 *mmio_vbase; 497 void __iomem *mmio_vbase;
510 498
511 unsigned char *bios_abase; 499 unsigned char *bios_abase;
512 500
@@ -533,8 +521,8 @@ struct sis_video_info {
533 int sisfb_nocrt2rate; 521 int sisfb_nocrt2rate;
534 522
535 u32 heapstart; /* offset */ 523 u32 heapstart; /* offset */
536 SIS_IOTYPE1 *sisfb_heap_start; /* address */ 524 void __iomem *sisfb_heap_start; /* address */
537 SIS_IOTYPE1 *sisfb_heap_end; /* address */ 525 void __iomem *sisfb_heap_end; /* address */
538 u32 sisfb_heap_size; 526 u32 sisfb_heap_size;
539 int havenoheap; 527 int havenoheap;
540 528
@@ -612,7 +600,7 @@ struct sis_video_info {
612 u8 detectedpdca; 600 u8 detectedpdca;
613 u8 detectedlcda; 601 u8 detectedlcda;
614 602
615 SIS_IOTYPE1 *hwcursor_vbase; 603 void __iomem *hwcursor_vbase;
616 604
617 int chronteltype; 605 int chronteltype;
618 int tvxpos, tvypos; 606 int tvxpos, tvypos;
diff --git a/drivers/video/sis/sis_accel.c b/drivers/video/sis/sis_accel.c
index 7addf91d2fea..ceb434c95c0d 100644
--- a/drivers/video/sis/sis_accel.c
+++ b/drivers/video/sis/sis_accel.c
@@ -28,7 +28,6 @@
28 * for more information and updates) 28 * for more information and updates)
29 */ 29 */
30 30
31#include <linux/version.h>
32#include <linux/module.h> 31#include <linux/module.h>
33#include <linux/kernel.h> 32#include <linux/kernel.h>
34#include <linux/fb.h> 33#include <linux/fb.h>
diff --git a/drivers/video/sis/sis_main.c b/drivers/video/sis/sis_main.c
index b9343844cd1f..346d6458cf76 100644
--- a/drivers/video/sis/sis_main.c
+++ b/drivers/video/sis/sis_main.c
@@ -33,7 +33,6 @@
33 * 33 *
34 */ 34 */
35 35
36#include <linux/version.h>
37#include <linux/module.h> 36#include <linux/module.h>
38#include <linux/moduleparam.h> 37#include <linux/moduleparam.h>
39#include <linux/kernel.h> 38#include <linux/kernel.h>
@@ -41,13 +40,7 @@
41#include <linux/errno.h> 40#include <linux/errno.h>
42#include <linux/string.h> 41#include <linux/string.h>
43#include <linux/mm.h> 42#include <linux/mm.h>
44
45#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,17)
46#include <linux/tty.h>
47#else
48#include <linux/screen_info.h> 43#include <linux/screen_info.h>
49#endif
50
51#include <linux/slab.h> 44#include <linux/slab.h>
52#include <linux/fb.h> 45#include <linux/fb.h>
53#include <linux/selection.h> 46#include <linux/selection.h>
@@ -1167,11 +1160,7 @@ sisfb_set_mode(struct sis_video_info *ivideo, int clrscrn)
1167 unsigned short modeno = ivideo->mode_no; 1160 unsigned short modeno = ivideo->mode_no;
1168 1161
1169 /* >=2.6.12's fbcon clears the screen anyway */ 1162 /* >=2.6.12's fbcon clears the screen anyway */
1170#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,12)
1171 if(!clrscrn) modeno |= 0x80;
1172#else
1173 modeno |= 0x80; 1163 modeno |= 0x80;
1174#endif
1175 1164
1176 outSISIDXREG(SISSR, IND_SIS_PASSWORD, SIS_PASSWORD); 1165 outSISIDXREG(SISSR, IND_SIS_PASSWORD, SIS_PASSWORD);
1177 1166
@@ -1436,11 +1425,8 @@ sisfb_set_par(struct fb_info *info)
1436 if((err = sisfb_do_set_var(&info->var, 1, info))) 1425 if((err = sisfb_do_set_var(&info->var, 1, info)))
1437 return err; 1426 return err;
1438 1427
1439#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,10)
1440 sisfb_get_fix(&info->fix, info->currcon, info);
1441#else
1442 sisfb_get_fix(&info->fix, -1, info); 1428 sisfb_get_fix(&info->fix, -1, info);
1443#endif 1429
1444 return 0; 1430 return 0;
1445} 1431}
1446 1432
@@ -1676,14 +1662,8 @@ sisfb_blank(int blank, struct fb_info *info)
1676 1662
1677/* ----------- FBDev related routines for all series ---------- */ 1663/* ----------- FBDev related routines for all series ---------- */
1678 1664
1679#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,15)
1680static int sisfb_ioctl(struct fb_info *info, unsigned int cmd, 1665static int sisfb_ioctl(struct fb_info *info, unsigned int cmd,
1681 unsigned long arg) 1666 unsigned long arg)
1682#else
1683static int sisfb_ioctl(struct inode *inode, struct file *file,
1684 unsigned int cmd, unsigned long arg,
1685 struct fb_info *info)
1686#endif
1687{ 1667{
1688 struct sis_video_info *ivideo = (struct sis_video_info *)info->par; 1668 struct sis_video_info *ivideo = (struct sis_video_info *)info->par;
1689 struct sis_memreq sismemreq; 1669 struct sis_memreq sismemreq;
@@ -3986,8 +3966,7 @@ sisfb_handle_command(struct sis_video_info *ivideo, struct sisfb_cmd *sisfb_comm
3986} 3966}
3987 3967
3988#ifndef MODULE 3968#ifndef MODULE
3989SISINITSTATIC int __init 3969static int __init sisfb_setup(char *options)
3990sisfb_setup(char *options)
3991{ 3970{
3992 char *this_opt; 3971 char *this_opt;
3993 3972
@@ -4086,9 +4065,9 @@ sisfb_setup(char *options)
4086#endif 4065#endif
4087 4066
4088static int __devinit 4067static int __devinit
4089sisfb_check_rom(SIS_IOTYPE1 *rom_base, struct sis_video_info *ivideo) 4068sisfb_check_rom(void __iomem *rom_base, struct sis_video_info *ivideo)
4090{ 4069{
4091 SIS_IOTYPE1 *rom; 4070 void __iomem *rom;
4092 int romptr; 4071 int romptr;
4093 4072
4094 if((readb(rom_base) != 0x55) || (readb(rom_base + 1) != 0xaa)) 4073 if((readb(rom_base) != 0x55) || (readb(rom_base + 1) != 0xaa))
@@ -4117,10 +4096,9 @@ static unsigned char * __devinit
4117sisfb_find_rom(struct pci_dev *pdev) 4096sisfb_find_rom(struct pci_dev *pdev)
4118{ 4097{
4119 struct sis_video_info *ivideo = pci_get_drvdata(pdev); 4098 struct sis_video_info *ivideo = pci_get_drvdata(pdev);
4120 SIS_IOTYPE1 *rom_base; 4099 void __iomem *rom_base;
4121 unsigned char *myrombase = NULL; 4100 unsigned char *myrombase = NULL;
4122 u32 temp; 4101 u32 temp;
4123#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,11)
4124 size_t romsize; 4102 size_t romsize;
4125 4103
4126 /* First, try the official pci ROM functions (except 4104 /* First, try the official pci ROM functions (except
@@ -4151,7 +4129,6 @@ sisfb_find_rom(struct pci_dev *pdev)
4151 } 4129 }
4152 4130
4153 if(myrombase) return myrombase; 4131 if(myrombase) return myrombase;
4154#endif
4155 4132
4156 /* Otherwise do it the conventional way. */ 4133 /* Otherwise do it the conventional way. */
4157 4134
@@ -4225,7 +4202,7 @@ sisfb_post_map_vram(struct sis_video_info *ivideo, unsigned int *mapsize,
4225static int __devinit 4202static int __devinit
4226sisfb_post_300_buswidth(struct sis_video_info *ivideo) 4203sisfb_post_300_buswidth(struct sis_video_info *ivideo)
4227{ 4204{
4228 SIS_IOTYPE1 *FBAddress = ivideo->video_vbase; 4205 void __iomem *FBAddress = ivideo->video_vbase;
4229 unsigned short temp; 4206 unsigned short temp;
4230 unsigned char reg; 4207 unsigned char reg;
4231 int i, j; 4208 int i, j;
@@ -4273,7 +4250,7 @@ sisfb_post_300_rwtest(struct sis_video_info *ivideo, int iteration, int buswidth
4273 int PseudoRankCapacity, int PseudoAdrPinCount, 4250 int PseudoRankCapacity, int PseudoAdrPinCount,
4274 unsigned int mapsize) 4251 unsigned int mapsize)
4275{ 4252{
4276 SIS_IOTYPE1 *FBAddr = ivideo->video_vbase; 4253 void __iomem *FBAddr = ivideo->video_vbase;
4277 unsigned short sr14; 4254 unsigned short sr14;
4278 unsigned int k, RankCapacity, PageCapacity, BankNumHigh, BankNumMid; 4255 unsigned int k, RankCapacity, PageCapacity, BankNumHigh, BankNumMid;
4279 unsigned int PhysicalAdrOtherPage, PhysicalAdrHigh, PhysicalAdrHalfPage; 4256 unsigned int PhysicalAdrOtherPage, PhysicalAdrHigh, PhysicalAdrHalfPage;
@@ -5829,7 +5806,7 @@ sisfb_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
5829 ivideo->engineok = 0; 5806 ivideo->engineok = 0;
5830 5807
5831 ivideo->sisfb_was_boot_device = 0; 5808 ivideo->sisfb_was_boot_device = 0;
5832#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,12)) 5809
5833 if(pdev->resource[PCI_ROM_RESOURCE].flags & IORESOURCE_ROM_SHADOW) { 5810 if(pdev->resource[PCI_ROM_RESOURCE].flags & IORESOURCE_ROM_SHADOW) {
5834 if(ivideo->sisvga_enabled) 5811 if(ivideo->sisvga_enabled)
5835 ivideo->sisfb_was_boot_device = 1; 5812 ivideo->sisfb_was_boot_device = 1;
@@ -5840,7 +5817,6 @@ sisfb_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
5840 "as the primary VGA device\n"); 5817 "as the primary VGA device\n");
5841 } 5818 }
5842 } 5819 }
5843#endif
5844 5820
5845 ivideo->sisfb_parm_mem = sisfb_parm_mem; 5821 ivideo->sisfb_parm_mem = sisfb_parm_mem;
5846 ivideo->sisfb_accel = sisfb_accel; 5822 ivideo->sisfb_accel = sisfb_accel;
@@ -6010,7 +5986,7 @@ sisfb_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
6010 ivideo->modeprechange = reg & 0x7f; 5986 ivideo->modeprechange = reg & 0x7f;
6011 } else if(ivideo->sisvga_enabled) { 5987 } else if(ivideo->sisvga_enabled) {
6012#if defined(__i386__) || defined(__x86_64__) 5988#if defined(__i386__) || defined(__x86_64__)
6013 unsigned char SIS_IOTYPE2 *tt = ioremap(0x400, 0x100); 5989 unsigned char __iomem *tt = ioremap(0x400, 0x100);
6014 if(tt) { 5990 if(tt) {
6015 ivideo->modeprechange = readb(tt + 0x49); 5991 ivideo->modeprechange = readb(tt + 0x49);
6016 iounmap(tt); 5992 iounmap(tt);
@@ -6503,7 +6479,7 @@ static struct pci_driver sisfb_driver = {
6503 .remove = __devexit_p(sisfb_remove) 6479 .remove = __devexit_p(sisfb_remove)
6504}; 6480};
6505 6481
6506SISINITSTATIC int __init sisfb_init(void) 6482static int __init sisfb_init(void)
6507{ 6483{
6508#ifndef MODULE 6484#ifndef MODULE
6509 char *options = NULL; 6485 char *options = NULL;
diff --git a/drivers/video/sis/sis_main.h b/drivers/video/sis/sis_main.h
index 3e3b7fa05d6c..9540e977270e 100644
--- a/drivers/video/sis/sis_main.h
+++ b/drivers/video/sis/sis_main.h
@@ -665,11 +665,11 @@ static struct _customttable {
665 665
666/* Interface used by the world */ 666/* Interface used by the world */
667#ifndef MODULE 667#ifndef MODULE
668SISINITSTATIC int sisfb_setup(char *options); 668static int sisfb_setup(char *options);
669#endif 669#endif
670 670
671/* Interface to the low level console driver */ 671/* Interface to the low level console driver */
672SISINITSTATIC int sisfb_init(void); 672static int sisfb_init(void);
673 673
674/* fbdev routines */ 674/* fbdev routines */
675static int sisfb_get_fix(struct fb_fix_screeninfo *fix, int con, 675static int sisfb_get_fix(struct fb_fix_screeninfo *fix, int con,
diff --git a/drivers/video/sis/vgatypes.h b/drivers/video/sis/vgatypes.h
index b532fbd2b04c..81a22eaabfde 100644
--- a/drivers/video/sis/vgatypes.h
+++ b/drivers/video/sis/vgatypes.h
@@ -53,10 +53,6 @@
53#ifndef _VGATYPES_H_ 53#ifndef _VGATYPES_H_
54#define _VGATYPES_H_ 54#define _VGATYPES_H_
55 55
56#ifdef SIS_LINUX_KERNEL
57#include <linux/version.h>
58#endif
59
60#define SISIOMEMTYPE 56#define SISIOMEMTYPE
61 57
62#ifdef SIS_LINUX_KERNEL 58#ifdef SIS_LINUX_KERNEL
diff --git a/drivers/video/skeletonfb.c b/drivers/video/skeletonfb.c
index 62321458f71a..df5336561d13 100644
--- a/drivers/video/skeletonfb.c
+++ b/drivers/video/skeletonfb.c
@@ -675,13 +675,13 @@ static struct fb_ops xxxfb_ops = {
675 * Initialization 675 * Initialization
676 */ 676 */
677 677
678/* static int __init xxfb_probe (struct device *device) -- for platform devs */ 678/* static int __init xxfb_probe (struct platform_device *pdev) -- for platform devs */
679static int __devinit xxxfb_probe(struct pci_dev *dev, 679static int __devinit xxxfb_probe(struct pci_dev *dev,
680 const struct pci_device_id *ent) 680 const struct pci_device_id *ent)
681{ 681{
682 struct fb_info *info; 682 struct fb_info *info;
683 struct xxx_par *par; 683 struct xxx_par *par;
684 struct device* device = &dev->dev; /* for pci drivers */ 684 struct device *device = &dev->dev; /* or &pdev->dev */
685 int cmap_len, retval; 685 int cmap_len, retval;
686 686
687 /* 687 /*
@@ -824,18 +824,18 @@ static int __devinit xxxfb_probe(struct pci_dev *dev,
824 return -EINVAL; 824 return -EINVAL;
825 printk(KERN_INFO "fb%d: %s frame buffer device\n", info->node, 825 printk(KERN_INFO "fb%d: %s frame buffer device\n", info->node,
826 info->fix.id); 826 info->fix.id);
827 pci_set_drvdata(dev, info); /* or dev_set_drvdata(device, info) */ 827 pci_set_drvdata(dev, info); /* or platform_set_drvdata(pdev, info) */
828 return 0; 828 return 0;
829} 829}
830 830
831 /* 831 /*
832 * Cleanup 832 * Cleanup
833 */ 833 */
834/* static void __devexit xxxfb_remove(struct device *device) */ 834/* static void __devexit xxxfb_remove(struct platform_device *pdev) */
835static void __devexit xxxfb_remove(struct pci_dev *dev) 835static void __devexit xxxfb_remove(struct pci_dev *dev)
836{ 836{
837 struct fb_info *info = pci_get_drvdata(dev); 837 struct fb_info *info = pci_get_drvdata(dev);
838 /* or dev_get_drvdata(device); */ 838 /* or platform_get_drvdata(pdev); */
839 839
840 if (info) { 840 if (info) {
841 unregister_framebuffer(info); 841 unregister_framebuffer(info);
@@ -961,18 +961,17 @@ static int xxxfb_resume(struct platform_dev *dev)
961#define xxxfb_resume NULL 961#define xxxfb_resume NULL
962#endif /* CONFIG_PM */ 962#endif /* CONFIG_PM */
963 963
964static struct device_driver xxxfb_driver = { 964static struct platform_device_driver xxxfb_driver = {
965 .name = "xxxfb",
966 .bus = &platform_bus_type,
967 .probe = xxxfb_probe, 965 .probe = xxxfb_probe,
968 .remove = xxxfb_remove, 966 .remove = xxxfb_remove,
969 .suspend = xxxfb_suspend, /* optional but recommended */ 967 .suspend = xxxfb_suspend, /* optional but recommended */
970 .resume = xxxfb_resume, /* optional but recommended */ 968 .resume = xxxfb_resume, /* optional but recommended */
969 .driver = {
970 .name = "xxxfb",
971 },
971}; 972};
972 973
973static struct platform_device xxxfb_device = { 974static struct platform_device *xxxfb_device;
974 .name = "xxxfb",
975};
976 975
977#ifndef MODULE 976#ifndef MODULE
978 /* 977 /*
@@ -1002,12 +1001,16 @@ static int __init xxxfb_init(void)
1002 return -ENODEV; 1001 return -ENODEV;
1003 xxxfb_setup(option); 1002 xxxfb_setup(option);
1004#endif 1003#endif
1005 ret = driver_register(&xxxfb_driver); 1004 ret = platform_driver_register(&xxxfb_driver);
1006 1005
1007 if (!ret) { 1006 if (!ret) {
1008 ret = platform_device_register(&xxxfb_device); 1007 xxxfb_device = platform_device_register_simple("xxxfb", 0,
1009 if (ret) 1008 NULL, 0);
1010 driver_unregister(&xxxfb_driver); 1009
1010 if (IS_ERR(xxxfb_device)) {
1011 platform_driver_unregister(&xxxfb_driver);
1012 ret = PTR_ERR(xxxfb_device);
1013 }
1011 } 1014 }
1012 1015
1013 return ret; 1016 return ret;
@@ -1015,8 +1018,8 @@ static int __init xxxfb_init(void)
1015 1018
1016static void __exit xxxfb_exit(void) 1019static void __exit xxxfb_exit(void)
1017{ 1020{
1018 platform_device_unregister(&xxxfb_device); 1021 platform_device_unregister(xxxfb_device);
1019 driver_unregister(&xxxfb_driver); 1022 platform_driver_unregister(&xxxfb_driver);
1020} 1023}
1021#endif /* CONFIG_PCI */ 1024#endif /* CONFIG_PCI */
1022 1025
diff --git a/drivers/video/sm501fb.c b/drivers/video/sm501fb.c
index 15d4a768b1f6..f94ae84a58cd 100644
--- a/drivers/video/sm501fb.c
+++ b/drivers/video/sm501fb.c
@@ -48,10 +48,15 @@ enum sm501_controller {
48 HEAD_PANEL = 1, 48 HEAD_PANEL = 1,
49}; 49};
50 50
51/* SM501 memory address */ 51/* SM501 memory address.
52 *
53 * This structure is used to track memory usage within the SM501 framebuffer
54 * allocation. The sm_addr field is stored as an offset as it is often used
55 * against both the physical and mapped addresses.
56 */
52struct sm501_mem { 57struct sm501_mem {
53 unsigned long size; 58 unsigned long size;
54 unsigned long sm_addr; 59 unsigned long sm_addr; /* offset from base of sm501 fb. */
55 void __iomem *k_addr; 60 void __iomem *k_addr;
56}; 61};
57 62
@@ -142,31 +147,68 @@ static inline void sm501fb_sync_regs(struct sm501fb_info *info)
142static int sm501_alloc_mem(struct sm501fb_info *inf, struct sm501_mem *mem, 147static int sm501_alloc_mem(struct sm501fb_info *inf, struct sm501_mem *mem,
143 unsigned int why, size_t size) 148 unsigned int why, size_t size)
144{ 149{
145 unsigned int ptr = 0; 150 struct sm501fb_par *par;
151 struct fb_info *fbi;
152 unsigned int ptr;
153 unsigned int end;
146 154
147 switch (why) { 155 switch (why) {
148 case SM501_MEMF_CURSOR: 156 case SM501_MEMF_CURSOR:
149 ptr = inf->fbmem_len - size; 157 ptr = inf->fbmem_len - size;
150 inf->fbmem_len = ptr; 158 inf->fbmem_len = ptr; /* adjust available memory. */
151 break; 159 break;
152 160
153 case SM501_MEMF_PANEL: 161 case SM501_MEMF_PANEL:
154 ptr = inf->fbmem_len - size; 162 ptr = inf->fbmem_len - size;
155 if (ptr < inf->fb[0]->fix.smem_len) 163 fbi = inf->fb[HEAD_CRT];
164
165 /* round down, some programs such as directfb do not draw
166 * 0,0 correctly unless the start is aligned to a page start.
167 */
168
169 if (ptr > 0)
170 ptr &= ~(PAGE_SIZE - 1);
171
172 if (fbi && ptr < fbi->fix.smem_len)
173 return -ENOMEM;
174
175 if (ptr < 0)
156 return -ENOMEM; 176 return -ENOMEM;
157 177
158 break; 178 break;
159 179
160 case SM501_MEMF_CRT: 180 case SM501_MEMF_CRT:
161 ptr = 0; 181 ptr = 0;
182
183 /* check to see if we have panel memory allocated
184 * which would put an limit on available memory. */
185
186 fbi = inf->fb[HEAD_PANEL];
187 if (fbi) {
188 par = fbi->par;
189 end = par->screen.k_addr ? par->screen.sm_addr : inf->fbmem_len;
190 } else
191 end = inf->fbmem_len;
192
193 if ((ptr + size) > end)
194 return -ENOMEM;
195
162 break; 196 break;
163 197
164 case SM501_MEMF_ACCEL: 198 case SM501_MEMF_ACCEL:
165 ptr = inf->fb[0]->fix.smem_len; 199 fbi = inf->fb[HEAD_CRT];
200 ptr = fbi ? fbi->fix.smem_len : 0;
201
202 fbi = inf->fb[HEAD_PANEL];
203 if (fbi) {
204 par = fbi->par;
205 end = par->screen.sm_addr;
206 } else
207 end = inf->fbmem_len;
166 208
167 if ((ptr + size) > 209 if ((ptr + size) > end)
168 (inf->fb[1]->fix.smem_start - inf->fbmem_res->start))
169 return -ENOMEM; 210 return -ENOMEM;
211
170 break; 212 break;
171 213
172 default: 214 default:
@@ -663,15 +705,25 @@ static void sm501fb_panel_power(struct sm501fb_info *fbi, int to)
663 sm501fb_sync_regs(fbi); 705 sm501fb_sync_regs(fbi);
664 mdelay(10); 706 mdelay(10);
665 707
708 /* VBIASEN */
709
666 if (!(pd->flags & SM501FB_FLAG_PANEL_NO_VBIASEN)) { 710 if (!(pd->flags & SM501FB_FLAG_PANEL_NO_VBIASEN)) {
667 control |= SM501_DC_PANEL_CONTROL_BIAS; /* VBIASEN */ 711 if (pd->flags & SM501FB_FLAG_PANEL_INV_VBIASEN)
712 control &= ~SM501_DC_PANEL_CONTROL_BIAS;
713 else
714 control |= SM501_DC_PANEL_CONTROL_BIAS;
715
668 writel(control, ctrl_reg); 716 writel(control, ctrl_reg);
669 sm501fb_sync_regs(fbi); 717 sm501fb_sync_regs(fbi);
670 mdelay(10); 718 mdelay(10);
671 } 719 }
672 720
673 if (!(pd->flags & SM501FB_FLAG_PANEL_NO_FPEN)) { 721 if (!(pd->flags & SM501FB_FLAG_PANEL_NO_FPEN)) {
674 control |= SM501_DC_PANEL_CONTROL_FPEN; 722 if (pd->flags & SM501FB_FLAG_PANEL_INV_FPEN)
723 control &= ~SM501_DC_PANEL_CONTROL_FPEN;
724 else
725 control |= SM501_DC_PANEL_CONTROL_FPEN;
726
675 writel(control, ctrl_reg); 727 writel(control, ctrl_reg);
676 sm501fb_sync_regs(fbi); 728 sm501fb_sync_regs(fbi);
677 mdelay(10); 729 mdelay(10);
@@ -679,14 +731,22 @@ static void sm501fb_panel_power(struct sm501fb_info *fbi, int to)
679 } else if (!to && (control & SM501_DC_PANEL_CONTROL_VDD) != 0) { 731 } else if (!to && (control & SM501_DC_PANEL_CONTROL_VDD) != 0) {
680 /* disable panel power */ 732 /* disable panel power */
681 if (!(pd->flags & SM501FB_FLAG_PANEL_NO_FPEN)) { 733 if (!(pd->flags & SM501FB_FLAG_PANEL_NO_FPEN)) {
682 control &= ~SM501_DC_PANEL_CONTROL_FPEN; 734 if (pd->flags & SM501FB_FLAG_PANEL_INV_FPEN)
735 control |= SM501_DC_PANEL_CONTROL_FPEN;
736 else
737 control &= ~SM501_DC_PANEL_CONTROL_FPEN;
738
683 writel(control, ctrl_reg); 739 writel(control, ctrl_reg);
684 sm501fb_sync_regs(fbi); 740 sm501fb_sync_regs(fbi);
685 mdelay(10); 741 mdelay(10);
686 } 742 }
687 743
688 if (!(pd->flags & SM501FB_FLAG_PANEL_NO_VBIASEN)) { 744 if (!(pd->flags & SM501FB_FLAG_PANEL_NO_VBIASEN)) {
689 control &= ~SM501_DC_PANEL_CONTROL_BIAS; 745 if (pd->flags & SM501FB_FLAG_PANEL_INV_VBIASEN)
746 control |= SM501_DC_PANEL_CONTROL_BIAS;
747 else
748 control &= ~SM501_DC_PANEL_CONTROL_BIAS;
749
690 writel(control, ctrl_reg); 750 writel(control, ctrl_reg);
691 sm501fb_sync_regs(fbi); 751 sm501fb_sync_regs(fbi);
692 mdelay(10); 752 mdelay(10);
@@ -1210,39 +1270,6 @@ static struct fb_ops sm501fb_ops_pnl = {
1210 .fb_imageblit = cfb_imageblit, 1270 .fb_imageblit = cfb_imageblit,
1211}; 1271};
1212 1272
1213/* sm501fb_info_alloc
1214 *
1215 * creates and initialises an sm501fb_info structure
1216*/
1217
1218static struct sm501fb_info *sm501fb_info_alloc(struct fb_info *fbinfo_crt,
1219 struct fb_info *fbinfo_pnl)
1220{
1221 struct sm501fb_info *info;
1222 struct sm501fb_par *par;
1223
1224 info = kzalloc(sizeof(struct sm501fb_info), GFP_KERNEL);
1225 if (info) {
1226 /* set the references back */
1227
1228 par = fbinfo_crt->par;
1229 par->info = info;
1230 par->head = HEAD_CRT;
1231 fbinfo_crt->pseudo_palette = &par->pseudo_palette;
1232
1233 par = fbinfo_pnl->par;
1234 par->info = info;
1235 par->head = HEAD_PANEL;
1236 fbinfo_pnl->pseudo_palette = &par->pseudo_palette;
1237
1238 /* store the two fbs into our info */
1239 info->fb[HEAD_CRT] = fbinfo_crt;
1240 info->fb[HEAD_PANEL] = fbinfo_pnl;
1241 }
1242
1243 return info;
1244}
1245
1246/* sm501_init_cursor 1273/* sm501_init_cursor
1247 * 1274 *
1248 * initialise hw cursor parameters 1275 * initialise hw cursor parameters
@@ -1250,10 +1277,16 @@ static struct sm501fb_info *sm501fb_info_alloc(struct fb_info *fbinfo_crt,
1250 1277
1251static int sm501_init_cursor(struct fb_info *fbi, unsigned int reg_base) 1278static int sm501_init_cursor(struct fb_info *fbi, unsigned int reg_base)
1252{ 1279{
1253 struct sm501fb_par *par = fbi->par; 1280 struct sm501fb_par *par;
1254 struct sm501fb_info *info = par->info; 1281 struct sm501fb_info *info;
1255 int ret; 1282 int ret;
1256 1283
1284 if (fbi == NULL)
1285 return 0;
1286
1287 par = fbi->par;
1288 info = par->info;
1289
1257 par->cursor_regs = info->regs + reg_base; 1290 par->cursor_regs = info->regs + reg_base;
1258 1291
1259 ret = sm501_alloc_mem(info, &par->cursor, SM501_MEMF_CURSOR, 1024); 1292 ret = sm501_alloc_mem(info, &par->cursor, SM501_MEMF_CURSOR, 1024);
@@ -1281,13 +1314,10 @@ static int sm501fb_start(struct sm501fb_info *info,
1281 struct platform_device *pdev) 1314 struct platform_device *pdev)
1282{ 1315{
1283 struct resource *res; 1316 struct resource *res;
1284 struct device *dev; 1317 struct device *dev = &pdev->dev;
1285 int k; 1318 int k;
1286 int ret; 1319 int ret;
1287 1320
1288 info->dev = dev = &pdev->dev;
1289 platform_set_drvdata(pdev, info);
1290
1291 info->irq = ret = platform_get_irq(pdev, 0); 1321 info->irq = ret = platform_get_irq(pdev, 0);
1292 if (ret < 0) { 1322 if (ret < 0) {
1293 /* we currently do not use the IRQ */ 1323 /* we currently do not use the IRQ */
@@ -1390,11 +1420,6 @@ static void sm501fb_stop(struct sm501fb_info *info)
1390 kfree(info->regs_res); 1420 kfree(info->regs_res);
1391} 1421}
1392 1422
1393static void sm501fb_info_release(struct sm501fb_info *info)
1394{
1395 kfree(info);
1396}
1397
1398static int sm501fb_init_fb(struct fb_info *fb, 1423static int sm501fb_init_fb(struct fb_info *fb,
1399 enum sm501_controller head, 1424 enum sm501_controller head,
1400 const char *fbname) 1425 const char *fbname)
@@ -1539,36 +1564,93 @@ static struct sm501_platdata_fb sm501fb_def_pdata = {
1539static char driver_name_crt[] = "sm501fb-crt"; 1564static char driver_name_crt[] = "sm501fb-crt";
1540static char driver_name_pnl[] = "sm501fb-panel"; 1565static char driver_name_pnl[] = "sm501fb-panel";
1541 1566
1542static int __init sm501fb_probe(struct platform_device *pdev) 1567static int __devinit sm501fb_probe_one(struct sm501fb_info *info,
1568 enum sm501_controller head)
1543{ 1569{
1544 struct sm501fb_info *info; 1570 unsigned char *name = (head == HEAD_CRT) ? "crt" : "panel";
1545 struct device *dev = &pdev->dev; 1571 struct sm501_platdata_fbsub *pd;
1546 struct fb_info *fbinfo_crt; 1572 struct sm501fb_par *par;
1547 struct fb_info *fbinfo_pnl; 1573 struct fb_info *fbi;
1548 int ret;
1549 1574
1550 /* allocate our framebuffers */ 1575 pd = (head == HEAD_CRT) ? info->pdata->fb_crt : info->pdata->fb_pnl;
1576
1577 /* Do not initialise if we've not been given any platform data */
1578 if (pd == NULL) {
1579 dev_info(info->dev, "no data for fb %s (disabled)\n", name);
1580 return 0;
1581 }
1551 1582
1552 fbinfo_crt = framebuffer_alloc(sizeof(struct sm501fb_par), dev); 1583 fbi = framebuffer_alloc(sizeof(struct sm501fb_par), info->dev);
1553 if (fbinfo_crt == NULL) { 1584 if (fbi == NULL) {
1554 dev_err(dev, "cannot allocate crt framebuffer\n"); 1585 dev_err(info->dev, "cannot allocate %s framebuffer\n", name);
1555 return -ENOMEM; 1586 return -ENOMEM;
1556 } 1587 }
1557 1588
1558 fbinfo_pnl = framebuffer_alloc(sizeof(struct sm501fb_par), dev); 1589 par = fbi->par;
1559 if (fbinfo_pnl == NULL) { 1590 par->info = info;
1560 dev_err(dev, "cannot allocate panel framebuffer\n"); 1591 par->head = head;
1561 ret = -ENOMEM; 1592 fbi->pseudo_palette = &par->pseudo_palette;
1562 goto fbinfo_crt_alloc_fail; 1593
1594 info->fb[head] = fbi;
1595
1596 return 0;
1597}
1598
1599/* Free up anything allocated by sm501fb_init_fb */
1600
1601static void sm501_free_init_fb(struct sm501fb_info *info,
1602 enum sm501_controller head)
1603{
1604 struct fb_info *fbi = info->fb[head];
1605
1606 fb_dealloc_cmap(&fbi->cmap);
1607}
1608
1609static int __devinit sm501fb_start_one(struct sm501fb_info *info,
1610 enum sm501_controller head,
1611 const char *drvname)
1612{
1613 struct fb_info *fbi = info->fb[head];
1614 int ret;
1615
1616 if (!fbi)
1617 return 0;
1618
1619 ret = sm501fb_init_fb(info->fb[head], head, drvname);
1620 if (ret) {
1621 dev_err(info->dev, "cannot initialise fb %s\n", drvname);
1622 return ret;
1623 }
1624
1625 ret = register_framebuffer(info->fb[head]);
1626 if (ret) {
1627 dev_err(info->dev, "failed to register fb %s\n", drvname);
1628 sm501_free_init_fb(info, head);
1629 return ret;
1563 } 1630 }
1564 1631
1565 info = sm501fb_info_alloc(fbinfo_crt, fbinfo_pnl); 1632 dev_info(info->dev, "fb%d: %s frame buffer\n", fbi->node, fbi->fix.id);
1566 if (info == NULL) { 1633
1567 dev_err(dev, "cannot allocate par\n"); 1634 return 0;
1568 ret = -ENOMEM; 1635}
1569 goto sm501fb_alloc_fail; 1636
1637static int __devinit sm501fb_probe(struct platform_device *pdev)
1638{
1639 struct sm501fb_info *info;
1640 struct device *dev = &pdev->dev;
1641 int ret;
1642
1643 /* allocate our framebuffers */
1644
1645 info = kzalloc(sizeof(struct sm501fb_info), GFP_KERNEL);
1646 if (!info) {
1647 dev_err(dev, "failed to allocate state\n");
1648 return -ENOMEM;
1570 } 1649 }
1571 1650
1651 info->dev = dev = &pdev->dev;
1652 platform_set_drvdata(pdev, info);
1653
1572 if (dev->parent->platform_data) { 1654 if (dev->parent->platform_data) {
1573 struct sm501_platdata *pd = dev->parent->platform_data; 1655 struct sm501_platdata *pd = dev->parent->platform_data;
1574 info->pdata = pd->fb; 1656 info->pdata = pd->fb;
@@ -1579,90 +1661,88 @@ static int __init sm501fb_probe(struct platform_device *pdev)
1579 info->pdata = &sm501fb_def_pdata; 1661 info->pdata = &sm501fb_def_pdata;
1580 } 1662 }
1581 1663
1582 /* start the framebuffers */ 1664 /* probe for the presence of each panel */
1583 1665
1584 ret = sm501fb_start(info, pdev); 1666 ret = sm501fb_probe_one(info, HEAD_CRT);
1585 if (ret) { 1667 if (ret < 0) {
1586 dev_err(dev, "cannot initialise SM501\n"); 1668 dev_err(dev, "failed to probe CRT\n");
1587 goto sm501fb_start_fail; 1669 goto err_alloc;
1588 } 1670 }
1589 1671
1590 /* CRT framebuffer setup */ 1672 ret = sm501fb_probe_one(info, HEAD_PANEL);
1673 if (ret < 0) {
1674 dev_err(dev, "failed to probe PANEL\n");
1675 goto err_probed_crt;
1676 }
1591 1677
1592 ret = sm501fb_init_fb(fbinfo_crt, HEAD_CRT, driver_name_crt); 1678 if (info->fb[HEAD_PANEL] == NULL &&
1593 if (ret) { 1679 info->fb[HEAD_CRT] == NULL) {
1594 dev_err(dev, "cannot initialise CRT fb\n"); 1680 dev_err(dev, "no framebuffers found\n");
1595 goto sm501fb_start_fail; 1681 goto err_alloc;
1596 } 1682 }
1597 1683
1598 /* Panel framebuffer setup */ 1684 /* get the resources for both of the framebuffers */
1599 1685
1600 ret = sm501fb_init_fb(fbinfo_pnl, HEAD_PANEL, driver_name_pnl); 1686 ret = sm501fb_start(info, pdev);
1601 if (ret) { 1687 if (ret) {
1602 dev_err(dev, "cannot initialise Panel fb\n"); 1688 dev_err(dev, "cannot initialise SM501\n");
1603 goto sm501fb_start_fail; 1689 goto err_probed_panel;
1604 } 1690 }
1605 1691
1606 /* register framebuffers */ 1692 ret = sm501fb_start_one(info, HEAD_CRT, driver_name_crt);
1607 1693 if (ret) {
1608 ret = register_framebuffer(fbinfo_crt); 1694 dev_err(dev, "failed to start CRT\n");
1609 if (ret < 0) { 1695 goto err_started;
1610 dev_err(dev, "failed to register CRT fb (%d)\n", ret);
1611 goto register_crt_fail;
1612 } 1696 }
1613 1697
1614 ret = register_framebuffer(fbinfo_pnl); 1698 ret = sm501fb_start_one(info, HEAD_PANEL, driver_name_pnl);
1615 if (ret < 0) { 1699 if (ret) {
1616 dev_err(dev, "failed to register panel fb (%d)\n", ret); 1700 dev_err(dev, "failed to start Panel\n");
1617 goto register_pnl_fail; 1701 goto err_started_crt;
1618 } 1702 }
1619 1703
1620 dev_info(dev, "fb%d: %s frame buffer device\n",
1621 fbinfo_crt->node, fbinfo_crt->fix.id);
1622
1623 dev_info(dev, "fb%d: %s frame buffer device\n",
1624 fbinfo_pnl->node, fbinfo_pnl->fix.id);
1625
1626 /* create device files */ 1704 /* create device files */
1627 1705
1628 ret = device_create_file(dev, &dev_attr_crt_src); 1706 ret = device_create_file(dev, &dev_attr_crt_src);
1629 if (ret) 1707 if (ret)
1630 goto crtsrc_fail; 1708 goto err_started_panel;
1631 1709
1632 ret = device_create_file(dev, &dev_attr_fbregs_pnl); 1710 ret = device_create_file(dev, &dev_attr_fbregs_pnl);
1633 if (ret) 1711 if (ret)
1634 goto fbregs_pnl_fail; 1712 goto err_attached_crtsrc_file;
1635 1713
1636 ret = device_create_file(dev, &dev_attr_fbregs_crt); 1714 ret = device_create_file(dev, &dev_attr_fbregs_crt);
1637 if (ret) 1715 if (ret)
1638 goto fbregs_crt_fail; 1716 goto err_attached_pnlregs_file;
1639 1717
1640 /* we registered, return ok */ 1718 /* we registered, return ok */
1641 return 0; 1719 return 0;
1642 1720
1643 fbregs_crt_fail: 1721err_attached_pnlregs_file:
1644 device_remove_file(dev, &dev_attr_fbregs_pnl); 1722 device_remove_file(dev, &dev_attr_fbregs_pnl);
1645 1723
1646 fbregs_pnl_fail: 1724err_attached_crtsrc_file:
1647 device_remove_file(dev, &dev_attr_crt_src); 1725 device_remove_file(dev, &dev_attr_crt_src);
1648 1726
1649 crtsrc_fail: 1727err_started_panel:
1650 unregister_framebuffer(fbinfo_pnl); 1728 unregister_framebuffer(info->fb[HEAD_PANEL]);
1729 sm501_free_init_fb(info, HEAD_PANEL);
1651 1730
1652 register_pnl_fail: 1731err_started_crt:
1653 unregister_framebuffer(fbinfo_crt); 1732 unregister_framebuffer(info->fb[HEAD_CRT]);
1733 sm501_free_init_fb(info, HEAD_CRT);
1654 1734
1655 register_crt_fail: 1735err_started:
1656 sm501fb_stop(info); 1736 sm501fb_stop(info);
1657 1737
1658 sm501fb_start_fail: 1738err_probed_panel:
1659 sm501fb_info_release(info); 1739 framebuffer_release(info->fb[HEAD_PANEL]);
1660 1740
1661 sm501fb_alloc_fail: 1741err_probed_crt:
1662 framebuffer_release(fbinfo_pnl); 1742 framebuffer_release(info->fb[HEAD_CRT]);
1663 1743
1664 fbinfo_crt_alloc_fail: 1744err_alloc:
1665 framebuffer_release(fbinfo_crt); 1745 kfree(info);
1666 1746
1667 return ret; 1747 return ret;
1668} 1748}
@@ -1681,11 +1761,14 @@ static int sm501fb_remove(struct platform_device *pdev)
1681 device_remove_file(&pdev->dev, &dev_attr_fbregs_pnl); 1761 device_remove_file(&pdev->dev, &dev_attr_fbregs_pnl);
1682 device_remove_file(&pdev->dev, &dev_attr_crt_src); 1762 device_remove_file(&pdev->dev, &dev_attr_crt_src);
1683 1763
1764 sm501_free_init_fb(info, HEAD_CRT);
1765 sm501_free_init_fb(info, HEAD_PANEL);
1766
1684 unregister_framebuffer(fbinfo_crt); 1767 unregister_framebuffer(fbinfo_crt);
1685 unregister_framebuffer(fbinfo_pnl); 1768 unregister_framebuffer(fbinfo_pnl);
1686 1769
1687 sm501fb_stop(info); 1770 sm501fb_stop(info);
1688 sm501fb_info_release(info); 1771 kfree(info);
1689 1772
1690 framebuffer_release(fbinfo_pnl); 1773 framebuffer_release(fbinfo_pnl);
1691 framebuffer_release(fbinfo_crt); 1774 framebuffer_release(fbinfo_crt);
diff --git a/drivers/video/tdfxfb.c b/drivers/video/tdfxfb.c
index ea9f19d25597..77aafcfae037 100644
--- a/drivers/video/tdfxfb.c
+++ b/drivers/video/tdfxfb.c
@@ -836,16 +836,12 @@ static int tdfxfb_pan_display(struct fb_var_screeninfo *var,
836 struct tdfx_par *par = info->par; 836 struct tdfx_par *par = info->par;
837 u32 addr = var->yoffset * info->fix.line_length; 837 u32 addr = var->yoffset * info->fix.line_length;
838 838
839 if (nopan || var->xoffset || (var->yoffset > var->yres_virtual)) 839 if (nopan || var->xoffset)
840 return -EINVAL;
841 if ((var->yoffset + var->yres > var->yres_virtual && nowrap))
842 return -EINVAL; 840 return -EINVAL;
843 841
844 banshee_make_room(par, 1); 842 banshee_make_room(par, 1);
845 tdfx_outl(par, VIDDESKSTART, addr); 843 tdfx_outl(par, VIDDESKSTART, addr);
846 844
847 info->var.xoffset = var->xoffset;
848 info->var.yoffset = var->yoffset;
849 return 0; 845 return 0;
850} 846}
851 847
@@ -1426,6 +1422,8 @@ MODULE_LICENSE("GPL");
1426module_param(hwcursor, int, 0644); 1422module_param(hwcursor, int, 0644);
1427MODULE_PARM_DESC(hwcursor, "Enable hardware cursor " 1423MODULE_PARM_DESC(hwcursor, "Enable hardware cursor "
1428 "(1=enable, 0=disable, default=1)"); 1424 "(1=enable, 0=disable, default=1)");
1425module_param(mode_option, charp, 0);
1426MODULE_PARM_DESC(mode_option, "Initial video mode e.g. '648x480-8@60'");
1429#ifdef CONFIG_MTRR 1427#ifdef CONFIG_MTRR
1430module_param(nomtrr, bool, 0); 1428module_param(nomtrr, bool, 0);
1431MODULE_PARM_DESC(nomtrr, "Disable MTRR support (default: enabled)"); 1429MODULE_PARM_DESC(nomtrr, "Disable MTRR support (default: enabled)");
diff --git a/drivers/video/tridentfb.c b/drivers/video/tridentfb.c
index beefab2992c0..479b2e79ad68 100644
--- a/drivers/video/tridentfb.c
+++ b/drivers/video/tridentfb.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Frame buffer driver for Trident Blade and Image series 2 * Frame buffer driver for Trident TGUI, Blade and Image series
3 * 3 *
4 * Copyright 2001, 2002 - Jani Monoses <jani@iv.ro> 4 * Copyright 2001, 2002 - Jani Monoses <jani@iv.ro>
5 * 5 *
@@ -13,7 +13,6 @@
13 * code, suggestions 13 * code, suggestions
14 * TODO: 14 * TODO:
15 * timing value tweaking so it looks good on every monitor in every mode 15 * timing value tweaking so it looks good on every monitor in every mode
16 * TGUI acceleration
17 */ 16 */
18 17
19#include <linux/module.h> 18#include <linux/module.h>
@@ -22,25 +21,26 @@
22#include <linux/pci.h> 21#include <linux/pci.h>
23 22
24#include <linux/delay.h> 23#include <linux/delay.h>
24#include <video/vga.h>
25#include <video/trident.h> 25#include <video/trident.h>
26 26
27#define VERSION "0.7.8-NEWAPI"
28
29struct tridentfb_par { 27struct tridentfb_par {
30 void __iomem *io_virt; /* iospace virtual memory address */ 28 void __iomem *io_virt; /* iospace virtual memory address */
29 u32 pseudo_pal[16];
30 int chip_id;
31 int flatpanel;
32 void (*init_accel) (struct tridentfb_par *, int, int);
33 void (*wait_engine) (struct tridentfb_par *);
34 void (*fill_rect)
35 (struct tridentfb_par *par, u32, u32, u32, u32, u32, u32);
36 void (*copy_rect)
37 (struct tridentfb_par *par, u32, u32, u32, u32, u32, u32);
38 void (*image_blit)
39 (struct tridentfb_par *par, const char*,
40 u32, u32, u32, u32, u32, u32);
41 unsigned char eng_oper; /* engine operation... */
31}; 42};
32 43
33static unsigned char eng_oper; /* engine operation... */
34static struct fb_ops tridentfb_ops;
35
36static struct tridentfb_par default_par;
37
38/* FIXME:kmalloc these 3 instead */
39static struct fb_info fb_info;
40static u32 pseudo_pal[16];
41
42static struct fb_var_screeninfo default_var;
43
44static struct fb_fix_screeninfo tridentfb_fix = { 44static struct fb_fix_screeninfo tridentfb_fix = {
45 .id = "Trident", 45 .id = "Trident",
46 .type = FB_TYPE_PACKED_PIXELS, 46 .type = FB_TYPE_PACKED_PIXELS,
@@ -49,27 +49,22 @@ static struct fb_fix_screeninfo tridentfb_fix = {
49 .accel = FB_ACCEL_NONE, 49 .accel = FB_ACCEL_NONE,
50}; 50};
51 51
52static int chip_id;
53
54static int defaultaccel;
55static int displaytype;
56
57/* defaults which are normally overriden by user values */ 52/* defaults which are normally overriden by user values */
58 53
59/* video mode */ 54/* video mode */
60static char *mode_option __devinitdata = "640x480"; 55static char *mode_option __devinitdata = "640x480-8@60";
61static int bpp = 8; 56static int bpp __devinitdata = 8;
62 57
63static int noaccel; 58static int noaccel __devinitdata;
64 59
65static int center; 60static int center;
66static int stretch; 61static int stretch;
67 62
68static int fp; 63static int fp __devinitdata;
69static int crt; 64static int crt __devinitdata;
70 65
71static int memsize; 66static int memsize __devinitdata;
72static int memdiff; 67static int memdiff __devinitdata;
73static int nativex; 68static int nativex;
74 69
75module_param(mode_option, charp, 0); 70module_param(mode_option, charp, 0);
@@ -84,25 +79,53 @@ module_param(memsize, int, 0);
84module_param(memdiff, int, 0); 79module_param(memdiff, int, 0);
85module_param(nativex, int, 0); 80module_param(nativex, int, 0);
86module_param(fp, int, 0); 81module_param(fp, int, 0);
82MODULE_PARM_DESC(fp, "Define if flatpanel is connected");
87module_param(crt, int, 0); 83module_param(crt, int, 0);
84MODULE_PARM_DESC(crt, "Define if CRT is connected");
85
86static inline int is_oldclock(int id)
87{
88 return (id == TGUI9440) ||
89 (id == TGUI9660) ||
90 (id == CYBER9320);
91}
92
93static inline int is_oldprotect(int id)
94{
95 return is_oldclock(id) ||
96 (id == PROVIDIA9685) ||
97 (id == CYBER9382) ||
98 (id == CYBER9385);
99}
100
101static inline int is_blade(int id)
102{
103 return (id == BLADE3D) ||
104 (id == CYBERBLADEE4) ||
105 (id == CYBERBLADEi7) ||
106 (id == CYBERBLADEi7D) ||
107 (id == CYBERBLADEi1) ||
108 (id == CYBERBLADEi1D) ||
109 (id == CYBERBLADEAi1) ||
110 (id == CYBERBLADEAi1D);
111}
88 112
89static int chip3D; 113static inline int is_xp(int id)
90static int chipcyber; 114{
115 return (id == CYBERBLADEXPAi1) ||
116 (id == CYBERBLADEXPm8) ||
117 (id == CYBERBLADEXPm16);
118}
91 119
92static int is3Dchip(int id) 120static inline int is3Dchip(int id)
93{ 121{
94 return ((id == BLADE3D) || (id == CYBERBLADEE4) || 122 return is_blade(id) || is_xp(id) ||
95 (id == CYBERBLADEi7) || (id == CYBERBLADEi7D) ||
96 (id == CYBER9397) || (id == CYBER9397DVD) || 123 (id == CYBER9397) || (id == CYBER9397DVD) ||
97 (id == CYBER9520) || (id == CYBER9525DVD) || 124 (id == CYBER9520) || (id == CYBER9525DVD) ||
98 (id == IMAGE975) || (id == IMAGE985) || 125 (id == IMAGE975) || (id == IMAGE985);
99 (id == CYBERBLADEi1) || (id == CYBERBLADEi1D) ||
100 (id == CYBERBLADEAi1) || (id == CYBERBLADEAi1D) ||
101 (id == CYBERBLADEXPm8) || (id == CYBERBLADEXPm16) ||
102 (id == CYBERBLADEXPAi1));
103} 126}
104 127
105static int iscyber(int id) 128static inline int iscyber(int id)
106{ 129{
107 switch (id) { 130 switch (id) {
108 case CYBER9388: 131 case CYBER9388:
@@ -122,12 +145,7 @@ static int iscyber(int id)
122 return 1; 145 return 1;
123 146
124 case CYBER9320: 147 case CYBER9320:
125 case TGUI9660:
126 case IMAGE975:
127 case IMAGE985:
128 case BLADE3D:
129 case CYBERBLADEi7: /* VIA MPV4 integrated version */ 148 case CYBERBLADEi7: /* VIA MPV4 integrated version */
130
131 default: 149 default:
132 /* case CYBERBLDAEXPm8: Strange */ 150 /* case CYBERBLDAEXPm8: Strange */
133 /* case CYBERBLDAEXPm16: Strange */ 151 /* case CYBERBLDAEXPm16: Strange */
@@ -135,147 +153,110 @@ static int iscyber(int id)
135 } 153 }
136} 154}
137 155
138#define CRT 0x3D0 /* CRTC registers offset for color display */ 156static inline void t_outb(struct tridentfb_par *p, u8 val, u16 reg)
139 157{
140#ifndef TRIDENT_MMIO 158 fb_writeb(val, p->io_virt + reg);
141 #define TRIDENT_MMIO 1 159}
142#endif
143
144#if TRIDENT_MMIO
145 #define t_outb(val, reg) writeb(val,((struct tridentfb_par *)(fb_info.par))->io_virt + reg)
146 #define t_inb(reg) readb(((struct tridentfb_par*)(fb_info.par))->io_virt + reg)
147#else
148 #define t_outb(val, reg) outb(val, reg)
149 #define t_inb(reg) inb(reg)
150#endif
151 160
161static inline u8 t_inb(struct tridentfb_par *p, u16 reg)
162{
163 return fb_readb(p->io_virt + reg);
164}
152 165
153static struct accel_switch { 166static inline void writemmr(struct tridentfb_par *par, u16 r, u32 v)
154 void (*init_accel) (int, int); 167{
155 void (*wait_engine) (void); 168 fb_writel(v, par->io_virt + r);
156 void (*fill_rect) (u32, u32, u32, u32, u32, u32); 169}
157 void (*copy_rect) (u32, u32, u32, u32, u32, u32);
158} *acc;
159 170
160#define writemmr(r, v) writel(v, ((struct tridentfb_par *)fb_info.par)->io_virt + r) 171static inline u32 readmmr(struct tridentfb_par *par, u16 r)
161#define readmmr(r) readl(((struct tridentfb_par *)fb_info.par)->io_virt + r) 172{
173 return fb_readl(par->io_virt + r);
174}
162 175
163/* 176/*
164 * Blade specific acceleration. 177 * Blade specific acceleration.
165 */ 178 */
166 179
167#define point(x, y) ((y) << 16 | (x)) 180#define point(x, y) ((y) << 16 | (x))
168#define STA 0x2120 181
169#define CMD 0x2144 182static void blade_init_accel(struct tridentfb_par *par, int pitch, int bpp)
170#define ROP 0x2148
171#define CLR 0x2160
172#define SR1 0x2100
173#define SR2 0x2104
174#define DR1 0x2108
175#define DR2 0x210C
176
177#define ROP_S 0xCC
178
179static void blade_init_accel(int pitch, int bpp)
180{ 183{
181 int v1 = (pitch >> 3) << 20; 184 int v1 = (pitch >> 3) << 20;
182 int tmp = 0, v2; 185 int tmp = bpp == 24 ? 2 : (bpp >> 4);
183 switch (bpp) { 186 int v2 = v1 | (tmp << 29);
184 case 8: 187
185 tmp = 0; 188 writemmr(par, 0x21C0, v2);
186 break; 189 writemmr(par, 0x21C4, v2);
187 case 15: 190 writemmr(par, 0x21B8, v2);
188 tmp = 5; 191 writemmr(par, 0x21BC, v2);
189 break; 192 writemmr(par, 0x21D0, v1);
190 case 16: 193 writemmr(par, 0x21D4, v1);
191 tmp = 1; 194 writemmr(par, 0x21C8, v1);
192 break; 195 writemmr(par, 0x21CC, v1);
193 case 24: 196 writemmr(par, 0x216C, 0);
194 case 32:
195 tmp = 2;
196 break;
197 }
198 v2 = v1 | (tmp << 29);
199 writemmr(0x21C0, v2);
200 writemmr(0x21C4, v2);
201 writemmr(0x21B8, v2);
202 writemmr(0x21BC, v2);
203 writemmr(0x21D0, v1);
204 writemmr(0x21D4, v1);
205 writemmr(0x21C8, v1);
206 writemmr(0x21CC, v1);
207 writemmr(0x216C, 0);
208} 197}
209 198
210static void blade_wait_engine(void) 199static void blade_wait_engine(struct tridentfb_par *par)
211{ 200{
212 while (readmmr(STA) & 0xFA800000) ; 201 while (readmmr(par, STATUS) & 0xFA800000)
202 cpu_relax();
213} 203}
214 204
215static void blade_fill_rect(u32 x, u32 y, u32 w, u32 h, u32 c, u32 rop) 205static void blade_fill_rect(struct tridentfb_par *par,
206 u32 x, u32 y, u32 w, u32 h, u32 c, u32 rop)
216{ 207{
217 writemmr(CLR, c); 208 writemmr(par, COLOR, c);
218 writemmr(ROP, rop ? 0x66 : ROP_S); 209 writemmr(par, ROP, rop ? ROP_X : ROP_S);
219 writemmr(CMD, 0x20000000 | 1 << 19 | 1 << 4 | 2 << 2); 210 writemmr(par, CMD, 0x20000000 | 1 << 19 | 1 << 4 | 2 << 2);
220 211
221 writemmr(DR1, point(x, y)); 212 writemmr(par, DST1, point(x, y));
222 writemmr(DR2, point(x + w - 1, y + h - 1)); 213 writemmr(par, DST2, point(x + w - 1, y + h - 1));
223} 214}
224 215
225static void blade_copy_rect(u32 x1, u32 y1, u32 x2, u32 y2, u32 w, u32 h) 216static void blade_image_blit(struct tridentfb_par *par, const char *data,
217 u32 x, u32 y, u32 w, u32 h, u32 c, u32 b)
218{
219 unsigned size = ((w + 31) >> 5) * h;
220
221 writemmr(par, COLOR, c);
222 writemmr(par, BGCOLOR, b);
223 writemmr(par, CMD, 0xa0000000 | 3 << 19);
224
225 writemmr(par, DST1, point(x, y));
226 writemmr(par, DST2, point(x + w - 1, y + h - 1));
227
228 memcpy(par->io_virt + 0x10000, data, 4 * size);
229}
230
231static void blade_copy_rect(struct tridentfb_par *par,
232 u32 x1, u32 y1, u32 x2, u32 y2, u32 w, u32 h)
226{ 233{
227 u32 s1, s2, d1, d2;
228 int direction = 2; 234 int direction = 2;
229 s1 = point(x1, y1); 235 u32 s1 = point(x1, y1);
230 s2 = point(x1 + w - 1, y1 + h - 1); 236 u32 s2 = point(x1 + w - 1, y1 + h - 1);
231 d1 = point(x2, y2); 237 u32 d1 = point(x2, y2);
232 d2 = point(x2 + w - 1, y2 + h - 1); 238 u32 d2 = point(x2 + w - 1, y2 + h - 1);
233 239
234 if ((y1 > y2) || ((y1 == y2) && (x1 > x2))) 240 if ((y1 > y2) || ((y1 == y2) && (x1 > x2)))
235 direction = 0; 241 direction = 0;
236 242
237 writemmr(ROP, ROP_S); 243 writemmr(par, ROP, ROP_S);
238 writemmr(CMD, 0xE0000000 | 1 << 19 | 1 << 4 | 1 << 2 | direction); 244 writemmr(par, CMD, 0xE0000000 | 1 << 19 | 1 << 4 | 1 << 2 | direction);
239 245
240 writemmr(SR1, direction ? s2 : s1); 246 writemmr(par, SRC1, direction ? s2 : s1);
241 writemmr(SR2, direction ? s1 : s2); 247 writemmr(par, SRC2, direction ? s1 : s2);
242 writemmr(DR1, direction ? d2 : d1); 248 writemmr(par, DST1, direction ? d2 : d1);
243 writemmr(DR2, direction ? d1 : d2); 249 writemmr(par, DST2, direction ? d1 : d2);
244} 250}
245 251
246static struct accel_switch accel_blade = {
247 blade_init_accel,
248 blade_wait_engine,
249 blade_fill_rect,
250 blade_copy_rect,
251};
252
253/* 252/*
254 * BladeXP specific acceleration functions 253 * BladeXP specific acceleration functions
255 */ 254 */
256 255
257#define ROP_P 0xF0 256static void xp_init_accel(struct tridentfb_par *par, int pitch, int bpp)
258#define masked_point(x, y) ((y & 0xffff)<<16|(x & 0xffff))
259
260static void xp_init_accel(int pitch, int bpp)
261{ 257{
262 int tmp = 0, v1; 258 unsigned char x = bpp == 24 ? 3 : (bpp >> 4);
263 unsigned char x = 0; 259 int v1 = pitch << (bpp == 24 ? 20 : (18 + x));
264
265 switch (bpp) {
266 case 8:
267 x = 0;
268 break;
269 case 16:
270 x = 1;
271 break;
272 case 24:
273 x = 3;
274 break;
275 case 32:
276 x = 2;
277 break;
278 }
279 260
280 switch (pitch << (bpp >> 3)) { 261 switch (pitch << (bpp >> 3)) {
281 case 8192: 262 case 8192:
@@ -293,42 +274,21 @@ static void xp_init_accel(int pitch, int bpp)
293 break; 274 break;
294 } 275 }
295 276
296 t_outb(x, 0x2125); 277 t_outb(par, x, 0x2125);
297
298 eng_oper = x | 0x40;
299
300 switch (bpp) {
301 case 8:
302 tmp = 18;
303 break;
304 case 15:
305 case 16:
306 tmp = 19;
307 break;
308 case 24:
309 case 32:
310 tmp = 20;
311 break;
312 }
313 278
314 v1 = pitch << tmp; 279 par->eng_oper = x | 0x40;
315 280
316 writemmr(0x2154, v1); 281 writemmr(par, 0x2154, v1);
317 writemmr(0x2150, v1); 282 writemmr(par, 0x2150, v1);
318 t_outb(3, 0x2126); 283 t_outb(par, 3, 0x2126);
319} 284}
320 285
321static void xp_wait_engine(void) 286static void xp_wait_engine(struct tridentfb_par *par)
322{ 287{
323 int busy; 288 int count = 0;
324 int count, timeout; 289 int timeout = 0;
325 290
326 count = 0; 291 while (t_inb(par, STATUS) & 0x80) {
327 timeout = 0;
328 for (;;) {
329 busy = t_inb(STA) & 0x80;
330 if (busy != 0x80)
331 return;
332 count++; 292 count++;
333 if (count == 10000000) { 293 if (count == 10000000) {
334 /* Timeout */ 294 /* Timeout */
@@ -336,30 +296,31 @@ static void xp_wait_engine(void)
336 timeout++; 296 timeout++;
337 if (timeout == 8) { 297 if (timeout == 8) {
338 /* Reset engine */ 298 /* Reset engine */
339 t_outb(0x00, 0x2120); 299 t_outb(par, 0x00, STATUS);
340 return; 300 return;
341 } 301 }
342 } 302 }
303 cpu_relax();
343 } 304 }
344} 305}
345 306
346static void xp_fill_rect(u32 x, u32 y, u32 w, u32 h, u32 c, u32 rop) 307static void xp_fill_rect(struct tridentfb_par *par,
308 u32 x, u32 y, u32 w, u32 h, u32 c, u32 rop)
347{ 309{
348 writemmr(0x2127, ROP_P); 310 writemmr(par, 0x2127, ROP_P);
349 writemmr(0x2158, c); 311 writemmr(par, 0x2158, c);
350 writemmr(0x2128, 0x4000); 312 writemmr(par, DRAWFL, 0x4000);
351 writemmr(0x2140, masked_point(h, w)); 313 writemmr(par, OLDDIM, point(h, w));
352 writemmr(0x2138, masked_point(y, x)); 314 writemmr(par, OLDDST, point(y, x));
353 t_outb(0x01, 0x2124); 315 t_outb(par, 0x01, OLDCMD);
354 t_outb(eng_oper, 0x2125); 316 t_outb(par, par->eng_oper, 0x2125);
355} 317}
356 318
357static void xp_copy_rect(u32 x1, u32 y1, u32 x2, u32 y2, u32 w, u32 h) 319static void xp_copy_rect(struct tridentfb_par *par,
320 u32 x1, u32 y1, u32 x2, u32 y2, u32 w, u32 h)
358{ 321{
359 int direction;
360 u32 x1_tmp, x2_tmp, y1_tmp, y2_tmp; 322 u32 x1_tmp, x2_tmp, y1_tmp, y2_tmp;
361 323 int direction = 0x0004;
362 direction = 0x0004;
363 324
364 if ((x1 < x2) && (y1 == y2)) { 325 if ((x1 < x2) && (y1 == y2)) {
365 direction |= 0x0200; 326 direction |= 0x0200;
@@ -379,103 +340,152 @@ static void xp_copy_rect(u32 x1, u32 y1, u32 x2, u32 y2, u32 w, u32 h)
379 y2_tmp = y2; 340 y2_tmp = y2;
380 } 341 }
381 342
382 writemmr(0x2128, direction); 343 writemmr(par, DRAWFL, direction);
383 t_outb(ROP_S, 0x2127); 344 t_outb(par, ROP_S, 0x2127);
384 writemmr(0x213C, masked_point(y1_tmp, x1_tmp)); 345 writemmr(par, OLDSRC, point(y1_tmp, x1_tmp));
385 writemmr(0x2138, masked_point(y2_tmp, x2_tmp)); 346 writemmr(par, OLDDST, point(y2_tmp, x2_tmp));
386 writemmr(0x2140, masked_point(h, w)); 347 writemmr(par, OLDDIM, point(h, w));
387 t_outb(0x01, 0x2124); 348 t_outb(par, 0x01, OLDCMD);
388} 349}
389 350
390static struct accel_switch accel_xp = {
391 xp_init_accel,
392 xp_wait_engine,
393 xp_fill_rect,
394 xp_copy_rect,
395};
396
397/* 351/*
398 * Image specific acceleration functions 352 * Image specific acceleration functions
399 */ 353 */
400static void image_init_accel(int pitch, int bpp) 354static void image_init_accel(struct tridentfb_par *par, int pitch, int bpp)
401{ 355{
402 int tmp = 0; 356 int tmp = bpp == 24 ? 2: (bpp >> 4);
403 switch (bpp) { 357
404 case 8: 358 writemmr(par, 0x2120, 0xF0000000);
405 tmp = 0; 359 writemmr(par, 0x2120, 0x40000000 | tmp);
406 break; 360 writemmr(par, 0x2120, 0x80000000);
407 case 15: 361 writemmr(par, 0x2144, 0x00000000);
408 tmp = 5; 362 writemmr(par, 0x2148, 0x00000000);
409 break; 363 writemmr(par, 0x2150, 0x00000000);
410 case 16: 364 writemmr(par, 0x2154, 0x00000000);
411 tmp = 1; 365 writemmr(par, 0x2120, 0x60000000 | (pitch << 16) | pitch);
412 break; 366 writemmr(par, 0x216C, 0x00000000);
413 case 24: 367 writemmr(par, 0x2170, 0x00000000);
414 case 32: 368 writemmr(par, 0x217C, 0x00000000);
415 tmp = 2; 369 writemmr(par, 0x2120, 0x10000000);
416 break; 370 writemmr(par, 0x2130, (2047 << 16) | 2047);
417 }
418 writemmr(0x2120, 0xF0000000);
419 writemmr(0x2120, 0x40000000 | tmp);
420 writemmr(0x2120, 0x80000000);
421 writemmr(0x2144, 0x00000000);
422 writemmr(0x2148, 0x00000000);
423 writemmr(0x2150, 0x00000000);
424 writemmr(0x2154, 0x00000000);
425 writemmr(0x2120, 0x60000000 | (pitch << 16) | pitch);
426 writemmr(0x216C, 0x00000000);
427 writemmr(0x2170, 0x00000000);
428 writemmr(0x217C, 0x00000000);
429 writemmr(0x2120, 0x10000000);
430 writemmr(0x2130, (2047 << 16) | 2047);
431} 371}
432 372
433static void image_wait_engine(void) 373static void image_wait_engine(struct tridentfb_par *par)
434{ 374{
435 while (readmmr(0x2164) & 0xF0000000) ; 375 while (readmmr(par, 0x2164) & 0xF0000000)
376 cpu_relax();
436} 377}
437 378
438static void image_fill_rect(u32 x, u32 y, u32 w, u32 h, u32 c, u32 rop) 379static void image_fill_rect(struct tridentfb_par *par,
380 u32 x, u32 y, u32 w, u32 h, u32 c, u32 rop)
439{ 381{
440 writemmr(0x2120, 0x80000000); 382 writemmr(par, 0x2120, 0x80000000);
441 writemmr(0x2120, 0x90000000 | ROP_S); 383 writemmr(par, 0x2120, 0x90000000 | ROP_S);
442 384
443 writemmr(0x2144, c); 385 writemmr(par, 0x2144, c);
444 386
445 writemmr(DR1, point(x, y)); 387 writemmr(par, DST1, point(x, y));
446 writemmr(DR2, point(x + w - 1, y + h - 1)); 388 writemmr(par, DST2, point(x + w - 1, y + h - 1));
447 389
448 writemmr(0x2124, 0x80000000 | 3 << 22 | 1 << 10 | 1 << 9); 390 writemmr(par, 0x2124, 0x80000000 | 3 << 22 | 1 << 10 | 1 << 9);
449} 391}
450 392
451static void image_copy_rect(u32 x1, u32 y1, u32 x2, u32 y2, u32 w, u32 h) 393static void image_copy_rect(struct tridentfb_par *par,
394 u32 x1, u32 y1, u32 x2, u32 y2, u32 w, u32 h)
452{ 395{
453 u32 s1, s2, d1, d2; 396 int direction = 0x4;
454 int direction = 2; 397 u32 s1 = point(x1, y1);
455 s1 = point(x1, y1); 398 u32 s2 = point(x1 + w - 1, y1 + h - 1);
456 s2 = point(x1 + w - 1, y1 + h - 1); 399 u32 d1 = point(x2, y2);
457 d1 = point(x2, y2); 400 u32 d2 = point(x2 + w - 1, y2 + h - 1);
458 d2 = point(x2 + w - 1, y2 + h - 1);
459 401
460 if ((y1 > y2) || ((y1 == y2) && (x1 > x2))) 402 if ((y1 > y2) || ((y1 == y2) && (x1 > x2)))
461 direction = 0; 403 direction = 0;
462 404
463 writemmr(0x2120, 0x80000000); 405 writemmr(par, 0x2120, 0x80000000);
464 writemmr(0x2120, 0x90000000 | ROP_S); 406 writemmr(par, 0x2120, 0x90000000 | ROP_S);
465 407
466 writemmr(SR1, direction ? s2 : s1); 408 writemmr(par, SRC1, direction ? s2 : s1);
467 writemmr(SR2, direction ? s1 : s2); 409 writemmr(par, SRC2, direction ? s1 : s2);
468 writemmr(DR1, direction ? d2 : d1); 410 writemmr(par, DST1, direction ? d2 : d1);
469 writemmr(DR2, direction ? d1 : d2); 411 writemmr(par, DST2, direction ? d1 : d2);
470 writemmr(0x2124, 0x80000000 | 1 << 22 | 1 << 10 | 1 << 7 | direction); 412 writemmr(par, 0x2124,
413 0x80000000 | 1 << 22 | 1 << 10 | 1 << 7 | direction);
471} 414}
472 415
473static struct accel_switch accel_image = { 416/*
474 image_init_accel, 417 * TGUI 9440/96XX acceleration
475 image_wait_engine, 418 */
476 image_fill_rect, 419
477 image_copy_rect, 420static void tgui_init_accel(struct tridentfb_par *par, int pitch, int bpp)
478}; 421{
422 unsigned char x = bpp == 24 ? 3 : (bpp >> 4);
423
424 /* disable clipping */
425 writemmr(par, 0x2148, 0);
426 writemmr(par, 0x214C, point(4095, 2047));
427
428 switch ((pitch * bpp) / 8) {
429 case 8192:
430 case 512:
431 x |= 0x00;
432 break;
433 case 1024:
434 x |= 0x04;
435 break;
436 case 2048:
437 x |= 0x08;
438 break;
439 case 4096:
440 x |= 0x0C;
441 break;
442 }
443
444 fb_writew(x, par->io_virt + 0x2122);
445}
446
447static void tgui_fill_rect(struct tridentfb_par *par,
448 u32 x, u32 y, u32 w, u32 h, u32 c, u32 rop)
449{
450 t_outb(par, ROP_P, 0x2127);
451 writemmr(par, OLDCLR, c);
452 writemmr(par, DRAWFL, 0x4020);
453 writemmr(par, OLDDIM, point(w - 1, h - 1));
454 writemmr(par, OLDDST, point(x, y));
455 t_outb(par, 1, OLDCMD);
456}
457
458static void tgui_copy_rect(struct tridentfb_par *par,
459 u32 x1, u32 y1, u32 x2, u32 y2, u32 w, u32 h)
460{
461 int flags = 0;
462 u16 x1_tmp, x2_tmp, y1_tmp, y2_tmp;
463
464 if ((x1 < x2) && (y1 == y2)) {
465 flags |= 0x0200;
466 x1_tmp = x1 + w - 1;
467 x2_tmp = x2 + w - 1;
468 } else {
469 x1_tmp = x1;
470 x2_tmp = x2;
471 }
472
473 if (y1 < y2) {
474 flags |= 0x0100;
475 y1_tmp = y1 + h - 1;
476 y2_tmp = y2 + h - 1;
477 } else {
478 y1_tmp = y1;
479 y2_tmp = y2;
480 }
481
482 writemmr(par, DRAWFL, 0x4 | flags);
483 t_outb(par, ROP_S, 0x2127);
484 writemmr(par, OLDSRC, point(x1_tmp, y1_tmp));
485 writemmr(par, OLDDST, point(x2_tmp, y2_tmp));
486 writemmr(par, OLDDIM, point(w - 1, h - 1));
487 t_outb(par, 1, OLDCMD);
488}
479 489
480/* 490/*
481 * Accel functions called by the upper layers 491 * Accel functions called by the upper layers
@@ -484,129 +494,162 @@ static struct accel_switch accel_image = {
484static void tridentfb_fillrect(struct fb_info *info, 494static void tridentfb_fillrect(struct fb_info *info,
485 const struct fb_fillrect *fr) 495 const struct fb_fillrect *fr)
486{ 496{
487 int bpp = info->var.bits_per_pixel; 497 struct tridentfb_par *par = info->par;
488 int col = 0; 498 int col;
489 499
490 switch (bpp) { 500 if (info->flags & FBINFO_HWACCEL_DISABLED) {
491 default: 501 cfb_fillrect(info, fr);
492 case 8: 502 return;
493 col |= fr->color; 503 }
504 if (info->var.bits_per_pixel == 8) {
505 col = fr->color;
494 col |= col << 8; 506 col |= col << 8;
495 col |= col << 16; 507 col |= col << 16;
496 break; 508 } else
497 case 16:
498 col = ((u32 *)(info->pseudo_palette))[fr->color]; 509 col = ((u32 *)(info->pseudo_palette))[fr->color];
499 break; 510
500 case 32: 511 par->wait_engine(par);
501 col = ((u32 *)(info->pseudo_palette))[fr->color]; 512 par->fill_rect(par, fr->dx, fr->dy, fr->width,
502 break; 513 fr->height, col, fr->rop);
514}
515
516static void tridentfb_imageblit(struct fb_info *info,
517 const struct fb_image *img)
518{
519 struct tridentfb_par *par = info->par;
520 int col, bgcol;
521
522 if ((info->flags & FBINFO_HWACCEL_DISABLED) || img->depth != 1) {
523 cfb_imageblit(info, img);
524 return;
525 }
526 if (info->var.bits_per_pixel == 8) {
527 col = img->fg_color;
528 col |= col << 8;
529 col |= col << 16;
530 bgcol = img->bg_color;
531 bgcol |= bgcol << 8;
532 bgcol |= bgcol << 16;
533 } else {
534 col = ((u32 *)(info->pseudo_palette))[img->fg_color];
535 bgcol = ((u32 *)(info->pseudo_palette))[img->bg_color];
503 } 536 }
504 537
505 acc->fill_rect(fr->dx, fr->dy, fr->width, fr->height, col, fr->rop); 538 par->wait_engine(par);
506 acc->wait_engine(); 539 if (par->image_blit)
540 par->image_blit(par, img->data, img->dx, img->dy,
541 img->width, img->height, col, bgcol);
542 else
543 cfb_imageblit(info, img);
507} 544}
545
508static void tridentfb_copyarea(struct fb_info *info, 546static void tridentfb_copyarea(struct fb_info *info,
509 const struct fb_copyarea *ca) 547 const struct fb_copyarea *ca)
510{ 548{
511 acc->copy_rect(ca->sx, ca->sy, ca->dx, ca->dy, ca->width, ca->height); 549 struct tridentfb_par *par = info->par;
512 acc->wait_engine(); 550
551 if (info->flags & FBINFO_HWACCEL_DISABLED) {
552 cfb_copyarea(info, ca);
553 return;
554 }
555 par->wait_engine(par);
556 par->copy_rect(par, ca->sx, ca->sy, ca->dx, ca->dy,
557 ca->width, ca->height);
558}
559
560static int tridentfb_sync(struct fb_info *info)
561{
562 struct tridentfb_par *par = info->par;
563
564 if (!(info->flags & FBINFO_HWACCEL_DISABLED))
565 par->wait_engine(par);
566 return 0;
513} 567}
514#else /* !CONFIG_FB_TRIDENT_ACCEL */ 568#else
515#define tridentfb_fillrect cfb_fillrect 569#define tridentfb_fillrect cfb_fillrect
516#define tridentfb_copyarea cfb_copyarea 570#define tridentfb_copyarea cfb_copyarea
571#define tridentfb_imageblit cfb_imageblit
517#endif /* CONFIG_FB_TRIDENT_ACCEL */ 572#endif /* CONFIG_FB_TRIDENT_ACCEL */
518 573
519
520/* 574/*
521 * Hardware access functions 575 * Hardware access functions
522 */ 576 */
523 577
524static inline unsigned char read3X4(int reg) 578static inline unsigned char read3X4(struct tridentfb_par *par, int reg)
525{ 579{
526 struct tridentfb_par *par = (struct tridentfb_par *)fb_info.par; 580 return vga_mm_rcrt(par->io_virt, reg);
527 writeb(reg, par->io_virt + CRT + 4);
528 return readb(par->io_virt + CRT + 5);
529} 581}
530 582
531static inline void write3X4(int reg, unsigned char val) 583static inline void write3X4(struct tridentfb_par *par, int reg,
584 unsigned char val)
532{ 585{
533 struct tridentfb_par *par = (struct tridentfb_par *)fb_info.par; 586 vga_mm_wcrt(par->io_virt, reg, val);
534 writeb(reg, par->io_virt + CRT + 4);
535 writeb(val, par->io_virt + CRT + 5);
536} 587}
537 588
538static inline unsigned char read3C4(int reg) 589static inline unsigned char read3CE(struct tridentfb_par *par,
590 unsigned char reg)
539{ 591{
540 t_outb(reg, 0x3C4); 592 return vga_mm_rgfx(par->io_virt, reg);
541 return t_inb(0x3C5);
542} 593}
543 594
544static inline void write3C4(int reg, unsigned char val) 595static inline void writeAttr(struct tridentfb_par *par, int reg,
596 unsigned char val)
545{ 597{
546 t_outb(reg, 0x3C4); 598 fb_readb(par->io_virt + VGA_IS1_RC); /* flip-flop to index */
547 t_outb(val, 0x3C5); 599 vga_mm_wattr(par->io_virt, reg, val);
548} 600}
549 601
550static inline unsigned char read3CE(int reg) 602static inline void write3CE(struct tridentfb_par *par, int reg,
603 unsigned char val)
551{ 604{
552 t_outb(reg, 0x3CE); 605 vga_mm_wgfx(par->io_virt, reg, val);
553 return t_inb(0x3CF);
554} 606}
555 607
556static inline void writeAttr(int reg, unsigned char val) 608static void enable_mmio(struct tridentfb_par *par)
557{
558 readb(((struct tridentfb_par *)fb_info.par)->io_virt + CRT + 0x0A); /* flip-flop to index */
559 t_outb(reg, 0x3C0);
560 t_outb(val, 0x3C0);
561}
562
563static inline void write3CE(int reg, unsigned char val)
564{
565 t_outb(reg, 0x3CE);
566 t_outb(val, 0x3CF);
567}
568
569static void enable_mmio(void)
570{ 609{
571 /* Goto New Mode */ 610 /* Goto New Mode */
572 outb(0x0B, 0x3C4); 611 vga_io_rseq(0x0B);
573 inb(0x3C5);
574 612
575 /* Unprotect registers */ 613 /* Unprotect registers */
576 outb(NewMode1, 0x3C4); 614 vga_io_wseq(NewMode1, 0x80);
577 outb(0x80, 0x3C5); 615 if (!is_oldprotect(par->chip_id))
616 vga_io_wseq(Protection, 0x92);
578 617
579 /* Enable MMIO */ 618 /* Enable MMIO */
580 outb(PCIReg, 0x3D4); 619 outb(PCIReg, 0x3D4);
581 outb(inb(0x3D5) | 0x01, 0x3D5); 620 outb(inb(0x3D5) | 0x01, 0x3D5);
582} 621}
583 622
584static void disable_mmio(void) 623static void disable_mmio(struct tridentfb_par *par)
585{ 624{
586 /* Goto New Mode */ 625 /* Goto New Mode */
587 t_outb(0x0B, 0x3C4); 626 vga_mm_rseq(par->io_virt, 0x0B);
588 t_inb(0x3C5);
589 627
590 /* Unprotect registers */ 628 /* Unprotect registers */
591 t_outb(NewMode1, 0x3C4); 629 vga_mm_wseq(par->io_virt, NewMode1, 0x80);
592 t_outb(0x80, 0x3C5); 630 if (!is_oldprotect(par->chip_id))
631 vga_mm_wseq(par->io_virt, Protection, 0x92);
593 632
594 /* Disable MMIO */ 633 /* Disable MMIO */
595 t_outb(PCIReg, 0x3D4); 634 t_outb(par, PCIReg, 0x3D4);
596 t_outb(t_inb(0x3D5) & ~0x01, 0x3D5); 635 t_outb(par, t_inb(par, 0x3D5) & ~0x01, 0x3D5);
597} 636}
598 637
599#define crtc_unlock() write3X4(CRTVSyncEnd, read3X4(CRTVSyncEnd) & 0x7F) 638static inline void crtc_unlock(struct tridentfb_par *par)
639{
640 write3X4(par, VGA_CRTC_V_SYNC_END,
641 read3X4(par, VGA_CRTC_V_SYNC_END) & 0x7F);
642}
600 643
601/* Return flat panel's maximum x resolution */ 644/* Return flat panel's maximum x resolution */
602static int __devinit get_nativex(void) 645static int __devinit get_nativex(struct tridentfb_par *par)
603{ 646{
604 int x, y, tmp; 647 int x, y, tmp;
605 648
606 if (nativex) 649 if (nativex)
607 return nativex; 650 return nativex;
608 651
609 tmp = (read3CE(VertStretch) >> 4) & 3; 652 tmp = (read3CE(par, VertStretch) >> 4) & 3;
610 653
611 switch (tmp) { 654 switch (tmp) {
612 case 0: 655 case 0:
@@ -632,77 +675,92 @@ static int __devinit get_nativex(void)
632} 675}
633 676
634/* Set pitch */ 677/* Set pitch */
635static void set_lwidth(int width) 678static inline void set_lwidth(struct tridentfb_par *par, int width)
636{ 679{
637 write3X4(Offset, width & 0xFF); 680 write3X4(par, VGA_CRTC_OFFSET, width & 0xFF);
638 write3X4(AddColReg, 681 write3X4(par, AddColReg,
639 (read3X4(AddColReg) & 0xCF) | ((width & 0x300) >> 4)); 682 (read3X4(par, AddColReg) & 0xCF) | ((width & 0x300) >> 4));
640} 683}
641 684
642/* For resolutions smaller than FP resolution stretch */ 685/* For resolutions smaller than FP resolution stretch */
643static void screen_stretch(void) 686static void screen_stretch(struct tridentfb_par *par)
644{ 687{
645 if (chip_id != CYBERBLADEXPAi1) 688 if (par->chip_id != CYBERBLADEXPAi1)
646 write3CE(BiosReg, 0); 689 write3CE(par, BiosReg, 0);
647 else 690 else
648 write3CE(BiosReg, 8); 691 write3CE(par, BiosReg, 8);
649 write3CE(VertStretch, (read3CE(VertStretch) & 0x7C) | 1); 692 write3CE(par, VertStretch, (read3CE(par, VertStretch) & 0x7C) | 1);
650 write3CE(HorStretch, (read3CE(HorStretch) & 0x7C) | 1); 693 write3CE(par, HorStretch, (read3CE(par, HorStretch) & 0x7C) | 1);
651} 694}
652 695
653/* For resolutions smaller than FP resolution center */ 696/* For resolutions smaller than FP resolution center */
654static void screen_center(void) 697static inline void screen_center(struct tridentfb_par *par)
655{ 698{
656 write3CE(VertStretch, (read3CE(VertStretch) & 0x7C) | 0x80); 699 write3CE(par, VertStretch, (read3CE(par, VertStretch) & 0x7C) | 0x80);
657 write3CE(HorStretch, (read3CE(HorStretch) & 0x7C) | 0x80); 700 write3CE(par, HorStretch, (read3CE(par, HorStretch) & 0x7C) | 0x80);
658} 701}
659 702
660/* Address of first shown pixel in display memory */ 703/* Address of first shown pixel in display memory */
661static void set_screen_start(int base) 704static void set_screen_start(struct tridentfb_par *par, int base)
662{ 705{
663 write3X4(StartAddrLow, base & 0xFF); 706 u8 tmp;
664 write3X4(StartAddrHigh, (base & 0xFF00) >> 8); 707 write3X4(par, VGA_CRTC_START_LO, base & 0xFF);
665 write3X4(CRTCModuleTest, 708 write3X4(par, VGA_CRTC_START_HI, (base & 0xFF00) >> 8);
666 (read3X4(CRTCModuleTest) & 0xDF) | ((base & 0x10000) >> 11)); 709 tmp = read3X4(par, CRTCModuleTest) & 0xDF;
667 write3X4(CRTHiOrd, 710 write3X4(par, CRTCModuleTest, tmp | ((base & 0x10000) >> 11));
668 (read3X4(CRTHiOrd) & 0xF8) | ((base & 0xE0000) >> 17)); 711 tmp = read3X4(par, CRTHiOrd) & 0xF8;
712 write3X4(par, CRTHiOrd, tmp | ((base & 0xE0000) >> 17));
669} 713}
670 714
671/* Set dotclock frequency */ 715/* Set dotclock frequency */
672static void set_vclk(unsigned long freq) 716static void set_vclk(struct tridentfb_par *par, unsigned long freq)
673{ 717{
674 int m, n, k; 718 int m, n, k;
675 unsigned long f, fi, d, di; 719 unsigned long fi, d, di;
676 unsigned char lo = 0, hi = 0; 720 unsigned char best_m = 0, best_n = 0, best_k = 0;
721 unsigned char hi, lo;
722 unsigned char shift = !is_oldclock(par->chip_id) ? 2 : 1;
677 723
678 d = 20000; 724 d = 20000;
679 for (k = 2; k >= 0; k--) 725 for (k = shift; k >= 0; k--)
680 for (m = 0; m < 63; m++) 726 for (m = 1; m < 32; m++) {
681 for (n = 0; n < 128; n++) { 727 n = ((m + 2) << shift) - 8;
728 for (n = (n < 0 ? 0 : n); n < 122; n++) {
682 fi = ((14318l * (n + 8)) / (m + 2)) >> k; 729 fi = ((14318l * (n + 8)) / (m + 2)) >> k;
683 if ((di = abs(fi - freq)) < d) { 730 di = abs(fi - freq);
731 if (di < d || (di == d && k == best_k)) {
684 d = di; 732 d = di;
685 f = fi; 733 best_n = n;
686 lo = n; 734 best_m = m;
687 hi = (k << 6) | m; 735 best_k = k;
688 } 736 }
689 if (fi > freq) 737 if (fi > freq)
690 break; 738 break;
691 } 739 }
692 if (chip3D) { 740 }
693 write3C4(ClockHigh, hi); 741
694 write3C4(ClockLow, lo); 742 if (is_oldclock(par->chip_id)) {
743 lo = best_n | (best_m << 7);
744 hi = (best_m >> 1) | (best_k << 4);
695 } else { 745 } else {
696 outb(lo, 0x43C8); 746 lo = best_n;
697 outb(hi, 0x43C9); 747 hi = best_m | (best_k << 6);
748 }
749
750 if (is3Dchip(par->chip_id)) {
751 vga_mm_wseq(par->io_virt, ClockHigh, hi);
752 vga_mm_wseq(par->io_virt, ClockLow, lo);
753 } else {
754 t_outb(par, lo, 0x43C8);
755 t_outb(par, hi, 0x43C9);
698 } 756 }
699 debug("VCLK = %X %X\n", hi, lo); 757 debug("VCLK = %X %X\n", hi, lo);
700} 758}
701 759
702/* Set number of lines for flat panels*/ 760/* Set number of lines for flat panels*/
703static void set_number_of_lines(int lines) 761static void set_number_of_lines(struct tridentfb_par *par, int lines)
704{ 762{
705 int tmp = read3CE(CyberEnhance) & 0x8F; 763 int tmp = read3CE(par, CyberEnhance) & 0x8F;
706 if (lines > 1024) 764 if (lines > 1024)
707 tmp |= 0x50; 765 tmp |= 0x50;
708 else if (lines > 768) 766 else if (lines > 768)
@@ -711,24 +769,24 @@ static void set_number_of_lines(int lines)
711 tmp |= 0x20; 769 tmp |= 0x20;
712 else if (lines > 480) 770 else if (lines > 480)
713 tmp |= 0x10; 771 tmp |= 0x10;
714 write3CE(CyberEnhance, tmp); 772 write3CE(par, CyberEnhance, tmp);
715} 773}
716 774
717/* 775/*
718 * If we see that FP is active we assume we have one. 776 * If we see that FP is active we assume we have one.
719 * Otherwise we have a CRT display.User can override. 777 * Otherwise we have a CRT display. User can override.
720 */ 778 */
721static unsigned int __devinit get_displaytype(void) 779static int __devinit is_flatpanel(struct tridentfb_par *par)
722{ 780{
723 if (fp) 781 if (fp)
724 return DISPLAY_FP; 782 return 1;
725 if (crt || !chipcyber) 783 if (crt || !iscyber(par->chip_id))
726 return DISPLAY_CRT; 784 return 0;
727 return (read3CE(FPConfig) & 0x10) ? DISPLAY_FP : DISPLAY_CRT; 785 return (read3CE(par, FPConfig) & 0x10) ? 1 : 0;
728} 786}
729 787
730/* Try detecting the video memory size */ 788/* Try detecting the video memory size */
731static unsigned int __devinit get_memsize(void) 789static unsigned int __devinit get_memsize(struct tridentfb_par *par)
732{ 790{
733 unsigned char tmp, tmp2; 791 unsigned char tmp, tmp2;
734 unsigned int k; 792 unsigned int k;
@@ -737,12 +795,12 @@ static unsigned int __devinit get_memsize(void)
737 if (memsize) 795 if (memsize)
738 k = memsize * Kb; 796 k = memsize * Kb;
739 else 797 else
740 switch (chip_id) { 798 switch (par->chip_id) {
741 case CYBER9525DVD: 799 case CYBER9525DVD:
742 k = 2560 * Kb; 800 k = 2560 * Kb;
743 break; 801 break;
744 default: 802 default:
745 tmp = read3X4(SPR) & 0x0F; 803 tmp = read3X4(par, SPR) & 0x0F;
746 switch (tmp) { 804 switch (tmp) {
747 805
748 case 0x01: 806 case 0x01:
@@ -774,7 +832,7 @@ static unsigned int __devinit get_memsize(void)
774 break; 832 break;
775 case 0x0E: /* XP */ 833 case 0x0E: /* XP */
776 834
777 tmp2 = read3C4(0xC1); 835 tmp2 = vga_mm_rseq(par->io_virt, 0xC1);
778 switch (tmp2) { 836 switch (tmp2) {
779 case 0x00: 837 case 0x00:
780 k = 20 * Mb; 838 k = 20 * Mb;
@@ -812,26 +870,67 @@ static unsigned int __devinit get_memsize(void)
812static int tridentfb_check_var(struct fb_var_screeninfo *var, 870static int tridentfb_check_var(struct fb_var_screeninfo *var,
813 struct fb_info *info) 871 struct fb_info *info)
814{ 872{
873 struct tridentfb_par *par = info->par;
815 int bpp = var->bits_per_pixel; 874 int bpp = var->bits_per_pixel;
875 int line_length;
876 int ramdac = 230000; /* 230MHz for most 3D chips */
816 debug("enter\n"); 877 debug("enter\n");
817 878
818 /* check color depth */ 879 /* check color depth */
819 if (bpp == 24) 880 if (bpp == 24)
820 bpp = var->bits_per_pixel = 32; 881 bpp = var->bits_per_pixel = 32;
882 if (bpp != 8 && bpp != 16 && bpp != 32)
883 return -EINVAL;
884 if (par->chip_id == TGUI9440 && bpp == 32)
885 return -EINVAL;
821 /* check whether resolution fits on panel and in memory */ 886 /* check whether resolution fits on panel and in memory */
822 if (flatpanel && nativex && var->xres > nativex) 887 if (par->flatpanel && nativex && var->xres > nativex)
888 return -EINVAL;
889 /* various resolution checks */
890 var->xres = (var->xres + 7) & ~0x7;
891 if (var->xres > var->xres_virtual)
892 var->xres_virtual = var->xres;
893 if (var->yres > var->yres_virtual)
894 var->yres_virtual = var->yres;
895 if (var->xres_virtual > 4095 || var->yres > 2048)
823 return -EINVAL; 896 return -EINVAL;
824 if (var->xres * var->yres_virtual * bpp / 8 > info->fix.smem_len) 897 /* prevent from position overflow for acceleration */
898 if (var->yres_virtual > 0xffff)
899 return -EINVAL;
900 line_length = var->xres_virtual * bpp / 8;
901
902 if (!is3Dchip(par->chip_id) &&
903 !(info->flags & FBINFO_HWACCEL_DISABLED)) {
904 /* acceleration requires line length to be power of 2 */
905 if (line_length <= 512)
906 var->xres_virtual = 512 * 8 / bpp;
907 else if (line_length <= 1024)
908 var->xres_virtual = 1024 * 8 / bpp;
909 else if (line_length <= 2048)
910 var->xres_virtual = 2048 * 8 / bpp;
911 else if (line_length <= 4096)
912 var->xres_virtual = 4096 * 8 / bpp;
913 else if (line_length <= 8192)
914 var->xres_virtual = 8192 * 8 / bpp;
915 else
916 return -EINVAL;
917
918 line_length = var->xres_virtual * bpp / 8;
919 }
920
921 /* datasheet specifies how to set panning only up to 4 MB */
922 if (line_length * (var->yres_virtual - var->yres) > (4 << 20))
923 var->yres_virtual = ((4 << 20) / line_length) + var->yres;
924
925 if (line_length * var->yres_virtual > info->fix.smem_len)
825 return -EINVAL; 926 return -EINVAL;
826 927
827 switch (bpp) { 928 switch (bpp) {
828 case 8: 929 case 8:
829 var->red.offset = 0; 930 var->red.offset = 0;
830 var->green.offset = 0; 931 var->red.length = 8;
831 var->blue.offset = 0; 932 var->green = var->red;
832 var->red.length = 6; 933 var->blue = var->red;
833 var->green.length = 6;
834 var->blue.length = 6;
835 break; 934 break;
836 case 16: 935 case 16:
837 var->red.offset = 11; 936 var->red.offset = 11;
@@ -852,6 +951,33 @@ static int tridentfb_check_var(struct fb_var_screeninfo *var,
852 default: 951 default:
853 return -EINVAL; 952 return -EINVAL;
854 } 953 }
954
955 if (is_xp(par->chip_id))
956 ramdac = 350000;
957
958 switch (par->chip_id) {
959 case TGUI9440:
960 ramdac = (bpp >= 16) ? 45000 : 90000;
961 break;
962 case CYBER9320:
963 case TGUI9660:
964 ramdac = 135000;
965 break;
966 case PROVIDIA9685:
967 case CYBER9388:
968 case CYBER9382:
969 case CYBER9385:
970 ramdac = 170000;
971 break;
972 }
973
974 /* The clock is doubled for 32 bpp */
975 if (bpp == 32)
976 ramdac /= 2;
977
978 if (PICOS2KHZ(var->pixclock) > ramdac)
979 return -EINVAL;
980
855 debug("exit\n"); 981 debug("exit\n");
856 982
857 return 0; 983 return 0;
@@ -862,25 +988,31 @@ static int tridentfb_check_var(struct fb_var_screeninfo *var,
862static int tridentfb_pan_display(struct fb_var_screeninfo *var, 988static int tridentfb_pan_display(struct fb_var_screeninfo *var,
863 struct fb_info *info) 989 struct fb_info *info)
864{ 990{
991 struct tridentfb_par *par = info->par;
865 unsigned int offset; 992 unsigned int offset;
866 993
867 debug("enter\n"); 994 debug("enter\n");
868 offset = (var->xoffset + (var->yoffset * var->xres)) 995 offset = (var->xoffset + (var->yoffset * var->xres_virtual))
869 * var->bits_per_pixel / 32; 996 * var->bits_per_pixel / 32;
870 info->var.xoffset = var->xoffset; 997 set_screen_start(par, offset);
871 info->var.yoffset = var->yoffset;
872 set_screen_start(offset);
873 debug("exit\n"); 998 debug("exit\n");
874 return 0; 999 return 0;
875} 1000}
876 1001
877#define shadowmode_on() write3CE(CyberControl, read3CE(CyberControl) | 0x81) 1002static inline void shadowmode_on(struct tridentfb_par *par)
878#define shadowmode_off() write3CE(CyberControl, read3CE(CyberControl) & 0x7E) 1003{
1004 write3CE(par, CyberControl, read3CE(par, CyberControl) | 0x81);
1005}
1006
1007static inline void shadowmode_off(struct tridentfb_par *par)
1008{
1009 write3CE(par, CyberControl, read3CE(par, CyberControl) & 0x7E);
1010}
879 1011
880/* Set the hardware to the requested video mode */ 1012/* Set the hardware to the requested video mode */
881static int tridentfb_set_par(struct fb_info *info) 1013static int tridentfb_set_par(struct fb_info *info)
882{ 1014{
883 struct tridentfb_par *par = (struct tridentfb_par *)(info->par); 1015 struct tridentfb_par *par = info->par;
884 u32 htotal, hdispend, hsyncstart, hsyncend, hblankstart, hblankend; 1016 u32 htotal, hdispend, hsyncstart, hsyncend, hblankstart, hblankend;
885 u32 vtotal, vdispend, vsyncstart, vsyncend, vblankstart, vblankend; 1017 u32 vtotal, vdispend, vsyncstart, vsyncend, vblankstart, vblankend;
886 struct fb_var_screeninfo *var = &info->var; 1018 struct fb_var_screeninfo *var = &info->var;
@@ -891,58 +1023,73 @@ static int tridentfb_set_par(struct fb_info *info)
891 debug("enter\n"); 1023 debug("enter\n");
892 hdispend = var->xres / 8 - 1; 1024 hdispend = var->xres / 8 - 1;
893 hsyncstart = (var->xres + var->right_margin) / 8; 1025 hsyncstart = (var->xres + var->right_margin) / 8;
894 hsyncend = var->hsync_len / 8; 1026 hsyncend = (var->xres + var->right_margin + var->hsync_len) / 8;
895 htotal = 1027 htotal = (var->xres + var->left_margin + var->right_margin +
896 (var->xres + var->left_margin + var->right_margin + 1028 var->hsync_len) / 8 - 5;
897 var->hsync_len) / 8 - 10;
898 hblankstart = hdispend + 1; 1029 hblankstart = hdispend + 1;
899 hblankend = htotal + 5; 1030 hblankend = htotal + 3;
900 1031
901 vdispend = var->yres - 1; 1032 vdispend = var->yres - 1;
902 vsyncstart = var->yres + var->lower_margin; 1033 vsyncstart = var->yres + var->lower_margin;
903 vsyncend = var->vsync_len; 1034 vsyncend = vsyncstart + var->vsync_len;
904 vtotal = var->upper_margin + vsyncstart + vsyncend - 2; 1035 vtotal = var->upper_margin + vsyncend - 2;
905 vblankstart = var->yres; 1036 vblankstart = vdispend + 1;
906 vblankend = vtotal + 2; 1037 vblankend = vtotal;
1038
1039 if (info->var.vmode & FB_VMODE_INTERLACED) {
1040 vtotal /= 2;
1041 vdispend /= 2;
1042 vsyncstart /= 2;
1043 vsyncend /= 2;
1044 vblankstart /= 2;
1045 vblankend /= 2;
1046 }
907 1047
908 crtc_unlock(); 1048 enable_mmio(par);
909 write3CE(CyberControl, 8); 1049 crtc_unlock(par);
1050 write3CE(par, CyberControl, 8);
1051 tmp = 0xEB;
1052 if (var->sync & FB_SYNC_HOR_HIGH_ACT)
1053 tmp &= ~0x40;
1054 if (var->sync & FB_SYNC_VERT_HIGH_ACT)
1055 tmp &= ~0x80;
910 1056
911 if (flatpanel && var->xres < nativex) { 1057 if (par->flatpanel && var->xres < nativex) {
912 /* 1058 /*
913 * on flat panels with native size larger 1059 * on flat panels with native size larger
914 * than requested resolution decide whether 1060 * than requested resolution decide whether
915 * we stretch or center 1061 * we stretch or center
916 */ 1062 */
917 t_outb(0xEB, 0x3C2); 1063 t_outb(par, tmp | 0xC0, VGA_MIS_W);
918 1064
919 shadowmode_on(); 1065 shadowmode_on(par);
920 1066
921 if (center) 1067 if (center)
922 screen_center(); 1068 screen_center(par);
923 else if (stretch) 1069 else if (stretch)
924 screen_stretch(); 1070 screen_stretch(par);
925 1071
926 } else { 1072 } else {
927 t_outb(0x2B, 0x3C2); 1073 t_outb(par, tmp, VGA_MIS_W);
928 write3CE(CyberControl, 8); 1074 write3CE(par, CyberControl, 8);
929 } 1075 }
930 1076
931 /* vertical timing values */ 1077 /* vertical timing values */
932 write3X4(CRTVTotal, vtotal & 0xFF); 1078 write3X4(par, VGA_CRTC_V_TOTAL, vtotal & 0xFF);
933 write3X4(CRTVDispEnd, vdispend & 0xFF); 1079 write3X4(par, VGA_CRTC_V_DISP_END, vdispend & 0xFF);
934 write3X4(CRTVSyncStart, vsyncstart & 0xFF); 1080 write3X4(par, VGA_CRTC_V_SYNC_START, vsyncstart & 0xFF);
935 write3X4(CRTVSyncEnd, (vsyncend & 0x0F)); 1081 write3X4(par, VGA_CRTC_V_SYNC_END, (vsyncend & 0x0F));
936 write3X4(CRTVBlankStart, vblankstart & 0xFF); 1082 write3X4(par, VGA_CRTC_V_BLANK_START, vblankstart & 0xFF);
937 write3X4(CRTVBlankEnd, 0 /* p->vblankend & 0xFF */ ); 1083 write3X4(par, VGA_CRTC_V_BLANK_END, vblankend & 0xFF);
938 1084
939 /* horizontal timing values */ 1085 /* horizontal timing values */
940 write3X4(CRTHTotal, htotal & 0xFF); 1086 write3X4(par, VGA_CRTC_H_TOTAL, htotal & 0xFF);
941 write3X4(CRTHDispEnd, hdispend & 0xFF); 1087 write3X4(par, VGA_CRTC_H_DISP, hdispend & 0xFF);
942 write3X4(CRTHSyncStart, hsyncstart & 0xFF); 1088 write3X4(par, VGA_CRTC_H_SYNC_START, hsyncstart & 0xFF);
943 write3X4(CRTHSyncEnd, (hsyncend & 0x1F) | ((hblankend & 0x20) << 2)); 1089 write3X4(par, VGA_CRTC_H_SYNC_END,
944 write3X4(CRTHBlankStart, hblankstart & 0xFF); 1090 (hsyncend & 0x1F) | ((hblankend & 0x20) << 2));
945 write3X4(CRTHBlankEnd, 0 /* (p->hblankend & 0x1F) */ ); 1091 write3X4(par, VGA_CRTC_H_BLANK_START, hblankstart & 0xFF);
1092 write3X4(par, VGA_CRTC_H_BLANK_END, hblankend & 0x1F);
946 1093
947 /* higher bits of vertical timing values */ 1094 /* higher bits of vertical timing values */
948 tmp = 0x10; 1095 tmp = 0x10;
@@ -954,39 +1101,43 @@ static int tridentfb_set_par(struct fb_info *info)
954 if (vtotal & 0x200) tmp |= 0x20; 1101 if (vtotal & 0x200) tmp |= 0x20;
955 if (vdispend & 0x200) tmp |= 0x40; 1102 if (vdispend & 0x200) tmp |= 0x40;
956 if (vsyncstart & 0x200) tmp |= 0x80; 1103 if (vsyncstart & 0x200) tmp |= 0x80;
957 write3X4(CRTOverflow, tmp); 1104 write3X4(par, VGA_CRTC_OVERFLOW, tmp);
958 1105
959 tmp = read3X4(CRTHiOrd) | 0x08; /* line compare bit 10 */ 1106 tmp = read3X4(par, CRTHiOrd) & 0x07;
1107 tmp |= 0x08; /* line compare bit 10 */
960 if (vtotal & 0x400) tmp |= 0x80; 1108 if (vtotal & 0x400) tmp |= 0x80;
961 if (vblankstart & 0x400) tmp |= 0x40; 1109 if (vblankstart & 0x400) tmp |= 0x40;
962 if (vsyncstart & 0x400) tmp |= 0x20; 1110 if (vsyncstart & 0x400) tmp |= 0x20;
963 if (vdispend & 0x400) tmp |= 0x10; 1111 if (vdispend & 0x400) tmp |= 0x10;
964 write3X4(CRTHiOrd, tmp); 1112 write3X4(par, CRTHiOrd, tmp);
965 1113
966 tmp = 0; 1114 tmp = (htotal >> 8) & 0x01;
967 if (htotal & 0x800) tmp |= 0x800 >> 11; 1115 tmp |= (hdispend >> 7) & 0x02;
968 if (hblankstart & 0x800) tmp |= 0x800 >> 7; 1116 tmp |= (hsyncstart >> 5) & 0x08;
969 write3X4(HorizOverflow, tmp); 1117 tmp |= (hblankstart >> 4) & 0x10;
1118 write3X4(par, HorizOverflow, tmp);
970 1119
971 tmp = 0x40; 1120 tmp = 0x40;
972 if (vblankstart & 0x200) tmp |= 0x20; 1121 if (vblankstart & 0x200) tmp |= 0x20;
973//FIXME if (info->var.vmode & FB_VMODE_DOUBLE) tmp |= 0x80; /* double scan for 200 line modes */ 1122//FIXME if (info->var.vmode & FB_VMODE_DOUBLE) tmp |= 0x80; /* double scan for 200 line modes */
974 write3X4(CRTMaxScanLine, tmp); 1123 write3X4(par, VGA_CRTC_MAX_SCAN, tmp);
975 1124
976 write3X4(CRTLineCompare, 0xFF); 1125 write3X4(par, VGA_CRTC_LINE_COMPARE, 0xFF);
977 write3X4(CRTPRowScan, 0); 1126 write3X4(par, VGA_CRTC_PRESET_ROW, 0);
978 write3X4(CRTModeControl, 0xC3); 1127 write3X4(par, VGA_CRTC_MODE, 0xC3);
979 1128
980 write3X4(LinearAddReg, 0x20); /* enable linear addressing */ 1129 write3X4(par, LinearAddReg, 0x20); /* enable linear addressing */
981 1130
982 tmp = (info->var.vmode & FB_VMODE_INTERLACED) ? 0x84 : 0x80; 1131 tmp = (info->var.vmode & FB_VMODE_INTERLACED) ? 0x84 : 0x80;
983 write3X4(CRTCModuleTest, tmp); /* enable access extended memory */ 1132 /* enable access extended memory */
984 1133 write3X4(par, CRTCModuleTest, tmp);
985 write3X4(GraphEngReg, 0x80); /* enable GE for text acceleration */ 1134 tmp = read3CE(par, MiscIntContReg) & ~0x4;
1135 if (info->var.vmode & FB_VMODE_INTERLACED)
1136 tmp |= 0x4;
1137 write3CE(par, MiscIntContReg, tmp);
986 1138
987#ifdef CONFIG_FB_TRIDENT_ACCEL 1139 /* enable GE for text acceleration */
988 acc->init_accel(info->var.xres, bpp); 1140 write3X4(par, GraphEngReg, 0x80);
989#endif
990 1141
991 switch (bpp) { 1142 switch (bpp) {
992 case 8: 1143 case 8:
@@ -1003,57 +1154,59 @@ static int tridentfb_set_par(struct fb_info *info)
1003 break; 1154 break;
1004 } 1155 }
1005 1156
1006 write3X4(PixelBusReg, tmp); 1157 write3X4(par, PixelBusReg, tmp);
1007 1158
1008 tmp = 0x10; 1159 tmp = read3X4(par, DRAMControl);
1009 if (chipcyber) 1160 if (!is_oldprotect(par->chip_id))
1161 tmp |= 0x10;
1162 if (iscyber(par->chip_id))
1010 tmp |= 0x20; 1163 tmp |= 0x20;
1011 write3X4(DRAMControl, tmp); /* both IO, linear enable */ 1164 write3X4(par, DRAMControl, tmp); /* both IO, linear enable */
1012 1165
1013 write3X4(InterfaceSel, read3X4(InterfaceSel) | 0x40); 1166 write3X4(par, InterfaceSel, read3X4(par, InterfaceSel) | 0x40);
1014 write3X4(Performance, 0x92); 1167 if (!is_xp(par->chip_id))
1015 write3X4(PCIReg, 0x07); /* MMIO & PCI read and write burst enable */ 1168 write3X4(par, Performance, read3X4(par, Performance) | 0x10);
1169 /* MMIO & PCI read and write burst enable */
1170 if (par->chip_id != TGUI9440 && par->chip_id != IMAGE975)
1171 write3X4(par, PCIReg, read3X4(par, PCIReg) | 0x06);
1172
1173 vga_mm_wseq(par->io_virt, 0, 3);
1174 vga_mm_wseq(par->io_virt, 1, 1); /* set char clock 8 dots wide */
1175 /* enable 4 maps because needed in chain4 mode */
1176 vga_mm_wseq(par->io_virt, 2, 0x0F);
1177 vga_mm_wseq(par->io_virt, 3, 0);
1178 vga_mm_wseq(par->io_virt, 4, 0x0E); /* memory mode enable bitmaps ?? */
1016 1179
1017 /* convert from picoseconds to kHz */ 1180 /* convert from picoseconds to kHz */
1018 vclk = PICOS2KHZ(info->var.pixclock); 1181 vclk = PICOS2KHZ(info->var.pixclock);
1019 if (bpp == 32) 1182
1183 /* divide clock by 2 if 32bpp chain4 mode display and CPU path */
1184 tmp = read3CE(par, MiscExtFunc) & 0xF0;
1185 if (bpp == 32 || (par->chip_id == TGUI9440 && bpp == 16)) {
1186 tmp |= 8;
1020 vclk *= 2; 1187 vclk *= 2;
1021 set_vclk(vclk);
1022
1023 write3C4(0, 3);
1024 write3C4(1, 1); /* set char clock 8 dots wide */
1025 write3C4(2, 0x0F); /* enable 4 maps because needed in chain4 mode */
1026 write3C4(3, 0);
1027 write3C4(4, 0x0E); /* memory mode enable bitmaps ?? */
1028
1029 write3CE(MiscExtFunc, (bpp == 32) ? 0x1A : 0x12); /* divide clock by 2 if 32bpp */
1030 /* chain4 mode display and CPU path */
1031 write3CE(0x5, 0x40); /* no CGA compat, allow 256 col */
1032 write3CE(0x6, 0x05); /* graphics mode */
1033 write3CE(0x7, 0x0F); /* planes? */
1034
1035 if (chip_id == CYBERBLADEXPAi1) {
1036 /* This fixes snow-effect in 32 bpp */
1037 write3X4(CRTHSyncStart, 0x84);
1038 } 1188 }
1189 set_vclk(par, vclk);
1190 write3CE(par, MiscExtFunc, tmp | 0x12);
1191 write3CE(par, 0x5, 0x40); /* no CGA compat, allow 256 col */
1192 write3CE(par, 0x6, 0x05); /* graphics mode */
1193 write3CE(par, 0x7, 0x0F); /* planes? */
1039 1194
1040 writeAttr(0x10, 0x41); /* graphics mode and support 256 color modes */ 1195 /* graphics mode and support 256 color modes */
1041 writeAttr(0x12, 0x0F); /* planes */ 1196 writeAttr(par, 0x10, 0x41);
1042 writeAttr(0x13, 0); /* horizontal pel panning */ 1197 writeAttr(par, 0x12, 0x0F); /* planes */
1198 writeAttr(par, 0x13, 0); /* horizontal pel panning */
1043 1199
1044 /* colors */ 1200 /* colors */
1045 for (tmp = 0; tmp < 0x10; tmp++) 1201 for (tmp = 0; tmp < 0x10; tmp++)
1046 writeAttr(tmp, tmp); 1202 writeAttr(par, tmp, tmp);
1047 readb(par->io_virt + CRT + 0x0A); /* flip-flop to index */ 1203 fb_readb(par->io_virt + VGA_IS1_RC); /* flip-flop to index */
1048 t_outb(0x20, 0x3C0); /* enable attr */ 1204 t_outb(par, 0x20, VGA_ATT_W); /* enable attr */
1049 1205
1050 switch (bpp) { 1206 switch (bpp) {
1051 case 8: 1207 case 8:
1052 tmp = 0; 1208 tmp = 0;
1053 break; 1209 break;
1054 case 15:
1055 tmp = 0x10;
1056 break;
1057 case 16: 1210 case 16:
1058 tmp = 0x30; 1211 tmp = 0x30;
1059 break; 1212 break;
@@ -1063,19 +1216,23 @@ static int tridentfb_set_par(struct fb_info *info)
1063 break; 1216 break;
1064 } 1217 }
1065 1218
1066 t_inb(0x3C8); 1219 t_inb(par, VGA_PEL_IW);
1067 t_inb(0x3C6); 1220 t_inb(par, VGA_PEL_MSK);
1068 t_inb(0x3C6); 1221 t_inb(par, VGA_PEL_MSK);
1069 t_inb(0x3C6); 1222 t_inb(par, VGA_PEL_MSK);
1070 t_inb(0x3C6); 1223 t_inb(par, VGA_PEL_MSK);
1071 t_outb(tmp, 0x3C6); 1224 t_outb(par, tmp, VGA_PEL_MSK);
1072 t_inb(0x3C8); 1225 t_inb(par, VGA_PEL_IW);
1073 1226
1074 if (flatpanel) 1227 if (par->flatpanel)
1075 set_number_of_lines(info->var.yres); 1228 set_number_of_lines(par, info->var.yres);
1076 set_lwidth(info->var.xres * bpp / (4 * 16)); 1229 info->fix.line_length = info->var.xres_virtual * bpp / 8;
1230 set_lwidth(par, info->fix.line_length / 8);
1231
1232 if (!(info->flags & FBINFO_HWACCEL_DISABLED))
1233 par->init_accel(par, info->var.xres_virtual, bpp);
1234
1077 info->fix.visual = (bpp == 8) ? FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_TRUECOLOR; 1235 info->fix.visual = (bpp == 8) ? FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_TRUECOLOR;
1078 info->fix.line_length = info->var.xres * (bpp >> 3);
1079 info->cmap.len = (bpp == 8) ? 256 : 16; 1236 info->cmap.len = (bpp == 8) ? 256 : 16;
1080 debug("exit\n"); 1237 debug("exit\n");
1081 return 0; 1238 return 0;
@@ -1087,17 +1244,18 @@ static int tridentfb_setcolreg(unsigned regno, unsigned red, unsigned green,
1087 struct fb_info *info) 1244 struct fb_info *info)
1088{ 1245{
1089 int bpp = info->var.bits_per_pixel; 1246 int bpp = info->var.bits_per_pixel;
1247 struct tridentfb_par *par = info->par;
1090 1248
1091 if (regno >= info->cmap.len) 1249 if (regno >= info->cmap.len)
1092 return 1; 1250 return 1;
1093 1251
1094 if (bpp == 8) { 1252 if (bpp == 8) {
1095 t_outb(0xFF, 0x3C6); 1253 t_outb(par, 0xFF, VGA_PEL_MSK);
1096 t_outb(regno, 0x3C8); 1254 t_outb(par, regno, VGA_PEL_IW);
1097 1255
1098 t_outb(red >> 10, 0x3C9); 1256 t_outb(par, red >> 10, VGA_PEL_D);
1099 t_outb(green >> 10, 0x3C9); 1257 t_outb(par, green >> 10, VGA_PEL_D);
1100 t_outb(blue >> 10, 0x3C9); 1258 t_outb(par, blue >> 10, VGA_PEL_D);
1101 1259
1102 } else if (regno < 16) { 1260 } else if (regno < 16) {
1103 if (bpp == 16) { /* RGB 565 */ 1261 if (bpp == 16) { /* RGB 565 */
@@ -1108,28 +1266,28 @@ static int tridentfb_setcolreg(unsigned regno, unsigned red, unsigned green,
1108 col |= col << 16; 1266 col |= col << 16;
1109 ((u32 *)(info->pseudo_palette))[regno] = col; 1267 ((u32 *)(info->pseudo_palette))[regno] = col;
1110 } else if (bpp == 32) /* ARGB 8888 */ 1268 } else if (bpp == 32) /* ARGB 8888 */
1111 ((u32*)info->pseudo_palette)[regno] = 1269 ((u32 *)info->pseudo_palette)[regno] =
1112 ((transp & 0xFF00) << 16) | 1270 ((transp & 0xFF00) << 16) |
1113 ((red & 0xFF00) << 8) | 1271 ((red & 0xFF00) << 8) |
1114 ((green & 0xFF00)) | 1272 ((green & 0xFF00)) |
1115 ((blue & 0xFF00) >> 8); 1273 ((blue & 0xFF00) >> 8);
1116 } 1274 }
1117 1275
1118/* debug("exit\n"); */
1119 return 0; 1276 return 0;
1120} 1277}
1121 1278
1122/* Try blanking the screen.For flat panels it does nothing */ 1279/* Try blanking the screen. For flat panels it does nothing */
1123static int tridentfb_blank(int blank_mode, struct fb_info *info) 1280static int tridentfb_blank(int blank_mode, struct fb_info *info)
1124{ 1281{
1125 unsigned char PMCont, DPMSCont; 1282 unsigned char PMCont, DPMSCont;
1283 struct tridentfb_par *par = info->par;
1126 1284
1127 debug("enter\n"); 1285 debug("enter\n");
1128 if (flatpanel) 1286 if (par->flatpanel)
1129 return 0; 1287 return 0;
1130 t_outb(0x04, 0x83C8); /* Read DPMS Control */ 1288 t_outb(par, 0x04, 0x83C8); /* Read DPMS Control */
1131 PMCont = t_inb(0x83C6) & 0xFC; 1289 PMCont = t_inb(par, 0x83C6) & 0xFC;
1132 DPMSCont = read3CE(PowerStatus) & 0xFC; 1290 DPMSCont = read3CE(par, PowerStatus) & 0xFC;
1133 switch (blank_mode) { 1291 switch (blank_mode) {
1134 case FB_BLANK_UNBLANK: 1292 case FB_BLANK_UNBLANK:
1135 /* Screen: On, HSync: On, VSync: On */ 1293 /* Screen: On, HSync: On, VSync: On */
@@ -1155,9 +1313,9 @@ static int tridentfb_blank(int blank_mode, struct fb_info *info)
1155 break; 1313 break;
1156 } 1314 }
1157 1315
1158 write3CE(PowerStatus, DPMSCont); 1316 write3CE(par, PowerStatus, DPMSCont);
1159 t_outb(4, 0x83C8); 1317 t_outb(par, 4, 0x83C8);
1160 t_outb(PMCont, 0x83C6); 1318 t_outb(par, PMCont, 0x83C6);
1161 1319
1162 debug("exit\n"); 1320 debug("exit\n");
1163 1321
@@ -1174,33 +1332,46 @@ static struct fb_ops tridentfb_ops = {
1174 .fb_set_par = tridentfb_set_par, 1332 .fb_set_par = tridentfb_set_par,
1175 .fb_fillrect = tridentfb_fillrect, 1333 .fb_fillrect = tridentfb_fillrect,
1176 .fb_copyarea = tridentfb_copyarea, 1334 .fb_copyarea = tridentfb_copyarea,
1177 .fb_imageblit = cfb_imageblit, 1335 .fb_imageblit = tridentfb_imageblit,
1336#ifdef CONFIG_FB_TRIDENT_ACCEL
1337 .fb_sync = tridentfb_sync,
1338#endif
1178}; 1339};
1179 1340
1180static int __devinit trident_pci_probe(struct pci_dev * dev, 1341static int __devinit trident_pci_probe(struct pci_dev *dev,
1181 const struct pci_device_id * id) 1342 const struct pci_device_id *id)
1182{ 1343{
1183 int err; 1344 int err;
1184 unsigned char revision; 1345 unsigned char revision;
1346 struct fb_info *info;
1347 struct tridentfb_par *default_par;
1348 int chip3D;
1349 int chip_id;
1185 1350
1186 err = pci_enable_device(dev); 1351 err = pci_enable_device(dev);
1187 if (err) 1352 if (err)
1188 return err; 1353 return err;
1189 1354
1190 chip_id = id->device; 1355 info = framebuffer_alloc(sizeof(struct tridentfb_par), &dev->dev);
1356 if (!info)
1357 return -ENOMEM;
1358 default_par = info->par;
1191 1359
1192 if (chip_id == CYBERBLADEi1) 1360 chip_id = id->device;
1193 output("*** Please do use cyblafb, Cyberblade/i1 support "
1194 "will soon be removed from tridentfb!\n");
1195 1361
1362#ifndef CONFIG_FB_TRIDENT_ACCEL
1363 noaccel = 1;
1364#endif
1196 1365
1197 /* If PCI id is 0x9660 then further detect chip type */ 1366 /* If PCI id is 0x9660 then further detect chip type */
1198 1367
1199 if (chip_id == TGUI9660) { 1368 if (chip_id == TGUI9660) {
1200 outb(RevisionID, 0x3C4); 1369 revision = vga_io_rseq(RevisionID);
1201 revision = inb(0x3C5);
1202 1370
1203 switch (revision) { 1371 switch (revision) {
1372 case 0x21:
1373 chip_id = PROVIDIA9685;
1374 break;
1204 case 0x22: 1375 case 0x22:
1205 case 0x23: 1376 case 0x23:
1206 chip_id = CYBER9397; 1377 chip_id = CYBER9397;
@@ -1229,123 +1400,170 @@ static int __devinit trident_pci_probe(struct pci_dev * dev,
1229 } 1400 }
1230 1401
1231 chip3D = is3Dchip(chip_id); 1402 chip3D = is3Dchip(chip_id);
1232 chipcyber = iscyber(chip_id);
1233 1403
1234 if (is_xp(chip_id)) { 1404 if (is_xp(chip_id)) {
1235 acc = &accel_xp; 1405 default_par->init_accel = xp_init_accel;
1406 default_par->wait_engine = xp_wait_engine;
1407 default_par->fill_rect = xp_fill_rect;
1408 default_par->copy_rect = xp_copy_rect;
1409 tridentfb_fix.accel = FB_ACCEL_TRIDENT_BLADEXP;
1236 } else if (is_blade(chip_id)) { 1410 } else if (is_blade(chip_id)) {
1237 acc = &accel_blade; 1411 default_par->init_accel = blade_init_accel;
1238 } else { 1412 default_par->wait_engine = blade_wait_engine;
1239 acc = &accel_image; 1413 default_par->fill_rect = blade_fill_rect;
1414 default_par->copy_rect = blade_copy_rect;
1415 default_par->image_blit = blade_image_blit;
1416 tridentfb_fix.accel = FB_ACCEL_TRIDENT_BLADE3D;
1417 } else if (chip3D) { /* 3DImage family left */
1418 default_par->init_accel = image_init_accel;
1419 default_par->wait_engine = image_wait_engine;
1420 default_par->fill_rect = image_fill_rect;
1421 default_par->copy_rect = image_copy_rect;
1422 tridentfb_fix.accel = FB_ACCEL_TRIDENT_3DIMAGE;
1423 } else { /* TGUI 9440/96XX family */
1424 default_par->init_accel = tgui_init_accel;
1425 default_par->wait_engine = xp_wait_engine;
1426 default_par->fill_rect = tgui_fill_rect;
1427 default_par->copy_rect = tgui_copy_rect;
1428 tridentfb_fix.accel = FB_ACCEL_TRIDENT_TGUI;
1240 } 1429 }
1241 1430
1242 /* acceleration is on by default for 3D chips */ 1431 default_par->chip_id = chip_id;
1243 defaultaccel = chip3D && !noaccel;
1244
1245 fb_info.par = &default_par;
1246 1432
1247 /* setup MMIO region */ 1433 /* setup MMIO region */
1248 tridentfb_fix.mmio_start = pci_resource_start(dev, 1); 1434 tridentfb_fix.mmio_start = pci_resource_start(dev, 1);
1249 tridentfb_fix.mmio_len = chip3D ? 0x20000 : 0x10000; 1435 tridentfb_fix.mmio_len = pci_resource_len(dev, 1);
1250 1436
1251 if (!request_mem_region(tridentfb_fix.mmio_start, tridentfb_fix.mmio_len, "tridentfb")) { 1437 if (!request_mem_region(tridentfb_fix.mmio_start,
1438 tridentfb_fix.mmio_len, "tridentfb")) {
1252 debug("request_region failed!\n"); 1439 debug("request_region failed!\n");
1440 framebuffer_release(info);
1253 return -1; 1441 return -1;
1254 } 1442 }
1255 1443
1256 default_par.io_virt = ioremap_nocache(tridentfb_fix.mmio_start, tridentfb_fix.mmio_len); 1444 default_par->io_virt = ioremap_nocache(tridentfb_fix.mmio_start,
1445 tridentfb_fix.mmio_len);
1257 1446
1258 if (!default_par.io_virt) { 1447 if (!default_par->io_virt) {
1259 debug("ioremap failed\n"); 1448 debug("ioremap failed\n");
1260 err = -1; 1449 err = -1;
1261 goto out_unmap1; 1450 goto out_unmap1;
1262 } 1451 }
1263 1452
1264 enable_mmio(); 1453 enable_mmio(default_par);
1265 1454
1266 /* setup framebuffer memory */ 1455 /* setup framebuffer memory */
1267 tridentfb_fix.smem_start = pci_resource_start(dev, 0); 1456 tridentfb_fix.smem_start = pci_resource_start(dev, 0);
1268 tridentfb_fix.smem_len = get_memsize(); 1457 tridentfb_fix.smem_len = get_memsize(default_par);
1269 1458
1270 if (!request_mem_region(tridentfb_fix.smem_start, tridentfb_fix.smem_len, "tridentfb")) { 1459 if (!request_mem_region(tridentfb_fix.smem_start,
1460 tridentfb_fix.smem_len, "tridentfb")) {
1271 debug("request_mem_region failed!\n"); 1461 debug("request_mem_region failed!\n");
1272 disable_mmio(); 1462 disable_mmio(info->par);
1273 err = -1; 1463 err = -1;
1274 goto out_unmap1; 1464 goto out_unmap1;
1275 } 1465 }
1276 1466
1277 fb_info.screen_base = ioremap_nocache(tridentfb_fix.smem_start, 1467 info->screen_base = ioremap_nocache(tridentfb_fix.smem_start,
1278 tridentfb_fix.smem_len); 1468 tridentfb_fix.smem_len);
1279 1469
1280 if (!fb_info.screen_base) { 1470 if (!info->screen_base) {
1281 debug("ioremap failed\n"); 1471 debug("ioremap failed\n");
1282 err = -1; 1472 err = -1;
1283 goto out_unmap2; 1473 goto out_unmap2;
1284 } 1474 }
1285 1475
1286 output("%s board found\n", pci_name(dev)); 1476 default_par->flatpanel = is_flatpanel(default_par);
1287 displaytype = get_displaytype();
1288 1477
1289 if (flatpanel) 1478 if (default_par->flatpanel)
1290 nativex = get_nativex(); 1479 nativex = get_nativex(default_par);
1291 1480
1292 fb_info.fix = tridentfb_fix; 1481 info->fix = tridentfb_fix;
1293 fb_info.fbops = &tridentfb_ops; 1482 info->fbops = &tridentfb_ops;
1483 info->pseudo_palette = default_par->pseudo_pal;
1294 1484
1485 info->flags = FBINFO_DEFAULT | FBINFO_HWACCEL_YPAN;
1486 if (!noaccel && default_par->init_accel) {
1487 info->flags &= ~FBINFO_HWACCEL_DISABLED;
1488 info->flags |= FBINFO_HWACCEL_COPYAREA;
1489 info->flags |= FBINFO_HWACCEL_FILLRECT;
1490 } else
1491 info->flags |= FBINFO_HWACCEL_DISABLED;
1295 1492
1296 fb_info.flags = FBINFO_DEFAULT | FBINFO_HWACCEL_YPAN; 1493 info->pixmap.addr = kmalloc(4096, GFP_KERNEL);
1297#ifdef CONFIG_FB_TRIDENT_ACCEL 1494 if (!info->pixmap.addr) {
1298 fb_info.flags |= FBINFO_HWACCEL_COPYAREA | FBINFO_HWACCEL_FILLRECT; 1495 err = -ENOMEM;
1299#endif 1496 goto out_unmap2;
1300 fb_info.pseudo_palette = pseudo_pal; 1497 }
1498
1499 info->pixmap.size = 4096;
1500 info->pixmap.buf_align = 4;
1501 info->pixmap.scan_align = 1;
1502 info->pixmap.access_align = 32;
1503 info->pixmap.flags = FB_PIXMAP_SYSTEM;
1301 1504
1302 if (!fb_find_mode(&default_var, &fb_info, 1505 if (default_par->image_blit) {
1506 info->flags |= FBINFO_HWACCEL_IMAGEBLIT;
1507 info->pixmap.scan_align = 4;
1508 }
1509
1510 if (noaccel) {
1511 printk(KERN_DEBUG "disabling acceleration\n");
1512 info->flags |= FBINFO_HWACCEL_DISABLED;
1513 info->pixmap.scan_align = 1;
1514 }
1515
1516 if (!fb_find_mode(&info->var, info,
1303 mode_option, NULL, 0, NULL, bpp)) { 1517 mode_option, NULL, 0, NULL, bpp)) {
1304 err = -EINVAL; 1518 err = -EINVAL;
1305 goto out_unmap2; 1519 goto out_unmap2;
1306 } 1520 }
1307 err = fb_alloc_cmap(&fb_info.cmap, 256, 0); 1521 err = fb_alloc_cmap(&info->cmap, 256, 0);
1308 if (err < 0) 1522 if (err < 0)
1309 goto out_unmap2; 1523 goto out_unmap2;
1310 1524
1311 if (defaultaccel && acc) 1525 info->var.activate |= FB_ACTIVATE_NOW;
1312 default_var.accel_flags |= FB_ACCELF_TEXT; 1526 info->device = &dev->dev;
1313 else 1527 if (register_framebuffer(info) < 0) {
1314 default_var.accel_flags &= ~FB_ACCELF_TEXT; 1528 printk(KERN_ERR "tridentfb: could not register framebuffer\n");
1315 default_var.activate |= FB_ACTIVATE_NOW; 1529 fb_dealloc_cmap(&info->cmap);
1316 fb_info.var = default_var;
1317 fb_info.device = &dev->dev;
1318 if (register_framebuffer(&fb_info) < 0) {
1319 printk(KERN_ERR "tridentfb: could not register Trident framebuffer\n");
1320 fb_dealloc_cmap(&fb_info.cmap);
1321 err = -EINVAL; 1530 err = -EINVAL;
1322 goto out_unmap2; 1531 goto out_unmap2;
1323 } 1532 }
1324 output("fb%d: %s frame buffer device %dx%d-%dbpp\n", 1533 output("fb%d: %s frame buffer device %dx%d-%dbpp\n",
1325 fb_info.node, fb_info.fix.id, default_var.xres, 1534 info->node, info->fix.id, info->var.xres,
1326 default_var.yres, default_var.bits_per_pixel); 1535 info->var.yres, info->var.bits_per_pixel);
1536
1537 pci_set_drvdata(dev, info);
1327 return 0; 1538 return 0;
1328 1539
1329out_unmap2: 1540out_unmap2:
1330 if (fb_info.screen_base) 1541 kfree(info->pixmap.addr);
1331 iounmap(fb_info.screen_base); 1542 if (info->screen_base)
1543 iounmap(info->screen_base);
1332 release_mem_region(tridentfb_fix.smem_start, tridentfb_fix.smem_len); 1544 release_mem_region(tridentfb_fix.smem_start, tridentfb_fix.smem_len);
1333 disable_mmio(); 1545 disable_mmio(info->par);
1334out_unmap1: 1546out_unmap1:
1335 if (default_par.io_virt) 1547 if (default_par->io_virt)
1336 iounmap(default_par.io_virt); 1548 iounmap(default_par->io_virt);
1337 release_mem_region(tridentfb_fix.mmio_start, tridentfb_fix.mmio_len); 1549 release_mem_region(tridentfb_fix.mmio_start, tridentfb_fix.mmio_len);
1550 framebuffer_release(info);
1338 return err; 1551 return err;
1339} 1552}
1340 1553
1341static void __devexit trident_pci_remove(struct pci_dev *dev) 1554static void __devexit trident_pci_remove(struct pci_dev *dev)
1342{ 1555{
1343 struct tridentfb_par *par = (struct tridentfb_par*)fb_info.par; 1556 struct fb_info *info = pci_get_drvdata(dev);
1344 unregister_framebuffer(&fb_info); 1557 struct tridentfb_par *par = info->par;
1558
1559 unregister_framebuffer(info);
1345 iounmap(par->io_virt); 1560 iounmap(par->io_virt);
1346 iounmap(fb_info.screen_base); 1561 iounmap(info->screen_base);
1347 release_mem_region(tridentfb_fix.smem_start, tridentfb_fix.smem_len); 1562 release_mem_region(tridentfb_fix.smem_start, tridentfb_fix.smem_len);
1348 release_mem_region(tridentfb_fix.mmio_start, tridentfb_fix.mmio_len); 1563 release_mem_region(tridentfb_fix.mmio_start, tridentfb_fix.mmio_len);
1564 pci_set_drvdata(dev, NULL);
1565 kfree(info->pixmap.addr);
1566 framebuffer_release(info);
1349} 1567}
1350 1568
1351/* List of boards that we are trying to support */ 1569/* List of boards that we are trying to support */
@@ -1358,6 +1576,7 @@ static struct pci_device_id trident_devices[] = {
1358 {PCI_VENDOR_ID_TRIDENT, CYBERBLADEAi1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, 1576 {PCI_VENDOR_ID_TRIDENT, CYBERBLADEAi1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
1359 {PCI_VENDOR_ID_TRIDENT, CYBERBLADEAi1D, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, 1577 {PCI_VENDOR_ID_TRIDENT, CYBERBLADEAi1D, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
1360 {PCI_VENDOR_ID_TRIDENT, CYBERBLADEE4, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, 1578 {PCI_VENDOR_ID_TRIDENT, CYBERBLADEE4, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
1579 {PCI_VENDOR_ID_TRIDENT, TGUI9440, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
1361 {PCI_VENDOR_ID_TRIDENT, TGUI9660, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, 1580 {PCI_VENDOR_ID_TRIDENT, TGUI9660, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
1362 {PCI_VENDOR_ID_TRIDENT, IMAGE975, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, 1581 {PCI_VENDOR_ID_TRIDENT, IMAGE975, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
1363 {PCI_VENDOR_ID_TRIDENT, IMAGE985, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, 1582 {PCI_VENDOR_ID_TRIDENT, IMAGE985, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
@@ -1399,9 +1618,9 @@ static int __init tridentfb_setup(char *options)
1399 if (!strncmp(opt, "noaccel", 7)) 1618 if (!strncmp(opt, "noaccel", 7))
1400 noaccel = 1; 1619 noaccel = 1;
1401 else if (!strncmp(opt, "fp", 2)) 1620 else if (!strncmp(opt, "fp", 2))
1402 displaytype = DISPLAY_FP; 1621 fp = 1;
1403 else if (!strncmp(opt, "crt", 3)) 1622 else if (!strncmp(opt, "crt", 3))
1404 displaytype = DISPLAY_CRT; 1623 fp = 0;
1405 else if (!strncmp(opt, "bpp=", 4)) 1624 else if (!strncmp(opt, "bpp=", 4))
1406 bpp = simple_strtoul(opt + 4, NULL, 0); 1625 bpp = simple_strtoul(opt + 4, NULL, 0);
1407 else if (!strncmp(opt, "center", 6)) 1626 else if (!strncmp(opt, "center", 6))
@@ -1430,7 +1649,6 @@ static int __init tridentfb_init(void)
1430 return -ENODEV; 1649 return -ENODEV;
1431 tridentfb_setup(option); 1650 tridentfb_setup(option);
1432#endif 1651#endif
1433 output("Trident framebuffer %s initializing\n", VERSION);
1434 return pci_register_driver(&tridentfb_pci_driver); 1652 return pci_register_driver(&tridentfb_pci_driver);
1435} 1653}
1436 1654
diff --git a/drivers/video/uvesafb.c b/drivers/video/uvesafb.c
index cdbb56edb6cb..50744229c7a9 100644
--- a/drivers/video/uvesafb.c
+++ b/drivers/video/uvesafb.c
@@ -2054,8 +2054,8 @@ MODULE_PARM_DESC(maxhf,
2054module_param(maxvf, ushort, 0); 2054module_param(maxvf, ushort, 0);
2055MODULE_PARM_DESC(maxvf, 2055MODULE_PARM_DESC(maxvf,
2056 "Maximum vertical frequency [Hz], overrides EDID data"); 2056 "Maximum vertical frequency [Hz], overrides EDID data");
2057module_param_named(mode, mode_option, charp, 0); 2057module_param(mode_option, charp, 0);
2058MODULE_PARM_DESC(mode, 2058MODULE_PARM_DESC(mode_option,
2059 "Specify initial video mode as \"<xres>x<yres>[-<bpp>][@<refresh>]\""); 2059 "Specify initial video mode as \"<xres>x<yres>[-<bpp>][@<refresh>]\"");
2060module_param(vbemode, ushort, 0); 2060module_param(vbemode, ushort, 0);
2061MODULE_PARM_DESC(vbemode, 2061MODULE_PARM_DESC(vbemode,
diff --git a/drivers/video/vfb.c b/drivers/video/vfb.c
index 072638a9528a..93fe08d6c78f 100644
--- a/drivers/video/vfb.c
+++ b/drivers/video/vfb.c
@@ -443,19 +443,29 @@ static int vfb_mmap(struct fb_info *info,
443} 443}
444 444
445#ifndef MODULE 445#ifndef MODULE
446/*
447 * The virtual framebuffer driver is only enabled if explicitly
448 * requested by passing 'video=vfb:' (or any actual options).
449 */
446static int __init vfb_setup(char *options) 450static int __init vfb_setup(char *options)
447{ 451{
448 char *this_opt; 452 char *this_opt;
449 453
454 vfb_enable = 0;
455
456 if (!options)
457 return 1;
458
450 vfb_enable = 1; 459 vfb_enable = 1;
451 460
452 if (!options || !*options) 461 if (!*options)
453 return 1; 462 return 1;
454 463
455 while ((this_opt = strsep(&options, ",")) != NULL) { 464 while ((this_opt = strsep(&options, ",")) != NULL) {
456 if (!*this_opt) 465 if (!*this_opt)
457 continue; 466 continue;
458 if (!strncmp(this_opt, "disable", 7)) 467 /* Test disable for backwards compatibility */
468 if (!strcmp(this_opt, "disable"))
459 vfb_enable = 0; 469 vfb_enable = 0;
460 } 470 }
461 return 1; 471 return 1;
diff --git a/drivers/video/vga16fb.c b/drivers/video/vga16fb.c
index 9b3c5923365e..e31bca8a0cb2 100644
--- a/drivers/video/vga16fb.c
+++ b/drivers/video/vga16fb.c
@@ -26,18 +26,6 @@
26#include <asm/io.h> 26#include <asm/io.h>
27#include <video/vga.h> 27#include <video/vga.h>
28 28
29#define GRAPHICS_ADDR_REG VGA_GFX_I /* Graphics address register. */
30#define GRAPHICS_DATA_REG VGA_GFX_D /* Graphics data register. */
31
32#define SET_RESET_INDEX VGA_GFX_SR_VALUE /* Set/Reset Register index. */
33#define ENABLE_SET_RESET_INDEX VGA_GFX_SR_ENABLE /* Enable Set/Reset Register index. */
34#define DATA_ROTATE_INDEX VGA_GFX_DATA_ROTATE /* Data Rotate Register index. */
35#define GRAPHICS_MODE_INDEX VGA_GFX_MODE /* Graphics Mode Register index. */
36#define BIT_MASK_INDEX VGA_GFX_BIT_MASK /* Bit Mask Register index. */
37
38#define dac_reg (VGA_PEL_IW)
39#define dac_val (VGA_PEL_D)
40
41#define VGA_FB_PHYS 0xA0000 29#define VGA_FB_PHYS 0xA0000
42#define VGA_FB_PHYS_LEN 65536 30#define VGA_FB_PHYS_LEN 65536
43 31
@@ -108,7 +96,7 @@ static struct fb_fix_screeninfo vga16fb_fix __initdata = {
108 .visual = FB_VISUAL_PSEUDOCOLOR, 96 .visual = FB_VISUAL_PSEUDOCOLOR,
109 .xpanstep = 8, 97 .xpanstep = 8,
110 .ypanstep = 1, 98 .ypanstep = 1,
111 .line_length = 640/8, 99 .line_length = 640 / 8,
112 .accel = FB_ACCEL_NONE 100 .accel = FB_ACCEL_NONE
113}; 101};
114 102
@@ -135,23 +123,22 @@ static inline int setmode(int mode)
135{ 123{
136 int oldmode; 124 int oldmode;
137 125
138 vga_io_w(GRAPHICS_ADDR_REG, GRAPHICS_MODE_INDEX); 126 oldmode = vga_io_rgfx(VGA_GFX_MODE);
139 oldmode = vga_io_r(GRAPHICS_DATA_REG); 127 vga_io_w(VGA_GFX_D, mode);
140 vga_io_w(GRAPHICS_DATA_REG, mode);
141 return oldmode; 128 return oldmode;
142} 129}
143 130
144/* Select the Bit Mask Register and return its value. */ 131/* Select the Bit Mask Register and return its value. */
145static inline int selectmask(void) 132static inline int selectmask(void)
146{ 133{
147 return vga_io_rgfx(BIT_MASK_INDEX); 134 return vga_io_rgfx(VGA_GFX_BIT_MASK);
148} 135}
149 136
150/* Set the value of the Bit Mask Register. It must already have been 137/* Set the value of the Bit Mask Register. It must already have been
151 selected with selectmask(). */ 138 selected with selectmask(). */
152static inline void setmask(int mask) 139static inline void setmask(int mask)
153{ 140{
154 vga_io_w(GRAPHICS_DATA_REG, mask); 141 vga_io_w(VGA_GFX_D, mask);
155} 142}
156 143
157/* Set the Data Rotate Register and return its old value. 144/* Set the Data Rotate Register and return its old value.
@@ -161,9 +148,8 @@ static inline int setop(int op)
161{ 148{
162 int oldop; 149 int oldop;
163 150
164 vga_io_w(GRAPHICS_ADDR_REG, DATA_ROTATE_INDEX); 151 oldop = vga_io_rgfx(VGA_GFX_DATA_ROTATE);
165 oldop = vga_io_r(GRAPHICS_DATA_REG); 152 vga_io_w(VGA_GFX_D, op);
166 vga_io_w(GRAPHICS_DATA_REG, op);
167 return oldop; 153 return oldop;
168} 154}
169 155
@@ -173,9 +159,8 @@ static inline int setsr(int sr)
173{ 159{
174 int oldsr; 160 int oldsr;
175 161
176 vga_io_w(GRAPHICS_ADDR_REG, ENABLE_SET_RESET_INDEX); 162 oldsr = vga_io_rgfx(VGA_GFX_SR_ENABLE);
177 oldsr = vga_io_r(GRAPHICS_DATA_REG); 163 vga_io_w(VGA_GFX_D, sr);
178 vga_io_w(GRAPHICS_DATA_REG, sr);
179 return oldsr; 164 return oldsr;
180} 165}
181 166
@@ -184,22 +169,21 @@ static inline int setcolor(int color)
184{ 169{
185 int oldcolor; 170 int oldcolor;
186 171
187 vga_io_w(GRAPHICS_ADDR_REG, SET_RESET_INDEX); 172 oldcolor = vga_io_rgfx(VGA_GFX_SR_VALUE);
188 oldcolor = vga_io_r(GRAPHICS_DATA_REG); 173 vga_io_w(VGA_GFX_D, color);
189 vga_io_w(GRAPHICS_DATA_REG, color);
190 return oldcolor; 174 return oldcolor;
191} 175}
192 176
193/* Return the value in the Graphics Address Register. */ 177/* Return the value in the Graphics Address Register. */
194static inline int getindex(void) 178static inline int getindex(void)
195{ 179{
196 return vga_io_r(GRAPHICS_ADDR_REG); 180 return vga_io_r(VGA_GFX_I);
197} 181}
198 182
199/* Set the value in the Graphics Address Register. */ 183/* Set the value in the Graphics Address Register. */
200static inline void setindex(int index) 184static inline void setindex(int index)
201{ 185{
202 vga_io_w(GRAPHICS_ADDR_REG, index); 186 vga_io_w(VGA_GFX_I, index);
203} 187}
204 188
205static void vga16fb_pan_var(struct fb_info *info, 189static void vga16fb_pan_var(struct fb_info *info,
@@ -672,10 +656,10 @@ static void ega16_setpalette(int regno, unsigned red, unsigned green, unsigned b
672 656
673static void vga16_setpalette(int regno, unsigned red, unsigned green, unsigned blue) 657static void vga16_setpalette(int regno, unsigned red, unsigned green, unsigned blue)
674{ 658{
675 outb(regno, dac_reg); 659 outb(regno, VGA_PEL_IW);
676 outb(red >> 10, dac_val); 660 outb(red >> 10, VGA_PEL_D);
677 outb(green >> 10, dac_val); 661 outb(green >> 10, VGA_PEL_D);
678 outb(blue >> 10, dac_val); 662 outb(blue >> 10, VGA_PEL_D);
679} 663}
680 664
681static int vga16fb_setcolreg(unsigned regno, unsigned red, unsigned green, 665static int vga16fb_setcolreg(unsigned regno, unsigned red, unsigned green,
@@ -719,28 +703,15 @@ static int vga16fb_pan_display(struct fb_var_screeninfo *var,
719 blanking code was originally by Huang shi chao, and modified by 703 blanking code was originally by Huang shi chao, and modified by
720 Christoph Rimek (chrimek@toppoint.de) and todd j. derr 704 Christoph Rimek (chrimek@toppoint.de) and todd j. derr
721 (tjd@barefoot.org) for Linux. */ 705 (tjd@barefoot.org) for Linux. */
722#define attrib_port VGA_ATC_IW
723#define seq_port_reg VGA_SEQ_I
724#define seq_port_val VGA_SEQ_D
725#define gr_port_reg VGA_GFX_I
726#define gr_port_val VGA_GFX_D
727#define video_misc_rd VGA_MIS_R
728#define video_misc_wr VGA_MIS_W
729#define vga_video_port_reg VGA_CRT_IC
730#define vga_video_port_val VGA_CRT_DC
731 706
732static void vga_vesa_blank(struct vga16fb_par *par, int mode) 707static void vga_vesa_blank(struct vga16fb_par *par, int mode)
733{ 708{
734 unsigned char SeqCtrlIndex; 709 unsigned char SeqCtrlIndex = vga_io_r(VGA_SEQ_I);
735 unsigned char CrtCtrlIndex; 710 unsigned char CrtCtrlIndex = vga_io_r(VGA_CRT_IC);
736 711
737 //cli();
738 SeqCtrlIndex = vga_io_r(seq_port_reg);
739 CrtCtrlIndex = vga_io_r(vga_video_port_reg);
740
741 /* save original values of VGA controller registers */ 712 /* save original values of VGA controller registers */
742 if(!par->vesa_blanked) { 713 if(!par->vesa_blanked) {
743 par->vga_state.CrtMiscIO = vga_io_r(video_misc_rd); 714 par->vga_state.CrtMiscIO = vga_io_r(VGA_MIS_R);
744 //sti(); 715 //sti();
745 716
746 par->vga_state.HorizontalTotal = vga_io_rcrt(0x00); /* HorizontalTotal */ 717 par->vga_state.HorizontalTotal = vga_io_rcrt(0x00); /* HorizontalTotal */
@@ -756,12 +727,11 @@ static void vga_vesa_blank(struct vga16fb_par *par, int mode)
756 727
757 /* assure that video is enabled */ 728 /* assure that video is enabled */
758 /* "0x20" is VIDEO_ENABLE_bit in register 01 of sequencer */ 729 /* "0x20" is VIDEO_ENABLE_bit in register 01 of sequencer */
759 //cli();
760 vga_io_wseq(0x01, par->vga_state.ClockingMode | 0x20); 730 vga_io_wseq(0x01, par->vga_state.ClockingMode | 0x20);
761 731
762 /* test for vertical retrace in process.... */ 732 /* test for vertical retrace in process.... */
763 if ((par->vga_state.CrtMiscIO & 0x80) == 0x80) 733 if ((par->vga_state.CrtMiscIO & 0x80) == 0x80)
764 vga_io_w(video_misc_wr, par->vga_state.CrtMiscIO & 0xef); 734 vga_io_w(VGA_MIS_W, par->vga_state.CrtMiscIO & 0xef);
765 735
766 /* 736 /*
767 * Set <End of vertical retrace> to minimum (0) and 737 * Set <End of vertical retrace> to minimum (0) and
@@ -769,12 +739,10 @@ static void vga_vesa_blank(struct vga16fb_par *par, int mode)
769 * Result: turn off vertical sync (VSync) pulse. 739 * Result: turn off vertical sync (VSync) pulse.
770 */ 740 */
771 if (mode & FB_BLANK_VSYNC_SUSPEND) { 741 if (mode & FB_BLANK_VSYNC_SUSPEND) {
772 outb_p(0x10,vga_video_port_reg); /* StartVertRetrace */ 742 vga_io_wcrt(VGA_CRTC_V_SYNC_START, 0xff);
773 outb_p(0xff,vga_video_port_val); /* maximum value */ 743 vga_io_wcrt(VGA_CRTC_V_SYNC_END, 0x40);
774 outb_p(0x11,vga_video_port_reg); /* EndVertRetrace */ 744 /* bits 9,10 of vert. retrace */
775 outb_p(0x40,vga_video_port_val); /* minimum (bits 0..3) */ 745 vga_io_wcrt(VGA_CRTC_OVERFLOW, par->vga_state.Overflow | 0x84);
776 outb_p(0x07,vga_video_port_reg); /* Overflow */
777 outb_p(par->vga_state.Overflow | 0x84,vga_video_port_val); /* bits 9,10 of vert. retrace */
778 } 746 }
779 747
780 if (mode & FB_BLANK_HSYNC_SUSPEND) { 748 if (mode & FB_BLANK_HSYNC_SUSPEND) {
@@ -783,29 +751,22 @@ static void vga_vesa_blank(struct vga16fb_par *par, int mode)
783 * <Start of horizontal Retrace> to maximum 751 * <Start of horizontal Retrace> to maximum
784 * Result: turn off horizontal sync (HSync) pulse. 752 * Result: turn off horizontal sync (HSync) pulse.
785 */ 753 */
786 outb_p(0x04,vga_video_port_reg); /* StartHorizRetrace */ 754 vga_io_wcrt(VGA_CRTC_H_SYNC_START, 0xff);
787 outb_p(0xff,vga_video_port_val); /* maximum */ 755 vga_io_wcrt(VGA_CRTC_H_SYNC_END, 0x00);
788 outb_p(0x05,vga_video_port_reg); /* EndHorizRetrace */
789 outb_p(0x00,vga_video_port_val); /* minimum (0) */
790 } 756 }
791 757
792 /* restore both index registers */ 758 /* restore both index registers */
793 outb_p(SeqCtrlIndex,seq_port_reg); 759 outb_p(SeqCtrlIndex, VGA_SEQ_I);
794 outb_p(CrtCtrlIndex,vga_video_port_reg); 760 outb_p(CrtCtrlIndex, VGA_CRT_IC);
795 //sti();
796} 761}
797 762
798static void vga_vesa_unblank(struct vga16fb_par *par) 763static void vga_vesa_unblank(struct vga16fb_par *par)
799{ 764{
800 unsigned char SeqCtrlIndex; 765 unsigned char SeqCtrlIndex = vga_io_r(VGA_SEQ_I);
801 unsigned char CrtCtrlIndex; 766 unsigned char CrtCtrlIndex = vga_io_r(VGA_CRT_IC);
802 767
803 //cli();
804 SeqCtrlIndex = vga_io_r(seq_port_reg);
805 CrtCtrlIndex = vga_io_r(vga_video_port_reg);
806
807 /* restore original values of VGA controller registers */ 768 /* restore original values of VGA controller registers */
808 vga_io_w(video_misc_wr, par->vga_state.CrtMiscIO); 769 vga_io_w(VGA_MIS_W, par->vga_state.CrtMiscIO);
809 770
810 /* HorizontalTotal */ 771 /* HorizontalTotal */
811 vga_io_wcrt(0x00, par->vga_state.HorizontalTotal); 772 vga_io_wcrt(0x00, par->vga_state.HorizontalTotal);
@@ -827,9 +788,8 @@ static void vga_vesa_unblank(struct vga16fb_par *par)
827 vga_io_wseq(0x01, par->vga_state.ClockingMode); 788 vga_io_wseq(0x01, par->vga_state.ClockingMode);
828 789
829 /* restore index/control registers */ 790 /* restore index/control registers */
830 vga_io_w(seq_port_reg, SeqCtrlIndex); 791 vga_io_w(VGA_SEQ_I, SeqCtrlIndex);
831 vga_io_w(vga_video_port_reg, CrtCtrlIndex); 792 vga_io_w(VGA_CRT_IC, CrtCtrlIndex);
832 //sti();
833} 793}
834 794
835static void vga_pal_blank(void) 795static void vga_pal_blank(void)
@@ -837,10 +797,10 @@ static void vga_pal_blank(void)
837 int i; 797 int i;
838 798
839 for (i=0; i<16; i++) { 799 for (i=0; i<16; i++) {
840 outb_p (i, dac_reg) ; 800 outb_p(i, VGA_PEL_IW);
841 outb_p (0, dac_val) ; 801 outb_p(0, VGA_PEL_D);
842 outb_p (0, dac_val) ; 802 outb_p(0, VGA_PEL_D);
843 outb_p (0, dac_val) ; 803 outb_p(0, VGA_PEL_D);
844 } 804 }
845} 805}
846 806
@@ -1087,12 +1047,15 @@ static void vga16fb_copyarea(struct fb_info *info, const struct fb_copyarea *are
1087 width = x2 - dx; 1047 width = x2 - dx;
1088 height = y2 - dy; 1048 height = y2 - dy;
1089 1049
1050 if (sx + dx < old_dx || sy + dy < old_dy)
1051 return;
1052
1090 /* update sx1,sy1 */ 1053 /* update sx1,sy1 */
1091 sx += (dx - old_dx); 1054 sx += (dx - old_dx);
1092 sy += (dy - old_dy); 1055 sy += (dy - old_dy);
1093 1056
1094 /* the source must be completely inside the virtual screen */ 1057 /* the source must be completely inside the virtual screen */
1095 if (sx < 0 || sy < 0 || (sx + width) > vxres || (sy + height) > vyres) 1058 if (sx + width > vxres || sy + height > vyres)
1096 return; 1059 return;
1097 1060
1098 switch (info->fix.type) { 1061 switch (info->fix.type) {
@@ -1482,6 +1445,7 @@ static void __exit vga16fb_exit(void)
1482 platform_driver_unregister(&vga16fb_driver); 1445 platform_driver_unregister(&vga16fb_driver);
1483} 1446}
1484 1447
1448MODULE_DESCRIPTION("Legacy VGA framebuffer device driver");
1485MODULE_LICENSE("GPL"); 1449MODULE_LICENSE("GPL");
1486module_init(vga16fb_init); 1450module_init(vga16fb_init);
1487module_exit(vga16fb_exit); 1451module_exit(vga16fb_exit);
diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
index ccb78f66c2b6..48399e134c0d 100644
--- a/drivers/watchdog/Kconfig
+++ b/drivers/watchdog/Kconfig
@@ -788,8 +788,6 @@ config WATCHDOG_RIO
788 machines. The watchdog timeout period is normally one minute but 788 machines. The watchdog timeout period is normally one minute but
789 can be changed with a boot-time parameter. 789 can be changed with a boot-time parameter.
790 790
791# V850 Architecture
792
793# XTENSA Architecture 791# XTENSA Architecture
794 792
795# 793#
diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile
index 25b352b664d9..edd305a64e63 100644
--- a/drivers/watchdog/Makefile
+++ b/drivers/watchdog/Makefile
@@ -119,8 +119,6 @@ obj-$(CONFIG_SH_WDT) += shwdt.o
119 119
120# SPARC64 Architecture 120# SPARC64 Architecture
121 121
122# V850 Architecture
123
124# XTENSA Architecture 122# XTENSA Architecture
125 123
126# Architecture Independant 124# Architecture Independant
diff --git a/drivers/zorro/zorro-sysfs.c b/drivers/zorro/zorro-sysfs.c
index 3da712cc7708..5290552d2ef7 100644
--- a/drivers/zorro/zorro-sysfs.c
+++ b/drivers/zorro/zorro-sysfs.c
@@ -15,7 +15,6 @@
15#include <linux/zorro.h> 15#include <linux/zorro.h>
16#include <linux/stat.h> 16#include <linux/stat.h>
17#include <linux/string.h> 17#include <linux/string.h>
18#include <linux/fs.h>
19 18
20#include "zorro.h" 19#include "zorro.h"
21 20