aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/block/floppy.c42
-rw-r--r--drivers/block/swim3.c230
-rw-r--r--drivers/char/agp/frontend.c2
-rw-r--r--drivers/char/applicom.c2
-rw-r--r--drivers/char/cs5535_gpio.c2
-rw-r--r--drivers/char/ds1286.c2
-rw-r--r--drivers/char/ds1302.c2
-rw-r--r--drivers/char/ds1620.c2
-rw-r--r--drivers/char/dsp56k.c2
-rw-r--r--drivers/char/dtlk.c2
-rw-r--r--drivers/char/efirtc.c2
-rw-r--r--drivers/char/ftape/zftape/zftape-init.c2
-rw-r--r--drivers/char/genrtc.c2
-rw-r--r--drivers/char/hpet.c2
-rw-r--r--drivers/char/hvsi.c7
-rw-r--r--drivers/char/hw_random/core.c2
-rw-r--r--drivers/char/i8k.c2
-rw-r--r--drivers/char/ip2/ip2main.c2
-rw-r--r--drivers/char/ip27-rtc.c2
-rw-r--r--drivers/char/ipmi/ipmi_devintf.c2
-rw-r--r--drivers/char/ipmi/ipmi_watchdog.c2
-rw-r--r--drivers/char/istallion.c2
-rw-r--r--drivers/char/ite_gpio.c2
-rw-r--r--drivers/char/lcd.c2
-rw-r--r--drivers/char/lp.c2
-rw-r--r--drivers/char/mem.c18
-rw-r--r--drivers/char/misc.c4
-rw-r--r--drivers/char/mmtimer.c2
-rw-r--r--drivers/char/mwave/mwavedd.c2
-rw-r--r--drivers/char/nvram.c2
-rw-r--r--drivers/char/nwbutton.c2
-rw-r--r--drivers/char/nwflash.c2
-rw-r--r--drivers/char/pc8736x_gpio.c2
-rw-r--r--drivers/char/pcmcia/cm4000_cs.c2
-rw-r--r--drivers/char/pcmcia/cm4040_cs.c2
-rw-r--r--drivers/char/ppdev.c2
-rw-r--r--drivers/char/random.c6
-rw-r--r--drivers/char/raw.c6
-rw-r--r--drivers/char/rio/rio_linux.c2
-rw-r--r--drivers/char/rtc.c4
-rw-r--r--drivers/char/scx200_gpio.c2
-rw-r--r--drivers/char/snsc.c2
-rw-r--r--drivers/char/sonypi.c2
-rw-r--r--drivers/char/stallion.c2
-rw-r--r--drivers/char/sx.c2
-rw-r--r--drivers/char/sysrq.c5
-rw-r--r--drivers/char/tb0219.c2
-rw-r--r--drivers/char/tipar.c2
-rw-r--r--drivers/char/tlclk.c2
-rw-r--r--drivers/char/toshiba.c2
-rw-r--r--drivers/char/tpm/tpm_atmel.c2
-rw-r--r--drivers/char/tpm/tpm_infineon.c2
-rw-r--r--drivers/char/tpm/tpm_nsc.c2
-rw-r--r--drivers/char/tpm/tpm_tis.c2
-rw-r--r--drivers/char/tty_io.c10
-rw-r--r--drivers/char/vc_screen.c2
-rw-r--r--drivers/char/viotape.c2
-rw-r--r--drivers/char/vr41xx_giu.c2
-rw-r--r--drivers/char/vt.c1
-rw-r--r--drivers/char/watchdog/acquirewdt.c2
-rw-r--r--drivers/char/watchdog/advantechwdt.c2
-rw-r--r--drivers/char/watchdog/alim1535_wdt.c2
-rw-r--r--drivers/char/watchdog/alim7101_wdt.c2
-rw-r--r--drivers/char/watchdog/at91_wdt.c2
-rw-r--r--drivers/char/watchdog/booke_wdt.c2
-rw-r--r--drivers/char/watchdog/cpu5wdt.c2
-rw-r--r--drivers/char/watchdog/ep93xx_wdt.c2
-rw-r--r--drivers/char/watchdog/eurotechwdt.c2
-rw-r--r--drivers/char/watchdog/i6300esb.c2
-rw-r--r--drivers/char/watchdog/i8xx_tco.c2
-rw-r--r--drivers/char/watchdog/ib700wdt.c2
-rw-r--r--drivers/char/watchdog/ibmasr.c2
-rw-r--r--drivers/char/watchdog/indydog.c2
-rw-r--r--drivers/char/watchdog/ixp2000_wdt.c2
-rw-r--r--drivers/char/watchdog/ixp4xx_wdt.c2
-rw-r--r--drivers/char/watchdog/machzwd.c2
-rw-r--r--drivers/char/watchdog/mixcomwd.c2
-rw-r--r--drivers/char/watchdog/mpc83xx_wdt.c2
-rw-r--r--drivers/char/watchdog/mpc8xx_wdt.c2
-rw-r--r--drivers/char/watchdog/mpcore_wdt.c2
-rw-r--r--drivers/char/watchdog/mv64x60_wdt.c2
-rw-r--r--drivers/char/watchdog/pcwd.c4
-rw-r--r--drivers/char/watchdog/pcwd_pci.c4
-rw-r--r--drivers/char/watchdog/pcwd_usb.c4
-rw-r--r--drivers/char/watchdog/s3c2410_wdt.c2
-rw-r--r--drivers/char/watchdog/sa1100_wdt.c2
-rw-r--r--drivers/char/watchdog/sbc60xxwdt.c2
-rw-r--r--drivers/char/watchdog/sbc8360.c2
-rw-r--r--drivers/char/watchdog/sbc_epx_c3.c2
-rw-r--r--drivers/char/watchdog/sc1200wdt.c2
-rw-r--r--drivers/char/watchdog/sc520_wdt.c2
-rw-r--r--drivers/char/watchdog/scx200_wdt.c2
-rw-r--r--drivers/char/watchdog/shwdt.c2
-rw-r--r--drivers/char/watchdog/softdog.c2
-rw-r--r--drivers/char/watchdog/w83627hf_wdt.c2
-rw-r--r--drivers/char/watchdog/w83877f_wdt.c2
-rw-r--r--drivers/char/watchdog/w83977f_wdt.c2
-rw-r--r--drivers/char/watchdog/wafer5823wdt.c2
-rw-r--r--drivers/char/watchdog/wdrtas.c4
-rw-r--r--drivers/char/watchdog/wdt.c4
-rw-r--r--drivers/char/watchdog/wdt285.c2
-rw-r--r--drivers/char/watchdog/wdt977.c2
-rw-r--r--drivers/char/watchdog/wdt_pci.c4
-rw-r--r--drivers/ide/ide-floppy.c2
-rw-r--r--drivers/ide/ide-io.c8
-rw-r--r--drivers/ide/ide-taskfile.c2
-rw-r--r--drivers/ieee1394/hosts.c10
-rw-r--r--drivers/input/serio/i8042-sparcio.h2
-rw-r--r--drivers/input/serio/libps2.c2
-rw-r--r--drivers/macintosh/macio-adb.c19
-rw-r--r--drivers/macintosh/macio_asic.c152
-rw-r--r--drivers/macintosh/smu.c6
-rw-r--r--drivers/macintosh/via-cuda.c24
-rw-r--r--drivers/macintosh/via-pmu.c33
-rw-r--r--drivers/md/md.c6
-rw-r--r--drivers/mmc/mmc.c2
-rw-r--r--drivers/net/3c59x.c4
-rw-r--r--drivers/net/8390.c4
-rw-r--r--drivers/net/forcedeth.c28
-rw-r--r--drivers/net/mace.c4
-rw-r--r--drivers/net/wireless/hostap/hostap_hw.c10
-rw-r--r--drivers/pnp/pnpacpi/rsparser.c11
-rw-r--r--drivers/s390/char/sclp.c10
-rw-r--r--drivers/s390/cio/cio.c2
-rw-r--r--drivers/s390/net/qeth_main.c6
-rw-r--r--drivers/s390/s390mach.c3
-rw-r--r--drivers/s390/scsi/zfcp_erp.c8
-rw-r--r--drivers/s390/scsi/zfcp_qdio.c9
-rw-r--r--drivers/scsi/libata-core.c2
-rw-r--r--drivers/serial/8250_pnp.c2
-rw-r--r--drivers/serial/pmac_zilog.c6
-rw-r--r--drivers/serial/serial_core.c11
-rw-r--r--drivers/spi/spi.c2
-rw-r--r--drivers/usb/core/inode.c4
-rw-r--r--drivers/video/Kconfig15
-rw-r--r--drivers/video/Makefile2
-rw-r--r--drivers/video/offb.c284
-rw-r--r--drivers/video/pnx4008/Makefile7
-rw-r--r--drivers/video/pnx4008/dum.h211
-rw-r--r--drivers/video/pnx4008/fbcommon.h43
-rw-r--r--drivers/video/pnx4008/pnxrgbfb.c213
-rw-r--r--drivers/video/pnx4008/sdum.c872
-rw-r--r--drivers/video/pnx4008/sdum.h139
143 files changed, 2125 insertions, 584 deletions
diff --git a/drivers/block/floppy.c b/drivers/block/floppy.c
index 0242cbb86a87..5109fa37c662 100644
--- a/drivers/block/floppy.c
+++ b/drivers/block/floppy.c
@@ -249,18 +249,6 @@ static int irqdma_allocated;
249#include <linux/cdrom.h> /* for the compatibility eject ioctl */ 249#include <linux/cdrom.h> /* for the compatibility eject ioctl */
250#include <linux/completion.h> 250#include <linux/completion.h>
251 251
252/*
253 * Interrupt freeing also means /proc VFS work - dont do it
254 * from interrupt context. We push this work into keventd:
255 */
256static void fd_free_irq_fn(void *data)
257{
258 fd_free_irq();
259}
260
261static DECLARE_WORK(fd_free_irq_work, fd_free_irq_fn, NULL);
262
263
264static struct request *current_req; 252static struct request *current_req;
265static struct request_queue *floppy_queue; 253static struct request_queue *floppy_queue;
266static void do_fd_request(request_queue_t * q); 254static void do_fd_request(request_queue_t * q);
@@ -826,15 +814,6 @@ static int set_dor(int fdc, char mask, char data)
826 UDRS->select_date = jiffies; 814 UDRS->select_date = jiffies;
827 } 815 }
828 } 816 }
829 /*
830 * We should propagate failures to grab the resources back
831 * nicely from here. Actually we ought to rewrite the fd
832 * driver some day too.
833 */
834 if (newdor & FLOPPY_MOTOR_MASK)
835 floppy_grab_irq_and_dma();
836 if (olddor & FLOPPY_MOTOR_MASK)
837 floppy_release_irq_and_dma();
838 return olddor; 817 return olddor;
839} 818}
840 819
@@ -892,8 +871,6 @@ static int _lock_fdc(int drive, int interruptible, int line)
892 line); 871 line);
893 return -1; 872 return -1;
894 } 873 }
895 if (floppy_grab_irq_and_dma() == -1)
896 return -EBUSY;
897 874
898 if (test_and_set_bit(0, &fdc_busy)) { 875 if (test_and_set_bit(0, &fdc_busy)) {
899 DECLARE_WAITQUEUE(wait, current); 876 DECLARE_WAITQUEUE(wait, current);
@@ -915,6 +892,8 @@ static int _lock_fdc(int drive, int interruptible, int line)
915 892
916 set_current_state(TASK_RUNNING); 893 set_current_state(TASK_RUNNING);
917 remove_wait_queue(&fdc_wait, &wait); 894 remove_wait_queue(&fdc_wait, &wait);
895
896 flush_scheduled_work();
918 } 897 }
919 command_status = FD_COMMAND_NONE; 898 command_status = FD_COMMAND_NONE;
920 899
@@ -948,7 +927,6 @@ static inline void unlock_fdc(void)
948 if (elv_next_request(floppy_queue)) 927 if (elv_next_request(floppy_queue))
949 do_fd_request(floppy_queue); 928 do_fd_request(floppy_queue);
950 spin_unlock_irqrestore(&floppy_lock, flags); 929 spin_unlock_irqrestore(&floppy_lock, flags);
951 floppy_release_irq_and_dma();
952 wake_up(&fdc_wait); 930 wake_up(&fdc_wait);
953} 931}
954 932
@@ -3694,8 +3672,8 @@ static int floppy_release(struct inode *inode, struct file *filp)
3694 } 3672 }
3695 if (!UDRS->fd_ref) 3673 if (!UDRS->fd_ref)
3696 opened_bdev[drive] = NULL; 3674 opened_bdev[drive] = NULL;
3697 floppy_release_irq_and_dma();
3698 mutex_unlock(&open_lock); 3675 mutex_unlock(&open_lock);
3676
3699 return 0; 3677 return 0;
3700} 3678}
3701 3679
@@ -3726,9 +3704,6 @@ static int floppy_open(struct inode *inode, struct file *filp)
3726 if (UDRS->fd_ref == -1 || (UDRS->fd_ref && (filp->f_flags & O_EXCL))) 3704 if (UDRS->fd_ref == -1 || (UDRS->fd_ref && (filp->f_flags & O_EXCL)))
3727 goto out2; 3705 goto out2;
3728 3706
3729 if (floppy_grab_irq_and_dma())
3730 goto out2;
3731
3732 if (filp->f_flags & O_EXCL) 3707 if (filp->f_flags & O_EXCL)
3733 UDRS->fd_ref = -1; 3708 UDRS->fd_ref = -1;
3734 else 3709 else
@@ -3805,7 +3780,6 @@ out:
3805 UDRS->fd_ref--; 3780 UDRS->fd_ref--;
3806 if (!UDRS->fd_ref) 3781 if (!UDRS->fd_ref)
3807 opened_bdev[drive] = NULL; 3782 opened_bdev[drive] = NULL;
3808 floppy_release_irq_and_dma();
3809out2: 3783out2:
3810 mutex_unlock(&open_lock); 3784 mutex_unlock(&open_lock);
3811 return res; 3785 return res;
@@ -3822,14 +3796,9 @@ static int check_floppy_change(struct gendisk *disk)
3822 return 1; 3796 return 1;
3823 3797
3824 if (time_after(jiffies, UDRS->last_checked + UDP->checkfreq)) { 3798 if (time_after(jiffies, UDRS->last_checked + UDP->checkfreq)) {
3825 if (floppy_grab_irq_and_dma()) {
3826 return 1;
3827 }
3828
3829 lock_fdc(drive, 0); 3799 lock_fdc(drive, 0);
3830 poll_drive(0, 0); 3800 poll_drive(0, 0);
3831 process_fd_request(); 3801 process_fd_request();
3832 floppy_release_irq_and_dma();
3833 } 3802 }
3834 3803
3835 if (UTESTF(FD_DISK_CHANGED) || 3804 if (UTESTF(FD_DISK_CHANGED) ||
@@ -4346,7 +4315,6 @@ static int __init floppy_init(void)
4346 fdc = 0; 4315 fdc = 0;
4347 del_timer(&fd_timeout); 4316 del_timer(&fd_timeout);
4348 current_drive = 0; 4317 current_drive = 0;
4349 floppy_release_irq_and_dma();
4350 initialising = 0; 4318 initialising = 0;
4351 if (have_no_fdc) { 4319 if (have_no_fdc) {
4352 DPRINT("no floppy controllers found\n"); 4320 DPRINT("no floppy controllers found\n");
@@ -4504,7 +4472,7 @@ static void floppy_release_irq_and_dma(void)
4504 if (irqdma_allocated) { 4472 if (irqdma_allocated) {
4505 fd_disable_dma(); 4473 fd_disable_dma();
4506 fd_free_dma(); 4474 fd_free_dma();
4507 schedule_work(&fd_free_irq_work); 4475 fd_free_irq();
4508 irqdma_allocated = 0; 4476 irqdma_allocated = 0;
4509 } 4477 }
4510 set_dor(0, ~0, 8); 4478 set_dor(0, ~0, 8);
@@ -4600,8 +4568,6 @@ void cleanup_module(void)
4600 /* eject disk, if any */ 4568 /* eject disk, if any */
4601 fd_eject(0); 4569 fd_eject(0);
4602 4570
4603 flush_scheduled_work(); /* fd_free_irq() might be pending */
4604
4605 wait_for_completion(&device_release); 4571 wait_for_completion(&device_release);
4606} 4572}
4607 4573
diff --git a/drivers/block/swim3.c b/drivers/block/swim3.c
index 3721e12135d9..cc42e762396f 100644
--- a/drivers/block/swim3.c
+++ b/drivers/block/swim3.c
@@ -250,8 +250,6 @@ static int floppy_open(struct inode *inode, struct file *filp);
250static int floppy_release(struct inode *inode, struct file *filp); 250static int floppy_release(struct inode *inode, struct file *filp);
251static int floppy_check_change(struct gendisk *disk); 251static int floppy_check_change(struct gendisk *disk);
252static int floppy_revalidate(struct gendisk *disk); 252static int floppy_revalidate(struct gendisk *disk);
253static int swim3_add_device(struct device_node *swims);
254int swim3_init(void);
255 253
256#ifndef CONFIG_PMAC_MEDIABAY 254#ifndef CONFIG_PMAC_MEDIABAY
257#define check_media_bay(which, what) 1 255#define check_media_bay(which, what) 1
@@ -1011,114 +1009,63 @@ static struct block_device_operations floppy_fops = {
1011 .revalidate_disk= floppy_revalidate, 1009 .revalidate_disk= floppy_revalidate,
1012}; 1010};
1013 1011
1014int swim3_init(void) 1012static int swim3_add_device(struct macio_dev *mdev, int index)
1015{
1016 struct device_node *swim;
1017 int err = -ENOMEM;
1018 int i;
1019
1020 swim = find_devices("floppy");
1021 while (swim && (floppy_count < MAX_FLOPPIES))
1022 {
1023 swim3_add_device(swim);
1024 swim = swim->next;
1025 }
1026
1027 swim = find_devices("swim3");
1028 while (swim && (floppy_count < MAX_FLOPPIES))
1029 {
1030 swim3_add_device(swim);
1031 swim = swim->next;
1032 }
1033
1034 if (!floppy_count)
1035 return -ENODEV;
1036
1037 for (i = 0; i < floppy_count; i++) {
1038 disks[i] = alloc_disk(1);
1039 if (!disks[i])
1040 goto out;
1041 }
1042
1043 if (register_blkdev(FLOPPY_MAJOR, "fd")) {
1044 err = -EBUSY;
1045 goto out;
1046 }
1047
1048 swim3_queue = blk_init_queue(do_fd_request, &swim3_lock);
1049 if (!swim3_queue) {
1050 err = -ENOMEM;
1051 goto out_queue;
1052 }
1053
1054 for (i = 0; i < floppy_count; i++) {
1055 struct gendisk *disk = disks[i];
1056 disk->major = FLOPPY_MAJOR;
1057 disk->first_minor = i;
1058 disk->fops = &floppy_fops;
1059 disk->private_data = &floppy_states[i];
1060 disk->queue = swim3_queue;
1061 disk->flags |= GENHD_FL_REMOVABLE;
1062 sprintf(disk->disk_name, "fd%d", i);
1063 set_capacity(disk, 2880);
1064 add_disk(disk);
1065 }
1066 return 0;
1067
1068out_queue:
1069 unregister_blkdev(FLOPPY_MAJOR, "fd");
1070out:
1071 while (i--)
1072 put_disk(disks[i]);
1073 /* shouldn't we do something with results of swim_add_device()? */
1074 return err;
1075}
1076
1077static int swim3_add_device(struct device_node *swim)
1078{ 1013{
1014 struct device_node *swim = mdev->ofdev.node;
1079 struct device_node *mediabay; 1015 struct device_node *mediabay;
1080 struct floppy_state *fs = &floppy_states[floppy_count]; 1016 struct floppy_state *fs = &floppy_states[index];
1081 struct resource res_reg, res_dma; 1017 int rc = -EBUSY;
1082 1018
1083 if (of_address_to_resource(swim, 0, &res_reg) || 1019 /* Check & Request resources */
1084 of_address_to_resource(swim, 1, &res_dma)) { 1020 if (macio_resource_count(mdev) < 2) {
1085 printk(KERN_ERR "swim3: Can't get addresses\n"); 1021 printk(KERN_WARNING "ifd%d: no address for %s\n",
1086 return -EINVAL; 1022 index, swim->full_name);
1023 return -ENXIO;
1087 } 1024 }
1088 if (request_mem_region(res_reg.start, res_reg.end - res_reg.start + 1, 1025 if (macio_irq_count(mdev) < 2) {
1089 " (reg)") == NULL) { 1026 printk(KERN_WARNING "fd%d: no intrs for device %s\n",
1090 printk(KERN_ERR "swim3: Can't request register space\n"); 1027 index, swim->full_name);
1091 return -EINVAL;
1092 } 1028 }
1093 if (request_mem_region(res_dma.start, res_dma.end - res_dma.start + 1, 1029 if (macio_request_resource(mdev, 0, "swim3 (mmio)")) {
1094 " (dma)") == NULL) { 1030 printk(KERN_ERR "fd%d: can't request mmio resource for %s\n",
1095 release_mem_region(res_reg.start, 1031 index, swim->full_name);
1096 res_reg.end - res_reg.start + 1); 1032 return -EBUSY;
1097 printk(KERN_ERR "swim3: Can't request DMA space\n");
1098 return -EINVAL;
1099 } 1033 }
1100 1034 if (macio_request_resource(mdev, 1, "swim3 (dma)")) {
1101 if (swim->n_intrs < 2) { 1035 printk(KERN_ERR "fd%d: can't request dma resource for %s\n",
1102 printk(KERN_INFO "swim3: expecting 2 intrs (n_intrs:%d)\n", 1036 index, swim->full_name);
1103 swim->n_intrs); 1037 macio_release_resource(mdev, 0);
1104 release_mem_region(res_reg.start, 1038 return -EBUSY;
1105 res_reg.end - res_reg.start + 1);
1106 release_mem_region(res_dma.start,
1107 res_dma.end - res_dma.start + 1);
1108 return -EINVAL;
1109 } 1039 }
1040 dev_set_drvdata(&mdev->ofdev.dev, fs);
1110 1041
1111 mediabay = (strcasecmp(swim->parent->type, "media-bay") == 0) ? swim->parent : NULL; 1042 mediabay = (strcasecmp(swim->parent->type, "media-bay") == 0) ?
1043 swim->parent : NULL;
1112 if (mediabay == NULL) 1044 if (mediabay == NULL)
1113 pmac_call_feature(PMAC_FTR_SWIM3_ENABLE, swim, 0, 1); 1045 pmac_call_feature(PMAC_FTR_SWIM3_ENABLE, swim, 0, 1);
1114 1046
1115 memset(fs, 0, sizeof(*fs)); 1047 memset(fs, 0, sizeof(*fs));
1116 spin_lock_init(&fs->lock); 1048 spin_lock_init(&fs->lock);
1117 fs->state = idle; 1049 fs->state = idle;
1118 fs->swim3 = (struct swim3 __iomem *)ioremap(res_reg.start, 0x200); 1050 fs->swim3 = (struct swim3 __iomem *)
1119 fs->dma = (struct dbdma_regs __iomem *)ioremap(res_dma.start, 0x200); 1051 ioremap(macio_resource_start(mdev, 0), 0x200);
1120 fs->swim3_intr = swim->intrs[0].line; 1052 if (fs->swim3 == NULL) {
1121 fs->dma_intr = swim->intrs[1].line; 1053 printk("fd%d: couldn't map registers for %s\n",
1054 index, swim->full_name);
1055 rc = -ENOMEM;
1056 goto out_release;
1057 }
1058 fs->dma = (struct dbdma_regs __iomem *)
1059 ioremap(macio_resource_start(mdev, 1), 0x200);
1060 if (fs->dma == NULL) {
1061 printk("fd%d: couldn't map DMA for %s\n",
1062 index, swim->full_name);
1063 iounmap(fs->swim3);
1064 rc = -ENOMEM;
1065 goto out_release;
1066 }
1067 fs->swim3_intr = macio_irq(mdev, 0);
1068 fs->dma_intr = macio_irq(mdev, 1);;
1122 fs->cur_cyl = -1; 1069 fs->cur_cyl = -1;
1123 fs->cur_sector = -1; 1070 fs->cur_sector = -1;
1124 fs->secpercyl = 36; 1071 fs->secpercyl = 36;
@@ -1132,15 +1079,16 @@ static int swim3_add_device(struct device_node *swim)
1132 st_le16(&fs->dma_cmd[1].command, DBDMA_STOP); 1079 st_le16(&fs->dma_cmd[1].command, DBDMA_STOP);
1133 1080
1134 if (request_irq(fs->swim3_intr, swim3_interrupt, 0, "SWIM3", fs)) { 1081 if (request_irq(fs->swim3_intr, swim3_interrupt, 0, "SWIM3", fs)) {
1135 printk(KERN_ERR "Couldn't get irq %d for SWIM3\n", fs->swim3_intr); 1082 printk(KERN_ERR "fd%d: couldn't request irq %d for %s\n",
1083 index, fs->swim3_intr, swim->full_name);
1136 pmac_call_feature(PMAC_FTR_SWIM3_ENABLE, swim, 0, 0); 1084 pmac_call_feature(PMAC_FTR_SWIM3_ENABLE, swim, 0, 0);
1085 goto out_unmap;
1137 return -EBUSY; 1086 return -EBUSY;
1138 } 1087 }
1139/* 1088/*
1140 if (request_irq(fs->dma_intr, fd_dma_interrupt, 0, "SWIM3-dma", fs)) { 1089 if (request_irq(fs->dma_intr, fd_dma_interrupt, 0, "SWIM3-dma", fs)) {
1141 printk(KERN_ERR "Couldn't get irq %d for SWIM3 DMA", 1090 printk(KERN_ERR "Couldn't get irq %d for SWIM3 DMA",
1142 fs->dma_intr); 1091 fs->dma_intr);
1143 pmac_call_feature(PMAC_FTR_SWIM3_ENABLE, swim, 0, 0);
1144 return -EBUSY; 1092 return -EBUSY;
1145 } 1093 }
1146*/ 1094*/
@@ -1150,8 +1098,90 @@ static int swim3_add_device(struct device_node *swim)
1150 printk(KERN_INFO "fd%d: SWIM3 floppy controller %s\n", floppy_count, 1098 printk(KERN_INFO "fd%d: SWIM3 floppy controller %s\n", floppy_count,
1151 mediabay ? "in media bay" : ""); 1099 mediabay ? "in media bay" : "");
1152 1100
1153 floppy_count++; 1101 return 0;
1154 1102
1103 out_unmap:
1104 iounmap(fs->dma);
1105 iounmap(fs->swim3);
1106
1107 out_release:
1108 macio_release_resource(mdev, 0);
1109 macio_release_resource(mdev, 1);
1110
1111 return rc;
1112}
1113
1114static int __devinit swim3_attach(struct macio_dev *mdev, const struct of_device_id *match)
1115{
1116 int i, rc;
1117 struct gendisk *disk;
1118
1119 /* Add the drive */
1120 rc = swim3_add_device(mdev, floppy_count);
1121 if (rc)
1122 return rc;
1123
1124 /* Now create the queue if not there yet */
1125 if (swim3_queue == NULL) {
1126 /* If we failed, there isn't much we can do as the driver is still
1127 * too dumb to remove the device, just bail out
1128 */
1129 if (register_blkdev(FLOPPY_MAJOR, "fd"))
1130 return 0;
1131 swim3_queue = blk_init_queue(do_fd_request, &swim3_lock);
1132 if (swim3_queue == NULL) {
1133 unregister_blkdev(FLOPPY_MAJOR, "fd");
1134 return 0;
1135 }
1136 }
1137
1138 /* Now register that disk. Same comment about failure handling */
1139 i = floppy_count++;
1140 disk = disks[i] = alloc_disk(1);
1141 if (disk == NULL)
1142 return 0;
1143
1144 disk->major = FLOPPY_MAJOR;
1145 disk->first_minor = i;
1146 disk->fops = &floppy_fops;
1147 disk->private_data = &floppy_states[i];
1148 disk->queue = swim3_queue;
1149 disk->flags |= GENHD_FL_REMOVABLE;
1150 sprintf(disk->disk_name, "fd%d", i);
1151 set_capacity(disk, 2880);
1152 add_disk(disk);
1153
1154 return 0;
1155}
1156
1157static struct of_device_id swim3_match[] =
1158{
1159 {
1160 .name = "swim3",
1161 },
1162 {
1163 .compatible = "ohare-swim3"
1164 },
1165 {
1166 .compatible = "swim3"
1167 },
1168};
1169
1170static struct macio_driver swim3_driver =
1171{
1172 .name = "swim3",
1173 .match_table = swim3_match,
1174 .probe = swim3_attach,
1175#if 0
1176 .suspend = swim3_suspend,
1177 .resume = swim3_resume,
1178#endif
1179};
1180
1181
1182int swim3_init(void)
1183{
1184 macio_register_driver(&swim3_driver);
1155 return 0; 1185 return 0;
1156} 1186}
1157 1187
diff --git a/drivers/char/agp/frontend.c b/drivers/char/agp/frontend.c
index ffcf15c30e90..d9c5a9142ad1 100644
--- a/drivers/char/agp/frontend.c
+++ b/drivers/char/agp/frontend.c
@@ -1059,7 +1059,7 @@ ioctl_out:
1059 return ret_val; 1059 return ret_val;
1060} 1060}
1061 1061
1062static struct file_operations agp_fops = 1062static const struct file_operations agp_fops =
1063{ 1063{
1064 .owner = THIS_MODULE, 1064 .owner = THIS_MODULE,
1065 .llseek = no_llseek, 1065 .llseek = no_llseek,
diff --git a/drivers/char/applicom.c b/drivers/char/applicom.c
index bcc4668835b5..10a389dafd60 100644
--- a/drivers/char/applicom.c
+++ b/drivers/char/applicom.c
@@ -112,7 +112,7 @@ static int ac_ioctl(struct inode *, struct file *, unsigned int,
112 unsigned long); 112 unsigned long);
113static irqreturn_t ac_interrupt(int, void *, struct pt_regs *); 113static irqreturn_t ac_interrupt(int, void *, struct pt_regs *);
114 114
115static struct file_operations ac_fops = { 115static const struct file_operations ac_fops = {
116 .owner = THIS_MODULE, 116 .owner = THIS_MODULE,
117 .llseek = no_llseek, 117 .llseek = no_llseek,
118 .read = ac_read, 118 .read = ac_read,
diff --git a/drivers/char/cs5535_gpio.c b/drivers/char/cs5535_gpio.c
index 46d66037b917..8ce3f34cfc22 100644
--- a/drivers/char/cs5535_gpio.c
+++ b/drivers/char/cs5535_gpio.c
@@ -158,7 +158,7 @@ static int cs5535_gpio_open(struct inode *inode, struct file *file)
158 return nonseekable_open(inode, file); 158 return nonseekable_open(inode, file);
159} 159}
160 160
161static struct file_operations cs5535_gpio_fops = { 161static const struct file_operations cs5535_gpio_fops = {
162 .owner = THIS_MODULE, 162 .owner = THIS_MODULE,
163 .write = cs5535_gpio_write, 163 .write = cs5535_gpio_write,
164 .read = cs5535_gpio_read, 164 .read = cs5535_gpio_read,
diff --git a/drivers/char/ds1286.c b/drivers/char/ds1286.c
index d755cac14bc1..21c8229f5443 100644
--- a/drivers/char/ds1286.c
+++ b/drivers/char/ds1286.c
@@ -281,7 +281,7 @@ static unsigned int ds1286_poll(struct file *file, poll_table *wait)
281 * The various file operations we support. 281 * The various file operations we support.
282 */ 282 */
283 283
284static struct file_operations ds1286_fops = { 284static const struct file_operations ds1286_fops = {
285 .llseek = no_llseek, 285 .llseek = no_llseek,
286 .read = ds1286_read, 286 .read = ds1286_read,
287 .poll = ds1286_poll, 287 .poll = ds1286_poll,
diff --git a/drivers/char/ds1302.c b/drivers/char/ds1302.c
index 625e8b517005..bcdb107aa967 100644
--- a/drivers/char/ds1302.c
+++ b/drivers/char/ds1302.c
@@ -282,7 +282,7 @@ get_rtc_status(char *buf)
282 282
283/* The various file operations we support. */ 283/* The various file operations we support. */
284 284
285static struct file_operations rtc_fops = { 285static const struct file_operations rtc_fops = {
286 .owner = THIS_MODULE, 286 .owner = THIS_MODULE,
287 .ioctl = rtc_ioctl, 287 .ioctl = rtc_ioctl,
288}; 288};
diff --git a/drivers/char/ds1620.c b/drivers/char/ds1620.c
index 953e670dcd09..48cb8f0e8ebf 100644
--- a/drivers/char/ds1620.c
+++ b/drivers/char/ds1620.c
@@ -336,7 +336,7 @@ proc_therm_ds1620_read(char *buf, char **start, off_t offset,
336static struct proc_dir_entry *proc_therm_ds1620; 336static struct proc_dir_entry *proc_therm_ds1620;
337#endif 337#endif
338 338
339static struct file_operations ds1620_fops = { 339static const struct file_operations ds1620_fops = {
340 .owner = THIS_MODULE, 340 .owner = THIS_MODULE,
341 .open = nonseekable_open, 341 .open = nonseekable_open,
342 .read = ds1620_read, 342 .read = ds1620_read,
diff --git a/drivers/char/dsp56k.c b/drivers/char/dsp56k.c
index 09b413618b57..9b1bf60ffbe7 100644
--- a/drivers/char/dsp56k.c
+++ b/drivers/char/dsp56k.c
@@ -483,7 +483,7 @@ static int dsp56k_release(struct inode *inode, struct file *file)
483 return 0; 483 return 0;
484} 484}
485 485
486static struct file_operations dsp56k_fops = { 486static const struct file_operations dsp56k_fops = {
487 .owner = THIS_MODULE, 487 .owner = THIS_MODULE,
488 .read = dsp56k_read, 488 .read = dsp56k_read,
489 .write = dsp56k_write, 489 .write = dsp56k_write,
diff --git a/drivers/char/dtlk.c b/drivers/char/dtlk.c
index da2c89f1b8bc..5e82c3bad2e3 100644
--- a/drivers/char/dtlk.c
+++ b/drivers/char/dtlk.c
@@ -94,7 +94,7 @@ static int dtlk_release(struct inode *, struct file *);
94static int dtlk_ioctl(struct inode *inode, struct file *file, 94static int dtlk_ioctl(struct inode *inode, struct file *file,
95 unsigned int cmd, unsigned long arg); 95 unsigned int cmd, unsigned long arg);
96 96
97static struct file_operations dtlk_fops = 97static const struct file_operations dtlk_fops =
98{ 98{
99 .owner = THIS_MODULE, 99 .owner = THIS_MODULE,
100 .read = dtlk_read, 100 .read = dtlk_read,
diff --git a/drivers/char/efirtc.c b/drivers/char/efirtc.c
index 0090e7a4fcd3..004141d535a2 100644
--- a/drivers/char/efirtc.c
+++ b/drivers/char/efirtc.c
@@ -285,7 +285,7 @@ efi_rtc_close(struct inode *inode, struct file *file)
285 * The various file operations we support. 285 * The various file operations we support.
286 */ 286 */
287 287
288static struct file_operations efi_rtc_fops = { 288static const struct file_operations efi_rtc_fops = {
289 .owner = THIS_MODULE, 289 .owner = THIS_MODULE,
290 .ioctl = efi_rtc_ioctl, 290 .ioctl = efi_rtc_ioctl,
291 .open = efi_rtc_open, 291 .open = efi_rtc_open,
diff --git a/drivers/char/ftape/zftape/zftape-init.c b/drivers/char/ftape/zftape/zftape-init.c
index 55272566b740..164a1aa77a2f 100644
--- a/drivers/char/ftape/zftape/zftape-init.c
+++ b/drivers/char/ftape/zftape/zftape-init.c
@@ -86,7 +86,7 @@ static ssize_t zft_read (struct file *fp, char __user *buff,
86static ssize_t zft_write(struct file *fp, const char __user *buff, 86static ssize_t zft_write(struct file *fp, const char __user *buff,
87 size_t req_len, loff_t *ppos); 87 size_t req_len, loff_t *ppos);
88 88
89static struct file_operations zft_cdev = 89static const struct file_operations zft_cdev =
90{ 90{
91 .owner = THIS_MODULE, 91 .owner = THIS_MODULE,
92 .read = zft_read, 92 .read = zft_read,
diff --git a/drivers/char/genrtc.c b/drivers/char/genrtc.c
index bebd7e34f792..817dc409ac20 100644
--- a/drivers/char/genrtc.c
+++ b/drivers/char/genrtc.c
@@ -482,7 +482,7 @@ static inline int gen_rtc_proc_init(void) { return 0; }
482 * The various file operations we support. 482 * The various file operations we support.
483 */ 483 */
484 484
485static struct file_operations gen_rtc_fops = { 485static const struct file_operations gen_rtc_fops = {
486 .owner = THIS_MODULE, 486 .owner = THIS_MODULE,
487#ifdef CONFIG_GEN_RTC_X 487#ifdef CONFIG_GEN_RTC_X
488 .read = gen_rtc_read, 488 .read = gen_rtc_read,
diff --git a/drivers/char/hpet.c b/drivers/char/hpet.c
index e5643f3aa73f..8afba339f05a 100644
--- a/drivers/char/hpet.c
+++ b/drivers/char/hpet.c
@@ -553,7 +553,7 @@ hpet_ioctl_common(struct hpet_dev *devp, int cmd, unsigned long arg, int kernel)
553 return err; 553 return err;
554} 554}
555 555
556static struct file_operations hpet_fops = { 556static const struct file_operations hpet_fops = {
557 .owner = THIS_MODULE, 557 .owner = THIS_MODULE,
558 .llseek = no_llseek, 558 .llseek = no_llseek,
559 .read = hpet_read, 559 .read = hpet_read,
diff --git a/drivers/char/hvsi.c b/drivers/char/hvsi.c
index 8dc205b275e3..56612a2dca6b 100644
--- a/drivers/char/hvsi.c
+++ b/drivers/char/hvsi.c
@@ -1299,13 +1299,12 @@ static int __init hvsi_console_init(void)
1299 hp->inbuf_end = hp->inbuf; 1299 hp->inbuf_end = hp->inbuf;
1300 hp->state = HVSI_CLOSED; 1300 hp->state = HVSI_CLOSED;
1301 hp->vtermno = *vtermno; 1301 hp->vtermno = *vtermno;
1302 hp->virq = virt_irq_create_mapping(irq[0]); 1302 hp->virq = irq_create_mapping(NULL, irq[0], 0);
1303 if (hp->virq == NO_IRQ) { 1303 if (hp->virq == NO_IRQ) {
1304 printk(KERN_ERR "%s: couldn't create irq mapping for 0x%x\n", 1304 printk(KERN_ERR "%s: couldn't create irq mapping for 0x%x\n",
1305 __FUNCTION__, hp->virq); 1305 __FUNCTION__, irq[0]);
1306 continue; 1306 continue;
1307 } else 1307 }
1308 hp->virq = irq_offset_up(hp->virq);
1309 1308
1310 hvsi_count++; 1309 hvsi_count++;
1311 } 1310 }
diff --git a/drivers/char/hw_random/core.c b/drivers/char/hw_random/core.c
index 88b026639f10..154a81d328c1 100644
--- a/drivers/char/hw_random/core.c
+++ b/drivers/char/hw_random/core.c
@@ -149,7 +149,7 @@ out:
149} 149}
150 150
151 151
152static struct file_operations rng_chrdev_ops = { 152static const struct file_operations rng_chrdev_ops = {
153 .owner = THIS_MODULE, 153 .owner = THIS_MODULE,
154 .open = rng_dev_open, 154 .open = rng_dev_open,
155 .read = rng_dev_read, 155 .read = rng_dev_read,
diff --git a/drivers/char/i8k.c b/drivers/char/i8k.c
index f3c3aaf4560e..353d9f3cf8d7 100644
--- a/drivers/char/i8k.c
+++ b/drivers/char/i8k.c
@@ -80,7 +80,7 @@ static int i8k_open_fs(struct inode *inode, struct file *file);
80static int i8k_ioctl(struct inode *, struct file *, unsigned int, 80static int i8k_ioctl(struct inode *, struct file *, unsigned int,
81 unsigned long); 81 unsigned long);
82 82
83static struct file_operations i8k_fops = { 83static const struct file_operations i8k_fops = {
84 .open = i8k_open_fs, 84 .open = i8k_open_fs,
85 .read = seq_read, 85 .read = seq_read,
86 .llseek = seq_lseek, 86 .llseek = seq_lseek,
diff --git a/drivers/char/ip2/ip2main.c b/drivers/char/ip2/ip2main.c
index a4200a2b0811..518ece7ac656 100644
--- a/drivers/char/ip2/ip2main.c
+++ b/drivers/char/ip2/ip2main.c
@@ -233,7 +233,7 @@ static void *DevTableMem[IP2_MAX_BOARDS];
233/* This is the driver descriptor for the ip2ipl device, which is used to 233/* This is the driver descriptor for the ip2ipl device, which is used to
234 * download the loadware to the boards. 234 * download the loadware to the boards.
235 */ 235 */
236static struct file_operations ip2_ipl = { 236static const struct file_operations ip2_ipl = {
237 .owner = THIS_MODULE, 237 .owner = THIS_MODULE,
238 .read = ip2_ipl_read, 238 .read = ip2_ipl_read,
239 .write = ip2_ipl_write, 239 .write = ip2_ipl_write,
diff --git a/drivers/char/ip27-rtc.c b/drivers/char/ip27-rtc.c
index 3acdac3c967e..a48da02aad2f 100644
--- a/drivers/char/ip27-rtc.c
+++ b/drivers/char/ip27-rtc.c
@@ -196,7 +196,7 @@ static int rtc_release(struct inode *inode, struct file *file)
196 * The various file operations we support. 196 * The various file operations we support.
197 */ 197 */
198 198
199static struct file_operations rtc_fops = { 199static const struct file_operations rtc_fops = {
200 .owner = THIS_MODULE, 200 .owner = THIS_MODULE,
201 .ioctl = rtc_ioctl, 201 .ioctl = rtc_ioctl,
202 .open = rtc_open, 202 .open = rtc_open,
diff --git a/drivers/char/ipmi/ipmi_devintf.c b/drivers/char/ipmi/ipmi_devintf.c
index 2fc894fef1cb..68d7c61a864e 100644
--- a/drivers/char/ipmi/ipmi_devintf.c
+++ b/drivers/char/ipmi/ipmi_devintf.c
@@ -765,7 +765,7 @@ static long compat_ipmi_ioctl(struct file *filep, unsigned int cmd,
765} 765}
766#endif 766#endif
767 767
768static struct file_operations ipmi_fops = { 768static const struct file_operations ipmi_fops = {
769 .owner = THIS_MODULE, 769 .owner = THIS_MODULE,
770 .ioctl = ipmi_ioctl, 770 .ioctl = ipmi_ioctl,
771#ifdef CONFIG_COMPAT 771#ifdef CONFIG_COMPAT
diff --git a/drivers/char/ipmi/ipmi_watchdog.c b/drivers/char/ipmi/ipmi_watchdog.c
index 74a889c58333..accaaf1a6b69 100644
--- a/drivers/char/ipmi/ipmi_watchdog.c
+++ b/drivers/char/ipmi/ipmi_watchdog.c
@@ -807,7 +807,7 @@ static int ipmi_close(struct inode *ino, struct file *filep)
807 return 0; 807 return 0;
808} 808}
809 809
810static struct file_operations ipmi_wdog_fops = { 810static const struct file_operations ipmi_wdog_fops = {
811 .owner = THIS_MODULE, 811 .owner = THIS_MODULE,
812 .read = ipmi_read, 812 .read = ipmi_read,
813 .poll = ipmi_poll, 813 .poll = ipmi_poll,
diff --git a/drivers/char/istallion.c b/drivers/char/istallion.c
index fbce2f0669d6..84dfc4278139 100644
--- a/drivers/char/istallion.c
+++ b/drivers/char/istallion.c
@@ -748,7 +748,7 @@ static int stli_initpcibrd(int brdtype, struct pci_dev *devp);
748 * will give access to the shared memory on the Stallion intelligent 748 * will give access to the shared memory on the Stallion intelligent
749 * board. This is also a very useful debugging tool. 749 * board. This is also a very useful debugging tool.
750 */ 750 */
751static struct file_operations stli_fsiomem = { 751static const struct file_operations stli_fsiomem = {
752 .owner = THIS_MODULE, 752 .owner = THIS_MODULE,
753 .read = stli_memread, 753 .read = stli_memread,
754 .write = stli_memwrite, 754 .write = stli_memwrite,
diff --git a/drivers/char/ite_gpio.c b/drivers/char/ite_gpio.c
index 747ba45e50e5..cde562d70c4f 100644
--- a/drivers/char/ite_gpio.c
+++ b/drivers/char/ite_gpio.c
@@ -357,7 +357,7 @@ DEB(printk("interrupt 0x%x %d\n",ITE_GPAISR, i));
357 } 357 }
358} 358}
359 359
360static struct file_operations ite_gpio_fops = { 360static const struct file_operations ite_gpio_fops = {
361 .owner = THIS_MODULE, 361 .owner = THIS_MODULE,
362 .ioctl = ite_gpio_ioctl, 362 .ioctl = ite_gpio_ioctl,
363 .open = ite_gpio_open, 363 .open = ite_gpio_open,
diff --git a/drivers/char/lcd.c b/drivers/char/lcd.c
index 7d49b241de56..da601fd6c07a 100644
--- a/drivers/char/lcd.c
+++ b/drivers/char/lcd.c
@@ -598,7 +598,7 @@ static ssize_t lcd_read(struct file *file, char *buf,
598 * The various file operations we support. 598 * The various file operations we support.
599 */ 599 */
600 600
601static struct file_operations lcd_fops = { 601static const struct file_operations lcd_fops = {
602 .read = lcd_read, 602 .read = lcd_read,
603 .ioctl = lcd_ioctl, 603 .ioctl = lcd_ioctl,
604 .open = lcd_open, 604 .open = lcd_open,
diff --git a/drivers/char/lp.c b/drivers/char/lp.c
index 582cdbdb0c42..f875fda3b089 100644
--- a/drivers/char/lp.c
+++ b/drivers/char/lp.c
@@ -666,7 +666,7 @@ static int lp_ioctl(struct inode *inode, struct file *file,
666 return retval; 666 return retval;
667} 667}
668 668
669static struct file_operations lp_fops = { 669static const struct file_operations lp_fops = {
670 .owner = THIS_MODULE, 670 .owner = THIS_MODULE,
671 .write = lp_write, 671 .write = lp_write,
672 .ioctl = lp_ioctl, 672 .ioctl = lp_ioctl,
diff --git a/drivers/char/mem.c b/drivers/char/mem.c
index 70f3954d6dfd..e97c32ceb796 100644
--- a/drivers/char/mem.c
+++ b/drivers/char/mem.c
@@ -776,7 +776,7 @@ static int open_port(struct inode * inode, struct file * filp)
776#define open_kmem open_mem 776#define open_kmem open_mem
777#define open_oldmem open_mem 777#define open_oldmem open_mem
778 778
779static struct file_operations mem_fops = { 779static const struct file_operations mem_fops = {
780 .llseek = memory_lseek, 780 .llseek = memory_lseek,
781 .read = read_mem, 781 .read = read_mem,
782 .write = write_mem, 782 .write = write_mem,
@@ -784,7 +784,7 @@ static struct file_operations mem_fops = {
784 .open = open_mem, 784 .open = open_mem,
785}; 785};
786 786
787static struct file_operations kmem_fops = { 787static const struct file_operations kmem_fops = {
788 .llseek = memory_lseek, 788 .llseek = memory_lseek,
789 .read = read_kmem, 789 .read = read_kmem,
790 .write = write_kmem, 790 .write = write_kmem,
@@ -792,7 +792,7 @@ static struct file_operations kmem_fops = {
792 .open = open_kmem, 792 .open = open_kmem,
793}; 793};
794 794
795static struct file_operations null_fops = { 795static const struct file_operations null_fops = {
796 .llseek = null_lseek, 796 .llseek = null_lseek,
797 .read = read_null, 797 .read = read_null,
798 .write = write_null, 798 .write = write_null,
@@ -800,7 +800,7 @@ static struct file_operations null_fops = {
800}; 800};
801 801
802#if defined(CONFIG_ISA) || !defined(__mc68000__) 802#if defined(CONFIG_ISA) || !defined(__mc68000__)
803static struct file_operations port_fops = { 803static const struct file_operations port_fops = {
804 .llseek = memory_lseek, 804 .llseek = memory_lseek,
805 .read = read_port, 805 .read = read_port,
806 .write = write_port, 806 .write = write_port,
@@ -808,7 +808,7 @@ static struct file_operations port_fops = {
808}; 808};
809#endif 809#endif
810 810
811static struct file_operations zero_fops = { 811static const struct file_operations zero_fops = {
812 .llseek = zero_lseek, 812 .llseek = zero_lseek,
813 .read = read_zero, 813 .read = read_zero,
814 .write = write_zero, 814 .write = write_zero,
@@ -819,14 +819,14 @@ static struct backing_dev_info zero_bdi = {
819 .capabilities = BDI_CAP_MAP_COPY, 819 .capabilities = BDI_CAP_MAP_COPY,
820}; 820};
821 821
822static struct file_operations full_fops = { 822static const struct file_operations full_fops = {
823 .llseek = full_lseek, 823 .llseek = full_lseek,
824 .read = read_full, 824 .read = read_full,
825 .write = write_full, 825 .write = write_full,
826}; 826};
827 827
828#ifdef CONFIG_CRASH_DUMP 828#ifdef CONFIG_CRASH_DUMP
829static struct file_operations oldmem_fops = { 829static const struct file_operations oldmem_fops = {
830 .read = read_oldmem, 830 .read = read_oldmem,
831 .open = open_oldmem, 831 .open = open_oldmem,
832}; 832};
@@ -853,7 +853,7 @@ static ssize_t kmsg_write(struct file * file, const char __user * buf,
853 return ret; 853 return ret;
854} 854}
855 855
856static struct file_operations kmsg_fops = { 856static const struct file_operations kmsg_fops = {
857 .write = kmsg_write, 857 .write = kmsg_write,
858}; 858};
859 859
@@ -903,7 +903,7 @@ static int memory_open(struct inode * inode, struct file * filp)
903 return 0; 903 return 0;
904} 904}
905 905
906static struct file_operations memory_fops = { 906static const struct file_operations memory_fops = {
907 .open = memory_open, /* just a selector for the real open */ 907 .open = memory_open, /* just a selector for the real open */
908}; 908};
909 909
diff --git a/drivers/char/misc.c b/drivers/char/misc.c
index d5fa19da330b..62ebe09656e3 100644
--- a/drivers/char/misc.c
+++ b/drivers/char/misc.c
@@ -113,7 +113,7 @@ static int misc_seq_open(struct inode *inode, struct file *file)
113 return seq_open(file, &misc_seq_ops); 113 return seq_open(file, &misc_seq_ops);
114} 114}
115 115
116static struct file_operations misc_proc_fops = { 116static const struct file_operations misc_proc_fops = {
117 .owner = THIS_MODULE, 117 .owner = THIS_MODULE,
118 .open = misc_seq_open, 118 .open = misc_seq_open,
119 .read = seq_read, 119 .read = seq_read,
@@ -176,7 +176,7 @@ fail:
176 */ 176 */
177static struct class *misc_class; 177static struct class *misc_class;
178 178
179static struct file_operations misc_fops = { 179static const struct file_operations misc_fops = {
180 .owner = THIS_MODULE, 180 .owner = THIS_MODULE,
181 .open = misc_open, 181 .open = misc_open,
182}; 182};
diff --git a/drivers/char/mmtimer.c b/drivers/char/mmtimer.c
index 70b774ff5aa4..1f0f2b6dae26 100644
--- a/drivers/char/mmtimer.c
+++ b/drivers/char/mmtimer.c
@@ -63,7 +63,7 @@ static int mmtimer_mmap(struct file *file, struct vm_area_struct *vma);
63 */ 63 */
64static unsigned long mmtimer_femtoperiod = 0; 64static unsigned long mmtimer_femtoperiod = 0;
65 65
66static struct file_operations mmtimer_fops = { 66static const struct file_operations mmtimer_fops = {
67 .owner = THIS_MODULE, 67 .owner = THIS_MODULE,
68 .mmap = mmtimer_mmap, 68 .mmap = mmtimer_mmap,
69 .ioctl = mmtimer_ioctl, 69 .ioctl = mmtimer_ioctl,
diff --git a/drivers/char/mwave/mwavedd.c b/drivers/char/mwave/mwavedd.c
index d3ba2f860ef0..39a2e661ff55 100644
--- a/drivers/char/mwave/mwavedd.c
+++ b/drivers/char/mwave/mwavedd.c
@@ -454,7 +454,7 @@ static int register_serial_portandirq(unsigned int port, int irq)
454} 454}
455 455
456 456
457static struct file_operations mwave_fops = { 457static const struct file_operations mwave_fops = {
458 .owner = THIS_MODULE, 458 .owner = THIS_MODULE,
459 .read = mwave_read, 459 .read = mwave_read,
460 .write = mwave_write, 460 .write = mwave_write,
diff --git a/drivers/char/nvram.c b/drivers/char/nvram.c
index 8c5f102622b6..a39f19c35a6a 100644
--- a/drivers/char/nvram.c
+++ b/drivers/char/nvram.c
@@ -437,7 +437,7 @@ nvram_read_proc(char *buffer, char **start, off_t offset,
437 437
438#endif /* CONFIG_PROC_FS */ 438#endif /* CONFIG_PROC_FS */
439 439
440static struct file_operations nvram_fops = { 440static const struct file_operations nvram_fops = {
441 .owner = THIS_MODULE, 441 .owner = THIS_MODULE,
442 .llseek = nvram_llseek, 442 .llseek = nvram_llseek,
443 .read = nvram_read, 443 .read = nvram_read,
diff --git a/drivers/char/nwbutton.c b/drivers/char/nwbutton.c
index f240a104d250..7c57ebfa8640 100644
--- a/drivers/char/nwbutton.c
+++ b/drivers/char/nwbutton.c
@@ -183,7 +183,7 @@ static int button_read (struct file *filp, char __user *buffer,
183 * attempts to perform these operations on the device. 183 * attempts to perform these operations on the device.
184 */ 184 */
185 185
186static struct file_operations button_fops = { 186static const struct file_operations button_fops = {
187 .owner = THIS_MODULE, 187 .owner = THIS_MODULE,
188 .read = button_read, 188 .read = button_read,
189}; 189};
diff --git a/drivers/char/nwflash.c b/drivers/char/nwflash.c
index 8865387d3448..206cf6f50695 100644
--- a/drivers/char/nwflash.c
+++ b/drivers/char/nwflash.c
@@ -642,7 +642,7 @@ static void kick_open(void)
642 udelay(25); 642 udelay(25);
643} 643}
644 644
645static struct file_operations flash_fops = 645static const struct file_operations flash_fops =
646{ 646{
647 .owner = THIS_MODULE, 647 .owner = THIS_MODULE,
648 .llseek = flash_llseek, 648 .llseek = flash_llseek,
diff --git a/drivers/char/pc8736x_gpio.c b/drivers/char/pc8736x_gpio.c
index c860de6a6fde..4005ee0aa11e 100644
--- a/drivers/char/pc8736x_gpio.c
+++ b/drivers/char/pc8736x_gpio.c
@@ -236,7 +236,7 @@ static int pc8736x_gpio_open(struct inode *inode, struct file *file)
236 return nonseekable_open(inode, file); 236 return nonseekable_open(inode, file);
237} 237}
238 238
239static struct file_operations pc8736x_gpio_fops = { 239static const struct file_operations pc8736x_gpio_fops = {
240 .owner = THIS_MODULE, 240 .owner = THIS_MODULE,
241 .open = pc8736x_gpio_open, 241 .open = pc8736x_gpio_open,
242 .write = nsc_gpio_write, 242 .write = nsc_gpio_write,
diff --git a/drivers/char/pcmcia/cm4000_cs.c b/drivers/char/pcmcia/cm4000_cs.c
index 31c8a21f9d87..50d20aafeb18 100644
--- a/drivers/char/pcmcia/cm4000_cs.c
+++ b/drivers/char/pcmcia/cm4000_cs.c
@@ -1938,7 +1938,7 @@ static void cm4000_detach(struct pcmcia_device *link)
1938 return; 1938 return;
1939} 1939}
1940 1940
1941static struct file_operations cm4000_fops = { 1941static const struct file_operations cm4000_fops = {
1942 .owner = THIS_MODULE, 1942 .owner = THIS_MODULE,
1943 .read = cmm_read, 1943 .read = cmm_read,
1944 .write = cmm_write, 1944 .write = cmm_write,
diff --git a/drivers/char/pcmcia/cm4040_cs.c b/drivers/char/pcmcia/cm4040_cs.c
index 47a8465bf95b..55cf4be42976 100644
--- a/drivers/char/pcmcia/cm4040_cs.c
+++ b/drivers/char/pcmcia/cm4040_cs.c
@@ -688,7 +688,7 @@ static void reader_detach(struct pcmcia_device *link)
688 return; 688 return;
689} 689}
690 690
691static struct file_operations reader_fops = { 691static const struct file_operations reader_fops = {
692 .owner = THIS_MODULE, 692 .owner = THIS_MODULE,
693 .read = cm4040_read, 693 .read = cm4040_read,
694 .write = cm4040_write, 694 .write = cm4040_write,
diff --git a/drivers/char/ppdev.c b/drivers/char/ppdev.c
index 24231d9743dc..520d2cf82bc0 100644
--- a/drivers/char/ppdev.c
+++ b/drivers/char/ppdev.c
@@ -739,7 +739,7 @@ static unsigned int pp_poll (struct file * file, poll_table * wait)
739 739
740static struct class *ppdev_class; 740static struct class *ppdev_class;
741 741
742static struct file_operations pp_fops = { 742static const struct file_operations pp_fops = {
743 .owner = THIS_MODULE, 743 .owner = THIS_MODULE,
744 .llseek = no_llseek, 744 .llseek = no_llseek,
745 .read = pp_read, 745 .read = pp_read,
diff --git a/drivers/char/random.c b/drivers/char/random.c
index 164bddae047f..4c3a5ca9d8f7 100644
--- a/drivers/char/random.c
+++ b/drivers/char/random.c
@@ -416,7 +416,7 @@ static struct entropy_store input_pool = {
416 .poolinfo = &poolinfo_table[0], 416 .poolinfo = &poolinfo_table[0],
417 .name = "input", 417 .name = "input",
418 .limit = 1, 418 .limit = 1,
419 .lock = SPIN_LOCK_UNLOCKED, 419 .lock = __SPIN_LOCK_UNLOCKED(&input_pool.lock),
420 .pool = input_pool_data 420 .pool = input_pool_data
421}; 421};
422 422
@@ -425,7 +425,7 @@ static struct entropy_store blocking_pool = {
425 .name = "blocking", 425 .name = "blocking",
426 .limit = 1, 426 .limit = 1,
427 .pull = &input_pool, 427 .pull = &input_pool,
428 .lock = SPIN_LOCK_UNLOCKED, 428 .lock = __SPIN_LOCK_UNLOCKED(&blocking_pool.lock),
429 .pool = blocking_pool_data 429 .pool = blocking_pool_data
430}; 430};
431 431
@@ -433,7 +433,7 @@ static struct entropy_store nonblocking_pool = {
433 .poolinfo = &poolinfo_table[1], 433 .poolinfo = &poolinfo_table[1],
434 .name = "nonblocking", 434 .name = "nonblocking",
435 .pull = &input_pool, 435 .pull = &input_pool,
436 .lock = SPIN_LOCK_UNLOCKED, 436 .lock = __SPIN_LOCK_UNLOCKED(&nonblocking_pool.lock),
437 .pool = nonblocking_pool_data 437 .pool = nonblocking_pool_data
438}; 438};
439 439
diff --git a/drivers/char/raw.c b/drivers/char/raw.c
index 9bf97c5e38c0..579868af4a54 100644
--- a/drivers/char/raw.c
+++ b/drivers/char/raw.c
@@ -30,7 +30,7 @@ struct raw_device_data {
30static struct class *raw_class; 30static struct class *raw_class;
31static struct raw_device_data raw_devices[MAX_RAW_MINORS]; 31static struct raw_device_data raw_devices[MAX_RAW_MINORS];
32static DEFINE_MUTEX(raw_mutex); 32static DEFINE_MUTEX(raw_mutex);
33static struct file_operations raw_ctl_fops; /* forward declaration */ 33static const struct file_operations raw_ctl_fops; /* forward declaration */
34 34
35/* 35/*
36 * Open/close code for raw IO. 36 * Open/close code for raw IO.
@@ -261,7 +261,7 @@ static ssize_t raw_file_aio_write(struct kiocb *iocb, const char __user *buf,
261} 261}
262 262
263 263
264static struct file_operations raw_fops = { 264static const struct file_operations raw_fops = {
265 .read = generic_file_read, 265 .read = generic_file_read,
266 .aio_read = generic_file_aio_read, 266 .aio_read = generic_file_aio_read,
267 .write = raw_file_write, 267 .write = raw_file_write,
@@ -274,7 +274,7 @@ static struct file_operations raw_fops = {
274 .owner = THIS_MODULE, 274 .owner = THIS_MODULE,
275}; 275};
276 276
277static struct file_operations raw_ctl_fops = { 277static const struct file_operations raw_ctl_fops = {
278 .ioctl = raw_ctl_ioctl, 278 .ioctl = raw_ctl_ioctl,
279 .open = raw_open, 279 .open = raw_open,
280 .owner = THIS_MODULE, 280 .owner = THIS_MODULE,
diff --git a/drivers/char/rio/rio_linux.c b/drivers/char/rio/rio_linux.c
index 3afc6a47ebbc..3fa80aaf4527 100644
--- a/drivers/char/rio/rio_linux.c
+++ b/drivers/char/rio/rio_linux.c
@@ -243,7 +243,7 @@ static struct real_driver rio_real_driver = {
243 * 243 *
244 */ 244 */
245 245
246static struct file_operations rio_fw_fops = { 246static const struct file_operations rio_fw_fops = {
247 .owner = THIS_MODULE, 247 .owner = THIS_MODULE,
248 .ioctl = rio_fw_ioctl, 248 .ioctl = rio_fw_ioctl,
249}; 249};
diff --git a/drivers/char/rtc.c b/drivers/char/rtc.c
index aefac4ac0bf5..cc7bd1a3095b 100644
--- a/drivers/char/rtc.c
+++ b/drivers/char/rtc.c
@@ -877,7 +877,7 @@ int rtc_control(rtc_task_t *task, unsigned int cmd, unsigned long arg)
877 * The various file operations we support. 877 * The various file operations we support.
878 */ 878 */
879 879
880static struct file_operations rtc_fops = { 880static const struct file_operations rtc_fops = {
881 .owner = THIS_MODULE, 881 .owner = THIS_MODULE,
882 .llseek = no_llseek, 882 .llseek = no_llseek,
883 .read = rtc_read, 883 .read = rtc_read,
@@ -896,7 +896,7 @@ static struct miscdevice rtc_dev = {
896 .fops = &rtc_fops, 896 .fops = &rtc_fops,
897}; 897};
898 898
899static struct file_operations rtc_proc_fops = { 899static const struct file_operations rtc_proc_fops = {
900 .owner = THIS_MODULE, 900 .owner = THIS_MODULE,
901 .open = rtc_proc_open, 901 .open = rtc_proc_open,
902 .read = seq_read, 902 .read = seq_read,
diff --git a/drivers/char/scx200_gpio.c b/drivers/char/scx200_gpio.c
index 45083e5dd23b..425c58719db6 100644
--- a/drivers/char/scx200_gpio.c
+++ b/drivers/char/scx200_gpio.c
@@ -63,7 +63,7 @@ static int scx200_gpio_release(struct inode *inode, struct file *file)
63} 63}
64 64
65 65
66static struct file_operations scx200_gpio_fops = { 66static const struct file_operations scx200_gpio_fops = {
67 .owner = THIS_MODULE, 67 .owner = THIS_MODULE,
68 .write = nsc_gpio_write, 68 .write = nsc_gpio_write,
69 .read = nsc_gpio_read, 69 .read = nsc_gpio_read,
diff --git a/drivers/char/snsc.c b/drivers/char/snsc.c
index 203240b6c08f..afc6eda602f7 100644
--- a/drivers/char/snsc.c
+++ b/drivers/char/snsc.c
@@ -347,7 +347,7 @@ scdrv_poll(struct file *file, struct poll_table_struct *wait)
347 return mask; 347 return mask;
348} 348}
349 349
350static struct file_operations scdrv_fops = { 350static const struct file_operations scdrv_fops = {
351 .owner = THIS_MODULE, 351 .owner = THIS_MODULE,
352 .read = scdrv_read, 352 .read = scdrv_read,
353 .write = scdrv_write, 353 .write = scdrv_write,
diff --git a/drivers/char/sonypi.c b/drivers/char/sonypi.c
index 45508a039508..d4e434d694b7 100644
--- a/drivers/char/sonypi.c
+++ b/drivers/char/sonypi.c
@@ -1106,7 +1106,7 @@ static int sonypi_misc_ioctl(struct inode *ip, struct file *fp,
1106 return ret; 1106 return ret;
1107} 1107}
1108 1108
1109static struct file_operations sonypi_misc_fops = { 1109static const struct file_operations sonypi_misc_fops = {
1110 .owner = THIS_MODULE, 1110 .owner = THIS_MODULE,
1111 .read = sonypi_misc_read, 1111 .read = sonypi_misc_read,
1112 .poll = sonypi_misc_poll, 1112 .poll = sonypi_misc_poll,
diff --git a/drivers/char/stallion.c b/drivers/char/stallion.c
index ed7b8eaf0367..3beb2203d24b 100644
--- a/drivers/char/stallion.c
+++ b/drivers/char/stallion.c
@@ -707,7 +707,7 @@ static unsigned int sc26198_baudtable[] = {
707 * Define the driver info for a user level control device. Used mainly 707 * Define the driver info for a user level control device. Used mainly
708 * to get at port stats - only not using the port device itself. 708 * to get at port stats - only not using the port device itself.
709 */ 709 */
710static struct file_operations stl_fsiomem = { 710static const struct file_operations stl_fsiomem = {
711 .owner = THIS_MODULE, 711 .owner = THIS_MODULE,
712 .ioctl = stl_memioctl, 712 .ioctl = stl_memioctl,
713}; 713};
diff --git a/drivers/char/sx.c b/drivers/char/sx.c
index 45c193aa11db..e1cd2bc4b1e4 100644
--- a/drivers/char/sx.c
+++ b/drivers/char/sx.c
@@ -410,7 +410,7 @@ static struct real_driver sx_real_driver = {
410 * 410 *
411 */ 411 */
412 412
413static struct file_operations sx_fw_fops = { 413static const struct file_operations sx_fw_fops = {
414 .owner = THIS_MODULE, 414 .owner = THIS_MODULE,
415 .ioctl = sx_fw_ioctl, 415 .ioctl = sx_fw_ioctl,
416}; 416};
diff --git a/drivers/char/sysrq.c b/drivers/char/sysrq.c
index a064ee9181c0..ee3ca8f1768e 100644
--- a/drivers/char/sysrq.c
+++ b/drivers/char/sysrq.c
@@ -147,12 +147,13 @@ static struct sysrq_key_op sysrq_mountro_op = {
147 .enable_mask = SYSRQ_ENABLE_REMOUNT, 147 .enable_mask = SYSRQ_ENABLE_REMOUNT,
148}; 148};
149 149
150#ifdef CONFIG_DEBUG_MUTEXES 150#ifdef CONFIG_LOCKDEP
151static void sysrq_handle_showlocks(int key, struct pt_regs *pt_regs, 151static void sysrq_handle_showlocks(int key, struct pt_regs *pt_regs,
152 struct tty_struct *tty) 152 struct tty_struct *tty)
153{ 153{
154 mutex_debug_show_all_locks(); 154 debug_show_all_locks();
155} 155}
156
156static struct sysrq_key_op sysrq_showlocks_op = { 157static struct sysrq_key_op sysrq_showlocks_op = {
157 .handler = sysrq_handle_showlocks, 158 .handler = sysrq_handle_showlocks,
158 .help_msg = "show-all-locks(D)", 159 .help_msg = "show-all-locks(D)",
diff --git a/drivers/char/tb0219.c b/drivers/char/tb0219.c
index a80c83210872..bb1bad4c18f9 100644
--- a/drivers/char/tb0219.c
+++ b/drivers/char/tb0219.c
@@ -255,7 +255,7 @@ static int tanbac_tb0219_release(struct inode *inode, struct file *file)
255 return 0; 255 return 0;
256} 256}
257 257
258static struct file_operations tb0219_fops = { 258static const struct file_operations tb0219_fops = {
259 .owner = THIS_MODULE, 259 .owner = THIS_MODULE,
260 .read = tanbac_tb0219_read, 260 .read = tanbac_tb0219_read,
261 .write = tanbac_tb0219_write, 261 .write = tanbac_tb0219_write,
diff --git a/drivers/char/tipar.c b/drivers/char/tipar.c
index e0633a119d29..d30dc09dbbc9 100644
--- a/drivers/char/tipar.c
+++ b/drivers/char/tipar.c
@@ -381,7 +381,7 @@ tipar_ioctl(struct inode *inode, struct file *file,
381 381
382/* ----- kernel module registering ------------------------------------ */ 382/* ----- kernel module registering ------------------------------------ */
383 383
384static struct file_operations tipar_fops = { 384static const struct file_operations tipar_fops = {
385 .owner = THIS_MODULE, 385 .owner = THIS_MODULE,
386 .llseek = no_llseek, 386 .llseek = no_llseek,
387 .read = tipar_read, 387 .read = tipar_read,
diff --git a/drivers/char/tlclk.c b/drivers/char/tlclk.c
index 952b829e2cb4..d2c5ba4e83b8 100644
--- a/drivers/char/tlclk.c
+++ b/drivers/char/tlclk.c
@@ -247,7 +247,7 @@ static ssize_t tlclk_write(struct file *filp, const char __user *buf, size_t cou
247 return 0; 247 return 0;
248} 248}
249 249
250static struct file_operations tlclk_fops = { 250static const struct file_operations tlclk_fops = {
251 .read = tlclk_read, 251 .read = tlclk_read,
252 .write = tlclk_write, 252 .write = tlclk_write,
253 .open = tlclk_open, 253 .open = tlclk_open,
diff --git a/drivers/char/toshiba.c b/drivers/char/toshiba.c
index e2fb234dee40..dd36fd04a842 100644
--- a/drivers/char/toshiba.c
+++ b/drivers/char/toshiba.c
@@ -92,7 +92,7 @@ static int tosh_ioctl(struct inode *, struct file *, unsigned int,
92 unsigned long); 92 unsigned long);
93 93
94 94
95static struct file_operations tosh_fops = { 95static const struct file_operations tosh_fops = {
96 .owner = THIS_MODULE, 96 .owner = THIS_MODULE,
97 .ioctl = tosh_ioctl, 97 .ioctl = tosh_ioctl,
98}; 98};
diff --git a/drivers/char/tpm/tpm_atmel.c b/drivers/char/tpm/tpm_atmel.c
index 58a258cec153..ad8ffe49256f 100644
--- a/drivers/char/tpm/tpm_atmel.c
+++ b/drivers/char/tpm/tpm_atmel.c
@@ -116,7 +116,7 @@ static u8 tpm_atml_status(struct tpm_chip *chip)
116 return ioread8(chip->vendor.iobase + 1); 116 return ioread8(chip->vendor.iobase + 1);
117} 117}
118 118
119static struct file_operations atmel_ops = { 119static const struct file_operations atmel_ops = {
120 .owner = THIS_MODULE, 120 .owner = THIS_MODULE,
121 .llseek = no_llseek, 121 .llseek = no_llseek,
122 .open = tpm_open, 122 .open = tpm_open,
diff --git a/drivers/char/tpm/tpm_infineon.c b/drivers/char/tpm/tpm_infineon.c
index adfff21beb21..1353b5a6bae8 100644
--- a/drivers/char/tpm/tpm_infineon.c
+++ b/drivers/char/tpm/tpm_infineon.c
@@ -338,7 +338,7 @@ static struct attribute *inf_attrs[] = {
338 338
339static struct attribute_group inf_attr_grp = {.attrs = inf_attrs }; 339static struct attribute_group inf_attr_grp = {.attrs = inf_attrs };
340 340
341static struct file_operations inf_ops = { 341static const struct file_operations inf_ops = {
342 .owner = THIS_MODULE, 342 .owner = THIS_MODULE,
343 .llseek = no_llseek, 343 .llseek = no_llseek,
344 .open = tpm_open, 344 .open = tpm_open,
diff --git a/drivers/char/tpm/tpm_nsc.c b/drivers/char/tpm/tpm_nsc.c
index 4c8bc06c7d95..26287aace87d 100644
--- a/drivers/char/tpm/tpm_nsc.c
+++ b/drivers/char/tpm/tpm_nsc.c
@@ -226,7 +226,7 @@ static u8 tpm_nsc_status(struct tpm_chip *chip)
226 return inb(chip->vendor.base + NSC_STATUS); 226 return inb(chip->vendor.base + NSC_STATUS);
227} 227}
228 228
229static struct file_operations nsc_ops = { 229static const struct file_operations nsc_ops = {
230 .owner = THIS_MODULE, 230 .owner = THIS_MODULE,
231 .llseek = no_llseek, 231 .llseek = no_llseek,
232 .open = tpm_open, 232 .open = tpm_open,
diff --git a/drivers/char/tpm/tpm_tis.c b/drivers/char/tpm/tpm_tis.c
index abb0f2aeae66..3232b1932597 100644
--- a/drivers/char/tpm/tpm_tis.c
+++ b/drivers/char/tpm/tpm_tis.c
@@ -330,7 +330,7 @@ out_err:
330 return rc; 330 return rc;
331} 331}
332 332
333static struct file_operations tis_ops = { 333static const struct file_operations tis_ops = {
334 .owner = THIS_MODULE, 334 .owner = THIS_MODULE,
335 .llseek = no_llseek, 335 .llseek = no_llseek,
336 .open = tpm_open, 336 .open = tpm_open,
diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c
index 615e934da05f..bfdb90242a90 100644
--- a/drivers/char/tty_io.c
+++ b/drivers/char/tty_io.c
@@ -912,7 +912,7 @@ static int hung_up_tty_ioctl(struct inode * inode, struct file * file,
912 return cmd == TIOCSPGRP ? -ENOTTY : -EIO; 912 return cmd == TIOCSPGRP ? -ENOTTY : -EIO;
913} 913}
914 914
915static struct file_operations tty_fops = { 915static const struct file_operations tty_fops = {
916 .llseek = no_llseek, 916 .llseek = no_llseek,
917 .read = tty_read, 917 .read = tty_read,
918 .write = tty_write, 918 .write = tty_write,
@@ -924,7 +924,7 @@ static struct file_operations tty_fops = {
924}; 924};
925 925
926#ifdef CONFIG_UNIX98_PTYS 926#ifdef CONFIG_UNIX98_PTYS
927static struct file_operations ptmx_fops = { 927static const struct file_operations ptmx_fops = {
928 .llseek = no_llseek, 928 .llseek = no_llseek,
929 .read = tty_read, 929 .read = tty_read,
930 .write = tty_write, 930 .write = tty_write,
@@ -936,7 +936,7 @@ static struct file_operations ptmx_fops = {
936}; 936};
937#endif 937#endif
938 938
939static struct file_operations console_fops = { 939static const struct file_operations console_fops = {
940 .llseek = no_llseek, 940 .llseek = no_llseek,
941 .read = tty_read, 941 .read = tty_read,
942 .write = redirected_tty_write, 942 .write = redirected_tty_write,
@@ -947,7 +947,7 @@ static struct file_operations console_fops = {
947 .fasync = tty_fasync, 947 .fasync = tty_fasync,
948}; 948};
949 949
950static struct file_operations hung_up_tty_fops = { 950static const struct file_operations hung_up_tty_fops = {
951 .llseek = no_llseek, 951 .llseek = no_llseek,
952 .read = hung_up_tty_read, 952 .read = hung_up_tty_read,
953 .write = hung_up_tty_write, 953 .write = hung_up_tty_write,
@@ -2336,7 +2336,7 @@ static int fionbio(struct file *file, int __user *p)
2336 2336
2337static int tiocsctty(struct tty_struct *tty, int arg) 2337static int tiocsctty(struct tty_struct *tty, int arg)
2338{ 2338{
2339 task_t *p; 2339 struct task_struct *p;
2340 2340
2341 if (current->signal->leader && 2341 if (current->signal->leader &&
2342 (current->signal->session == tty->session)) 2342 (current->signal->session == tty->session))
diff --git a/drivers/char/vc_screen.c b/drivers/char/vc_screen.c
index 45e9bd81bc0e..a9247b5213d5 100644
--- a/drivers/char/vc_screen.c
+++ b/drivers/char/vc_screen.c
@@ -465,7 +465,7 @@ vcs_open(struct inode *inode, struct file *filp)
465 return 0; 465 return 0;
466} 466}
467 467
468static struct file_operations vcs_fops = { 468static const struct file_operations vcs_fops = {
469 .llseek = vcs_lseek, 469 .llseek = vcs_lseek,
470 .read = vcs_read, 470 .read = vcs_read,
471 .write = vcs_write, 471 .write = vcs_write,
diff --git a/drivers/char/viotape.c b/drivers/char/viotape.c
index 7d42c8ec8dbc..b72b2049aaae 100644
--- a/drivers/char/viotape.c
+++ b/drivers/char/viotape.c
@@ -292,7 +292,7 @@ static int proc_viotape_open(struct inode *inode, struct file *file)
292 return single_open(file, proc_viotape_show, NULL); 292 return single_open(file, proc_viotape_show, NULL);
293} 293}
294 294
295static struct file_operations proc_viotape_operations = { 295static const struct file_operations proc_viotape_operations = {
296 .open = proc_viotape_open, 296 .open = proc_viotape_open,
297 .read = seq_read, 297 .read = seq_read,
298 .llseek = seq_lseek, 298 .llseek = seq_lseek,
diff --git a/drivers/char/vr41xx_giu.c b/drivers/char/vr41xx_giu.c
index 073da48c092e..1b9b1f1d4c49 100644
--- a/drivers/char/vr41xx_giu.c
+++ b/drivers/char/vr41xx_giu.c
@@ -605,7 +605,7 @@ static int gpio_release(struct inode *inode, struct file *file)
605 return 0; 605 return 0;
606} 606}
607 607
608static struct file_operations gpio_fops = { 608static const struct file_operations gpio_fops = {
609 .owner = THIS_MODULE, 609 .owner = THIS_MODULE,
610 .read = gpio_read, 610 .read = gpio_read,
611 .write = gpio_write, 611 .write = gpio_write,
diff --git a/drivers/char/vt.c b/drivers/char/vt.c
index 3ef823d7d255..da7e66a2a38b 100644
--- a/drivers/char/vt.c
+++ b/drivers/char/vt.c
@@ -886,6 +886,7 @@ void vc_disallocate(unsigned int currcons)
886 if (vc_cons_allocated(currcons)) { 886 if (vc_cons_allocated(currcons)) {
887 struct vc_data *vc = vc_cons[currcons].d; 887 struct vc_data *vc = vc_cons[currcons].d;
888 vc->vc_sw->con_deinit(vc); 888 vc->vc_sw->con_deinit(vc);
889 module_put(vc->vc_sw->owner);
889 if (vc->vc_kmalloced) 890 if (vc->vc_kmalloced)
890 kfree(vc->vc_screenbuf); 891 kfree(vc->vc_screenbuf);
891 if (currcons >= MIN_NR_CONSOLES) 892 if (currcons >= MIN_NR_CONSOLES)
diff --git a/drivers/char/watchdog/acquirewdt.c b/drivers/char/watchdog/acquirewdt.c
index 7289f4af93d0..c77fe3cf2852 100644
--- a/drivers/char/watchdog/acquirewdt.c
+++ b/drivers/char/watchdog/acquirewdt.c
@@ -231,7 +231,7 @@ static int acq_notify_sys(struct notifier_block *this, unsigned long code,
231 * Kernel Interfaces 231 * Kernel Interfaces
232 */ 232 */
233 233
234static struct file_operations acq_fops = { 234static const struct file_operations acq_fops = {
235 .owner = THIS_MODULE, 235 .owner = THIS_MODULE,
236 .llseek = no_llseek, 236 .llseek = no_llseek,
237 .write = acq_write, 237 .write = acq_write,
diff --git a/drivers/char/watchdog/advantechwdt.c b/drivers/char/watchdog/advantechwdt.c
index 194a3fd36b91..8069be445edc 100644
--- a/drivers/char/watchdog/advantechwdt.c
+++ b/drivers/char/watchdog/advantechwdt.c
@@ -227,7 +227,7 @@ advwdt_notify_sys(struct notifier_block *this, unsigned long code,
227 * Kernel Interfaces 227 * Kernel Interfaces
228 */ 228 */
229 229
230static struct file_operations advwdt_fops = { 230static const struct file_operations advwdt_fops = {
231 .owner = THIS_MODULE, 231 .owner = THIS_MODULE,
232 .llseek = no_llseek, 232 .llseek = no_llseek,
233 .write = advwdt_write, 233 .write = advwdt_write,
diff --git a/drivers/char/watchdog/alim1535_wdt.c b/drivers/char/watchdog/alim1535_wdt.c
index 8338ca300e2e..c5c94e4c9495 100644
--- a/drivers/char/watchdog/alim1535_wdt.c
+++ b/drivers/char/watchdog/alim1535_wdt.c
@@ -362,7 +362,7 @@ static int __init ali_find_watchdog(void)
362 * Kernel Interfaces 362 * Kernel Interfaces
363 */ 363 */
364 364
365static struct file_operations ali_fops = { 365static const struct file_operations ali_fops = {
366 .owner = THIS_MODULE, 366 .owner = THIS_MODULE,
367 .llseek = no_llseek, 367 .llseek = no_llseek,
368 .write = ali_write, 368 .write = ali_write,
diff --git a/drivers/char/watchdog/alim7101_wdt.c b/drivers/char/watchdog/alim7101_wdt.c
index c05ac188a4d7..ffd7684f999b 100644
--- a/drivers/char/watchdog/alim7101_wdt.c
+++ b/drivers/char/watchdog/alim7101_wdt.c
@@ -281,7 +281,7 @@ static int fop_ioctl(struct inode *inode, struct file *file, unsigned int cmd, u
281 } 281 }
282} 282}
283 283
284static struct file_operations wdt_fops = { 284static const struct file_operations wdt_fops = {
285 .owner= THIS_MODULE, 285 .owner= THIS_MODULE,
286 .llseek= no_llseek, 286 .llseek= no_llseek,
287 .write= fop_write, 287 .write= fop_write,
diff --git a/drivers/char/watchdog/at91_wdt.c b/drivers/char/watchdog/at91_wdt.c
index f61dedc3c96c..cc266715ea32 100644
--- a/drivers/char/watchdog/at91_wdt.c
+++ b/drivers/char/watchdog/at91_wdt.c
@@ -183,7 +183,7 @@ static ssize_t at91_wdt_write(struct file *file, const char *data, size_t len, l
183 183
184/* ......................................................................... */ 184/* ......................................................................... */
185 185
186static struct file_operations at91wdt_fops = { 186static const struct file_operations at91wdt_fops = {
187 .owner = THIS_MODULE, 187 .owner = THIS_MODULE,
188 .llseek = no_llseek, 188 .llseek = no_llseek,
189 .ioctl = at91_wdt_ioctl, 189 .ioctl = at91_wdt_ioctl,
diff --git a/drivers/char/watchdog/booke_wdt.c b/drivers/char/watchdog/booke_wdt.c
index 537f5c6729bf..e3cefc538b40 100644
--- a/drivers/char/watchdog/booke_wdt.c
+++ b/drivers/char/watchdog/booke_wdt.c
@@ -145,7 +145,7 @@ static int booke_wdt_open (struct inode *inode, struct file *file)
145 return 0; 145 return 0;
146} 146}
147 147
148static struct file_operations booke_wdt_fops = { 148static const struct file_operations booke_wdt_fops = {
149 .owner = THIS_MODULE, 149 .owner = THIS_MODULE,
150 .llseek = no_llseek, 150 .llseek = no_llseek,
151 .write = booke_wdt_write, 151 .write = booke_wdt_write,
diff --git a/drivers/char/watchdog/cpu5wdt.c b/drivers/char/watchdog/cpu5wdt.c
index 3e8410b5a65e..04c7e49918db 100644
--- a/drivers/char/watchdog/cpu5wdt.c
+++ b/drivers/char/watchdog/cpu5wdt.c
@@ -198,7 +198,7 @@ static ssize_t cpu5wdt_write(struct file *file, const char __user *buf, size_t c
198 return count; 198 return count;
199} 199}
200 200
201static struct file_operations cpu5wdt_fops = { 201static const struct file_operations cpu5wdt_fops = {
202 .owner = THIS_MODULE, 202 .owner = THIS_MODULE,
203 .llseek = no_llseek, 203 .llseek = no_llseek,
204 .ioctl = cpu5wdt_ioctl, 204 .ioctl = cpu5wdt_ioctl,
diff --git a/drivers/char/watchdog/ep93xx_wdt.c b/drivers/char/watchdog/ep93xx_wdt.c
index 9021dbb78299..77c8a955ae9e 100644
--- a/drivers/char/watchdog/ep93xx_wdt.c
+++ b/drivers/char/watchdog/ep93xx_wdt.c
@@ -187,7 +187,7 @@ static int ep93xx_wdt_release(struct inode *inode, struct file *file)
187 return 0; 187 return 0;
188} 188}
189 189
190static struct file_operations ep93xx_wdt_fops = { 190static const struct file_operations ep93xx_wdt_fops = {
191 .owner = THIS_MODULE, 191 .owner = THIS_MODULE,
192 .write = ep93xx_wdt_write, 192 .write = ep93xx_wdt_write,
193 .ioctl = ep93xx_wdt_ioctl, 193 .ioctl = ep93xx_wdt_ioctl,
diff --git a/drivers/char/watchdog/eurotechwdt.c b/drivers/char/watchdog/eurotechwdt.c
index ea670de4fab7..62dbccb2f6df 100644
--- a/drivers/char/watchdog/eurotechwdt.c
+++ b/drivers/char/watchdog/eurotechwdt.c
@@ -356,7 +356,7 @@ static int eurwdt_notify_sys(struct notifier_block *this, unsigned long code,
356 */ 356 */
357 357
358 358
359static struct file_operations eurwdt_fops = { 359static const struct file_operations eurwdt_fops = {
360 .owner = THIS_MODULE, 360 .owner = THIS_MODULE,
361 .llseek = no_llseek, 361 .llseek = no_llseek,
362 .write = eurwdt_write, 362 .write = eurwdt_write,
diff --git a/drivers/char/watchdog/i6300esb.c b/drivers/char/watchdog/i6300esb.c
index 93785f13242e..870539eabbf3 100644
--- a/drivers/char/watchdog/i6300esb.c
+++ b/drivers/char/watchdog/i6300esb.c
@@ -337,7 +337,7 @@ static int esb_notify_sys (struct notifier_block *this, unsigned long code, void
337 * Kernel Interfaces 337 * Kernel Interfaces
338 */ 338 */
339 339
340static struct file_operations esb_fops = { 340static const struct file_operations esb_fops = {
341 .owner = THIS_MODULE, 341 .owner = THIS_MODULE,
342 .llseek = no_llseek, 342 .llseek = no_llseek,
343 .write = esb_write, 343 .write = esb_write,
diff --git a/drivers/char/watchdog/i8xx_tco.c b/drivers/char/watchdog/i8xx_tco.c
index bfbdbbf3c2f2..8385dd36eefe 100644
--- a/drivers/char/watchdog/i8xx_tco.c
+++ b/drivers/char/watchdog/i8xx_tco.c
@@ -378,7 +378,7 @@ static int i8xx_tco_notify_sys (struct notifier_block *this, unsigned long code,
378 * Kernel Interfaces 378 * Kernel Interfaces
379 */ 379 */
380 380
381static struct file_operations i8xx_tco_fops = { 381static const struct file_operations i8xx_tco_fops = {
382 .owner = THIS_MODULE, 382 .owner = THIS_MODULE,
383 .llseek = no_llseek, 383 .llseek = no_llseek,
384 .write = i8xx_tco_write, 384 .write = i8xx_tco_write,
diff --git a/drivers/char/watchdog/ib700wdt.c b/drivers/char/watchdog/ib700wdt.c
index a2e53c715b36..fd95f7327798 100644
--- a/drivers/char/watchdog/ib700wdt.c
+++ b/drivers/char/watchdog/ib700wdt.c
@@ -255,7 +255,7 @@ ibwdt_notify_sys(struct notifier_block *this, unsigned long code,
255 * Kernel Interfaces 255 * Kernel Interfaces
256 */ 256 */
257 257
258static struct file_operations ibwdt_fops = { 258static const struct file_operations ibwdt_fops = {
259 .owner = THIS_MODULE, 259 .owner = THIS_MODULE,
260 .llseek = no_llseek, 260 .llseek = no_llseek,
261 .write = ibwdt_write, 261 .write = ibwdt_write,
diff --git a/drivers/char/watchdog/ibmasr.c b/drivers/char/watchdog/ibmasr.c
index b0741cbdc139..26ceee7a4df0 100644
--- a/drivers/char/watchdog/ibmasr.c
+++ b/drivers/char/watchdog/ibmasr.c
@@ -322,7 +322,7 @@ static int asr_release(struct inode *inode, struct file *file)
322 return 0; 322 return 0;
323} 323}
324 324
325static struct file_operations asr_fops = { 325static const struct file_operations asr_fops = {
326 .owner = THIS_MODULE, 326 .owner = THIS_MODULE,
327 .llseek = no_llseek, 327 .llseek = no_llseek,
328 .write = asr_write, 328 .write = asr_write,
diff --git a/drivers/char/watchdog/indydog.c b/drivers/char/watchdog/indydog.c
index d387979b2434..dacc1c20a310 100644
--- a/drivers/char/watchdog/indydog.c
+++ b/drivers/char/watchdog/indydog.c
@@ -154,7 +154,7 @@ static int indydog_notify_sys(struct notifier_block *this, unsigned long code, v
154 return NOTIFY_DONE; 154 return NOTIFY_DONE;
155} 155}
156 156
157static struct file_operations indydog_fops = { 157static const struct file_operations indydog_fops = {
158 .owner = THIS_MODULE, 158 .owner = THIS_MODULE,
159 .llseek = no_llseek, 159 .llseek = no_llseek,
160 .write = indydog_write, 160 .write = indydog_write,
diff --git a/drivers/char/watchdog/ixp2000_wdt.c b/drivers/char/watchdog/ixp2000_wdt.c
index aa29a7d68759..692908819e26 100644
--- a/drivers/char/watchdog/ixp2000_wdt.c
+++ b/drivers/char/watchdog/ixp2000_wdt.c
@@ -168,7 +168,7 @@ ixp2000_wdt_release(struct inode *inode, struct file *file)
168} 168}
169 169
170 170
171static struct file_operations ixp2000_wdt_fops = 171static const struct file_operations ixp2000_wdt_fops =
172{ 172{
173 .owner = THIS_MODULE, 173 .owner = THIS_MODULE,
174 .llseek = no_llseek, 174 .llseek = no_llseek,
diff --git a/drivers/char/watchdog/ixp4xx_wdt.c b/drivers/char/watchdog/ixp4xx_wdt.c
index e6a3fe83fa01..9db5cf2c38c3 100644
--- a/drivers/char/watchdog/ixp4xx_wdt.c
+++ b/drivers/char/watchdog/ixp4xx_wdt.c
@@ -162,7 +162,7 @@ ixp4xx_wdt_release(struct inode *inode, struct file *file)
162} 162}
163 163
164 164
165static struct file_operations ixp4xx_wdt_fops = 165static const struct file_operations ixp4xx_wdt_fops =
166{ 166{
167 .owner = THIS_MODULE, 167 .owner = THIS_MODULE,
168 .llseek = no_llseek, 168 .llseek = no_llseek,
diff --git a/drivers/char/watchdog/machzwd.c b/drivers/char/watchdog/machzwd.c
index b67b4878ae0f..23734e07fb22 100644
--- a/drivers/char/watchdog/machzwd.c
+++ b/drivers/char/watchdog/machzwd.c
@@ -388,7 +388,7 @@ static int zf_notify_sys(struct notifier_block *this, unsigned long code,
388 388
389 389
390 390
391static struct file_operations zf_fops = { 391static const struct file_operations zf_fops = {
392 .owner = THIS_MODULE, 392 .owner = THIS_MODULE,
393 .llseek = no_llseek, 393 .llseek = no_llseek,
394 .write = zf_write, 394 .write = zf_write,
diff --git a/drivers/char/watchdog/mixcomwd.c b/drivers/char/watchdog/mixcomwd.c
index 433c27f98159..ae943324d251 100644
--- a/drivers/char/watchdog/mixcomwd.c
+++ b/drivers/char/watchdog/mixcomwd.c
@@ -190,7 +190,7 @@ static int mixcomwd_ioctl(struct inode *inode, struct file *file,
190 return 0; 190 return 0;
191} 191}
192 192
193static struct file_operations mixcomwd_fops= 193static const struct file_operations mixcomwd_fops=
194{ 194{
195 .owner = THIS_MODULE, 195 .owner = THIS_MODULE,
196 .llseek = no_llseek, 196 .llseek = no_llseek,
diff --git a/drivers/char/watchdog/mpc83xx_wdt.c b/drivers/char/watchdog/mpc83xx_wdt.c
index dac1381af364..a480903ee1a5 100644
--- a/drivers/char/watchdog/mpc83xx_wdt.c
+++ b/drivers/char/watchdog/mpc83xx_wdt.c
@@ -129,7 +129,7 @@ static int mpc83xx_wdt_ioctl(struct inode *inode, struct file *file,
129 } 129 }
130} 130}
131 131
132static struct file_operations mpc83xx_wdt_fops = { 132static const struct file_operations mpc83xx_wdt_fops = {
133 .owner = THIS_MODULE, 133 .owner = THIS_MODULE,
134 .llseek = no_llseek, 134 .llseek = no_llseek,
135 .write = mpc83xx_wdt_write, 135 .write = mpc83xx_wdt_write,
diff --git a/drivers/char/watchdog/mpc8xx_wdt.c b/drivers/char/watchdog/mpc8xx_wdt.c
index 11f0ccd4c4d4..35dd9e6e1140 100644
--- a/drivers/char/watchdog/mpc8xx_wdt.c
+++ b/drivers/char/watchdog/mpc8xx_wdt.c
@@ -132,7 +132,7 @@ static int mpc8xx_wdt_ioctl(struct inode *inode, struct file *file,
132 return 0; 132 return 0;
133} 133}
134 134
135static struct file_operations mpc8xx_wdt_fops = { 135static const struct file_operations mpc8xx_wdt_fops = {
136 .owner = THIS_MODULE, 136 .owner = THIS_MODULE,
137 .llseek = no_llseek, 137 .llseek = no_llseek,
138 .write = mpc8xx_wdt_write, 138 .write = mpc8xx_wdt_write,
diff --git a/drivers/char/watchdog/mpcore_wdt.c b/drivers/char/watchdog/mpcore_wdt.c
index c2d492c852fc..54b3c56ead0d 100644
--- a/drivers/char/watchdog/mpcore_wdt.c
+++ b/drivers/char/watchdog/mpcore_wdt.c
@@ -297,7 +297,7 @@ static void mpcore_wdt_shutdown(struct platform_device *dev)
297/* 297/*
298 * Kernel Interfaces 298 * Kernel Interfaces
299 */ 299 */
300static struct file_operations mpcore_wdt_fops = { 300static const struct file_operations mpcore_wdt_fops = {
301 .owner = THIS_MODULE, 301 .owner = THIS_MODULE,
302 .llseek = no_llseek, 302 .llseek = no_llseek,
303 .write = mpcore_wdt_write, 303 .write = mpcore_wdt_write,
diff --git a/drivers/char/watchdog/mv64x60_wdt.c b/drivers/char/watchdog/mv64x60_wdt.c
index 20a6cbb0fbb8..5c8fab345b40 100644
--- a/drivers/char/watchdog/mv64x60_wdt.c
+++ b/drivers/char/watchdog/mv64x60_wdt.c
@@ -166,7 +166,7 @@ static int mv64x60_wdt_ioctl(struct inode *inode, struct file *file,
166 return 0; 166 return 0;
167} 167}
168 168
169static struct file_operations mv64x60_wdt_fops = { 169static const struct file_operations mv64x60_wdt_fops = {
170 .owner = THIS_MODULE, 170 .owner = THIS_MODULE,
171 .llseek = no_llseek, 171 .llseek = no_llseek,
172 .write = mv64x60_wdt_write, 172 .write = mv64x60_wdt_write,
diff --git a/drivers/char/watchdog/pcwd.c b/drivers/char/watchdog/pcwd.c
index 6d44ca68312d..cd7d1b6a5d9f 100644
--- a/drivers/char/watchdog/pcwd.c
+++ b/drivers/char/watchdog/pcwd.c
@@ -740,7 +740,7 @@ static int pcwd_notify_sys(struct notifier_block *this, unsigned long code, void
740 * Kernel Interfaces 740 * Kernel Interfaces
741 */ 741 */
742 742
743static struct file_operations pcwd_fops = { 743static const struct file_operations pcwd_fops = {
744 .owner = THIS_MODULE, 744 .owner = THIS_MODULE,
745 .llseek = no_llseek, 745 .llseek = no_llseek,
746 .write = pcwd_write, 746 .write = pcwd_write,
@@ -755,7 +755,7 @@ static struct miscdevice pcwd_miscdev = {
755 .fops = &pcwd_fops, 755 .fops = &pcwd_fops,
756}; 756};
757 757
758static struct file_operations pcwd_temp_fops = { 758static const struct file_operations pcwd_temp_fops = {
759 .owner = THIS_MODULE, 759 .owner = THIS_MODULE,
760 .llseek = no_llseek, 760 .llseek = no_llseek,
761 .read = pcwd_temp_read, 761 .read = pcwd_temp_read,
diff --git a/drivers/char/watchdog/pcwd_pci.c b/drivers/char/watchdog/pcwd_pci.c
index 1f40ecefbf72..c7cfd6dbfe1b 100644
--- a/drivers/char/watchdog/pcwd_pci.c
+++ b/drivers/char/watchdog/pcwd_pci.c
@@ -625,7 +625,7 @@ static int pcipcwd_notify_sys(struct notifier_block *this, unsigned long code, v
625 * Kernel Interfaces 625 * Kernel Interfaces
626 */ 626 */
627 627
628static struct file_operations pcipcwd_fops = { 628static const struct file_operations pcipcwd_fops = {
629 .owner = THIS_MODULE, 629 .owner = THIS_MODULE,
630 .llseek = no_llseek, 630 .llseek = no_llseek,
631 .write = pcipcwd_write, 631 .write = pcipcwd_write,
@@ -640,7 +640,7 @@ static struct miscdevice pcipcwd_miscdev = {
640 .fops = &pcipcwd_fops, 640 .fops = &pcipcwd_fops,
641}; 641};
642 642
643static struct file_operations pcipcwd_temp_fops = { 643static const struct file_operations pcipcwd_temp_fops = {
644 .owner = THIS_MODULE, 644 .owner = THIS_MODULE,
645 .llseek = no_llseek, 645 .llseek = no_llseek,
646 .read = pcipcwd_temp_read, 646 .read = pcipcwd_temp_read,
diff --git a/drivers/char/watchdog/pcwd_usb.c b/drivers/char/watchdog/pcwd_usb.c
index 92bf8c1a0f0d..b7ae73dcdd08 100644
--- a/drivers/char/watchdog/pcwd_usb.c
+++ b/drivers/char/watchdog/pcwd_usb.c
@@ -523,7 +523,7 @@ static int usb_pcwd_notify_sys(struct notifier_block *this, unsigned long code,
523 * Kernel Interfaces 523 * Kernel Interfaces
524 */ 524 */
525 525
526static struct file_operations usb_pcwd_fops = { 526static const struct file_operations usb_pcwd_fops = {
527 .owner = THIS_MODULE, 527 .owner = THIS_MODULE,
528 .llseek = no_llseek, 528 .llseek = no_llseek,
529 .write = usb_pcwd_write, 529 .write = usb_pcwd_write,
@@ -538,7 +538,7 @@ static struct miscdevice usb_pcwd_miscdev = {
538 .fops = &usb_pcwd_fops, 538 .fops = &usb_pcwd_fops,
539}; 539};
540 540
541static struct file_operations usb_pcwd_temperature_fops = { 541static const struct file_operations usb_pcwd_temperature_fops = {
542 .owner = THIS_MODULE, 542 .owner = THIS_MODULE,
543 .llseek = no_llseek, 543 .llseek = no_llseek,
544 .read = usb_pcwd_temperature_read, 544 .read = usb_pcwd_temperature_read,
diff --git a/drivers/char/watchdog/s3c2410_wdt.c b/drivers/char/watchdog/s3c2410_wdt.c
index f267dad26071..be978e8ed754 100644
--- a/drivers/char/watchdog/s3c2410_wdt.c
+++ b/drivers/char/watchdog/s3c2410_wdt.c
@@ -319,7 +319,7 @@ static int s3c2410wdt_ioctl(struct inode *inode, struct file *file,
319 319
320/* kernel interface */ 320/* kernel interface */
321 321
322static struct file_operations s3c2410wdt_fops = { 322static const struct file_operations s3c2410wdt_fops = {
323 .owner = THIS_MODULE, 323 .owner = THIS_MODULE,
324 .llseek = no_llseek, 324 .llseek = no_llseek,
325 .write = s3c2410wdt_write, 325 .write = s3c2410wdt_write,
diff --git a/drivers/char/watchdog/sa1100_wdt.c b/drivers/char/watchdog/sa1100_wdt.c
index b22e95c5470c..1fc16d995788 100644
--- a/drivers/char/watchdog/sa1100_wdt.c
+++ b/drivers/char/watchdog/sa1100_wdt.c
@@ -135,7 +135,7 @@ static int sa1100dog_ioctl(struct inode *inode, struct file *file,
135 return ret; 135 return ret;
136} 136}
137 137
138static struct file_operations sa1100dog_fops = 138static const struct file_operations sa1100dog_fops =
139{ 139{
140 .owner = THIS_MODULE, 140 .owner = THIS_MODULE,
141 .llseek = no_llseek, 141 .llseek = no_llseek,
diff --git a/drivers/char/watchdog/sbc60xxwdt.c b/drivers/char/watchdog/sbc60xxwdt.c
index ed0bd55fbfc1..4663c2fd53cd 100644
--- a/drivers/char/watchdog/sbc60xxwdt.c
+++ b/drivers/char/watchdog/sbc60xxwdt.c
@@ -282,7 +282,7 @@ static int fop_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
282 } 282 }
283} 283}
284 284
285static struct file_operations wdt_fops = { 285static const struct file_operations wdt_fops = {
286 .owner = THIS_MODULE, 286 .owner = THIS_MODULE,
287 .llseek = no_llseek, 287 .llseek = no_llseek,
288 .write = fop_write, 288 .write = fop_write,
diff --git a/drivers/char/watchdog/sbc8360.c b/drivers/char/watchdog/sbc8360.c
index 6562aa910ace..1035be5b5019 100644
--- a/drivers/char/watchdog/sbc8360.c
+++ b/drivers/char/watchdog/sbc8360.c
@@ -305,7 +305,7 @@ static int sbc8360_notify_sys(struct notifier_block *this, unsigned long code,
305 * Kernel Interfaces 305 * Kernel Interfaces
306 */ 306 */
307 307
308static struct file_operations sbc8360_fops = { 308static const struct file_operations sbc8360_fops = {
309 .owner = THIS_MODULE, 309 .owner = THIS_MODULE,
310 .llseek = no_llseek, 310 .llseek = no_llseek,
311 .write = sbc8360_write, 311 .write = sbc8360_write,
diff --git a/drivers/char/watchdog/sbc_epx_c3.c b/drivers/char/watchdog/sbc_epx_c3.c
index 09867fadc720..bfc475dabe6d 100644
--- a/drivers/char/watchdog/sbc_epx_c3.c
+++ b/drivers/char/watchdog/sbc_epx_c3.c
@@ -154,7 +154,7 @@ static int epx_c3_notify_sys(struct notifier_block *this, unsigned long code,
154 return NOTIFY_DONE; 154 return NOTIFY_DONE;
155} 155}
156 156
157static struct file_operations epx_c3_fops = { 157static const struct file_operations epx_c3_fops = {
158 .owner = THIS_MODULE, 158 .owner = THIS_MODULE,
159 .llseek = no_llseek, 159 .llseek = no_llseek,
160 .write = epx_c3_write, 160 .write = epx_c3_write,
diff --git a/drivers/char/watchdog/sc1200wdt.c b/drivers/char/watchdog/sc1200wdt.c
index 78ef6333c181..7c3cf293a5af 100644
--- a/drivers/char/watchdog/sc1200wdt.c
+++ b/drivers/char/watchdog/sc1200wdt.c
@@ -292,7 +292,7 @@ static struct notifier_block sc1200wdt_notifier =
292 .notifier_call = sc1200wdt_notify_sys, 292 .notifier_call = sc1200wdt_notify_sys,
293}; 293};
294 294
295static struct file_operations sc1200wdt_fops = 295static const struct file_operations sc1200wdt_fops =
296{ 296{
297 .owner = THIS_MODULE, 297 .owner = THIS_MODULE,
298 .llseek = no_llseek, 298 .llseek = no_llseek,
diff --git a/drivers/char/watchdog/sc520_wdt.c b/drivers/char/watchdog/sc520_wdt.c
index 4ee9974ad8cb..2c7c9db71be8 100644
--- a/drivers/char/watchdog/sc520_wdt.c
+++ b/drivers/char/watchdog/sc520_wdt.c
@@ -336,7 +336,7 @@ static int fop_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
336 } 336 }
337} 337}
338 338
339static struct file_operations wdt_fops = { 339static const struct file_operations wdt_fops = {
340 .owner = THIS_MODULE, 340 .owner = THIS_MODULE,
341 .llseek = no_llseek, 341 .llseek = no_llseek,
342 .write = fop_write, 342 .write = fop_write,
diff --git a/drivers/char/watchdog/scx200_wdt.c b/drivers/char/watchdog/scx200_wdt.c
index c0b4754e8de0..c561299a5537 100644
--- a/drivers/char/watchdog/scx200_wdt.c
+++ b/drivers/char/watchdog/scx200_wdt.c
@@ -194,7 +194,7 @@ static int scx200_wdt_ioctl(struct inode *inode, struct file *file,
194 } 194 }
195} 195}
196 196
197static struct file_operations scx200_wdt_fops = { 197static const struct file_operations scx200_wdt_fops = {
198 .owner = THIS_MODULE, 198 .owner = THIS_MODULE,
199 .llseek = no_llseek, 199 .llseek = no_llseek,
200 .write = scx200_wdt_write, 200 .write = scx200_wdt_write,
diff --git a/drivers/char/watchdog/shwdt.c b/drivers/char/watchdog/shwdt.c
index 803701b675c0..1355038f1044 100644
--- a/drivers/char/watchdog/shwdt.c
+++ b/drivers/char/watchdog/shwdt.c
@@ -344,7 +344,7 @@ static int sh_wdt_notify_sys(struct notifier_block *this,
344 return NOTIFY_DONE; 344 return NOTIFY_DONE;
345} 345}
346 346
347static struct file_operations sh_wdt_fops = { 347static const struct file_operations sh_wdt_fops = {
348 .owner = THIS_MODULE, 348 .owner = THIS_MODULE,
349 .llseek = no_llseek, 349 .llseek = no_llseek,
350 .write = sh_wdt_write, 350 .write = sh_wdt_write,
diff --git a/drivers/char/watchdog/softdog.c b/drivers/char/watchdog/softdog.c
index 79ce5c655428..ef8da517545a 100644
--- a/drivers/char/watchdog/softdog.c
+++ b/drivers/char/watchdog/softdog.c
@@ -243,7 +243,7 @@ static int softdog_notify_sys(struct notifier_block *this, unsigned long code,
243 * Kernel Interfaces 243 * Kernel Interfaces
244 */ 244 */
245 245
246static struct file_operations softdog_fops = { 246static const struct file_operations softdog_fops = {
247 .owner = THIS_MODULE, 247 .owner = THIS_MODULE,
248 .llseek = no_llseek, 248 .llseek = no_llseek,
249 .write = softdog_write, 249 .write = softdog_write,
diff --git a/drivers/char/watchdog/w83627hf_wdt.c b/drivers/char/watchdog/w83627hf_wdt.c
index d15ca9a3986f..13f16d41c2fd 100644
--- a/drivers/char/watchdog/w83627hf_wdt.c
+++ b/drivers/char/watchdog/w83627hf_wdt.c
@@ -274,7 +274,7 @@ wdt_notify_sys(struct notifier_block *this, unsigned long code,
274 * Kernel Interfaces 274 * Kernel Interfaces
275 */ 275 */
276 276
277static struct file_operations wdt_fops = { 277static const struct file_operations wdt_fops = {
278 .owner = THIS_MODULE, 278 .owner = THIS_MODULE,
279 .llseek = no_llseek, 279 .llseek = no_llseek,
280 .write = wdt_write, 280 .write = wdt_write,
diff --git a/drivers/char/watchdog/w83877f_wdt.c b/drivers/char/watchdog/w83877f_wdt.c
index 52a8bd0a5988..ccf6c0915945 100644
--- a/drivers/char/watchdog/w83877f_wdt.c
+++ b/drivers/char/watchdog/w83877f_wdt.c
@@ -299,7 +299,7 @@ static int fop_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
299 } 299 }
300} 300}
301 301
302static struct file_operations wdt_fops = { 302static const struct file_operations wdt_fops = {
303 .owner = THIS_MODULE, 303 .owner = THIS_MODULE,
304 .llseek = no_llseek, 304 .llseek = no_llseek,
305 .write = fop_write, 305 .write = fop_write,
diff --git a/drivers/char/watchdog/w83977f_wdt.c b/drivers/char/watchdog/w83977f_wdt.c
index c31849e4c5c2..98f4e17db70a 100644
--- a/drivers/char/watchdog/w83977f_wdt.c
+++ b/drivers/char/watchdog/w83977f_wdt.c
@@ -449,7 +449,7 @@ static int wdt_notify_sys(struct notifier_block *this, unsigned long code,
449 return NOTIFY_DONE; 449 return NOTIFY_DONE;
450} 450}
451 451
452static struct file_operations wdt_fops= 452static const struct file_operations wdt_fops=
453{ 453{
454 .owner = THIS_MODULE, 454 .owner = THIS_MODULE,
455 .llseek = no_llseek, 455 .llseek = no_llseek,
diff --git a/drivers/char/watchdog/wafer5823wdt.c b/drivers/char/watchdog/wafer5823wdt.c
index 7cf6c9bbf486..2bb6a9d6ad28 100644
--- a/drivers/char/watchdog/wafer5823wdt.c
+++ b/drivers/char/watchdog/wafer5823wdt.c
@@ -222,7 +222,7 @@ static int wafwdt_notify_sys(struct notifier_block *this, unsigned long code, vo
222 * Kernel Interfaces 222 * Kernel Interfaces
223 */ 223 */
224 224
225static struct file_operations wafwdt_fops = { 225static const struct file_operations wafwdt_fops = {
226 .owner = THIS_MODULE, 226 .owner = THIS_MODULE,
227 .llseek = no_llseek, 227 .llseek = no_llseek,
228 .write = wafwdt_write, 228 .write = wafwdt_write,
diff --git a/drivers/char/watchdog/wdrtas.c b/drivers/char/watchdog/wdrtas.c
index 3a462c34b92a..5c38cdf41731 100644
--- a/drivers/char/watchdog/wdrtas.c
+++ b/drivers/char/watchdog/wdrtas.c
@@ -520,7 +520,7 @@ wdrtas_reboot(struct notifier_block *this, unsigned long code, void *ptr)
520 520
521/*** initialization stuff */ 521/*** initialization stuff */
522 522
523static struct file_operations wdrtas_fops = { 523static const struct file_operations wdrtas_fops = {
524 .owner = THIS_MODULE, 524 .owner = THIS_MODULE,
525 .llseek = no_llseek, 525 .llseek = no_llseek,
526 .write = wdrtas_write, 526 .write = wdrtas_write,
@@ -535,7 +535,7 @@ static struct miscdevice wdrtas_miscdev = {
535 .fops = &wdrtas_fops, 535 .fops = &wdrtas_fops,
536}; 536};
537 537
538static struct file_operations wdrtas_temp_fops = { 538static const struct file_operations wdrtas_temp_fops = {
539 .owner = THIS_MODULE, 539 .owner = THIS_MODULE,
540 .llseek = no_llseek, 540 .llseek = no_llseek,
541 .read = wdrtas_temp_read, 541 .read = wdrtas_temp_read,
diff --git a/drivers/char/watchdog/wdt.c b/drivers/char/watchdog/wdt.c
index a1d972c8f44c..70be81e39a61 100644
--- a/drivers/char/watchdog/wdt.c
+++ b/drivers/char/watchdog/wdt.c
@@ -494,7 +494,7 @@ static int wdt_notify_sys(struct notifier_block *this, unsigned long code,
494 */ 494 */
495 495
496 496
497static struct file_operations wdt_fops = { 497static const struct file_operations wdt_fops = {
498 .owner = THIS_MODULE, 498 .owner = THIS_MODULE,
499 .llseek = no_llseek, 499 .llseek = no_llseek,
500 .write = wdt_write, 500 .write = wdt_write,
@@ -510,7 +510,7 @@ static struct miscdevice wdt_miscdev = {
510}; 510};
511 511
512#ifdef CONFIG_WDT_501 512#ifdef CONFIG_WDT_501
513static struct file_operations wdt_temp_fops = { 513static const struct file_operations wdt_temp_fops = {
514 .owner = THIS_MODULE, 514 .owner = THIS_MODULE,
515 .llseek = no_llseek, 515 .llseek = no_llseek,
516 .read = wdt_temp_read, 516 .read = wdt_temp_read,
diff --git a/drivers/char/watchdog/wdt285.c b/drivers/char/watchdog/wdt285.c
index 52825a1f1779..6555fb844f23 100644
--- a/drivers/char/watchdog/wdt285.c
+++ b/drivers/char/watchdog/wdt285.c
@@ -178,7 +178,7 @@ watchdog_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
178 return ret; 178 return ret;
179} 179}
180 180
181static struct file_operations watchdog_fops = { 181static const struct file_operations watchdog_fops = {
182 .owner = THIS_MODULE, 182 .owner = THIS_MODULE,
183 .llseek = no_llseek, 183 .llseek = no_llseek,
184 .write = watchdog_write, 184 .write = watchdog_write,
diff --git a/drivers/char/watchdog/wdt977.c b/drivers/char/watchdog/wdt977.c
index 3cde2b9bb763..a0935bc775f8 100644
--- a/drivers/char/watchdog/wdt977.c
+++ b/drivers/char/watchdog/wdt977.c
@@ -418,7 +418,7 @@ static int wdt977_notify_sys(struct notifier_block *this, unsigned long code,
418 return NOTIFY_DONE; 418 return NOTIFY_DONE;
419} 419}
420 420
421static struct file_operations wdt977_fops= 421static const struct file_operations wdt977_fops=
422{ 422{
423 .owner = THIS_MODULE, 423 .owner = THIS_MODULE,
424 .llseek = no_llseek, 424 .llseek = no_llseek,
diff --git a/drivers/char/watchdog/wdt_pci.c b/drivers/char/watchdog/wdt_pci.c
index 7529ecdbabae..5918ca2c9c35 100644
--- a/drivers/char/watchdog/wdt_pci.c
+++ b/drivers/char/watchdog/wdt_pci.c
@@ -543,7 +543,7 @@ static int wdtpci_notify_sys(struct notifier_block *this, unsigned long code,
543 */ 543 */
544 544
545 545
546static struct file_operations wdtpci_fops = { 546static const struct file_operations wdtpci_fops = {
547 .owner = THIS_MODULE, 547 .owner = THIS_MODULE,
548 .llseek = no_llseek, 548 .llseek = no_llseek,
549 .write = wdtpci_write, 549 .write = wdtpci_write,
@@ -559,7 +559,7 @@ static struct miscdevice wdtpci_miscdev = {
559}; 559};
560 560
561#ifdef CONFIG_WDT_501_PCI 561#ifdef CONFIG_WDT_501_PCI
562static struct file_operations wdtpci_temp_fops = { 562static const struct file_operations wdtpci_temp_fops = {
563 .owner = THIS_MODULE, 563 .owner = THIS_MODULE,
564 .llseek = no_llseek, 564 .llseek = no_llseek,
565 .read = wdtpci_temp_read, 565 .read = wdtpci_temp_read,
diff --git a/drivers/ide/ide-floppy.c b/drivers/ide/ide-floppy.c
index 6ca3476d02c7..adbe9f76a505 100644
--- a/drivers/ide/ide-floppy.c
+++ b/drivers/ide/ide-floppy.c
@@ -838,7 +838,7 @@ static ide_startstop_t idefloppy_pc_intr (ide_drive_t *drive)
838 "transferred\n", pc->actually_transferred); 838 "transferred\n", pc->actually_transferred);
839 clear_bit(PC_DMA_IN_PROGRESS, &pc->flags); 839 clear_bit(PC_DMA_IN_PROGRESS, &pc->flags);
840 840
841 local_irq_enable(); 841 local_irq_enable_in_hardirq();
842 842
843 if (status.b.check || test_bit(PC_DMA_ERROR, &pc->flags)) { 843 if (status.b.check || test_bit(PC_DMA_ERROR, &pc->flags)) {
844 /* Error detected */ 844 /* Error detected */
diff --git a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c
index 7dba9992ad30..fb6795236e76 100644
--- a/drivers/ide/ide-io.c
+++ b/drivers/ide/ide-io.c
@@ -693,7 +693,7 @@ static ide_startstop_t drive_cmd_intr (ide_drive_t *drive)
693 u8 stat = hwif->INB(IDE_STATUS_REG); 693 u8 stat = hwif->INB(IDE_STATUS_REG);
694 int retries = 10; 694 int retries = 10;
695 695
696 local_irq_enable(); 696 local_irq_enable_in_hardirq();
697 if ((stat & DRQ_STAT) && args && args[3]) { 697 if ((stat & DRQ_STAT) && args && args[3]) {
698 u8 io_32bit = drive->io_32bit; 698 u8 io_32bit = drive->io_32bit;
699 drive->io_32bit = 0; 699 drive->io_32bit = 0;
@@ -1286,7 +1286,7 @@ static void ide_do_request (ide_hwgroup_t *hwgroup, int masked_irq)
1286 if (masked_irq != IDE_NO_IRQ && hwif->irq != masked_irq) 1286 if (masked_irq != IDE_NO_IRQ && hwif->irq != masked_irq)
1287 disable_irq_nosync(hwif->irq); 1287 disable_irq_nosync(hwif->irq);
1288 spin_unlock(&ide_lock); 1288 spin_unlock(&ide_lock);
1289 local_irq_enable(); 1289 local_irq_enable_in_hardirq();
1290 /* allow other IRQs while we start this request */ 1290 /* allow other IRQs while we start this request */
1291 startstop = start_request(drive, rq); 1291 startstop = start_request(drive, rq);
1292 spin_lock_irq(&ide_lock); 1292 spin_lock_irq(&ide_lock);
@@ -1631,7 +1631,7 @@ irqreturn_t ide_intr (int irq, void *dev_id, struct pt_regs *regs)
1631 spin_unlock(&ide_lock); 1631 spin_unlock(&ide_lock);
1632 1632
1633 if (drive->unmask) 1633 if (drive->unmask)
1634 local_irq_enable(); 1634 local_irq_enable_in_hardirq();
1635 /* service this interrupt, may set handler for next interrupt */ 1635 /* service this interrupt, may set handler for next interrupt */
1636 startstop = handler(drive); 1636 startstop = handler(drive);
1637 spin_lock_irq(&ide_lock); 1637 spin_lock_irq(&ide_lock);
@@ -1705,7 +1705,7 @@ int ide_do_drive_cmd (ide_drive_t *drive, struct request *rq, ide_action_t actio
1705{ 1705{
1706 unsigned long flags; 1706 unsigned long flags;
1707 ide_hwgroup_t *hwgroup = HWGROUP(drive); 1707 ide_hwgroup_t *hwgroup = HWGROUP(drive);
1708 DECLARE_COMPLETION(wait); 1708 DECLARE_COMPLETION_ONSTACK(wait);
1709 int where = ELEVATOR_INSERT_BACK, err; 1709 int where = ELEVATOR_INSERT_BACK, err;
1710 int must_wait = (action == ide_wait || action == ide_head_wait); 1710 int must_wait = (action == ide_wait || action == ide_head_wait);
1711 1711
diff --git a/drivers/ide/ide-taskfile.c b/drivers/ide/ide-taskfile.c
index 04547eb0833f..97a9244312fc 100644
--- a/drivers/ide/ide-taskfile.c
+++ b/drivers/ide/ide-taskfile.c
@@ -222,7 +222,7 @@ ide_startstop_t task_no_data_intr (ide_drive_t *drive)
222 ide_hwif_t *hwif = HWIF(drive); 222 ide_hwif_t *hwif = HWIF(drive);
223 u8 stat; 223 u8 stat;
224 224
225 local_irq_enable(); 225 local_irq_enable_in_hardirq();
226 if (!OK_STAT(stat = hwif->INB(IDE_STATUS_REG),READY_STAT,BAD_STAT)) { 226 if (!OK_STAT(stat = hwif->INB(IDE_STATUS_REG),READY_STAT,BAD_STAT)) {
227 return ide_error(drive, "task_no_data_intr", stat); 227 return ide_error(drive, "task_no_data_intr", stat);
228 /* calls ide_end_drive_cmd */ 228 /* calls ide_end_drive_cmd */
diff --git a/drivers/ieee1394/hosts.c b/drivers/ieee1394/hosts.c
index 2c669287f5bd..4feead4a35c5 100644
--- a/drivers/ieee1394/hosts.c
+++ b/drivers/ieee1394/hosts.c
@@ -107,6 +107,14 @@ static int alloc_hostnum_cb(struct hpsb_host *host, void *__data)
107 */ 107 */
108static DEFINE_MUTEX(host_num_alloc); 108static DEFINE_MUTEX(host_num_alloc);
109 109
110/*
111 * The pending_packet_queue is special in that it's processed
112 * from hardirq context too (such as hpsb_bus_reset()). Hence
113 * split the lock class from the usual networking skb-head
114 * lock class by using a separate key for it:
115 */
116static struct lock_class_key pending_packet_queue_key;
117
110struct hpsb_host *hpsb_alloc_host(struct hpsb_host_driver *drv, size_t extra, 118struct hpsb_host *hpsb_alloc_host(struct hpsb_host_driver *drv, size_t extra,
111 struct device *dev) 119 struct device *dev)
112{ 120{
@@ -128,6 +136,8 @@ struct hpsb_host *hpsb_alloc_host(struct hpsb_host_driver *drv, size_t extra,
128 h->driver = drv; 136 h->driver = drv;
129 137
130 skb_queue_head_init(&h->pending_packet_queue); 138 skb_queue_head_init(&h->pending_packet_queue);
139 lockdep_set_class(&h->pending_packet_queue.lock,
140 &pending_packet_queue_key);
131 INIT_LIST_HEAD(&h->addr_space); 141 INIT_LIST_HEAD(&h->addr_space);
132 142
133 for (i = 2; i < 16; i++) 143 for (i = 2; i < 16; i++)
diff --git a/drivers/input/serio/i8042-sparcio.h b/drivers/input/serio/i8042-sparcio.h
index 7d9fafea9615..54adba2d8ed5 100644
--- a/drivers/input/serio/i8042-sparcio.h
+++ b/drivers/input/serio/i8042-sparcio.h
@@ -88,7 +88,7 @@ static struct of_device_id sparc_i8042_match[] = {
88 }, 88 },
89 {}, 89 {},
90}; 90};
91MODULE_DEVICE_TABLE(of, i8042_match); 91MODULE_DEVICE_TABLE(of, sparc_i8042_match);
92 92
93static struct of_platform_driver sparc_i8042_driver = { 93static struct of_platform_driver sparc_i8042_driver = {
94 .name = "i8042", 94 .name = "i8042",
diff --git a/drivers/input/serio/libps2.c b/drivers/input/serio/libps2.c
index 79c97f94bcbd..61a6f977846f 100644
--- a/drivers/input/serio/libps2.c
+++ b/drivers/input/serio/libps2.c
@@ -177,7 +177,7 @@ int ps2_command(struct ps2dev *ps2dev, unsigned char *param, int command)
177 return -1; 177 return -1;
178 } 178 }
179 179
180 mutex_lock(&ps2dev->cmd_mutex); 180 mutex_lock_nested(&ps2dev->cmd_mutex, SINGLE_DEPTH_NESTING);
181 181
182 serio_pause_rx(ps2dev->serio); 182 serio_pause_rx(ps2dev->serio);
183 ps2dev->flags = command == PS2_CMD_GETID ? PS2_FLAG_WAITID : 0; 183 ps2dev->flags = command == PS2_CMD_GETID ? PS2_FLAG_WAITID : 0;
diff --git a/drivers/macintosh/macio-adb.c b/drivers/macintosh/macio-adb.c
index 314fc0830d90..4b08852c35ee 100644
--- a/drivers/macintosh/macio-adb.c
+++ b/drivers/macintosh/macio-adb.c
@@ -90,22 +90,12 @@ int macio_init(void)
90{ 90{
91 struct device_node *adbs; 91 struct device_node *adbs;
92 struct resource r; 92 struct resource r;
93 unsigned int irq;
93 94
94 adbs = find_compatible_devices("adb", "chrp,adb0"); 95 adbs = find_compatible_devices("adb", "chrp,adb0");
95 if (adbs == 0) 96 if (adbs == 0)
96 return -ENXIO; 97 return -ENXIO;
97 98
98#if 0
99 { int i = 0;
100
101 printk("macio_adb_init: node = %p, addrs =", adbs->node);
102 while(!of_address_to_resource(adbs, i, &r))
103 printk(" %x(%x)", r.start, r.end - r.start);
104 printk(", intrs =");
105 for (i = 0; i < adbs->n_intrs; ++i)
106 printk(" %x", adbs->intrs[i].line);
107 printk("\n"); }
108#endif
109 if (of_address_to_resource(adbs, 0, &r)) 99 if (of_address_to_resource(adbs, 0, &r))
110 return -ENXIO; 100 return -ENXIO;
111 adb = ioremap(r.start, sizeof(struct adb_regs)); 101 adb = ioremap(r.start, sizeof(struct adb_regs));
@@ -117,10 +107,9 @@ int macio_init(void)
117 out_8(&adb->active_lo.r, 0xff); 107 out_8(&adb->active_lo.r, 0xff);
118 out_8(&adb->autopoll.r, APE); 108 out_8(&adb->autopoll.r, APE);
119 109
120 if (request_irq(adbs->intrs[0].line, macio_adb_interrupt, 110 irq = irq_of_parse_and_map(adbs, 0);
121 0, "ADB", (void *)0)) { 111 if (request_irq(irq, macio_adb_interrupt, 0, "ADB", (void *)0)) {
122 printk(KERN_ERR "ADB: can't get irq %d\n", 112 printk(KERN_ERR "ADB: can't get irq %d\n", irq);
123 adbs->intrs[0].line);
124 return -EAGAIN; 113 return -EAGAIN;
125 } 114 }
126 out_8(&adb->intr_enb.r, DFB | TAG); 115 out_8(&adb->intr_enb.r, DFB | TAG);
diff --git a/drivers/macintosh/macio_asic.c b/drivers/macintosh/macio_asic.c
index 40ae7b6a939d..80c0c665b5f6 100644
--- a/drivers/macintosh/macio_asic.c
+++ b/drivers/macintosh/macio_asic.c
@@ -280,75 +280,128 @@ static void macio_release_dev(struct device *dev)
280static int macio_resource_quirks(struct device_node *np, struct resource *res, 280static int macio_resource_quirks(struct device_node *np, struct resource *res,
281 int index) 281 int index)
282{ 282{
283 if (res->flags & IORESOURCE_MEM) { 283 /* Only quirks for memory resources for now */
284 /* Grand Central has too large resource 0 on some machines */ 284 if ((res->flags & IORESOURCE_MEM) == 0)
285 if (index == 0 && !strcmp(np->name, "gc")) 285 return 0;
286 res->end = res->start + 0x1ffff; 286
287 /* Grand Central has too large resource 0 on some machines */
288 if (index == 0 && !strcmp(np->name, "gc"))
289 res->end = res->start + 0x1ffff;
287 290
288 /* Airport has bogus resource 2 */ 291 /* Airport has bogus resource 2 */
289 if (index >= 2 && !strcmp(np->name, "radio")) 292 if (index >= 2 && !strcmp(np->name, "radio"))
290 return 1; 293 return 1;
291 294
292#ifndef CONFIG_PPC64 295#ifndef CONFIG_PPC64
293 /* DBDMAs may have bogus sizes */ 296 /* DBDMAs may have bogus sizes */
294 if ((res->start & 0x0001f000) == 0x00008000) 297 if ((res->start & 0x0001f000) == 0x00008000)
295 res->end = res->start + 0xff; 298 res->end = res->start + 0xff;
296#endif /* CONFIG_PPC64 */ 299#endif /* CONFIG_PPC64 */
297 300
298 /* ESCC parent eats child resources. We could have added a 301 /* ESCC parent eats child resources. We could have added a
299 * level of hierarchy, but I don't really feel the need 302 * level of hierarchy, but I don't really feel the need
300 * for it 303 * for it
301 */ 304 */
302 if (!strcmp(np->name, "escc")) 305 if (!strcmp(np->name, "escc"))
303 return 1; 306 return 1;
304 307
305 /* ESCC has bogus resources >= 3 */ 308 /* ESCC has bogus resources >= 3 */
306 if (index >= 3 && !(strcmp(np->name, "ch-a") && 309 if (index >= 3 && !(strcmp(np->name, "ch-a") &&
307 strcmp(np->name, "ch-b"))) 310 strcmp(np->name, "ch-b")))
308 return 1; 311 return 1;
309 312
310 /* Media bay has too many resources, keep only first one */ 313 /* Media bay has too many resources, keep only first one */
311 if (index > 0 && !strcmp(np->name, "media-bay")) 314 if (index > 0 && !strcmp(np->name, "media-bay"))
312 return 1; 315 return 1;
313 316
314 /* Some older IDE resources have bogus sizes */ 317 /* Some older IDE resources have bogus sizes */
315 if (!(strcmp(np->name, "IDE") && strcmp(np->name, "ATA") && 318 if (!(strcmp(np->name, "IDE") && strcmp(np->name, "ATA") &&
316 strcmp(np->type, "ide") && strcmp(np->type, "ata"))) { 319 strcmp(np->type, "ide") && strcmp(np->type, "ata"))) {
317 if (index == 0 && (res->end - res->start) > 0xfff) 320 if (index == 0 && (res->end - res->start) > 0xfff)
318 res->end = res->start + 0xfff; 321 res->end = res->start + 0xfff;
319 if (index == 1 && (res->end - res->start) > 0xff) 322 if (index == 1 && (res->end - res->start) > 0xff)
320 res->end = res->start + 0xff; 323 res->end = res->start + 0xff;
321 }
322 } 324 }
323 return 0; 325 return 0;
324} 326}
325 327
328static void macio_create_fixup_irq(struct macio_dev *dev, int index,
329 unsigned int line)
330{
331 unsigned int irq;
326 332
327static void macio_setup_interrupts(struct macio_dev *dev) 333 irq = irq_create_mapping(NULL, line, 0);
334 if (irq != NO_IRQ) {
335 dev->interrupt[index].start = irq;
336 dev->interrupt[index].flags = IORESOURCE_IRQ;
337 dev->interrupt[index].name = dev->ofdev.dev.bus_id;
338 }
339 if (dev->n_interrupts <= index)
340 dev->n_interrupts = index + 1;
341}
342
343static void macio_add_missing_resources(struct macio_dev *dev)
328{ 344{
329 struct device_node *np = dev->ofdev.node; 345 struct device_node *np = dev->ofdev.node;
330 int i,j; 346 unsigned int irq_base;
347
348 /* Gatwick has some missing interrupts on child nodes */
349 if (dev->bus->chip->type != macio_gatwick)
350 return;
331 351
332 /* For now, we use pre-parsed entries in the device-tree for 352 /* irq_base is always 64 on gatwick. I have no cleaner way to get
333 * interrupt routing and addresses, but we should change that 353 * that value from here at this point
334 * to dynamically parsed entries and so get rid of most of the
335 * clutter in struct device_node
336 */ 354 */
337 for (i = j = 0; i < np->n_intrs; i++) { 355 irq_base = 64;
356
357 /* Fix SCC */
358 if (strcmp(np->name, "ch-a") == 0) {
359 macio_create_fixup_irq(dev, 0, 15 + irq_base);
360 macio_create_fixup_irq(dev, 1, 4 + irq_base);
361 macio_create_fixup_irq(dev, 2, 5 + irq_base);
362 printk(KERN_INFO "macio: fixed SCC irqs on gatwick\n");
363 }
364
365 /* Fix media-bay */
366 if (strcmp(np->name, "media-bay") == 0) {
367 macio_create_fixup_irq(dev, 0, 29 + irq_base);
368 printk(KERN_INFO "macio: fixed media-bay irq on gatwick\n");
369 }
370
371 /* Fix left media bay childs */
372 if (dev->media_bay != NULL && strcmp(np->name, "floppy") == 0) {
373 macio_create_fixup_irq(dev, 0, 19 + irq_base);
374 macio_create_fixup_irq(dev, 1, 1 + irq_base);
375 printk(KERN_INFO "macio: fixed left floppy irqs\n");
376 }
377 if (dev->media_bay != NULL && strcasecmp(np->name, "ata4") == 0) {
378 macio_create_fixup_irq(dev, 0, 14 + irq_base);
379 macio_create_fixup_irq(dev, 0, 3 + irq_base);
380 printk(KERN_INFO "macio: fixed left ide irqs\n");
381 }
382}
383
384static void macio_setup_interrupts(struct macio_dev *dev)
385{
386 struct device_node *np = dev->ofdev.node;
387 unsigned int irq;
388 int i = 0, j = 0;
389
390 for (;;) {
338 struct resource *res = &dev->interrupt[j]; 391 struct resource *res = &dev->interrupt[j];
339 392
340 if (j >= MACIO_DEV_COUNT_IRQS) 393 if (j >= MACIO_DEV_COUNT_IRQS)
341 break; 394 break;
342 res->start = np->intrs[i].line; 395 irq = irq_of_parse_and_map(np, i++);
343 res->flags = IORESOURCE_IO; 396 if (irq == NO_IRQ)
344 if (np->intrs[j].sense) 397 break;
345 res->flags |= IORESOURCE_IRQ_LOWLEVEL; 398 res->start = irq;
346 else 399 res->flags = IORESOURCE_IRQ;
347 res->flags |= IORESOURCE_IRQ_HIGHEDGE;
348 res->name = dev->ofdev.dev.bus_id; 400 res->name = dev->ofdev.dev.bus_id;
349 if (macio_resource_quirks(np, res, i)) 401 if (macio_resource_quirks(np, res, i - 1)) {
350 memset(res, 0, sizeof(struct resource)); 402 memset(res, 0, sizeof(struct resource));
351 else 403 continue;
404 } else
352 j++; 405 j++;
353 } 406 }
354 dev->n_interrupts = j; 407 dev->n_interrupts = j;
@@ -445,6 +498,7 @@ static struct macio_dev * macio_add_one_device(struct macio_chip *chip,
445 /* Setup interrupts & resources */ 498 /* Setup interrupts & resources */
446 macio_setup_interrupts(dev); 499 macio_setup_interrupts(dev);
447 macio_setup_resources(dev, parent_res); 500 macio_setup_resources(dev, parent_res);
501 macio_add_missing_resources(dev);
448 502
449 /* Register with core */ 503 /* Register with core */
450 if (of_device_register(&dev->ofdev) != 0) { 504 if (of_device_register(&dev->ofdev) != 0) {
diff --git a/drivers/macintosh/smu.c b/drivers/macintosh/smu.c
index ff6d9bfdc3d2..f139a74696fe 100644
--- a/drivers/macintosh/smu.c
+++ b/drivers/macintosh/smu.c
@@ -497,8 +497,7 @@ int __init smu_init (void)
497 smu->doorbell = *data; 497 smu->doorbell = *data;
498 if (smu->doorbell < 0x50) 498 if (smu->doorbell < 0x50)
499 smu->doorbell += 0x50; 499 smu->doorbell += 0x50;
500 if (np->n_intrs > 0) 500 smu->db_irq = irq_of_parse_and_map(np, 0);
501 smu->db_irq = np->intrs[0].line;
502 501
503 of_node_put(np); 502 of_node_put(np);
504 503
@@ -515,8 +514,7 @@ int __init smu_init (void)
515 smu->msg = *data; 514 smu->msg = *data;
516 if (smu->msg < 0x50) 515 if (smu->msg < 0x50)
517 smu->msg += 0x50; 516 smu->msg += 0x50;
518 if (np->n_intrs > 0) 517 smu->msg_irq = irq_of_parse_and_map(np, 0);
519 smu->msg_irq = np->intrs[0].line;
520 of_node_put(np); 518 of_node_put(np);
521 } while(0); 519 } while(0);
522 520
diff --git a/drivers/macintosh/via-cuda.c b/drivers/macintosh/via-cuda.c
index 6501db50fb83..69d5452fd22f 100644
--- a/drivers/macintosh/via-cuda.c
+++ b/drivers/macintosh/via-cuda.c
@@ -34,13 +34,6 @@
34static volatile unsigned char __iomem *via; 34static volatile unsigned char __iomem *via;
35static DEFINE_SPINLOCK(cuda_lock); 35static DEFINE_SPINLOCK(cuda_lock);
36 36
37#ifdef CONFIG_MAC
38#define CUDA_IRQ IRQ_MAC_ADB
39#define eieio()
40#else
41#define CUDA_IRQ vias->intrs[0].line
42#endif
43
44/* VIA registers - spaced 0x200 bytes apart */ 37/* VIA registers - spaced 0x200 bytes apart */
45#define RS 0x200 /* skip between registers */ 38#define RS 0x200 /* skip between registers */
46#define B 0 /* B-side data */ 39#define B 0 /* B-side data */
@@ -189,11 +182,24 @@ int __init find_via_cuda(void)
189 182
190static int __init via_cuda_start(void) 183static int __init via_cuda_start(void)
191{ 184{
185 unsigned int irq;
186
192 if (via == NULL) 187 if (via == NULL)
193 return -ENODEV; 188 return -ENODEV;
194 189
195 if (request_irq(CUDA_IRQ, cuda_interrupt, 0, "ADB", cuda_interrupt)) { 190#ifdef CONFIG_MAC
196 printk(KERN_ERR "cuda_init: can't get irq %d\n", CUDA_IRQ); 191 irq = IRQ_MAC_ADB;
192#else /* CONFIG_MAC */
193 irq = irq_of_parse_and_map(vias, 0);
194 if (irq == NO_IRQ) {
195 printk(KERN_ERR "via-cuda: can't map interrupts for %s\n",
196 vias->full_name);
197 return -ENODEV;
198 }
199#endif /* CONFIG_MAP */
200
201 if (request_irq(irq, cuda_interrupt, 0, "ADB", cuda_interrupt)) {
202 printk(KERN_ERR "via-cuda: can't request irq %d\n", irq);
197 return -EAGAIN; 203 return -EAGAIN;
198 } 204 }
199 205
diff --git a/drivers/macintosh/via-pmu.c b/drivers/macintosh/via-pmu.c
index c1193d34ec9e..06ca80bfd6b9 100644
--- a/drivers/macintosh/via-pmu.c
+++ b/drivers/macintosh/via-pmu.c
@@ -64,10 +64,6 @@
64#include <asm/backlight.h> 64#include <asm/backlight.h>
65#endif 65#endif
66 66
67#ifdef CONFIG_PPC32
68#include <asm/open_pic.h>
69#endif
70
71#include "via-pmu-event.h" 67#include "via-pmu-event.h"
72 68
73/* Some compile options */ 69/* Some compile options */
@@ -151,7 +147,7 @@ static int pmu_fully_inited = 0;
151static int pmu_has_adb; 147static int pmu_has_adb;
152static struct device_node *gpio_node; 148static struct device_node *gpio_node;
153static unsigned char __iomem *gpio_reg = NULL; 149static unsigned char __iomem *gpio_reg = NULL;
154static int gpio_irq = -1; 150static int gpio_irq = NO_IRQ;
155static int gpio_irq_enabled = -1; 151static int gpio_irq_enabled = -1;
156static volatile int pmu_suspended = 0; 152static volatile int pmu_suspended = 0;
157static spinlock_t pmu_lock; 153static spinlock_t pmu_lock;
@@ -403,22 +399,21 @@ static int __init pmu_init(void)
403 */ 399 */
404static int __init via_pmu_start(void) 400static int __init via_pmu_start(void)
405{ 401{
402 unsigned int irq;
403
406 if (vias == NULL) 404 if (vias == NULL)
407 return -ENODEV; 405 return -ENODEV;
408 406
409 batt_req.complete = 1; 407 batt_req.complete = 1;
410 408
411#ifndef CONFIG_PPC_MERGE 409 irq = irq_of_parse_and_map(vias, 0);
412 if (pmu_kind == PMU_KEYLARGO_BASED) 410 if (irq == NO_IRQ) {
413 openpic_set_irq_priority(vias->intrs[0].line, 411 printk(KERN_ERR "via-pmu: can't map interruptn");
414 OPENPIC_PRIORITY_DEFAULT + 1); 412 return -ENODEV;
415#endif 413 }
416 414 if (request_irq(irq, via_pmu_interrupt, 0, "VIA-PMU", (void *)0)) {
417 if (request_irq(vias->intrs[0].line, via_pmu_interrupt, 0, "VIA-PMU", 415 printk(KERN_ERR "via-pmu: can't request irq %d\n", irq);
418 (void *)0)) { 416 return -ENODEV;
419 printk(KERN_ERR "VIA-PMU: can't get irq %d\n",
420 vias->intrs[0].line);
421 return -EAGAIN;
422 } 417 }
423 418
424 if (pmu_kind == PMU_KEYLARGO_BASED) { 419 if (pmu_kind == PMU_KEYLARGO_BASED) {
@@ -426,10 +421,10 @@ static int __init via_pmu_start(void)
426 if (gpio_node == NULL) 421 if (gpio_node == NULL)
427 gpio_node = of_find_node_by_name(NULL, 422 gpio_node = of_find_node_by_name(NULL,
428 "pmu-interrupt"); 423 "pmu-interrupt");
429 if (gpio_node && gpio_node->n_intrs > 0) 424 if (gpio_node)
430 gpio_irq = gpio_node->intrs[0].line; 425 gpio_irq = irq_of_parse_and_map(gpio_node, 0);
431 426
432 if (gpio_irq != -1) { 427 if (gpio_irq != NO_IRQ) {
433 if (request_irq(gpio_irq, gpio1_interrupt, 0, 428 if (request_irq(gpio_irq, gpio1_interrupt, 0,
434 "GPIO1 ADB", (void *)0)) 429 "GPIO1 ADB", (void *)0))
435 printk(KERN_ERR "pmu: can't get irq %d" 430 printk(KERN_ERR "pmu: can't get irq %d"
diff --git a/drivers/md/md.c b/drivers/md/md.c
index 2fe32c261922..e4e161372a3e 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -1404,7 +1404,7 @@ static int lock_rdev(mdk_rdev_t *rdev, dev_t dev)
1404 struct block_device *bdev; 1404 struct block_device *bdev;
1405 char b[BDEVNAME_SIZE]; 1405 char b[BDEVNAME_SIZE];
1406 1406
1407 bdev = open_by_devnum(dev, FMODE_READ|FMODE_WRITE); 1407 bdev = open_partition_by_devnum(dev, FMODE_READ|FMODE_WRITE);
1408 if (IS_ERR(bdev)) { 1408 if (IS_ERR(bdev)) {
1409 printk(KERN_ERR "md: could not open %s.\n", 1409 printk(KERN_ERR "md: could not open %s.\n",
1410 __bdevname(dev, b)); 1410 __bdevname(dev, b));
@@ -1414,7 +1414,7 @@ static int lock_rdev(mdk_rdev_t *rdev, dev_t dev)
1414 if (err) { 1414 if (err) {
1415 printk(KERN_ERR "md: could not bd_claim %s.\n", 1415 printk(KERN_ERR "md: could not bd_claim %s.\n",
1416 bdevname(bdev, b)); 1416 bdevname(bdev, b));
1417 blkdev_put(bdev); 1417 blkdev_put_partition(bdev);
1418 return err; 1418 return err;
1419 } 1419 }
1420 rdev->bdev = bdev; 1420 rdev->bdev = bdev;
@@ -1428,7 +1428,7 @@ static void unlock_rdev(mdk_rdev_t *rdev)
1428 if (!bdev) 1428 if (!bdev)
1429 MD_BUG(); 1429 MD_BUG();
1430 bd_release(bdev); 1430 bd_release(bdev);
1431 blkdev_put(bdev); 1431 blkdev_put_partition(bdev);
1432} 1432}
1433 1433
1434void md_autodetect_dev(dev_t dev); 1434void md_autodetect_dev(dev_t dev);
diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c
index 247ff2f23ac9..33525bdf2ab6 100644
--- a/drivers/mmc/mmc.c
+++ b/drivers/mmc/mmc.c
@@ -128,7 +128,7 @@ static void mmc_wait_done(struct mmc_request *mrq)
128 128
129int mmc_wait_for_req(struct mmc_host *host, struct mmc_request *mrq) 129int mmc_wait_for_req(struct mmc_host *host, struct mmc_request *mrq)
130{ 130{
131 DECLARE_COMPLETION(complete); 131 DECLARE_COMPLETION_ONSTACK(complete);
132 132
133 mrq->done_data = &complete; 133 mrq->done_data = &complete;
134 mrq->done = mmc_wait_done; 134 mrq->done = mmc_wait_done;
diff --git a/drivers/net/3c59x.c b/drivers/net/3c59x.c
index 8ab03b4a885e..2819de79442c 100644
--- a/drivers/net/3c59x.c
+++ b/drivers/net/3c59x.c
@@ -1897,7 +1897,7 @@ vortex_timer(unsigned long data)
1897 printk(KERN_DEBUG "dev->watchdog_timeo=%d\n", dev->watchdog_timeo); 1897 printk(KERN_DEBUG "dev->watchdog_timeo=%d\n", dev->watchdog_timeo);
1898 } 1898 }
1899 1899
1900 disable_irq(dev->irq); 1900 disable_irq_lockdep(dev->irq);
1901 old_window = ioread16(ioaddr + EL3_CMD) >> 13; 1901 old_window = ioread16(ioaddr + EL3_CMD) >> 13;
1902 EL3WINDOW(4); 1902 EL3WINDOW(4);
1903 media_status = ioread16(ioaddr + Wn4_Media); 1903 media_status = ioread16(ioaddr + Wn4_Media);
@@ -1978,7 +1978,7 @@ leave_media_alone:
1978 dev->name, media_tbl[dev->if_port].name); 1978 dev->name, media_tbl[dev->if_port].name);
1979 1979
1980 EL3WINDOW(old_window); 1980 EL3WINDOW(old_window);
1981 enable_irq(dev->irq); 1981 enable_irq_lockdep(dev->irq);
1982 mod_timer(&vp->timer, RUN_AT(next_tick)); 1982 mod_timer(&vp->timer, RUN_AT(next_tick));
1983 if (vp->deferred) 1983 if (vp->deferred)
1984 iowrite16(FakeIntr, ioaddr + EL3_CMD); 1984 iowrite16(FakeIntr, ioaddr + EL3_CMD);
diff --git a/drivers/net/8390.c b/drivers/net/8390.c
index 86be96af9c8f..d2935ae39814 100644
--- a/drivers/net/8390.c
+++ b/drivers/net/8390.c
@@ -249,7 +249,7 @@ void ei_tx_timeout(struct net_device *dev)
249 249
250 /* Ugly but a reset can be slow, yet must be protected */ 250 /* Ugly but a reset can be slow, yet must be protected */
251 251
252 disable_irq_nosync(dev->irq); 252 disable_irq_nosync_lockdep(dev->irq);
253 spin_lock(&ei_local->page_lock); 253 spin_lock(&ei_local->page_lock);
254 254
255 /* Try to restart the card. Perhaps the user has fixed something. */ 255 /* Try to restart the card. Perhaps the user has fixed something. */
@@ -257,7 +257,7 @@ void ei_tx_timeout(struct net_device *dev)
257 NS8390_init(dev, 1); 257 NS8390_init(dev, 1);
258 258
259 spin_unlock(&ei_local->page_lock); 259 spin_unlock(&ei_local->page_lock);
260 enable_irq(dev->irq); 260 enable_irq_lockdep(dev->irq);
261 netif_wake_queue(dev); 261 netif_wake_queue(dev);
262} 262}
263 263
diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c
index 3c90003f4230..037d870712ff 100644
--- a/drivers/net/forcedeth.c
+++ b/drivers/net/forcedeth.c
@@ -2735,21 +2735,21 @@ static void nv_do_nic_poll(unsigned long data)
2735 2735
2736 if (!using_multi_irqs(dev)) { 2736 if (!using_multi_irqs(dev)) {
2737 if (np->msi_flags & NV_MSI_X_ENABLED) 2737 if (np->msi_flags & NV_MSI_X_ENABLED)
2738 disable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_ALL].vector); 2738 disable_irq_lockdep(np->msi_x_entry[NV_MSI_X_VECTOR_ALL].vector);
2739 else 2739 else
2740 disable_irq(dev->irq); 2740 disable_irq_lockdep(dev->irq);
2741 mask = np->irqmask; 2741 mask = np->irqmask;
2742 } else { 2742 } else {
2743 if (np->nic_poll_irq & NVREG_IRQ_RX_ALL) { 2743 if (np->nic_poll_irq & NVREG_IRQ_RX_ALL) {
2744 disable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_RX].vector); 2744 disable_irq_lockdep(np->msi_x_entry[NV_MSI_X_VECTOR_RX].vector);
2745 mask |= NVREG_IRQ_RX_ALL; 2745 mask |= NVREG_IRQ_RX_ALL;
2746 } 2746 }
2747 if (np->nic_poll_irq & NVREG_IRQ_TX_ALL) { 2747 if (np->nic_poll_irq & NVREG_IRQ_TX_ALL) {
2748 disable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_TX].vector); 2748 disable_irq_lockdep(np->msi_x_entry[NV_MSI_X_VECTOR_TX].vector);
2749 mask |= NVREG_IRQ_TX_ALL; 2749 mask |= NVREG_IRQ_TX_ALL;
2750 } 2750 }
2751 if (np->nic_poll_irq & NVREG_IRQ_OTHER) { 2751 if (np->nic_poll_irq & NVREG_IRQ_OTHER) {
2752 disable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_OTHER].vector); 2752 disable_irq_lockdep(np->msi_x_entry[NV_MSI_X_VECTOR_OTHER].vector);
2753 mask |= NVREG_IRQ_OTHER; 2753 mask |= NVREG_IRQ_OTHER;
2754 } 2754 }
2755 } 2755 }
@@ -2761,23 +2761,23 @@ static void nv_do_nic_poll(unsigned long data)
2761 pci_push(base); 2761 pci_push(base);
2762 2762
2763 if (!using_multi_irqs(dev)) { 2763 if (!using_multi_irqs(dev)) {
2764 nv_nic_irq((int) 0, (void *) data, (struct pt_regs *) NULL); 2764 nv_nic_irq(0, dev, NULL);
2765 if (np->msi_flags & NV_MSI_X_ENABLED) 2765 if (np->msi_flags & NV_MSI_X_ENABLED)
2766 enable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_ALL].vector); 2766 enable_irq_lockdep(np->msi_x_entry[NV_MSI_X_VECTOR_ALL].vector);
2767 else 2767 else
2768 enable_irq(dev->irq); 2768 enable_irq_lockdep(dev->irq);
2769 } else { 2769 } else {
2770 if (np->nic_poll_irq & NVREG_IRQ_RX_ALL) { 2770 if (np->nic_poll_irq & NVREG_IRQ_RX_ALL) {
2771 nv_nic_irq_rx((int) 0, (void *) data, (struct pt_regs *) NULL); 2771 nv_nic_irq_rx(0, dev, NULL);
2772 enable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_RX].vector); 2772 enable_irq_lockdep(np->msi_x_entry[NV_MSI_X_VECTOR_RX].vector);
2773 } 2773 }
2774 if (np->nic_poll_irq & NVREG_IRQ_TX_ALL) { 2774 if (np->nic_poll_irq & NVREG_IRQ_TX_ALL) {
2775 nv_nic_irq_tx((int) 0, (void *) data, (struct pt_regs *) NULL); 2775 nv_nic_irq_tx(0, dev, NULL);
2776 enable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_TX].vector); 2776 enable_irq_lockdep(np->msi_x_entry[NV_MSI_X_VECTOR_TX].vector);
2777 } 2777 }
2778 if (np->nic_poll_irq & NVREG_IRQ_OTHER) { 2778 if (np->nic_poll_irq & NVREG_IRQ_OTHER) {
2779 nv_nic_irq_other((int) 0, (void *) data, (struct pt_regs *) NULL); 2779 nv_nic_irq_other(0, dev, NULL);
2780 enable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_OTHER].vector); 2780 enable_irq_lockdep(np->msi_x_entry[NV_MSI_X_VECTOR_OTHER].vector);
2781 } 2781 }
2782 } 2782 }
2783} 2783}
diff --git a/drivers/net/mace.c b/drivers/net/mace.c
index f2c0bf89f0c7..29e4b5aa6ead 100644
--- a/drivers/net/mace.c
+++ b/drivers/net/mace.c
@@ -242,12 +242,12 @@ static int __devinit mace_probe(struct macio_dev *mdev, const struct of_device_i
242 } 242 }
243 rc = request_irq(mp->tx_dma_intr, mace_txdma_intr, 0, "MACE-txdma", dev); 243 rc = request_irq(mp->tx_dma_intr, mace_txdma_intr, 0, "MACE-txdma", dev);
244 if (rc) { 244 if (rc) {
245 printk(KERN_ERR "MACE: can't get irq %d\n", mace->intrs[1].line); 245 printk(KERN_ERR "MACE: can't get irq %d\n", mp->tx_dma_intr);
246 goto err_free_irq; 246 goto err_free_irq;
247 } 247 }
248 rc = request_irq(mp->rx_dma_intr, mace_rxdma_intr, 0, "MACE-rxdma", dev); 248 rc = request_irq(mp->rx_dma_intr, mace_rxdma_intr, 0, "MACE-rxdma", dev);
249 if (rc) { 249 if (rc) {
250 printk(KERN_ERR "MACE: can't get irq %d\n", mace->intrs[2].line); 250 printk(KERN_ERR "MACE: can't get irq %d\n", mp->rx_dma_intr);
251 goto err_free_tx_irq; 251 goto err_free_tx_irq;
252 } 252 }
253 253
diff --git a/drivers/net/wireless/hostap/hostap_hw.c b/drivers/net/wireless/hostap/hostap_hw.c
index b764cfda6e84..dafaa5ff5aa6 100644
--- a/drivers/net/wireless/hostap/hostap_hw.c
+++ b/drivers/net/wireless/hostap/hostap_hw.c
@@ -3095,6 +3095,14 @@ static void prism2_clear_set_tim_queue(local_info_t *local)
3095} 3095}
3096 3096
3097 3097
3098/*
3099 * HostAP uses two layers of net devices, where the inner
3100 * layer gets called all the time from the outer layer.
3101 * This is a natural nesting, which needs a split lock type.
3102 */
3103static struct lock_class_key hostap_netdev_xmit_lock_key;
3104
3105
3098static struct net_device * 3106static struct net_device *
3099prism2_init_local_data(struct prism2_helper_functions *funcs, int card_idx, 3107prism2_init_local_data(struct prism2_helper_functions *funcs, int card_idx,
3100 struct device *sdev) 3108 struct device *sdev)
@@ -3259,6 +3267,8 @@ while (0)
3259 SET_NETDEV_DEV(dev, sdev); 3267 SET_NETDEV_DEV(dev, sdev);
3260 if (ret >= 0) 3268 if (ret >= 0)
3261 ret = register_netdevice(dev); 3269 ret = register_netdevice(dev);
3270
3271 lockdep_set_class(&dev->_xmit_lock, &hostap_netdev_xmit_lock_key);
3262 rtnl_unlock(); 3272 rtnl_unlock();
3263 if (ret < 0) { 3273 if (ret < 0) {
3264 printk(KERN_WARNING "%s: register netdevice failed!\n", 3274 printk(KERN_WARNING "%s: register netdevice failed!\n",
diff --git a/drivers/pnp/pnpacpi/rsparser.c b/drivers/pnp/pnpacpi/rsparser.c
index 3a4a644c2686..212268881857 100644
--- a/drivers/pnp/pnpacpi/rsparser.c
+++ b/drivers/pnp/pnpacpi/rsparser.c
@@ -74,7 +74,7 @@ static void decode_irq_flags(int flag, int *triggering, int *polarity)
74 74
75static void 75static void
76pnpacpi_parse_allocated_irqresource(struct pnp_resource_table *res, u32 gsi, 76pnpacpi_parse_allocated_irqresource(struct pnp_resource_table *res, u32 gsi,
77 int triggering, int polarity) 77 int triggering, int polarity, int shareable)
78{ 78{
79 int i = 0; 79 int i = 0;
80 int irq; 80 int irq;
@@ -95,6 +95,9 @@ pnpacpi_parse_allocated_irqresource(struct pnp_resource_table *res, u32 gsi,
95 return; 95 return;
96 } 96 }
97 97
98 if (shareable)
99 res->irq_resource[i].flags |= IORESOURCE_IRQ_SHAREABLE;
100
98 res->irq_resource[i].start = irq; 101 res->irq_resource[i].start = irq;
99 res->irq_resource[i].end = irq; 102 res->irq_resource[i].end = irq;
100 pcibios_penalize_isa_irq(irq, 1); 103 pcibios_penalize_isa_irq(irq, 1);
@@ -194,7 +197,8 @@ static acpi_status pnpacpi_allocated_resource(struct acpi_resource *res,
194 pnpacpi_parse_allocated_irqresource(res_table, 197 pnpacpi_parse_allocated_irqresource(res_table,
195 res->data.irq.interrupts[i], 198 res->data.irq.interrupts[i],
196 res->data.irq.triggering, 199 res->data.irq.triggering,
197 res->data.irq.polarity); 200 res->data.irq.polarity,
201 res->data.irq.sharable);
198 } 202 }
199 break; 203 break;
200 204
@@ -255,7 +259,8 @@ static acpi_status pnpacpi_allocated_resource(struct acpi_resource *res,
255 pnpacpi_parse_allocated_irqresource(res_table, 259 pnpacpi_parse_allocated_irqresource(res_table,
256 res->data.extended_irq.interrupts[i], 260 res->data.extended_irq.interrupts[i],
257 res->data.extended_irq.triggering, 261 res->data.extended_irq.triggering,
258 res->data.extended_irq.polarity); 262 res->data.extended_irq.polarity,
263 res->data.extended_irq.sharable);
259 } 264 }
260 break; 265 break;
261 266
diff --git a/drivers/s390/char/sclp.c b/drivers/s390/char/sclp.c
index 4138564402b8..985d1613baaa 100644
--- a/drivers/s390/char/sclp.c
+++ b/drivers/s390/char/sclp.c
@@ -383,6 +383,7 @@ void
383sclp_sync_wait(void) 383sclp_sync_wait(void)
384{ 384{
385 unsigned long psw_mask; 385 unsigned long psw_mask;
386 unsigned long flags;
386 unsigned long cr0, cr0_sync; 387 unsigned long cr0, cr0_sync;
387 u64 timeout; 388 u64 timeout;
388 389
@@ -395,9 +396,11 @@ sclp_sync_wait(void)
395 sclp_tod_from_jiffies(sclp_request_timer.expires - 396 sclp_tod_from_jiffies(sclp_request_timer.expires -
396 jiffies); 397 jiffies);
397 } 398 }
399 local_irq_save(flags);
398 /* Prevent bottom half from executing once we force interrupts open */ 400 /* Prevent bottom half from executing once we force interrupts open */
399 local_bh_disable(); 401 local_bh_disable();
400 /* Enable service-signal interruption, disable timer interrupts */ 402 /* Enable service-signal interruption, disable timer interrupts */
403 trace_hardirqs_on();
401 __ctl_store(cr0, 0, 0); 404 __ctl_store(cr0, 0, 0);
402 cr0_sync = cr0; 405 cr0_sync = cr0;
403 cr0_sync |= 0x00000200; 406 cr0_sync |= 0x00000200;
@@ -415,11 +418,10 @@ sclp_sync_wait(void)
415 barrier(); 418 barrier();
416 cpu_relax(); 419 cpu_relax();
417 } 420 }
418 /* Restore interrupt settings */ 421 local_irq_disable();
419 asm volatile ("SSM 0(%0)"
420 : : "a" (&psw_mask) : "memory");
421 __ctl_load(cr0, 0, 0); 422 __ctl_load(cr0, 0, 0);
422 __local_bh_enable(); 423 _local_bh_enable();
424 local_irq_restore(flags);
423} 425}
424 426
425EXPORT_SYMBOL(sclp_sync_wait); 427EXPORT_SYMBOL(sclp_sync_wait);
diff --git a/drivers/s390/cio/cio.c b/drivers/s390/cio/cio.c
index a3423267467f..6fec90eab00e 100644
--- a/drivers/s390/cio/cio.c
+++ b/drivers/s390/cio/cio.c
@@ -147,7 +147,7 @@ cio_tpi(void)
147 sch->driver->irq(&sch->dev); 147 sch->driver->irq(&sch->dev);
148 spin_unlock(&sch->lock); 148 spin_unlock(&sch->lock);
149 irq_exit (); 149 irq_exit ();
150 __local_bh_enable(); 150 _local_bh_enable();
151 return 1; 151 return 1;
152} 152}
153 153
diff --git a/drivers/s390/net/qeth_main.c b/drivers/s390/net/qeth_main.c
index 36733b9823c6..8e8963f15731 100644
--- a/drivers/s390/net/qeth_main.c
+++ b/drivers/s390/net/qeth_main.c
@@ -84,6 +84,8 @@ static debug_info_t *qeth_dbf_qerr = NULL;
84 84
85DEFINE_PER_CPU(char[256], qeth_dbf_txt_buf); 85DEFINE_PER_CPU(char[256], qeth_dbf_txt_buf);
86 86
87static struct lock_class_key qdio_out_skb_queue_key;
88
87/** 89/**
88 * some more definitions and declarations 90 * some more definitions and declarations
89 */ 91 */
@@ -3229,6 +3231,9 @@ qeth_alloc_qdio_buffers(struct qeth_card *card)
3229 &card->qdio.out_qs[i]->qdio_bufs[j]; 3231 &card->qdio.out_qs[i]->qdio_bufs[j];
3230 skb_queue_head_init(&card->qdio.out_qs[i]->bufs[j]. 3232 skb_queue_head_init(&card->qdio.out_qs[i]->bufs[j].
3231 skb_list); 3233 skb_list);
3234 lockdep_set_class(
3235 &card->qdio.out_qs[i]->bufs[j].skb_list.lock,
3236 &qdio_out_skb_queue_key);
3232 INIT_LIST_HEAD(&card->qdio.out_qs[i]->bufs[j].ctx_list); 3237 INIT_LIST_HEAD(&card->qdio.out_qs[i]->bufs[j].ctx_list);
3233 } 3238 }
3234 } 3239 }
@@ -5272,6 +5277,7 @@ qeth_free_vlan_buffer(struct qeth_card *card, struct qeth_qdio_out_buffer *buf,
5272 struct sk_buff_head tmp_list; 5277 struct sk_buff_head tmp_list;
5273 5278
5274 skb_queue_head_init(&tmp_list); 5279 skb_queue_head_init(&tmp_list);
5280 lockdep_set_class(&tmp_list.lock, &qdio_out_skb_queue_key);
5275 for(i = 0; i < QETH_MAX_BUFFER_ELEMENTS(card); ++i){ 5281 for(i = 0; i < QETH_MAX_BUFFER_ELEMENTS(card); ++i){
5276 while ((skb = skb_dequeue(&buf->skb_list))){ 5282 while ((skb = skb_dequeue(&buf->skb_list))){
5277 if (vlan_tx_tag_present(skb) && 5283 if (vlan_tx_tag_present(skb) &&
diff --git a/drivers/s390/s390mach.c b/drivers/s390/s390mach.c
index 432136f96e64..ffb3677e354f 100644
--- a/drivers/s390/s390mach.c
+++ b/drivers/s390/s390mach.c
@@ -378,6 +378,8 @@ s390_do_machine_check(struct pt_regs *regs)
378 struct mcck_struct *mcck; 378 struct mcck_struct *mcck;
379 int umode; 379 int umode;
380 380
381 lockdep_off();
382
381 mci = (struct mci *) &S390_lowcore.mcck_interruption_code; 383 mci = (struct mci *) &S390_lowcore.mcck_interruption_code;
382 mcck = &__get_cpu_var(cpu_mcck); 384 mcck = &__get_cpu_var(cpu_mcck);
383 umode = user_mode(regs); 385 umode = user_mode(regs);
@@ -482,6 +484,7 @@ s390_do_machine_check(struct pt_regs *regs)
482 mcck->warning = 1; 484 mcck->warning = 1;
483 set_thread_flag(TIF_MCCK_PENDING); 485 set_thread_flag(TIF_MCCK_PENDING);
484 } 486 }
487 lockdep_on();
485} 488}
486 489
487/* 490/*
diff --git a/drivers/s390/scsi/zfcp_erp.c b/drivers/s390/scsi/zfcp_erp.c
index 909731b99d26..8ec8da0beaa8 100644
--- a/drivers/s390/scsi/zfcp_erp.c
+++ b/drivers/s390/scsi/zfcp_erp.c
@@ -2168,9 +2168,9 @@ zfcp_erp_adapter_strategy_open_fsf_xconfig(struct zfcp_erp_action *erp_action)
2168 atomic_clear_mask(ZFCP_STATUS_ADAPTER_HOST_CON_INIT, 2168 atomic_clear_mask(ZFCP_STATUS_ADAPTER_HOST_CON_INIT,
2169 &adapter->status); 2169 &adapter->status);
2170 ZFCP_LOG_DEBUG("Doing exchange config data\n"); 2170 ZFCP_LOG_DEBUG("Doing exchange config data\n");
2171 write_lock(&adapter->erp_lock); 2171 write_lock_irq(&adapter->erp_lock);
2172 zfcp_erp_action_to_running(erp_action); 2172 zfcp_erp_action_to_running(erp_action);
2173 write_unlock(&adapter->erp_lock); 2173 write_unlock_irq(&adapter->erp_lock);
2174 zfcp_erp_timeout_init(erp_action); 2174 zfcp_erp_timeout_init(erp_action);
2175 if (zfcp_fsf_exchange_config_data(erp_action)) { 2175 if (zfcp_fsf_exchange_config_data(erp_action)) {
2176 retval = ZFCP_ERP_FAILED; 2176 retval = ZFCP_ERP_FAILED;
@@ -2236,9 +2236,9 @@ zfcp_erp_adapter_strategy_open_fsf_xport(struct zfcp_erp_action *erp_action)
2236 adapter = erp_action->adapter; 2236 adapter = erp_action->adapter;
2237 atomic_clear_mask(ZFCP_STATUS_ADAPTER_XPORT_OK, &adapter->status); 2237 atomic_clear_mask(ZFCP_STATUS_ADAPTER_XPORT_OK, &adapter->status);
2238 2238
2239 write_lock(&adapter->erp_lock); 2239 write_lock_irq(&adapter->erp_lock);
2240 zfcp_erp_action_to_running(erp_action); 2240 zfcp_erp_action_to_running(erp_action);
2241 write_unlock(&adapter->erp_lock); 2241 write_unlock_irq(&adapter->erp_lock);
2242 2242
2243 zfcp_erp_timeout_init(erp_action); 2243 zfcp_erp_timeout_init(erp_action);
2244 ret = zfcp_fsf_exchange_port_data(erp_action, adapter, NULL); 2244 ret = zfcp_fsf_exchange_port_data(erp_action, adapter, NULL);
diff --git a/drivers/s390/scsi/zfcp_qdio.c b/drivers/s390/scsi/zfcp_qdio.c
index 345a191926a4..49ea5add4abc 100644
--- a/drivers/s390/scsi/zfcp_qdio.c
+++ b/drivers/s390/scsi/zfcp_qdio.c
@@ -427,6 +427,7 @@ int
427zfcp_qdio_reqid_check(struct zfcp_adapter *adapter, void *sbale_addr) 427zfcp_qdio_reqid_check(struct zfcp_adapter *adapter, void *sbale_addr)
428{ 428{
429 struct zfcp_fsf_req *fsf_req; 429 struct zfcp_fsf_req *fsf_req;
430 unsigned long flags;
430 431
431 /* invalid (per convention used in this driver) */ 432 /* invalid (per convention used in this driver) */
432 if (unlikely(!sbale_addr)) { 433 if (unlikely(!sbale_addr)) {
@@ -438,15 +439,15 @@ zfcp_qdio_reqid_check(struct zfcp_adapter *adapter, void *sbale_addr)
438 fsf_req = (struct zfcp_fsf_req *) sbale_addr; 439 fsf_req = (struct zfcp_fsf_req *) sbale_addr;
439 440
440 /* serialize with zfcp_fsf_req_dismiss_all */ 441 /* serialize with zfcp_fsf_req_dismiss_all */
441 spin_lock(&adapter->fsf_req_list_lock); 442 spin_lock_irqsave(&adapter->fsf_req_list_lock, flags);
442 if (list_empty(&adapter->fsf_req_list_head)) { 443 if (list_empty(&adapter->fsf_req_list_head)) {
443 spin_unlock(&adapter->fsf_req_list_lock); 444 spin_unlock_irqrestore(&adapter->fsf_req_list_lock, flags);
444 return 0; 445 return 0;
445 } 446 }
446 list_del(&fsf_req->list); 447 list_del(&fsf_req->list);
447 atomic_dec(&adapter->fsf_reqs_active); 448 atomic_dec(&adapter->fsf_reqs_active);
448 spin_unlock(&adapter->fsf_req_list_lock); 449 spin_unlock_irqrestore(&adapter->fsf_req_list_lock, flags);
449 450
450 if (unlikely(adapter != fsf_req->adapter)) { 451 if (unlikely(adapter != fsf_req->adapter)) {
451 ZFCP_LOG_NORMAL("bug: invalid reqid (fsf_req=%p, " 452 ZFCP_LOG_NORMAL("bug: invalid reqid (fsf_req=%p, "
452 "fsf_req->adapter=%p, adapter=%p)\n", 453 "fsf_req->adapter=%p, adapter=%p)\n",
diff --git a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c
index 82caba464291..1c960ac1617f 100644
--- a/drivers/scsi/libata-core.c
+++ b/drivers/scsi/libata-core.c
@@ -1001,7 +1001,7 @@ unsigned ata_exec_internal(struct ata_device *dev,
1001 struct ata_queued_cmd *qc; 1001 struct ata_queued_cmd *qc;
1002 unsigned int tag, preempted_tag; 1002 unsigned int tag, preempted_tag;
1003 u32 preempted_sactive, preempted_qc_active; 1003 u32 preempted_sactive, preempted_qc_active;
1004 DECLARE_COMPLETION(wait); 1004 DECLARE_COMPLETION_ONSTACK(wait);
1005 unsigned long flags; 1005 unsigned long flags;
1006 unsigned int err_mask; 1006 unsigned int err_mask;
1007 int rc; 1007 int rc;
diff --git a/drivers/serial/8250_pnp.c b/drivers/serial/8250_pnp.c
index 739bc84f91e9..632f62d6ec7e 100644
--- a/drivers/serial/8250_pnp.c
+++ b/drivers/serial/8250_pnp.c
@@ -431,6 +431,8 @@ serial_pnp_probe(struct pnp_dev *dev, const struct pnp_device_id *dev_id)
431#endif 431#endif
432 432
433 port.flags |= UPF_SKIP_TEST | UPF_BOOT_AUTOCONF; 433 port.flags |= UPF_SKIP_TEST | UPF_BOOT_AUTOCONF;
434 if (pnp_irq_flags(dev, 0) & IORESOURCE_IRQ_SHAREABLE)
435 port.flags |= UPF_SHARE_IRQ;
434 port.uartclk = 1843200; 436 port.uartclk = 1843200;
435 port.dev = &dev->dev; 437 port.dev = &dev->dev;
436 438
diff --git a/drivers/serial/pmac_zilog.c b/drivers/serial/pmac_zilog.c
index 459c0231aef3..bfd2a22759eb 100644
--- a/drivers/serial/pmac_zilog.c
+++ b/drivers/serial/pmac_zilog.c
@@ -1443,8 +1443,8 @@ static int __init pmz_init_port(struct uart_pmac_port *uap)
1443 uap->flags &= ~PMACZILOG_FLAG_HAS_DMA; 1443 uap->flags &= ~PMACZILOG_FLAG_HAS_DMA;
1444 goto no_dma; 1444 goto no_dma;
1445 } 1445 }
1446 uap->tx_dma_irq = np->intrs[1].line; 1446 uap->tx_dma_irq = irq_of_parse_and_map(np, 1);
1447 uap->rx_dma_irq = np->intrs[2].line; 1447 uap->rx_dma_irq = irq_of_parse_and_map(np, 2);
1448 } 1448 }
1449no_dma: 1449no_dma:
1450 1450
@@ -1491,7 +1491,7 @@ no_dma:
1491 * Init remaining bits of "port" structure 1491 * Init remaining bits of "port" structure
1492 */ 1492 */
1493 uap->port.iotype = UPIO_MEM; 1493 uap->port.iotype = UPIO_MEM;
1494 uap->port.irq = np->intrs[0].line; 1494 uap->port.irq = irq_of_parse_and_map(np, 0);
1495 uap->port.uartclk = ZS_CLOCK; 1495 uap->port.uartclk = ZS_CLOCK;
1496 uap->port.fifosize = 1; 1496 uap->port.fifosize = 1;
1497 uap->port.ops = &pmz_pops; 1497 uap->port.ops = &pmz_pops;
diff --git a/drivers/serial/serial_core.c b/drivers/serial/serial_core.c
index c54af8774393..95831808334c 100644
--- a/drivers/serial/serial_core.c
+++ b/drivers/serial/serial_core.c
@@ -49,6 +49,12 @@
49 */ 49 */
50static DEFINE_MUTEX(port_mutex); 50static DEFINE_MUTEX(port_mutex);
51 51
52/*
53 * lockdep: port->lock is initialized in two places, but we
54 * want only one lock-class:
55 */
56static struct lock_class_key port_lock_key;
57
52#define HIGH_BITS_OFFSET ((sizeof(long)-sizeof(int))*8) 58#define HIGH_BITS_OFFSET ((sizeof(long)-sizeof(int))*8)
53 59
54#define uart_users(state) ((state)->count + ((state)->info ? (state)->info->blocked_open : 0)) 60#define uart_users(state) ((state)->count + ((state)->info ? (state)->info->blocked_open : 0))
@@ -1865,6 +1871,7 @@ uart_set_options(struct uart_port *port, struct console *co,
1865 * early. 1871 * early.
1866 */ 1872 */
1867 spin_lock_init(&port->lock); 1873 spin_lock_init(&port->lock);
1874 lockdep_set_class(&port->lock, &port_lock_key);
1868 1875
1869 memset(&termios, 0, sizeof(struct termios)); 1876 memset(&termios, 0, sizeof(struct termios));
1870 1877
@@ -2247,8 +2254,10 @@ int uart_add_one_port(struct uart_driver *drv, struct uart_port *port)
2247 * If this port is a console, then the spinlock is already 2254 * If this port is a console, then the spinlock is already
2248 * initialised. 2255 * initialised.
2249 */ 2256 */
2250 if (!(uart_console(port) && (port->cons->flags & CON_ENABLED))) 2257 if (!(uart_console(port) && (port->cons->flags & CON_ENABLED))) {
2251 spin_lock_init(&port->lock); 2258 spin_lock_init(&port->lock);
2259 lockdep_set_class(&port->lock, &port_lock_key);
2260 }
2252 2261
2253 uart_configure_port(drv, state, port); 2262 uart_configure_port(drv, state, port);
2254 2263
diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c
index ed1cdf6ac8f3..146298ad7371 100644
--- a/drivers/spi/spi.c
+++ b/drivers/spi/spi.c
@@ -510,7 +510,7 @@ static void spi_complete(void *arg)
510 */ 510 */
511int spi_sync(struct spi_device *spi, struct spi_message *message) 511int spi_sync(struct spi_device *spi, struct spi_message *message)
512{ 512{
513 DECLARE_COMPLETION(done); 513 DECLARE_COMPLETION_ONSTACK(done);
514 int status; 514 int status;
515 515
516 message->complete = spi_complete; 516 message->complete = spi_complete;
diff --git a/drivers/usb/core/inode.c b/drivers/usb/core/inode.c
index e47e3a8ed6e4..f48c3dbc367a 100644
--- a/drivers/usb/core/inode.c
+++ b/drivers/usb/core/inode.c
@@ -200,7 +200,7 @@ static void update_sb(struct super_block *sb)
200 if (!root) 200 if (!root)
201 return; 201 return;
202 202
203 mutex_lock(&root->d_inode->i_mutex); 203 mutex_lock_nested(&root->d_inode->i_mutex, I_MUTEX_PARENT);
204 204
205 list_for_each_entry(bus, &root->d_subdirs, d_u.d_child) { 205 list_for_each_entry(bus, &root->d_subdirs, d_u.d_child) {
206 if (bus->d_inode) { 206 if (bus->d_inode) {
@@ -527,7 +527,7 @@ static void fs_remove_file (struct dentry *dentry)
527 if (!parent || !parent->d_inode) 527 if (!parent || !parent->d_inode)
528 return; 528 return;
529 529
530 mutex_lock(&parent->d_inode->i_mutex); 530 mutex_lock_nested(&parent->d_inode->i_mutex, I_MUTEX_PARENT);
531 if (usbfs_positive(dentry)) { 531 if (usbfs_positive(dentry)) {
532 if (dentry->d_inode) { 532 if (dentry->d_inode) {
533 if (S_ISDIR(dentry->d_inode->i_mode)) 533 if (S_ISDIR(dentry->d_inode->i_mode))
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index 17de4c84db69..3badb48d662b 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -1557,6 +1557,21 @@ config FB_S3C2410_DEBUG
1557 Turn on debugging messages. Note that you can set/unset at run time 1557 Turn on debugging messages. Note that you can set/unset at run time
1558 through sysfs 1558 through sysfs
1559 1559
1560config FB_PNX4008_DUM
1561 tristate "Display Update Module support on Philips PNX4008 board"
1562 depends on FB && ARCH_PNX4008
1563 ---help---
1564 Say Y here to enable support for PNX4008 Display Update Module (DUM)
1565
1566config FB_PNX4008_DUM_RGB
1567 tristate "RGB Framebuffer support on Philips PNX4008 board"
1568 depends on FB_PNX4008_DUM
1569 select FB_CFB_FILLRECT
1570 select FB_CFB_COPYAREA
1571 select FB_CFB_IMAGEBLIT
1572 ---help---
1573 Say Y here to enable support for PNX4008 RGB Framebuffer
1574
1560config FB_VIRTUAL 1575config FB_VIRTUAL
1561 tristate "Virtual Frame Buffer support (ONLY FOR TESTING!)" 1576 tristate "Virtual Frame Buffer support (ONLY FOR TESTING!)"
1562 depends on FB 1577 depends on FB
diff --git a/drivers/video/Makefile b/drivers/video/Makefile
index c335e9bc3b20..6283d015f8f5 100644
--- a/drivers/video/Makefile
+++ b/drivers/video/Makefile
@@ -94,6 +94,8 @@ obj-$(CONFIG_FB_TX3912) += tx3912fb.o
94obj-$(CONFIG_FB_S1D13XXX) += s1d13xxxfb.o 94obj-$(CONFIG_FB_S1D13XXX) += s1d13xxxfb.o
95obj-$(CONFIG_FB_IMX) += imxfb.o 95obj-$(CONFIG_FB_IMX) += imxfb.o
96obj-$(CONFIG_FB_S3C2410) += s3c2410fb.o 96obj-$(CONFIG_FB_S3C2410) += s3c2410fb.o
97obj-$(CONFIG_FB_PNX4008_DUM) += pnx4008/
98obj-$(CONFIG_FB_PNX4008_DUM_RGB) += pnx4008/
97 99
98# Platform or fallback drivers go here 100# Platform or fallback drivers go here
99obj-$(CONFIG_FB_VESA) += vesafb.o 101obj-$(CONFIG_FB_VESA) += vesafb.o
diff --git a/drivers/video/offb.c b/drivers/video/offb.c
index bfeb11bd4712..71ce1fa45cf4 100644
--- a/drivers/video/offb.c
+++ b/drivers/video/offb.c
@@ -97,14 +97,43 @@ static int offb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
97 u_int transp, struct fb_info *info) 97 u_int transp, struct fb_info *info)
98{ 98{
99 struct offb_par *par = (struct offb_par *) info->par; 99 struct offb_par *par = (struct offb_par *) info->par;
100 int i, depth;
101 u32 *pal = info->pseudo_palette;
100 102
101 if (!par->cmap_adr || regno > 255) 103 depth = info->var.bits_per_pixel;
104 if (depth == 16)
105 depth = (info->var.green.length == 5) ? 15 : 16;
106
107 if (regno > 255 ||
108 (depth == 16 && regno > 63) ||
109 (depth == 15 && regno > 31))
102 return 1; 110 return 1;
103 111
112 if (regno < 16) {
113 switch (depth) {
114 case 15:
115 pal[regno] = (regno << 10) | (regno << 5) | regno;
116 break;
117 case 16:
118 pal[regno] = (regno << 11) | (regno << 5) | regno;
119 break;
120 case 24:
121 pal[regno] = (regno << 16) | (regno << 8) | regno;
122 break;
123 case 32:
124 i = (regno << 8) | regno;
125 pal[regno] = (i << 16) | i;
126 break;
127 }
128 }
129
104 red >>= 8; 130 red >>= 8;
105 green >>= 8; 131 green >>= 8;
106 blue >>= 8; 132 blue >>= 8;
107 133
134 if (!par->cmap_adr)
135 return 0;
136
108 switch (par->cmap_type) { 137 switch (par->cmap_type) {
109 case cmap_m64: 138 case cmap_m64:
110 writeb(regno, par->cmap_adr); 139 writeb(regno, par->cmap_adr);
@@ -141,20 +170,6 @@ static int offb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
141 break; 170 break;
142 } 171 }
143 172
144 if (regno < 16)
145 switch (info->var.bits_per_pixel) {
146 case 16:
147 ((u16 *) (info->pseudo_palette))[regno] =
148 (regno << 10) | (regno << 5) | regno;
149 break;
150 case 32:
151 {
152 int i = (regno << 8) | regno;
153 ((u32 *) (info->pseudo_palette))[regno] =
154 (i << 16) | i;
155 break;
156 }
157 }
158 return 0; 173 return 0;
159} 174}
160 175
@@ -223,81 +238,9 @@ int __init offb_init(void)
223{ 238{
224 struct device_node *dp = NULL, *boot_disp = NULL; 239 struct device_node *dp = NULL, *boot_disp = NULL;
225 240
226#if defined(CONFIG_BOOTX_TEXT) && defined(CONFIG_PPC32)
227 struct device_node *macos_display = NULL;
228#endif
229 if (fb_get_options("offb", NULL)) 241 if (fb_get_options("offb", NULL))
230 return -ENODEV; 242 return -ENODEV;
231 243
232#if defined(CONFIG_BOOTX_TEXT) && defined(CONFIG_PPC32)
233 /* If we're booted from BootX... */
234 if (boot_infos != 0) {
235 unsigned long addr =
236 (unsigned long) boot_infos->dispDeviceBase;
237 u32 *addrp;
238 u64 daddr, dsize;
239 unsigned int flags;
240
241 /* find the device node corresponding to the macos display */
242 while ((dp = of_find_node_by_type(dp, "display"))) {
243 int i;
244
245 /*
246 * Look for an AAPL,address property first.
247 */
248 unsigned int na;
249 unsigned int *ap =
250 (unsigned int *)get_property(dp, "AAPL,address",
251 &na);
252 if (ap != 0) {
253 for (na /= sizeof(unsigned int); na > 0;
254 --na, ++ap)
255 if (*ap <= addr &&
256 addr < *ap + 0x1000000) {
257 macos_display = dp;
258 goto foundit;
259 }
260 }
261
262 /*
263 * See if the display address is in one of the address
264 * ranges for this display.
265 */
266 i = 0;
267 for (;;) {
268 addrp = of_get_address(dp, i++, &dsize, &flags);
269 if (addrp == NULL)
270 break;
271 if (!(flags & IORESOURCE_MEM))
272 continue;
273 daddr = of_translate_address(dp, addrp);
274 if (daddr == OF_BAD_ADDR)
275 continue;
276 if (daddr <= addr && addr < (daddr + dsize)) {
277 macos_display = dp;
278 goto foundit;
279 }
280 }
281 foundit:
282 if (macos_display) {
283 printk(KERN_INFO "MacOS display is %s\n",
284 dp->full_name);
285 break;
286 }
287 }
288
289 /* initialize it */
290 offb_init_fb(macos_display ? macos_display->
291 name : "MacOS display",
292 macos_display ? macos_display->
293 full_name : "MacOS display",
294 boot_infos->dispDeviceRect[2],
295 boot_infos->dispDeviceRect[3],
296 boot_infos->dispDeviceDepth,
297 boot_infos->dispDeviceRowBytes, addr, NULL);
298 }
299#endif /* defined(CONFIG_BOOTX_TEXT) && defined(CONFIG_PPC32) */
300
301 for (dp = NULL; (dp = of_find_node_by_type(dp, "display"));) { 244 for (dp = NULL; (dp = of_find_node_by_type(dp, "display"));) {
302 if (get_property(dp, "linux,opened", NULL) && 245 if (get_property(dp, "linux,opened", NULL) &&
303 get_property(dp, "linux,boot-display", NULL)) { 246 get_property(dp, "linux,boot-display", NULL)) {
@@ -317,94 +260,93 @@ int __init offb_init(void)
317 260
318static void __init offb_init_nodriver(struct device_node *dp) 261static void __init offb_init_nodriver(struct device_node *dp)
319{ 262{
320 int *pp, i;
321 unsigned int len; 263 unsigned int len;
322 int width = 640, height = 480, depth = 8, pitch; 264 int i, width = 640, height = 480, depth = 8, pitch = 640;
323 unsigned int flags, rsize, *up; 265 unsigned int flags, rsize, addr_prop = 0;
324 u64 address = OF_BAD_ADDR; 266 unsigned long max_size = 0;
325 u32 *addrp; 267 u64 rstart, address = OF_BAD_ADDR;
268 u32 *pp, *addrp, *up;
326 u64 asize; 269 u64 asize;
327 270
328 if ((pp = (int *) get_property(dp, "depth", &len)) != NULL 271 pp = (u32 *)get_property(dp, "linux,bootx-depth", &len);
329 && len == sizeof(int)) 272 if (pp == NULL)
273 pp = (u32 *)get_property(dp, "depth", &len);
274 if (pp && len == sizeof(u32))
330 depth = *pp; 275 depth = *pp;
331 if ((pp = (int *) get_property(dp, "width", &len)) != NULL 276
332 && len == sizeof(int)) 277 pp = (u32 *)get_property(dp, "linux,bootx-width", &len);
278 if (pp == NULL)
279 pp = (u32 *)get_property(dp, "width", &len);
280 if (pp && len == sizeof(u32))
333 width = *pp; 281 width = *pp;
334 if ((pp = (int *) get_property(dp, "height", &len)) != NULL 282
335 && len == sizeof(int)) 283 pp = (u32 *)get_property(dp, "linux,bootx-height", &len);
284 if (pp == NULL)
285 pp = (u32 *)get_property(dp, "height", &len);
286 if (pp && len == sizeof(u32))
336 height = *pp; 287 height = *pp;
337 if ((pp = (int *) get_property(dp, "linebytes", &len)) != NULL 288
338 && len == sizeof(int)) { 289 pp = (u32 *)get_property(dp, "linux,bootx-linebytes", &len);
290 if (pp == NULL)
291 pp = (u32 *)get_property(dp, "linebytes", &len);
292 if (pp && len == sizeof(u32))
339 pitch = *pp; 293 pitch = *pp;
340 if (pitch == 1) 294 else
341 pitch = 0x1000; 295 pitch = width * ((depth + 7) / 8);
342 } else 296
343 pitch = width; 297 rsize = (unsigned long)pitch * (unsigned long)height;
344 298
345 rsize = (unsigned long)pitch * (unsigned long)height * 299 /* Ok, now we try to figure out the address of the framebuffer.
346 (unsigned long)(depth / 8); 300 *
347 301 * Unfortunately, Open Firmware doesn't provide a standard way to do
348 /* Try to match device to a PCI device in order to get a properly 302 * so. All we can do is a dodgy heuristic that happens to work in
349 * translated address rather then trying to decode the open firmware 303 * practice. On most machines, the "address" property contains what
350 * stuff in various incorrect ways 304 * we need, though not on Matrox cards found in IBM machines. What I've
351 */ 305 * found that appears to give good results is to go through the PCI
352#ifdef CONFIG_PCI 306 * ranges and pick one that is both big enough and if possible encloses
353 /* First try to locate the PCI device if any */ 307 * the "address" property. If none match, we pick the biggest
354 { 308 */
355 struct pci_dev *pdev = NULL; 309 up = (u32 *)get_property(dp, "linux,bootx-addr", &len);
356 310 if (up == NULL)
357 for_each_pci_dev(pdev) { 311 up = (u32 *)get_property(dp, "address", &len);
358 if (dp == pci_device_to_OF_node(pdev)) 312 if (up && len == sizeof(u32))
359 break; 313 addr_prop = *up;
360 } 314
361 if (pdev) { 315 for (i = 0; (addrp = of_get_address(dp, i, &asize, &flags))
362 for (i = 0; i < 6 && address == OF_BAD_ADDR; i++) { 316 != NULL; i++) {
363 if ((pci_resource_flags(pdev, i) & 317 int match_addrp = 0;
364 IORESOURCE_MEM) && 318
365 (pci_resource_len(pdev, i) >= rsize)) 319 if (!(flags & IORESOURCE_MEM))
366 address = pci_resource_start(pdev, i); 320 continue;
367 } 321 if (asize < rsize)
368 pci_dev_put(pdev); 322 continue;
369 } 323 rstart = of_translate_address(dp, addrp);
370 } 324 if (rstart == OF_BAD_ADDR)
371#endif /* CONFIG_PCI */ 325 continue;
372 326 if (addr_prop && (rstart <= addr_prop) &&
373 /* This one is dodgy, we may drop it ... */ 327 ((rstart + asize) >= (addr_prop + rsize)))
374 if (address == OF_BAD_ADDR && 328 match_addrp = 1;
375 (up = (unsigned *) get_property(dp, "address", &len)) != NULL && 329 if (match_addrp) {
376 len == sizeof(unsigned int)) 330 address = addr_prop;
377 address = (u64) * up; 331 break;
378
379 if (address == OF_BAD_ADDR) {
380 for (i = 0; (addrp = of_get_address(dp, i, &asize, &flags))
381 != NULL; i++) {
382 if (!(flags & IORESOURCE_MEM))
383 continue;
384 if (asize >= pitch * height * depth / 8)
385 break;
386 }
387 if (addrp == NULL) {
388 printk(KERN_ERR
389 "no framebuffer address found for %s\n",
390 dp->full_name);
391 return;
392 }
393 address = of_translate_address(dp, addrp);
394 if (address == OF_BAD_ADDR) {
395 printk(KERN_ERR
396 "can't translate framebuffer address for %s\n",
397 dp->full_name);
398 return;
399 } 332 }
333 if (rsize > max_size) {
334 max_size = rsize;
335 address = OF_BAD_ADDR;
336 }
400 337
338 if (address == OF_BAD_ADDR)
339 address = rstart;
340 }
341 if (address == OF_BAD_ADDR && addr_prop)
342 address = (u64)addr_prop;
343 if (address != OF_BAD_ADDR) {
401 /* kludge for valkyrie */ 344 /* kludge for valkyrie */
402 if (strcmp(dp->name, "valkyrie") == 0) 345 if (strcmp(dp->name, "valkyrie") == 0)
403 address += 0x1000; 346 address += 0x1000;
347 offb_init_fb(dp->name, dp->full_name, width, height, depth,
348 pitch, address, dp);
404 } 349 }
405 offb_init_fb(dp->name, dp->full_name, width, height, depth,
406 pitch, address, dp);
407
408} 350}
409 351
410static void __init offb_init_fb(const char *name, const char *full_name, 352static void __init offb_init_fb(const char *name, const char *full_name,
@@ -412,7 +354,7 @@ static void __init offb_init_fb(const char *name, const char *full_name,
412 int pitch, unsigned long address, 354 int pitch, unsigned long address,
413 struct device_node *dp) 355 struct device_node *dp)
414{ 356{
415 unsigned long res_size = pitch * height * depth / 8; 357 unsigned long res_size = pitch * height * (depth + 7) / 8;
416 struct offb_par *par = &default_par; 358 struct offb_par *par = &default_par;
417 unsigned long res_start = address; 359 unsigned long res_start = address;
418 struct fb_fix_screeninfo *fix; 360 struct fb_fix_screeninfo *fix;
@@ -426,7 +368,7 @@ static void __init offb_init_fb(const char *name, const char *full_name,
426 printk(KERN_INFO 368 printk(KERN_INFO
427 "Using unsupported %dx%d %s at %lx, depth=%d, pitch=%d\n", 369 "Using unsupported %dx%d %s at %lx, depth=%d, pitch=%d\n",
428 width, height, name, address, depth, pitch); 370 width, height, name, address, depth, pitch);
429 if (depth != 8 && depth != 16 && depth != 32) { 371 if (depth != 8 && depth != 15 && depth != 16 && depth != 32) {
430 printk(KERN_ERR "%s: can't use depth = %d\n", full_name, 372 printk(KERN_ERR "%s: can't use depth = %d\n", full_name,
431 depth); 373 depth);
432 release_mem_region(res_start, res_size); 374 release_mem_region(res_start, res_size);
@@ -502,7 +444,6 @@ static void __init offb_init_fb(const char *name, const char *full_name,
502 : */ FB_VISUAL_TRUECOLOR; 444 : */ FB_VISUAL_TRUECOLOR;
503 445
504 var->xoffset = var->yoffset = 0; 446 var->xoffset = var->yoffset = 0;
505 var->bits_per_pixel = depth;
506 switch (depth) { 447 switch (depth) {
507 case 8: 448 case 8:
508 var->bits_per_pixel = 8; 449 var->bits_per_pixel = 8;
@@ -515,7 +456,7 @@ static void __init offb_init_fb(const char *name, const char *full_name,
515 var->transp.offset = 0; 456 var->transp.offset = 0;
516 var->transp.length = 0; 457 var->transp.length = 0;
517 break; 458 break;
518 case 16: /* RGB 555 */ 459 case 15: /* RGB 555 */
519 var->bits_per_pixel = 16; 460 var->bits_per_pixel = 16;
520 var->red.offset = 10; 461 var->red.offset = 10;
521 var->red.length = 5; 462 var->red.length = 5;
@@ -526,6 +467,17 @@ static void __init offb_init_fb(const char *name, const char *full_name,
526 var->transp.offset = 0; 467 var->transp.offset = 0;
527 var->transp.length = 0; 468 var->transp.length = 0;
528 break; 469 break;
470 case 16: /* RGB 565 */
471 var->bits_per_pixel = 16;
472 var->red.offset = 11;
473 var->red.length = 5;
474 var->green.offset = 5;
475 var->green.length = 6;
476 var->blue.offset = 0;
477 var->blue.length = 5;
478 var->transp.offset = 0;
479 var->transp.length = 0;
480 break;
529 case 32: /* RGB 888 */ 481 case 32: /* RGB 888 */
530 var->bits_per_pixel = 32; 482 var->bits_per_pixel = 32;
531 var->red.offset = 16; 483 var->red.offset = 16;
diff --git a/drivers/video/pnx4008/Makefile b/drivers/video/pnx4008/Makefile
new file mode 100644
index 000000000000..636aaccf01fd
--- /dev/null
+++ b/drivers/video/pnx4008/Makefile
@@ -0,0 +1,7 @@
1#
2# Makefile for the new PNX4008 framebuffer device driver
3#
4
5obj-$(CONFIG_FB_PNX4008_DUM) += sdum.o
6obj-$(CONFIG_FB_PNX4008_DUM_RGB) += pnxrgbfb.o
7
diff --git a/drivers/video/pnx4008/dum.h b/drivers/video/pnx4008/dum.h
new file mode 100644
index 000000000000..d80a614d89ed
--- /dev/null
+++ b/drivers/video/pnx4008/dum.h
@@ -0,0 +1,211 @@
1/*
2 * linux/drivers/video/pnx4008/dum.h
3 *
4 * Internal header for SDUM
5 *
6 * 2005 (c) Koninklijke Philips N.V. This file is licensed under
7 * the terms of the GNU General Public License version 2. This program
8 * is licensed "as is" without any warranty of any kind, whether express
9 * or implied.
10 */
11
12#ifndef __PNX008_DUM_H__
13#define __PNX008_DUM_H__
14
15#include <asm/arch/platform.h>
16
17#define PNX4008_DUMCONF_VA_BASE IO_ADDRESS(PNX4008_DUMCONF_BASE)
18#define PNX4008_DUM_MAIN_VA_BASE IO_ADDRESS(PNX4008_DUM_MAINCFG_BASE)
19
20/* DUM CFG ADDRESSES */
21#define DUM_CH_BASE_ADR (PNX4008_DUMCONF_VA_BASE + 0x00)
22#define DUM_CH_MIN_ADR (PNX4008_DUMCONF_VA_BASE + 0x00)
23#define DUM_CH_MAX_ADR (PNX4008_DUMCONF_VA_BASE + 0x04)
24#define DUM_CH_CONF_ADR (PNX4008_DUMCONF_VA_BASE + 0x08)
25#define DUM_CH_STAT_ADR (PNX4008_DUMCONF_VA_BASE + 0x0C)
26#define DUM_CH_CTRL_ADR (PNX4008_DUMCONF_VA_BASE + 0x10)
27
28#define CH_MARG (0x100 / sizeof(u32))
29#define DUM_CH_MIN(i) (*((volatile u32 *)DUM_CH_MIN_ADR + (i) * CH_MARG))
30#define DUM_CH_MAX(i) (*((volatile u32 *)DUM_CH_MAX_ADR + (i) * CH_MARG))
31#define DUM_CH_CONF(i) (*((volatile u32 *)DUM_CH_CONF_ADR + (i) * CH_MARG))
32#define DUM_CH_STAT(i) (*((volatile u32 *)DUM_CH_STAT_ADR + (i) * CH_MARG))
33#define DUM_CH_CTRL(i) (*((volatile u32 *)DUM_CH_CTRL_ADR + (i) * CH_MARG))
34
35#define DUM_CONF_ADR (PNX4008_DUM_MAIN_VA_BASE + 0x00)
36#define DUM_CTRL_ADR (PNX4008_DUM_MAIN_VA_BASE + 0x04)
37#define DUM_STAT_ADR (PNX4008_DUM_MAIN_VA_BASE + 0x08)
38#define DUM_DECODE_ADR (PNX4008_DUM_MAIN_VA_BASE + 0x0C)
39#define DUM_COM_BASE_ADR (PNX4008_DUM_MAIN_VA_BASE + 0x10)
40#define DUM_SYNC_C_ADR (PNX4008_DUM_MAIN_VA_BASE + 0x14)
41#define DUM_CLK_DIV_ADR (PNX4008_DUM_MAIN_VA_BASE + 0x18)
42#define DUM_DIRTY_LOW_ADR (PNX4008_DUM_MAIN_VA_BASE + 0x20)
43#define DUM_DIRTY_HIGH_ADR (PNX4008_DUM_MAIN_VA_BASE + 0x24)
44#define DUM_FORMAT_ADR (PNX4008_DUM_MAIN_VA_BASE + 0x28)
45#define DUM_WTCFG1_ADR (PNX4008_DUM_MAIN_VA_BASE + 0x30)
46#define DUM_RTCFG1_ADR (PNX4008_DUM_MAIN_VA_BASE + 0x34)
47#define DUM_WTCFG2_ADR (PNX4008_DUM_MAIN_VA_BASE + 0x38)
48#define DUM_RTCFG2_ADR (PNX4008_DUM_MAIN_VA_BASE + 0x3C)
49#define DUM_TCFG_ADR (PNX4008_DUM_MAIN_VA_BASE + 0x40)
50#define DUM_OUTP_FORMAT1_ADR (PNX4008_DUM_MAIN_VA_BASE + 0x44)
51#define DUM_OUTP_FORMAT2_ADR (PNX4008_DUM_MAIN_VA_BASE + 0x48)
52#define DUM_SYNC_MODE_ADR (PNX4008_DUM_MAIN_VA_BASE + 0x4C)
53#define DUM_SYNC_OUT_C_ADR (PNX4008_DUM_MAIN_VA_BASE + 0x50)
54
55#define DUM_CONF (*(volatile u32 *)(DUM_CONF_ADR))
56#define DUM_CTRL (*(volatile u32 *)(DUM_CTRL_ADR))
57#define DUM_STAT (*(volatile u32 *)(DUM_STAT_ADR))
58#define DUM_DECODE (*(volatile u32 *)(DUM_DECODE_ADR))
59#define DUM_COM_BASE (*(volatile u32 *)(DUM_COM_BASE_ADR))
60#define DUM_SYNC_C (*(volatile u32 *)(DUM_SYNC_C_ADR))
61#define DUM_CLK_DIV (*(volatile u32 *)(DUM_CLK_DIV_ADR))
62#define DUM_DIRTY_LOW (*(volatile u32 *)(DUM_DIRTY_LOW_ADR))
63#define DUM_DIRTY_HIGH (*(volatile u32 *)(DUM_DIRTY_HIGH_ADR))
64#define DUM_FORMAT (*(volatile u32 *)(DUM_FORMAT_ADR))
65#define DUM_WTCFG1 (*(volatile u32 *)(DUM_WTCFG1_ADR))
66#define DUM_RTCFG1 (*(volatile u32 *)(DUM_RTCFG1_ADR))
67#define DUM_WTCFG2 (*(volatile u32 *)(DUM_WTCFG2_ADR))
68#define DUM_RTCFG2 (*(volatile u32 *)(DUM_RTCFG2_ADR))
69#define DUM_TCFG (*(volatile u32 *)(DUM_TCFG_ADR))
70#define DUM_OUTP_FORMAT1 (*(volatile u32 *)(DUM_OUTP_FORMAT1_ADR))
71#define DUM_OUTP_FORMAT2 (*(volatile u32 *)(DUM_OUTP_FORMAT2_ADR))
72#define DUM_SYNC_MODE (*(volatile u32 *)(DUM_SYNC_MODE_ADR))
73#define DUM_SYNC_OUT_C (*(volatile u32 *)(DUM_SYNC_OUT_C_ADR))
74
75/* DUM SLAVE ADDRESSES */
76#define DUM_SLAVE_WRITE_ADR (PNX4008_DUM_MAINCFG_BASE + 0x0000000)
77#define DUM_SLAVE_READ1_I_ADR (PNX4008_DUM_MAINCFG_BASE + 0x1000000)
78#define DUM_SLAVE_READ1_R_ADR (PNX4008_DUM_MAINCFG_BASE + 0x1000004)
79#define DUM_SLAVE_READ2_I_ADR (PNX4008_DUM_MAINCFG_BASE + 0x1000008)
80#define DUM_SLAVE_READ2_R_ADR (PNX4008_DUM_MAINCFG_BASE + 0x100000C)
81
82#define DUM_SLAVE_WRITE_W ((volatile u32 *)(DUM_SLAVE_WRITE_ADR))
83#define DUM_SLAVE_WRITE_HW ((volatile u16 *)(DUM_SLAVE_WRITE_ADR))
84#define DUM_SLAVE_READ1_I ((volatile u8 *)(DUM_SLAVE_READ1_I_ADR))
85#define DUM_SLAVE_READ1_R ((volatile u16 *)(DUM_SLAVE_READ1_R_ADR))
86#define DUM_SLAVE_READ2_I ((volatile u8 *)(DUM_SLAVE_READ2_I_ADR))
87#define DUM_SLAVE_READ2_R ((volatile u16 *)(DUM_SLAVE_READ2_R_ADR))
88
89/* Sony display register addresses */
90#define DISP_0_REG (0x00)
91#define DISP_1_REG (0x01)
92#define DISP_CAL_REG (0x20)
93#define DISP_ID_REG (0x2A)
94#define DISP_XMIN_L_REG (0x30)
95#define DISP_XMIN_H_REG (0x31)
96#define DISP_YMIN_REG (0x32)
97#define DISP_XMAX_L_REG (0x34)
98#define DISP_XMAX_H_REG (0x35)
99#define DISP_YMAX_REG (0x36)
100#define DISP_SYNC_EN_REG (0x38)
101#define DISP_SYNC_RISE_L_REG (0x3C)
102#define DISP_SYNC_RISE_H_REG (0x3D)
103#define DISP_SYNC_FALL_L_REG (0x3E)
104#define DISP_SYNC_FALL_H_REG (0x3F)
105#define DISP_PIXEL_REG (0x0B)
106#define DISP_DUMMY1_REG (0x28)
107#define DISP_DUMMY2_REG (0x29)
108#define DISP_TIMING_REG (0x98)
109#define DISP_DUMP_REG (0x99)
110
111/* Sony display constants */
112#define SONY_ID1 (0x22)
113#define SONY_ID2 (0x23)
114
115/* Philips display register addresses */
116#define PH_DISP_ORIENT_REG (0x003)
117#define PH_DISP_YPOINT_REG (0x200)
118#define PH_DISP_XPOINT_REG (0x201)
119#define PH_DISP_PIXEL_REG (0x202)
120#define PH_DISP_YMIN_REG (0x406)
121#define PH_DISP_YMAX_REG (0x407)
122#define PH_DISP_XMIN_REG (0x408)
123#define PH_DISP_XMAX_REG (0x409)
124
125/* Misc constants */
126#define NO_VALID_DISPLAY_FOUND (0)
127#define DISPLAY2_IS_NOT_CONNECTED (0)
128
129/* register values */
130#define V_BAC_ENABLE (BIT(0))
131#define V_BAC_DISABLE_IDLE (BIT(1))
132#define V_BAC_DISABLE_TRIG (BIT(2))
133#define V_DUM_RESET (BIT(3))
134#define V_MUX_RESET (BIT(4))
135#define BAC_ENABLED (BIT(0))
136#define BAC_DISABLED 0
137
138/* Sony LCD commands */
139#define V_LCD_STANDBY_OFF ((BIT(25)) | (0 << 16) | DISP_0_REG)
140#define V_LCD_USE_9BIT_BUS ((BIT(25)) | (2 << 16) | DISP_1_REG)
141#define V_LCD_SYNC_RISE_L ((BIT(25)) | (0 << 16) | DISP_SYNC_RISE_L_REG)
142#define V_LCD_SYNC_RISE_H ((BIT(25)) | (0 << 16) | DISP_SYNC_RISE_H_REG)
143#define V_LCD_SYNC_FALL_L ((BIT(25)) | (160 << 16) | DISP_SYNC_FALL_L_REG)
144#define V_LCD_SYNC_FALL_H ((BIT(25)) | (0 << 16) | DISP_SYNC_FALL_H_REG)
145#define V_LCD_SYNC_ENABLE ((BIT(25)) | (128 << 16) | DISP_SYNC_EN_REG)
146#define V_LCD_DISPLAY_ON ((BIT(25)) | (64 << 16) | DISP_0_REG)
147
148enum {
149 PAD_NONE,
150 PAD_512,
151 PAD_1024
152};
153
154enum {
155 RGB888,
156 RGB666,
157 RGB565,
158 BGR565,
159 ARGB1555,
160 ABGR1555,
161 ARGB4444,
162 ABGR4444
163};
164
165struct dum_setup {
166 int sync_neg_edge;
167 int round_robin;
168 int mux_int;
169 int synced_dirty_flag_int;
170 int dirty_flag_int;
171 int error_int;
172 int pf_empty_int;
173 int sf_empty_int;
174 int bac_dis_int;
175 u32 dirty_base_adr;
176 u32 command_base_adr;
177 u32 sync_clk_div;
178 int sync_output;
179 u32 sync_restart_val;
180 u32 set_sync_high;
181 u32 set_sync_low;
182};
183
184struct dum_ch_setup {
185 int disp_no;
186 u32 xmin;
187 u32 ymin;
188 u32 xmax;
189 u32 ymax;
190 int xmirror;
191 int ymirror;
192 int rotate;
193 u32 minadr;
194 u32 maxadr;
195 u32 dirtybuffer;
196 int pad;
197 int format;
198 int hwdirty;
199 int slave_trans;
200};
201
202struct disp_window {
203 u32 xmin_l;
204 u32 xmin_h;
205 u32 ymin;
206 u32 xmax_l;
207 u32 xmax_h;
208 u32 ymax;
209};
210
211#endif /* #ifndef __PNX008_DUM_H__ */
diff --git a/drivers/video/pnx4008/fbcommon.h b/drivers/video/pnx4008/fbcommon.h
new file mode 100644
index 000000000000..4ebc87dafafb
--- /dev/null
+++ b/drivers/video/pnx4008/fbcommon.h
@@ -0,0 +1,43 @@
1/*
2 * Copyright (C) 2005 Philips Semiconductors
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2, or (at your option)
7 * any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; see the file COPYING. If not, write to
16 * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 * Boston, MA 02111-1307, USA, or http://www.gnu.org/licenses/gpl.html
18*/
19
20#define QCIF_W (176)
21#define QCIF_H (144)
22
23#define CIF_W (352)
24#define CIF_H (288)
25
26#define LCD_X_RES 208
27#define LCD_Y_RES 320
28#define LCD_X_PAD 256
29#define LCD_BBP 4 /* Bytes Per Pixel */
30
31#define DISP_MAX_X_SIZE (320)
32#define DISP_MAX_Y_SIZE (208)
33
34#define RETURNVAL_BASE (0x400)
35
36enum fb_ioctl_returntype {
37 ENORESOURCESLEFT = RETURNVAL_BASE,
38 ERESOURCESNOTFREED,
39 EPROCNOTOWNER,
40 EFBNOTOWNER,
41 ECOPYFAILED,
42 EIOREMAPFAILED,
43};
diff --git a/drivers/video/pnx4008/pnxrgbfb.c b/drivers/video/pnx4008/pnxrgbfb.c
new file mode 100644
index 000000000000..7d9453c91a42
--- /dev/null
+++ b/drivers/video/pnx4008/pnxrgbfb.c
@@ -0,0 +1,213 @@
1/*
2 * drivers/video/pnx4008/pnxrgbfb.c
3 *
4 * PNX4008's framebuffer support
5 *
6 * Author: Grigory Tolstolytkin <gtolstolytkin@ru.mvista.com>
7 * Based on Philips Semiconductors's code
8 *
9 * Copyrght (c) 2005 MontaVista Software, Inc.
10 * Copyright (c) 2005 Philips Semiconductors
11 * This file is licensed under the terms of the GNU General Public License
12 * version 2. This program is licensed "as is" without any warranty of any
13 * kind, whether express or implied.
14 */
15
16#include <linux/module.h>
17#include <linux/kernel.h>
18#include <linux/errno.h>
19#include <linux/string.h>
20#include <linux/mm.h>
21#include <linux/slab.h>
22#include <linux/vmalloc.h>
23#include <linux/delay.h>
24#include <linux/interrupt.h>
25#include <linux/fb.h>
26#include <linux/init.h>
27#include <linux/platform_device.h>
28
29#include <asm/uaccess.h>
30#include "sdum.h"
31#include "fbcommon.h"
32
33static u32 colreg[16];
34
35static struct fb_var_screeninfo rgbfb_var __initdata = {
36 .xres = LCD_X_RES,
37 .yres = LCD_Y_RES,
38 .xres_virtual = LCD_X_RES,
39 .yres_virtual = LCD_Y_RES,
40 .bits_per_pixel = 32,
41 .red.offset = 16,
42 .red.length = 8,
43 .green.offset = 8,
44 .green.length = 8,
45 .blue.offset = 0,
46 .blue.length = 8,
47 .left_margin = 0,
48 .right_margin = 0,
49 .upper_margin = 0,
50 .lower_margin = 0,
51 .vmode = FB_VMODE_NONINTERLACED,
52};
53static struct fb_fix_screeninfo rgbfb_fix __initdata = {
54 .id = "RGBFB",
55 .line_length = LCD_X_RES * LCD_BBP,
56 .type = FB_TYPE_PACKED_PIXELS,
57 .visual = FB_VISUAL_TRUECOLOR,
58 .xpanstep = 0,
59 .ypanstep = 0,
60 .ywrapstep = 0,
61 .accel = FB_ACCEL_NONE,
62};
63
64static int channel_owned;
65
66static int no_cursor(struct fb_info *info, struct fb_cursor *cursor)
67{
68 return 0;
69}
70
71static int rgbfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
72 u_int transp, struct fb_info *info)
73{
74 if (regno > 15)
75 return 1;
76
77 colreg[regno] = ((red & 0xff00) << 8) | (green & 0xff00) |
78 ((blue & 0xff00) >> 8);
79 return 0;
80}
81
82static int rgbfb_mmap(struct fb_info *info, struct vm_area_struct *vma)
83{
84 return pnx4008_sdum_mmap(info, vma, NULL);
85}
86
87static struct fb_ops rgbfb_ops = {
88 .fb_mmap = rgbfb_mmap,
89 .fb_setcolreg = rgbfb_setcolreg,
90 .fb_fillrect = cfb_fillrect,
91 .fb_copyarea = cfb_copyarea,
92 .fb_imageblit = cfb_imageblit,
93};
94
95static int rgbfb_remove(struct platform_device *pdev)
96{
97 struct fb_info *info = platform_get_drvdata(pdev);
98
99 if (info) {
100 unregister_framebuffer(info);
101 fb_dealloc_cmap(&info->cmap);
102 framebuffer_release(info);
103 platform_set_drvdata(pdev, NULL);
104 kfree(info);
105 }
106
107 pnx4008_free_dum_channel(channel_owned, pdev->id);
108 pnx4008_set_dum_exit_notification(pdev->id);
109
110 return 0;
111}
112
113static int __devinit rgbfb_probe(struct platform_device *pdev)
114{
115 struct fb_info *info;
116 struct dumchannel_uf chan_uf;
117 int ret;
118 char *option;
119
120 info = framebuffer_alloc(sizeof(u32) * 16, &pdev->dev);
121 if (!info) {
122 ret = -ENOMEM;
123 goto err;
124 }
125
126 pnx4008_get_fb_addresses(FB_TYPE_RGB, (void **)&info->screen_base,
127 (dma_addr_t *) &rgbfb_fix.smem_start,
128 &rgbfb_fix.smem_len);
129
130 if ((ret = pnx4008_alloc_dum_channel(pdev->id)) < 0)
131 goto err0;
132 else {
133 channel_owned = ret;
134 chan_uf.channelnr = channel_owned;
135 chan_uf.dirty = (u32 *) NULL;
136 chan_uf.source = (u32 *) rgbfb_fix.smem_start;
137 chan_uf.x_offset = 0;
138 chan_uf.y_offset = 0;
139 chan_uf.width = LCD_X_RES;
140 chan_uf.height = LCD_Y_RES;
141
142 if ((ret = pnx4008_put_dum_channel_uf(chan_uf, pdev->id))< 0)
143 goto err1;
144
145 if ((ret =
146 pnx4008_set_dum_channel_sync(channel_owned, CONF_SYNC_ON,
147 pdev->id)) < 0)
148 goto err1;
149
150 if ((ret =
151 pnx4008_set_dum_channel_dirty_detect(channel_owned,
152 CONF_DIRTYDETECTION_ON,
153 pdev->id)) < 0)
154 goto err1;
155 }
156
157 if (!fb_get_options("pnxrgbfb", &option) && !strcmp(option, "nocursor"))
158 rgbfb_ops.fb_cursor = no_cursor;
159
160 info->node = -1;
161 info->flags = FBINFO_FLAG_DEFAULT;
162 info->fbops = &rgbfb_ops;
163 info->fix = rgbfb_fix;
164 info->var = rgbfb_var;
165 info->screen_size = rgbfb_fix.smem_len;
166 info->pseudo_palette = info->par;
167 info->par = NULL;
168
169 ret = fb_alloc_cmap(&info->cmap, 256, 0);
170 if (ret < 0)
171 goto err2;
172
173 ret = register_framebuffer(info);
174 if (ret < 0)
175 goto err3;
176 platform_set_drvdata(pdev, info);
177
178 return 0;
179
180err3:
181 fb_dealloc_cmap(&info->cmap);
182err2:
183 framebuffer_release(info);
184err1:
185 pnx4008_free_dum_channel(channel_owned, pdev->id);
186err0:
187 kfree(info);
188err:
189 return ret;
190}
191
192static struct platform_driver rgbfb_driver = {
193 .driver = {
194 .name = "rgbfb",
195 },
196 .probe = rgbfb_probe,
197 .remove = rgbfb_remove,
198};
199
200static int __init rgbfb_init(void)
201{
202 return platform_driver_register(&rgbfb_driver);
203}
204
205static void __exit rgbfb_exit(void)
206{
207 platform_driver_unregister(&rgbfb_driver);
208}
209
210module_init(rgbfb_init);
211module_exit(rgbfb_exit);
212
213MODULE_LICENSE("GPL");
diff --git a/drivers/video/pnx4008/sdum.c b/drivers/video/pnx4008/sdum.c
new file mode 100644
index 000000000000..51f0ecc2a511
--- /dev/null
+++ b/drivers/video/pnx4008/sdum.c
@@ -0,0 +1,872 @@
1/*
2 * drivers/video/pnx4008/sdum.c
3 *
4 * Display Update Master support
5 *
6 * Authors: Grigory Tolstolytkin <gtolstolytkin@ru.mvista.com>
7 * Vitaly Wool <vitalywool@gmail.com>
8 * Based on Philips Semiconductors's code
9 *
10 * Copyrght (c) 2005-2006 MontaVista Software, Inc.
11 * Copyright (c) 2005 Philips Semiconductors
12 * This file is licensed under the terms of the GNU General Public License
13 * version 2. This program is licensed "as is" without any warranty of any
14 * kind, whether express or implied.
15 */
16
17#include <linux/module.h>
18#include <linux/kernel.h>
19#include <linux/errno.h>
20#include <linux/string.h>
21#include <linux/mm.h>
22#include <linux/tty.h>
23#include <linux/slab.h>
24#include <linux/vmalloc.h>
25#include <linux/delay.h>
26#include <linux/interrupt.h>
27#include <linux/platform_device.h>
28#include <linux/fb.h>
29#include <linux/init.h>
30#include <linux/dma-mapping.h>
31#include <linux/clk.h>
32#include <asm/uaccess.h>
33#include <asm/arch/gpio.h>
34
35#include "sdum.h"
36#include "fbcommon.h"
37#include "dum.h"
38
39/* Framebuffers we have */
40
41static struct pnx4008_fb_addr {
42 int fb_type;
43 long addr_offset;
44 long fb_length;
45} fb_addr[] = {
46 [0] = {
47 FB_TYPE_YUV, 0, 0xB0000
48 },
49 [1] = {
50 FB_TYPE_RGB, 0xB0000, 0x50000
51 },
52};
53
54static struct dum_data {
55 u32 lcd_phys_start;
56 u32 lcd_virt_start;
57 u32 slave_phys_base;
58 u32 *slave_virt_base;
59 int fb_owning_channel[MAX_DUM_CHANNELS];
60 struct dumchannel_uf chan_uf_store[MAX_DUM_CHANNELS];
61} dum_data;
62
63/* Different local helper functions */
64
65static u32 nof_pixels_dx(struct dum_ch_setup *ch_setup)
66{
67 return (ch_setup->xmax - ch_setup->xmin + 1);
68}
69
70static u32 nof_pixels_dy(struct dum_ch_setup *ch_setup)
71{
72 return (ch_setup->ymax - ch_setup->ymin + 1);
73}
74
75static u32 nof_pixels_dxy(struct dum_ch_setup *ch_setup)
76{
77 return (nof_pixels_dx(ch_setup) * nof_pixels_dy(ch_setup));
78}
79
80static u32 nof_bytes(struct dum_ch_setup *ch_setup)
81{
82 u32 r = nof_pixels_dxy(ch_setup);
83 switch (ch_setup->format) {
84 case RGB888:
85 case RGB666:
86 r *= 4;
87 break;
88
89 default:
90 r *= 2;
91 break;
92 }
93 return r;
94}
95
96static u32 build_command(int disp_no, u32 reg, u32 val)
97{
98 return ((disp_no << 26) | BIT(25) | (val << 16) | (disp_no << 10) |
99 (reg << 0));
100}
101
102static u32 build_double_index(int disp_no, u32 val)
103{
104 return ((disp_no << 26) | (val << 16) | (disp_no << 10) | (val << 0));
105}
106
107static void build_disp_window(struct dum_ch_setup * ch_setup, struct disp_window * dw)
108{
109 dw->ymin = ch_setup->ymin;
110 dw->ymax = ch_setup->ymax;
111 dw->xmin_l = ch_setup->xmin & 0xFF;
112 dw->xmin_h = (ch_setup->xmin & BIT(8)) >> 8;
113 dw->xmax_l = ch_setup->xmax & 0xFF;
114 dw->xmax_h = (ch_setup->xmax & BIT(8)) >> 8;
115}
116
117static int put_channel(struct dumchannel chan)
118{
119 int i = chan.channelnr;
120
121 if (i < 0 || i > MAX_DUM_CHANNELS)
122 return -EINVAL;
123 else {
124 DUM_CH_MIN(i) = chan.dum_ch_min;
125 DUM_CH_MAX(i) = chan.dum_ch_max;
126 DUM_CH_CONF(i) = chan.dum_ch_conf;
127 DUM_CH_CTRL(i) = chan.dum_ch_ctrl;
128 }
129
130 return 0;
131}
132
133static void clear_channel(int channr)
134{
135 struct dumchannel chan;
136
137 chan.channelnr = channr;
138 chan.dum_ch_min = 0;
139 chan.dum_ch_max = 0;
140 chan.dum_ch_conf = 0;
141 chan.dum_ch_ctrl = 0;
142
143 put_channel(chan);
144}
145
146static int put_cmd_string(struct cmdstring cmds)
147{
148 u16 *cmd_str_virtaddr;
149 u32 *cmd_ptr0_virtaddr;
150 u32 cmd_str_physaddr;
151
152 int i = cmds.channelnr;
153
154 if (i < 0 || i > MAX_DUM_CHANNELS)
155 return -EINVAL;
156 else if ((cmd_ptr0_virtaddr =
157 (int *)ioremap_nocache(DUM_COM_BASE,
158 sizeof(int) * MAX_DUM_CHANNELS)) ==
159 NULL)
160 return -EIOREMAPFAILED;
161 else {
162 cmd_str_physaddr = ioread32(&cmd_ptr0_virtaddr[cmds.channelnr]);
163 if ((cmd_str_virtaddr =
164 (u16 *) ioremap_nocache(cmd_str_physaddr,
165 sizeof(cmds))) == NULL) {
166 iounmap(cmd_ptr0_virtaddr);
167 return -EIOREMAPFAILED;
168 } else {
169 int t;
170 for (t = 0; t < 8; t++)
171 iowrite16(*((u16 *)&cmds.prestringlen + t),
172 cmd_str_virtaddr + t);
173
174 for (t = 0; t < cmds.prestringlen / 2; t++)
175 iowrite16(*((u16 *)&cmds.precmd + t),
176 cmd_str_virtaddr + t + 8);
177
178 for (t = 0; t < cmds.poststringlen / 2; t++)
179 iowrite16(*((u16 *)&cmds.postcmd + t),
180 cmd_str_virtaddr + t + 8 +
181 cmds.prestringlen / 2);
182
183 iounmap(cmd_ptr0_virtaddr);
184 iounmap(cmd_str_virtaddr);
185 }
186 }
187
188 return 0;
189}
190
191static u32 dum_ch_setup(int ch_no, struct dum_ch_setup * ch_setup)
192{
193 struct cmdstring cmds_c;
194 struct cmdstring *cmds = &cmds_c;
195 struct disp_window dw;
196 int standard;
197 u32 orientation = 0;
198 struct dumchannel chan = { 0 };
199 int ret;
200
201 if ((ch_setup->xmirror) || (ch_setup->ymirror) || (ch_setup->rotate)) {
202 standard = 0;
203
204 orientation = BIT(1); /* always set 9-bit-bus */
205 if (ch_setup->xmirror)
206 orientation |= BIT(4);
207 if (ch_setup->ymirror)
208 orientation |= BIT(3);
209 if (ch_setup->rotate)
210 orientation |= BIT(0);
211 } else
212 standard = 1;
213
214 cmds->channelnr = ch_no;
215
216 /* build command string header */
217 if (standard) {
218 cmds->prestringlen = 32;
219 cmds->poststringlen = 0;
220 } else {
221 cmds->prestringlen = 48;
222 cmds->poststringlen = 16;
223 }
224
225 cmds->format =
226 (u16) ((ch_setup->disp_no << 4) | (BIT(3)) | (ch_setup->format));
227 cmds->reserved = 0x0;
228 cmds->startaddr_low = (ch_setup->minadr & 0xFFFF);
229 cmds->startaddr_high = (ch_setup->minadr >> 16);
230
231 if ((ch_setup->minadr == 0) && (ch_setup->maxadr == 0)
232 && (ch_setup->xmin == 0)
233 && (ch_setup->ymin == 0) && (ch_setup->xmax == 0)
234 && (ch_setup->ymax == 0)) {
235 cmds->pixdatlen_low = 0;
236 cmds->pixdatlen_high = 0;
237 } else {
238 u32 nbytes = nof_bytes(ch_setup);
239 cmds->pixdatlen_low = (nbytes & 0xFFFF);
240 cmds->pixdatlen_high = (nbytes >> 16);
241 }
242
243 if (ch_setup->slave_trans)
244 cmds->pixdatlen_high |= BIT(15);
245
246 /* build pre-string */
247 build_disp_window(ch_setup, &dw);
248
249 if (standard) {
250 cmds->precmd[0] =
251 build_command(ch_setup->disp_no, DISP_XMIN_L_REG, 0x99);
252 cmds->precmd[1] =
253 build_command(ch_setup->disp_no, DISP_XMIN_L_REG,
254 dw.xmin_l);
255 cmds->precmd[2] =
256 build_command(ch_setup->disp_no, DISP_XMIN_H_REG,
257 dw.xmin_h);
258 cmds->precmd[3] =
259 build_command(ch_setup->disp_no, DISP_YMIN_REG, dw.ymin);
260 cmds->precmd[4] =
261 build_command(ch_setup->disp_no, DISP_XMAX_L_REG,
262 dw.xmax_l);
263 cmds->precmd[5] =
264 build_command(ch_setup->disp_no, DISP_XMAX_H_REG,
265 dw.xmax_h);
266 cmds->precmd[6] =
267 build_command(ch_setup->disp_no, DISP_YMAX_REG, dw.ymax);
268 cmds->precmd[7] =
269 build_double_index(ch_setup->disp_no, DISP_PIXEL_REG);
270 } else {
271 if (dw.xmin_l == ch_no)
272 cmds->precmd[0] =
273 build_command(ch_setup->disp_no, DISP_XMIN_L_REG,
274 0x99);
275 else
276 cmds->precmd[0] =
277 build_command(ch_setup->disp_no, DISP_XMIN_L_REG,
278 ch_no);
279
280 cmds->precmd[1] =
281 build_command(ch_setup->disp_no, DISP_XMIN_L_REG,
282 dw.xmin_l);
283 cmds->precmd[2] =
284 build_command(ch_setup->disp_no, DISP_XMIN_H_REG,
285 dw.xmin_h);
286 cmds->precmd[3] =
287 build_command(ch_setup->disp_no, DISP_YMIN_REG, dw.ymin);
288 cmds->precmd[4] =
289 build_command(ch_setup->disp_no, DISP_XMAX_L_REG,
290 dw.xmax_l);
291 cmds->precmd[5] =
292 build_command(ch_setup->disp_no, DISP_XMAX_H_REG,
293 dw.xmax_h);
294 cmds->precmd[6] =
295 build_command(ch_setup->disp_no, DISP_YMAX_REG, dw.ymax);
296 cmds->precmd[7] =
297 build_command(ch_setup->disp_no, DISP_1_REG, orientation);
298 cmds->precmd[8] =
299 build_double_index(ch_setup->disp_no, DISP_PIXEL_REG);
300 cmds->precmd[9] =
301 build_double_index(ch_setup->disp_no, DISP_PIXEL_REG);
302 cmds->precmd[0xA] =
303 build_double_index(ch_setup->disp_no, DISP_PIXEL_REG);
304 cmds->precmd[0xB] =
305 build_double_index(ch_setup->disp_no, DISP_PIXEL_REG);
306 cmds->postcmd[0] =
307 build_command(ch_setup->disp_no, DISP_1_REG, BIT(1));
308 cmds->postcmd[1] =
309 build_command(ch_setup->disp_no, DISP_DUMMY1_REG, 1);
310 cmds->postcmd[2] =
311 build_command(ch_setup->disp_no, DISP_DUMMY1_REG, 2);
312 cmds->postcmd[3] =
313 build_command(ch_setup->disp_no, DISP_DUMMY1_REG, 3);
314 }
315
316 if ((ret = put_cmd_string(cmds_c)) != 0) {
317 return ret;
318 }
319
320 chan.channelnr = cmds->channelnr;
321 chan.dum_ch_min = ch_setup->dirtybuffer + ch_setup->minadr;
322 chan.dum_ch_max = ch_setup->dirtybuffer + ch_setup->maxadr;
323 chan.dum_ch_conf = 0x002;
324 chan.dum_ch_ctrl = 0x04;
325
326 put_channel(chan);
327
328 return 0;
329}
330
331static u32 display_open(int ch_no, int auto_update, u32 * dirty_buffer,
332 u32 * frame_buffer, u32 xpos, u32 ypos, u32 w, u32 h)
333{
334
335 struct dum_ch_setup k;
336 int ret;
337
338 /* keep width & height within display area */
339 if ((xpos + w) > DISP_MAX_X_SIZE)
340 w = DISP_MAX_X_SIZE - xpos;
341
342 if ((ypos + h) > DISP_MAX_Y_SIZE)
343 h = DISP_MAX_Y_SIZE - ypos;
344
345 /* assume 1 display only */
346 k.disp_no = 0;
347 k.xmin = xpos;
348 k.ymin = ypos;
349 k.xmax = xpos + (w - 1);
350 k.ymax = ypos + (h - 1);
351
352 /* adjust min and max values if necessary */
353 if (k.xmin > DISP_MAX_X_SIZE - 1)
354 k.xmin = DISP_MAX_X_SIZE - 1;
355 if (k.ymin > DISP_MAX_Y_SIZE - 1)
356 k.ymin = DISP_MAX_Y_SIZE - 1;
357
358 if (k.xmax > DISP_MAX_X_SIZE - 1)
359 k.xmax = DISP_MAX_X_SIZE - 1;
360 if (k.ymax > DISP_MAX_Y_SIZE - 1)
361 k.ymax = DISP_MAX_Y_SIZE - 1;
362
363 k.xmirror = 0;
364 k.ymirror = 0;
365 k.rotate = 0;
366 k.minadr = (u32) frame_buffer;
367 k.maxadr = (u32) frame_buffer + (((w - 1) << 10) | ((h << 2) - 2));
368 k.pad = PAD_1024;
369 k.dirtybuffer = (u32) dirty_buffer;
370 k.format = RGB888;
371 k.hwdirty = 0;
372 k.slave_trans = 0;
373
374 ret = dum_ch_setup(ch_no, &k);
375
376 return ret;
377}
378
379static void lcd_reset(void)
380{
381 u32 *dum_pio_base = (u32 *)IO_ADDRESS(PNX4008_PIO_BASE);
382
383 udelay(1);
384 iowrite32(BIT(19), &dum_pio_base[2]);
385 udelay(1);
386 iowrite32(BIT(19), &dum_pio_base[1]);
387 udelay(1);
388}
389
390static int dum_init(struct platform_device *pdev)
391{
392 struct clk *clk;
393
394 /* enable DUM clock */
395 clk = clk_get(&pdev->dev, "dum_ck");
396 if (IS_ERR(clk)) {
397 printk(KERN_ERR "pnx4008_dum: Unable to access DUM clock\n");
398 return PTR_ERR(clk);
399 }
400
401 clk_set_rate(clk, 1);
402 clk_put(clk);
403
404 DUM_CTRL = V_DUM_RESET;
405
406 /* set priority to "round-robin". All other params to "false" */
407 DUM_CONF = BIT(9);
408
409 /* Display 1 */
410 DUM_WTCFG1 = PNX4008_DUM_WT_CFG;
411 DUM_RTCFG1 = PNX4008_DUM_RT_CFG;
412 DUM_TCFG = PNX4008_DUM_T_CFG;
413
414 return 0;
415}
416
417static void dum_chan_init(void)
418{
419 int i = 0, ch = 0;
420 u32 *cmdptrs;
421 u32 *cmdstrings;
422
423 DUM_COM_BASE =
424 CMDSTRING_BASEADDR + BYTES_PER_CMDSTRING * NR_OF_CMDSTRINGS;
425
426 if ((cmdptrs =
427 (u32 *) ioremap_nocache(DUM_COM_BASE,
428 sizeof(u32) * NR_OF_CMDSTRINGS)) == NULL)
429 return;
430
431 for (ch = 0; ch < NR_OF_CMDSTRINGS; ch++)
432 iowrite32(CMDSTRING_BASEADDR + BYTES_PER_CMDSTRING * ch,
433 cmdptrs + ch);
434
435 for (ch = 0; ch < MAX_DUM_CHANNELS; ch++)
436 clear_channel(ch);
437
438 /* Clear the cmdstrings */
439 cmdstrings =
440 (u32 *)ioremap_nocache(*cmdptrs,
441 BYTES_PER_CMDSTRING * NR_OF_CMDSTRINGS);
442
443 if (!cmdstrings)
444 goto out;
445
446 for (i = 0; i < NR_OF_CMDSTRINGS * BYTES_PER_CMDSTRING / sizeof(u32);
447 i++)
448 iowrite32(0, cmdstrings + i);
449
450 iounmap((u32 *)cmdstrings);
451
452out:
453 iounmap((u32 *)cmdptrs);
454}
455
456static void lcd_init(void)
457{
458 lcd_reset();
459
460 DUM_OUTP_FORMAT1 = 0; /* RGB666 */
461
462 udelay(1);
463 iowrite32(V_LCD_STANDBY_OFF, dum_data.slave_virt_base);
464 udelay(1);
465 iowrite32(V_LCD_USE_9BIT_BUS, dum_data.slave_virt_base);
466 udelay(1);
467 iowrite32(V_LCD_SYNC_RISE_L, dum_data.slave_virt_base);
468 udelay(1);
469 iowrite32(V_LCD_SYNC_RISE_H, dum_data.slave_virt_base);
470 udelay(1);
471 iowrite32(V_LCD_SYNC_FALL_L, dum_data.slave_virt_base);
472 udelay(1);
473 iowrite32(V_LCD_SYNC_FALL_H, dum_data.slave_virt_base);
474 udelay(1);
475 iowrite32(V_LCD_SYNC_ENABLE, dum_data.slave_virt_base);
476 udelay(1);
477 iowrite32(V_LCD_DISPLAY_ON, dum_data.slave_virt_base);
478 udelay(1);
479}
480
481/* Interface exported to framebuffer drivers */
482
483int pnx4008_get_fb_addresses(int fb_type, void **virt_addr,
484 dma_addr_t *phys_addr, int *fb_length)
485{
486 int i;
487 int ret = -1;
488 for (i = 0; i < ARRAY_SIZE(fb_addr); i++)
489 if (fb_addr[i].fb_type == fb_type) {
490 *virt_addr = (void *)(dum_data.lcd_virt_start +
491 fb_addr[i].addr_offset);
492 *phys_addr =
493 dum_data.lcd_phys_start + fb_addr[i].addr_offset;
494 *fb_length = fb_addr[i].fb_length;
495 ret = 0;
496 break;
497 }
498
499 return ret;
500}
501
502EXPORT_SYMBOL(pnx4008_get_fb_addresses);
503
504int pnx4008_alloc_dum_channel(int dev_id)
505{
506 int i = 0;
507
508 while ((i < MAX_DUM_CHANNELS) && (dum_data.fb_owning_channel[i] != -1))
509 i++;
510
511 if (i == MAX_DUM_CHANNELS)
512 return -ENORESOURCESLEFT;
513 else {
514 dum_data.fb_owning_channel[i] = dev_id;
515 return i;
516 }
517}
518
519EXPORT_SYMBOL(pnx4008_alloc_dum_channel);
520
521int pnx4008_free_dum_channel(int channr, int dev_id)
522{
523 if (channr < 0 || channr > MAX_DUM_CHANNELS)
524 return -EINVAL;
525 else if (dum_data.fb_owning_channel[channr] != dev_id)
526 return -EFBNOTOWNER;
527 else {
528 clear_channel(channr);
529 dum_data.fb_owning_channel[channr] = -1;
530 }
531
532 return 0;
533}
534
535EXPORT_SYMBOL(pnx4008_free_dum_channel);
536
537int pnx4008_put_dum_channel_uf(struct dumchannel_uf chan_uf, int dev_id)
538{
539 int i = chan_uf.channelnr;
540 int ret;
541
542 if (i < 0 || i > MAX_DUM_CHANNELS)
543 return -EINVAL;
544 else if (dum_data.fb_owning_channel[i] != dev_id)
545 return -EFBNOTOWNER;
546 else if ((ret =
547 display_open(chan_uf.channelnr, 0, chan_uf.dirty,
548 chan_uf.source, chan_uf.y_offset,
549 chan_uf.x_offset, chan_uf.height,
550 chan_uf.width)) != 0)
551 return ret;
552 else {
553 dum_data.chan_uf_store[i].dirty = chan_uf.dirty;
554 dum_data.chan_uf_store[i].source = chan_uf.source;
555 dum_data.chan_uf_store[i].x_offset = chan_uf.x_offset;
556 dum_data.chan_uf_store[i].y_offset = chan_uf.y_offset;
557 dum_data.chan_uf_store[i].width = chan_uf.width;
558 dum_data.chan_uf_store[i].height = chan_uf.height;
559 }
560
561 return 0;
562}
563
564EXPORT_SYMBOL(pnx4008_put_dum_channel_uf);
565
566int pnx4008_set_dum_channel_sync(int channr, int val, int dev_id)
567{
568 if (channr < 0 || channr > MAX_DUM_CHANNELS)
569 return -EINVAL;
570 else if (dum_data.fb_owning_channel[channr] != dev_id)
571 return -EFBNOTOWNER;
572 else {
573 if (val == CONF_SYNC_ON) {
574 DUM_CH_CONF(channr) |= CONF_SYNCENABLE;
575 DUM_CH_CONF(channr) |= DUM_CHANNEL_CFG_SYNC_MASK |
576 DUM_CHANNEL_CFG_SYNC_MASK_SET;
577 } else if (val == CONF_SYNC_OFF)
578 DUM_CH_CONF(channr) &= ~CONF_SYNCENABLE;
579 else
580 return -EINVAL;
581 }
582
583 return 0;
584}
585
586EXPORT_SYMBOL(pnx4008_set_dum_channel_sync);
587
588int pnx4008_set_dum_channel_dirty_detect(int channr, int val, int dev_id)
589{
590 if (channr < 0 || channr > MAX_DUM_CHANNELS)
591 return -EINVAL;
592 else if (dum_data.fb_owning_channel[channr] != dev_id)
593 return -EFBNOTOWNER;
594 else {
595 if (val == CONF_DIRTYDETECTION_ON)
596 DUM_CH_CONF(channr) |= CONF_DIRTYENABLE;
597 else if (val == CONF_DIRTYDETECTION_OFF)
598 DUM_CH_CONF(channr) &= ~CONF_DIRTYENABLE;
599 else
600 return -EINVAL;
601 }
602
603 return 0;
604}
605
606EXPORT_SYMBOL(pnx4008_set_dum_channel_dirty_detect);
607
608#if 0 /* Functions not used currently, but likely to be used in future */
609
610static int get_channel(struct dumchannel *p_chan)
611{
612 int i = p_chan->channelnr;
613
614 if (i < 0 || i > MAX_DUM_CHANNELS)
615 return -EINVAL;
616 else {
617 p_chan->dum_ch_min = DUM_CH_MIN(i);
618 p_chan->dum_ch_max = DUM_CH_MAX(i);
619 p_chan->dum_ch_conf = DUM_CH_CONF(i);
620 p_chan->dum_ch_stat = DUM_CH_STAT(i);
621 p_chan->dum_ch_ctrl = 0; /* WriteOnly control register */
622 }
623
624 return 0;
625}
626
627int pnx4008_get_dum_channel_uf(struct dumchannel_uf *p_chan_uf, int dev_id)
628{
629 int i = p_chan_uf->channelnr;
630
631 if (i < 0 || i > MAX_DUM_CHANNELS)
632 return -EINVAL;
633 else if (dum_data.fb_owning_channel[i] != dev_id)
634 return -EFBNOTOWNER;
635 else {
636 p_chan_uf->dirty = dum_data.chan_uf_store[i].dirty;
637 p_chan_uf->source = dum_data.chan_uf_store[i].source;
638 p_chan_uf->x_offset = dum_data.chan_uf_store[i].x_offset;
639 p_chan_uf->y_offset = dum_data.chan_uf_store[i].y_offset;
640 p_chan_uf->width = dum_data.chan_uf_store[i].width;
641 p_chan_uf->height = dum_data.chan_uf_store[i].height;
642 }
643
644 return 0;
645}
646
647EXPORT_SYMBOL(pnx4008_get_dum_channel_uf);
648
649int pnx4008_get_dum_channel_config(int channr, int dev_id)
650{
651 int ret;
652 struct dumchannel chan;
653
654 if (channr < 0 || channr > MAX_DUM_CHANNELS)
655 return -EINVAL;
656 else if (dum_data.fb_owning_channel[channr] != dev_id)
657 return -EFBNOTOWNER;
658 else {
659 chan.channelnr = channr;
660 if ((ret = get_channel(&chan)) != 0)
661 return ret;
662 }
663
664 return (chan.dum_ch_conf & DUM_CHANNEL_CFG_MASK);
665}
666
667EXPORT_SYMBOL(pnx4008_get_dum_channel_config);
668
669int pnx4008_force_update_dum_channel(int channr, int dev_id)
670{
671 if (channr < 0 || channr > MAX_DUM_CHANNELS)
672 return -EINVAL;
673
674 else if (dum_data.fb_owning_channel[channr] != dev_id)
675 return -EFBNOTOWNER;
676 else
677 DUM_CH_CTRL(channr) = CTRL_SETDIRTY;
678
679 return 0;
680}
681
682EXPORT_SYMBOL(pnx4008_force_update_dum_channel);
683
684#endif
685
686int pnx4008_sdum_mmap(struct fb_info *info, struct vm_area_struct *vma,
687 struct device *dev)
688{
689 unsigned long off = vma->vm_pgoff << PAGE_SHIFT;
690
691 if (off < info->fix.smem_len) {
692 vma->vm_pgoff += 1;
693 return dma_mmap_writecombine(dev, vma,
694 (void *)dum_data.lcd_virt_start,
695 dum_data.lcd_phys_start,
696 FB_DMA_SIZE);
697 }
698 return -EINVAL;
699}
700
701EXPORT_SYMBOL(pnx4008_sdum_mmap);
702
703int pnx4008_set_dum_exit_notification(int dev_id)
704{
705 int i;
706
707 for (i = 0; i < MAX_DUM_CHANNELS; i++)
708 if (dum_data.fb_owning_channel[i] == dev_id)
709 return -ERESOURCESNOTFREED;
710
711 return 0;
712}
713
714EXPORT_SYMBOL(pnx4008_set_dum_exit_notification);
715
716/* Platform device driver for DUM */
717
718static int sdum_suspend(struct platform_device *pdev, pm_message_t state)
719{
720 int retval = 0;
721 struct clk *clk;
722
723 clk = clk_get(0, "dum_ck");
724 if (!IS_ERR(clk)) {
725 clk_set_rate(clk, 0);
726 clk_put(clk);
727 } else
728 retval = PTR_ERR(clk);
729
730 /* disable BAC */
731 DUM_CTRL = V_BAC_DISABLE_IDLE;
732
733 /* LCD standby & turn off display */
734 lcd_reset();
735
736 return retval;
737}
738
739static int sdum_resume(struct platform_device *pdev)
740{
741 int retval = 0;
742 struct clk *clk;
743
744 clk = clk_get(0, "dum_ck");
745 if (!IS_ERR(clk)) {
746 clk_set_rate(clk, 1);
747 clk_put(clk);
748 } else
749 retval = PTR_ERR(clk);
750
751 /* wait for BAC disable */
752 DUM_CTRL = V_BAC_DISABLE_TRIG;
753
754 while (DUM_CTRL & BAC_ENABLED)
755 udelay(10);
756
757 /* re-init LCD */
758 lcd_init();
759
760 /* enable BAC and reset MUX */
761 DUM_CTRL = V_BAC_ENABLE;
762 udelay(1);
763 DUM_CTRL = V_MUX_RESET;
764 return 0;
765}
766
767static int __devinit sdum_probe(struct platform_device *pdev)
768{
769 int ret = 0, i = 0;
770
771 /* map frame buffer */
772 dum_data.lcd_virt_start = (u32) dma_alloc_writecombine(&pdev->dev,
773 FB_DMA_SIZE,
774 &dum_data.lcd_phys_start,
775 GFP_KERNEL);
776
777 if (!dum_data.lcd_virt_start) {
778 ret = -ENOMEM;
779 goto out_3;
780 }
781
782 /* map slave registers */
783 dum_data.slave_phys_base = PNX4008_DUM_SLAVE_BASE;
784 dum_data.slave_virt_base =
785 (u32 *) ioremap_nocache(dum_data.slave_phys_base, sizeof(u32));
786
787 if (dum_data.slave_virt_base == NULL) {
788 ret = -ENOMEM;
789 goto out_2;
790 }
791
792 /* initialize DUM and LCD display */
793 ret = dum_init(pdev);
794 if (ret)
795 goto out_1;
796
797 dum_chan_init();
798 lcd_init();
799
800 DUM_CTRL = V_BAC_ENABLE;
801 udelay(1);
802 DUM_CTRL = V_MUX_RESET;
803
804 /* set decode address and sync clock divider */
805 DUM_DECODE = dum_data.lcd_phys_start & DUM_DECODE_MASK;
806 DUM_CLK_DIV = PNX4008_DUM_CLK_DIV;
807
808 for (i = 0; i < MAX_DUM_CHANNELS; i++)
809 dum_data.fb_owning_channel[i] = -1;
810
811 /*setup wakeup interrupt */
812 start_int_set_rising_edge(SE_DISP_SYNC_INT);
813 start_int_ack(SE_DISP_SYNC_INT);
814 start_int_umask(SE_DISP_SYNC_INT);
815
816 return 0;
817
818out_1:
819 iounmap((void *)dum_data.slave_virt_base);
820out_2:
821 dma_free_writecombine(&pdev->dev, FB_DMA_SIZE,
822 (void *)dum_data.lcd_virt_start,
823 dum_data.lcd_phys_start);
824out_3:
825 return ret;
826}
827
828static int sdum_remove(struct platform_device *pdev)
829{
830 struct clk *clk;
831
832 start_int_mask(SE_DISP_SYNC_INT);
833
834 clk = clk_get(0, "dum_ck");
835 if (!IS_ERR(clk)) {
836 clk_set_rate(clk, 0);
837 clk_put(clk);
838 }
839
840 iounmap((void *)dum_data.slave_virt_base);
841
842 dma_free_writecombine(&pdev->dev, FB_DMA_SIZE,
843 (void *)dum_data.lcd_virt_start,
844 dum_data.lcd_phys_start);
845
846 return 0;
847}
848
849static struct platform_driver sdum_driver = {
850 .driver = {
851 .name = "sdum",
852 },
853 .probe = sdum_probe,
854 .remove = sdum_remove,
855 .suspend = sdum_suspend,
856 .resume = sdum_resume,
857};
858
859int __init sdum_init(void)
860{
861 return platform_driver_register(&sdum_driver);
862}
863
864static void __exit sdum_exit(void)
865{
866 platform_driver_unregister(&sdum_driver);
867};
868
869module_init(sdum_init);
870module_exit(sdum_exit);
871
872MODULE_LICENSE("GPL");
diff --git a/drivers/video/pnx4008/sdum.h b/drivers/video/pnx4008/sdum.h
new file mode 100644
index 000000000000..e8c5dcdd8813
--- /dev/null
+++ b/drivers/video/pnx4008/sdum.h
@@ -0,0 +1,139 @@
1/*
2 * Copyright (C) 2005 Philips Semiconductors
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2, or (at your option)
7 * any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; see the file COPYING. If not, write to
16 * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 * Boston, MA 02111-1307, USA, or http://www.gnu.org/licenses/gpl.html
18*/
19
20#define MAX_DUM_CHANNELS 64
21
22#define RGB_MEM_WINDOW(x) (0x10000000 + (x)*0x00100000)
23
24#define QCIF_OFFSET(x) (((x) == 0) ? 0x00000: ((x) == 1) ? 0x30000: -1)
25#define CIF_OFFSET(x) (((x) == 0) ? 0x00000: ((x) == 1) ? 0x60000: -1)
26
27#define CTRL_SETDIRTY (0x00000001)
28#define CONF_DIRTYENABLE (0x00000020)
29#define CONF_SYNCENABLE (0x00000004)
30
31#define DIRTY_ENABLED(conf) ((conf) & 0x0020)
32#define SYNC_ENABLED(conf) ((conf) & 0x0004)
33
34/* Display 1 & 2 Write Timing Configuration */
35#define PNX4008_DUM_WT_CFG 0x00372000
36
37/* Display 1 & 2 Read Timing Configuration */
38#define PNX4008_DUM_RT_CFG 0x00003A47
39
40/* DUM Transit State Timing Configuration */
41#define PNX4008_DUM_T_CFG 0x1D /* 29 HCLK cycles */
42
43/* DUM Sync count clock divider */
44#define PNX4008_DUM_CLK_DIV 0x02DD
45
46/* Memory size for framebuffer, allocated through dma_alloc_writecombine().
47 * Must be PAGE aligned
48 */
49#define FB_DMA_SIZE (PAGE_ALIGN(SZ_1M + PAGE_SIZE))
50
51#define OFFSET_RGBBUFFER (0xB0000)
52#define OFFSET_YUVBUFFER (0x00000)
53
54#define YUVBUFFER (lcd_video_start + OFFSET_YUVBUFFER)
55#define RGBBUFFER (lcd_video_start + OFFSET_RGBBUFFER)
56
57#define CMDSTRING_BASEADDR (0x00C000) /* iram */
58#define BYTES_PER_CMDSTRING (0x80)
59#define NR_OF_CMDSTRINGS (64)
60
61#define MAX_NR_PRESTRINGS (0x40)
62#define MAX_NR_POSTSTRINGS (0x40)
63
64/* various mask definitions */
65#define DUM_CLK_ENABLE 0x01
66#define DUM_CLK_DISABLE 0
67#define DUM_DECODE_MASK 0x1FFFFFFF
68#define DUM_CHANNEL_CFG_MASK 0x01FF
69#define DUM_CHANNEL_CFG_SYNC_MASK 0xFFFE00FF
70#define DUM_CHANNEL_CFG_SYNC_MASK_SET 0x0CA00
71
72#define SDUM_RETURNVAL_BASE (0x500)
73
74#define CONF_SYNC_OFF (0x602)
75#define CONF_SYNC_ON (0x603)
76
77#define CONF_DIRTYDETECTION_OFF (0x600)
78#define CONF_DIRTYDETECTION_ON (0x601)
79
80/* Set the corresponding bit. */
81#define BIT(n) (0x1U << (n))
82
83struct dumchannel_uf {
84 int channelnr;
85 u32 *dirty;
86 u32 *source;
87 u32 x_offset;
88 u32 y_offset;
89 u32 width;
90 u32 height;
91};
92
93enum {
94 FB_TYPE_YUV,
95 FB_TYPE_RGB
96};
97
98struct cmdstring {
99 int channelnr;
100 uint16_t prestringlen;
101 uint16_t poststringlen;
102 uint16_t format;
103 uint16_t reserved;
104 uint16_t startaddr_low;
105 uint16_t startaddr_high;
106 uint16_t pixdatlen_low;
107 uint16_t pixdatlen_high;
108 u32 precmd[MAX_NR_PRESTRINGS];
109 u32 postcmd[MAX_NR_POSTSTRINGS];
110
111};
112
113struct dumchannel {
114 int channelnr;
115 int dum_ch_min;
116 int dum_ch_max;
117 int dum_ch_conf;
118 int dum_ch_stat;
119 int dum_ch_ctrl;
120};
121
122int pnx4008_alloc_dum_channel(int dev_id);
123int pnx4008_free_dum_channel(int channr, int dev_id);
124
125int pnx4008_get_dum_channel_uf(struct dumchannel_uf *pChan_uf, int dev_id);
126int pnx4008_put_dum_channel_uf(struct dumchannel_uf chan_uf, int dev_id);
127
128int pnx4008_set_dum_channel_sync(int channr, int val, int dev_id);
129int pnx4008_set_dum_channel_dirty_detect(int channr, int val, int dev_id);
130
131int pnx4008_force_dum_update_channel(int channr, int dev_id);
132
133int pnx4008_get_dum_channel_config(int channr, int dev_id);
134
135int pnx4008_sdum_mmap(struct fb_info *info, struct vm_area_struct *vma, struct device *dev);
136int pnx4008_set_dum_exit_notification(int dev_id);
137
138int pnx4008_get_fb_addresses(int fb_type, void **virt_addr,
139 dma_addr_t * phys_addr, int *fb_length);