aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/acpi/glue.c46
-rw-r--r--drivers/acpi/numa.c4
-rw-r--r--drivers/acpi/osl.c1
-rw-r--r--drivers/acpi/scan.c2
-rw-r--r--drivers/acpi/sleep/proc.c19
-rw-r--r--drivers/base/platform.c18
-rw-r--r--drivers/block/acsi_slm.c1
-rw-r--r--drivers/block/cciss.c288
-rw-r--r--drivers/block/cciss_scsi.c1
-rw-r--r--drivers/block/floppy.c7
-rw-r--r--drivers/block/loop.c184
-rw-r--r--drivers/block/umem.c1
-rw-r--r--drivers/char/Kconfig8
-rw-r--r--drivers/char/amiserial.c4
-rw-r--r--drivers/char/consolemap.c6
-rw-r--r--drivers/char/cs5535_gpio.c1
-rw-r--r--drivers/char/cyclades.c2581
-rw-r--r--drivers/char/digi.h71
-rw-r--r--drivers/char/ds1620.c1
-rw-r--r--drivers/char/dsp56k.c1
-rw-r--r--drivers/char/dtlk.c15
-rw-r--r--drivers/char/ec3104_keyb.c1
-rw-r--r--drivers/char/epca.c2
-rw-r--r--drivers/char/genrtc.c2
-rw-r--r--drivers/char/hangcheck-timer.c1
-rw-r--r--drivers/char/hvc_console.c12
-rw-r--r--drivers/char/hw_random/intel-rng.c219
-rw-r--r--drivers/char/i8k.c1
-rw-r--r--drivers/char/ip27-rtc.c1
-rw-r--r--drivers/char/ipmi/ipmi_si_intf.c235
-rw-r--r--drivers/char/ipmi/ipmi_watchdog.c136
-rw-r--r--drivers/char/isicom.c3
-rw-r--r--drivers/char/keyboard.c2
-rw-r--r--drivers/char/lp.c8
-rw-r--r--drivers/char/mem.c9
-rw-r--r--drivers/char/misc.c27
-rw-r--r--drivers/char/moxa.c8
-rw-r--r--drivers/char/mxser.c1
-rw-r--r--drivers/char/mxser_new.c1
-rw-r--r--drivers/char/n_r3964.c4
-rw-r--r--drivers/char/ppdev.c3
-rw-r--r--drivers/char/riscom8.c2
-rw-r--r--drivers/char/rocket.c33
-rw-r--r--drivers/char/rocket_int.h4
-rw-r--r--drivers/char/rtc.c2
-rw-r--r--drivers/char/selection.c2
-rw-r--r--drivers/char/serial167.c2
-rw-r--r--drivers/char/synclink.c7
-rw-r--r--drivers/char/synclink_gt.c34
-rw-r--r--drivers/char/sysrq.c1
-rw-r--r--drivers/char/tipar.c2
-rw-r--r--drivers/char/tpm/tpm.c36
-rw-r--r--drivers/char/tpm/tpm.h5
-rw-r--r--drivers/char/tpm/tpm_infineon.c231
-rw-r--r--drivers/char/tty_io.c53
-rw-r--r--drivers/char/vc_screen.c19
-rw-r--r--drivers/char/vt.c304
-rw-r--r--drivers/char/vt_ioctl.c2
-rw-r--r--drivers/char/watchdog/omap_wdt.c1
-rw-r--r--drivers/cpufreq/cpufreq_ondemand.c2
-rw-r--r--drivers/edac/i82875p_edac.c13
-rw-r--r--drivers/eisa/virtual_root.c2
-rw-r--r--drivers/hid/hid-core.c1
-rw-r--r--drivers/hwmon/Kconfig24
-rw-r--r--drivers/hwmon/Makefile1
-rw-r--r--drivers/hwmon/applesmc.c1339
-rw-r--r--drivers/hwmon/hdaps.c38
-rw-r--r--drivers/i2c/busses/i2c-parport.c1
-rw-r--r--drivers/i2c/busses/scx200_acb.c1
-rw-r--r--drivers/i2c/i2c-dev.c1
-rw-r--r--drivers/ieee1394/dv1394.c1
-rw-r--r--drivers/ieee1394/raw1394.c1
-rw-r--r--drivers/ieee1394/video1394.c1
-rw-r--r--drivers/infiniband/hw/ipath/ipath_fs.c2
-rw-r--r--drivers/infiniband/ulp/iser/iser_verbs.c1
-rw-r--r--drivers/input/evdev.c1
-rw-r--r--drivers/input/input.c1
-rw-r--r--drivers/input/joydev.c1
-rw-r--r--drivers/input/mousedev.c1
-rw-r--r--drivers/input/tsdev.c1
-rw-r--r--drivers/isdn/capi/capi.c34
-rw-r--r--drivers/isdn/capi/capiutil.c8
-rw-r--r--drivers/isdn/divert/divert_procfs.c1
-rw-r--r--drivers/isdn/hardware/eicon/capimain.c1
-rw-r--r--drivers/isdn/hardware/eicon/dbgioctl.h198
-rw-r--r--drivers/isdn/hardware/eicon/divamnt.c1
-rw-r--r--drivers/isdn/hardware/eicon/divasi.c1
-rw-r--r--drivers/isdn/hardware/eicon/divasmain.c1
-rw-r--r--drivers/isdn/hardware/eicon/main_if.h50
-rw-r--r--drivers/isdn/hardware/eicon/platform.h1
-rw-r--r--drivers/isdn/hisax/hfc_usb.c1
-rw-r--r--drivers/isdn/hysdn/boardergo.c2
-rw-r--r--drivers/isdn/hysdn/hysdn_proclog.c4
-rw-r--r--drivers/isdn/isdnloop/isdnloop.c2
-rw-r--r--drivers/macintosh/therm_adt746x.c1
-rw-r--r--drivers/macintosh/therm_pm72.c1
-rw-r--r--drivers/macintosh/windfarm_core.c1
-rw-r--r--drivers/md/bitmap.c8
-rw-r--r--drivers/media/dvb/bt8xx/dst_common.h1
-rw-r--r--drivers/media/dvb/ttpci/av7110_av.c1
-rw-r--r--drivers/media/dvb/ttpci/av7110_ca.c1
-rw-r--r--drivers/media/dvb/ttpci/av7110_hw.c1
-rw-r--r--drivers/media/dvb/ttpci/av7110_v4l.c1
-rw-r--r--drivers/media/radio/dsbr100.c1
-rw-r--r--drivers/media/video/cpia.h1
-rw-r--r--drivers/media/video/cpia_pp.c1
-rw-r--r--drivers/media/video/cx88/cx88-tvaudio.c1
-rw-r--r--drivers/media/video/dabusb.c1
-rw-r--r--drivers/media/video/ov511.h1
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-main.c1
-rw-r--r--drivers/media/video/saa7134/saa7134-tvaudio.c1
-rw-r--r--drivers/media/video/se401.h1
-rw-r--r--drivers/media/video/tvaudio.c1
-rw-r--r--drivers/media/video/usbvideo/usbvideo.c1
-rw-r--r--drivers/media/video/usbvision/usbvision-core.c1
-rw-r--r--drivers/media/video/usbvision/usbvision-video.c1
-rw-r--r--drivers/media/video/v4l1-compat.c1
-rw-r--r--drivers/media/video/v4l2-common.c1
-rw-r--r--drivers/media/video/videodev.c1
-rw-r--r--drivers/media/video/zoran_driver.c2
-rw-r--r--drivers/message/i2o/i2o_lan.h159
-rw-r--r--drivers/mfd/ucb1x00-ts.c1
-rw-r--r--drivers/misc/Kconfig18
-rw-r--r--drivers/misc/Makefile2
-rw-r--r--drivers/misc/blink.c27
-rw-r--r--drivers/misc/phantom.c463
-rw-r--r--drivers/mtd/mtd_blkdevs.c4
-rw-r--r--drivers/net/irda/sir_dev.c1
-rw-r--r--drivers/net/irda/sir_dongle.c1
-rw-r--r--drivers/net/irda/smsc-ircc2.c112
-rw-r--r--drivers/net/irda/vlsi_ir.c1
-rw-r--r--drivers/net/ns83820.c1
-rw-r--r--drivers/net/ppp_generic.c1
-rw-r--r--drivers/net/wan/cosa.c1
-rw-r--r--drivers/net/wireless/airo.c1
-rw-r--r--drivers/net/wireless/hostap/hostap_ioctl.c1
-rw-r--r--drivers/parisc/lba_pci.c1
-rw-r--r--drivers/parport/parport_cs.c2
-rw-r--r--drivers/parport/parport_mfc3.c1
-rw-r--r--drivers/parport/parport_pc.c70
-rw-r--r--drivers/parport/parport_serial.c10
-rw-r--r--drivers/parport/parport_sunbpp.c1
-rw-r--r--drivers/parport/share.c5
-rw-r--r--drivers/pci/hotplug/acpiphp_core.c1
-rw-r--r--drivers/pci/hotplug/acpiphp_glue.c1
-rw-r--r--drivers/pci/hotplug/ibmphp_core.c1
-rw-r--r--drivers/pci/hotplug/ibmphp_hpc.c1
-rw-r--r--drivers/pci/hotplug/pci_hotplug_core.c1
-rw-r--r--drivers/pci/hotplug/rpaphp_core.c1
-rw-r--r--drivers/pci/hotplug/shpchp_ctrl.c1
-rw-r--r--drivers/pci/msi.c1
-rw-r--r--drivers/pci/proc.c1
-rw-r--r--drivers/pcmcia/pxa2xx_mainstone.c1
-rw-r--r--drivers/pcmcia/pxa2xx_sharpsl.c1
-rw-r--r--drivers/pnp/core.c11
-rw-r--r--drivers/pnp/pnpacpi/core.c55
-rw-r--r--drivers/pnp/pnpbios/core.c17
-rw-r--r--drivers/pnp/quirks.c30
-rw-r--r--drivers/rtc/Kconfig276
-rw-r--r--drivers/rtc/Makefile8
-rw-r--r--drivers/rtc/class.c118
-rw-r--r--drivers/rtc/hctosys.c14
-rw-r--r--drivers/rtc/interface.c86
-rw-r--r--drivers/rtc/rtc-at91rm9200.c32
-rw-r--r--drivers/rtc/rtc-cmos.c79
-rw-r--r--drivers/rtc/rtc-core.h70
-rw-r--r--drivers/rtc/rtc-dev.c184
-rw-r--r--drivers/rtc/rtc-ds1553.c2
-rw-r--r--drivers/rtc/rtc-lib.c81
-rw-r--r--drivers/rtc/rtc-max6900.c311
-rw-r--r--drivers/rtc/rtc-omap.c57
-rw-r--r--drivers/rtc/rtc-pl031.c2
-rw-r--r--drivers/rtc/rtc-proc.c68
-rw-r--r--drivers/rtc/rtc-rs5c313.c405
-rw-r--r--drivers/rtc/rtc-s3c.c26
-rw-r--r--drivers/rtc/rtc-sa1100.c4
-rw-r--r--drivers/rtc/rtc-sh.c6
-rw-r--r--drivers/rtc/rtc-sysfs.c129
-rw-r--r--drivers/rtc/rtc-test.c6
-rw-r--r--drivers/rtc/rtc-vr41xx.c32
-rw-r--r--drivers/sbus/char/bpp.c1
-rw-r--r--drivers/sbus/char/rtc.c1
-rw-r--r--drivers/sbus/char/vfc_dev.c1
-rw-r--r--drivers/scsi/aic7xxx/aic79xx_osm.h1
-rw-r--r--drivers/scsi/aic7xxx/aic7xxx_osm.h1
-rw-r--r--drivers/scsi/dpt_i2o.c1
-rw-r--r--drivers/scsi/scsi_debug.c1
-rw-r--r--drivers/scsi/sg.c1
-rw-r--r--drivers/scsi/sni_53c710.c2
-rw-r--r--drivers/serial/8250.c2
-rw-r--r--drivers/serial/Kconfig14
-rw-r--r--drivers/serial/cpm_uart/cpm_uart_core.c12
-rw-r--r--drivers/serial/icom.c1
-rw-r--r--drivers/serial/jsm/jsm_neo.c7
-rw-r--r--drivers/serial/jsm/jsm_tty.c1
-rw-r--r--drivers/serial/s3c2410.c6
-rw-r--r--drivers/serial/serial_txx9.c32
-rw-r--r--drivers/spi/Kconfig20
-rw-r--r--drivers/spi/Makefile2
-rw-r--r--drivers/spi/au1550_spi.c974
-rw-r--r--drivers/spi/spi.c33
-rw-r--r--drivers/spi/spi_butterfly.c83
-rw-r--r--drivers/spi/spidev.c584
-rw-r--r--drivers/telephony/ixj.c3
-rw-r--r--drivers/usb/atm/usbatm.c1
-rw-r--r--drivers/usb/class/cdc-acm.c1
-rw-r--r--drivers/usb/class/usblp.c1
-rw-r--r--drivers/usb/core/hub.c1
-rw-r--r--drivers/usb/core/inode.c1
-rw-r--r--drivers/usb/core/usb.c1
-rw-r--r--drivers/usb/gadget/at91_udc.c1
-rw-r--r--drivers/usb/gadget/dummy_hcd.c1
-rw-r--r--drivers/usb/gadget/ether.c1
-rw-r--r--drivers/usb/gadget/goku_udc.c1
-rw-r--r--drivers/usb/gadget/net2280.c1
-rw-r--r--drivers/usb/gadget/serial.c1
-rw-r--r--drivers/usb/gadget/zero.c1
-rw-r--r--drivers/usb/host/ehci-hcd.c1
-rw-r--r--drivers/usb/host/ohci-hcd.c1
-rw-r--r--drivers/usb/host/sl811-hcd.c1
-rw-r--r--drivers/usb/host/u132-hcd.c1
-rw-r--r--drivers/usb/image/mdc800.c1
-rw-r--r--drivers/usb/image/microtek.c1
-rw-r--r--drivers/usb/input/xpad.c1
-rw-r--r--drivers/usb/misc/idmouse.c1
-rw-r--r--drivers/usb/misc/legousbtower.c1
-rw-r--r--drivers/usb/misc/rio500.c1
-rw-r--r--drivers/usb/misc/sisusbvga/sisusb_con.c3
-rw-r--r--drivers/usb/mon/mon_main.c1
-rw-r--r--drivers/usb/serial/usb-serial.c1
-rw-r--r--drivers/usb/storage/usb.h1
-rw-r--r--drivers/video/Kconfig127
-rw-r--r--drivers/video/Makefile20
-rw-r--r--drivers/video/arcfb.c28
-rw-r--r--drivers/video/aty/ati_ids.h2
-rw-r--r--drivers/video/aty/aty128fb.c29
-rw-r--r--drivers/video/aty/atyfb_base.c37
-rw-r--r--drivers/video/aty/mach64_ct.c8
-rw-r--r--drivers/video/aty/radeon_base.c5
-rw-r--r--drivers/video/aty/radeon_pm.c10
-rw-r--r--drivers/video/aty/radeonfb.h4
-rw-r--r--drivers/video/backlight/Kconfig8
-rw-r--r--drivers/video/backlight/Makefile1
-rw-r--r--drivers/video/backlight/cr_bllcd.c287
-rw-r--r--drivers/video/cfbcopyarea.c14
-rw-r--r--drivers/video/cfbfillrect.c68
-rw-r--r--drivers/video/cirrusfb.c69
-rw-r--r--drivers/video/console/fbcon.c136
-rw-r--r--drivers/video/console/fonts.c10
-rw-r--r--drivers/video/console/mdacon.c3
-rw-r--r--drivers/video/console/promcon.c3
-rw-r--r--drivers/video/console/sticon.c2
-rw-r--r--drivers/video/console/sticore.c2
-rw-r--r--drivers/video/console/vgacon.c17
-rw-r--r--drivers/video/display/Kconfig24
-rw-r--r--drivers/video/display/Makefile6
-rw-r--r--drivers/video/display/display-sysfs.c217
-rw-r--r--drivers/video/epson1355fb.c21
-rw-r--r--drivers/video/fb_defio.c151
-rw-r--r--drivers/video/fb_draw.h72
-rw-r--r--drivers/video/fb_sys_fops.c104
-rw-r--r--drivers/video/fbmem.c127
-rw-r--r--drivers/video/fbmon.c169
-rw-r--r--drivers/video/fbsysfs.c2
-rw-r--r--drivers/video/hecubafb.c471
-rw-r--r--drivers/video/i810/i810.h2
-rw-r--r--drivers/video/intelfb/intelfbhw.c34
-rw-r--r--drivers/video/logo/Kconfig30
-rw-r--r--drivers/video/modedb.c4
-rw-r--r--drivers/video/neofb.c1
-rw-r--r--drivers/video/nvidia/nv_accel.c76
-rw-r--r--drivers/video/nvidia/nv_hw.c15
-rw-r--r--drivers/video/nvidia/nv_i2c.c94
-rw-r--r--drivers/video/nvidia/nv_local.h4
-rw-r--r--drivers/video/nvidia/nv_setup.c5
-rw-r--r--drivers/video/nvidia/nv_type.h8
-rw-r--r--drivers/video/nvidia/nvidia.c81
-rw-r--r--drivers/video/pm2fb.c246
-rw-r--r--drivers/video/pvr2fb.c4
-rw-r--r--drivers/video/pxafb.c2
-rw-r--r--drivers/video/riva/fbdev.c18
-rw-r--r--drivers/video/riva/nv4ref.h2445
-rw-r--r--drivers/video/riva/nv_driver.c6
-rw-r--r--drivers/video/riva/riva_hw.c12
-rw-r--r--drivers/video/riva/rivafb-i2c.c41
-rw-r--r--drivers/video/riva/rivafb.h2
-rw-r--r--drivers/video/s3fb.c66
-rw-r--r--drivers/video/savage/savagefb-i2c.c22
-rw-r--r--drivers/video/savage/savagefb.h10
-rw-r--r--drivers/video/savage/savagefb_driver.c39
-rw-r--r--drivers/video/sis/osdef.h5
-rw-r--r--drivers/video/sis/sis.h51
-rw-r--r--drivers/video/sis/sis_main.c106
-rw-r--r--drivers/video/skeletonfb.c217
-rw-r--r--drivers/video/sm501fb.c2
-rw-r--r--drivers/video/svgalib.c38
-rw-r--r--drivers/video/syscopyarea.c378
-rw-r--r--drivers/video/sysfillrect.c334
-rw-r--r--drivers/video/sysimgblt.c291
-rw-r--r--drivers/video/tgafb.c425
-rw-r--r--drivers/video/vermilion/Makefile5
-rw-r--r--drivers/video/vermilion/cr_pll.c208
-rw-r--r--drivers/video/vermilion/vermilion.c1195
-rw-r--r--drivers/video/vermilion/vermilion.h260
-rw-r--r--drivers/video/vfb.c8
-rw-r--r--drivers/video/vga16fb.c2
-rw-r--r--drivers/video/vgastate.c26
-rw-r--r--drivers/video/xilinxfb.c381
-rw-r--r--drivers/w1/masters/Kconfig8
-rw-r--r--drivers/w1/masters/Makefile2
-rw-r--r--drivers/w1/masters/ds1wm.c468
-rw-r--r--drivers/w1/w1.c2
-rw-r--r--drivers/w1/w1_int.c3
313 files changed, 14177 insertions, 7025 deletions
diff --git a/drivers/acpi/glue.c b/drivers/acpi/glue.c
index 4334c208841a..41427a41f620 100644
--- a/drivers/acpi/glue.c
+++ b/drivers/acpi/glue.c
@@ -245,6 +245,35 @@ arch_initcall(init_acpi_device_notify);
245 245
246#if defined(CONFIG_RTC_DRV_CMOS) || defined(CONFIG_RTC_DRV_CMOS_MODULE) 246#if defined(CONFIG_RTC_DRV_CMOS) || defined(CONFIG_RTC_DRV_CMOS_MODULE)
247 247
248#ifdef CONFIG_PM
249static u32 rtc_handler(void *context)
250{
251 acpi_clear_event(ACPI_EVENT_RTC);
252 acpi_disable_event(ACPI_EVENT_RTC, 0);
253 return ACPI_INTERRUPT_HANDLED;
254}
255
256static inline void rtc_wake_setup(void)
257{
258 acpi_install_fixed_event_handler(ACPI_EVENT_RTC, rtc_handler, NULL);
259}
260
261static void rtc_wake_on(struct device *dev)
262{
263 acpi_clear_event(ACPI_EVENT_RTC);
264 acpi_enable_event(ACPI_EVENT_RTC, 0);
265}
266
267static void rtc_wake_off(struct device *dev)
268{
269 acpi_disable_event(ACPI_EVENT_RTC, 0);
270}
271#else
272#define rtc_wake_setup() do{}while(0)
273#define rtc_wake_on NULL
274#define rtc_wake_off NULL
275#endif
276
248/* Every ACPI platform has a mc146818 compatible "cmos rtc". Here we find 277/* Every ACPI platform has a mc146818 compatible "cmos rtc". Here we find
249 * its device node and pass extra config data. This helps its driver use 278 * its device node and pass extra config data. This helps its driver use
250 * capabilities that the now-obsolete mc146818 didn't have, and informs it 279 * capabilities that the now-obsolete mc146818 didn't have, and informs it
@@ -283,11 +312,24 @@ static int __init acpi_rtc_init(void)
283 struct device *dev = get_rtc_dev(); 312 struct device *dev = get_rtc_dev();
284 313
285 if (dev) { 314 if (dev) {
315 rtc_wake_setup();
316 rtc_info.wake_on = rtc_wake_on;
317 rtc_info.wake_off = rtc_wake_off;
318
319 /* workaround bug in some ACPI tables */
320 if (acpi_gbl_FADT.month_alarm && !acpi_gbl_FADT.day_alarm) {
321 DBG("bogus FADT month_alarm\n");
322 acpi_gbl_FADT.month_alarm = 0;
323 }
324
286 rtc_info.rtc_day_alarm = acpi_gbl_FADT.day_alarm; 325 rtc_info.rtc_day_alarm = acpi_gbl_FADT.day_alarm;
287 rtc_info.rtc_mon_alarm = acpi_gbl_FADT.month_alarm; 326 rtc_info.rtc_mon_alarm = acpi_gbl_FADT.month_alarm;
288 rtc_info.rtc_century = acpi_gbl_FADT.century; 327 rtc_info.rtc_century = acpi_gbl_FADT.century;
289 328
290 /* NOTE: acpi_gbl_FADT->rtcs4 is NOT currently useful */ 329 /* NOTE: S4_RTC_WAKE is NOT currently useful to Linux */
330 if (acpi_gbl_FADT.flags & ACPI_FADT_S4_RTC_WAKE)
331 printk(PREFIX "RTC can wake from S4\n");
332
291 333
292 dev->platform_data = &rtc_info; 334 dev->platform_data = &rtc_info;
293 335
@@ -296,7 +338,7 @@ static int __init acpi_rtc_init(void)
296 338
297 put_device(dev); 339 put_device(dev);
298 } else 340 } else
299 pr_debug("ACPI: RTC unavailable?\n"); 341 DBG("RTC unavailable?\n");
300 return 0; 342 return 0;
301} 343}
302/* do this between RTC subsys_initcall() and rtc_cmos driver_initcall() */ 344/* do this between RTC subsys_initcall() and rtc_cmos driver_initcall() */
diff --git a/drivers/acpi/numa.c b/drivers/acpi/numa.c
index 8fcd6a15517f..4dd0dabe81cb 100644
--- a/drivers/acpi/numa.c
+++ b/drivers/acpi/numa.c
@@ -228,7 +228,7 @@ int __init acpi_numa_init(void)
228 return 0; 228 return 0;
229} 229}
230 230
231int acpi_get_pxm(acpi_handle h) 231int __meminit acpi_get_pxm(acpi_handle h)
232{ 232{
233 unsigned long pxm; 233 unsigned long pxm;
234 acpi_status status; 234 acpi_status status;
@@ -246,7 +246,7 @@ int acpi_get_pxm(acpi_handle h)
246} 246}
247EXPORT_SYMBOL(acpi_get_pxm); 247EXPORT_SYMBOL(acpi_get_pxm);
248 248
249int acpi_get_node(acpi_handle *handle) 249int __meminit acpi_get_node(acpi_handle *handle)
250{ 250{
251 int pxm, node = -1; 251 int pxm, node = -1;
252 252
diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c
index 971eca4864fa..c2bed56915e1 100644
--- a/drivers/acpi/osl.c
+++ b/drivers/acpi/osl.c
@@ -30,7 +30,6 @@
30#include <linux/slab.h> 30#include <linux/slab.h>
31#include <linux/mm.h> 31#include <linux/mm.h>
32#include <linux/pci.h> 32#include <linux/pci.h>
33#include <linux/smp_lock.h>
34#include <linux/interrupt.h> 33#include <linux/interrupt.h>
35#include <linux/kmod.h> 34#include <linux/kmod.h>
36#include <linux/delay.h> 35#include <linux/delay.h>
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index d80dd84e5bfd..6b3b8a522476 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -302,7 +302,7 @@ static void acpi_device_shutdown(struct device *dev)
302 return ; 302 return ;
303} 303}
304 304
305static struct bus_type acpi_bus_type = { 305struct bus_type acpi_bus_type = {
306 .name = "acpi", 306 .name = "acpi",
307 .suspend = acpi_device_suspend, 307 .suspend = acpi_device_suspend,
308 .resume = acpi_device_resume, 308 .resume = acpi_device_resume,
diff --git a/drivers/acpi/sleep/proc.c b/drivers/acpi/sleep/proc.c
index dcde9ddd105a..5a76e5be61d5 100644
--- a/drivers/acpi/sleep/proc.c
+++ b/drivers/acpi/sleep/proc.c
@@ -70,6 +70,14 @@ acpi_system_write_sleep(struct file *file,
70} 70}
71#endif /* CONFIG_ACPI_SLEEP_PROC_SLEEP */ 71#endif /* CONFIG_ACPI_SLEEP_PROC_SLEEP */
72 72
73#if defined(CONFIG_RTC_DRV_CMOS) || defined(CONFIG_RTC_DRV_CMOS_MODULE)
74/* use /sys/class/rtc/rtcX/wakealarm instead; it's not ACPI-specific */
75#else
76#define HAVE_ACPI_LEGACY_ALARM
77#endif
78
79#ifdef HAVE_ACPI_LEGACY_ALARM
80
73static int acpi_system_alarm_seq_show(struct seq_file *seq, void *offset) 81static int acpi_system_alarm_seq_show(struct seq_file *seq, void *offset)
74{ 82{
75 u32 sec, min, hr; 83 u32 sec, min, hr;
@@ -341,6 +349,8 @@ acpi_system_write_alarm(struct file *file,
341 end: 349 end:
342 return_VALUE(result ? result : count); 350 return_VALUE(result ? result : count);
343} 351}
352#endif /* HAVE_ACPI_LEGACY_ALARM */
353
344 354
345extern struct list_head acpi_wakeup_device_list; 355extern struct list_head acpi_wakeup_device_list;
346extern spinlock_t acpi_device_lock; 356extern spinlock_t acpi_device_lock;
@@ -464,6 +474,7 @@ static const struct file_operations acpi_system_sleep_fops = {
464}; 474};
465#endif /* CONFIG_ACPI_SLEEP_PROC_SLEEP */ 475#endif /* CONFIG_ACPI_SLEEP_PROC_SLEEP */
466 476
477#ifdef HAVE_ACPI_LEGACY_ALARM
467static const struct file_operations acpi_system_alarm_fops = { 478static const struct file_operations acpi_system_alarm_fops = {
468 .open = acpi_system_alarm_open_fs, 479 .open = acpi_system_alarm_open_fs,
469 .read = seq_read, 480 .read = seq_read,
@@ -479,8 +490,9 @@ static u32 rtc_handler(void *context)
479 490
480 return ACPI_INTERRUPT_HANDLED; 491 return ACPI_INTERRUPT_HANDLED;
481} 492}
493#endif /* HAVE_ACPI_LEGACY_ALARM */
482 494
483static int acpi_sleep_proc_init(void) 495static int __init acpi_sleep_proc_init(void)
484{ 496{
485 struct proc_dir_entry *entry = NULL; 497 struct proc_dir_entry *entry = NULL;
486 498
@@ -496,6 +508,7 @@ static int acpi_sleep_proc_init(void)
496 entry->proc_fops = &acpi_system_sleep_fops; 508 entry->proc_fops = &acpi_system_sleep_fops;
497#endif 509#endif
498 510
511#ifdef HAVE_ACPI_LEGACY_ALARM
499 /* 'alarm' [R/W] */ 512 /* 'alarm' [R/W] */
500 entry = 513 entry =
501 create_proc_entry("alarm", S_IFREG | S_IRUGO | S_IWUSR, 514 create_proc_entry("alarm", S_IFREG | S_IRUGO | S_IWUSR,
@@ -503,6 +516,9 @@ static int acpi_sleep_proc_init(void)
503 if (entry) 516 if (entry)
504 entry->proc_fops = &acpi_system_alarm_fops; 517 entry->proc_fops = &acpi_system_alarm_fops;
505 518
519 acpi_install_fixed_event_handler(ACPI_EVENT_RTC, rtc_handler, NULL);
520#endif /* HAVE_ACPI_LEGACY_ALARM */
521
506 /* 'wakeup device' [R/W] */ 522 /* 'wakeup device' [R/W] */
507 entry = 523 entry =
508 create_proc_entry("wakeup", S_IFREG | S_IRUGO | S_IWUSR, 524 create_proc_entry("wakeup", S_IFREG | S_IRUGO | S_IWUSR,
@@ -510,7 +526,6 @@ static int acpi_sleep_proc_init(void)
510 if (entry) 526 if (entry)
511 entry->proc_fops = &acpi_system_wakeup_device_fops; 527 entry->proc_fops = &acpi_system_wakeup_device_fops;
512 528
513 acpi_install_fixed_event_handler(ACPI_EVENT_RTC, rtc_handler, NULL);
514 return 0; 529 return 0;
515} 530}
516 531
diff --git a/drivers/base/platform.c b/drivers/base/platform.c
index 17b5ece8f82c..eb84d9d44645 100644
--- a/drivers/base/platform.c
+++ b/drivers/base/platform.c
@@ -160,6 +160,11 @@ static void platform_device_release(struct device *dev)
160 * 160 *
161 * Create a platform device object which can have other objects attached 161 * Create a platform device object which can have other objects attached
162 * to it, and which will have attached objects freed when it is released. 162 * to it, and which will have attached objects freed when it is released.
163 *
164 * This device will be marked as not supporting hotpluggable drivers; no
165 * device add/remove uevents will be generated. In the unusual case that
166 * the device isn't being dynamically allocated as a legacy "probe the
167 * hardware" driver, infrastructure code should reverse this marking.
163 */ 168 */
164struct platform_device *platform_device_alloc(const char *name, unsigned int id) 169struct platform_device *platform_device_alloc(const char *name, unsigned int id)
165{ 170{
@@ -172,6 +177,12 @@ struct platform_device *platform_device_alloc(const char *name, unsigned int id)
172 pa->pdev.id = id; 177 pa->pdev.id = id;
173 device_initialize(&pa->pdev.dev); 178 device_initialize(&pa->pdev.dev);
174 pa->pdev.dev.release = platform_device_release; 179 pa->pdev.dev.release = platform_device_release;
180
181 /* prevent hotplug "modprobe $(MODALIAS)" from causing trouble in
182 * legacy probe-the-hardware drivers, which don't properly split
183 * out device enumeration logic from drivers.
184 */
185 pa->pdev.dev.uevent_suppress = 1;
175 } 186 }
176 187
177 return pa ? &pa->pdev : NULL; 188 return pa ? &pa->pdev : NULL;
@@ -351,6 +362,13 @@ EXPORT_SYMBOL_GPL(platform_device_unregister);
351 * memory allocated for the device allows drivers using such devices 362 * memory allocated for the device allows drivers using such devices
352 * to be unloaded iwithout waiting for the last reference to the device 363 * to be unloaded iwithout waiting for the last reference to the device
353 * to be dropped. 364 * to be dropped.
365 *
366 * This interface is primarily intended for use with legacy drivers
367 * which probe hardware directly. Because such drivers create sysfs
368 * device nodes themselves, rather than letting system infrastructure
369 * handle such device enumeration tasks, they don't fully conform to
370 * the Linux driver model. In particular, when such drivers are built
371 * as modules, they can't be "hotplugged".
354 */ 372 */
355struct platform_device *platform_device_register_simple(char *name, unsigned int id, 373struct platform_device *platform_device_register_simple(char *name, unsigned int id,
356 struct resource *res, unsigned int num) 374 struct resource *res, unsigned int num)
diff --git a/drivers/block/acsi_slm.c b/drivers/block/acsi_slm.c
index e2e043290963..1d9d9b4f48cc 100644
--- a/drivers/block/acsi_slm.c
+++ b/drivers/block/acsi_slm.c
@@ -65,7 +65,6 @@ not be guaranteed. There are several ways to assure this:
65#include <linux/time.h> 65#include <linux/time.h>
66#include <linux/mm.h> 66#include <linux/mm.h>
67#include <linux/slab.h> 67#include <linux/slab.h>
68#include <linux/smp_lock.h>
69 68
70#include <asm/pgtable.h> 69#include <asm/pgtable.h>
71#include <asm/system.h> 70#include <asm/system.h>
diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c
index 65a725cd3422..370dfe1c422e 100644
--- a/drivers/block/cciss.c
+++ b/drivers/block/cciss.c
@@ -45,6 +45,10 @@
45#include <linux/blkdev.h> 45#include <linux/blkdev.h>
46#include <linux/genhd.h> 46#include <linux/genhd.h>
47#include <linux/completion.h> 47#include <linux/completion.h>
48#include <scsi/scsi.h>
49#include <scsi/sg.h>
50#include <scsi/scsi_ioctl.h>
51#include <linux/cdrom.h>
48 52
49#define CCISS_DRIVER_VERSION(maj,min,submin) ((maj<<16)|(min<<8)|(submin)) 53#define CCISS_DRIVER_VERSION(maj,min,submin) ((maj<<16)|(min<<8)|(submin))
50#define DRIVER_NAME "HP CISS Driver (v 3.6.14)" 54#define DRIVER_NAME "HP CISS Driver (v 3.6.14)"
@@ -1152,6 +1156,30 @@ static int cciss_ioctl(struct inode *inode, struct file *filep,
1152 kfree(ioc); 1156 kfree(ioc);
1153 return status; 1157 return status;
1154 } 1158 }
1159
1160 /* scsi_cmd_ioctl handles these, below, though some are not */
1161 /* very meaningful for cciss. SG_IO is the main one people want. */
1162
1163 case SG_GET_VERSION_NUM:
1164 case SG_SET_TIMEOUT:
1165 case SG_GET_TIMEOUT:
1166 case SG_GET_RESERVED_SIZE:
1167 case SG_SET_RESERVED_SIZE:
1168 case SG_EMULATED_HOST:
1169 case SG_IO:
1170 case SCSI_IOCTL_SEND_COMMAND:
1171 return scsi_cmd_ioctl(filep, disk, cmd, argp);
1172
1173 /* scsi_cmd_ioctl would normally handle these, below, but */
1174 /* they aren't a good fit for cciss, as CD-ROMs are */
1175 /* not supported, and we don't have any bus/target/lun */
1176 /* which we present to the kernel. */
1177
1178 case CDROM_SEND_PACKET:
1179 case CDROMCLOSETRAY:
1180 case CDROMEJECT:
1181 case SCSI_IOCTL_GET_IDLUN:
1182 case SCSI_IOCTL_GET_BUS_NUMBER:
1155 default: 1183 default:
1156 return -ENOTTY; 1184 return -ENOTTY;
1157 } 1185 }
@@ -1234,7 +1262,7 @@ static void cciss_softirq_done(struct request *rq)
1234 pci_unmap_page(h->pdev, temp64.val, cmd->SG[i].Len, ddir); 1262 pci_unmap_page(h->pdev, temp64.val, cmd->SG[i].Len, ddir);
1235 } 1263 }
1236 1264
1237 complete_buffers(rq->bio, rq->errors); 1265 complete_buffers(rq->bio, (rq->errors == 0));
1238 1266
1239 if (blk_fs_request(rq)) { 1267 if (blk_fs_request(rq)) {
1240 const int rw = rq_data_dir(rq); 1268 const int rw = rq_data_dir(rq);
@@ -1248,7 +1276,7 @@ static void cciss_softirq_done(struct request *rq)
1248 1276
1249 add_disk_randomness(rq->rq_disk); 1277 add_disk_randomness(rq->rq_disk);
1250 spin_lock_irqsave(&h->lock, flags); 1278 spin_lock_irqsave(&h->lock, flags);
1251 end_that_request_last(rq, rq->errors); 1279 end_that_request_last(rq, (rq->errors == 0));
1252 cmd_free(h, cmd, 1); 1280 cmd_free(h, cmd, 1);
1253 cciss_check_queues(h); 1281 cciss_check_queues(h);
1254 spin_unlock_irqrestore(&h->lock, flags); 1282 spin_unlock_irqrestore(&h->lock, flags);
@@ -2336,6 +2364,44 @@ static inline void resend_cciss_cmd(ctlr_info_t *h, CommandList_struct *c)
2336 start_io(h); 2364 start_io(h);
2337} 2365}
2338 2366
2367static inline int evaluate_target_status(CommandList_struct *cmd)
2368{
2369 unsigned char sense_key;
2370 int error_count = 1;
2371
2372 if (cmd->err_info->ScsiStatus != 0x02) { /* not check condition? */
2373 if (!blk_pc_request(cmd->rq))
2374 printk(KERN_WARNING "cciss: cmd %p "
2375 "has SCSI Status 0x%x\n",
2376 cmd, cmd->err_info->ScsiStatus);
2377 return error_count;
2378 }
2379
2380 /* check the sense key */
2381 sense_key = 0xf & cmd->err_info->SenseInfo[2];
2382 /* no status or recovered error */
2383 if ((sense_key == 0x0) || (sense_key == 0x1))
2384 error_count = 0;
2385
2386 if (!blk_pc_request(cmd->rq)) { /* Not SG_IO or similar? */
2387 if (error_count != 0)
2388 printk(KERN_WARNING "cciss: cmd %p has CHECK CONDITION"
2389 " sense key = 0x%x\n", cmd, sense_key);
2390 return error_count;
2391 }
2392
2393 /* SG_IO or similar, copy sense data back */
2394 if (cmd->rq->sense) {
2395 if (cmd->rq->sense_len > cmd->err_info->SenseLen)
2396 cmd->rq->sense_len = cmd->err_info->SenseLen;
2397 memcpy(cmd->rq->sense, cmd->err_info->SenseInfo,
2398 cmd->rq->sense_len);
2399 } else
2400 cmd->rq->sense_len = 0;
2401
2402 return error_count;
2403}
2404
2339/* checks the status of the job and calls complete buffers to mark all 2405/* checks the status of the job and calls complete buffers to mark all
2340 * buffers for the completed job. Note that this function does not need 2406 * buffers for the completed job. Note that this function does not need
2341 * to hold the hba/queue lock. 2407 * to hold the hba/queue lock.
@@ -2343,109 +2409,99 @@ static inline void resend_cciss_cmd(ctlr_info_t *h, CommandList_struct *c)
2343static inline void complete_command(ctlr_info_t *h, CommandList_struct *cmd, 2409static inline void complete_command(ctlr_info_t *h, CommandList_struct *cmd,
2344 int timeout) 2410 int timeout)
2345{ 2411{
2346 int status = 1;
2347 int retry_cmd = 0; 2412 int retry_cmd = 0;
2413 struct request *rq = cmd->rq;
2414
2415 rq->errors = 0;
2348 2416
2349 if (timeout) 2417 if (timeout)
2350 status = 0; 2418 rq->errors = 1;
2351 2419
2352 if (cmd->err_info->CommandStatus != 0) { /* an error has occurred */ 2420 if (cmd->err_info->CommandStatus == 0) /* no error has occurred */
2353 switch (cmd->err_info->CommandStatus) { 2421 goto after_error_processing;
2354 unsigned char sense_key;
2355 case CMD_TARGET_STATUS:
2356 status = 0;
2357 2422
2358 if (cmd->err_info->ScsiStatus == 0x02) { 2423 switch (cmd->err_info->CommandStatus) {
2359 printk(KERN_WARNING "cciss: cmd %p " 2424 case CMD_TARGET_STATUS:
2360 "has CHECK CONDITION " 2425 rq->errors = evaluate_target_status(cmd);
2361 " byte 2 = 0x%x\n", cmd, 2426 break;
2362 cmd->err_info->SenseInfo[2] 2427 case CMD_DATA_UNDERRUN:
2363 ); 2428 if (blk_fs_request(cmd->rq)) {
2364 /* check the sense key */
2365 sense_key = 0xf & cmd->err_info->SenseInfo[2];
2366 /* no status or recovered error */
2367 if ((sense_key == 0x0) || (sense_key == 0x1)) {
2368 status = 1;
2369 }
2370 } else {
2371 printk(KERN_WARNING "cciss: cmd %p "
2372 "has SCSI Status 0x%x\n",
2373 cmd, cmd->err_info->ScsiStatus);
2374 }
2375 break;
2376 case CMD_DATA_UNDERRUN:
2377 printk(KERN_WARNING "cciss: cmd %p has" 2429 printk(KERN_WARNING "cciss: cmd %p has"
2378 " completed with data underrun " 2430 " completed with data underrun "
2379 "reported\n", cmd); 2431 "reported\n", cmd);
2380 break; 2432 cmd->rq->data_len = cmd->err_info->ResidualCnt;
2381 case CMD_DATA_OVERRUN: 2433 }
2434 break;
2435 case CMD_DATA_OVERRUN:
2436 if (blk_fs_request(cmd->rq))
2382 printk(KERN_WARNING "cciss: cmd %p has" 2437 printk(KERN_WARNING "cciss: cmd %p has"
2383 " completed with data overrun " 2438 " completed with data overrun "
2384 "reported\n", cmd); 2439 "reported\n", cmd);
2385 break; 2440 break;
2386 case CMD_INVALID: 2441 case CMD_INVALID:
2387 printk(KERN_WARNING "cciss: cmd %p is " 2442 printk(KERN_WARNING "cciss: cmd %p is "
2388 "reported invalid\n", cmd); 2443 "reported invalid\n", cmd);
2389 status = 0; 2444 rq->errors = 1;
2390 break; 2445 break;
2391 case CMD_PROTOCOL_ERR: 2446 case CMD_PROTOCOL_ERR:
2392 printk(KERN_WARNING "cciss: cmd %p has " 2447 printk(KERN_WARNING "cciss: cmd %p has "
2393 "protocol error \n", cmd); 2448 "protocol error \n", cmd);
2394 status = 0; 2449 rq->errors = 1;
2395 break; 2450 break;
2396 case CMD_HARDWARE_ERR: 2451 case CMD_HARDWARE_ERR:
2397 printk(KERN_WARNING "cciss: cmd %p had " 2452 printk(KERN_WARNING "cciss: cmd %p had "
2398 " hardware error\n", cmd); 2453 " hardware error\n", cmd);
2399 status = 0; 2454 rq->errors = 1;
2400 break; 2455 break;
2401 case CMD_CONNECTION_LOST: 2456 case CMD_CONNECTION_LOST:
2402 printk(KERN_WARNING "cciss: cmd %p had " 2457 printk(KERN_WARNING "cciss: cmd %p had "
2403 "connection lost\n", cmd); 2458 "connection lost\n", cmd);
2404 status = 0; 2459 rq->errors = 1;
2405 break; 2460 break;
2406 case CMD_ABORTED: 2461 case CMD_ABORTED:
2407 printk(KERN_WARNING "cciss: cmd %p was " 2462 printk(KERN_WARNING "cciss: cmd %p was "
2408 "aborted\n", cmd); 2463 "aborted\n", cmd);
2409 status = 0; 2464 rq->errors = 1;
2410 break; 2465 break;
2411 case CMD_ABORT_FAILED: 2466 case CMD_ABORT_FAILED:
2412 printk(KERN_WARNING "cciss: cmd %p reports " 2467 printk(KERN_WARNING "cciss: cmd %p reports "
2413 "abort failed\n", cmd); 2468 "abort failed\n", cmd);
2414 status = 0; 2469 rq->errors = 1;
2415 break; 2470 break;
2416 case CMD_UNSOLICITED_ABORT: 2471 case CMD_UNSOLICITED_ABORT:
2417 printk(KERN_WARNING "cciss%d: unsolicited " 2472 printk(KERN_WARNING "cciss%d: unsolicited "
2418 "abort %p\n", h->ctlr, cmd); 2473 "abort %p\n", h->ctlr, cmd);
2419 if (cmd->retry_count < MAX_CMD_RETRIES) { 2474 if (cmd->retry_count < MAX_CMD_RETRIES) {
2420 retry_cmd = 1; 2475 retry_cmd = 1;
2421 printk(KERN_WARNING 2476 printk(KERN_WARNING
2422 "cciss%d: retrying %p\n", h->ctlr, cmd); 2477 "cciss%d: retrying %p\n", h->ctlr, cmd);
2423 cmd->retry_count++; 2478 cmd->retry_count++;
2424 } else 2479 } else
2425 printk(KERN_WARNING 2480 printk(KERN_WARNING
2426 "cciss%d: %p retried too " 2481 "cciss%d: %p retried too "
2427 "many times\n", h->ctlr, cmd); 2482 "many times\n", h->ctlr, cmd);
2428 status = 0; 2483 rq->errors = 1;
2429 break; 2484 break;
2430 case CMD_TIMEOUT: 2485 case CMD_TIMEOUT:
2431 printk(KERN_WARNING "cciss: cmd %p timedout\n", cmd); 2486 printk(KERN_WARNING "cciss: cmd %p timedout\n", cmd);
2432 status = 0; 2487 rq->errors = 1;
2433 break; 2488 break;
2434 default: 2489 default:
2435 printk(KERN_WARNING "cciss: cmd %p returned " 2490 printk(KERN_WARNING "cciss: cmd %p returned "
2436 "unknown status %x\n", cmd, 2491 "unknown status %x\n", cmd,
2437 cmd->err_info->CommandStatus); 2492 cmd->err_info->CommandStatus);
2438 status = 0; 2493 rq->errors = 1;
2439 }
2440 } 2494 }
2495
2496after_error_processing:
2497
2441 /* We need to return this command */ 2498 /* We need to return this command */
2442 if (retry_cmd) { 2499 if (retry_cmd) {
2443 resend_cciss_cmd(h, cmd); 2500 resend_cciss_cmd(h, cmd);
2444 return; 2501 return;
2445 } 2502 }
2446 2503 cmd->rq->data_len = 0;
2447 cmd->rq->completion_data = cmd; 2504 cmd->rq->completion_data = cmd;
2448 cmd->rq->errors = status;
2449 blk_add_trace_rq(cmd->rq->q, cmd->rq, BLK_TA_COMPLETE); 2505 blk_add_trace_rq(cmd->rq->q, cmd->rq, BLK_TA_COMPLETE);
2450 blk_complete_request(cmd->rq); 2506 blk_complete_request(cmd->rq);
2451} 2507}
@@ -2539,32 +2595,40 @@ static void do_cciss_request(request_queue_t *q)
2539#endif /* CCISS_DEBUG */ 2595#endif /* CCISS_DEBUG */
2540 2596
2541 c->Header.SGList = c->Header.SGTotal = seg; 2597 c->Header.SGList = c->Header.SGTotal = seg;
2542 if(h->cciss_read == CCISS_READ_10) { 2598 if (likely(blk_fs_request(creq))) {
2543 c->Request.CDB[1] = 0; 2599 if(h->cciss_read == CCISS_READ_10) {
2544 c->Request.CDB[2] = (start_blk >> 24) & 0xff; //MSB 2600 c->Request.CDB[1] = 0;
2545 c->Request.CDB[3] = (start_blk >> 16) & 0xff; 2601 c->Request.CDB[2] = (start_blk >> 24) & 0xff; //MSB
2546 c->Request.CDB[4] = (start_blk >> 8) & 0xff; 2602 c->Request.CDB[3] = (start_blk >> 16) & 0xff;
2547 c->Request.CDB[5] = start_blk & 0xff; 2603 c->Request.CDB[4] = (start_blk >> 8) & 0xff;
2548 c->Request.CDB[6] = 0; // (sect >> 24) & 0xff; MSB 2604 c->Request.CDB[5] = start_blk & 0xff;
2549 c->Request.CDB[7] = (creq->nr_sectors >> 8) & 0xff; 2605 c->Request.CDB[6] = 0; // (sect >> 24) & 0xff; MSB
2550 c->Request.CDB[8] = creq->nr_sectors & 0xff; 2606 c->Request.CDB[7] = (creq->nr_sectors >> 8) & 0xff;
2551 c->Request.CDB[9] = c->Request.CDB[11] = c->Request.CDB[12] = 0; 2607 c->Request.CDB[8] = creq->nr_sectors & 0xff;
2608 c->Request.CDB[9] = c->Request.CDB[11] = c->Request.CDB[12] = 0;
2609 } else {
2610 c->Request.CDBLen = 16;
2611 c->Request.CDB[1]= 0;
2612 c->Request.CDB[2]= (start_blk >> 56) & 0xff; //MSB
2613 c->Request.CDB[3]= (start_blk >> 48) & 0xff;
2614 c->Request.CDB[4]= (start_blk >> 40) & 0xff;
2615 c->Request.CDB[5]= (start_blk >> 32) & 0xff;
2616 c->Request.CDB[6]= (start_blk >> 24) & 0xff;
2617 c->Request.CDB[7]= (start_blk >> 16) & 0xff;
2618 c->Request.CDB[8]= (start_blk >> 8) & 0xff;
2619 c->Request.CDB[9]= start_blk & 0xff;
2620 c->Request.CDB[10]= (creq->nr_sectors >> 24) & 0xff;
2621 c->Request.CDB[11]= (creq->nr_sectors >> 16) & 0xff;
2622 c->Request.CDB[12]= (creq->nr_sectors >> 8) & 0xff;
2623 c->Request.CDB[13]= creq->nr_sectors & 0xff;
2624 c->Request.CDB[14] = c->Request.CDB[15] = 0;
2625 }
2626 } else if (blk_pc_request(creq)) {
2627 c->Request.CDBLen = creq->cmd_len;
2628 memcpy(c->Request.CDB, creq->cmd, BLK_MAX_CDB);
2552 } else { 2629 } else {
2553 c->Request.CDBLen = 16; 2630 printk(KERN_WARNING "cciss%d: bad request type %d\n", h->ctlr, creq->cmd_type);
2554 c->Request.CDB[1]= 0; 2631 BUG();
2555 c->Request.CDB[2]= (start_blk >> 56) & 0xff; //MSB
2556 c->Request.CDB[3]= (start_blk >> 48) & 0xff;
2557 c->Request.CDB[4]= (start_blk >> 40) & 0xff;
2558 c->Request.CDB[5]= (start_blk >> 32) & 0xff;
2559 c->Request.CDB[6]= (start_blk >> 24) & 0xff;
2560 c->Request.CDB[7]= (start_blk >> 16) & 0xff;
2561 c->Request.CDB[8]= (start_blk >> 8) & 0xff;
2562 c->Request.CDB[9]= start_blk & 0xff;
2563 c->Request.CDB[10]= (creq->nr_sectors >> 24) & 0xff;
2564 c->Request.CDB[11]= (creq->nr_sectors >> 16) & 0xff;
2565 c->Request.CDB[12]= (creq->nr_sectors >> 8) & 0xff;
2566 c->Request.CDB[13]= creq->nr_sectors & 0xff;
2567 c->Request.CDB[14] = c->Request.CDB[15] = 0;
2568 } 2632 }
2569 2633
2570 spin_lock_irq(q->queue_lock); 2634 spin_lock_irq(q->queue_lock);
diff --git a/drivers/block/cciss_scsi.c b/drivers/block/cciss_scsi.c
index bb15051ffbe0..90961a8ea895 100644
--- a/drivers/block/cciss_scsi.c
+++ b/drivers/block/cciss_scsi.c
@@ -35,7 +35,6 @@
35 35
36#include <asm/atomic.h> 36#include <asm/atomic.h>
37 37
38#include <scsi/scsi.h>
39#include <scsi/scsi_cmnd.h> 38#include <scsi/scsi_cmnd.h>
40#include <scsi/scsi_device.h> 39#include <scsi/scsi_device.h>
41#include <scsi/scsi_host.h> 40#include <scsi/scsi_host.h>
diff --git a/drivers/block/floppy.c b/drivers/block/floppy.c
index 5231ed7e723f..3587cb434371 100644
--- a/drivers/block/floppy.c
+++ b/drivers/block/floppy.c
@@ -4334,7 +4334,10 @@ static int __init floppy_init(void)
4334 if (err) 4334 if (err)
4335 goto out_flush_work; 4335 goto out_flush_work;
4336 4336
4337 device_create_file(&floppy_device[drive].dev,&dev_attr_cmos); 4337 err = device_create_file(&floppy_device[drive].dev,&dev_attr_cmos);
4338 if (err)
4339 goto out_unreg_platform_dev;
4340
4338 /* to be cleaned up... */ 4341 /* to be cleaned up... */
4339 disks[drive]->private_data = (void *)(long)drive; 4342 disks[drive]->private_data = (void *)(long)drive;
4340 disks[drive]->queue = floppy_queue; 4343 disks[drive]->queue = floppy_queue;
@@ -4345,6 +4348,8 @@ static int __init floppy_init(void)
4345 4348
4346 return 0; 4349 return 0;
4347 4350
4351out_unreg_platform_dev:
4352 platform_device_unregister(&floppy_device[drive]);
4348out_flush_work: 4353out_flush_work:
4349 flush_scheduled_work(); 4354 flush_scheduled_work();
4350 if (usage_count) 4355 if (usage_count)
diff --git a/drivers/block/loop.c b/drivers/block/loop.c
index 0d4ccd4a0957..af6d7274a7cc 100644
--- a/drivers/block/loop.c
+++ b/drivers/block/loop.c
@@ -77,9 +77,8 @@
77 77
78#include <asm/uaccess.h> 78#include <asm/uaccess.h>
79 79
80static int max_loop = 8; 80static LIST_HEAD(loop_devices);
81static struct loop_device *loop_dev; 81static DEFINE_MUTEX(loop_devices_mutex);
82static struct gendisk **disks;
83 82
84/* 83/*
85 * Transfer functions 84 * Transfer functions
@@ -183,7 +182,7 @@ figure_loop_size(struct loop_device *lo)
183 if (unlikely((loff_t)x != size)) 182 if (unlikely((loff_t)x != size))
184 return -EFBIG; 183 return -EFBIG;
185 184
186 set_capacity(disks[lo->lo_number], x); 185 set_capacity(lo->lo_disk, x);
187 return 0; 186 return 0;
188} 187}
189 188
@@ -812,7 +811,7 @@ static int loop_set_fd(struct loop_device *lo, struct file *lo_file,
812 lo->lo_queue->queuedata = lo; 811 lo->lo_queue->queuedata = lo;
813 lo->lo_queue->unplug_fn = loop_unplug; 812 lo->lo_queue->unplug_fn = loop_unplug;
814 813
815 set_capacity(disks[lo->lo_number], size); 814 set_capacity(lo->lo_disk, size);
816 bd_set_size(bdev, size << 9); 815 bd_set_size(bdev, size << 9);
817 816
818 set_blocksize(bdev, lo_blocksize); 817 set_blocksize(bdev, lo_blocksize);
@@ -832,7 +831,7 @@ out_clr:
832 lo->lo_device = NULL; 831 lo->lo_device = NULL;
833 lo->lo_backing_file = NULL; 832 lo->lo_backing_file = NULL;
834 lo->lo_flags = 0; 833 lo->lo_flags = 0;
835 set_capacity(disks[lo->lo_number], 0); 834 set_capacity(lo->lo_disk, 0);
836 invalidate_bdev(bdev); 835 invalidate_bdev(bdev);
837 bd_set_size(bdev, 0); 836 bd_set_size(bdev, 0);
838 mapping_set_gfp_mask(mapping, lo->old_gfp_mask); 837 mapping_set_gfp_mask(mapping, lo->old_gfp_mask);
@@ -918,7 +917,7 @@ static int loop_clr_fd(struct loop_device *lo, struct block_device *bdev)
918 memset(lo->lo_crypt_name, 0, LO_NAME_SIZE); 917 memset(lo->lo_crypt_name, 0, LO_NAME_SIZE);
919 memset(lo->lo_file_name, 0, LO_NAME_SIZE); 918 memset(lo->lo_file_name, 0, LO_NAME_SIZE);
920 invalidate_bdev(bdev); 919 invalidate_bdev(bdev);
921 set_capacity(disks[lo->lo_number], 0); 920 set_capacity(lo->lo_disk, 0);
922 bd_set_size(bdev, 0); 921 bd_set_size(bdev, 0);
923 mapping_set_gfp_mask(filp->f_mapping, gfp); 922 mapping_set_gfp_mask(filp->f_mapping, gfp);
924 lo->lo_state = Lo_unbound; 923 lo->lo_state = Lo_unbound;
@@ -1322,6 +1321,18 @@ static long lo_compat_ioctl(struct file *file, unsigned int cmd, unsigned long a
1322} 1321}
1323#endif 1322#endif
1324 1323
1324static struct loop_device *loop_find_dev(int number)
1325{
1326 struct loop_device *lo;
1327
1328 list_for_each_entry(lo, &loop_devices, lo_list) {
1329 if (lo->lo_number == number)
1330 return lo;
1331 }
1332 return NULL;
1333}
1334
1335static struct loop_device *loop_init_one(int i);
1325static int lo_open(struct inode *inode, struct file *file) 1336static int lo_open(struct inode *inode, struct file *file)
1326{ 1337{
1327 struct loop_device *lo = inode->i_bdev->bd_disk->private_data; 1338 struct loop_device *lo = inode->i_bdev->bd_disk->private_data;
@@ -1330,6 +1341,11 @@ static int lo_open(struct inode *inode, struct file *file)
1330 lo->lo_refcnt++; 1341 lo->lo_refcnt++;
1331 mutex_unlock(&lo->lo_ctl_mutex); 1342 mutex_unlock(&lo->lo_ctl_mutex);
1332 1343
1344 mutex_lock(&loop_devices_mutex);
1345 if (!loop_find_dev(lo->lo_number + 1))
1346 loop_init_one(lo->lo_number + 1);
1347 mutex_unlock(&loop_devices_mutex);
1348
1333 return 0; 1349 return 0;
1334} 1350}
1335 1351
@@ -1357,8 +1373,9 @@ static struct block_device_operations lo_fops = {
1357/* 1373/*
1358 * And now the modules code and kernel interface. 1374 * And now the modules code and kernel interface.
1359 */ 1375 */
1376static int max_loop;
1360module_param(max_loop, int, 0); 1377module_param(max_loop, int, 0);
1361MODULE_PARM_DESC(max_loop, "Maximum number of loop devices (1-256)"); 1378MODULE_PARM_DESC(max_loop, "obsolete, loop device is created on-demand");
1362MODULE_LICENSE("GPL"); 1379MODULE_LICENSE("GPL");
1363MODULE_ALIAS_BLOCKDEV_MAJOR(LOOP_MAJOR); 1380MODULE_ALIAS_BLOCKDEV_MAJOR(LOOP_MAJOR);
1364 1381
@@ -1383,7 +1400,7 @@ int loop_unregister_transfer(int number)
1383 1400
1384 xfer_funcs[n] = NULL; 1401 xfer_funcs[n] = NULL;
1385 1402
1386 for (lo = &loop_dev[0]; lo < &loop_dev[max_loop]; lo++) { 1403 list_for_each_entry(lo, &loop_devices, lo_list) {
1387 mutex_lock(&lo->lo_ctl_mutex); 1404 mutex_lock(&lo->lo_ctl_mutex);
1388 1405
1389 if (lo->lo_encryption == xfer) 1406 if (lo->lo_encryption == xfer)
@@ -1398,91 +1415,110 @@ int loop_unregister_transfer(int number)
1398EXPORT_SYMBOL(loop_register_transfer); 1415EXPORT_SYMBOL(loop_register_transfer);
1399EXPORT_SYMBOL(loop_unregister_transfer); 1416EXPORT_SYMBOL(loop_unregister_transfer);
1400 1417
1401static int __init loop_init(void) 1418static struct loop_device *loop_init_one(int i)
1419{
1420 struct loop_device *lo;
1421 struct gendisk *disk;
1422
1423 lo = kzalloc(sizeof(*lo), GFP_KERNEL);
1424 if (!lo)
1425 goto out;
1426
1427 lo->lo_queue = blk_alloc_queue(GFP_KERNEL);
1428 if (!lo->lo_queue)
1429 goto out_free_dev;
1430
1431 disk = lo->lo_disk = alloc_disk(1);
1432 if (!disk)
1433 goto out_free_queue;
1434
1435 mutex_init(&lo->lo_ctl_mutex);
1436 lo->lo_number = i;
1437 lo->lo_thread = NULL;
1438 init_waitqueue_head(&lo->lo_event);
1439 spin_lock_init(&lo->lo_lock);
1440 disk->major = LOOP_MAJOR;
1441 disk->first_minor = i;
1442 disk->fops = &lo_fops;
1443 disk->private_data = lo;
1444 disk->queue = lo->lo_queue;
1445 sprintf(disk->disk_name, "loop%d", i);
1446 add_disk(disk);
1447 list_add_tail(&lo->lo_list, &loop_devices);
1448 return lo;
1449
1450out_free_queue:
1451 blk_cleanup_queue(lo->lo_queue);
1452out_free_dev:
1453 kfree(lo);
1454out:
1455 return ERR_PTR(-ENOMEM);
1456}
1457
1458static void loop_del_one(struct loop_device *lo)
1402{ 1459{
1403 int i; 1460 del_gendisk(lo->lo_disk);
1461 blk_cleanup_queue(lo->lo_queue);
1462 put_disk(lo->lo_disk);
1463 list_del(&lo->lo_list);
1464 kfree(lo);
1465}
1404 1466
1405 if (max_loop < 1 || max_loop > 256) { 1467static struct kobject *loop_probe(dev_t dev, int *part, void *data)
1406 printk(KERN_WARNING "loop: invalid max_loop (must be between" 1468{
1407 " 1 and 256), using default (8)\n"); 1469 unsigned int number = dev & MINORMASK;
1408 max_loop = 8; 1470 struct loop_device *lo;
1409 } 1471
1472 mutex_lock(&loop_devices_mutex);
1473 lo = loop_find_dev(number);
1474 if (lo == NULL)
1475 lo = loop_init_one(number);
1476 mutex_unlock(&loop_devices_mutex);
1477
1478 *part = 0;
1479 if (IS_ERR(lo))
1480 return (void *)lo;
1481 else
1482 return &lo->lo_disk->kobj;
1483}
1484
1485static int __init loop_init(void)
1486{
1487 struct loop_device *lo;
1410 1488
1411 if (register_blkdev(LOOP_MAJOR, "loop")) 1489 if (register_blkdev(LOOP_MAJOR, "loop"))
1412 return -EIO; 1490 return -EIO;
1491 blk_register_region(MKDEV(LOOP_MAJOR, 0), 1UL << MINORBITS,
1492 THIS_MODULE, loop_probe, NULL, NULL);
1413 1493
1414 loop_dev = kmalloc(max_loop * sizeof(struct loop_device), GFP_KERNEL); 1494 lo = loop_init_one(0);
1415 if (!loop_dev) 1495 if (IS_ERR(lo))
1416 goto out_mem1; 1496 goto out;
1417 memset(loop_dev, 0, max_loop * sizeof(struct loop_device));
1418 1497
1419 disks = kmalloc(max_loop * sizeof(struct gendisk *), GFP_KERNEL); 1498 if (max_loop) {
1420 if (!disks) 1499 printk(KERN_INFO "loop: the max_loop option is obsolete "
1421 goto out_mem2; 1500 "and will be removed in March 2008\n");
1422 1501
1423 for (i = 0; i < max_loop; i++) {
1424 disks[i] = alloc_disk(1);
1425 if (!disks[i])
1426 goto out_mem3;
1427 } 1502 }
1428 1503 printk(KERN_INFO "loop: module loaded\n");
1429 for (i = 0; i < max_loop; i++) {
1430 struct loop_device *lo = &loop_dev[i];
1431 struct gendisk *disk = disks[i];
1432
1433 memset(lo, 0, sizeof(*lo));
1434 lo->lo_queue = blk_alloc_queue(GFP_KERNEL);
1435 if (!lo->lo_queue)
1436 goto out_mem4;
1437 mutex_init(&lo->lo_ctl_mutex);
1438 lo->lo_number = i;
1439 lo->lo_thread = NULL;
1440 init_waitqueue_head(&lo->lo_event);
1441 spin_lock_init(&lo->lo_lock);
1442 disk->major = LOOP_MAJOR;
1443 disk->first_minor = i;
1444 disk->fops = &lo_fops;
1445 sprintf(disk->disk_name, "loop%d", i);
1446 disk->private_data = lo;
1447 disk->queue = lo->lo_queue;
1448 }
1449
1450 /* We cannot fail after we call this, so another loop!*/
1451 for (i = 0; i < max_loop; i++)
1452 add_disk(disks[i]);
1453 printk(KERN_INFO "loop: loaded (max %d devices)\n", max_loop);
1454 return 0; 1504 return 0;
1455 1505
1456out_mem4: 1506out:
1457 while (i--)
1458 blk_cleanup_queue(loop_dev[i].lo_queue);
1459 i = max_loop;
1460out_mem3:
1461 while (i--)
1462 put_disk(disks[i]);
1463 kfree(disks);
1464out_mem2:
1465 kfree(loop_dev);
1466out_mem1:
1467 unregister_blkdev(LOOP_MAJOR, "loop"); 1507 unregister_blkdev(LOOP_MAJOR, "loop");
1468 printk(KERN_ERR "loop: ran out of memory\n"); 1508 printk(KERN_ERR "loop: ran out of memory\n");
1469 return -ENOMEM; 1509 return -ENOMEM;
1470} 1510}
1471 1511
1472static void loop_exit(void) 1512static void __exit loop_exit(void)
1473{ 1513{
1474 int i; 1514 struct loop_device *lo, *next;
1475 1515
1476 for (i = 0; i < max_loop; i++) { 1516 list_for_each_entry_safe(lo, next, &loop_devices, lo_list)
1477 del_gendisk(disks[i]); 1517 loop_del_one(lo);
1478 blk_cleanup_queue(loop_dev[i].lo_queue); 1518
1479 put_disk(disks[i]); 1519 blk_unregister_region(MKDEV(LOOP_MAJOR, 0), 1UL << MINORBITS);
1480 }
1481 if (unregister_blkdev(LOOP_MAJOR, "loop")) 1520 if (unregister_blkdev(LOOP_MAJOR, "loop"))
1482 printk(KERN_WARNING "loop: cannot unregister blkdev\n"); 1521 printk(KERN_WARNING "loop: cannot unregister blkdev\n");
1483
1484 kfree(disks);
1485 kfree(loop_dev);
1486} 1522}
1487 1523
1488module_init(loop_init); 1524module_init(loop_init);
diff --git a/drivers/block/umem.c b/drivers/block/umem.c
index 5872036e8ae6..6f5d6203d725 100644
--- a/drivers/block/umem.c
+++ b/drivers/block/umem.c
@@ -44,7 +44,6 @@
44#include <linux/module.h> 44#include <linux/module.h>
45#include <linux/init.h> 45#include <linux/init.h>
46#include <linux/interrupt.h> 46#include <linux/interrupt.h>
47#include <linux/smp_lock.h>
48#include <linux/timer.h> 47#include <linux/timer.h>
49#include <linux/pci.h> 48#include <linux/pci.h>
50#include <linux/slab.h> 49#include <linux/slab.h>
diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig
index a26d91743b24..1e32fb834eb8 100644
--- a/drivers/char/Kconfig
+++ b/drivers/char/Kconfig
@@ -127,7 +127,7 @@ config ROCKETPORT
127 127
128config CYCLADES 128config CYCLADES
129 tristate "Cyclades async mux support" 129 tristate "Cyclades async mux support"
130 depends on SERIAL_NONSTANDARD 130 depends on SERIAL_NONSTANDARD && (PCI || ISA)
131 ---help--- 131 ---help---
132 This driver supports Cyclades Z and Y multiserial boards. 132 This driver supports Cyclades Z and Y multiserial boards.
133 You would need something like this to connect more than two modems to 133 You would need something like this to connect more than two modems to
@@ -1071,5 +1071,11 @@ config TELCLOCK
1071 /sys/devices/platform/telco_clock, with a number of files for 1071 /sys/devices/platform/telco_clock, with a number of files for
1072 controlling the behavior of this hardware. 1072 controlling the behavior of this hardware.
1073 1073
1074config DEVPORT
1075 bool
1076 depends on !M68K
1077 depends on ISA || PCI
1078 default y
1079
1074endmenu 1080endmenu
1075 1081
diff --git a/drivers/char/amiserial.c b/drivers/char/amiserial.c
index 0e2b72f2b887..4eaceabd8cea 100644
--- a/drivers/char/amiserial.c
+++ b/drivers/char/amiserial.c
@@ -1574,7 +1574,7 @@ static void rs_wait_until_sent(struct tty_struct *tty, int timeout)
1574 if (timeout && time_after(jiffies, orig_jiffies + timeout)) 1574 if (timeout && time_after(jiffies, orig_jiffies + timeout))
1575 break; 1575 break;
1576 } 1576 }
1577 current->state = TASK_RUNNING; 1577 __set_current_state(TASK_RUNNING);
1578#ifdef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT 1578#ifdef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT
1579 printk("lsr = %d (jiff=%lu)...done\n", lsr, jiffies); 1579 printk("lsr = %d (jiff=%lu)...done\n", lsr, jiffies);
1580#endif 1580#endif
@@ -1700,7 +1700,7 @@ static int block_til_ready(struct tty_struct *tty, struct file * filp,
1700#endif 1700#endif
1701 schedule(); 1701 schedule();
1702 } 1702 }
1703 current->state = TASK_RUNNING; 1703 __set_current_state(TASK_RUNNING);
1704 remove_wait_queue(&info->open_wait, &wait); 1704 remove_wait_queue(&info->open_wait, &wait);
1705 if (extra_count) 1705 if (extra_count)
1706 state->count++; 1706 state->count++;
diff --git a/drivers/char/consolemap.c b/drivers/char/consolemap.c
index b99b7561260d..fd40b959afdd 100644
--- a/drivers/char/consolemap.c
+++ b/drivers/char/consolemap.c
@@ -626,10 +626,10 @@ conv_uni_to_pc(struct vc_data *conp, long ucs)
626 626
627 /* Only 16-bit codes supported at this time */ 627 /* Only 16-bit codes supported at this time */
628 if (ucs > 0xffff) 628 if (ucs > 0xffff)
629 ucs = 0xfffd; /* U+FFFD: REPLACEMENT CHARACTER */ 629 return -4; /* Not found */
630 else if (ucs < 0x20 || ucs >= 0xfffe) 630 else if (ucs < 0x20)
631 return -1; /* Not a printable character */ 631 return -1; /* Not a printable character */
632 else if (ucs == 0xfeff || (ucs >= 0x200a && ucs <= 0x200f)) 632 else if (ucs == 0xfeff || (ucs >= 0x200b && ucs <= 0x200f))
633 return -2; /* Zero-width space */ 633 return -2; /* Zero-width space */
634 /* 634 /*
635 * UNI_DIRECT_BASE indicates the start of the region in the User Zone 635 * UNI_DIRECT_BASE indicates the start of the region in the User Zone
diff --git a/drivers/char/cs5535_gpio.c b/drivers/char/cs5535_gpio.c
index c02d9e99e050..fe6d2407baed 100644
--- a/drivers/char/cs5535_gpio.c
+++ b/drivers/char/cs5535_gpio.c
@@ -44,6 +44,7 @@ static struct pci_device_id divil_pci[] = {
44 { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_ISA) }, 44 { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_ISA) },
45 { } /* NULL entry */ 45 { } /* NULL entry */
46}; 46};
47MODULE_DEVICE_TABLE(pci, divil_pci);
47 48
48static struct cdev cs5535_gpio_cdev; 49static struct cdev cs5535_gpio_cdev;
49 50
diff --git a/drivers/char/cyclades.c b/drivers/char/cyclades.c
index 16dc5d1d3cb4..c72ee97d3892 100644
--- a/drivers/char/cyclades.c
+++ b/drivers/char/cyclades.c
@@ -10,15 +10,14 @@
10 * 10 *
11 * Initially written by Randolph Bentson <bentson@grieg.seaslug.org>. 11 * Initially written by Randolph Bentson <bentson@grieg.seaslug.org>.
12 * Modified and maintained by Marcio Saito <marcio@cyclades.com>. 12 * Modified and maintained by Marcio Saito <marcio@cyclades.com>.
13 * Currently maintained by Cyclades team <async@cyclades.com>.
14 * 13 *
15 * For Technical support and installation problems, please send e-mail 14 * Copyright (C) 2007 Jiri Slaby <jirislaby@gmail.com>
16 * to support@cyclades.com.
17 * 15 *
18 * Much of the design and some of the code came from serial.c 16 * Much of the design and some of the code came from serial.c
19 * which was copyright (C) 1991, 1992 Linus Torvalds. It was 17 * which was copyright (C) 1991, 1992 Linus Torvalds. It was
20 * extensively rewritten by Theodore Ts'o, 8/16/92 -- 9/14/92, 18 * extensively rewritten by Theodore Ts'o, 8/16/92 -- 9/14/92,
21 * and then fixed as suggested by Michael K. Johnson 12/12/92. 19 * and then fixed as suggested by Michael K. Johnson 12/12/92.
20 * Converted to pci probing and cleaned up by Jiri Slaby.
22 * 21 *
23 * This version supports shared IRQ's (only for PCI boards). 22 * This version supports shared IRQ's (only for PCI boards).
24 * 23 *
@@ -591,7 +590,7 @@
591 * 590 *
592 */ 591 */
593 592
594#define CY_VERSION "2.4" 593#define CY_VERSION "2.5"
595 594
596/* If you need to install more boards than NR_CARDS, change the constant 595/* If you need to install more boards than NR_CARDS, change the constant
597 in the definition below. No other change is necessary to support up to 596 in the definition below. No other change is necessary to support up to
@@ -624,12 +623,6 @@
624#undef CY_ENABLE_MONITORING 623#undef CY_ENABLE_MONITORING
625#undef CY_PCI_DEBUG 624#undef CY_PCI_DEBUG
626 625
627#if 0
628#define PAUSE __asm__("nop")
629#else
630#define PAUSE do {} while (0)
631#endif
632
633/* 626/*
634 * Include section 627 * Include section
635 */ 628 */
@@ -659,17 +652,6 @@
659#include <asm/irq.h> 652#include <asm/irq.h>
660#include <asm/uaccess.h> 653#include <asm/uaccess.h>
661 654
662#define CY_LOCK(info,flags) \
663 do { \
664 spin_lock_irqsave(&cy_card[info->card].card_lock, flags); \
665 } while (0)
666
667#define CY_UNLOCK(info,flags) \
668 do { \
669 spin_unlock_irqrestore(&cy_card[info->card].card_lock, flags); \
670 } while (0)
671
672#include <linux/types.h>
673#include <linux/kernel.h> 655#include <linux/kernel.h>
674#include <linux/pci.h> 656#include <linux/pci.h>
675 657
@@ -682,13 +664,13 @@ static void cy_send_xchar(struct tty_struct *tty, char ch);
682#define IS_CYC_Z(card) ((card).num_chips == -1) 664#define IS_CYC_Z(card) ((card).num_chips == -1)
683 665
684#define Z_FPGA_CHECK(card) \ 666#define Z_FPGA_CHECK(card) \
685 ((cy_readl(&((struct RUNTIME_9060 __iomem *) \ 667 ((readl(&((struct RUNTIME_9060 __iomem *) \
686 ((card).ctl_addr))->init_ctrl) & (1<<17)) != 0) 668 ((card).ctl_addr))->init_ctrl) & (1<<17)) != 0)
687 669
688#define ISZLOADED(card) (((ZO_V1==cy_readl(&((struct RUNTIME_9060 __iomem *) \ 670#define ISZLOADED(card) (((ZO_V1==readl(&((struct RUNTIME_9060 __iomem *) \
689 ((card).ctl_addr))->mail_box_0)) || \ 671 ((card).ctl_addr))->mail_box_0)) || \
690 Z_FPGA_CHECK(card)) && \ 672 Z_FPGA_CHECK(card)) && \
691 (ZFIRM_ID==cy_readl(&((struct FIRM_ID __iomem *) \ 673 (ZFIRM_ID==readl(&((struct FIRM_ID __iomem *) \
692 ((card).base_addr+ID_ADDRESS))->signature))) 674 ((card).base_addr+ID_ADDRESS))->signature)))
693 675
694#ifndef SERIAL_XMIT_SIZE 676#ifndef SERIAL_XMIT_SIZE
@@ -725,8 +707,8 @@ static unsigned int cy_isa_addresses[] = {
725#define NR_ISA_ADDRS ARRAY_SIZE(cy_isa_addresses) 707#define NR_ISA_ADDRS ARRAY_SIZE(cy_isa_addresses)
726 708
727#ifdef MODULE 709#ifdef MODULE
728static long maddr[NR_CARDS] = { 0, }; 710static long maddr[NR_CARDS];
729static int irq[NR_CARDS] = { 0, }; 711static int irq[NR_CARDS];
730 712
731module_param_array(maddr, long, NULL, 0); 713module_param_array(maddr, long, NULL, 0);
732module_param_array(irq, int, NULL, 0); 714module_param_array(irq, int, NULL, 0);
@@ -739,11 +721,6 @@ module_param_array(irq, int, NULL, 0);
739*/ 721*/
740static struct cyclades_card cy_card[NR_CARDS]; 722static struct cyclades_card cy_card[NR_CARDS];
741 723
742/* This is the per-channel data structure containing pointers, flags
743 and variables for the port. This driver supports a maximum of NR_PORTS.
744*/
745static struct cyclades_port cy_port[NR_PORTS];
746
747static int cy_next_channel; /* next minor available */ 724static int cy_next_channel; /* next minor available */
748 725
749/* 726/*
@@ -825,9 +802,6 @@ static int cy_chip_offset[] = { 0x0000,
825 802
826/* PCI related definitions */ 803/* PCI related definitions */
827 804
828static unsigned short cy_pci_nboard;
829static unsigned short cy_isa_nboard;
830static unsigned short cy_nboard;
831#ifdef CONFIG_PCI 805#ifdef CONFIG_PCI
832static struct pci_device_id cy_pci_dev_id[] __devinitdata = { 806static struct pci_device_id cy_pci_dev_id[] __devinitdata = {
833 { PCI_DEVICE(PCI_VENDOR_ID_CYCLADES, PCI_DEVICE_ID_CYCLOM_Y_Lo) }, /* PCI < 1Mb */ 807 { PCI_DEVICE(PCI_VENDOR_ID_CYCLADES, PCI_DEVICE_ID_CYCLOM_Y_Lo) }, /* PCI < 1Mb */
@@ -845,7 +819,7 @@ MODULE_DEVICE_TABLE(pci, cy_pci_dev_id);
845 819
846static void cy_start(struct tty_struct *); 820static void cy_start(struct tty_struct *);
847static void set_line_char(struct cyclades_port *); 821static void set_line_char(struct cyclades_port *);
848static int cyz_issue_cmd(struct cyclades_card *, uclong, ucchar, uclong); 822static int cyz_issue_cmd(struct cyclades_card *, __u32, __u8, __u32);
849#ifdef CONFIG_ISA 823#ifdef CONFIG_ISA
850static unsigned detect_isa_irq(void __iomem *); 824static unsigned detect_isa_irq(void __iomem *);
851#endif /* CONFIG_ISA */ 825#endif /* CONFIG_ISA */
@@ -858,7 +832,6 @@ static void cyz_poll(unsigned long);
858/* The Cyclades-Z polling cycle is defined by this variable */ 832/* The Cyclades-Z polling cycle is defined by this variable */
859static long cyz_polling_cycle = CZ_DEF_POLL; 833static long cyz_polling_cycle = CZ_DEF_POLL;
860 834
861static int cyz_timeron = 0;
862static DEFINE_TIMER(cyz_timerlist, cyz_poll, 0, 0); 835static DEFINE_TIMER(cyz_timerlist, cyz_poll, 0, 0);
863 836
864#else /* CONFIG_CYZ_INTR */ 837#else /* CONFIG_CYZ_INTR */
@@ -871,21 +844,14 @@ static inline int serial_paranoia_check(struct cyclades_port *info,
871{ 844{
872#ifdef SERIAL_PARANOIA_CHECK 845#ifdef SERIAL_PARANOIA_CHECK
873 if (!info) { 846 if (!info) {
874 printk("cyc Warning: null cyclades_port for (%s) in %s\n", 847 printk(KERN_WARNING "cyc Warning: null cyclades_port for (%s) "
875 name, routine); 848 "in %s\n", name, routine);
876 return 1;
877 }
878
879 if ((long)info < (long)(&cy_port[0]) ||
880 (long)(&cy_port[NR_PORTS]) < (long)info) {
881 printk("cyc Warning: cyclades_port out of range for (%s) in "
882 "%s\n", name, routine);
883 return 1; 849 return 1;
884 } 850 }
885 851
886 if (info->magic != CYCLADES_MAGIC) { 852 if (info->magic != CYCLADES_MAGIC) {
887 printk("cyc Warning: bad magic number for serial struct (%s) " 853 printk(KERN_WARNING "cyc Warning: bad magic number for serial "
888 "in %s\n", name, routine); 854 "struct (%s) in %s\n", name, routine);
889 return 1; 855 return 1;
890 } 856 }
891#endif 857#endif
@@ -943,22 +909,16 @@ do_softint(struct work_struct *work)
943 if (test_and_clear_bit(Cy_EVENT_OPEN_WAKEUP, &info->event)) 909 if (test_and_clear_bit(Cy_EVENT_OPEN_WAKEUP, &info->event))
944 wake_up_interruptible(&info->open_wait); 910 wake_up_interruptible(&info->open_wait);
945#ifdef CONFIG_CYZ_INTR 911#ifdef CONFIG_CYZ_INTR
946 if (test_and_clear_bit(Cy_EVENT_Z_RX_FULL, &info->event)) { 912 if (test_and_clear_bit(Cy_EVENT_Z_RX_FULL, &info->event) &&
947 if (cyz_rx_full_timer[info->line].function == NULL) { 913 !timer_pending(&cyz_rx_full_timer[info->line]))
948 cyz_rx_full_timer[info->line].expires = jiffies + 1; 914 mod_timer(&cyz_rx_full_timer[info->line], jiffies + 1);
949 cyz_rx_full_timer[info->line].function = cyz_rx_restart;
950 cyz_rx_full_timer[info->line].data =
951 (unsigned long)info;
952 add_timer(&cyz_rx_full_timer[info->line]);
953 }
954 }
955#endif 915#endif
956 if (test_and_clear_bit(Cy_EVENT_DELTA_WAKEUP, &info->event)) 916 if (test_and_clear_bit(Cy_EVENT_DELTA_WAKEUP, &info->event))
957 wake_up_interruptible(&info->delta_msr_wait); 917 wake_up_interruptible(&info->delta_msr_wait);
958 tty_wakeup(tty); 918 tty_wakeup(tty);
959#ifdef Z_WAKE 919#ifdef Z_WAKE
960 if (test_and_clear_bit(Cy_EVENT_SHUTDOWN_WAKEUP, &info->event)) 920 if (test_and_clear_bit(Cy_EVENT_SHUTDOWN_WAKEUP, &info->event))
961 wake_up_interruptible(&info->shutdown_wait); 921 complete(&info->shutdown_wait);
962#endif 922#endif
963} /* do_softint */ 923} /* do_softint */
964 924
@@ -975,11 +935,11 @@ do_softint(struct work_struct *work)
975 */ 935 */
976static int cyy_issue_cmd(void __iomem * base_addr, u_char cmd, int index) 936static int cyy_issue_cmd(void __iomem * base_addr, u_char cmd, int index)
977{ 937{
978 volatile int i; 938 unsigned int i;
979 939
980 /* Check to see that the previous command has completed */ 940 /* Check to see that the previous command has completed */
981 for (i = 0; i < 100; i++) { 941 for (i = 0; i < 100; i++) {
982 if (cy_readb(base_addr + (CyCCR << index)) == 0) { 942 if (readb(base_addr + (CyCCR << index)) == 0) {
983 break; 943 break;
984 } 944 }
985 udelay(10L); 945 udelay(10L);
@@ -1022,7 +982,7 @@ static unsigned detect_isa_irq(void __iomem * address)
1022 982
1023 cy_writeb(address + (CyCAR << index), 0); 983 cy_writeb(address + (CyCAR << index), 0);
1024 cy_writeb(address + (CySRER << index), 984 cy_writeb(address + (CySRER << index),
1025 cy_readb(address + (CySRER << index)) | CyTxRdy); 985 readb(address + (CySRER << index)) | CyTxRdy);
1026 local_irq_restore(flags); 986 local_irq_restore(flags);
1027 987
1028 /* Wait ... */ 988 /* Wait ... */
@@ -1032,11 +992,11 @@ static unsigned detect_isa_irq(void __iomem * address)
1032 irq = probe_irq_off(irqs); 992 irq = probe_irq_off(irqs);
1033 993
1034 /* Clean up */ 994 /* Clean up */
1035 save_xir = (u_char) cy_readb(address + (CyTIR << index)); 995 save_xir = (u_char) readb(address + (CyTIR << index));
1036 save_car = cy_readb(address + (CyCAR << index)); 996 save_car = readb(address + (CyCAR << index));
1037 cy_writeb(address + (CyCAR << index), (save_xir & 0x3)); 997 cy_writeb(address + (CyCAR << index), (save_xir & 0x3));
1038 cy_writeb(address + (CySRER << index), 998 cy_writeb(address + (CySRER << index),
1039 cy_readb(address + (CySRER << index)) & ~CyTxRdy); 999 readb(address + (CySRER << index)) & ~CyTxRdy);
1040 cy_writeb(address + (CyTIR << index), (save_xir & 0x3f)); 1000 cy_writeb(address + (CyTIR << index), (save_xir & 0x3f));
1041 cy_writeb(address + (CyCAR << index), (save_car)); 1001 cy_writeb(address + (CyCAR << index), (save_car));
1042 cy_writeb(address + (Cy_ClrIntr << index), 0); 1002 cy_writeb(address + (Cy_ClrIntr << index), 0);
@@ -1051,45 +1011,43 @@ static void cyy_intr_chip(struct cyclades_card *cinfo, int chip,
1051{ 1011{
1052 struct cyclades_port *info; 1012 struct cyclades_port *info;
1053 struct tty_struct *tty; 1013 struct tty_struct *tty;
1054 volatile int char_count; 1014 int char_count;
1055 int i, j, len, mdm_change, mdm_status, outch; 1015 int j, len, mdm_change, mdm_status, outch;
1056 int save_xir, channel, save_car; 1016 int save_xir, channel, save_car;
1057 char data; 1017 char data;
1058 1018
1059 if (status & CySRReceive) { /* reception interrupt */ 1019 if (status & CySRReceive) { /* reception interrupt */
1060#ifdef CY_DEBUG_INTERRUPTS 1020#ifdef CY_DEBUG_INTERRUPTS
1061 printk("cyy_interrupt: rcvd intr, chip %d\n\r", chip); 1021 printk(KERN_DEBUG "cyy_interrupt: rcvd intr, chip %d\n", chip);
1062#endif 1022#endif
1063 /* determine the channel & change to that context */ 1023 /* determine the channel & change to that context */
1064 spin_lock(&cinfo->card_lock); 1024 spin_lock(&cinfo->card_lock);
1065 save_xir = (u_char) cy_readb(base_addr + (CyRIR << index)); 1025 save_xir = (u_char) readb(base_addr + (CyRIR << index));
1066 channel = (u_short) (save_xir & CyIRChannel); 1026 channel = (u_short) (save_xir & CyIRChannel);
1067 i = channel + chip * 4 + cinfo->first_line; 1027 info = &cinfo->ports[channel + chip * 4];
1068 info = &cy_port[i]; 1028 save_car = readb(base_addr + (CyCAR << index));
1069 info->last_active = jiffies;
1070 save_car = cy_readb(base_addr + (CyCAR << index));
1071 cy_writeb(base_addr + (CyCAR << index), save_xir); 1029 cy_writeb(base_addr + (CyCAR << index), save_xir);
1072 1030
1073 /* if there is nowhere to put the data, discard it */ 1031 /* if there is nowhere to put the data, discard it */
1074 if (info->tty == 0) { 1032 if (info->tty == NULL) {
1075 j = (cy_readb(base_addr + (CyRIVR << index)) & 1033 j = (readb(base_addr + (CyRIVR << index)) &
1076 CyIVRMask); 1034 CyIVRMask);
1077 if (j == CyIVRRxEx) { /* exception */ 1035 if (j == CyIVRRxEx) { /* exception */
1078 data = cy_readb(base_addr + (CyRDSR << index)); 1036 data = readb(base_addr + (CyRDSR << index));
1079 } else { /* normal character reception */ 1037 } else { /* normal character reception */
1080 char_count = cy_readb(base_addr + 1038 char_count = readb(base_addr +
1081 (CyRDCR << index)); 1039 (CyRDCR << index));
1082 while (char_count--) { 1040 while (char_count--) {
1083 data = cy_readb(base_addr + 1041 data = readb(base_addr +
1084 (CyRDSR << index)); 1042 (CyRDSR << index));
1085 } 1043 }
1086 } 1044 }
1087 } else { /* there is an open port for this data */ 1045 } else { /* there is an open port for this data */
1088 tty = info->tty; 1046 tty = info->tty;
1089 j = (cy_readb(base_addr + (CyRIVR << index)) & 1047 j = (readb(base_addr + (CyRIVR << index)) &
1090 CyIVRMask); 1048 CyIVRMask);
1091 if (j == CyIVRRxEx) { /* exception */ 1049 if (j == CyIVRRxEx) { /* exception */
1092 data = cy_readb(base_addr + (CyRDSR << index)); 1050 data = readb(base_addr + (CyRDSR << index));
1093 1051
1094 /* For statistics only */ 1052 /* For statistics only */
1095 if (data & CyBREAK) 1053 if (data & CyBREAK)
@@ -1110,7 +1068,7 @@ static void cyy_intr_chip(struct cyclades_card *cinfo, int chip,
1110 if (data & CyBREAK) { 1068 if (data & CyBREAK) {
1111 tty_insert_flip_char( 1069 tty_insert_flip_char(
1112 tty, 1070 tty,
1113 cy_readb( 1071 readb(
1114 base_addr + 1072 base_addr +
1115 (CyRDSR << 1073 (CyRDSR <<
1116 index)), 1074 index)),
@@ -1123,7 +1081,7 @@ static void cyy_intr_chip(struct cyclades_card *cinfo, int chip,
1123 } else if (data & CyFRAME) { 1081 } else if (data & CyFRAME) {
1124 tty_insert_flip_char( 1082 tty_insert_flip_char(
1125 tty, 1083 tty,
1126 cy_readb( 1084 readb(
1127 base_addr + 1085 base_addr +
1128 (CyRDSR << 1086 (CyRDSR <<
1129 index)), 1087 index)),
@@ -1135,7 +1093,7 @@ static void cyy_intr_chip(struct cyclades_card *cinfo, int chip,
1135 /* Pieces of seven... */ 1093 /* Pieces of seven... */
1136 tty_insert_flip_char( 1094 tty_insert_flip_char(
1137 tty, 1095 tty,
1138 cy_readb( 1096 readb(
1139 base_addr + 1097 base_addr +
1140 (CyRDSR << 1098 (CyRDSR <<
1141 index)), 1099 index)),
@@ -1154,7 +1112,7 @@ static void cyy_intr_chip(struct cyclades_card *cinfo, int chip,
1154 */ 1112 */
1155 tty_insert_flip_char( 1113 tty_insert_flip_char(
1156 tty, 1114 tty,
1157 cy_readb( 1115 readb(
1158 base_addr + 1116 base_addr +
1159 (CyRDSR << 1117 (CyRDSR <<
1160 index)), 1118 index)),
@@ -1186,7 +1144,7 @@ static void cyy_intr_chip(struct cyclades_card *cinfo, int chip,
1186 } 1144 }
1187 } else { /* normal character reception */ 1145 } else { /* normal character reception */
1188 /* load # chars available from the chip */ 1146 /* load # chars available from the chip */
1189 char_count = cy_readb(base_addr + 1147 char_count = readb(base_addr +
1190 (CyRDCR << index)); 1148 (CyRDCR << index));
1191 1149
1192#ifdef CY_ENABLE_MONITORING 1150#ifdef CY_ENABLE_MONITORING
@@ -1198,7 +1156,7 @@ static void cyy_intr_chip(struct cyclades_card *cinfo, int chip,
1198#endif 1156#endif
1199 len = tty_buffer_request_room(tty, char_count); 1157 len = tty_buffer_request_room(tty, char_count);
1200 while (len--) { 1158 while (len--) {
1201 data = cy_readb(base_addr + 1159 data = readb(base_addr +
1202 (CyRDSR << index)); 1160 (CyRDSR << index));
1203 tty_insert_flip_char(tty, data, 1161 tty_insert_flip_char(tty, data,
1204 TTY_NORMAL); 1162 TTY_NORMAL);
@@ -1223,29 +1181,27 @@ static void cyy_intr_chip(struct cyclades_card *cinfo, int chip,
1223 is empty, we know we can always stuff a dozen 1181 is empty, we know we can always stuff a dozen
1224 characters. */ 1182 characters. */
1225#ifdef CY_DEBUG_INTERRUPTS 1183#ifdef CY_DEBUG_INTERRUPTS
1226 printk("cyy_interrupt: xmit intr, chip %d\n\r", chip); 1184 printk(KERN_DEBUG "cyy_interrupt: xmit intr, chip %d\n", chip);
1227#endif 1185#endif
1228 1186
1229 /* determine the channel & change to that context */ 1187 /* determine the channel & change to that context */
1230 spin_lock(&cinfo->card_lock); 1188 spin_lock(&cinfo->card_lock);
1231 save_xir = (u_char) cy_readb(base_addr + (CyTIR << index)); 1189 save_xir = (u_char) readb(base_addr + (CyTIR << index));
1232 channel = (u_short) (save_xir & CyIRChannel); 1190 channel = (u_short) (save_xir & CyIRChannel);
1233 i = channel + chip * 4 + cinfo->first_line; 1191 save_car = readb(base_addr + (CyCAR << index));
1234 save_car = cy_readb(base_addr + (CyCAR << index));
1235 cy_writeb(base_addr + (CyCAR << index), save_xir); 1192 cy_writeb(base_addr + (CyCAR << index), save_xir);
1236 1193
1237 /* validate the port# (as configured and open) */ 1194 /* validate the port# (as configured and open) */
1238 if ((i < 0) || (NR_PORTS <= i)) { 1195 if (channel + chip * 4 >= cinfo->nports) {
1239 cy_writeb(base_addr + (CySRER << index), 1196 cy_writeb(base_addr + (CySRER << index),
1240 cy_readb(base_addr + (CySRER << index)) & 1197 readb(base_addr + (CySRER << index)) &
1241 ~CyTxRdy); 1198 ~CyTxRdy);
1242 goto txend; 1199 goto txend;
1243 } 1200 }
1244 info = &cy_port[i]; 1201 info = &cinfo->ports[channel + chip * 4];
1245 info->last_active = jiffies; 1202 if (info->tty == NULL) {
1246 if (info->tty == 0) {
1247 cy_writeb(base_addr + (CySRER << index), 1203 cy_writeb(base_addr + (CySRER << index),
1248 cy_readb(base_addr + (CySRER << index)) & 1204 readb(base_addr + (CySRER << index)) &
1249 ~CyTxRdy); 1205 ~CyTxRdy);
1250 goto txdone; 1206 goto txdone;
1251 } 1207 }
@@ -1278,29 +1234,29 @@ static void cyy_intr_chip(struct cyclades_card *cinfo, int chip,
1278 1234
1279 while (char_count-- > 0) { 1235 while (char_count-- > 0) {
1280 if (!info->xmit_cnt) { 1236 if (!info->xmit_cnt) {
1281 if (cy_readb(base_addr + (CySRER << index)) & 1237 if (readb(base_addr + (CySRER << index)) &
1282 CyTxMpty) { 1238 CyTxMpty) {
1283 cy_writeb(base_addr + (CySRER << index), 1239 cy_writeb(base_addr + (CySRER << index),
1284 cy_readb(base_addr + 1240 readb(base_addr +
1285 (CySRER << index)) & 1241 (CySRER << index)) &
1286 ~CyTxMpty); 1242 ~CyTxMpty);
1287 } else { 1243 } else {
1288 cy_writeb(base_addr + (CySRER << index), 1244 cy_writeb(base_addr + (CySRER << index),
1289 (cy_readb(base_addr + 1245 (readb(base_addr +
1290 (CySRER << index)) & 1246 (CySRER << index)) &
1291 ~CyTxRdy) | CyTxMpty); 1247 ~CyTxRdy) | CyTxMpty);
1292 } 1248 }
1293 goto txdone; 1249 goto txdone;
1294 } 1250 }
1295 if (info->xmit_buf == 0) { 1251 if (info->xmit_buf == NULL) {
1296 cy_writeb(base_addr + (CySRER << index), 1252 cy_writeb(base_addr + (CySRER << index),
1297 cy_readb(base_addr + (CySRER << index))& 1253 readb(base_addr + (CySRER << index)) &
1298 ~CyTxRdy); 1254 ~CyTxRdy);
1299 goto txdone; 1255 goto txdone;
1300 } 1256 }
1301 if (info->tty->stopped || info->tty->hw_stopped) { 1257 if (info->tty->stopped || info->tty->hw_stopped) {
1302 cy_writeb(base_addr + (CySRER << index), 1258 cy_writeb(base_addr + (CySRER << index),
1303 cy_readb(base_addr + (CySRER << index))& 1259 readb(base_addr + (CySRER << index)) &
1304 ~CyTxRdy); 1260 ~CyTxRdy);
1305 goto txdone; 1261 goto txdone;
1306 } 1262 }
@@ -1333,7 +1289,6 @@ static void cyy_intr_chip(struct cyclades_card *cinfo, int chip,
1333 0); 1289 0);
1334 info->icount.tx++; 1290 info->icount.tx++;
1335 char_count--; 1291 char_count--;
1336 } else {
1337 } 1292 }
1338 } 1293 }
1339 } 1294 }
@@ -1353,19 +1308,16 @@ txend:
1353 1308
1354 /* determine the channel & change to that context */ 1309 /* determine the channel & change to that context */
1355 spin_lock(&cinfo->card_lock); 1310 spin_lock(&cinfo->card_lock);
1356 save_xir = (u_char) cy_readb(base_addr + (CyMIR << index)); 1311 save_xir = (u_char) readb(base_addr + (CyMIR << index));
1357 channel = (u_short) (save_xir & CyIRChannel); 1312 channel = (u_short) (save_xir & CyIRChannel);
1358 info = &cy_port[channel + chip * 4 + cinfo->first_line]; 1313 info = &cinfo->ports[channel + chip * 4];
1359 info->last_active = jiffies; 1314 save_car = readb(base_addr + (CyCAR << index));
1360 save_car = cy_readb(base_addr + (CyCAR << index));
1361 cy_writeb(base_addr + (CyCAR << index), save_xir); 1315 cy_writeb(base_addr + (CyCAR << index), save_xir);
1362 1316
1363 mdm_change = cy_readb(base_addr + (CyMISR << index)); 1317 mdm_change = readb(base_addr + (CyMISR << index));
1364 mdm_status = cy_readb(base_addr + (CyMSVR1 << index)); 1318 mdm_status = readb(base_addr + (CyMSVR1 << index));
1365 1319
1366 if (info->tty == 0) { /* no place for data, ignore it */ 1320 if (info->tty) {
1367 ;
1368 } else {
1369 if (mdm_change & CyANY_DELTA) { 1321 if (mdm_change & CyANY_DELTA) {
1370 /* For statistics only */ 1322 /* For statistics only */
1371 if (mdm_change & CyDCD) 1323 if (mdm_change & CyDCD)
@@ -1398,7 +1350,7 @@ txend:
1398 info->tty->hw_stopped = 0; 1350 info->tty->hw_stopped = 0;
1399 cy_writeb(base_addr + 1351 cy_writeb(base_addr +
1400 (CySRER << index), 1352 (CySRER << index),
1401 cy_readb(base_addr + 1353 readb(base_addr +
1402 (CySRER << 1354 (CySRER <<
1403 index))| 1355 index))|
1404 CyTxRdy); 1356 CyTxRdy);
@@ -1412,17 +1364,17 @@ txend:
1412 info->tty->hw_stopped = 1; 1364 info->tty->hw_stopped = 1;
1413 cy_writeb(base_addr + 1365 cy_writeb(base_addr +
1414 (CySRER << index), 1366 (CySRER << index),
1415 cy_readb(base_addr + 1367 readb(base_addr +
1416 (CySRER << 1368 (CySRER <<
1417 index)) & 1369 index)) &
1418 ~CyTxRdy); 1370 ~CyTxRdy);
1419 } 1371 }
1420 } 1372 }
1421 } 1373 }
1422 if (mdm_change & CyDSR) { 1374/* if (mdm_change & CyDSR) {
1423 } 1375 }
1424 if (mdm_change & CyRI) { 1376 if (mdm_change & CyRI) {
1425 } 1377 }*/
1426 } 1378 }
1427 /* end of service */ 1379 /* end of service */
1428 cy_writeb(base_addr + (CyMIR << index), (save_xir & 0x3f)); 1380 cy_writeb(base_addr + (CyMIR << index), (save_xir & 0x3f));
@@ -1438,16 +1390,16 @@ txend:
1438static irqreturn_t cyy_interrupt(int irq, void *dev_id) 1390static irqreturn_t cyy_interrupt(int irq, void *dev_id)
1439{ 1391{
1440 int status; 1392 int status;
1441 struct cyclades_card *cinfo; 1393 struct cyclades_card *cinfo = dev_id;
1442 void __iomem *base_addr, *card_base_addr; 1394 void __iomem *base_addr, *card_base_addr;
1443 int chip; 1395 int chip;
1444 int index; 1396 int index;
1445 int too_many; 1397 int too_many;
1446 int had_work; 1398 int had_work;
1447 1399
1448 if ((cinfo = (struct cyclades_card *)dev_id) == 0) { 1400 if (unlikely(cinfo == NULL)) {
1449#ifdef CY_DEBUG_INTERRUPTS 1401#ifdef CY_DEBUG_INTERRUPTS
1450 printk("cyy_interrupt: spurious interrupt %d\n\r", irq); 1402 printk(KERN_DEBUG "cyy_interrupt: spurious interrupt %d\n",irq);
1451#endif 1403#endif
1452 return IRQ_NONE; /* spurious interrupt */ 1404 return IRQ_NONE; /* spurious interrupt */
1453 } 1405 }
@@ -1455,6 +1407,10 @@ static irqreturn_t cyy_interrupt(int irq, void *dev_id)
1455 card_base_addr = cinfo->base_addr; 1407 card_base_addr = cinfo->base_addr;
1456 index = cinfo->bus_index; 1408 index = cinfo->bus_index;
1457 1409
1410 /* card was not initialized yet (e.g. DEBUG_SHIRQ) */
1411 if (unlikely(card_base_addr == NULL))
1412 return IRQ_HANDLED;
1413
1458 /* This loop checks all chips in the card. Make a note whenever 1414 /* This loop checks all chips in the card. Make a note whenever
1459 _any_ chip had some work to do, as this is considered an 1415 _any_ chip had some work to do, as this is considered an
1460 indication that there will be more to do. Only when no chip 1416 indication that there will be more to do. Only when no chip
@@ -1466,7 +1422,7 @@ static irqreturn_t cyy_interrupt(int irq, void *dev_id)
1466 base_addr = cinfo->base_addr + 1422 base_addr = cinfo->base_addr +
1467 (cy_chip_offset[chip] << index); 1423 (cy_chip_offset[chip] << index);
1468 too_many = 0; 1424 too_many = 0;
1469 while ((status = cy_readb(base_addr + 1425 while ((status = readb(base_addr +
1470 (CySVRR << index))) != 0x00) { 1426 (CySVRR << index))) != 0x00) {
1471 had_work++; 1427 had_work++;
1472 /* The purpose of the following test is to ensure that 1428 /* The purpose of the following test is to ensure that
@@ -1498,7 +1454,7 @@ static irqreturn_t cyy_interrupt(int irq, void *dev_id)
1498 1454
1499static int 1455static int
1500cyz_fetch_msg(struct cyclades_card *cinfo, 1456cyz_fetch_msg(struct cyclades_card *cinfo,
1501 uclong * channel, ucchar * cmd, uclong * param) 1457 __u32 * channel, __u8 * cmd, __u32 * param)
1502{ 1458{
1503 struct FIRM_ID __iomem *firm_id; 1459 struct FIRM_ID __iomem *firm_id;
1504 struct ZFW_CTRL __iomem *zfw_ctrl; 1460 struct ZFW_CTRL __iomem *zfw_ctrl;
@@ -1509,16 +1465,15 @@ cyz_fetch_msg(struct cyclades_card *cinfo,
1509 if (!ISZLOADED(*cinfo)) { 1465 if (!ISZLOADED(*cinfo)) {
1510 return -1; 1466 return -1;
1511 } 1467 }
1512 zfw_ctrl = cinfo->base_addr + (cy_readl(&firm_id->zfwctrl_addr) & 1468 zfw_ctrl = cinfo->base_addr + (readl(&firm_id->zfwctrl_addr) & 0xfffff);
1513 0xfffff);
1514 board_ctrl = &zfw_ctrl->board_ctrl; 1469 board_ctrl = &zfw_ctrl->board_ctrl;
1515 1470
1516 loc_doorbell = cy_readl(&((struct RUNTIME_9060 __iomem *) 1471 loc_doorbell = readl(&((struct RUNTIME_9060 __iomem *)
1517 (cinfo->ctl_addr))->loc_doorbell); 1472 (cinfo->ctl_addr))->loc_doorbell);
1518 if (loc_doorbell) { 1473 if (loc_doorbell) {
1519 *cmd = (char)(0xff & loc_doorbell); 1474 *cmd = (char)(0xff & loc_doorbell);
1520 *channel = cy_readl(&board_ctrl->fwcmd_channel); 1475 *channel = readl(&board_ctrl->fwcmd_channel);
1521 *param = (uclong) cy_readl(&board_ctrl->fwcmd_param); 1476 *param = (__u32) readl(&board_ctrl->fwcmd_param);
1522 cy_writel(&((struct RUNTIME_9060 __iomem *)(cinfo->ctl_addr))-> 1477 cy_writel(&((struct RUNTIME_9060 __iomem *)(cinfo->ctl_addr))->
1523 loc_doorbell, 0xffffffff); 1478 loc_doorbell, 0xffffffff);
1524 return 1; 1479 return 1;
@@ -1528,28 +1483,27 @@ cyz_fetch_msg(struct cyclades_card *cinfo,
1528 1483
1529static int 1484static int
1530cyz_issue_cmd(struct cyclades_card *cinfo, 1485cyz_issue_cmd(struct cyclades_card *cinfo,
1531 uclong channel, ucchar cmd, uclong param) 1486 __u32 channel, __u8 cmd, __u32 param)
1532{ 1487{
1533 struct FIRM_ID __iomem *firm_id; 1488 struct FIRM_ID __iomem *firm_id;
1534 struct ZFW_CTRL __iomem *zfw_ctrl; 1489 struct ZFW_CTRL __iomem *zfw_ctrl;
1535 struct BOARD_CTRL __iomem *board_ctrl; 1490 struct BOARD_CTRL __iomem *board_ctrl;
1536 unsigned long __iomem *pci_doorbell; 1491 __u32 __iomem *pci_doorbell;
1537 int index; 1492 int index;
1538 1493
1539 firm_id = cinfo->base_addr + ID_ADDRESS; 1494 firm_id = cinfo->base_addr + ID_ADDRESS;
1540 if (!ISZLOADED(*cinfo)) { 1495 if (!ISZLOADED(*cinfo)) {
1541 return -1; 1496 return -1;
1542 } 1497 }
1543 zfw_ctrl = cinfo->base_addr + (cy_readl(&firm_id->zfwctrl_addr) & 1498 zfw_ctrl = cinfo->base_addr + (readl(&firm_id->zfwctrl_addr) & 0xfffff);
1544 0xfffff);
1545 board_ctrl = &zfw_ctrl->board_ctrl; 1499 board_ctrl = &zfw_ctrl->board_ctrl;
1546 1500
1547 index = 0; 1501 index = 0;
1548 pci_doorbell = 1502 pci_doorbell =
1549 &((struct RUNTIME_9060 __iomem *)(cinfo->ctl_addr))->pci_doorbell; 1503 &((struct RUNTIME_9060 __iomem *)(cinfo->ctl_addr))->pci_doorbell;
1550 while ((cy_readl(pci_doorbell) & 0xff) != 0) { 1504 while ((readl(pci_doorbell) & 0xff) != 0) {
1551 if (index++ == 1000) { 1505 if (index++ == 1000) {
1552 return (int)(cy_readl(pci_doorbell) & 0xff); 1506 return (int)(readl(pci_doorbell) & 0xff);
1553 } 1507 }
1554 udelay(50L); 1508 udelay(50L);
1555 } 1509 }
@@ -1561,34 +1515,30 @@ cyz_issue_cmd(struct cyclades_card *cinfo,
1561} /* cyz_issue_cmd */ 1515} /* cyz_issue_cmd */
1562 1516
1563static void 1517static void
1564cyz_handle_rx(struct cyclades_port *info, 1518cyz_handle_rx(struct cyclades_port *info, struct CH_CTRL __iomem *ch_ctrl,
1565 volatile struct CH_CTRL __iomem * ch_ctrl, 1519 struct BUF_CTRL __iomem *buf_ctrl)
1566 volatile struct BUF_CTRL __iomem * buf_ctrl)
1567{ 1520{
1568 struct cyclades_card *cinfo = &cy_card[info->card]; 1521 struct cyclades_card *cinfo = info->card;
1569 struct tty_struct *tty = info->tty; 1522 struct tty_struct *tty = info->tty;
1570 volatile int char_count; 1523 int char_count;
1571 int len; 1524 int len;
1572#ifdef BLOCKMOVE 1525#ifdef BLOCKMOVE
1573 int small_count; 1526 unsigned char *buf;
1574#else 1527#else
1575 char data; 1528 char data;
1576#endif 1529#endif
1577 volatile uclong rx_put, rx_get, new_rx_get, rx_bufsize, rx_bufaddr; 1530 __u32 rx_put, rx_get, new_rx_get, rx_bufsize, rx_bufaddr;
1578 1531
1579 rx_get = new_rx_get = cy_readl(&buf_ctrl->rx_get); 1532 rx_get = new_rx_get = readl(&buf_ctrl->rx_get);
1580 rx_put = cy_readl(&buf_ctrl->rx_put); 1533 rx_put = readl(&buf_ctrl->rx_put);
1581 rx_bufsize = cy_readl(&buf_ctrl->rx_bufsize); 1534 rx_bufsize = readl(&buf_ctrl->rx_bufsize);
1582 rx_bufaddr = cy_readl(&buf_ctrl->rx_bufaddr); 1535 rx_bufaddr = readl(&buf_ctrl->rx_bufaddr);
1583 if (rx_put >= rx_get) 1536 if (rx_put >= rx_get)
1584 char_count = rx_put - rx_get; 1537 char_count = rx_put - rx_get;
1585 else 1538 else
1586 char_count = rx_put - rx_get + rx_bufsize; 1539 char_count = rx_put - rx_get + rx_bufsize;
1587 1540
1588 if (char_count) { 1541 if (char_count) {
1589 info->last_active = jiffies;
1590 info->jiffies[1] = jiffies;
1591
1592#ifdef CY_ENABLE_MONITORING 1542#ifdef CY_ENABLE_MONITORING
1593 info->mon.int_count++; 1543 info->mon.int_count++;
1594 info->mon.char_count += char_count; 1544 info->mon.char_count += char_count;
@@ -1596,7 +1546,7 @@ cyz_handle_rx(struct cyclades_port *info,
1596 info->mon.char_max = char_count; 1546 info->mon.char_max = char_count;
1597 info->mon.char_last = char_count; 1547 info->mon.char_last = char_count;
1598#endif 1548#endif
1599 if (tty == 0) { 1549 if (tty == NULL) {
1600 /* flush received characters */ 1550 /* flush received characters */
1601 new_rx_get = (new_rx_get + char_count) & 1551 new_rx_get = (new_rx_get + char_count) &
1602 (rx_bufsize - 1); 1552 (rx_bufsize - 1);
@@ -1606,30 +1556,28 @@ cyz_handle_rx(struct cyclades_port *info,
1606 /* we'd like to use memcpy(t, f, n) and memset(s, c, count) 1556 /* we'd like to use memcpy(t, f, n) and memset(s, c, count)
1607 for performance, but because of buffer boundaries, there 1557 for performance, but because of buffer boundaries, there
1608 may be several steps to the operation */ 1558 may be several steps to the operation */
1609 while (0 < (small_count = min_t(unsigned int, 1559 while (1) {
1610 rx_bufsize - new_rx_get, 1560 len = tty_prepare_flip_string(tty, &buf,
1611 min_t(unsigned int, TTY_FLIPBUF_SIZE - 1561 char_count);
1612 tty->flip.count, char_count)))){ 1562 if (!len)
1613 memcpy_fromio(tty->flip.char_buf_ptr, 1563 break;
1614 (char *)(cinfo->base_addr + rx_bufaddr +
1615 new_rx_get),
1616 small_count);
1617 1564
1618 tty->flip.char_buf_ptr += small_count; 1565 len = min_t(unsigned int, min(len, char_count),
1619 memset(tty->flip.flag_buf_ptr, TTY_NORMAL, 1566 rx_bufsize - new_rx_get);
1620 small_count); 1567
1621 tty->flip.flag_buf_ptr += small_count; 1568 memcpy_fromio(buf, cinfo->base_addr +
1622 new_rx_get = (new_rx_get + small_count) & 1569 rx_bufaddr + new_rx_get, len);
1570
1571 new_rx_get = (new_rx_get + len) &
1623 (rx_bufsize - 1); 1572 (rx_bufsize - 1);
1624 char_count -= small_count; 1573 char_count -= len;
1625 info->icount.rx += small_count; 1574 info->icount.rx += len;
1626 info->idle_stats.recv_bytes += small_count; 1575 info->idle_stats.recv_bytes += len;
1627 tty->flip.count += small_count;
1628 } 1576 }
1629#else 1577#else
1630 len = tty_buffer_request_room(tty, char_count); 1578 len = tty_buffer_request_room(tty, char_count);
1631 while (len--) { 1579 while (len--) {
1632 data = cy_readb(cinfo->base_addr + rx_bufaddr + 1580 data = readb(cinfo->base_addr + rx_bufaddr +
1633 new_rx_get); 1581 new_rx_get);
1634 new_rx_get = (new_rx_get + 1)& (rx_bufsize - 1); 1582 new_rx_get = (new_rx_get + 1)& (rx_bufsize - 1);
1635 tty_insert_flip_char(tty, data, TTY_NORMAL); 1583 tty_insert_flip_char(tty, data, TTY_NORMAL);
@@ -1640,13 +1588,12 @@ cyz_handle_rx(struct cyclades_port *info,
1640#ifdef CONFIG_CYZ_INTR 1588#ifdef CONFIG_CYZ_INTR
1641 /* Recalculate the number of chars in the RX buffer and issue 1589 /* Recalculate the number of chars in the RX buffer and issue
1642 a cmd in case it's higher than the RX high water mark */ 1590 a cmd in case it's higher than the RX high water mark */
1643 rx_put = cy_readl(&buf_ctrl->rx_put); 1591 rx_put = readl(&buf_ctrl->rx_put);
1644 if (rx_put >= rx_get) 1592 if (rx_put >= rx_get)
1645 char_count = rx_put - rx_get; 1593 char_count = rx_put - rx_get;
1646 else 1594 else
1647 char_count = rx_put - rx_get + rx_bufsize; 1595 char_count = rx_put - rx_get + rx_bufsize;
1648 if (char_count >= (int)cy_readl(&buf_ctrl-> 1596 if (char_count >= (int)readl(&buf_ctrl->rx_threshold)) {
1649 rx_threshold)) {
1650 cy_sched_event(info, Cy_EVENT_Z_RX_FULL); 1597 cy_sched_event(info, Cy_EVENT_Z_RX_FULL);
1651 } 1598 }
1652#endif 1599#endif
@@ -1659,26 +1606,25 @@ cyz_handle_rx(struct cyclades_port *info,
1659} 1606}
1660 1607
1661static void 1608static void
1662cyz_handle_tx(struct cyclades_port *info, 1609cyz_handle_tx(struct cyclades_port *info, struct CH_CTRL __iomem *ch_ctrl,
1663 volatile struct CH_CTRL __iomem * ch_ctrl, 1610 struct BUF_CTRL __iomem *buf_ctrl)
1664 volatile struct BUF_CTRL __iomem * buf_ctrl)
1665{ 1611{
1666 struct cyclades_card *cinfo = &cy_card[info->card]; 1612 struct cyclades_card *cinfo = info->card;
1667 struct tty_struct *tty = info->tty; 1613 struct tty_struct *tty = info->tty;
1668 char data; 1614 char data;
1669 volatile int char_count; 1615 int char_count;
1670#ifdef BLOCKMOVE 1616#ifdef BLOCKMOVE
1671 int small_count; 1617 int small_count;
1672#endif 1618#endif
1673 volatile uclong tx_put, tx_get, tx_bufsize, tx_bufaddr; 1619 __u32 tx_put, tx_get, tx_bufsize, tx_bufaddr;
1674 1620
1675 if (info->xmit_cnt <= 0) /* Nothing to transmit */ 1621 if (info->xmit_cnt <= 0) /* Nothing to transmit */
1676 return; 1622 return;
1677 1623
1678 tx_get = cy_readl(&buf_ctrl->tx_get); 1624 tx_get = readl(&buf_ctrl->tx_get);
1679 tx_put = cy_readl(&buf_ctrl->tx_put); 1625 tx_put = readl(&buf_ctrl->tx_put);
1680 tx_bufsize = cy_readl(&buf_ctrl->tx_bufsize); 1626 tx_bufsize = readl(&buf_ctrl->tx_bufsize);
1681 tx_bufaddr = cy_readl(&buf_ctrl->tx_bufaddr); 1627 tx_bufaddr = readl(&buf_ctrl->tx_bufaddr);
1682 if (tx_put >= tx_get) 1628 if (tx_put >= tx_get)
1683 char_count = tx_get - tx_put - 1 + tx_bufsize; 1629 char_count = tx_get - tx_put - 1 + tx_bufsize;
1684 else 1630 else
@@ -1686,9 +1632,8 @@ cyz_handle_tx(struct cyclades_port *info,
1686 1632
1687 if (char_count) { 1633 if (char_count) {
1688 1634
1689 if (tty == 0) { 1635 if (tty == NULL)
1690 goto ztxdone; 1636 goto ztxdone;
1691 }
1692 1637
1693 if (info->x_char) { /* send special char */ 1638 if (info->x_char) { /* send special char */
1694 data = info->x_char; 1639 data = info->x_char;
@@ -1698,8 +1643,6 @@ cyz_handle_tx(struct cyclades_port *info,
1698 info->x_char = 0; 1643 info->x_char = 0;
1699 char_count--; 1644 char_count--;
1700 info->icount.tx++; 1645 info->icount.tx++;
1701 info->last_active = jiffies;
1702 info->jiffies[2] = jiffies;
1703 } 1646 }
1704#ifdef BLOCKMOVE 1647#ifdef BLOCKMOVE
1705 while (0 < (small_count = min_t(unsigned int, 1648 while (0 < (small_count = min_t(unsigned int,
@@ -1719,8 +1662,6 @@ cyz_handle_tx(struct cyclades_port *info,
1719 info->xmit_cnt -= small_count; 1662 info->xmit_cnt -= small_count;
1720 info->xmit_tail = (info->xmit_tail + small_count) & 1663 info->xmit_tail = (info->xmit_tail + small_count) &
1721 (SERIAL_XMIT_SIZE - 1); 1664 (SERIAL_XMIT_SIZE - 1);
1722 info->last_active = jiffies;
1723 info->jiffies[2] = jiffies;
1724 } 1665 }
1725#else 1666#else
1726 while (info->xmit_cnt && char_count) { 1667 while (info->xmit_cnt && char_count) {
@@ -1733,8 +1674,6 @@ cyz_handle_tx(struct cyclades_port *info,
1733 tx_put = (tx_put + 1) & (tx_bufsize - 1); 1674 tx_put = (tx_put + 1) & (tx_bufsize - 1);
1734 char_count--; 1675 char_count--;
1735 info->icount.tx++; 1676 info->icount.tx++;
1736 info->last_active = jiffies;
1737 info->jiffies[2] = jiffies;
1738 } 1677 }
1739#endif 1678#endif
1740ztxdone: 1679ztxdone:
@@ -1750,33 +1689,32 @@ static void cyz_handle_cmd(struct cyclades_card *cinfo)
1750{ 1689{
1751 struct tty_struct *tty; 1690 struct tty_struct *tty;
1752 struct cyclades_port *info; 1691 struct cyclades_port *info;
1753 static volatile struct FIRM_ID __iomem *firm_id; 1692 static struct FIRM_ID __iomem *firm_id;
1754 static volatile struct ZFW_CTRL __iomem *zfw_ctrl; 1693 static struct ZFW_CTRL __iomem *zfw_ctrl;
1755 static volatile struct BOARD_CTRL __iomem *board_ctrl; 1694 static struct BOARD_CTRL __iomem *board_ctrl;
1756 static volatile struct CH_CTRL __iomem *ch_ctrl; 1695 static struct CH_CTRL __iomem *ch_ctrl;
1757 static volatile struct BUF_CTRL __iomem *buf_ctrl; 1696 static struct BUF_CTRL __iomem *buf_ctrl;
1758 uclong channel; 1697 __u32 channel;
1759 ucchar cmd; 1698 __u8 cmd;
1760 uclong param; 1699 __u32 param;
1761 uclong hw_ver, fw_ver; 1700 __u32 hw_ver, fw_ver;
1762 int special_count; 1701 int special_count;
1763 int delta_count; 1702 int delta_count;
1764 1703
1765 firm_id = cinfo->base_addr + ID_ADDRESS; 1704 firm_id = cinfo->base_addr + ID_ADDRESS;
1766 zfw_ctrl = cinfo->base_addr + (cy_readl(&firm_id->zfwctrl_addr) & 1705 zfw_ctrl = cinfo->base_addr + (readl(&firm_id->zfwctrl_addr) & 0xfffff);
1767 0xfffff);
1768 board_ctrl = &zfw_ctrl->board_ctrl; 1706 board_ctrl = &zfw_ctrl->board_ctrl;
1769 fw_ver = cy_readl(&board_ctrl->fw_version); 1707 fw_ver = readl(&board_ctrl->fw_version);
1770 hw_ver = cy_readl(&((struct RUNTIME_9060 __iomem *)(cinfo->ctl_addr))-> 1708 hw_ver = readl(&((struct RUNTIME_9060 __iomem *)(cinfo->ctl_addr))->
1771 mail_box_0); 1709 mail_box_0);
1772 1710
1773 while (cyz_fetch_msg(cinfo, &channel, &cmd, &param) == 1) { 1711 while (cyz_fetch_msg(cinfo, &channel, &cmd, &param) == 1) {
1774 special_count = 0; 1712 special_count = 0;
1775 delta_count = 0; 1713 delta_count = 0;
1776 info = &cy_port[channel + cinfo->first_line]; 1714 info = &cinfo->ports[channel];
1777 if ((tty = info->tty) == 0) { 1715 if ((tty = info->tty) == NULL)
1778 continue; 1716 continue;
1779 } 1717
1780 ch_ctrl = &(zfw_ctrl->ch_ctrl[channel]); 1718 ch_ctrl = &(zfw_ctrl->ch_ctrl[channel]);
1781 buf_ctrl = &(zfw_ctrl->buf_ctrl[channel]); 1719 buf_ctrl = &(zfw_ctrl->buf_ctrl[channel]);
1782 1720
@@ -1801,7 +1739,7 @@ static void cyz_handle_cmd(struct cyclades_card *cinfo)
1801 delta_count++; 1739 delta_count++;
1802 if (info->flags & ASYNC_CHECK_CD) { 1740 if (info->flags & ASYNC_CHECK_CD) {
1803 if ((fw_ver > 241 ? ((u_long) param) : 1741 if ((fw_ver > 241 ? ((u_long) param) :
1804 cy_readl(&ch_ctrl->rs_status)) & 1742 readl(&ch_ctrl->rs_status)) &
1805 C_RS_DCD) { 1743 C_RS_DCD) {
1806 cy_sched_event(info, 1744 cy_sched_event(info,
1807 Cy_EVENT_OPEN_WAKEUP); 1745 Cy_EVENT_OPEN_WAKEUP);
@@ -1833,8 +1771,8 @@ static void cyz_handle_cmd(struct cyclades_card *cinfo)
1833 case C_CM_INTBACK2: 1771 case C_CM_INTBACK2:
1834 /* Reception Interrupt */ 1772 /* Reception Interrupt */
1835#ifdef CY_DEBUG_INTERRUPTS 1773#ifdef CY_DEBUG_INTERRUPTS
1836 printk("cyz_interrupt: rcvd intr, card %d, " 1774 printk(KERN_DEBUG "cyz_interrupt: rcvd intr, card %d, "
1837 "port %ld\n\r", info->card, channel); 1775 "port %ld\n", info->card, channel);
1838#endif 1776#endif
1839 cyz_handle_rx(info, ch_ctrl, buf_ctrl); 1777 cyz_handle_rx(info, ch_ctrl, buf_ctrl);
1840 break; 1778 break;
@@ -1843,8 +1781,8 @@ static void cyz_handle_cmd(struct cyclades_card *cinfo)
1843 case C_CM_INTBACK: 1781 case C_CM_INTBACK:
1844 /* Transmission Interrupt */ 1782 /* Transmission Interrupt */
1845#ifdef CY_DEBUG_INTERRUPTS 1783#ifdef CY_DEBUG_INTERRUPTS
1846 printk("cyz_interrupt: xmit intr, card %d, " 1784 printk(KERN_DEBUG "cyz_interrupt: xmit intr, card %d, "
1847 "port %ld\n\r", info->card, channel); 1785 "port %ld\n", info->card, channel);
1848#endif 1786#endif
1849 cyz_handle_tx(info, ch_ctrl, buf_ctrl); 1787 cyz_handle_tx(info, ch_ctrl, buf_ctrl);
1850 break; 1788 break;
@@ -1865,18 +1803,19 @@ static void cyz_handle_cmd(struct cyclades_card *cinfo)
1865#ifdef CONFIG_CYZ_INTR 1803#ifdef CONFIG_CYZ_INTR
1866static irqreturn_t cyz_interrupt(int irq, void *dev_id) 1804static irqreturn_t cyz_interrupt(int irq, void *dev_id)
1867{ 1805{
1868 struct cyclades_card *cinfo; 1806 struct cyclades_card *cinfo = dev_id;
1869 1807
1870 if ((cinfo = (struct cyclades_card *)dev_id) == 0) { 1808 if (unlikely(cinfo == NULL)) {
1871#ifdef CY_DEBUG_INTERRUPTS 1809#ifdef CY_DEBUG_INTERRUPTS
1872 printk("cyz_interrupt: spurious interrupt %d\n\r", irq); 1810 printk(KERN_DEBUG "cyz_interrupt: spurious interrupt %d\n",irq);
1873#endif 1811#endif
1874 return IRQ_NONE; /* spurious interrupt */ 1812 return IRQ_NONE; /* spurious interrupt */
1875 } 1813 }
1876 1814
1877 if (!ISZLOADED(*cinfo)) { 1815 if (unlikely(!ISZLOADED(*cinfo))) {
1878#ifdef CY_DEBUG_INTERRUPTS 1816#ifdef CY_DEBUG_INTERRUPTS
1879 printk("cyz_interrupt: board not yet loaded (IRQ%d).\n\r", irq); 1817 printk(KERN_DEBUG "cyz_interrupt: board not yet loaded "
1818 "(IRQ%d).\n", irq);
1880#endif 1819#endif
1881 return IRQ_NONE; 1820 return IRQ_NONE;
1882 } 1821 }
@@ -1890,19 +1829,18 @@ static irqreturn_t cyz_interrupt(int irq, void *dev_id)
1890static void cyz_rx_restart(unsigned long arg) 1829static void cyz_rx_restart(unsigned long arg)
1891{ 1830{
1892 struct cyclades_port *info = (struct cyclades_port *)arg; 1831 struct cyclades_port *info = (struct cyclades_port *)arg;
1832 struct cyclades_card *card = info->card;
1893 int retval; 1833 int retval;
1894 int card = info->card; 1834 __u32 channel = info->line - card->first_line;
1895 uclong channel = (info->line) - (cy_card[card].first_line);
1896 unsigned long flags; 1835 unsigned long flags;
1897 1836
1898 CY_LOCK(info, flags); 1837 spin_lock_irqsave(&card->card_lock, flags);
1899 retval = cyz_issue_cmd(&cy_card[card], channel, C_CM_INTBACK2, 0L); 1838 retval = cyz_issue_cmd(card, channel, C_CM_INTBACK2, 0L);
1900 if (retval != 0) { 1839 if (retval != 0) {
1901 printk("cyc:cyz_rx_restart retval on ttyC%d was %x\n", 1840 printk(KERN_ERR "cyc:cyz_rx_restart retval on ttyC%d was %x\n",
1902 info->line, retval); 1841 info->line, retval);
1903 } 1842 }
1904 cyz_rx_full_timer[info->line].function = NULL; 1843 spin_unlock_irqrestore(&card->card_lock, flags);
1905 CY_UNLOCK(info, flags);
1906} 1844}
1907 1845
1908#else /* CONFIG_CYZ_INTR */ 1846#else /* CONFIG_CYZ_INTR */
@@ -1912,14 +1850,14 @@ static void cyz_poll(unsigned long arg)
1912 struct cyclades_card *cinfo; 1850 struct cyclades_card *cinfo;
1913 struct cyclades_port *info; 1851 struct cyclades_port *info;
1914 struct tty_struct *tty; 1852 struct tty_struct *tty;
1915 static volatile struct FIRM_ID *firm_id; 1853 static struct FIRM_ID *firm_id;
1916 static volatile struct ZFW_CTRL *zfw_ctrl; 1854 static struct ZFW_CTRL *zfw_ctrl;
1917 static volatile struct BOARD_CTRL *board_ctrl; 1855 static struct BOARD_CTRL *board_ctrl;
1918 static volatile struct CH_CTRL *ch_ctrl; 1856 static struct CH_CTRL *ch_ctrl;
1919 static volatile struct BUF_CTRL *buf_ctrl; 1857 static struct BUF_CTRL *buf_ctrl;
1858 unsigned long expires = jiffies + HZ;
1920 int card, port; 1859 int card, port;
1921 1860
1922 cyz_timerlist.expires = jiffies + (HZ);
1923 for (card = 0; card < NR_CARDS; card++) { 1861 for (card = 0; card < NR_CARDS; card++) {
1924 cinfo = &cy_card[card]; 1862 cinfo = &cy_card[card];
1925 1863
@@ -1930,12 +1868,12 @@ static void cyz_poll(unsigned long arg)
1930 1868
1931 firm_id = cinfo->base_addr + ID_ADDRESS; 1869 firm_id = cinfo->base_addr + ID_ADDRESS;
1932 zfw_ctrl = cinfo->base_addr + 1870 zfw_ctrl = cinfo->base_addr +
1933 (cy_readl(&firm_id->zfwctrl_addr) & 0xfffff); 1871 (readl(&firm_id->zfwctrl_addr) & 0xfffff);
1934 board_ctrl = &(zfw_ctrl->board_ctrl); 1872 board_ctrl = &(zfw_ctrl->board_ctrl);
1935 1873
1936 /* Skip first polling cycle to avoid racing conditions with the FW */ 1874 /* Skip first polling cycle to avoid racing conditions with the FW */
1937 if (!cinfo->intr_enabled) { 1875 if (!cinfo->intr_enabled) {
1938 cinfo->nports = (int)cy_readl(&board_ctrl->n_channel); 1876 cinfo->nports = (int)readl(&board_ctrl->n_channel);
1939 cinfo->intr_enabled = 1; 1877 cinfo->intr_enabled = 1;
1940 continue; 1878 continue;
1941 } 1879 }
@@ -1943,7 +1881,7 @@ static void cyz_poll(unsigned long arg)
1943 cyz_handle_cmd(cinfo); 1881 cyz_handle_cmd(cinfo);
1944 1882
1945 for (port = 0; port < cinfo->nports; port++) { 1883 for (port = 0; port < cinfo->nports; port++) {
1946 info = &cy_port[port + cinfo->first_line]; 1884 info = &cinfo->ports[port];
1947 tty = info->tty; 1885 tty = info->tty;
1948 ch_ctrl = &(zfw_ctrl->ch_ctrl[port]); 1886 ch_ctrl = &(zfw_ctrl->ch_ctrl[port]);
1949 buf_ctrl = &(zfw_ctrl->buf_ctrl[port]); 1887 buf_ctrl = &(zfw_ctrl->buf_ctrl[port]);
@@ -1953,9 +1891,9 @@ static void cyz_poll(unsigned long arg)
1953 cyz_handle_tx(info, ch_ctrl, buf_ctrl); 1891 cyz_handle_tx(info, ch_ctrl, buf_ctrl);
1954 } 1892 }
1955 /* poll every 'cyz_polling_cycle' period */ 1893 /* poll every 'cyz_polling_cycle' period */
1956 cyz_timerlist.expires = jiffies + cyz_polling_cycle; 1894 expires = jiffies + cyz_polling_cycle;
1957 } 1895 }
1958 add_timer(&cyz_timerlist); 1896 mod_timer(&cyz_timerlist, expires);
1959} /* cyz_poll */ 1897} /* cyz_poll */
1960 1898
1961#endif /* CONFIG_CYZ_INTR */ 1899#endif /* CONFIG_CYZ_INTR */
@@ -1968,20 +1906,21 @@ static void cyz_poll(unsigned long arg)
1968 */ 1906 */
1969static int startup(struct cyclades_port *info) 1907static int startup(struct cyclades_port *info)
1970{ 1908{
1909 struct cyclades_card *card;
1971 unsigned long flags; 1910 unsigned long flags;
1972 int retval = 0; 1911 int retval = 0;
1973 void __iomem *base_addr; 1912 void __iomem *base_addr;
1974 int card, chip, channel, index; 1913 int chip, channel, index;
1975 unsigned long page; 1914 unsigned long page;
1976 1915
1977 card = info->card; 1916 card = info->card;
1978 channel = (info->line) - (cy_card[card].first_line); 1917 channel = info->line - card->first_line;
1979 1918
1980 page = get_zeroed_page(GFP_KERNEL); 1919 page = get_zeroed_page(GFP_KERNEL);
1981 if (!page) 1920 if (!page)
1982 return -ENOMEM; 1921 return -ENOMEM;
1983 1922
1984 CY_LOCK(info, flags); 1923 spin_lock_irqsave(&card->card_lock, flags);
1985 1924
1986 if (info->flags & ASYNC_INITIALIZED) { 1925 if (info->flags & ASYNC_INITIALIZED) {
1987 free_page(page); 1926 free_page(page);
@@ -2001,24 +1940,22 @@ static int startup(struct cyclades_port *info)
2001 else 1940 else
2002 info->xmit_buf = (unsigned char *)page; 1941 info->xmit_buf = (unsigned char *)page;
2003 1942
2004 CY_UNLOCK(info, flags); 1943 spin_unlock_irqrestore(&card->card_lock, flags);
2005 1944
2006 set_line_char(info); 1945 set_line_char(info);
2007 1946
2008 if (!IS_CYC_Z(cy_card[card])) { 1947 if (!IS_CYC_Z(*card)) {
2009 chip = channel >> 2; 1948 chip = channel >> 2;
2010 channel &= 0x03; 1949 channel &= 0x03;
2011 index = cy_card[card].bus_index; 1950 index = card->bus_index;
2012 base_addr = cy_card[card].base_addr + 1951 base_addr = card->base_addr + (cy_chip_offset[chip] << index);
2013 (cy_chip_offset[chip] << index);
2014 1952
2015#ifdef CY_DEBUG_OPEN 1953#ifdef CY_DEBUG_OPEN
2016 printk("cyc startup card %d, chip %d, channel %d, " 1954 printk(KERN_DEBUG "cyc startup card %d, chip %d, channel %d, "
2017 "base_addr %lx\n", 1955 "base_addr %p\n",
2018 card, chip, channel, (long)base_addr); 1956 card, chip, channel, base_addr);
2019 /**/
2020#endif 1957#endif
2021 CY_LOCK(info, flags); 1958 spin_lock_irqsave(&card->card_lock, flags);
2022 1959
2023 cy_writeb(base_addr + (CyCAR << index), (u_char) channel); 1960 cy_writeb(base_addr + (CyCAR << index), (u_char) channel);
2024 1961
@@ -2034,14 +1971,14 @@ static int startup(struct cyclades_port *info)
2034 cy_writeb(base_addr + (CyMSVR2 << index), CyDTR); 1971 cy_writeb(base_addr + (CyMSVR2 << index), CyDTR);
2035 1972
2036#ifdef CY_DEBUG_DTR 1973#ifdef CY_DEBUG_DTR
2037 printk("cyc:startup raising DTR\n"); 1974 printk(KERN_DEBUG "cyc:startup raising DTR\n");
2038 printk(" status: 0x%x, 0x%x\n", 1975 printk(KERN_DEBUG " status: 0x%x, 0x%x\n",
2039 cy_readb(base_addr + (CyMSVR1 << index)), 1976 readb(base_addr + (CyMSVR1 << index)),
2040 cy_readb(base_addr + (CyMSVR2 << index))); 1977 readb(base_addr + (CyMSVR2 << index)));
2041#endif 1978#endif
2042 1979
2043 cy_writeb(base_addr + (CySRER << index), 1980 cy_writeb(base_addr + (CySRER << index),
2044 cy_readb(base_addr + (CySRER << index)) | CyRxData); 1981 readb(base_addr + (CySRER << index)) | CyRxData);
2045 info->flags |= ASYNC_INITIALIZED; 1982 info->flags |= ASYNC_INITIALIZED;
2046 1983
2047 if (info->tty) { 1984 if (info->tty) {
@@ -2054,7 +1991,7 @@ static int startup(struct cyclades_port *info)
2054 info->idle_stats.recv_idle = 1991 info->idle_stats.recv_idle =
2055 info->idle_stats.xmit_idle = jiffies; 1992 info->idle_stats.xmit_idle = jiffies;
2056 1993
2057 CY_UNLOCK(info, flags); 1994 spin_unlock_irqrestore(&card->card_lock, flags);
2058 1995
2059 } else { 1996 } else {
2060 struct FIRM_ID __iomem *firm_id; 1997 struct FIRM_ID __iomem *firm_id;
@@ -2063,24 +2000,23 @@ static int startup(struct cyclades_port *info)
2063 struct CH_CTRL __iomem *ch_ctrl; 2000 struct CH_CTRL __iomem *ch_ctrl;
2064 int retval; 2001 int retval;
2065 2002
2066 base_addr = cy_card[card].base_addr; 2003 base_addr = card->base_addr;
2067 2004
2068 firm_id = base_addr + ID_ADDRESS; 2005 firm_id = base_addr + ID_ADDRESS;
2069 if (!ISZLOADED(cy_card[card])) { 2006 if (!ISZLOADED(*card)) {
2070 return -ENODEV; 2007 return -ENODEV;
2071 } 2008 }
2072 2009
2073 zfw_ctrl = cy_card[card].base_addr + 2010 zfw_ctrl = card->base_addr +
2074 (cy_readl(&firm_id->zfwctrl_addr) & 0xfffff); 2011 (readl(&firm_id->zfwctrl_addr) & 0xfffff);
2075 board_ctrl = &zfw_ctrl->board_ctrl; 2012 board_ctrl = &zfw_ctrl->board_ctrl;
2076 ch_ctrl = zfw_ctrl->ch_ctrl; 2013 ch_ctrl = zfw_ctrl->ch_ctrl;
2077 2014
2078#ifdef CY_DEBUG_OPEN 2015#ifdef CY_DEBUG_OPEN
2079 printk("cyc startup Z card %d, channel %d, base_addr %lx\n", 2016 printk(KERN_DEBUG "cyc startup Z card %d, channel %d, "
2080 card, channel, (long)base_addr); 2017 "base_addr %p\n", card, channel, base_addr);
2081 /**/
2082#endif 2018#endif
2083 CY_LOCK(info, flags); 2019 spin_lock_irqsave(&card->card_lock, flags);
2084 2020
2085 cy_writel(&ch_ctrl[channel].op_mode, C_CH_ENABLE); 2021 cy_writel(&ch_ctrl[channel].op_mode, C_CH_ENABLE);
2086#ifdef Z_WAKE 2022#ifdef Z_WAKE
@@ -2102,33 +2038,31 @@ static int startup(struct cyclades_port *info)
2102#endif /* CONFIG_CYZ_INTR */ 2038#endif /* CONFIG_CYZ_INTR */
2103#endif /* Z_WAKE */ 2039#endif /* Z_WAKE */
2104 2040
2105 retval = cyz_issue_cmd(&cy_card[card], channel, C_CM_IOCTL, 0L); 2041 retval = cyz_issue_cmd(card, channel, C_CM_IOCTL, 0L);
2106 if (retval != 0) { 2042 if (retval != 0) {
2107 printk("cyc:startup(1) retval on ttyC%d was %x\n", 2043 printk(KERN_ERR "cyc:startup(1) retval on ttyC%d was "
2108 info->line, retval); 2044 "%x\n", info->line, retval);
2109 } 2045 }
2110 2046
2111 /* Flush RX buffers before raising DTR and RTS */ 2047 /* Flush RX buffers before raising DTR and RTS */
2112 retval = cyz_issue_cmd(&cy_card[card], channel, C_CM_FLUSH_RX, 2048 retval = cyz_issue_cmd(card, channel, C_CM_FLUSH_RX, 0L);
2113 0L);
2114 if (retval != 0) { 2049 if (retval != 0) {
2115 printk("cyc:startup(2) retval on ttyC%d was %x\n", 2050 printk(KERN_ERR "cyc:startup(2) retval on ttyC%d was "
2116 info->line, retval); 2051 "%x\n", info->line, retval);
2117 } 2052 }
2118 2053
2119 /* set timeout !!! */ 2054 /* set timeout !!! */
2120 /* set RTS and DTR !!! */ 2055 /* set RTS and DTR !!! */
2121 cy_writel(&ch_ctrl[channel].rs_control, 2056 cy_writel(&ch_ctrl[channel].rs_control,
2122 cy_readl(&ch_ctrl[channel].rs_control) | C_RS_RTS | 2057 readl(&ch_ctrl[channel].rs_control) | C_RS_RTS |
2123 C_RS_DTR); 2058 C_RS_DTR);
2124 retval = cyz_issue_cmd(&cy_card[info->card], channel, 2059 retval = cyz_issue_cmd(card, channel, C_CM_IOCTLM, 0L);
2125 C_CM_IOCTLM, 0L);
2126 if (retval != 0) { 2060 if (retval != 0) {
2127 printk("cyc:startup(3) retval on ttyC%d was %x\n", 2061 printk(KERN_ERR "cyc:startup(3) retval on ttyC%d was "
2128 info->line, retval); 2062 "%x\n", info->line, retval);
2129 } 2063 }
2130#ifdef CY_DEBUG_DTR 2064#ifdef CY_DEBUG_DTR
2131 printk("cyc:startup raising Z DTR\n"); 2065 printk(KERN_DEBUG "cyc:startup raising Z DTR\n");
2132#endif 2066#endif
2133 2067
2134 /* enable send, recv, modem !!! */ 2068 /* enable send, recv, modem !!! */
@@ -2144,51 +2078,50 @@ static int startup(struct cyclades_port *info)
2144 info->idle_stats.recv_idle = 2078 info->idle_stats.recv_idle =
2145 info->idle_stats.xmit_idle = jiffies; 2079 info->idle_stats.xmit_idle = jiffies;
2146 2080
2147 CY_UNLOCK(info, flags); 2081 spin_unlock_irqrestore(&card->card_lock, flags);
2148 } 2082 }
2149 2083
2150#ifdef CY_DEBUG_OPEN 2084#ifdef CY_DEBUG_OPEN
2151 printk(" cyc startup done\n"); 2085 printk(KERN_DEBUG "cyc startup done\n");
2152#endif 2086#endif
2153 return 0; 2087 return 0;
2154 2088
2155errout: 2089errout:
2156 CY_UNLOCK(info, flags); 2090 spin_unlock_irqrestore(&card->card_lock, flags);
2157 return retval; 2091 return retval;
2158} /* startup */ 2092} /* startup */
2159 2093
2160static void start_xmit(struct cyclades_port *info) 2094static void start_xmit(struct cyclades_port *info)
2161{ 2095{
2096 struct cyclades_card *card;
2162 unsigned long flags; 2097 unsigned long flags;
2163 void __iomem *base_addr; 2098 void __iomem *base_addr;
2164 int card, chip, channel, index; 2099 int chip, channel, index;
2165 2100
2166 card = info->card; 2101 card = info->card;
2167 channel = (info->line) - (cy_card[card].first_line); 2102 channel = info->line - card->first_line;
2168 if (!IS_CYC_Z(cy_card[card])) { 2103 if (!IS_CYC_Z(*card)) {
2169 chip = channel >> 2; 2104 chip = channel >> 2;
2170 channel &= 0x03; 2105 channel &= 0x03;
2171 index = cy_card[card].bus_index; 2106 index = card->bus_index;
2172 base_addr = cy_card[card].base_addr + 2107 base_addr = card->base_addr + (cy_chip_offset[chip] << index);
2173 (cy_chip_offset[chip] << index);
2174 2108
2175 CY_LOCK(info, flags); 2109 spin_lock_irqsave(&card->card_lock, flags);
2176 cy_writeb(base_addr + (CyCAR << index), channel); 2110 cy_writeb(base_addr + (CyCAR << index), channel);
2177 cy_writeb(base_addr + (CySRER << index), 2111 cy_writeb(base_addr + (CySRER << index),
2178 cy_readb(base_addr + (CySRER << index)) | CyTxRdy); 2112 readb(base_addr + (CySRER << index)) | CyTxRdy);
2179 CY_UNLOCK(info, flags); 2113 spin_unlock_irqrestore(&card->card_lock, flags);
2180 } else { 2114 } else {
2181#ifdef CONFIG_CYZ_INTR 2115#ifdef CONFIG_CYZ_INTR
2182 int retval; 2116 int retval;
2183 2117
2184 CY_LOCK(info, flags); 2118 spin_lock_irqsave(&card->card_lock, flags);
2185 retval = cyz_issue_cmd(&cy_card[card], channel, C_CM_INTBACK, 2119 retval = cyz_issue_cmd(card, channel, C_CM_INTBACK, 0L);
2186 0L);
2187 if (retval != 0) { 2120 if (retval != 0) {
2188 printk("cyc:start_xmit retval on ttyC%d was %x\n", 2121 printk(KERN_ERR "cyc:start_xmit retval on ttyC%d was "
2189 info->line, retval); 2122 "%x\n", info->line, retval);
2190 } 2123 }
2191 CY_UNLOCK(info, flags); 2124 spin_unlock_irqrestore(&card->card_lock, flags);
2192#else /* CONFIG_CYZ_INTR */ 2125#else /* CONFIG_CYZ_INTR */
2193 /* Don't have to do anything at this time */ 2126 /* Don't have to do anything at this time */
2194#endif /* CONFIG_CYZ_INTR */ 2127#endif /* CONFIG_CYZ_INTR */
@@ -2201,30 +2134,30 @@ static void start_xmit(struct cyclades_port *info)
2201 */ 2134 */
2202static void shutdown(struct cyclades_port *info) 2135static void shutdown(struct cyclades_port *info)
2203{ 2136{
2137 struct cyclades_card *card;
2204 unsigned long flags; 2138 unsigned long flags;
2205 void __iomem *base_addr; 2139 void __iomem *base_addr;
2206 int card, chip, channel, index; 2140 int chip, channel, index;
2207 2141
2208 if (!(info->flags & ASYNC_INITIALIZED)) { 2142 if (!(info->flags & ASYNC_INITIALIZED)) {
2209 return; 2143 return;
2210 } 2144 }
2211 2145
2212 card = info->card; 2146 card = info->card;
2213 channel = info->line - cy_card[card].first_line; 2147 channel = info->line - card->first_line;
2214 if (!IS_CYC_Z(cy_card[card])) { 2148 if (!IS_CYC_Z(*card)) {
2215 chip = channel >> 2; 2149 chip = channel >> 2;
2216 channel &= 0x03; 2150 channel &= 0x03;
2217 index = cy_card[card].bus_index; 2151 index = card->bus_index;
2218 base_addr = cy_card[card].base_addr + 2152 base_addr = card->base_addr + (cy_chip_offset[chip] << index);
2219 (cy_chip_offset[chip] << index);
2220 2153
2221#ifdef CY_DEBUG_OPEN 2154#ifdef CY_DEBUG_OPEN
2222 printk("cyc shutdown Y card %d, chip %d, channel %d, " 2155 printk(KERN_DEBUG "cyc shutdown Y card %d, chip %d, "
2223 "base_addr %lx\n", 2156 "channel %d, base_addr %p\n",
2224 card, chip, channel, (long)base_addr); 2157 card, chip, channel, base_addr);
2225#endif 2158#endif
2226 2159
2227 CY_LOCK(info, flags); 2160 spin_lock_irqsave(&card->card_lock, flags);
2228 2161
2229 /* Clear delta_msr_wait queue to avoid mem leaks. */ 2162 /* Clear delta_msr_wait queue to avoid mem leaks. */
2230 wake_up_interruptible(&info->delta_msr_wait); 2163 wake_up_interruptible(&info->delta_msr_wait);
@@ -2240,10 +2173,10 @@ static void shutdown(struct cyclades_port *info)
2240 cy_writeb(base_addr + (CyMSVR1 << index), ~CyRTS); 2173 cy_writeb(base_addr + (CyMSVR1 << index), ~CyRTS);
2241 cy_writeb(base_addr + (CyMSVR2 << index), ~CyDTR); 2174 cy_writeb(base_addr + (CyMSVR2 << index), ~CyDTR);
2242#ifdef CY_DEBUG_DTR 2175#ifdef CY_DEBUG_DTR
2243 printk("cyc shutdown dropping DTR\n"); 2176 printk(KERN_DEBUG "cyc shutdown dropping DTR\n");
2244 printk(" status: 0x%x, 0x%x\n", 2177 printk(KERN_DEBUG " status: 0x%x, 0x%x\n",
2245 cy_readb(base_addr + (CyMSVR1 << index)), 2178 readb(base_addr + (CyMSVR1 << index)),
2246 cy_readb(base_addr + (CyMSVR2 << index))); 2179 readb(base_addr + (CyMSVR2 << index)));
2247#endif 2180#endif
2248 } 2181 }
2249 cyy_issue_cmd(base_addr, CyCHAN_CTL | CyDIS_RCVR, index); 2182 cyy_issue_cmd(base_addr, CyCHAN_CTL | CyDIS_RCVR, index);
@@ -2254,7 +2187,7 @@ static void shutdown(struct cyclades_port *info)
2254 set_bit(TTY_IO_ERROR, &info->tty->flags); 2187 set_bit(TTY_IO_ERROR, &info->tty->flags);
2255 } 2188 }
2256 info->flags &= ~ASYNC_INITIALIZED; 2189 info->flags &= ~ASYNC_INITIALIZED;
2257 CY_UNLOCK(info, flags); 2190 spin_unlock_irqrestore(&card->card_lock, flags);
2258 } else { 2191 } else {
2259 struct FIRM_ID __iomem *firm_id; 2192 struct FIRM_ID __iomem *firm_id;
2260 struct ZFW_CTRL __iomem *zfw_ctrl; 2193 struct ZFW_CTRL __iomem *zfw_ctrl;
@@ -2262,23 +2195,23 @@ static void shutdown(struct cyclades_port *info)
2262 struct CH_CTRL __iomem *ch_ctrl; 2195 struct CH_CTRL __iomem *ch_ctrl;
2263 int retval; 2196 int retval;
2264 2197
2265 base_addr = cy_card[card].base_addr; 2198 base_addr = card->base_addr;
2266#ifdef CY_DEBUG_OPEN 2199#ifdef CY_DEBUG_OPEN
2267 printk("cyc shutdown Z card %d, channel %d, base_addr %lx\n", 2200 printk(KERN_DEBUG "cyc shutdown Z card %d, channel %d, "
2268 card, channel, (long)base_addr); 2201 "base_addr %p\n", card, channel, base_addr);
2269#endif 2202#endif
2270 2203
2271 firm_id = base_addr + ID_ADDRESS; 2204 firm_id = base_addr + ID_ADDRESS;
2272 if (!ISZLOADED(cy_card[card])) { 2205 if (!ISZLOADED(*card)) {
2273 return; 2206 return;
2274 } 2207 }
2275 2208
2276 zfw_ctrl = cy_card[card].base_addr + 2209 zfw_ctrl = card->base_addr +
2277 (cy_readl(&firm_id->zfwctrl_addr) & 0xfffff); 2210 (readl(&firm_id->zfwctrl_addr) & 0xfffff);
2278 board_ctrl = &zfw_ctrl->board_ctrl; 2211 board_ctrl = &zfw_ctrl->board_ctrl;
2279 ch_ctrl = zfw_ctrl->ch_ctrl; 2212 ch_ctrl = zfw_ctrl->ch_ctrl;
2280 2213
2281 CY_LOCK(info, flags); 2214 spin_lock_irqsave(&card->card_lock, flags);
2282 2215
2283 if (info->xmit_buf) { 2216 if (info->xmit_buf) {
2284 unsigned char *temp; 2217 unsigned char *temp;
@@ -2289,16 +2222,16 @@ static void shutdown(struct cyclades_port *info)
2289 2222
2290 if (!info->tty || (info->tty->termios->c_cflag & HUPCL)) { 2223 if (!info->tty || (info->tty->termios->c_cflag & HUPCL)) {
2291 cy_writel(&ch_ctrl[channel].rs_control, 2224 cy_writel(&ch_ctrl[channel].rs_control,
2292 (uclong)(cy_readl(&ch_ctrl[channel].rs_control)& 2225 (__u32)(readl(&ch_ctrl[channel].rs_control) &
2293 ~(C_RS_RTS | C_RS_DTR))); 2226 ~(C_RS_RTS | C_RS_DTR)));
2294 retval = cyz_issue_cmd(&cy_card[info->card], channel, 2227 retval = cyz_issue_cmd(info->card, channel,
2295 C_CM_IOCTLM, 0L); 2228 C_CM_IOCTLM, 0L);
2296 if (retval != 0) { 2229 if (retval != 0) {
2297 printk("cyc:shutdown retval on ttyC%d was %x\n", 2230 printk(KERN_ERR"cyc:shutdown retval on ttyC%d "
2298 info->line, retval); 2231 "was %x\n", info->line, retval);
2299 } 2232 }
2300#ifdef CY_DEBUG_DTR 2233#ifdef CY_DEBUG_DTR
2301 printk("cyc:shutdown dropping Z DTR\n"); 2234 printk(KERN_DEBUG "cyc:shutdown dropping Z DTR\n");
2302#endif 2235#endif
2303 } 2236 }
2304 2237
@@ -2307,11 +2240,11 @@ static void shutdown(struct cyclades_port *info)
2307 } 2240 }
2308 info->flags &= ~ASYNC_INITIALIZED; 2241 info->flags &= ~ASYNC_INITIALIZED;
2309 2242
2310 CY_UNLOCK(info, flags); 2243 spin_unlock_irqrestore(&card->card_lock, flags);
2311 } 2244 }
2312 2245
2313#ifdef CY_DEBUG_OPEN 2246#ifdef CY_DEBUG_OPEN
2314 printk(" cyc shutdown done\n"); 2247 printk(KERN_DEBUG "cyc shutdown done\n");
2315#endif 2248#endif
2316} /* shutdown */ 2249} /* shutdown */
2317 2250
@@ -2332,7 +2265,7 @@ block_til_ready(struct tty_struct *tty, struct file *filp,
2332 int retval; 2265 int retval;
2333 void __iomem *base_addr; 2266 void __iomem *base_addr;
2334 2267
2335 cinfo = &cy_card[info->card]; 2268 cinfo = info->card;
2336 channel = info->line - cinfo->first_line; 2269 channel = info->line - cinfo->first_line;
2337 2270
2338 /* 2271 /*
@@ -2340,9 +2273,8 @@ block_til_ready(struct tty_struct *tty, struct file *filp,
2340 * until it's done, and then try again. 2273 * until it's done, and then try again.
2341 */ 2274 */
2342 if (tty_hung_up_p(filp) || (info->flags & ASYNC_CLOSING)) { 2275 if (tty_hung_up_p(filp) || (info->flags & ASYNC_CLOSING)) {
2343 if (info->flags & ASYNC_CLOSING) { 2276 wait_event_interruptible(info->close_wait,
2344 interruptible_sleep_on(&info->close_wait); 2277 !(info->flags & ASYNC_CLOSING));
2345 }
2346 return (info->flags & ASYNC_HUP_NOTIFY) ? -EAGAIN: -ERESTARTSYS; 2278 return (info->flags & ASYNC_HUP_NOTIFY) ? -EAGAIN: -ERESTARTSYS;
2347 } 2279 }
2348 2280
@@ -2365,17 +2297,16 @@ block_til_ready(struct tty_struct *tty, struct file *filp,
2365 retval = 0; 2297 retval = 0;
2366 add_wait_queue(&info->open_wait, &wait); 2298 add_wait_queue(&info->open_wait, &wait);
2367#ifdef CY_DEBUG_OPEN 2299#ifdef CY_DEBUG_OPEN
2368 printk("cyc block_til_ready before block: ttyC%d, count = %d\n", 2300 printk(KERN_DEBUG "cyc block_til_ready before block: ttyC%d, "
2369 info->line, info->count); 2301 "count = %d\n", info->line, info->count);
2370 /**/
2371#endif 2302#endif
2372 CY_LOCK(info, flags); 2303 spin_lock_irqsave(&cinfo->card_lock, flags);
2373 if (!tty_hung_up_p(filp)) 2304 if (!tty_hung_up_p(filp))
2374 info->count--; 2305 info->count--;
2375 CY_UNLOCK(info, flags); 2306 spin_unlock_irqrestore(&cinfo->card_lock, flags);
2376#ifdef CY_DEBUG_COUNT 2307#ifdef CY_DEBUG_COUNT
2377 printk("cyc block_til_ready: (%d): decrementing count to %d\n", 2308 printk(KERN_DEBUG "cyc block_til_ready: (%d): decrementing count to "
2378 current->pid, info->count); 2309 "%d\n", current->pid, info->count);
2379#endif 2310#endif
2380 info->blocked_open++; 2311 info->blocked_open++;
2381 2312
@@ -2386,7 +2317,7 @@ block_til_ready(struct tty_struct *tty, struct file *filp,
2386 base_addr = cinfo->base_addr + (cy_chip_offset[chip] << index); 2317 base_addr = cinfo->base_addr + (cy_chip_offset[chip] << index);
2387 2318
2388 while (1) { 2319 while (1) {
2389 CY_LOCK(info, flags); 2320 spin_lock_irqsave(&cinfo->card_lock, flags);
2390 if ((tty->termios->c_cflag & CBAUD)) { 2321 if ((tty->termios->c_cflag & CBAUD)) {
2391 cy_writeb(base_addr + (CyCAR << index), 2322 cy_writeb(base_addr + (CyCAR << index),
2392 (u_char) channel); 2323 (u_char) channel);
@@ -2395,15 +2326,14 @@ block_til_ready(struct tty_struct *tty, struct file *filp,
2395 cy_writeb(base_addr + (CyMSVR2 << index), 2326 cy_writeb(base_addr + (CyMSVR2 << index),
2396 CyDTR); 2327 CyDTR);
2397#ifdef CY_DEBUG_DTR 2328#ifdef CY_DEBUG_DTR
2398 printk("cyc:block_til_ready raising DTR\n"); 2329 printk(KERN_DEBUG "cyc:block_til_ready raising "
2399 printk(" status: 0x%x, 0x%x\n", 2330 "DTR\n");
2400 cy_readb(base_addr + 2331 printk(KERN_DEBUG " status: 0x%x, 0x%x\n",
2401 (CyMSVR1 << index)), 2332 readb(base_addr + (CyMSVR1 << index)),
2402 cy_readb(base_addr + 2333 readb(base_addr + (CyMSVR2 << index)));
2403 (CyMSVR2 << index)));
2404#endif 2334#endif
2405 } 2335 }
2406 CY_UNLOCK(info, flags); 2336 spin_unlock_irqrestore(&cinfo->card_lock, flags);
2407 2337
2408 set_current_state(TASK_INTERRUPTIBLE); 2338 set_current_state(TASK_INTERRUPTIBLE);
2409 if (tty_hung_up_p(filp) || 2339 if (tty_hung_up_p(filp) ||
@@ -2413,26 +2343,25 @@ block_til_ready(struct tty_struct *tty, struct file *filp,
2413 break; 2343 break;
2414 } 2344 }
2415 2345
2416 CY_LOCK(info, flags); 2346 spin_lock_irqsave(&cinfo->card_lock, flags);
2417 cy_writeb(base_addr + (CyCAR << index), 2347 cy_writeb(base_addr + (CyCAR << index),
2418 (u_char) channel); 2348 (u_char) channel);
2419 if (!(info->flags & ASYNC_CLOSING) && (C_CLOCAL(tty) || 2349 if (!(info->flags & ASYNC_CLOSING) && (C_CLOCAL(tty) ||
2420 (cy_readb(base_addr + 2350 (readb(base_addr +
2421 (CyMSVR1 << index)) & CyDCD))) { 2351 (CyMSVR1 << index)) & CyDCD))) {
2422 CY_UNLOCK(info, flags); 2352 spin_unlock_irqrestore(&cinfo->card_lock, flags);
2423 break; 2353 break;
2424 } 2354 }
2425 CY_UNLOCK(info, flags); 2355 spin_unlock_irqrestore(&cinfo->card_lock, flags);
2426 2356
2427 if (signal_pending(current)) { 2357 if (signal_pending(current)) {
2428 retval = -ERESTARTSYS; 2358 retval = -ERESTARTSYS;
2429 break; 2359 break;
2430 } 2360 }
2431#ifdef CY_DEBUG_OPEN 2361#ifdef CY_DEBUG_OPEN
2432 printk("cyc block_til_ready blocking: ttyC%d, " 2362 printk(KERN_DEBUG "cyc block_til_ready blocking: "
2433 "count = %d\n", 2363 "ttyC%d, count = %d\n",
2434 info->line, info->count); 2364 info->line, info->count);
2435 /**/
2436#endif 2365#endif
2437 schedule(); 2366 schedule();
2438 } 2367 }
@@ -2446,31 +2375,30 @@ block_til_ready(struct tty_struct *tty, struct file *filp,
2446 base_addr = cinfo->base_addr; 2375 base_addr = cinfo->base_addr;
2447 firm_id = base_addr + ID_ADDRESS; 2376 firm_id = base_addr + ID_ADDRESS;
2448 if (!ISZLOADED(*cinfo)) { 2377 if (!ISZLOADED(*cinfo)) {
2449 current->state = TASK_RUNNING; 2378 __set_current_state(TASK_RUNNING);
2450 remove_wait_queue(&info->open_wait, &wait); 2379 remove_wait_queue(&info->open_wait, &wait);
2451 return -EINVAL; 2380 return -EINVAL;
2452 } 2381 }
2453 2382
2454 zfw_ctrl = base_addr + (cy_readl(&firm_id->zfwctrl_addr) & 2383 zfw_ctrl = base_addr + (readl(&firm_id->zfwctrl_addr)& 0xfffff);
2455 0xfffff);
2456 board_ctrl = &zfw_ctrl->board_ctrl; 2384 board_ctrl = &zfw_ctrl->board_ctrl;
2457 ch_ctrl = zfw_ctrl->ch_ctrl; 2385 ch_ctrl = zfw_ctrl->ch_ctrl;
2458 2386
2459 while (1) { 2387 while (1) {
2460 if ((tty->termios->c_cflag & CBAUD)) { 2388 if ((tty->termios->c_cflag & CBAUD)) {
2461 cy_writel(&ch_ctrl[channel].rs_control, 2389 cy_writel(&ch_ctrl[channel].rs_control,
2462 cy_readl(&ch_ctrl[channel]. 2390 readl(&ch_ctrl[channel].rs_control) |
2463 rs_control) | (C_RS_RTS | 2391 C_RS_RTS | C_RS_DTR);
2464 C_RS_DTR)); 2392 retval = cyz_issue_cmd(cinfo,
2465 retval = cyz_issue_cmd(&cy_card[info->card], 2393 channel, C_CM_IOCTLM, 0L);
2466 channel, C_CM_IOCTLM, 0L);
2467 if (retval != 0) { 2394 if (retval != 0) {
2468 printk("cyc:block_til_ready retval on " 2395 printk(KERN_ERR "cyc:block_til_ready "
2469 "ttyC%d was %x\n", 2396 "retval on ttyC%d was %x\n",
2470 info->line, retval); 2397 info->line, retval);
2471 } 2398 }
2472#ifdef CY_DEBUG_DTR 2399#ifdef CY_DEBUG_DTR
2473 printk("cyc:block_til_ready raising Z DTR\n"); 2400 printk(KERN_DEBUG "cyc:block_til_ready raising "
2401 "Z DTR\n");
2474#endif 2402#endif
2475 } 2403 }
2476 2404
@@ -2482,7 +2410,7 @@ block_til_ready(struct tty_struct *tty, struct file *filp,
2482 break; 2410 break;
2483 } 2411 }
2484 if (!(info->flags & ASYNC_CLOSING) && (C_CLOCAL(tty) || 2412 if (!(info->flags & ASYNC_CLOSING) && (C_CLOCAL(tty) ||
2485 (cy_readl(&ch_ctrl[channel].rs_status) & 2413 (readl(&ch_ctrl[channel].rs_status) &
2486 C_RS_DCD))) { 2414 C_RS_DCD))) {
2487 break; 2415 break;
2488 } 2416 }
@@ -2491,28 +2419,26 @@ block_til_ready(struct tty_struct *tty, struct file *filp,
2491 break; 2419 break;
2492 } 2420 }
2493#ifdef CY_DEBUG_OPEN 2421#ifdef CY_DEBUG_OPEN
2494 printk("cyc block_til_ready blocking: ttyC%d, " 2422 printk(KERN_DEBUG "cyc block_til_ready blocking: "
2495 "count = %d\n", 2423 "ttyC%d, count = %d\n",
2496 info->line, info->count); 2424 info->line, info->count);
2497 /**/
2498#endif 2425#endif
2499 schedule(); 2426 schedule();
2500 } 2427 }
2501 } 2428 }
2502 current->state = TASK_RUNNING; 2429 __set_current_state(TASK_RUNNING);
2503 remove_wait_queue(&info->open_wait, &wait); 2430 remove_wait_queue(&info->open_wait, &wait);
2504 if (!tty_hung_up_p(filp)) { 2431 if (!tty_hung_up_p(filp)) {
2505 info->count++; 2432 info->count++;
2506#ifdef CY_DEBUG_COUNT 2433#ifdef CY_DEBUG_COUNT
2507 printk("cyc:block_til_ready (%d): incrementing count to %d\n", 2434 printk(KERN_DEBUG "cyc:block_til_ready (%d): incrementing "
2508 current->pid, info->count); 2435 "count to %d\n", current->pid, info->count);
2509#endif 2436#endif
2510 } 2437 }
2511 info->blocked_open--; 2438 info->blocked_open--;
2512#ifdef CY_DEBUG_OPEN 2439#ifdef CY_DEBUG_OPEN
2513 printk("cyc:block_til_ready after blocking: ttyC%d, count = %d\n", 2440 printk(KERN_DEBUG "cyc:block_til_ready after blocking: ttyC%d, "
2514 info->line, info->count); 2441 "count = %d\n", info->line, info->count);
2515 /**/
2516#endif 2442#endif
2517 if (retval) 2443 if (retval)
2518 return retval; 2444 return retval;
@@ -2527,13 +2453,20 @@ block_til_ready(struct tty_struct *tty, struct file *filp,
2527static int cy_open(struct tty_struct *tty, struct file *filp) 2453static int cy_open(struct tty_struct *tty, struct file *filp)
2528{ 2454{
2529 struct cyclades_port *info; 2455 struct cyclades_port *info;
2456 unsigned int i;
2530 int retval, line; 2457 int retval, line;
2531 2458
2532 line = tty->index; 2459 line = tty->index;
2533 if ((line < 0) || (NR_PORTS <= line)) { 2460 if ((line < 0) || (NR_PORTS <= line)) {
2534 return -ENODEV; 2461 return -ENODEV;
2535 } 2462 }
2536 info = &cy_port[line]; 2463 for (i = 0; i < NR_CARDS; i++)
2464 if (line < cy_card[i].first_line + cy_card[i].nports &&
2465 line >= cy_card[i].first_line)
2466 break;
2467 if (i >= NR_CARDS)
2468 return -ENODEV;
2469 info = &cy_card[i].ports[line - cy_card[i].first_line];
2537 if (info->line < 0) { 2470 if (info->line < 0) {
2538 return -ENODEV; 2471 return -ENODEV;
2539 } 2472 }
@@ -2542,23 +2475,23 @@ static int cy_open(struct tty_struct *tty, struct file *filp)
2542 treat it as absent from the system. This 2475 treat it as absent from the system. This
2543 will make the user pay attention. 2476 will make the user pay attention.
2544 */ 2477 */
2545 if (IS_CYC_Z(cy_card[info->card])) { 2478 if (IS_CYC_Z(*info->card)) {
2546 struct cyclades_card *cinfo = &cy_card[info->card]; 2479 struct cyclades_card *cinfo = info->card;
2547 struct FIRM_ID __iomem *firm_id = cinfo->base_addr + ID_ADDRESS; 2480 struct FIRM_ID __iomem *firm_id = cinfo->base_addr + ID_ADDRESS;
2548 2481
2549 if (!ISZLOADED(*cinfo)) { 2482 if (!ISZLOADED(*cinfo)) {
2550 if (((ZE_V1 == cy_readl( 2483 if (((ZE_V1 == readl(&((struct RUNTIME_9060 __iomem *)
2551 &((struct RUNTIME_9060 __iomem *)
2552 (cinfo->ctl_addr))->mail_box_0)) && 2484 (cinfo->ctl_addr))->mail_box_0)) &&
2553 Z_FPGA_CHECK(*cinfo)) && 2485 Z_FPGA_CHECK(*cinfo)) &&
2554 (ZFIRM_HLT == cy_readl( 2486 (ZFIRM_HLT == readl(
2555 &firm_id->signature))) { 2487 &firm_id->signature))) {
2556 printk("cyc:Cyclades-Z Error: you need an " 2488 printk(KERN_ERR "cyc:Cyclades-Z Error: you "
2557 "external power supply for this number " 2489 "need an external power supply for "
2558 "of ports.\n\rFirmware halted.\r\n"); 2490 "this number of ports.\nFirmware "
2491 "halted.\n");
2559 } else { 2492 } else {
2560 printk("cyc:Cyclades-Z firmware not yet " 2493 printk(KERN_ERR "cyc:Cyclades-Z firmware not "
2561 "loaded\n"); 2494 "yet loaded\n");
2562 } 2495 }
2563 return -ENODEV; 2496 return -ENODEV;
2564 } 2497 }
@@ -2572,24 +2505,23 @@ static int cy_open(struct tty_struct *tty, struct file *filp)
2572 struct BOARD_CTRL __iomem *board_ctrl; 2505 struct BOARD_CTRL __iomem *board_ctrl;
2573 2506
2574 zfw_ctrl = cinfo->base_addr + 2507 zfw_ctrl = cinfo->base_addr +
2575 (cy_readl(&firm_id->zfwctrl_addr) & 2508 (readl(&firm_id->zfwctrl_addr) &
2576 0xfffff); 2509 0xfffff);
2577 2510
2578 board_ctrl = &zfw_ctrl->board_ctrl; 2511 board_ctrl = &zfw_ctrl->board_ctrl;
2579 2512
2580 /* Enable interrupts on the PLX chip */ 2513 /* Enable interrupts on the PLX chip */
2581 cy_writew(cinfo->ctl_addr + 0x68, 2514 cy_writew(cinfo->ctl_addr + 0x68,
2582 cy_readw(cinfo->ctl_addr + 2515 readw(cinfo->ctl_addr + 0x68) | 0x0900);
2583 0x68) | 0x0900);
2584 /* Enable interrupts on the FW */ 2516 /* Enable interrupts on the FW */
2585 retval = cyz_issue_cmd(cinfo, 0, 2517 retval = cyz_issue_cmd(cinfo, 0,
2586 C_CM_IRQ_ENBL, 0L); 2518 C_CM_IRQ_ENBL, 0L);
2587 if (retval != 0) { 2519 if (retval != 0) {
2588 printk("cyc:IRQ enable retval was %x\n", 2520 printk(KERN_ERR "cyc:IRQ enable retval "
2589 retval); 2521 "was %x\n", retval);
2590 } 2522 }
2591 cinfo->nports = 2523 cinfo->nports =
2592 (int)cy_readl(&board_ctrl->n_channel); 2524 (int)readl(&board_ctrl->n_channel);
2593 cinfo->intr_enabled = 1; 2525 cinfo->intr_enabled = 1;
2594 } 2526 }
2595 } 2527 }
@@ -2599,7 +2531,7 @@ static int cy_open(struct tty_struct *tty, struct file *filp)
2599 return -ENODEV; 2531 return -ENODEV;
2600 } 2532 }
2601#ifdef CY_DEBUG_OTHER 2533#ifdef CY_DEBUG_OTHER
2602 printk("cyc:cy_open ttyC%d\n", info->line); /* */ 2534 printk(KERN_DEBUG "cyc:cy_open ttyC%d\n", info->line);
2603#endif 2535#endif
2604 tty->driver_data = info; 2536 tty->driver_data = info;
2605 info->tty = tty; 2537 info->tty = tty;
@@ -2607,12 +2539,12 @@ static int cy_open(struct tty_struct *tty, struct file *filp)
2607 return -ENODEV; 2539 return -ENODEV;
2608 } 2540 }
2609#ifdef CY_DEBUG_OPEN 2541#ifdef CY_DEBUG_OPEN
2610 printk("cyc:cy_open ttyC%d, count = %d\n", info->line, info->count); 2542 printk(KERN_DEBUG "cyc:cy_open ttyC%d, count = %d\n", info->line,
2611 /**/ 2543 info->count);
2612#endif 2544#endif
2613 info->count++; 2545 info->count++;
2614#ifdef CY_DEBUG_COUNT 2546#ifdef CY_DEBUG_COUNT
2615 printk("cyc:cy_open (%d): incrementing count to %d\n", 2547 printk(KERN_DEBUG "cyc:cy_open (%d): incrementing count to %d\n",
2616 current->pid, info->count); 2548 current->pid, info->count);
2617#endif 2549#endif
2618 2550
@@ -2620,8 +2552,8 @@ static int cy_open(struct tty_struct *tty, struct file *filp)
2620 * If the port is the middle of closing, bail out now 2552 * If the port is the middle of closing, bail out now
2621 */ 2553 */
2622 if (tty_hung_up_p(filp) || (info->flags & ASYNC_CLOSING)) { 2554 if (tty_hung_up_p(filp) || (info->flags & ASYNC_CLOSING)) {
2623 if (info->flags & ASYNC_CLOSING) 2555 wait_event_interruptible(info->close_wait,
2624 interruptible_sleep_on(&info->close_wait); 2556 !(info->flags & ASYNC_CLOSING));
2625 return (info->flags & ASYNC_HUP_NOTIFY) ? -EAGAIN: -ERESTARTSYS; 2557 return (info->flags & ASYNC_HUP_NOTIFY) ? -EAGAIN: -ERESTARTSYS;
2626 } 2558 }
2627 2559
@@ -2636,8 +2568,8 @@ static int cy_open(struct tty_struct *tty, struct file *filp)
2636 retval = block_til_ready(tty, filp, info); 2568 retval = block_til_ready(tty, filp, info);
2637 if (retval) { 2569 if (retval) {
2638#ifdef CY_DEBUG_OPEN 2570#ifdef CY_DEBUG_OPEN
2639 printk("cyc:cy_open returning after block_til_ready with %d\n", 2571 printk(KERN_DEBUG "cyc:cy_open returning after block_til_ready "
2640 retval); 2572 "with %d\n", retval);
2641#endif 2573#endif
2642 return retval; 2574 return retval;
2643 } 2575 }
@@ -2645,8 +2577,7 @@ static int cy_open(struct tty_struct *tty, struct file *filp)
2645 info->throttle = 0; 2577 info->throttle = 0;
2646 2578
2647#ifdef CY_DEBUG_OPEN 2579#ifdef CY_DEBUG_OPEN
2648 printk(" cyc:cy_open done\n"); 2580 printk(KERN_DEBUG "cyc:cy_open done\n");
2649 /**/
2650#endif 2581#endif
2651 return 0; 2582 return 0;
2652} /* cy_open */ 2583} /* cy_open */
@@ -2656,9 +2587,10 @@ static int cy_open(struct tty_struct *tty, struct file *filp)
2656 */ 2587 */
2657static void cy_wait_until_sent(struct tty_struct *tty, int timeout) 2588static void cy_wait_until_sent(struct tty_struct *tty, int timeout)
2658{ 2589{
2659 struct cyclades_port *info = (struct cyclades_port *)tty->driver_data; 2590 struct cyclades_card *card;
2591 struct cyclades_port *info = tty->driver_data;
2660 void __iomem *base_addr; 2592 void __iomem *base_addr;
2661 int card, chip, channel, index; 2593 int chip, channel, index;
2662 unsigned long orig_jiffies; 2594 unsigned long orig_jiffies;
2663 int char_time; 2595 int char_time;
2664 2596
@@ -2697,20 +2629,19 @@ static void cy_wait_until_sent(struct tty_struct *tty, int timeout)
2697 if (!timeout || timeout > 2 * info->timeout) 2629 if (!timeout || timeout > 2 * info->timeout)
2698 timeout = 2 * info->timeout; 2630 timeout = 2 * info->timeout;
2699#ifdef CY_DEBUG_WAIT_UNTIL_SENT 2631#ifdef CY_DEBUG_WAIT_UNTIL_SENT
2700 printk("In cy_wait_until_sent(%d) check=%lu...", timeout, char_time); 2632 printk(KERN_DEBUG "In cy_wait_until_sent(%d) check=%d, jiff=%lu...",
2701 printk("jiff=%lu...", jiffies); 2633 timeout, char_time, jiffies);
2702#endif 2634#endif
2703 card = info->card; 2635 card = info->card;
2704 channel = (info->line) - (cy_card[card].first_line); 2636 channel = (info->line) - (card->first_line);
2705 if (!IS_CYC_Z(cy_card[card])) { 2637 if (!IS_CYC_Z(*card)) {
2706 chip = channel >> 2; 2638 chip = channel >> 2;
2707 channel &= 0x03; 2639 channel &= 0x03;
2708 index = cy_card[card].bus_index; 2640 index = card->bus_index;
2709 base_addr = 2641 base_addr = card->base_addr + (cy_chip_offset[chip] << index);
2710 cy_card[card].base_addr + (cy_chip_offset[chip] << index); 2642 while (readb(base_addr + (CySRER << index)) & CyTxRdy) {
2711 while (cy_readb(base_addr + (CySRER << index)) & CyTxRdy) {
2712#ifdef CY_DEBUG_WAIT_UNTIL_SENT 2643#ifdef CY_DEBUG_WAIT_UNTIL_SENT
2713 printk("Not clean (jiff=%lu)...", jiffies); 2644 printk(KERN_DEBUG "Not clean (jiff=%lu)...", jiffies);
2714#endif 2645#endif
2715 if (msleep_interruptible(jiffies_to_msecs(char_time))) 2646 if (msleep_interruptible(jiffies_to_msecs(char_time)))
2716 break; 2647 break;
@@ -2718,13 +2649,11 @@ static void cy_wait_until_sent(struct tty_struct *tty, int timeout)
2718 timeout)) 2649 timeout))
2719 break; 2650 break;
2720 } 2651 }
2721 } else {
2722 /* Nothing to do! */
2723 } 2652 }
2724 /* Run one more char cycle */ 2653 /* Run one more char cycle */
2725 msleep_interruptible(jiffies_to_msecs(char_time * 5)); 2654 msleep_interruptible(jiffies_to_msecs(char_time * 5));
2726#ifdef CY_DEBUG_WAIT_UNTIL_SENT 2655#ifdef CY_DEBUG_WAIT_UNTIL_SENT
2727 printk("Clean (jiff=%lu)...done\n", jiffies); 2656 printk(KERN_DEBUG "Clean (jiff=%lu)...done\n", jiffies);
2728#endif 2657#endif
2729} 2658}
2730 2659
@@ -2733,25 +2662,29 @@ static void cy_wait_until_sent(struct tty_struct *tty, int timeout)
2733 */ 2662 */
2734static void cy_close(struct tty_struct *tty, struct file *filp) 2663static void cy_close(struct tty_struct *tty, struct file *filp)
2735{ 2664{
2736 struct cyclades_port *info = (struct cyclades_port *)tty->driver_data; 2665 struct cyclades_port *info = tty->driver_data;
2666 struct cyclades_card *card;
2737 unsigned long flags; 2667 unsigned long flags;
2738 2668
2739#ifdef CY_DEBUG_OTHER 2669#ifdef CY_DEBUG_OTHER
2740 printk("cyc:cy_close ttyC%d\n", info->line); 2670 printk(KERN_DEBUG "cyc:cy_close ttyC%d\n", info->line);
2741#endif 2671#endif
2742 2672
2743 if (!info || serial_paranoia_check(info, tty->name, "cy_close")) { 2673 if (!info || serial_paranoia_check(info, tty->name, "cy_close")) {
2744 return; 2674 return;
2745 } 2675 }
2746 2676
2747 CY_LOCK(info, flags); 2677 card = info->card;
2678
2679 spin_lock_irqsave(&card->card_lock, flags);
2748 /* If the TTY is being hung up, nothing to do */ 2680 /* If the TTY is being hung up, nothing to do */
2749 if (tty_hung_up_p(filp)) { 2681 if (tty_hung_up_p(filp)) {
2750 CY_UNLOCK(info, flags); 2682 spin_unlock_irqrestore(&card->card_lock, flags);
2751 return; 2683 return;
2752 } 2684 }
2753#ifdef CY_DEBUG_OPEN 2685#ifdef CY_DEBUG_OPEN
2754 printk("cyc:cy_close ttyC%d, count = %d\n", info->line, info->count); 2686 printk(KERN_DEBUG "cyc:cy_close ttyC%d, count = %d\n", info->line,
2687 info->count);
2755#endif 2688#endif
2756 if ((tty->count == 1) && (info->count != 1)) { 2689 if ((tty->count == 1) && (info->count != 1)) {
2757 /* 2690 /*
@@ -2761,22 +2694,22 @@ static void cy_close(struct tty_struct *tty, struct file *filp)
2761 * one, we've got real problems, since it means the 2694 * one, we've got real problems, since it means the
2762 * serial port won't be shutdown. 2695 * serial port won't be shutdown.
2763 */ 2696 */
2764 printk("cyc:cy_close: bad serial port count; tty->count is 1, " 2697 printk(KERN_ERR "cyc:cy_close: bad serial port count; "
2765 "info->count is %d\n", info->count); 2698 "tty->count is 1, info->count is %d\n", info->count);
2766 info->count = 1; 2699 info->count = 1;
2767 } 2700 }
2768#ifdef CY_DEBUG_COUNT 2701#ifdef CY_DEBUG_COUNT
2769 printk("cyc:cy_close at (%d): decrementing count to %d\n", 2702 printk(KERN_DEBUG "cyc:cy_close at (%d): decrementing count to %d\n",
2770 current->pid, info->count - 1); 2703 current->pid, info->count - 1);
2771#endif 2704#endif
2772 if (--info->count < 0) { 2705 if (--info->count < 0) {
2773#ifdef CY_DEBUG_COUNT 2706#ifdef CY_DEBUG_COUNT
2774 printk("cyc:cyc_close setting count to 0\n"); 2707 printk(KERN_DEBUG "cyc:cyc_close setting count to 0\n");
2775#endif 2708#endif
2776 info->count = 0; 2709 info->count = 0;
2777 } 2710 }
2778 if (info->count) { 2711 if (info->count) {
2779 CY_UNLOCK(info, flags); 2712 spin_unlock_irqrestore(&card->card_lock, flags);
2780 return; 2713 return;
2781 } 2714 }
2782 info->flags |= ASYNC_CLOSING; 2715 info->flags |= ASYNC_CLOSING;
@@ -2786,81 +2719,80 @@ static void cy_close(struct tty_struct *tty, struct file *filp)
2786 * the line discipline to only process XON/XOFF characters. 2719 * the line discipline to only process XON/XOFF characters.
2787 */ 2720 */
2788 tty->closing = 1; 2721 tty->closing = 1;
2789 CY_UNLOCK(info, flags); 2722 spin_unlock_irqrestore(&card->card_lock, flags);
2790 if (info->closing_wait != CY_CLOSING_WAIT_NONE) { 2723 if (info->closing_wait != CY_CLOSING_WAIT_NONE) {
2791 tty_wait_until_sent(tty, info->closing_wait); 2724 tty_wait_until_sent(tty, info->closing_wait);
2792 } 2725 }
2793 CY_LOCK(info, flags); 2726 spin_lock_irqsave(&card->card_lock, flags);
2794 2727
2795 if (!IS_CYC_Z(cy_card[info->card])) { 2728 if (!IS_CYC_Z(*card)) {
2796 int channel = info->line - cy_card[info->card].first_line; 2729 int channel = info->line - card->first_line;
2797 int index = cy_card[info->card].bus_index; 2730 int index = card->bus_index;
2798 void __iomem *base_addr = cy_card[info->card].base_addr + 2731 void __iomem *base_addr = card->base_addr +
2799 (cy_chip_offset[channel >> 2] << index); 2732 (cy_chip_offset[channel >> 2] << index);
2800 /* Stop accepting input */ 2733 /* Stop accepting input */
2801 channel &= 0x03; 2734 channel &= 0x03;
2802 cy_writeb(base_addr + (CyCAR << index), (u_char) channel); 2735 cy_writeb(base_addr + (CyCAR << index), (u_char) channel);
2803 cy_writeb(base_addr + (CySRER << index), 2736 cy_writeb(base_addr + (CySRER << index),
2804 cy_readb(base_addr + (CySRER << index)) & ~CyRxData); 2737 readb(base_addr + (CySRER << index)) & ~CyRxData);
2805 if (info->flags & ASYNC_INITIALIZED) { 2738 if (info->flags & ASYNC_INITIALIZED) {
2806 /* Waiting for on-board buffers to be empty before closing 2739 /* Waiting for on-board buffers to be empty before closing
2807 the port */ 2740 the port */
2808 CY_UNLOCK(info, flags); 2741 spin_unlock_irqrestore(&card->card_lock, flags);
2809 cy_wait_until_sent(tty, info->timeout); 2742 cy_wait_until_sent(tty, info->timeout);
2810 CY_LOCK(info, flags); 2743 spin_lock_irqsave(&card->card_lock, flags);
2811 } 2744 }
2812 } else { 2745 } else {
2813#ifdef Z_WAKE 2746#ifdef Z_WAKE
2814 /* Waiting for on-board buffers to be empty before closing the port */ 2747 /* Waiting for on-board buffers to be empty before closing the port */
2815 void __iomem *base_addr = cy_card[info->card].base_addr; 2748 void __iomem *base_addr = card->base_addr;
2816 struct FIRM_ID __iomem *firm_id = base_addr + ID_ADDRESS; 2749 struct FIRM_ID __iomem *firm_id = base_addr + ID_ADDRESS;
2817 struct ZFW_CTRL __iomem *zfw_ctrl = 2750 struct ZFW_CTRL __iomem *zfw_ctrl =
2818 base_addr + (cy_readl(&firm_id->zfwctrl_addr) & 0xfffff); 2751 base_addr + (readl(&firm_id->zfwctrl_addr) & 0xfffff);
2819 struct CH_CTRL __iomem *ch_ctrl = zfw_ctrl->ch_ctrl; 2752 struct CH_CTRL __iomem *ch_ctrl = zfw_ctrl->ch_ctrl;
2820 int channel = info->line - cy_card[info->card].first_line; 2753 int channel = info->line - card->first_line;
2821 int retval; 2754 int retval;
2822 2755
2823 if (cy_readl(&ch_ctrl[channel].flow_status) != C_FS_TXIDLE) { 2756 if (readl(&ch_ctrl[channel].flow_status) != C_FS_TXIDLE) {
2824 retval = cyz_issue_cmd(&cy_card[info->card], channel, 2757 retval = cyz_issue_cmd(card, channel, C_CM_IOCTLW, 0L);
2825 C_CM_IOCTLW, 0L);
2826 if (retval != 0) { 2758 if (retval != 0) {
2827 printk("cyc:cy_close retval on ttyC%d was %x\n", 2759 printk(KERN_DEBUG "cyc:cy_close retval on "
2828 info->line, retval); 2760 "ttyC%d was %x\n", info->line, retval);
2829 } 2761 }
2830 CY_UNLOCK(info, flags); 2762 spin_unlock_irqrestore(&card->card_lock, flags);
2831 interruptible_sleep_on(&info->shutdown_wait); 2763 wait_for_completion_interruptible(&info->shutdown_wait);
2832 CY_LOCK(info, flags); 2764 spin_lock_irqsave(&card->card_lock, flags);
2833 } 2765 }
2834#endif 2766#endif
2835 } 2767 }
2836 2768
2837 CY_UNLOCK(info, flags); 2769 spin_unlock_irqrestore(&card->card_lock, flags);
2838 shutdown(info); 2770 shutdown(info);
2839 if (tty->driver->flush_buffer) 2771 if (tty->driver->flush_buffer)
2840 tty->driver->flush_buffer(tty); 2772 tty->driver->flush_buffer(tty);
2841 tty_ldisc_flush(tty); 2773 tty_ldisc_flush(tty);
2842 CY_LOCK(info, flags); 2774 spin_lock_irqsave(&card->card_lock, flags);
2843 2775
2844 tty->closing = 0; 2776 tty->closing = 0;
2845 info->event = 0; 2777 info->event = 0;
2846 info->tty = NULL; 2778 info->tty = NULL;
2847 if (info->blocked_open) { 2779 if (info->blocked_open) {
2848 CY_UNLOCK(info, flags); 2780 spin_unlock_irqrestore(&card->card_lock, flags);
2849 if (info->close_delay) { 2781 if (info->close_delay) {
2850 msleep_interruptible(jiffies_to_msecs 2782 msleep_interruptible(jiffies_to_msecs
2851 (info->close_delay)); 2783 (info->close_delay));
2852 } 2784 }
2853 wake_up_interruptible(&info->open_wait); 2785 wake_up_interruptible(&info->open_wait);
2854 CY_LOCK(info, flags); 2786 spin_lock_irqsave(&card->card_lock, flags);
2855 } 2787 }
2856 info->flags &= ~(ASYNC_NORMAL_ACTIVE | ASYNC_CLOSING); 2788 info->flags &= ~(ASYNC_NORMAL_ACTIVE | ASYNC_CLOSING);
2857 wake_up_interruptible(&info->close_wait); 2789 wake_up_interruptible(&info->close_wait);
2858 2790
2859#ifdef CY_DEBUG_OTHER 2791#ifdef CY_DEBUG_OTHER
2860 printk(" cyc:cy_close done\n"); 2792 printk(KERN_DEBUG "cyc:cy_close done\n");
2861#endif 2793#endif
2862 2794
2863 CY_UNLOCK(info, flags); 2795 spin_unlock_irqrestore(&card->card_lock, flags);
2864} /* cy_close */ 2796} /* cy_close */
2865 2797
2866/* This routine gets called when tty_write has put something into 2798/* This routine gets called when tty_write has put something into
@@ -2878,12 +2810,12 @@ static void cy_close(struct tty_struct *tty, struct file *filp)
2878 */ 2810 */
2879static int cy_write(struct tty_struct *tty, const unsigned char *buf, int count) 2811static int cy_write(struct tty_struct *tty, const unsigned char *buf, int count)
2880{ 2812{
2881 struct cyclades_port *info = (struct cyclades_port *)tty->driver_data; 2813 struct cyclades_port *info = tty->driver_data;
2882 unsigned long flags; 2814 unsigned long flags;
2883 int c, ret = 0; 2815 int c, ret = 0;
2884 2816
2885#ifdef CY_DEBUG_IO 2817#ifdef CY_DEBUG_IO
2886 printk("cyc:cy_write ttyC%d\n", info->line); /* */ 2818 printk(KERN_DEBUG "cyc:cy_write ttyC%d\n", info->line);
2887#endif 2819#endif
2888 2820
2889 if (serial_paranoia_check(info, tty->name, "cy_write")) { 2821 if (serial_paranoia_check(info, tty->name, "cy_write")) {
@@ -2893,7 +2825,7 @@ static int cy_write(struct tty_struct *tty, const unsigned char *buf, int count)
2893 if (!info->xmit_buf) 2825 if (!info->xmit_buf)
2894 return 0; 2826 return 0;
2895 2827
2896 CY_LOCK(info, flags); 2828 spin_lock_irqsave(&info->card->card_lock, flags);
2897 while (1) { 2829 while (1) {
2898 c = min(count, min((int)(SERIAL_XMIT_SIZE - info->xmit_cnt - 1), 2830 c = min(count, min((int)(SERIAL_XMIT_SIZE - info->xmit_cnt - 1),
2899 (int)(SERIAL_XMIT_SIZE - info->xmit_head))); 2831 (int)(SERIAL_XMIT_SIZE - info->xmit_head)));
@@ -2909,7 +2841,7 @@ static int cy_write(struct tty_struct *tty, const unsigned char *buf, int count)
2909 count -= c; 2841 count -= c;
2910 ret += c; 2842 ret += c;
2911 } 2843 }
2912 CY_UNLOCK(info, flags); 2844 spin_unlock_irqrestore(&info->card->card_lock, flags);
2913 2845
2914 info->idle_stats.xmit_bytes += ret; 2846 info->idle_stats.xmit_bytes += ret;
2915 info->idle_stats.xmit_idle = jiffies; 2847 info->idle_stats.xmit_idle = jiffies;
@@ -2929,11 +2861,11 @@ static int cy_write(struct tty_struct *tty, const unsigned char *buf, int count)
2929 */ 2861 */
2930static void cy_put_char(struct tty_struct *tty, unsigned char ch) 2862static void cy_put_char(struct tty_struct *tty, unsigned char ch)
2931{ 2863{
2932 struct cyclades_port *info = (struct cyclades_port *)tty->driver_data; 2864 struct cyclades_port *info = tty->driver_data;
2933 unsigned long flags; 2865 unsigned long flags;
2934 2866
2935#ifdef CY_DEBUG_IO 2867#ifdef CY_DEBUG_IO
2936 printk("cyc:cy_put_char ttyC%d\n", info->line); 2868 printk(KERN_DEBUG "cyc:cy_put_char ttyC%d\n", info->line);
2937#endif 2869#endif
2938 2870
2939 if (serial_paranoia_check(info, tty->name, "cy_put_char")) 2871 if (serial_paranoia_check(info, tty->name, "cy_put_char"))
@@ -2942,9 +2874,9 @@ static void cy_put_char(struct tty_struct *tty, unsigned char ch)
2942 if (!info->xmit_buf) 2874 if (!info->xmit_buf)
2943 return; 2875 return;
2944 2876
2945 CY_LOCK(info, flags); 2877 spin_lock_irqsave(&info->card->card_lock, flags);
2946 if (info->xmit_cnt >= (int)(SERIAL_XMIT_SIZE - 1)) { 2878 if (info->xmit_cnt >= (int)(SERIAL_XMIT_SIZE - 1)) {
2947 CY_UNLOCK(info, flags); 2879 spin_unlock_irqrestore(&info->card->card_lock, flags);
2948 return; 2880 return;
2949 } 2881 }
2950 2882
@@ -2953,7 +2885,7 @@ static void cy_put_char(struct tty_struct *tty, unsigned char ch)
2953 info->xmit_cnt++; 2885 info->xmit_cnt++;
2954 info->idle_stats.xmit_bytes++; 2886 info->idle_stats.xmit_bytes++;
2955 info->idle_stats.xmit_idle = jiffies; 2887 info->idle_stats.xmit_idle = jiffies;
2956 CY_UNLOCK(info, flags); 2888 spin_unlock_irqrestore(&info->card->card_lock, flags);
2957} /* cy_put_char */ 2889} /* cy_put_char */
2958 2890
2959/* 2891/*
@@ -2962,10 +2894,10 @@ static void cy_put_char(struct tty_struct *tty, unsigned char ch)
2962 */ 2894 */
2963static void cy_flush_chars(struct tty_struct *tty) 2895static void cy_flush_chars(struct tty_struct *tty)
2964{ 2896{
2965 struct cyclades_port *info = (struct cyclades_port *)tty->driver_data; 2897 struct cyclades_port *info = tty->driver_data;
2966 2898
2967#ifdef CY_DEBUG_IO 2899#ifdef CY_DEBUG_IO
2968 printk("cyc:cy_flush_chars ttyC%d\n", info->line); /* */ 2900 printk(KERN_DEBUG "cyc:cy_flush_chars ttyC%d\n", info->line);
2969#endif 2901#endif
2970 2902
2971 if (serial_paranoia_check(info, tty->name, "cy_flush_chars")) 2903 if (serial_paranoia_check(info, tty->name, "cy_flush_chars"))
@@ -2986,11 +2918,11 @@ static void cy_flush_chars(struct tty_struct *tty)
2986 */ 2918 */
2987static int cy_write_room(struct tty_struct *tty) 2919static int cy_write_room(struct tty_struct *tty)
2988{ 2920{
2989 struct cyclades_port *info = (struct cyclades_port *)tty->driver_data; 2921 struct cyclades_port *info = tty->driver_data;
2990 int ret; 2922 int ret;
2991 2923
2992#ifdef CY_DEBUG_IO 2924#ifdef CY_DEBUG_IO
2993 printk("cyc:cy_write_room ttyC%d\n", info->line); /* */ 2925 printk(KERN_DEBUG "cyc:cy_write_room ttyC%d\n", info->line);
2994#endif 2926#endif
2995 2927
2996 if (serial_paranoia_check(info, tty->name, "cy_write_room")) 2928 if (serial_paranoia_check(info, tty->name, "cy_write_room"))
@@ -3003,46 +2935,49 @@ static int cy_write_room(struct tty_struct *tty)
3003 2935
3004static int cy_chars_in_buffer(struct tty_struct *tty) 2936static int cy_chars_in_buffer(struct tty_struct *tty)
3005{ 2937{
3006 struct cyclades_port *info = (struct cyclades_port *)tty->driver_data; 2938 struct cyclades_card *card;
3007 int card, channel; 2939 struct cyclades_port *info = tty->driver_data;
2940 int channel;
3008 2941
3009 if (serial_paranoia_check(info, tty->name, "cy_chars_in_buffer")) 2942 if (serial_paranoia_check(info, tty->name, "cy_chars_in_buffer"))
3010 return 0; 2943 return 0;
3011 2944
3012 card = info->card; 2945 card = info->card;
3013 channel = (info->line) - (cy_card[card].first_line); 2946 channel = (info->line) - (card->first_line);
3014 2947
3015#ifdef Z_EXT_CHARS_IN_BUFFER 2948#ifdef Z_EXT_CHARS_IN_BUFFER
3016 if (!IS_CYC_Z(cy_card[card])) { 2949 if (!IS_CYC_Z(cy_card[card])) {
3017#endif /* Z_EXT_CHARS_IN_BUFFER */ 2950#endif /* Z_EXT_CHARS_IN_BUFFER */
3018#ifdef CY_DEBUG_IO 2951#ifdef CY_DEBUG_IO
3019 printk("cyc:cy_chars_in_buffer ttyC%d %d\n", info->line, info->xmit_cnt); /* */ 2952 printk(KERN_DEBUG "cyc:cy_chars_in_buffer ttyC%d %d\n",
2953 info->line, info->xmit_cnt);
3020#endif 2954#endif
3021 return info->xmit_cnt; 2955 return info->xmit_cnt;
3022#ifdef Z_EXT_CHARS_IN_BUFFER 2956#ifdef Z_EXT_CHARS_IN_BUFFER
3023 } else { 2957 } else {
3024 static volatile struct FIRM_ID *firm_id; 2958 static struct FIRM_ID *firm_id;
3025 static volatile struct ZFW_CTRL *zfw_ctrl; 2959 static struct ZFW_CTRL *zfw_ctrl;
3026 static volatile struct CH_CTRL *ch_ctrl; 2960 static struct CH_CTRL *ch_ctrl;
3027 static volatile struct BUF_CTRL *buf_ctrl; 2961 static struct BUF_CTRL *buf_ctrl;
3028 int char_count; 2962 int char_count;
3029 volatile uclong tx_put, tx_get, tx_bufsize; 2963 __u32 tx_put, tx_get, tx_bufsize;
3030 2964
3031 firm_id = cy_card[card].base_addr + ID_ADDRESS; 2965 firm_id = card->base_addr + ID_ADDRESS;
3032 zfw_ctrl = cy_card[card].base_addr + 2966 zfw_ctrl = card->base_addr +
3033 (cy_readl(&firm_id->zfwctrl_addr) & 0xfffff); 2967 (readl(&firm_id->zfwctrl_addr) & 0xfffff);
3034 ch_ctrl = &(zfw_ctrl->ch_ctrl[channel]); 2968 ch_ctrl = &(zfw_ctrl->ch_ctrl[channel]);
3035 buf_ctrl = &(zfw_ctrl->buf_ctrl[channel]); 2969 buf_ctrl = &(zfw_ctrl->buf_ctrl[channel]);
3036 2970
3037 tx_get = cy_readl(&buf_ctrl->tx_get); 2971 tx_get = readl(&buf_ctrl->tx_get);
3038 tx_put = cy_readl(&buf_ctrl->tx_put); 2972 tx_put = readl(&buf_ctrl->tx_put);
3039 tx_bufsize = cy_readl(&buf_ctrl->tx_bufsize); 2973 tx_bufsize = readl(&buf_ctrl->tx_bufsize);
3040 if (tx_put >= tx_get) 2974 if (tx_put >= tx_get)
3041 char_count = tx_put - tx_get; 2975 char_count = tx_put - tx_get;
3042 else 2976 else
3043 char_count = tx_put - tx_get + tx_bufsize; 2977 char_count = tx_put - tx_get + tx_bufsize;
3044#ifdef CY_DEBUG_IO 2978#ifdef CY_DEBUG_IO
3045 printk("cyc:cy_chars_in_buffer ttyC%d %d\n", info->line, info->xmit_cnt + char_count); /* */ 2979 printk(KERN_DEBUG "cyc:cy_chars_in_buffer ttyC%d %d\n",
2980 info->line, info->xmit_cnt + char_count);
3046#endif 2981#endif
3047 return info->xmit_cnt + char_count; 2982 return info->xmit_cnt + char_count;
3048 } 2983 }
@@ -3055,10 +2990,10 @@ static int cy_chars_in_buffer(struct tty_struct *tty)
3055 * ------------------------------------------------------------ 2990 * ------------------------------------------------------------
3056 */ 2991 */
3057 2992
3058static void cyy_baud_calc(struct cyclades_port *info, uclong baud) 2993static void cyy_baud_calc(struct cyclades_port *info, __u32 baud)
3059{ 2994{
3060 int co, co_val, bpr; 2995 int co, co_val, bpr;
3061 uclong cy_clock = ((info->chip_rev >= CD1400_REV_J) ? 60000000 : 2996 __u32 cy_clock = ((info->chip_rev >= CD1400_REV_J) ? 60000000 :
3062 25000000); 2997 25000000);
3063 2998
3064 if (baud == 0) { 2999 if (baud == 0) {
@@ -3086,9 +3021,10 @@ static void cyy_baud_calc(struct cyclades_port *info, uclong baud)
3086 */ 3021 */
3087static void set_line_char(struct cyclades_port *info) 3022static void set_line_char(struct cyclades_port *info)
3088{ 3023{
3024 struct cyclades_card *card;
3089 unsigned long flags; 3025 unsigned long flags;
3090 void __iomem *base_addr; 3026 void __iomem *base_addr;
3091 int card, chip, channel, index; 3027 int chip, channel, index;
3092 unsigned cflag, iflag; 3028 unsigned cflag, iflag;
3093 unsigned short chip_number; 3029 unsigned short chip_number;
3094 int baud, baud_rate = 0; 3030 int baud, baud_rate = 0;
@@ -3118,12 +3054,12 @@ static void set_line_char(struct cyclades_port *info)
3118 } 3054 }
3119 3055
3120 card = info->card; 3056 card = info->card;
3121 channel = (info->line) - (cy_card[card].first_line); 3057 channel = info->line - card->first_line;
3122 chip_number = channel / 4; 3058 chip_number = channel / 4;
3123 3059
3124 if (!IS_CYC_Z(cy_card[card])) { 3060 if (!IS_CYC_Z(*card)) {
3125 3061
3126 index = cy_card[card].bus_index; 3062 index = card->bus_index;
3127 3063
3128 /* baud rate */ 3064 /* baud rate */
3129 baud = tty_get_baud_rate(info->tty); 3065 baud = tty_get_baud_rate(info->tty);
@@ -3241,10 +3177,9 @@ static void set_line_char(struct cyclades_port *info)
3241 3177
3242 chip = channel >> 2; 3178 chip = channel >> 2;
3243 channel &= 0x03; 3179 channel &= 0x03;
3244 base_addr = cy_card[card].base_addr + 3180 base_addr = card->base_addr + (cy_chip_offset[chip] << index);
3245 (cy_chip_offset[chip] << index);
3246 3181
3247 CY_LOCK(info, flags); 3182 spin_lock_irqsave(&card->card_lock, flags);
3248 cy_writeb(base_addr + (CyCAR << index), (u_char) channel); 3183 cy_writeb(base_addr + (CyCAR << index), (u_char) channel);
3249 3184
3250 /* tx and rx baud rate */ 3185 /* tx and rx baud rate */
@@ -3276,8 +3211,7 @@ static void set_line_char(struct cyclades_port *info)
3276 if (C_CLOCAL(info->tty)) { 3211 if (C_CLOCAL(info->tty)) {
3277 /* without modem intr */ 3212 /* without modem intr */
3278 cy_writeb(base_addr + (CySRER << index), 3213 cy_writeb(base_addr + (CySRER << index),
3279 cy_readb(base_addr + 3214 readb(base_addr + (CySRER << index)) | CyMdmCh);
3280 (CySRER << index)) | CyMdmCh);
3281 /* act on 1->0 modem transitions */ 3215 /* act on 1->0 modem transitions */
3282 if ((cflag & CRTSCTS) && info->rflow) { 3216 if ((cflag & CRTSCTS) && info->rflow) {
3283 cy_writeb(base_addr + (CyMCOR1 << index), 3217 cy_writeb(base_addr + (CyMCOR1 << index),
@@ -3291,7 +3225,7 @@ static void set_line_char(struct cyclades_port *info)
3291 } else { 3225 } else {
3292 /* without modem intr */ 3226 /* without modem intr */
3293 cy_writeb(base_addr + (CySRER << index), 3227 cy_writeb(base_addr + (CySRER << index),
3294 cy_readb(base_addr + 3228 readb(base_addr +
3295 (CySRER << index)) | CyMdmCh); 3229 (CySRER << index)) | CyMdmCh);
3296 /* act on 1->0 modem transitions */ 3230 /* act on 1->0 modem transitions */
3297 if ((cflag & CRTSCTS) && info->rflow) { 3231 if ((cflag & CRTSCTS) && info->rflow) {
@@ -3316,10 +3250,10 @@ static void set_line_char(struct cyclades_port *info)
3316 ~CyDTR); 3250 ~CyDTR);
3317 } 3251 }
3318#ifdef CY_DEBUG_DTR 3252#ifdef CY_DEBUG_DTR
3319 printk("cyc:set_line_char dropping DTR\n"); 3253 printk(KERN_DEBUG "cyc:set_line_char dropping DTR\n");
3320 printk(" status: 0x%x, 0x%x\n", 3254 printk(KERN_DEBUG " status: 0x%x, 0x%x\n",
3321 cy_readb(base_addr + (CyMSVR1 << index)), 3255 readb(base_addr + (CyMSVR1 << index)),
3322 cy_readb(base_addr + (CyMSVR2 << index))); 3256 readb(base_addr + (CyMSVR2 << index)));
3323#endif 3257#endif
3324 } else { 3258 } else {
3325 if (info->rtsdtr_inv) { 3259 if (info->rtsdtr_inv) {
@@ -3330,17 +3264,17 @@ static void set_line_char(struct cyclades_port *info)
3330 CyDTR); 3264 CyDTR);
3331 } 3265 }
3332#ifdef CY_DEBUG_DTR 3266#ifdef CY_DEBUG_DTR
3333 printk("cyc:set_line_char raising DTR\n"); 3267 printk(KERN_DEBUG "cyc:set_line_char raising DTR\n");
3334 printk(" status: 0x%x, 0x%x\n", 3268 printk(KERN_DEBUG " status: 0x%x, 0x%x\n",
3335 cy_readb(base_addr + (CyMSVR1 << index)), 3269 readb(base_addr + (CyMSVR1 << index)),
3336 cy_readb(base_addr + (CyMSVR2 << index))); 3270 readb(base_addr + (CyMSVR2 << index)));
3337#endif 3271#endif
3338 } 3272 }
3339 3273
3340 if (info->tty) { 3274 if (info->tty) {
3341 clear_bit(TTY_IO_ERROR, &info->tty->flags); 3275 clear_bit(TTY_IO_ERROR, &info->tty->flags);
3342 } 3276 }
3343 CY_UNLOCK(info, flags); 3277 spin_unlock_irqrestore(&card->card_lock, flags);
3344 3278
3345 } else { 3279 } else {
3346 struct FIRM_ID __iomem *firm_id; 3280 struct FIRM_ID __iomem *firm_id;
@@ -3348,16 +3282,16 @@ static void set_line_char(struct cyclades_port *info)
3348 struct BOARD_CTRL __iomem *board_ctrl; 3282 struct BOARD_CTRL __iomem *board_ctrl;
3349 struct CH_CTRL __iomem *ch_ctrl; 3283 struct CH_CTRL __iomem *ch_ctrl;
3350 struct BUF_CTRL __iomem *buf_ctrl; 3284 struct BUF_CTRL __iomem *buf_ctrl;
3351 uclong sw_flow; 3285 __u32 sw_flow;
3352 int retval; 3286 int retval;
3353 3287
3354 firm_id = cy_card[card].base_addr + ID_ADDRESS; 3288 firm_id = card->base_addr + ID_ADDRESS;
3355 if (!ISZLOADED(cy_card[card])) { 3289 if (!ISZLOADED(*card)) {
3356 return; 3290 return;
3357 } 3291 }
3358 3292
3359 zfw_ctrl = cy_card[card].base_addr + 3293 zfw_ctrl = card->base_addr +
3360 (cy_readl(&firm_id->zfwctrl_addr) & 0xfffff); 3294 (readl(&firm_id->zfwctrl_addr) & 0xfffff);
3361 board_ctrl = &zfw_ctrl->board_ctrl; 3295 board_ctrl = &zfw_ctrl->board_ctrl;
3362 ch_ctrl = &(zfw_ctrl->ch_ctrl[channel]); 3296 ch_ctrl = &(zfw_ctrl->ch_ctrl[channel]);
3363 buf_ctrl = &zfw_ctrl->buf_ctrl[channel]; 3297 buf_ctrl = &zfw_ctrl->buf_ctrl[channel];
@@ -3408,10 +3342,10 @@ static void set_line_char(struct cyclades_port *info)
3408 } 3342 }
3409 if (cflag & CSTOPB) { 3343 if (cflag & CSTOPB) {
3410 cy_writel(&ch_ctrl->comm_data_l, 3344 cy_writel(&ch_ctrl->comm_data_l,
3411 cy_readl(&ch_ctrl->comm_data_l) | C_DL_2STOP); 3345 readl(&ch_ctrl->comm_data_l) | C_DL_2STOP);
3412 } else { 3346 } else {
3413 cy_writel(&ch_ctrl->comm_data_l, 3347 cy_writel(&ch_ctrl->comm_data_l,
3414 cy_readl(&ch_ctrl->comm_data_l) | C_DL_1STOP); 3348 readl(&ch_ctrl->comm_data_l) | C_DL_1STOP);
3415 } 3349 }
3416 if (cflag & PARENB) { 3350 if (cflag & PARENB) {
3417 if (cflag & PARODD) { 3351 if (cflag & PARODD) {
@@ -3426,12 +3360,10 @@ static void set_line_char(struct cyclades_port *info)
3426 /* CTS flow control flag */ 3360 /* CTS flow control flag */
3427 if (cflag & CRTSCTS) { 3361 if (cflag & CRTSCTS) {
3428 cy_writel(&ch_ctrl->hw_flow, 3362 cy_writel(&ch_ctrl->hw_flow,
3429 cy_readl(&ch_ctrl-> 3363 readl(&ch_ctrl->hw_flow) | C_RS_CTS | C_RS_RTS);
3430 hw_flow) | C_RS_CTS | C_RS_RTS);
3431 } else { 3364 } else {
3432 cy_writel(&ch_ctrl->hw_flow, 3365 cy_writel(&ch_ctrl->hw_flow, readl(&ch_ctrl->hw_flow) &
3433 cy_readl(&ch_ctrl-> 3366 ~(C_RS_CTS | C_RS_RTS));
3434 hw_flow) & ~(C_RS_CTS | C_RS_RTS));
3435 } 3367 }
3436 /* As the HW flow control is done in firmware, the driver 3368 /* As the HW flow control is done in firmware, the driver
3437 doesn't need to care about it */ 3369 doesn't need to care about it */
@@ -3446,10 +3378,10 @@ static void set_line_char(struct cyclades_port *info)
3446 } 3378 }
3447 cy_writel(&ch_ctrl->sw_flow, sw_flow); 3379 cy_writel(&ch_ctrl->sw_flow, sw_flow);
3448 3380
3449 retval = cyz_issue_cmd(&cy_card[card], channel, C_CM_IOCTL, 0L); 3381 retval = cyz_issue_cmd(card, channel, C_CM_IOCTL, 0L);
3450 if (retval != 0) { 3382 if (retval != 0) {
3451 printk("cyc:set_line_char retval on ttyC%d was %x\n", 3383 printk(KERN_ERR "cyc:set_line_char retval on ttyC%d "
3452 info->line, retval); 3384 "was %x\n", info->line, retval);
3453 } 3385 }
3454 3386
3455 /* CD sensitivity */ 3387 /* CD sensitivity */
@@ -3461,22 +3393,22 @@ static void set_line_char(struct cyclades_port *info)
3461 3393
3462 if (baud == 0) { /* baud rate is zero, turn off line */ 3394 if (baud == 0) { /* baud rate is zero, turn off line */
3463 cy_writel(&ch_ctrl->rs_control, 3395 cy_writel(&ch_ctrl->rs_control,
3464 cy_readl(&ch_ctrl->rs_control) & ~C_RS_DTR); 3396 readl(&ch_ctrl->rs_control) & ~C_RS_DTR);
3465#ifdef CY_DEBUG_DTR 3397#ifdef CY_DEBUG_DTR
3466 printk("cyc:set_line_char dropping Z DTR\n"); 3398 printk(KERN_DEBUG "cyc:set_line_char dropping Z DTR\n");
3467#endif 3399#endif
3468 } else { 3400 } else {
3469 cy_writel(&ch_ctrl->rs_control, 3401 cy_writel(&ch_ctrl->rs_control,
3470 cy_readl(&ch_ctrl->rs_control) | C_RS_DTR); 3402 readl(&ch_ctrl->rs_control) | C_RS_DTR);
3471#ifdef CY_DEBUG_DTR 3403#ifdef CY_DEBUG_DTR
3472 printk("cyc:set_line_char raising Z DTR\n"); 3404 printk(KERN_DEBUG "cyc:set_line_char raising Z DTR\n");
3473#endif 3405#endif
3474 } 3406 }
3475 3407
3476 retval = cyz_issue_cmd(&cy_card[card], channel, C_CM_IOCTLM,0L); 3408 retval = cyz_issue_cmd(card, channel, C_CM_IOCTLM,0L);
3477 if (retval != 0) { 3409 if (retval != 0) {
3478 printk("cyc:set_line_char(2) retval on ttyC%d was %x\n", 3410 printk(KERN_ERR "cyc:set_line_char(2) retval on ttyC%d "
3479 info->line, retval); 3411 "was %x\n", info->line, retval);
3480 } 3412 }
3481 3413
3482 if (info->tty) { 3414 if (info->tty) {
@@ -3490,14 +3422,15 @@ get_serial_info(struct cyclades_port *info,
3490 struct serial_struct __user * retinfo) 3422 struct serial_struct __user * retinfo)
3491{ 3423{
3492 struct serial_struct tmp; 3424 struct serial_struct tmp;
3493 struct cyclades_card *cinfo = &cy_card[info->card]; 3425 struct cyclades_card *cinfo = info->card;
3494 3426
3495 if (!retinfo) 3427 if (!retinfo)
3496 return -EFAULT; 3428 return -EFAULT;
3497 memset(&tmp, 0, sizeof(tmp)); 3429 memset(&tmp, 0, sizeof(tmp));
3498 tmp.type = info->type; 3430 tmp.type = info->type;
3499 tmp.line = info->line; 3431 tmp.line = info->line;
3500 tmp.port = info->card * 0x100 + info->line - cinfo->first_line; 3432 tmp.port = (info->card - cy_card) * 0x100 + info->line -
3433 cinfo->first_line;
3501 tmp.irq = cinfo->irq; 3434 tmp.irq = cinfo->irq;
3502 tmp.flags = info->flags; 3435 tmp.flags = info->flags;
3503 tmp.close_delay = info->close_delay; 3436 tmp.close_delay = info->close_delay;
@@ -3566,25 +3499,25 @@ check_and_exit:
3566 */ 3499 */
3567static int get_lsr_info(struct cyclades_port *info, unsigned int __user * value) 3500static int get_lsr_info(struct cyclades_port *info, unsigned int __user * value)
3568{ 3501{
3569 int card, chip, channel, index; 3502 struct cyclades_card *card;
3503 int chip, channel, index;
3570 unsigned char status; 3504 unsigned char status;
3571 unsigned int result; 3505 unsigned int result;
3572 unsigned long flags; 3506 unsigned long flags;
3573 void __iomem *base_addr; 3507 void __iomem *base_addr;
3574 3508
3575 card = info->card; 3509 card = info->card;
3576 channel = (info->line) - (cy_card[card].first_line); 3510 channel = (info->line) - (card->first_line);
3577 if (!IS_CYC_Z(cy_card[card])) { 3511 if (!IS_CYC_Z(*card)) {
3578 chip = channel >> 2; 3512 chip = channel >> 2;
3579 channel &= 0x03; 3513 channel &= 0x03;
3580 index = cy_card[card].bus_index; 3514 index = card->bus_index;
3581 base_addr = 3515 base_addr = card->base_addr + (cy_chip_offset[chip] << index);
3582 cy_card[card].base_addr + (cy_chip_offset[chip] << index);
3583 3516
3584 CY_LOCK(info, flags); 3517 spin_lock_irqsave(&card->card_lock, flags);
3585 status = cy_readb(base_addr + (CySRER << index)) & 3518 status = readb(base_addr + (CySRER << index)) &
3586 (CyTxRdy | CyTxMpty); 3519 (CyTxRdy | CyTxMpty);
3587 CY_UNLOCK(info, flags); 3520 spin_unlock_irqrestore(&card->card_lock, flags);
3588 result = (status ? 0 : TIOCSER_TEMT); 3521 result = (status ? 0 : TIOCSER_TEMT);
3589 } else { 3522 } else {
3590 /* Not supported yet */ 3523 /* Not supported yet */
@@ -3595,8 +3528,9 @@ static int get_lsr_info(struct cyclades_port *info, unsigned int __user * value)
3595 3528
3596static int cy_tiocmget(struct tty_struct *tty, struct file *file) 3529static int cy_tiocmget(struct tty_struct *tty, struct file *file)
3597{ 3530{
3598 struct cyclades_port *info = (struct cyclades_port *)tty->driver_data; 3531 struct cyclades_port *info = tty->driver_data;
3599 int card, chip, channel, index; 3532 struct cyclades_card *card;
3533 int chip, channel, index;
3600 void __iomem *base_addr; 3534 void __iomem *base_addr;
3601 unsigned long flags; 3535 unsigned long flags;
3602 unsigned char status; 3536 unsigned char status;
@@ -3611,19 +3545,18 @@ static int cy_tiocmget(struct tty_struct *tty, struct file *file)
3611 return -ENODEV; 3545 return -ENODEV;
3612 3546
3613 card = info->card; 3547 card = info->card;
3614 channel = (info->line) - (cy_card[card].first_line); 3548 channel = info->line - card->first_line;
3615 if (!IS_CYC_Z(cy_card[card])) { 3549 if (!IS_CYC_Z(*card)) {
3616 chip = channel >> 2; 3550 chip = channel >> 2;
3617 channel &= 0x03; 3551 channel &= 0x03;
3618 index = cy_card[card].bus_index; 3552 index = card->bus_index;
3619 base_addr = 3553 base_addr = card->base_addr + (cy_chip_offset[chip] << index);
3620 cy_card[card].base_addr + (cy_chip_offset[chip] << index);
3621 3554
3622 CY_LOCK(info, flags); 3555 spin_lock_irqsave(&card->card_lock, flags);
3623 cy_writeb(base_addr + (CyCAR << index), (u_char) channel); 3556 cy_writeb(base_addr + (CyCAR << index), (u_char) channel);
3624 status = cy_readb(base_addr + (CyMSVR1 << index)); 3557 status = readb(base_addr + (CyMSVR1 << index));
3625 status |= cy_readb(base_addr + (CyMSVR2 << index)); 3558 status |= readb(base_addr + (CyMSVR2 << index));
3626 CY_UNLOCK(info, flags); 3559 spin_unlock_irqrestore(&card->card_lock, flags);
3627 3560
3628 if (info->rtsdtr_inv) { 3561 if (info->rtsdtr_inv) {
3629 result = ((status & CyRTS) ? TIOCM_DTR : 0) | 3562 result = ((status & CyRTS) ? TIOCM_DTR : 0) |
@@ -3637,19 +3570,14 @@ static int cy_tiocmget(struct tty_struct *tty, struct file *file)
3637 ((status & CyDSR) ? TIOCM_DSR : 0) | 3570 ((status & CyDSR) ? TIOCM_DSR : 0) |
3638 ((status & CyCTS) ? TIOCM_CTS : 0); 3571 ((status & CyCTS) ? TIOCM_CTS : 0);
3639 } else { 3572 } else {
3640 base_addr = cy_card[card].base_addr; 3573 base_addr = card->base_addr;
3641 3574 firm_id = card->base_addr + ID_ADDRESS;
3642 if (cy_card[card].num_chips != -1) { 3575 if (ISZLOADED(*card)) {
3643 return -EINVAL; 3576 zfw_ctrl = card->base_addr +
3644 } 3577 (readl(&firm_id->zfwctrl_addr) & 0xfffff);
3645
3646 firm_id = cy_card[card].base_addr + ID_ADDRESS;
3647 if (ISZLOADED(cy_card[card])) {
3648 zfw_ctrl = cy_card[card].base_addr +
3649 (cy_readl(&firm_id->zfwctrl_addr) & 0xfffff);
3650 board_ctrl = &zfw_ctrl->board_ctrl; 3578 board_ctrl = &zfw_ctrl->board_ctrl;
3651 ch_ctrl = zfw_ctrl->ch_ctrl; 3579 ch_ctrl = zfw_ctrl->ch_ctrl;
3652 lstatus = cy_readl(&ch_ctrl[channel].rs_status); 3580 lstatus = readl(&ch_ctrl[channel].rs_status);
3653 result = ((lstatus & C_RS_RTS) ? TIOCM_RTS : 0) | 3581 result = ((lstatus & C_RS_RTS) ? TIOCM_RTS : 0) |
3654 ((lstatus & C_RS_DTR) ? TIOCM_DTR : 0) | 3582 ((lstatus & C_RS_DTR) ? TIOCM_DTR : 0) |
3655 ((lstatus & C_RS_DCD) ? TIOCM_CAR : 0) | 3583 ((lstatus & C_RS_DCD) ? TIOCM_CAR : 0) |
@@ -3669,8 +3597,9 @@ static int
3669cy_tiocmset(struct tty_struct *tty, struct file *file, 3597cy_tiocmset(struct tty_struct *tty, struct file *file,
3670 unsigned int set, unsigned int clear) 3598 unsigned int set, unsigned int clear)
3671{ 3599{
3672 struct cyclades_port *info = (struct cyclades_port *)tty->driver_data; 3600 struct cyclades_port *info = tty->driver_data;
3673 int card, chip, channel, index; 3601 struct cyclades_card *card;
3602 int chip, channel, index;
3674 void __iomem *base_addr; 3603 void __iomem *base_addr;
3675 unsigned long flags; 3604 unsigned long flags;
3676 struct FIRM_ID __iomem *firm_id; 3605 struct FIRM_ID __iomem *firm_id;
@@ -3683,16 +3612,15 @@ cy_tiocmset(struct tty_struct *tty, struct file *file,
3683 return -ENODEV; 3612 return -ENODEV;
3684 3613
3685 card = info->card; 3614 card = info->card;
3686 channel = (info->line) - (cy_card[card].first_line); 3615 channel = (info->line) - (card->first_line);
3687 if (!IS_CYC_Z(cy_card[card])) { 3616 if (!IS_CYC_Z(*card)) {
3688 chip = channel >> 2; 3617 chip = channel >> 2;
3689 channel &= 0x03; 3618 channel &= 0x03;
3690 index = cy_card[card].bus_index; 3619 index = card->bus_index;
3691 base_addr = 3620 base_addr = card->base_addr + (cy_chip_offset[chip] << index);
3692 cy_card[card].base_addr + (cy_chip_offset[chip] << index);
3693 3621
3694 if (set & TIOCM_RTS) { 3622 if (set & TIOCM_RTS) {
3695 CY_LOCK(info, flags); 3623 spin_lock_irqsave(&card->card_lock, flags);
3696 cy_writeb(base_addr + (CyCAR << index), 3624 cy_writeb(base_addr + (CyCAR << index),
3697 (u_char) channel); 3625 (u_char) channel);
3698 if (info->rtsdtr_inv) { 3626 if (info->rtsdtr_inv) {
@@ -3702,10 +3630,10 @@ cy_tiocmset(struct tty_struct *tty, struct file *file,
3702 cy_writeb(base_addr + (CyMSVR1 << index), 3630 cy_writeb(base_addr + (CyMSVR1 << index),
3703 CyRTS); 3631 CyRTS);
3704 } 3632 }
3705 CY_UNLOCK(info, flags); 3633 spin_unlock_irqrestore(&card->card_lock, flags);
3706 } 3634 }
3707 if (clear & TIOCM_RTS) { 3635 if (clear & TIOCM_RTS) {
3708 CY_LOCK(info, flags); 3636 spin_lock_irqsave(&card->card_lock, flags);
3709 cy_writeb(base_addr + (CyCAR << index), 3637 cy_writeb(base_addr + (CyCAR << index),
3710 (u_char) channel); 3638 (u_char) channel);
3711 if (info->rtsdtr_inv) { 3639 if (info->rtsdtr_inv) {
@@ -3715,10 +3643,10 @@ cy_tiocmset(struct tty_struct *tty, struct file *file,
3715 cy_writeb(base_addr + (CyMSVR1 << index), 3643 cy_writeb(base_addr + (CyMSVR1 << index),
3716 ~CyRTS); 3644 ~CyRTS);
3717 } 3645 }
3718 CY_UNLOCK(info, flags); 3646 spin_unlock_irqrestore(&card->card_lock, flags);
3719 } 3647 }
3720 if (set & TIOCM_DTR) { 3648 if (set & TIOCM_DTR) {
3721 CY_LOCK(info, flags); 3649 spin_lock_irqsave(&card->card_lock, flags);
3722 cy_writeb(base_addr + (CyCAR << index), 3650 cy_writeb(base_addr + (CyCAR << index),
3723 (u_char) channel); 3651 (u_char) channel);
3724 if (info->rtsdtr_inv) { 3652 if (info->rtsdtr_inv) {
@@ -3729,15 +3657,15 @@ cy_tiocmset(struct tty_struct *tty, struct file *file,
3729 CyDTR); 3657 CyDTR);
3730 } 3658 }
3731#ifdef CY_DEBUG_DTR 3659#ifdef CY_DEBUG_DTR
3732 printk("cyc:set_modem_info raising DTR\n"); 3660 printk(KERN_DEBUG "cyc:set_modem_info raising DTR\n");
3733 printk(" status: 0x%x, 0x%x\n", 3661 printk(KERN_DEBUG " status: 0x%x, 0x%x\n",
3734 cy_readb(base_addr + (CyMSVR1 << index)), 3662 readb(base_addr + (CyMSVR1 << index)),
3735 cy_readb(base_addr + (CyMSVR2 << index))); 3663 readb(base_addr + (CyMSVR2 << index)));
3736#endif 3664#endif
3737 CY_UNLOCK(info, flags); 3665 spin_unlock_irqrestore(&card->card_lock, flags);
3738 } 3666 }
3739 if (clear & TIOCM_DTR) { 3667 if (clear & TIOCM_DTR) {
3740 CY_LOCK(info, flags); 3668 spin_lock_irqsave(&card->card_lock, flags);
3741 cy_writeb(base_addr + (CyCAR << index), 3669 cy_writeb(base_addr + (CyCAR << index),
3742 (u_char) channel); 3670 (u_char) channel);
3743 if (info->rtsdtr_inv) { 3671 if (info->rtsdtr_inv) {
@@ -3749,68 +3677,69 @@ cy_tiocmset(struct tty_struct *tty, struct file *file,
3749 } 3677 }
3750 3678
3751#ifdef CY_DEBUG_DTR 3679#ifdef CY_DEBUG_DTR
3752 printk("cyc:set_modem_info dropping DTR\n"); 3680 printk(KERN_DEBUG "cyc:set_modem_info dropping DTR\n");
3753 printk(" status: 0x%x, 0x%x\n", 3681 printk(KERN_DEBUG " status: 0x%x, 0x%x\n",
3754 cy_readb(base_addr + (CyMSVR1 << index)), 3682 readb(base_addr + (CyMSVR1 << index)),
3755 cy_readb(base_addr + (CyMSVR2 << index))); 3683 readb(base_addr + (CyMSVR2 << index)));
3756#endif 3684#endif
3757 CY_UNLOCK(info, flags); 3685 spin_unlock_irqrestore(&card->card_lock, flags);
3758 } 3686 }
3759 } else { 3687 } else {
3760 base_addr = cy_card[card].base_addr; 3688 base_addr = card->base_addr;
3761 3689
3762 firm_id = cy_card[card].base_addr + ID_ADDRESS; 3690 firm_id = card->base_addr + ID_ADDRESS;
3763 if (ISZLOADED(cy_card[card])) { 3691 if (ISZLOADED(*card)) {
3764 zfw_ctrl = cy_card[card].base_addr + 3692 zfw_ctrl = card->base_addr +
3765 (cy_readl(&firm_id->zfwctrl_addr) & 0xfffff); 3693 (readl(&firm_id->zfwctrl_addr) & 0xfffff);
3766 board_ctrl = &zfw_ctrl->board_ctrl; 3694 board_ctrl = &zfw_ctrl->board_ctrl;
3767 ch_ctrl = zfw_ctrl->ch_ctrl; 3695 ch_ctrl = zfw_ctrl->ch_ctrl;
3768 3696
3769 if (set & TIOCM_RTS) { 3697 if (set & TIOCM_RTS) {
3770 CY_LOCK(info, flags); 3698 spin_lock_irqsave(&card->card_lock, flags);
3771 cy_writel(&ch_ctrl[channel].rs_control, 3699 cy_writel(&ch_ctrl[channel].rs_control,
3772 cy_readl(&ch_ctrl[channel]. 3700 readl(&ch_ctrl[channel].rs_control) |
3773 rs_control) | C_RS_RTS); 3701 C_RS_RTS);
3774 CY_UNLOCK(info, flags); 3702 spin_unlock_irqrestore(&card->card_lock, flags);
3775 } 3703 }
3776 if (clear & TIOCM_RTS) { 3704 if (clear & TIOCM_RTS) {
3777 CY_LOCK(info, flags); 3705 spin_lock_irqsave(&card->card_lock, flags);
3778 cy_writel(&ch_ctrl[channel].rs_control, 3706 cy_writel(&ch_ctrl[channel].rs_control,
3779 cy_readl(&ch_ctrl[channel]. 3707 readl(&ch_ctrl[channel].rs_control) &
3780 rs_control) & ~C_RS_RTS); 3708 ~C_RS_RTS);
3781 CY_UNLOCK(info, flags); 3709 spin_unlock_irqrestore(&card->card_lock, flags);
3782 } 3710 }
3783 if (set & TIOCM_DTR) { 3711 if (set & TIOCM_DTR) {
3784 CY_LOCK(info, flags); 3712 spin_lock_irqsave(&card->card_lock, flags);
3785 cy_writel(&ch_ctrl[channel].rs_control, 3713 cy_writel(&ch_ctrl[channel].rs_control,
3786 cy_readl(&ch_ctrl[channel]. 3714 readl(&ch_ctrl[channel].rs_control) |
3787 rs_control) | C_RS_DTR); 3715 C_RS_DTR);
3788#ifdef CY_DEBUG_DTR 3716#ifdef CY_DEBUG_DTR
3789 printk("cyc:set_modem_info raising Z DTR\n"); 3717 printk(KERN_DEBUG "cyc:set_modem_info raising "
3718 "Z DTR\n");
3790#endif 3719#endif
3791 CY_UNLOCK(info, flags); 3720 spin_unlock_irqrestore(&card->card_lock, flags);
3792 } 3721 }
3793 if (clear & TIOCM_DTR) { 3722 if (clear & TIOCM_DTR) {
3794 CY_LOCK(info, flags); 3723 spin_lock_irqsave(&card->card_lock, flags);
3795 cy_writel(&ch_ctrl[channel].rs_control, 3724 cy_writel(&ch_ctrl[channel].rs_control,
3796 cy_readl(&ch_ctrl[channel]. 3725 readl(&ch_ctrl[channel].rs_control) &
3797 rs_control) & ~C_RS_DTR); 3726 ~C_RS_DTR);
3798#ifdef CY_DEBUG_DTR 3727#ifdef CY_DEBUG_DTR
3799 printk("cyc:set_modem_info clearing Z DTR\n"); 3728 printk(KERN_DEBUG "cyc:set_modem_info clearing "
3729 "Z DTR\n");
3800#endif 3730#endif
3801 CY_UNLOCK(info, flags); 3731 spin_unlock_irqrestore(&card->card_lock, flags);
3802 } 3732 }
3803 } else { 3733 } else {
3804 return -ENODEV; 3734 return -ENODEV;
3805 } 3735 }
3806 CY_LOCK(info, flags); 3736 spin_lock_irqsave(&card->card_lock, flags);
3807 retval = cyz_issue_cmd(&cy_card[info->card], 3737 retval = cyz_issue_cmd(card, channel, C_CM_IOCTLM, 0L);
3808 channel, C_CM_IOCTLM, 0L);
3809 if (retval != 0) { 3738 if (retval != 0) {
3810 printk("cyc:set_modem_info retval on ttyC%d was %x\n", 3739 printk(KERN_ERR "cyc:set_modem_info retval on ttyC%d "
3811 info->line, retval); 3740 "was %x\n", info->line, retval);
3812 } 3741 }
3813 CY_UNLOCK(info, flags); 3742 spin_unlock_irqrestore(&card->card_lock, flags);
3814 } 3743 }
3815 return 0; 3744 return 0;
3816} /* cy_tiocmset */ 3745} /* cy_tiocmset */
@@ -3820,14 +3749,17 @@ cy_tiocmset(struct tty_struct *tty, struct file *file,
3820 */ 3749 */
3821static void cy_break(struct tty_struct *tty, int break_state) 3750static void cy_break(struct tty_struct *tty, int break_state)
3822{ 3751{
3823 struct cyclades_port *info = (struct cyclades_port *)tty->driver_data; 3752 struct cyclades_port *info = tty->driver_data;
3753 struct cyclades_card *card;
3824 unsigned long flags; 3754 unsigned long flags;
3825 3755
3826 if (serial_paranoia_check(info, tty->name, "cy_break")) 3756 if (serial_paranoia_check(info, tty->name, "cy_break"))
3827 return; 3757 return;
3828 3758
3829 CY_LOCK(info, flags); 3759 card = info->card;
3830 if (!IS_CYC_Z(cy_card[info->card])) { 3760
3761 spin_lock_irqsave(&card->card_lock, flags);
3762 if (!IS_CYC_Z(*card)) {
3831 /* Let the transmit ISR take care of this (since it 3763 /* Let the transmit ISR take care of this (since it
3832 requires stuffing characters into the output stream). 3764 requires stuffing characters into the output stream).
3833 */ 3765 */
@@ -3835,18 +3767,18 @@ static void cy_break(struct tty_struct *tty, int break_state)
3835 if (!info->breakon) { 3767 if (!info->breakon) {
3836 info->breakon = 1; 3768 info->breakon = 1;
3837 if (!info->xmit_cnt) { 3769 if (!info->xmit_cnt) {
3838 CY_UNLOCK(info, flags); 3770 spin_unlock_irqrestore(&card->card_lock, flags);
3839 start_xmit(info); 3771 start_xmit(info);
3840 CY_LOCK(info, flags); 3772 spin_lock_irqsave(&card->card_lock, flags);
3841 } 3773 }
3842 } 3774 }
3843 } else { 3775 } else {
3844 if (!info->breakoff) { 3776 if (!info->breakoff) {
3845 info->breakoff = 1; 3777 info->breakoff = 1;
3846 if (!info->xmit_cnt) { 3778 if (!info->xmit_cnt) {
3847 CY_UNLOCK(info, flags); 3779 spin_unlock_irqrestore(&card->card_lock, flags);
3848 start_xmit(info); 3780 start_xmit(info);
3849 CY_LOCK(info, flags); 3781 spin_lock_irqsave(&card->card_lock, flags);
3850 } 3782 }
3851 } 3783 }
3852 } 3784 }
@@ -3854,24 +3786,25 @@ static void cy_break(struct tty_struct *tty, int break_state)
3854 int retval; 3786 int retval;
3855 3787
3856 if (break_state == -1) { 3788 if (break_state == -1) {
3857 retval = cyz_issue_cmd(&cy_card[info->card], 3789 retval = cyz_issue_cmd(card,
3858 info->line - cy_card[info->card].first_line, 3790 info->line - card->first_line,
3859 C_CM_SET_BREAK, 0L); 3791 C_CM_SET_BREAK, 0L);
3860 if (retval != 0) { 3792 if (retval != 0) {
3861 printk("cyc:cy_break (set) retval on ttyC%d " 3793 printk(KERN_ERR "cyc:cy_break (set) retval on "
3862 "was %x\n", info->line, retval); 3794 "ttyC%d was %x\n", info->line, retval);
3863 } 3795 }
3864 } else { 3796 } else {
3865 retval = cyz_issue_cmd(&cy_card[info->card], 3797 retval = cyz_issue_cmd(card,
3866 info->line - cy_card[info->card].first_line, 3798 info->line - card->first_line,
3867 C_CM_CLR_BREAK, 0L); 3799 C_CM_CLR_BREAK, 0L);
3868 if (retval != 0) { 3800 if (retval != 0) {
3869 printk("cyc:cy_break (clr) retval on ttyC%d " 3801 printk(KERN_DEBUG "cyc:cy_break (clr) retval "
3870 "was %x\n", info->line, retval); 3802 "on ttyC%d was %x\n", info->line,
3803 retval);
3871 } 3804 }
3872 } 3805 }
3873 } 3806 }
3874 CY_UNLOCK(info, flags); 3807 spin_unlock_irqrestore(&card->card_lock, flags);
3875} /* cy_break */ 3808} /* cy_break */
3876 3809
3877static int 3810static int
@@ -3889,28 +3822,27 @@ get_mon_info(struct cyclades_port *info, struct cyclades_monitor __user * mon)
3889 3822
3890static int set_threshold(struct cyclades_port *info, unsigned long value) 3823static int set_threshold(struct cyclades_port *info, unsigned long value)
3891{ 3824{
3825 struct cyclades_card *card;
3892 void __iomem *base_addr; 3826 void __iomem *base_addr;
3893 int card, channel, chip, index; 3827 int channel, chip, index;
3894 unsigned long flags; 3828 unsigned long flags;
3895 3829
3896 card = info->card; 3830 card = info->card;
3897 channel = info->line - cy_card[card].first_line; 3831 channel = info->line - card->first_line;
3898 if (!IS_CYC_Z(cy_card[card])) { 3832 if (!IS_CYC_Z(*card)) {
3899 chip = channel >> 2; 3833 chip = channel >> 2;
3900 channel &= 0x03; 3834 channel &= 0x03;
3901 index = cy_card[card].bus_index; 3835 index = card->bus_index;
3902 base_addr = 3836 base_addr =
3903 cy_card[card].base_addr + (cy_chip_offset[chip] << index); 3837 card->base_addr + (cy_chip_offset[chip] << index);
3904 3838
3905 info->cor3 &= ~CyREC_FIFO; 3839 info->cor3 &= ~CyREC_FIFO;
3906 info->cor3 |= value & CyREC_FIFO; 3840 info->cor3 |= value & CyREC_FIFO;
3907 3841
3908 CY_LOCK(info, flags); 3842 spin_lock_irqsave(&card->card_lock, flags);
3909 cy_writeb(base_addr + (CyCOR3 << index), info->cor3); 3843 cy_writeb(base_addr + (CyCOR3 << index), info->cor3);
3910 cyy_issue_cmd(base_addr, CyCOR_CHANGE | CyCOR3ch, index); 3844 cyy_issue_cmd(base_addr, CyCOR_CHANGE | CyCOR3ch, index);
3911 CY_UNLOCK(info, flags); 3845 spin_unlock_irqrestore(&card->card_lock, flags);
3912 } else {
3913 /* Nothing to do! */
3914 } 3846 }
3915 return 0; 3847 return 0;
3916} /* set_threshold */ 3848} /* set_threshold */
@@ -3918,25 +3850,23 @@ static int set_threshold(struct cyclades_port *info, unsigned long value)
3918static int 3850static int
3919get_threshold(struct cyclades_port *info, unsigned long __user * value) 3851get_threshold(struct cyclades_port *info, unsigned long __user * value)
3920{ 3852{
3853 struct cyclades_card *card;
3921 void __iomem *base_addr; 3854 void __iomem *base_addr;
3922 int card, channel, chip, index; 3855 int channel, chip, index;
3923 unsigned long tmp; 3856 unsigned long tmp;
3924 3857
3925 card = info->card; 3858 card = info->card;
3926 channel = info->line - cy_card[card].first_line; 3859 channel = info->line - card->first_line;
3927 if (!IS_CYC_Z(cy_card[card])) { 3860 if (!IS_CYC_Z(*card)) {
3928 chip = channel >> 2; 3861 chip = channel >> 2;
3929 channel &= 0x03; 3862 channel &= 0x03;
3930 index = cy_card[card].bus_index; 3863 index = card->bus_index;
3931 base_addr = 3864 base_addr = card->base_addr + (cy_chip_offset[chip] << index);
3932 cy_card[card].base_addr + (cy_chip_offset[chip] << index);
3933 3865
3934 tmp = cy_readb(base_addr + (CyCOR3 << index)) & CyREC_FIFO; 3866 tmp = readb(base_addr + (CyCOR3 << index)) & CyREC_FIFO;
3935 return put_user(tmp, value); 3867 return put_user(tmp, value);
3936 } else {
3937 /* Nothing to do! */
3938 return 0;
3939 } 3868 }
3869 return 0;
3940} /* get_threshold */ 3870} /* get_threshold */
3941 3871
3942static int 3872static int
@@ -3954,49 +3884,45 @@ get_default_threshold(struct cyclades_port *info, unsigned long __user * value)
3954 3884
3955static int set_timeout(struct cyclades_port *info, unsigned long value) 3885static int set_timeout(struct cyclades_port *info, unsigned long value)
3956{ 3886{
3887 struct cyclades_card *card;
3957 void __iomem *base_addr; 3888 void __iomem *base_addr;
3958 int card, channel, chip, index; 3889 int channel, chip, index;
3959 unsigned long flags; 3890 unsigned long flags;
3960 3891
3961 card = info->card; 3892 card = info->card;
3962 channel = info->line - cy_card[card].first_line; 3893 channel = info->line - card->first_line;
3963 if (!IS_CYC_Z(cy_card[card])) { 3894 if (!IS_CYC_Z(*card)) {
3964 chip = channel >> 2; 3895 chip = channel >> 2;
3965 channel &= 0x03; 3896 channel &= 0x03;
3966 index = cy_card[card].bus_index; 3897 index = card->bus_index;
3967 base_addr = 3898 base_addr = card->base_addr + (cy_chip_offset[chip] << index);
3968 cy_card[card].base_addr + (cy_chip_offset[chip] << index);
3969 3899
3970 CY_LOCK(info, flags); 3900 spin_lock_irqsave(&card->card_lock, flags);
3971 cy_writeb(base_addr + (CyRTPR << index), value & 0xff); 3901 cy_writeb(base_addr + (CyRTPR << index), value & 0xff);
3972 CY_UNLOCK(info, flags); 3902 spin_unlock_irqrestore(&card->card_lock, flags);
3973 } else {
3974 /* Nothing to do! */
3975 } 3903 }
3976 return 0; 3904 return 0;
3977} /* set_timeout */ 3905} /* set_timeout */
3978 3906
3979static int get_timeout(struct cyclades_port *info, unsigned long __user * value) 3907static int get_timeout(struct cyclades_port *info, unsigned long __user * value)
3980{ 3908{
3909 struct cyclades_card *card;
3981 void __iomem *base_addr; 3910 void __iomem *base_addr;
3982 int card, channel, chip, index; 3911 int channel, chip, index;
3983 unsigned long tmp; 3912 unsigned long tmp;
3984 3913
3985 card = info->card; 3914 card = info->card;
3986 channel = info->line - cy_card[card].first_line; 3915 channel = info->line - card->first_line;
3987 if (!IS_CYC_Z(cy_card[card])) { 3916 if (!IS_CYC_Z(*card)) {
3988 chip = channel >> 2; 3917 chip = channel >> 2;
3989 channel &= 0x03; 3918 channel &= 0x03;
3990 index = cy_card[card].bus_index; 3919 index = card->bus_index;
3991 base_addr = 3920 base_addr = card->base_addr + (cy_chip_offset[chip] << index);
3992 cy_card[card].base_addr + (cy_chip_offset[chip] << index);
3993 3921
3994 tmp = cy_readb(base_addr + (CyRTPR << index)); 3922 tmp = readb(base_addr + (CyRTPR << index));
3995 return put_user(tmp, value); 3923 return put_user(tmp, value);
3996 } else {
3997 /* Nothing to do! */
3998 return 0;
3999 } 3924 }
3925 return 0;
4000} /* get_timeout */ 3926} /* get_timeout */
4001 3927
4002static int set_default_timeout(struct cyclades_port *info, unsigned long value) 3928static int set_default_timeout(struct cyclades_port *info, unsigned long value)
@@ -4020,7 +3946,7 @@ static int
4020cy_ioctl(struct tty_struct *tty, struct file *file, 3946cy_ioctl(struct tty_struct *tty, struct file *file,
4021 unsigned int cmd, unsigned long arg) 3947 unsigned int cmd, unsigned long arg)
4022{ 3948{
4023 struct cyclades_port *info = (struct cyclades_port *)tty->driver_data; 3949 struct cyclades_port *info = tty->driver_data;
4024 struct cyclades_icount cprev, cnow; /* kernel counter temps */ 3950 struct cyclades_icount cprev, cnow; /* kernel counter temps */
4025 struct serial_icounter_struct __user *p_cuser; /* user space */ 3951 struct serial_icounter_struct __user *p_cuser; /* user space */
4026 int ret_val = 0; 3952 int ret_val = 0;
@@ -4031,7 +3957,8 @@ cy_ioctl(struct tty_struct *tty, struct file *file,
4031 return -ENODEV; 3957 return -ENODEV;
4032 3958
4033#ifdef CY_DEBUG_OTHER 3959#ifdef CY_DEBUG_OTHER
4034 printk("cyc:cy_ioctl ttyC%d, cmd = %x arg = %lx\n", info->line, cmd, arg); /* */ 3960 printk(KERN_DEBUG "cyc:cy_ioctl ttyC%d, cmd = %x arg = %lx\n",
3961 info->line, cmd, arg);
4035#endif 3962#endif
4036 3963
4037 switch (cmd) { 3964 switch (cmd) {
@@ -4076,14 +4003,6 @@ cy_ioctl(struct tty_struct *tty, struct file *file,
4076 case CYGETRTSDTR_INV: 4003 case CYGETRTSDTR_INV:
4077 ret_val = info->rtsdtr_inv; 4004 ret_val = info->rtsdtr_inv;
4078 break; 4005 break;
4079 case CYGETCARDINFO:
4080 if (copy_to_user(argp, &cy_card[info->card],
4081 sizeof(struct cyclades_card))) {
4082 ret_val = -EFAULT;
4083 break;
4084 }
4085 ret_val = 0;
4086 break;
4087 case CYGETCD1400VER: 4006 case CYGETCD1400VER:
4088 ret_val = info->chip_rev; 4007 ret_val = info->chip_rev;
4089 break; 4008 break;
@@ -4119,34 +4038,22 @@ cy_ioctl(struct tty_struct *tty, struct file *file,
4119 * Caller should use TIOCGICOUNT to see which one it was 4038 * Caller should use TIOCGICOUNT to see which one it was
4120 */ 4039 */
4121 case TIOCMIWAIT: 4040 case TIOCMIWAIT:
4122 CY_LOCK(info, flags); 4041 spin_lock_irqsave(&info->card->card_lock, flags);
4123 /* note the counters on entry */ 4042 /* note the counters on entry */
4124 cprev = info->icount; 4043 cnow = info->icount;
4125 CY_UNLOCK(info, flags); 4044 spin_unlock_irqrestore(&info->card->card_lock, flags);
4126 while (1) { 4045 ret_val = wait_event_interruptible(info->delta_msr_wait, ({
4127 interruptible_sleep_on(&info->delta_msr_wait); 4046 cprev = cnow;
4128 /* see if a signal did it */ 4047 spin_lock_irqsave(&info->card->card_lock, flags);
4129 if (signal_pending(current)) {
4130 return -ERESTARTSYS;
4131 }
4132
4133 CY_LOCK(info, flags);
4134 cnow = info->icount; /* atomic copy */ 4048 cnow = info->icount; /* atomic copy */
4135 CY_UNLOCK(info, flags); 4049 spin_unlock_irqrestore(&info->card->card_lock, flags);
4136 4050
4137 if (cnow.rng == cprev.rng && cnow.dsr == cprev.dsr && 4051 ((arg & TIOCM_RNG) && (cnow.rng != cprev.rng)) ||
4138 cnow.dcd == cprev.dcd && cnow.cts == cprev.cts) { 4052 ((arg & TIOCM_DSR) && (cnow.dsr != cprev.dsr)) ||
4139 return -EIO; /* no change => error */ 4053 ((arg & TIOCM_CD) && (cnow.dcd != cprev.dcd)) ||
4140 } 4054 ((arg & TIOCM_CTS) && (cnow.cts != cprev.cts));
4141 if (((arg & TIOCM_RNG) && (cnow.rng != cprev.rng)) || 4055 }));
4142 ((arg & TIOCM_DSR) && (cnow.dsr != cprev.dsr)) || 4056 break;
4143 ((arg & TIOCM_CD) && (cnow.dcd != cprev.dcd)) ||
4144 ((arg & TIOCM_CTS) && (cnow.cts != cprev.cts))) {
4145 return 0;
4146 }
4147 cprev = cnow;
4148 }
4149 /* NOTREACHED */
4150 4057
4151 /* 4058 /*
4152 * Get counter of input serial line interrupts (DCD,RI,DSR,CTS) 4059 * Get counter of input serial line interrupts (DCD,RI,DSR,CTS)
@@ -4155,9 +4062,9 @@ cy_ioctl(struct tty_struct *tty, struct file *file,
4155 * RI where only 0->1 is counted. 4062 * RI where only 0->1 is counted.
4156 */ 4063 */
4157 case TIOCGICOUNT: 4064 case TIOCGICOUNT:
4158 CY_LOCK(info, flags); 4065 spin_lock_irqsave(&info->card->card_lock, flags);
4159 cnow = info->icount; 4066 cnow = info->icount;
4160 CY_UNLOCK(info, flags); 4067 spin_unlock_irqrestore(&info->card->card_lock, flags);
4161 p_cuser = argp; 4068 p_cuser = argp;
4162 ret_val = put_user(cnow.cts, &p_cuser->cts); 4069 ret_val = put_user(cnow.cts, &p_cuser->cts);
4163 if (ret_val) 4070 if (ret_val)
@@ -4199,7 +4106,7 @@ cy_ioctl(struct tty_struct *tty, struct file *file,
4199 } 4106 }
4200 4107
4201#ifdef CY_DEBUG_OTHER 4108#ifdef CY_DEBUG_OTHER
4202 printk(" cyc:cy_ioctl done\n"); 4109 printk(KERN_DEBUG "cyc:cy_ioctl done\n");
4203#endif 4110#endif
4204 4111
4205 return ret_val; 4112 return ret_val;
@@ -4213,10 +4120,10 @@ cy_ioctl(struct tty_struct *tty, struct file *file,
4213 */ 4120 */
4214static void cy_set_termios(struct tty_struct *tty, struct ktermios *old_termios) 4121static void cy_set_termios(struct tty_struct *tty, struct ktermios *old_termios)
4215{ 4122{
4216 struct cyclades_port *info = (struct cyclades_port *)tty->driver_data; 4123 struct cyclades_port *info = tty->driver_data;
4217 4124
4218#ifdef CY_DEBUG_OTHER 4125#ifdef CY_DEBUG_OTHER
4219 printk("cyc:cy_set_termios ttyC%d\n", info->line); 4126 printk(KERN_DEBUG "cyc:cy_set_termios ttyC%d\n", info->line);
4220#endif 4127#endif
4221 4128
4222 if (tty->termios->c_cflag == old_termios->c_cflag && 4129 if (tty->termios->c_cflag == old_termios->c_cflag &&
@@ -4248,8 +4155,9 @@ static void cy_set_termios(struct tty_struct *tty, struct ktermios *old_termios)
4248*/ 4155*/
4249static void cy_send_xchar(struct tty_struct *tty, char ch) 4156static void cy_send_xchar(struct tty_struct *tty, char ch)
4250{ 4157{
4251 struct cyclades_port *info = (struct cyclades_port *)tty->driver_data; 4158 struct cyclades_port *info = tty->driver_data;
4252 int card, channel; 4159 struct cyclades_card *card;
4160 int channel;
4253 4161
4254 if (serial_paranoia_check(info, tty->name, "cy_send_xchar")) 4162 if (serial_paranoia_check(info, tty->name, "cy_send_xchar"))
4255 return; 4163 return;
@@ -4260,15 +4168,13 @@ static void cy_send_xchar(struct tty_struct *tty, char ch)
4260 cy_start(tty); 4168 cy_start(tty);
4261 4169
4262 card = info->card; 4170 card = info->card;
4263 channel = info->line - cy_card[card].first_line; 4171 channel = info->line - card->first_line;
4264 4172
4265 if (IS_CYC_Z(cy_card[card])) { 4173 if (IS_CYC_Z(*card)) {
4266 if (ch == STOP_CHAR(tty)) 4174 if (ch == STOP_CHAR(tty))
4267 cyz_issue_cmd(&cy_card[card], channel, C_CM_SENDXOFF, 4175 cyz_issue_cmd(card, channel, C_CM_SENDXOFF, 0L);
4268 0L);
4269 else if (ch == START_CHAR(tty)) 4176 else if (ch == START_CHAR(tty))
4270 cyz_issue_cmd(&cy_card[card], channel, C_CM_SENDXON, 4177 cyz_issue_cmd(card, channel, C_CM_SENDXON, 0L);
4271 0L);
4272 } 4178 }
4273} 4179}
4274 4180
@@ -4278,15 +4184,16 @@ static void cy_send_xchar(struct tty_struct *tty, char ch)
4278 */ 4184 */
4279static void cy_throttle(struct tty_struct *tty) 4185static void cy_throttle(struct tty_struct *tty)
4280{ 4186{
4281 struct cyclades_port *info = (struct cyclades_port *)tty->driver_data; 4187 struct cyclades_port *info = tty->driver_data;
4188 struct cyclades_card *card;
4282 unsigned long flags; 4189 unsigned long flags;
4283 void __iomem *base_addr; 4190 void __iomem *base_addr;
4284 int card, chip, channel, index; 4191 int chip, channel, index;
4285 4192
4286#ifdef CY_DEBUG_THROTTLE 4193#ifdef CY_DEBUG_THROTTLE
4287 char buf[64]; 4194 char buf[64];
4288 4195
4289 printk("cyc:throttle %s: %d....ttyC%d\n", tty_name(tty, buf), 4196 printk(KERN_DEBUG "cyc:throttle %s: %ld...ttyC%d\n", tty_name(tty, buf),
4290 tty->ldisc.chars_in_buffer(tty), info->line); 4197 tty->ldisc.chars_in_buffer(tty), info->line);
4291#endif 4198#endif
4292 4199
@@ -4297,22 +4204,22 @@ static void cy_throttle(struct tty_struct *tty)
4297 card = info->card; 4204 card = info->card;
4298 4205
4299 if (I_IXOFF(tty)) { 4206 if (I_IXOFF(tty)) {
4300 if (!IS_CYC_Z(cy_card[card])) 4207 if (!IS_CYC_Z(*card))
4301 cy_send_xchar(tty, STOP_CHAR(tty)); 4208 cy_send_xchar(tty, STOP_CHAR(tty));
4302 else 4209 else
4303 info->throttle = 1; 4210 info->throttle = 1;
4304 } 4211 }
4305 4212
4306 if (tty->termios->c_cflag & CRTSCTS) { 4213 if (tty->termios->c_cflag & CRTSCTS) {
4307 channel = info->line - cy_card[card].first_line; 4214 channel = info->line - card->first_line;
4308 if (!IS_CYC_Z(cy_card[card])) { 4215 if (!IS_CYC_Z(*card)) {
4309 chip = channel >> 2; 4216 chip = channel >> 2;
4310 channel &= 0x03; 4217 channel &= 0x03;
4311 index = cy_card[card].bus_index; 4218 index = card->bus_index;
4312 base_addr = cy_card[card].base_addr + 4219 base_addr = card->base_addr +
4313 (cy_chip_offset[chip] << index); 4220 (cy_chip_offset[chip] << index);
4314 4221
4315 CY_LOCK(info, flags); 4222 spin_lock_irqsave(&card->card_lock, flags);
4316 cy_writeb(base_addr + (CyCAR << index), 4223 cy_writeb(base_addr + (CyCAR << index),
4317 (u_char) channel); 4224 (u_char) channel);
4318 if (info->rtsdtr_inv) { 4225 if (info->rtsdtr_inv) {
@@ -4322,7 +4229,7 @@ static void cy_throttle(struct tty_struct *tty)
4322 cy_writeb(base_addr + (CyMSVR1 << index), 4229 cy_writeb(base_addr + (CyMSVR1 << index),
4323 ~CyRTS); 4230 ~CyRTS);
4324 } 4231 }
4325 CY_UNLOCK(info, flags); 4232 spin_unlock_irqrestore(&card->card_lock, flags);
4326 } else { 4233 } else {
4327 info->throttle = 1; 4234 info->throttle = 1;
4328 } 4235 }
@@ -4336,16 +4243,17 @@ static void cy_throttle(struct tty_struct *tty)
4336 */ 4243 */
4337static void cy_unthrottle(struct tty_struct *tty) 4244static void cy_unthrottle(struct tty_struct *tty)
4338{ 4245{
4339 struct cyclades_port *info = (struct cyclades_port *)tty->driver_data; 4246 struct cyclades_port *info = tty->driver_data;
4247 struct cyclades_card *card;
4340 unsigned long flags; 4248 unsigned long flags;
4341 void __iomem *base_addr; 4249 void __iomem *base_addr;
4342 int card, chip, channel, index; 4250 int chip, channel, index;
4343 4251
4344#ifdef CY_DEBUG_THROTTLE 4252#ifdef CY_DEBUG_THROTTLE
4345 char buf[64]; 4253 char buf[64];
4346 4254
4347 printk("cyc:unthrottle %s: %d....ttyC%d\n", tty_name(tty, buf), 4255 printk(KERN_DEBUG "cyc:unthrottle %s: %ld...ttyC%d\n",
4348 tty->ldisc.chars_in_buffer(tty), info->line); 4256 tty_name(tty, buf), tty->ldisc.chars_in_buffer(tty),info->line);
4349#endif 4257#endif
4350 4258
4351 if (serial_paranoia_check(info, tty->name, "cy_unthrottle")) { 4259 if (serial_paranoia_check(info, tty->name, "cy_unthrottle")) {
@@ -4361,15 +4269,15 @@ static void cy_unthrottle(struct tty_struct *tty)
4361 4269
4362 if (tty->termios->c_cflag & CRTSCTS) { 4270 if (tty->termios->c_cflag & CRTSCTS) {
4363 card = info->card; 4271 card = info->card;
4364 channel = info->line - cy_card[card].first_line; 4272 channel = info->line - card->first_line;
4365 if (!IS_CYC_Z(cy_card[card])) { 4273 if (!IS_CYC_Z(*card)) {
4366 chip = channel >> 2; 4274 chip = channel >> 2;
4367 channel &= 0x03; 4275 channel &= 0x03;
4368 index = cy_card[card].bus_index; 4276 index = card->bus_index;
4369 base_addr = cy_card[card].base_addr + 4277 base_addr = card->base_addr +
4370 (cy_chip_offset[chip] << index); 4278 (cy_chip_offset[chip] << index);
4371 4279
4372 CY_LOCK(info, flags); 4280 spin_lock_irqsave(&card->card_lock, flags);
4373 cy_writeb(base_addr + (CyCAR << index), 4281 cy_writeb(base_addr + (CyCAR << index),
4374 (u_char) channel); 4282 (u_char) channel);
4375 if (info->rtsdtr_inv) { 4283 if (info->rtsdtr_inv) {
@@ -4379,7 +4287,7 @@ static void cy_unthrottle(struct tty_struct *tty)
4379 cy_writeb(base_addr + (CyMSVR1 << index), 4287 cy_writeb(base_addr + (CyMSVR1 << index),
4380 CyRTS); 4288 CyRTS);
4381 } 4289 }
4382 CY_UNLOCK(info, flags); 4290 spin_unlock_irqrestore(&card->card_lock, flags);
4383 } else { 4291 } else {
4384 info->throttle = 0; 4292 info->throttle = 0;
4385 } 4293 }
@@ -4392,102 +4300,96 @@ static void cy_unthrottle(struct tty_struct *tty)
4392static void cy_stop(struct tty_struct *tty) 4300static void cy_stop(struct tty_struct *tty)
4393{ 4301{
4394 struct cyclades_card *cinfo; 4302 struct cyclades_card *cinfo;
4395 struct cyclades_port *info = (struct cyclades_port *)tty->driver_data; 4303 struct cyclades_port *info = tty->driver_data;
4396 void __iomem *base_addr; 4304 void __iomem *base_addr;
4397 int chip, channel, index; 4305 int chip, channel, index;
4398 unsigned long flags; 4306 unsigned long flags;
4399 4307
4400#ifdef CY_DEBUG_OTHER 4308#ifdef CY_DEBUG_OTHER
4401 printk("cyc:cy_stop ttyC%d\n", info->line); /* */ 4309 printk(KERN_DEBUG "cyc:cy_stop ttyC%d\n", info->line);
4402#endif 4310#endif
4403 4311
4404 if (serial_paranoia_check(info, tty->name, "cy_stop")) 4312 if (serial_paranoia_check(info, tty->name, "cy_stop"))
4405 return; 4313 return;
4406 4314
4407 cinfo = &cy_card[info->card]; 4315 cinfo = info->card;
4408 channel = info->line - cinfo->first_line; 4316 channel = info->line - cinfo->first_line;
4409 if (!IS_CYC_Z(*cinfo)) { 4317 if (!IS_CYC_Z(*cinfo)) {
4410 index = cinfo->bus_index; 4318 index = cinfo->bus_index;
4411 chip = channel >> 2; 4319 chip = channel >> 2;
4412 channel &= 0x03; 4320 channel &= 0x03;
4413 base_addr = cy_card[info->card].base_addr + 4321 base_addr = cinfo->base_addr + (cy_chip_offset[chip] << index);
4414 (cy_chip_offset[chip] << index);
4415 4322
4416 CY_LOCK(info, flags); 4323 spin_lock_irqsave(&cinfo->card_lock, flags);
4417 cy_writeb(base_addr + (CyCAR << index), 4324 cy_writeb(base_addr + (CyCAR << index),
4418 (u_char)(channel & 0x0003)); /* index channel */ 4325 (u_char)(channel & 0x0003)); /* index channel */
4419 cy_writeb(base_addr + (CySRER << index), 4326 cy_writeb(base_addr + (CySRER << index),
4420 cy_readb(base_addr + (CySRER << index)) & ~CyTxRdy); 4327 readb(base_addr + (CySRER << index)) & ~CyTxRdy);
4421 CY_UNLOCK(info, flags); 4328 spin_unlock_irqrestore(&cinfo->card_lock, flags);
4422 } else {
4423 /* Nothing to do! */
4424 } 4329 }
4425} /* cy_stop */ 4330} /* cy_stop */
4426 4331
4427static void cy_start(struct tty_struct *tty) 4332static void cy_start(struct tty_struct *tty)
4428{ 4333{
4429 struct cyclades_card *cinfo; 4334 struct cyclades_card *cinfo;
4430 struct cyclades_port *info = (struct cyclades_port *)tty->driver_data; 4335 struct cyclades_port *info = tty->driver_data;
4431 void __iomem *base_addr; 4336 void __iomem *base_addr;
4432 int chip, channel, index; 4337 int chip, channel, index;
4433 unsigned long flags; 4338 unsigned long flags;
4434 4339
4435#ifdef CY_DEBUG_OTHER 4340#ifdef CY_DEBUG_OTHER
4436 printk("cyc:cy_start ttyC%d\n", info->line); /* */ 4341 printk(KERN_DEBUG "cyc:cy_start ttyC%d\n", info->line);
4437#endif 4342#endif
4438 4343
4439 if (serial_paranoia_check(info, tty->name, "cy_start")) 4344 if (serial_paranoia_check(info, tty->name, "cy_start"))
4440 return; 4345 return;
4441 4346
4442 cinfo = &cy_card[info->card]; 4347 cinfo = info->card;
4443 channel = info->line - cinfo->first_line; 4348 channel = info->line - cinfo->first_line;
4444 index = cinfo->bus_index; 4349 index = cinfo->bus_index;
4445 if (!IS_CYC_Z(*cinfo)) { 4350 if (!IS_CYC_Z(*cinfo)) {
4446 chip = channel >> 2; 4351 chip = channel >> 2;
4447 channel &= 0x03; 4352 channel &= 0x03;
4448 base_addr = cy_card[info->card].base_addr + 4353 base_addr = cinfo->base_addr + (cy_chip_offset[chip] << index);
4449 (cy_chip_offset[chip] << index);
4450 4354
4451 CY_LOCK(info, flags); 4355 spin_lock_irqsave(&cinfo->card_lock, flags);
4452 cy_writeb(base_addr + (CyCAR << index), (u_char) (channel & 0x0003)); /* index channel */ 4356 cy_writeb(base_addr + (CyCAR << index), (u_char) (channel & 0x0003)); /* index channel */
4453 cy_writeb(base_addr + (CySRER << index), 4357 cy_writeb(base_addr + (CySRER << index),
4454 cy_readb(base_addr + (CySRER << index)) | CyTxRdy); 4358 readb(base_addr + (CySRER << index)) | CyTxRdy);
4455 CY_UNLOCK(info, flags); 4359 spin_unlock_irqrestore(&cinfo->card_lock, flags);
4456 } else {
4457 /* Nothing to do! */
4458 } 4360 }
4459} /* cy_start */ 4361} /* cy_start */
4460 4362
4461static void cy_flush_buffer(struct tty_struct *tty) 4363static void cy_flush_buffer(struct tty_struct *tty)
4462{ 4364{
4463 struct cyclades_port *info = (struct cyclades_port *)tty->driver_data; 4365 struct cyclades_port *info = tty->driver_data;
4464 int card, channel, retval; 4366 struct cyclades_card *card;
4367 int channel, retval;
4465 unsigned long flags; 4368 unsigned long flags;
4466 4369
4467#ifdef CY_DEBUG_IO 4370#ifdef CY_DEBUG_IO
4468 printk("cyc:cy_flush_buffer ttyC%d\n", info->line); /* */ 4371 printk(KERN_DEBUG "cyc:cy_flush_buffer ttyC%d\n", info->line);
4469#endif 4372#endif
4470 4373
4471 if (serial_paranoia_check(info, tty->name, "cy_flush_buffer")) 4374 if (serial_paranoia_check(info, tty->name, "cy_flush_buffer"))
4472 return; 4375 return;
4473 4376
4474 card = info->card; 4377 card = info->card;
4475 channel = (info->line) - (cy_card[card].first_line); 4378 channel = info->line - card->first_line;
4476 4379
4477 CY_LOCK(info, flags); 4380 spin_lock_irqsave(&card->card_lock, flags);
4478 info->xmit_cnt = info->xmit_head = info->xmit_tail = 0; 4381 info->xmit_cnt = info->xmit_head = info->xmit_tail = 0;
4479 CY_UNLOCK(info, flags); 4382 spin_unlock_irqrestore(&card->card_lock, flags);
4480 4383
4481 if (IS_CYC_Z(cy_card[card])) { /* If it is a Z card, flush the on-board 4384 if (IS_CYC_Z(*card)) { /* If it is a Z card, flush the on-board
4482 buffers as well */ 4385 buffers as well */
4483 CY_LOCK(info, flags); 4386 spin_lock_irqsave(&card->card_lock, flags);
4484 retval = 4387 retval = cyz_issue_cmd(card, channel, C_CM_FLUSH_TX, 0L);
4485 cyz_issue_cmd(&cy_card[card], channel, C_CM_FLUSH_TX, 0L);
4486 if (retval != 0) { 4388 if (retval != 0) {
4487 printk("cyc: flush_buffer retval on ttyC%d was %x\n", 4389 printk(KERN_ERR "cyc: flush_buffer retval on ttyC%d "
4488 info->line, retval); 4390 "was %x\n", info->line, retval);
4489 } 4391 }
4490 CY_UNLOCK(info, flags); 4392 spin_unlock_irqrestore(&card->card_lock, flags);
4491 } 4393 }
4492 tty_wakeup(tty); 4394 tty_wakeup(tty);
4493} /* cy_flush_buffer */ 4395} /* cy_flush_buffer */
@@ -4497,10 +4399,10 @@ static void cy_flush_buffer(struct tty_struct *tty)
4497 */ 4399 */
4498static void cy_hangup(struct tty_struct *tty) 4400static void cy_hangup(struct tty_struct *tty)
4499{ 4401{
4500 struct cyclades_port *info = (struct cyclades_port *)tty->driver_data; 4402 struct cyclades_port *info = tty->driver_data;
4501 4403
4502#ifdef CY_DEBUG_OTHER 4404#ifdef CY_DEBUG_OTHER
4503 printk("cyc:cy_hangup ttyC%d\n", info->line); /* */ 4405 printk(KERN_DEBUG "cyc:cy_hangup ttyC%d\n", info->line);
4504#endif 4406#endif
4505 4407
4506 if (serial_paranoia_check(info, tty->name, "cy_hangup")) 4408 if (serial_paranoia_check(info, tty->name, "cy_hangup"))
@@ -4511,7 +4413,8 @@ static void cy_hangup(struct tty_struct *tty)
4511 info->event = 0; 4413 info->event = 0;
4512 info->count = 0; 4414 info->count = 0;
4513#ifdef CY_DEBUG_COUNT 4415#ifdef CY_DEBUG_COUNT
4514 printk("cyc:cy_hangup (%d): setting count to 0\n", current->pid); 4416 printk(KERN_DEBUG "cyc:cy_hangup (%d): setting count to 0\n",
4417 current->pid);
4515#endif 4418#endif
4516 info->tty = NULL; 4419 info->tty = NULL;
4517 info->flags &= ~ASYNC_NORMAL_ACTIVE; 4420 info->flags &= ~ASYNC_NORMAL_ACTIVE;
@@ -4526,10 +4429,107 @@ static void cy_hangup(struct tty_struct *tty)
4526 * --------------------------------------------------------------------- 4429 * ---------------------------------------------------------------------
4527 */ 4430 */
4528 4431
4432static int __devinit cy_init_card(struct cyclades_card *cinfo)
4433{
4434 struct cyclades_port *info;
4435 u32 mailbox;
4436 unsigned int nports;
4437 unsigned short chip_number;
4438 int index, port;
4439
4440 spin_lock_init(&cinfo->card_lock);
4441
4442 if (IS_CYC_Z(*cinfo)) { /* Cyclades-Z */
4443 mailbox = readl(&((struct RUNTIME_9060 __iomem *)
4444 cinfo->ctl_addr)->mail_box_0);
4445 nports = (mailbox == ZE_V1) ? ZE_V1_NPORTS : 8;
4446 cinfo->intr_enabled = 0;
4447 cinfo->nports = 0; /* Will be correctly set later, after
4448 Z FW is loaded */
4449 } else {
4450 index = cinfo->bus_index;
4451 nports = cinfo->nports = CyPORTS_PER_CHIP * cinfo->num_chips;
4452 }
4453
4454 cinfo->ports = kzalloc(sizeof(*cinfo->ports) * nports, GFP_KERNEL);
4455 if (cinfo->ports == NULL) {
4456 printk(KERN_ERR "Cyclades: cannot allocate ports\n");
4457 cinfo->nports = 0;
4458 return -ENOMEM;
4459 }
4460
4461 for (port = cinfo->first_line; port < cinfo->first_line + nports;
4462 port++) {
4463 info = &cinfo->ports[port - cinfo->first_line];
4464 info->magic = CYCLADES_MAGIC;
4465 info->card = cinfo;
4466 info->line = port;
4467 info->flags = STD_COM_FLAGS;
4468 info->closing_wait = CLOSING_WAIT_DELAY;
4469 info->close_delay = 5 * HZ / 10;
4470
4471 INIT_WORK(&info->tqueue, do_softint);
4472 init_waitqueue_head(&info->open_wait);
4473 init_waitqueue_head(&info->close_wait);
4474 init_completion(&info->shutdown_wait);
4475 init_waitqueue_head(&info->delta_msr_wait);
4476
4477 if (IS_CYC_Z(*cinfo)) {
4478 info->type = PORT_STARTECH;
4479 if (mailbox == ZO_V1)
4480 info->xmit_fifo_size = CYZ_FIFO_SIZE;
4481 else
4482 info->xmit_fifo_size = 4 * CYZ_FIFO_SIZE;
4483#ifdef CONFIG_CYZ_INTR
4484 setup_timer(&cyz_rx_full_timer[port],
4485 cyz_rx_restart, (unsigned long)info);
4486#endif
4487 } else {
4488 info->type = PORT_CIRRUS;
4489 info->xmit_fifo_size = CyMAX_CHAR_FIFO;
4490 info->cor1 = CyPARITY_NONE | Cy_1_STOP | Cy_8_BITS;
4491 info->cor2 = CyETC;
4492 info->cor3 = 0x08; /* _very_ small rcv threshold */
4493
4494 chip_number = (port - cinfo->first_line) / 4;
4495 if ((info->chip_rev = readb(cinfo->base_addr +
4496 (cy_chip_offset[chip_number] <<
4497 index) + (CyGFRCR << index))) >=
4498 CD1400_REV_J) {
4499 /* It is a CD1400 rev. J or later */
4500 info->tbpr = baud_bpr_60[13]; /* Tx BPR */
4501 info->tco = baud_co_60[13]; /* Tx CO */
4502 info->rbpr = baud_bpr_60[13]; /* Rx BPR */
4503 info->rco = baud_co_60[13]; /* Rx CO */
4504 info->rtsdtr_inv = 1;
4505 } else {
4506 info->tbpr = baud_bpr_25[13]; /* Tx BPR */
4507 info->tco = baud_co_25[13]; /* Tx CO */
4508 info->rbpr = baud_bpr_25[13]; /* Rx BPR */
4509 info->rco = baud_co_25[13]; /* Rx CO */
4510 info->rtsdtr_inv = 0;
4511 }
4512 info->read_status_mask = CyTIMEOUT | CySPECHAR |
4513 CyBREAK | CyPARITY | CyFRAME | CyOVERRUN;
4514 }
4515
4516 }
4517
4518#ifndef CONFIG_CYZ_INTR
4519 if (IS_CYC_Z(*cinfo) && !timer_pending(&cyz_timerlist)) {
4520 mod_timer(&cyz_timerlist, jiffies + 1);
4521#ifdef CY_PCI_DEBUG
4522 printk(KERN_DEBUG "Cyclades-Z polling initialized\n");
4523#endif
4524 }
4525#endif
4526 return 0;
4527}
4528
4529/* initialize chips on Cyclom-Y card -- return number of valid 4529/* initialize chips on Cyclom-Y card -- return number of valid
4530 chips (which is number of ports/4) */ 4530 chips (which is number of ports/4) */
4531static unsigned short __init 4531static unsigned short __devinit cyy_init_card(void __iomem *true_base_addr,
4532cyy_init_card(void __iomem * true_base_addr, int index) 4532 int index)
4533{ 4533{
4534 unsigned int chip_number; 4534 unsigned int chip_number;
4535 void __iomem *base_addr; 4535 void __iomem *base_addr;
@@ -4544,7 +4544,7 @@ cyy_init_card(void __iomem * true_base_addr, int index)
4544 base_addr = 4544 base_addr =
4545 true_base_addr + (cy_chip_offset[chip_number] << index); 4545 true_base_addr + (cy_chip_offset[chip_number] << index);
4546 mdelay(1); 4546 mdelay(1);
4547 if (cy_readb(base_addr + (CyCCR << index)) != 0x00) { 4547 if (readb(base_addr + (CyCCR << index)) != 0x00) {
4548 /************* 4548 /*************
4549 printk(" chip #%d at %#6lx is never idle (CCR != 0)\n", 4549 printk(" chip #%d at %#6lx is never idle (CCR != 0)\n",
4550 chip_number, (unsigned long)base_addr); 4550 chip_number, (unsigned long)base_addr);
@@ -4561,7 +4561,7 @@ cyy_init_card(void __iomem * true_base_addr, int index)
4561 chip 4 GFRCR register appears at chip 0, there is no chip 4 4561 chip 4 GFRCR register appears at chip 0, there is no chip 4
4562 and this must be a Cyclom-16Y, not a Cyclom-32Ye. 4562 and this must be a Cyclom-16Y, not a Cyclom-32Ye.
4563 */ 4563 */
4564 if (chip_number == 4 && cy_readb(true_base_addr + 4564 if (chip_number == 4 && readb(true_base_addr +
4565 (cy_chip_offset[0] << index) + 4565 (cy_chip_offset[0] << index) +
4566 (CyGFRCR << index)) == 0) { 4566 (CyGFRCR << index)) == 0) {
4567 return chip_number; 4567 return chip_number;
@@ -4570,7 +4570,7 @@ cyy_init_card(void __iomem * true_base_addr, int index)
4570 cy_writeb(base_addr + (CyCCR << index), CyCHIP_RESET); 4570 cy_writeb(base_addr + (CyCCR << index), CyCHIP_RESET);
4571 mdelay(1); 4571 mdelay(1);
4572 4572
4573 if (cy_readb(base_addr + (CyGFRCR << index)) == 0x00) { 4573 if (readb(base_addr + (CyGFRCR << index)) == 0x00) {
4574 /* 4574 /*
4575 printk(" chip #%d at %#6lx is not responding ", 4575 printk(" chip #%d at %#6lx is not responding ",
4576 chip_number, (unsigned long)base_addr); 4576 chip_number, (unsigned long)base_addr);
@@ -4578,7 +4578,7 @@ cyy_init_card(void __iomem * true_base_addr, int index)
4578 */ 4578 */
4579 return chip_number; 4579 return chip_number;
4580 } 4580 }
4581 if ((0xf0 & (cy_readb(base_addr + (CyGFRCR << index)))) != 4581 if ((0xf0 & (readb(base_addr + (CyGFRCR << index)))) !=
4582 0x40) { 4582 0x40) {
4583 /* 4583 /*
4584 printk(" chip #%d at %#6lx is not valid (GFRCR == " 4584 printk(" chip #%d at %#6lx is not valid (GFRCR == "
@@ -4589,7 +4589,7 @@ cyy_init_card(void __iomem * true_base_addr, int index)
4589 return chip_number; 4589 return chip_number;
4590 } 4590 }
4591 cy_writeb(base_addr + (CyGCR << index), CyCH0_SERIAL); 4591 cy_writeb(base_addr + (CyGCR << index), CyCH0_SERIAL);
4592 if (cy_readb(base_addr + (CyGFRCR << index)) >= CD1400_REV_J) { 4592 if (readb(base_addr + (CyGFRCR << index)) >= CD1400_REV_J) {
4593 /* It is a CD1400 rev. J or later */ 4593 /* It is a CD1400 rev. J or later */
4594 /* Impossible to reach 5ms with this chip. 4594 /* Impossible to reach 5ms with this chip.
4595 Changed to 2ms instead (f = 500 Hz). */ 4595 Changed to 2ms instead (f = 500 Hz). */
@@ -4602,7 +4602,7 @@ cyy_init_card(void __iomem * true_base_addr, int index)
4602 /* 4602 /*
4603 printk(" chip #%d at %#6lx is rev 0x%2x\n", 4603 printk(" chip #%d at %#6lx is rev 0x%2x\n",
4604 chip_number, (unsigned long)base_addr, 4604 chip_number, (unsigned long)base_addr,
4605 cy_readb(base_addr+(CyGFRCR<<index))); 4605 readb(base_addr+(CyGFRCR<<index)));
4606 */ 4606 */
4607 } 4607 }
4608 return chip_number; 4608 return chip_number;
@@ -4647,9 +4647,15 @@ static int __init cy_detect_isa(void)
4647 4647
4648 /* probe for CD1400... */ 4648 /* probe for CD1400... */
4649 cy_isa_address = ioremap(isa_address, CyISA_Ywin); 4649 cy_isa_address = ioremap(isa_address, CyISA_Ywin);
4650 if (cy_isa_address == NULL) {
4651 printk(KERN_ERR "Cyclom-Y/ISA: can't remap base "
4652 "address\n");
4653 continue;
4654 }
4650 cy_isa_nchan = CyPORTS_PER_CHIP * 4655 cy_isa_nchan = CyPORTS_PER_CHIP *
4651 cyy_init_card(cy_isa_address, 0); 4656 cyy_init_card(cy_isa_address, 0);
4652 if (cy_isa_nchan == 0) { 4657 if (cy_isa_nchan == 0) {
4658 iounmap(cy_isa_address);
4653 continue; 4659 continue;
4654 } 4660 }
4655#ifdef MODULE 4661#ifdef MODULE
@@ -4660,40 +4666,42 @@ static int __init cy_detect_isa(void)
4660 /* find out the board's irq by probing */ 4666 /* find out the board's irq by probing */
4661 cy_isa_irq = detect_isa_irq(cy_isa_address); 4667 cy_isa_irq = detect_isa_irq(cy_isa_address);
4662 if (cy_isa_irq == 0) { 4668 if (cy_isa_irq == 0) {
4663 printk("Cyclom-Y/ISA found at 0x%lx ", 4669 printk(KERN_ERR "Cyclom-Y/ISA found at 0x%lx, but the "
4670 "IRQ could not be detected.\n",
4664 (unsigned long)cy_isa_address); 4671 (unsigned long)cy_isa_address);
4665 printk("but the IRQ could not be detected.\n"); 4672 iounmap(cy_isa_address);
4666 continue; 4673 continue;
4667 } 4674 }
4668 4675
4669 if ((cy_next_channel + cy_isa_nchan) > NR_PORTS) { 4676 if ((cy_next_channel + cy_isa_nchan) > NR_PORTS) {
4670 printk("Cyclom-Y/ISA found at 0x%lx ", 4677 printk(KERN_ERR "Cyclom-Y/ISA found at 0x%lx, but no "
4678 "more channels are available. Change NR_PORTS "
4679 "in cyclades.c and recompile kernel.\n",
4671 (unsigned long)cy_isa_address); 4680 (unsigned long)cy_isa_address);
4672 printk("but no more channels are available.\n"); 4681 iounmap(cy_isa_address);
4673 printk("Change NR_PORTS in cyclades.c and recompile "
4674 "kernel.\n");
4675 return nboard; 4682 return nboard;
4676 } 4683 }
4677 /* fill the next cy_card structure available */ 4684 /* fill the next cy_card structure available */
4678 for (j = 0; j < NR_CARDS; j++) { 4685 for (j = 0; j < NR_CARDS; j++) {
4679 if (cy_card[j].base_addr == 0) 4686 if (cy_card[j].base_addr == NULL)
4680 break; 4687 break;
4681 } 4688 }
4682 if (j == NR_CARDS) { /* no more cy_cards available */ 4689 if (j == NR_CARDS) { /* no more cy_cards available */
4683 printk("Cyclom-Y/ISA found at 0x%lx ", 4690 printk(KERN_ERR "Cyclom-Y/ISA found at 0x%lx, but no "
4691 "more cards can be used. Change NR_CARDS in "
4692 "cyclades.c and recompile kernel.\n",
4684 (unsigned long)cy_isa_address); 4693 (unsigned long)cy_isa_address);
4685 printk("but no more cards can be used .\n"); 4694 iounmap(cy_isa_address);
4686 printk("Change NR_CARDS in cyclades.c and recompile "
4687 "kernel.\n");
4688 return nboard; 4695 return nboard;
4689 } 4696 }
4690 4697
4691 /* allocate IRQ */ 4698 /* allocate IRQ */
4692 if (request_irq(cy_isa_irq, cyy_interrupt, 4699 if (request_irq(cy_isa_irq, cyy_interrupt,
4693 IRQF_DISABLED, "Cyclom-Y", &cy_card[j])) { 4700 IRQF_DISABLED, "Cyclom-Y", &cy_card[j])) {
4694 printk("Cyclom-Y/ISA found at 0x%lx ", 4701 printk(KERN_ERR "Cyclom-Y/ISA found at 0x%lx, but "
4695 (unsigned long)cy_isa_address); 4702 "could not allocate IRQ#%d.\n",
4696 printk("but could not allocate IRQ#%d.\n", cy_isa_irq); 4703 (unsigned long)cy_isa_address, cy_isa_irq);
4704 iounmap(cy_isa_address);
4697 return nboard; 4705 return nboard;
4698 } 4706 }
4699 4707
@@ -4704,15 +4712,23 @@ static int __init cy_detect_isa(void)
4704 cy_card[j].bus_index = 0; 4712 cy_card[j].bus_index = 0;
4705 cy_card[j].first_line = cy_next_channel; 4713 cy_card[j].first_line = cy_next_channel;
4706 cy_card[j].num_chips = cy_isa_nchan / 4; 4714 cy_card[j].num_chips = cy_isa_nchan / 4;
4715 if (cy_init_card(&cy_card[j])) {
4716 cy_card[j].base_addr = NULL;
4717 free_irq(cy_isa_irq, &cy_card[j]);
4718 iounmap(cy_isa_address);
4719 continue;
4720 }
4707 nboard++; 4721 nboard++;
4708 4722
4709 /* print message */ 4723 printk(KERN_INFO "Cyclom-Y/ISA #%d: 0x%lx-0x%lx, IRQ%d found: "
4710 printk("Cyclom-Y/ISA #%d: 0x%lx-0x%lx, IRQ%d, ", 4724 "%d channels starting from port %d\n",
4711 j + 1, (unsigned long)cy_isa_address, 4725 j + 1, (unsigned long)cy_isa_address,
4712 (unsigned long)(cy_isa_address + (CyISA_Ywin - 1)), 4726 (unsigned long)(cy_isa_address + (CyISA_Ywin - 1)),
4713 cy_isa_irq); 4727 cy_isa_irq, cy_isa_nchan, cy_next_channel);
4714 printk("%d channels starting from port %d.\n", 4728
4715 cy_isa_nchan, cy_next_channel); 4729 for (j = cy_next_channel;
4730 j < cy_next_channel + cy_isa_nchan; j++)
4731 tty_register_device(cy_serial_driver, j, NULL);
4716 cy_next_channel += cy_isa_nchan; 4732 cy_next_channel += cy_isa_nchan;
4717 } 4733 }
4718 return nboard; 4734 return nboard;
@@ -4721,510 +4737,310 @@ static int __init cy_detect_isa(void)
4721#endif /* CONFIG_ISA */ 4737#endif /* CONFIG_ISA */
4722} /* cy_detect_isa */ 4738} /* cy_detect_isa */
4723 4739
4724static void plx_init(void __iomem * addr, uclong initctl) 4740#ifdef CONFIG_PCI
4741static void __devinit plx_init(void __iomem * addr, __u32 initctl)
4725{ 4742{
4726 /* Reset PLX */ 4743 /* Reset PLX */
4727 cy_writel(addr + initctl, cy_readl(addr + initctl) | 0x40000000); 4744 cy_writel(addr + initctl, readl(addr + initctl) | 0x40000000);
4728 udelay(100L); 4745 udelay(100L);
4729 cy_writel(addr + initctl, cy_readl(addr + initctl) & ~0x40000000); 4746 cy_writel(addr + initctl, readl(addr + initctl) & ~0x40000000);
4730 4747
4731 /* Reload Config. Registers from EEPROM */ 4748 /* Reload Config. Registers from EEPROM */
4732 cy_writel(addr + initctl, cy_readl(addr + initctl) | 0x20000000); 4749 cy_writel(addr + initctl, readl(addr + initctl) | 0x20000000);
4733 udelay(100L); 4750 udelay(100L);
4734 cy_writel(addr + initctl, cy_readl(addr + initctl) & ~0x20000000); 4751 cy_writel(addr + initctl, readl(addr + initctl) & ~0x20000000);
4735} 4752}
4736 4753
4737/* 4754static int __devinit cy_pci_probe(struct pci_dev *pdev,
4738 * --------------------------------------------------------------------- 4755 const struct pci_device_id *ent)
4739 * cy_detect_pci() - Test PCI bus presence and Cyclom-Ye/PCI.
4740 * sets global variables and return the number of PCI boards found.
4741 * ---------------------------------------------------------------------
4742 */
4743static int __init cy_detect_pci(void)
4744{ 4756{
4745#ifdef CONFIG_PCI 4757 void __iomem *addr0 = NULL, *addr2 = NULL;
4746 4758 char *card_name = NULL;
4747 struct pci_dev *pdev = NULL; 4759 u32 mailbox;
4748 unsigned char cyy_rev_id; 4760 unsigned int device_id, nchan = 0, card_no, i;
4749 unsigned char cy_pci_irq = 0; 4761 unsigned char plx_ver;
4750 uclong cy_pci_phys0, cy_pci_phys2; 4762 int retval, irq;
4751 void __iomem *cy_pci_addr0, *cy_pci_addr2; 4763
4752 unsigned short i, j, cy_pci_nchan, plx_ver; 4764 retval = pci_enable_device(pdev);
4753 unsigned short device_id, dev_index = 0; 4765 if (retval) {
4754 uclong mailbox; 4766 dev_err(&pdev->dev, "cannot enable device\n");
4755 uclong ZeIndex = 0; 4767 goto err;
4756 void __iomem *Ze_addr0[NR_CARDS], *Ze_addr2[NR_CARDS]; 4768 }
4757 uclong Ze_phys0[NR_CARDS], Ze_phys2[NR_CARDS];
4758 unsigned char Ze_irq[NR_CARDS];
4759 struct pci_dev *Ze_pdev[NR_CARDS];
4760
4761 for (i = 0; i < NR_CARDS; i++) {
4762 /* look for a Cyclades card by vendor and device id */
4763 while ((device_id = cy_pci_dev_id[dev_index].device) != 0) {
4764 if ((pdev = pci_get_device(PCI_VENDOR_ID_CYCLADES,
4765 device_id, pdev)) == NULL) {
4766 dev_index++; /* try next device id */
4767 } else {
4768 break; /* found a board */
4769 }
4770 }
4771
4772 if (device_id == 0)
4773 break;
4774
4775 if (pci_enable_device(pdev))
4776 continue;
4777
4778 /* read PCI configuration area */
4779 cy_pci_irq = pdev->irq;
4780 cy_pci_phys0 = pci_resource_start(pdev, 0);
4781 cy_pci_phys2 = pci_resource_start(pdev, 2);
4782 pci_read_config_byte(pdev, PCI_REVISION_ID, &cyy_rev_id);
4783 4769
4784 device_id &= ~PCI_DEVICE_ID_MASK; 4770 /* read PCI configuration area */
4771 irq = pdev->irq;
4772 device_id = pdev->device & ~PCI_DEVICE_ID_MASK;
4785 4773
4786 if (device_id == PCI_DEVICE_ID_CYCLOM_Y_Lo || 4774#if defined(__alpha__)
4787 device_id == PCI_DEVICE_ID_CYCLOM_Y_Hi) { 4775 if (device_id == PCI_DEVICE_ID_CYCLOM_Y_Lo) { /* below 1M? */
4788#ifdef CY_PCI_DEBUG 4776 dev_err(&pdev->dev, "Cyclom-Y/PCI not supported for low "
4789 printk("Cyclom-Y/PCI (bus=0x0%x, pci_id=0x%x, ", 4777 "addresses on Alpha systems.\n");
4790 pdev->bus->number, pdev->devfn); 4778 retval = -EIO;
4791 printk("rev_id=%d) IRQ%d\n", 4779 goto err_dis;
4792 cyy_rev_id, (int)cy_pci_irq); 4780 }
4793 printk("Cyclom-Y/PCI:found winaddr=0x%lx "
4794 "ctladdr=0x%lx\n",
4795 (ulong)cy_pci_phys2, (ulong)cy_pci_phys0);
4796#endif 4781#endif
4782 if (device_id == PCI_DEVICE_ID_CYCLOM_Z_Lo) {
4783 dev_err(&pdev->dev, "Cyclades-Z/PCI not supported for low "
4784 "addresses\n");
4785 retval = -EIO;
4786 goto err_dis;
4787 }
4797 4788
4798 if (pci_resource_flags(pdev, 2) & IORESOURCE_IO) { 4789 if (pci_resource_flags(pdev, 2) & IORESOURCE_IO) {
4799 printk(" Warning: PCI I/O bit incorrectly " 4790 dev_warn(&pdev->dev, "PCI I/O bit incorrectly set. Ignoring "
4800 "set. Ignoring it...\n"); 4791 "it...\n");
4801 pdev->resource[2].flags &= ~IORESOURCE_IO; 4792 pdev->resource[2].flags &= ~IORESOURCE_IO;
4802 } 4793 }
4803 4794
4804 /* Although we don't use this I/O region, we should 4795 retval = pci_request_regions(pdev, "cyclades");
4805 request it from the kernel anyway, to avoid problems 4796 if (retval) {
4806 with other drivers accessing it. */ 4797 dev_err(&pdev->dev, "failed to reserve resources\n");
4807 if (pci_request_regions(pdev, "Cyclom-Y") != 0) { 4798 goto err_dis;
4808 printk(KERN_ERR "cyclades: failed to reserve " 4799 }
4809 "PCI resources\n");
4810 continue;
4811 }
4812#if defined(__alpha__)
4813 if (device_id == PCI_DEVICE_ID_CYCLOM_Y_Lo) { /* below 1M? */
4814 printk("Cyclom-Y/PCI (bus=0x0%x, pci_id=0x%x, ",
4815 pdev->bus->number, pdev->devfn);
4816 printk("rev_id=%d) IRQ%d\n",
4817 cyy_rev_id, (int)cy_pci_irq);
4818 printk("Cyclom-Y/PCI:found winaddr=0x%lx "
4819 "ctladdr=0x%lx\n",
4820 (ulong)cy_pci_phys2,
4821 (ulong)cy_pci_phys0);
4822 printk("Cyclom-Y/PCI not supported for low "
4823 "addresses in Alpha systems.\n");
4824 i--;
4825 continue;
4826 }
4827#endif
4828 cy_pci_addr0 = ioremap(cy_pci_phys0, CyPCI_Yctl);
4829 cy_pci_addr2 = ioremap(cy_pci_phys2, CyPCI_Ywin);
4830 4800
4831#ifdef CY_PCI_DEBUG 4801 retval = -EIO;
4832 printk("Cyclom-Y/PCI: relocate winaddr=0x%lx " 4802 if (device_id == PCI_DEVICE_ID_CYCLOM_Y_Lo ||
4833 "ctladdr=0x%lx\n", 4803 device_id == PCI_DEVICE_ID_CYCLOM_Y_Hi) {
4834 (u_long)cy_pci_addr2, (u_long)cy_pci_addr0); 4804 card_name = "Cyclom-Y";
4835#endif
4836 cy_pci_nchan = (unsigned short)(CyPORTS_PER_CHIP *
4837 cyy_init_card(cy_pci_addr2, 1));
4838 if (cy_pci_nchan == 0) {
4839 printk("Cyclom-Y PCI host card with ");
4840 printk("no Serial-Modules at 0x%lx.\n",
4841 (ulong) cy_pci_phys2);
4842 i--;
4843 continue;
4844 }
4845 if ((cy_next_channel + cy_pci_nchan) > NR_PORTS) {
4846 printk("Cyclom-Y/PCI found at 0x%lx ",
4847 (ulong) cy_pci_phys2);
4848 printk("but no channels are available.\n");
4849 printk("Change NR_PORTS in cyclades.c and "
4850 "recompile kernel.\n");
4851 return i;
4852 }
4853 /* fill the next cy_card structure available */
4854 for (j = 0; j < NR_CARDS; j++) {
4855 if (cy_card[j].base_addr == 0)
4856 break;
4857 }
4858 if (j == NR_CARDS) { /* no more cy_cards available */
4859 printk("Cyclom-Y/PCI found at 0x%lx ",
4860 (ulong) cy_pci_phys2);
4861 printk("but no more cards can be used.\n");
4862 printk("Change NR_CARDS in cyclades.c and "
4863 "recompile kernel.\n");
4864 return i;
4865 }
4866 4805
4867 /* allocate IRQ */ 4806 addr0 = pci_iomap(pdev, 0, CyPCI_Yctl);
4868 if (request_irq(cy_pci_irq, cyy_interrupt, 4807 if (addr0 == NULL) {
4869 IRQF_SHARED, "Cyclom-Y", &cy_card[j])) { 4808 dev_err(&pdev->dev, "can't remap ctl region\n");
4870 printk("Cyclom-Y/PCI found at 0x%lx ", 4809 goto err_reg;
4871 (ulong) cy_pci_phys2); 4810 }
4872 printk("but could not allocate IRQ%d.\n", 4811 addr2 = pci_iomap(pdev, 2, CyPCI_Ywin);
4873 cy_pci_irq); 4812 if (addr2 == NULL) {
4874 return i; 4813 dev_err(&pdev->dev, "can't remap base region\n");
4875 } 4814 goto err_unmap;
4815 }
4876 4816
4877 /* set cy_card */ 4817 nchan = CyPORTS_PER_CHIP * cyy_init_card(addr2, 1);
4878 cy_card[j].base_phys = (ulong) cy_pci_phys2; 4818 if (nchan == 0) {
4879 cy_card[j].ctl_phys = (ulong) cy_pci_phys0; 4819 dev_err(&pdev->dev, "Cyclom-Y PCI host card with no "
4880 cy_card[j].base_addr = cy_pci_addr2; 4820 "Serial-Modules\n");
4881 cy_card[j].ctl_addr = cy_pci_addr0; 4821 return -EIO;
4882 cy_card[j].irq = (int)cy_pci_irq; 4822 }
4883 cy_card[j].bus_index = 1; 4823 } else if (device_id == PCI_DEVICE_ID_CYCLOM_Z_Hi) {
4884 cy_card[j].first_line = cy_next_channel; 4824 struct RUNTIME_9060 __iomem *ctl_addr;
4885 cy_card[j].num_chips = cy_pci_nchan / 4;
4886 cy_card[j].pdev = pdev;
4887
4888 /* enable interrupts in the PCI interface */
4889 plx_ver = cy_readb(cy_pci_addr2 + CyPLX_VER) & 0x0f;
4890 switch (plx_ver) {
4891 case PLX_9050:
4892
4893 cy_writeb(cy_pci_addr0 + 0x4c, 0x43);
4894 break;
4895 4825
4896 case PLX_9060: 4826 ctl_addr = addr0 = pci_iomap(pdev, 0, CyPCI_Zctl);
4897 case PLX_9080: 4827 if (addr0 == NULL) {
4898 default: /* Old boards, use PLX_9060 */ 4828 dev_err(&pdev->dev, "can't remap ctl region\n");
4899 4829 goto err_reg;
4900 plx_init(cy_pci_addr0, 0x6c); 4830 }
4901 /* For some yet unknown reason, once the PLX9060 reloads
4902 the EEPROM, the IRQ is lost and, thus, we have to
4903 re-write it to the PCI config. registers.
4904 This will remain here until we find a permanent
4905 fix. */
4906 pci_write_config_byte(pdev, PCI_INTERRUPT_LINE,
4907 cy_pci_irq);
4908
4909 cy_writew(cy_pci_addr0 + 0x68,
4910 cy_readw(cy_pci_addr0 +
4911 0x68) | 0x0900);
4912 break;
4913 }
4914 4831
4915 /* print message */ 4832 /* Disable interrupts on the PLX before resetting it */
4916 printk("Cyclom-Y/PCI #%d: 0x%lx-0x%lx, IRQ%d, ", 4833 cy_writew(addr0 + 0x68,
4917 j + 1, (ulong)cy_pci_phys2, 4834 readw(addr0 + 0x68) & ~0x0900);
4918 (ulong) (cy_pci_phys2 + CyPCI_Ywin - 1), 4835
4919 (int)cy_pci_irq); 4836 plx_init(addr0, 0x6c);
4920 printk("%d channels starting from port %d.\n", 4837 /* For some yet unknown reason, once the PLX9060 reloads
4921 cy_pci_nchan, cy_next_channel); 4838 the EEPROM, the IRQ is lost and, thus, we have to
4922 4839 re-write it to the PCI config. registers.
4923 cy_next_channel += cy_pci_nchan; 4840 This will remain here until we find a permanent
4924 } else if (device_id == PCI_DEVICE_ID_CYCLOM_Z_Lo) { 4841 fix. */
4925 /* print message */ 4842 pci_write_config_byte(pdev, PCI_INTERRUPT_LINE, irq);
4926 printk("Cyclades-Z/PCI (bus=0x0%x, pci_id=0x%x, ", 4843
4927 pdev->bus->number, pdev->devfn); 4844 mailbox = (u32)readl(&ctl_addr->mail_box_0);
4928 printk("rev_id=%d) IRQ%d\n", 4845
4929 cyy_rev_id, (int)cy_pci_irq); 4846 addr2 = pci_iomap(pdev, 2, mailbox == ZE_V1 ?
4930 printk("Cyclades-Z/PCI: found winaddr=0x%lx " 4847 CyPCI_Ze_win : CyPCI_Zwin);
4931 "ctladdr=0x%lx\n", 4848 if (addr2 == NULL) {
4932 (ulong)cy_pci_phys2, (ulong)cy_pci_phys0); 4849 dev_err(&pdev->dev, "can't remap base region\n");
4933 printk("Cyclades-Z/PCI not supported for low " 4850 goto err_unmap;
4934 "addresses\n"); 4851 }
4935 break;
4936 } else if (device_id == PCI_DEVICE_ID_CYCLOM_Z_Hi) {
4937#ifdef CY_PCI_DEBUG
4938 printk("Cyclades-Z/PCI (bus=0x0%x, pci_id=0x%x, ",
4939 pdev->bus->number, pdev->devfn);
4940 printk("rev_id=%d) IRQ%d\n",
4941 cyy_rev_id, (int)cy_pci_irq);
4942 printk("Cyclades-Z/PCI: found winaddr=0x%lx "
4943 "ctladdr=0x%lx\n",
4944 (ulong) cy_pci_phys2, (ulong) cy_pci_phys0);
4945#endif
4946 cy_pci_addr0 = ioremap(cy_pci_phys0, CyPCI_Zctl);
4947
4948 /* Disable interrupts on the PLX before resetting it */
4949 cy_writew(cy_pci_addr0 + 0x68,
4950 cy_readw(cy_pci_addr0 + 0x68) & ~0x0900);
4951
4952 plx_init(cy_pci_addr0, 0x6c);
4953 /* For some yet unknown reason, once the PLX9060 reloads
4954 the EEPROM, the IRQ is lost and, thus, we have to
4955 re-write it to the PCI config. registers.
4956 This will remain here until we find a permanent
4957 fix. */
4958 pci_write_config_byte(pdev, PCI_INTERRUPT_LINE,
4959 cy_pci_irq);
4960
4961 mailbox =
4962 (uclong)cy_readl(&((struct RUNTIME_9060 __iomem *)
4963 cy_pci_addr0)->mail_box_0);
4964
4965 if (pci_resource_flags(pdev, 2) & IORESOURCE_IO) {
4966 printk(" Warning: PCI I/O bit incorrectly "
4967 "set. Ignoring it...\n");
4968 pdev->resource[2].flags &= ~IORESOURCE_IO;
4969 }
4970 4852
4971 /* Although we don't use this I/O region, we should 4853 if (mailbox == ZE_V1) {
4972 request it from the kernel anyway, to avoid problems 4854 card_name = "Cyclades-Ze";
4973 with other drivers accessing it. */
4974 if (pci_request_regions(pdev, "Cyclades-Z") != 0) {
4975 printk(KERN_ERR "cyclades: failed to reserve "
4976 "PCI resources\n");
4977 continue;
4978 }
4979 4855
4980 if (mailbox == ZE_V1) { 4856 readl(&ctl_addr->mail_box_0);
4981 cy_pci_addr2 = ioremap(cy_pci_phys2, 4857 nchan = ZE_V1_NPORTS;
4982 CyPCI_Ze_win); 4858 } else {
4983 if (ZeIndex == NR_CARDS) { 4859 card_name = "Cyclades-8Zo";
4984 printk("Cyclades-Ze/PCI found at "
4985 "0x%lx but no more cards can "
4986 "be used.\nChange NR_CARDS in "
4987 "cyclades.c and recompile "
4988 "kernel.\n",
4989 (ulong)cy_pci_phys2);
4990 } else {
4991 Ze_phys0[ZeIndex] = cy_pci_phys0;
4992 Ze_phys2[ZeIndex] = cy_pci_phys2;
4993 Ze_addr0[ZeIndex] = cy_pci_addr0;
4994 Ze_addr2[ZeIndex] = cy_pci_addr2;
4995 Ze_irq[ZeIndex] = cy_pci_irq;
4996 Ze_pdev[ZeIndex] = pdev;
4997 ZeIndex++;
4998 }
4999 i--;
5000 continue;
5001 } else {
5002 cy_pci_addr2 = ioremap(cy_pci_phys2,CyPCI_Zwin);
5003 }
5004 4860
5005#ifdef CY_PCI_DEBUG 4861#ifdef CY_PCI_DEBUG
5006 printk("Cyclades-Z/PCI: relocate winaddr=0x%lx "
5007 "ctladdr=0x%lx\n",
5008 (ulong) cy_pci_addr2, (ulong) cy_pci_addr0);
5009 if (mailbox == ZO_V1) { 4862 if (mailbox == ZO_V1) {
5010 cy_writel(&((struct RUNTIME_9060 *) 4863 cy_writel(&ctl_addr->loc_addr_base, WIN_CREG);
5011 (cy_pci_addr0))->loc_addr_base, 4864 dev_info(&pdev->dev, "Cyclades-8Zo/PCI: FPGA "
5012 WIN_CREG); 4865 "id %lx, ver %lx\n", (ulong)(0xff &
5013 PAUSE; 4866 readl(&((struct CUSTOM_REG *)addr2)->
5014 printk("Cyclades-8Zo/PCI: FPGA id %lx, ver " 4867 fpga_id)), (ulong)(0xff &
5015 "%lx\n", (ulong) (0xff & 4868 readl(&((struct CUSTOM_REG *)addr2)->
5016 cy_readl(&((struct CUSTOM_REG *) 4869 fpga_version)));
5017 (cy_pci_addr2))->fpga_id)), 4870 cy_writel(&ctl_addr->loc_addr_base, WIN_RAM);
5018 (ulong)(0xff &
5019 cy_readl(&((struct CUSTOM_REG *)
5020 (cy_pci_addr2))->
5021 fpga_version)));
5022 cy_writel(&((struct RUNTIME_9060 *)
5023 (cy_pci_addr0))->loc_addr_base,
5024 WIN_RAM);
5025 } else { 4871 } else {
5026 printk("Cyclades-Z/PCI: New Cyclades-Z board. " 4872 dev_info(&pdev->dev, "Cyclades-Z/PCI: New "
5027 "FPGA not loaded\n"); 4873 "Cyclades-Z board. FPGA not loaded\n");
5028 } 4874 }
5029#endif 4875#endif
5030 /* The following clears the firmware id word. This 4876 /* The following clears the firmware id word. This
5031 ensures that the driver will not attempt to talk to 4877 ensures that the driver will not attempt to talk to
5032 the board until it has been properly initialized. 4878 the board until it has been properly initialized.
5033 */ 4879 */
5034 PAUSE;
5035 if ((mailbox == ZO_V1) || (mailbox == ZO_V2)) 4880 if ((mailbox == ZO_V1) || (mailbox == ZO_V2))
5036 cy_writel(cy_pci_addr2 + ID_ADDRESS, 0L); 4881 cy_writel(addr2 + ID_ADDRESS, 0L);
5037 4882
5038 /* This must be a Cyclades-8Zo/PCI. The extendable 4883 /* This must be a Cyclades-8Zo/PCI. The extendable
5039 version will have a different device_id and will 4884 version will have a different device_id and will
5040 be allocated its maximum number of ports. */ 4885 be allocated its maximum number of ports. */
5041 cy_pci_nchan = 8; 4886 nchan = 8;
5042
5043 if ((cy_next_channel + cy_pci_nchan) > NR_PORTS) {
5044 printk("Cyclades-8Zo/PCI found at 0x%lx but"
5045 "no channels are available.\nChange "
5046 "NR_PORTS in cyclades.c and recompile "
5047 "kernel.\n", (ulong)cy_pci_phys2);
5048 return i;
5049 }
5050
5051 /* fill the next cy_card structure available */
5052 for (j = 0; j < NR_CARDS; j++) {
5053 if (cy_card[j].base_addr == 0)
5054 break;
5055 }
5056 if (j == NR_CARDS) { /* no more cy_cards available */
5057 printk("Cyclades-8Zo/PCI found at 0x%lx but"
5058 "no more cards can be used.\nChange "
5059 "NR_CARDS in cyclades.c and recompile "
5060 "kernel.\n", (ulong)cy_pci_phys2);
5061 return i;
5062 }
5063#ifdef CONFIG_CYZ_INTR
5064 /* allocate IRQ only if board has an IRQ */
5065 if ((cy_pci_irq != 0) && (cy_pci_irq != 255)) {
5066 if (request_irq(cy_pci_irq, cyz_interrupt,
5067 IRQF_SHARED, "Cyclades-Z",
5068 &cy_card[j])) {
5069 printk("Cyclom-8Zo/PCI found at 0x%lx "
5070 "but could not allocate "
5071 "IRQ%d.\n", (ulong)cy_pci_phys2,
5072 cy_pci_irq);
5073 return i;
5074 }
5075 }
5076#endif /* CONFIG_CYZ_INTR */
5077
5078 /* set cy_card */
5079 cy_card[j].base_phys = cy_pci_phys2;
5080 cy_card[j].ctl_phys = cy_pci_phys0;
5081 cy_card[j].base_addr = cy_pci_addr2;
5082 cy_card[j].ctl_addr = cy_pci_addr0;
5083 cy_card[j].irq = (int)cy_pci_irq;
5084 cy_card[j].bus_index = 1;
5085 cy_card[j].first_line = cy_next_channel;
5086 cy_card[j].num_chips = -1;
5087 cy_card[j].pdev = pdev;
5088
5089 /* print message */
5090#ifdef CONFIG_CYZ_INTR
5091 /* don't report IRQ if board is no IRQ */
5092 if ((cy_pci_irq != 0) && (cy_pci_irq != 255))
5093 printk("Cyclades-8Zo/PCI #%d: 0x%lx-0x%lx, "
5094 "IRQ%d, ", j + 1, (ulong)cy_pci_phys2,
5095 (ulong) (cy_pci_phys2 + CyPCI_Zwin - 1),
5096 (int)cy_pci_irq);
5097 else
5098#endif /* CONFIG_CYZ_INTR */
5099 printk("Cyclades-8Zo/PCI #%d: 0x%lx-0x%lx, ",
5100 j + 1, (ulong)cy_pci_phys2,
5101 (ulong)(cy_pci_phys2 + CyPCI_Zwin - 1));
5102
5103 printk("%d channels starting from port %d.\n",
5104 cy_pci_nchan, cy_next_channel);
5105 cy_next_channel += cy_pci_nchan;
5106 } 4887 }
5107 } 4888 }
5108 4889
5109 for (; ZeIndex != 0 && i < NR_CARDS; i++) { 4890 if ((cy_next_channel + nchan) > NR_PORTS) {
5110 cy_pci_phys0 = Ze_phys0[0]; 4891 dev_err(&pdev->dev, "Cyclades-8Zo/PCI found, but no "
5111 cy_pci_phys2 = Ze_phys2[0]; 4892 "channels are available. Change NR_PORTS in "
5112 cy_pci_addr0 = Ze_addr0[0]; 4893 "cyclades.c and recompile kernel.\n");
5113 cy_pci_addr2 = Ze_addr2[0]; 4894 goto err_unmap;
5114 cy_pci_irq = Ze_irq[0]; 4895 }
5115 pdev = Ze_pdev[0]; 4896 /* fill the next cy_card structure available */
5116 for (j = 0; j < ZeIndex - 1; j++) { 4897 for (card_no = 0; card_no < NR_CARDS; card_no++) {
5117 Ze_phys0[j] = Ze_phys0[j + 1]; 4898 if (cy_card[card_no].base_addr == NULL)
5118 Ze_phys2[j] = Ze_phys2[j + 1]; 4899 break;
5119 Ze_addr0[j] = Ze_addr0[j + 1]; 4900 }
5120 Ze_addr2[j] = Ze_addr2[j + 1]; 4901 if (card_no == NR_CARDS) { /* no more cy_cards available */
5121 Ze_irq[j] = Ze_irq[j + 1]; 4902 dev_err(&pdev->dev, "Cyclades-8Zo/PCI found, but no "
5122 Ze_pdev[j] = Ze_pdev[j + 1]; 4903 "more cards can be used. Change NR_CARDS in "
5123 } 4904 "cyclades.c and recompile kernel.\n");
5124 ZeIndex--; 4905 goto err_unmap;
5125 mailbox = (uclong)cy_readl(&((struct RUNTIME_9060 __iomem *) 4906 }
5126 cy_pci_addr0)->mail_box_0);
5127#ifdef CY_PCI_DEBUG
5128 printk("Cyclades-Z/PCI: relocate winaddr=0x%lx ctladdr=0x%lx\n",
5129 (ulong)cy_pci_addr2, (ulong)cy_pci_addr0);
5130 printk("Cyclades-Z/PCI: New Cyclades-Z board. FPGA not "
5131 "loaded\n");
5132#endif
5133 PAUSE;
5134 /* This must be the new Cyclades-Ze/PCI. */
5135 cy_pci_nchan = ZE_V1_NPORTS;
5136
5137 if ((cy_next_channel + cy_pci_nchan) > NR_PORTS) {
5138 printk("Cyclades-Ze/PCI found at 0x%lx but no channels "
5139 "are available.\nChange NR_PORTS in cyclades.c "
5140 "and recompile kernel.\n",
5141 (ulong) cy_pci_phys2);
5142 return i;
5143 }
5144 4907
5145 /* fill the next cy_card structure available */ 4908 if (device_id == PCI_DEVICE_ID_CYCLOM_Y_Lo ||
5146 for (j = 0; j < NR_CARDS; j++) { 4909 device_id == PCI_DEVICE_ID_CYCLOM_Y_Hi) {
5147 if (cy_card[j].base_addr == 0) 4910 /* allocate IRQ */
5148 break; 4911 retval = request_irq(irq, cyy_interrupt,
5149 } 4912 IRQF_SHARED, "Cyclom-Y", &cy_card[card_no]);
5150 if (j == NR_CARDS) { /* no more cy_cards available */ 4913 if (retval) {
5151 printk("Cyclades-Ze/PCI found at 0x%lx but no more " 4914 dev_err(&pdev->dev, "could not allocate IRQ\n");
5152 "cards can be used.\nChange NR_CARDS in " 4915 goto err_unmap;
5153 "cyclades.c and recompile kernel.\n",
5154 (ulong) cy_pci_phys2);
5155 return i;
5156 } 4916 }
4917 cy_card[card_no].num_chips = nchan / 4;
4918 } else {
5157#ifdef CONFIG_CYZ_INTR 4919#ifdef CONFIG_CYZ_INTR
5158 /* allocate IRQ only if board has an IRQ */ 4920 /* allocate IRQ only if board has an IRQ */
5159 if ((cy_pci_irq != 0) && (cy_pci_irq != 255)) { 4921 if (irq != 0 && irq != 255) {
5160 if (request_irq(cy_pci_irq, cyz_interrupt, 4922 retval = request_irq(irq, cyz_interrupt,
5161 IRQF_SHARED, "Cyclades-Z", 4923 IRQF_SHARED, "Cyclades-Z",
5162 &cy_card[j])) { 4924 &cy_card[card_no]);
5163 printk("Cyclom-Ze/PCI found at 0x%lx ", 4925 if (retval) {
5164 (ulong) cy_pci_phys2); 4926 dev_err(&pdev->dev, "could not allocate IRQ\n");
5165 printk("but could not allocate IRQ%d.\n", 4927 goto err_unmap;
5166 cy_pci_irq);
5167 return i;
5168 } 4928 }
5169 } 4929 }
5170#endif /* CONFIG_CYZ_INTR */ 4930#endif /* CONFIG_CYZ_INTR */
4931 cy_card[card_no].num_chips = -1;
4932 }
5171 4933
5172 /* set cy_card */ 4934 /* set cy_card */
5173 cy_card[j].base_phys = cy_pci_phys2; 4935 cy_card[card_no].base_addr = addr2;
5174 cy_card[j].ctl_phys = cy_pci_phys0; 4936 cy_card[card_no].ctl_addr = addr0;
5175 cy_card[j].base_addr = cy_pci_addr2; 4937 cy_card[card_no].irq = irq;
5176 cy_card[j].ctl_addr = cy_pci_addr0; 4938 cy_card[card_no].bus_index = 1;
5177 cy_card[j].irq = (int)cy_pci_irq; 4939 cy_card[card_no].first_line = cy_next_channel;
5178 cy_card[j].bus_index = 1; 4940 retval = cy_init_card(&cy_card[card_no]);
5179 cy_card[j].first_line = cy_next_channel; 4941 if (retval)
5180 cy_card[j].num_chips = -1; 4942 goto err_null;
5181 cy_card[j].pdev = pdev;
5182 4943
5183 /* print message */ 4944 pci_set_drvdata(pdev, &cy_card[card_no]);
5184#ifdef CONFIG_CYZ_INTR
5185 /* don't report IRQ if board is no IRQ */
5186 if ((cy_pci_irq != 0) && (cy_pci_irq != 255))
5187 printk("Cyclades-Ze/PCI #%d: 0x%lx-0x%lx, IRQ%d, ",
5188 j + 1, (ulong) cy_pci_phys2,
5189 (ulong) (cy_pci_phys2 + CyPCI_Ze_win - 1),
5190 (int)cy_pci_irq);
5191 else
5192#endif /* CONFIG_CYZ_INTR */
5193 printk("Cyclades-Ze/PCI #%d: 0x%lx-0x%lx, ",
5194 j + 1, (ulong) cy_pci_phys2,
5195 (ulong) (cy_pci_phys2 + CyPCI_Ze_win - 1));
5196 4945
5197 printk("%d channels starting from port %d.\n", 4946 if (device_id == PCI_DEVICE_ID_CYCLOM_Y_Lo ||
5198 cy_pci_nchan, cy_next_channel); 4947 device_id == PCI_DEVICE_ID_CYCLOM_Y_Hi) {
5199 cy_next_channel += cy_pci_nchan; 4948 /* enable interrupts in the PCI interface */
5200 } 4949 plx_ver = readb(addr2 + CyPLX_VER) & 0x0f;
5201 if (ZeIndex != 0) { 4950 switch (plx_ver) {
5202 printk("Cyclades-Ze/PCI found at 0x%x but no more cards can be " 4951 case PLX_9050:
5203 "used.\nChange NR_CARDS in cyclades.c and recompile " 4952
5204 "kernel.\n", (unsigned int)Ze_phys2[0]); 4953 cy_writeb(addr0 + 0x4c, 0x43);
4954 break;
4955
4956 case PLX_9060:
4957 case PLX_9080:
4958 default: /* Old boards, use PLX_9060 */
4959
4960 plx_init(addr0, 0x6c);
4961 /* For some yet unknown reason, once the PLX9060 reloads
4962 the EEPROM, the IRQ is lost and, thus, we have to
4963 re-write it to the PCI config. registers.
4964 This will remain here until we find a permanent
4965 fix. */
4966 pci_write_config_byte(pdev, PCI_INTERRUPT_LINE, irq);
4967
4968 cy_writew(addr0 + 0x68, readw(addr0 + 0x68) | 0x0900);
4969 break;
4970 }
5205 } 4971 }
5206 return i; 4972
5207#else 4973 dev_info(&pdev->dev, "%s/PCI #%d found: %d channels starting from "
4974 "port %d.\n", card_name, card_no + 1, nchan, cy_next_channel);
4975 for (i = cy_next_channel; i < cy_next_channel + nchan; i++)
4976 tty_register_device(cy_serial_driver, i, &pdev->dev);
4977 cy_next_channel += nchan;
4978
5208 return 0; 4979 return 0;
5209#endif /* ifdef CONFIG_PCI */ 4980err_null:
5210} /* cy_detect_pci */ 4981 cy_card[card_no].base_addr = NULL;
4982 free_irq(irq, &cy_card[card_no]);
4983err_unmap:
4984 pci_iounmap(pdev, addr0);
4985 if (addr2)
4986 pci_iounmap(pdev, addr2);
4987err_reg:
4988 pci_release_regions(pdev);
4989err_dis:
4990 pci_disable_device(pdev);
4991err:
4992 return retval;
4993}
5211 4994
5212/* 4995static void __devexit cy_pci_remove(struct pci_dev *pdev)
5213 * This routine prints out the appropriate serial driver version number
5214 * and identifies which options were configured into this driver.
5215 */
5216static inline void show_version(void)
5217{ 4996{
5218 printk("Cyclades driver " CY_VERSION "\n"); 4997 struct cyclades_card *cinfo = pci_get_drvdata(pdev);
5219 printk(" built %s %s\n", __DATE__, __TIME__); 4998 unsigned int i;
5220} /* show_version */ 4999
5000 /* non-Z with old PLX */
5001 if (!IS_CYC_Z(*cinfo) && (readb(cinfo->base_addr + CyPLX_VER) & 0x0f) ==
5002 PLX_9050)
5003 cy_writeb(cinfo->ctl_addr + 0x4c, 0);
5004 else
5005#ifndef CONFIG_CYZ_INTR
5006 if (!IS_CYC_Z(*cinfo))
5007#endif
5008 cy_writew(cinfo->ctl_addr + 0x68,
5009 readw(cinfo->ctl_addr + 0x68) & ~0x0900);
5010
5011 pci_iounmap(pdev, cinfo->base_addr);
5012 if (cinfo->ctl_addr)
5013 pci_iounmap(pdev, cinfo->ctl_addr);
5014 if (cinfo->irq
5015#ifndef CONFIG_CYZ_INTR
5016 && !IS_CYC_Z(*cinfo)
5017#endif /* CONFIG_CYZ_INTR */
5018 )
5019 free_irq(cinfo->irq, cinfo);
5020 pci_release_regions(pdev);
5021
5022 cinfo->base_addr = NULL;
5023 for (i = cinfo->first_line; i < cinfo->first_line +
5024 cinfo->nports; i++)
5025 tty_unregister_device(cy_serial_driver, i);
5026 cinfo->nports = 0;
5027 kfree(cinfo->ports);
5028}
5029
5030static struct pci_driver cy_pci_driver = {
5031 .name = "cyclades",
5032 .id_table = cy_pci_dev_id,
5033 .probe = cy_pci_probe,
5034 .remove = __devexit_p(cy_pci_remove)
5035};
5036#endif
5221 5037
5222static int 5038static int
5223cyclades_get_proc_info(char *buf, char **start, off_t offset, int length, 5039cyclades_get_proc_info(char *buf, char **start, off_t offset, int length,
5224 int *eof, void *data) 5040 int *eof, void *data)
5225{ 5041{
5226 struct cyclades_port *info; 5042 struct cyclades_port *info;
5227 int i; 5043 unsigned int i, j;
5228 int len = 0; 5044 int len = 0;
5229 off_t begin = 0; 5045 off_t begin = 0;
5230 off_t pos = 0; 5046 off_t pos = 0;
@@ -5238,33 +5054,34 @@ cyclades_get_proc_info(char *buf, char **start, off_t offset, int length,
5238 len += size; 5054 len += size;
5239 5055
5240 /* Output one line for each known port */ 5056 /* Output one line for each known port */
5241 for (i = 0; i < NR_PORTS && cy_port[i].line >= 0; i++) { 5057 for (i = 0; i < NR_CARDS; i++)
5242 info = &cy_port[i]; 5058 for (j = 0; j < cy_card[i].nports; j++) {
5243 5059 info = &cy_card[i].ports[j];
5244 if (info->count) 5060
5245 size = sprintf(buf + len, "%3d %8lu %10lu %8lu %10lu " 5061 if (info->count)
5246 "%8lu %9lu %6ld\n", info->line, 5062 size = sprintf(buf + len, "%3d %8lu %10lu %8lu "
5247 (cur_jifs - info->idle_stats.in_use) / HZ, 5063 "%10lu %8lu %9lu %6ld\n", info->line,
5248 info->idle_stats.xmit_bytes, 5064 (cur_jifs - info->idle_stats.in_use) /
5249 (cur_jifs - info->idle_stats.xmit_idle) / HZ, 5065 HZ, info->idle_stats.xmit_bytes,
5250 info->idle_stats.recv_bytes, 5066 (cur_jifs - info->idle_stats.xmit_idle)/
5251 (cur_jifs - info->idle_stats.recv_idle) / HZ, 5067 HZ, info->idle_stats.recv_bytes,
5252 info->idle_stats.overruns, 5068 (cur_jifs - info->idle_stats.recv_idle)/
5253 (long)info->tty->ldisc.num); 5069 HZ, info->idle_stats.overruns,
5254 else 5070 (long)info->tty->ldisc.num);
5255 size = sprintf(buf + len, "%3d %8lu %10lu %8lu %10lu " 5071 else
5256 "%8lu %9lu %6ld\n", 5072 size = sprintf(buf + len, "%3d %8lu %10lu %8lu "
5257 info->line, 0L, 0L, 0L, 0L, 0L, 0L, 0L); 5073 "%10lu %8lu %9lu %6ld\n",
5258 len += size; 5074 info->line, 0L, 0L, 0L, 0L, 0L, 0L, 0L);
5259 pos = begin + len; 5075 len += size;
5260 5076 pos = begin + len;
5261 if (pos < offset) { 5077
5262 len = 0; 5078 if (pos < offset) {
5263 begin = pos; 5079 len = 0;
5080 begin = pos;
5081 }
5082 if (pos > offset + length)
5083 goto done;
5264 } 5084 }
5265 if (pos > offset + length)
5266 goto done;
5267 }
5268 *eof = 1; 5085 *eof = 1;
5269done: 5086done:
5270 *start = buf + (offset - begin); /* Start of wanted data */ 5087 *start = buf + (offset - begin); /* Start of wanted data */
@@ -5319,18 +5136,15 @@ static const struct tty_operations cy_ops = {
5319 5136
5320static int __init cy_init(void) 5137static int __init cy_init(void)
5321{ 5138{
5322 struct cyclades_port *info; 5139 unsigned int nboards;
5323 struct cyclades_card *cinfo; 5140 int retval = -ENOMEM;
5324 int number_z_boards = 0;
5325 int board, port, i, index;
5326 unsigned long mailbox;
5327 unsigned short chip_number;
5328 int nports;
5329 5141
5330 cy_serial_driver = alloc_tty_driver(NR_PORTS); 5142 cy_serial_driver = alloc_tty_driver(NR_PORTS);
5331 if (!cy_serial_driver) 5143 if (!cy_serial_driver)
5332 return -ENOMEM; 5144 goto err;
5333 show_version(); 5145
5146 printk(KERN_INFO "Cyclades driver " CY_VERSION " (built %s %s)\n",
5147 __DATE__, __TIME__);
5334 5148
5335 /* Initialize the tty_driver structure */ 5149 /* Initialize the tty_driver structure */
5336 5150
@@ -5344,15 +5158,13 @@ static int __init cy_init(void)
5344 cy_serial_driver->init_termios = tty_std_termios; 5158 cy_serial_driver->init_termios = tty_std_termios;
5345 cy_serial_driver->init_termios.c_cflag = 5159 cy_serial_driver->init_termios.c_cflag =
5346 B9600 | CS8 | CREAD | HUPCL | CLOCAL; 5160 B9600 | CS8 | CREAD | HUPCL | CLOCAL;
5347 cy_serial_driver->flags = TTY_DRIVER_REAL_RAW; 5161 cy_serial_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV;
5348 tty_set_operations(cy_serial_driver, &cy_ops); 5162 tty_set_operations(cy_serial_driver, &cy_ops);
5349 5163
5350 if (tty_register_driver(cy_serial_driver)) 5164 retval = tty_register_driver(cy_serial_driver);
5351 panic("Couldn't register Cyclades serial driver\n"); 5165 if (retval) {
5352 5166 printk(KERN_ERR "Couldn't register Cyclades serial driver\n");
5353 for (i = 0; i < NR_CARDS; i++) { 5167 goto err_frtty;
5354 /* base_addr=0 indicates board not found */
5355 cy_card[i].base_addr = NULL;
5356 } 5168 }
5357 5169
5358 /* the code below is responsible to find the boards. Each different 5170 /* the code below is responsible to find the boards. Each different
@@ -5363,223 +5175,68 @@ static int __init cy_init(void)
5363 the cy_next_channel. */ 5175 the cy_next_channel. */
5364 5176
5365 /* look for isa boards */ 5177 /* look for isa boards */
5366 cy_isa_nboard = cy_detect_isa(); 5178 nboards = cy_detect_isa();
5367 5179
5180#ifdef CONFIG_PCI
5368 /* look for pci boards */ 5181 /* look for pci boards */
5369 cy_pci_nboard = cy_detect_pci(); 5182 retval = pci_register_driver(&cy_pci_driver);
5370 5183 if (retval && !nboards)
5371 cy_nboard = cy_isa_nboard + cy_pci_nboard; 5184 goto err_unr;
5372
5373 /* invalidate remaining cy_card structures */
5374 for (i = 0; i < NR_CARDS; i++) {
5375 if (cy_card[i].base_addr == 0) {
5376 cy_card[i].first_line = -1;
5377 cy_card[i].ctl_addr = NULL;
5378 cy_card[i].irq = 0;
5379 cy_card[i].bus_index = 0;
5380 cy_card[i].first_line = 0;
5381 cy_card[i].num_chips = 0;
5382 }
5383 }
5384 /* invalidate remaining cy_port structures */
5385 for (i = cy_next_channel; i < NR_PORTS; i++) {
5386 cy_port[i].line = -1;
5387 cy_port[i].magic = -1;
5388 }
5389
5390 /* initialize per-port data structures for each valid board found */
5391 for (board = 0; board < cy_nboard; board++) {
5392 cinfo = &cy_card[board];
5393 if (cinfo->num_chips == -1) { /* Cyclades-Z */
5394 number_z_boards++;
5395 mailbox = cy_readl(&((struct RUNTIME_9060 __iomem *)
5396 cy_card[board].ctl_addr)->
5397 mail_box_0);
5398 nports = (mailbox == ZE_V1) ? ZE_V1_NPORTS : 8;
5399 cinfo->intr_enabled = 0;
5400 cinfo->nports = 0; /* Will be correctly set later, after
5401 Z FW is loaded */
5402 spin_lock_init(&cinfo->card_lock);
5403 for (port = cinfo->first_line;
5404 port < cinfo->first_line + nports; port++) {
5405 info = &cy_port[port];
5406 info->magic = CYCLADES_MAGIC;
5407 info->type = PORT_STARTECH;
5408 info->card = board;
5409 info->line = port;
5410 info->chip_rev = 0;
5411 info->flags = STD_COM_FLAGS;
5412 info->tty = NULL;
5413 if (mailbox == ZO_V1)
5414 info->xmit_fifo_size = CYZ_FIFO_SIZE;
5415 else
5416 info->xmit_fifo_size =
5417 4 * CYZ_FIFO_SIZE;
5418 info->cor1 = 0;
5419 info->cor2 = 0;
5420 info->cor3 = 0;
5421 info->cor4 = 0;
5422 info->cor5 = 0;
5423 info->tbpr = 0;
5424 info->tco = 0;
5425 info->rbpr = 0;
5426 info->rco = 0;
5427 info->custom_divisor = 0;
5428 info->close_delay = 5 * HZ / 10;
5429 info->closing_wait = CLOSING_WAIT_DELAY;
5430 info->icount.cts = info->icount.dsr =
5431 info->icount.rng = info->icount.dcd = 0;
5432 info->icount.rx = info->icount.tx = 0;
5433 info->icount.frame = info->icount.parity = 0;
5434 info->icount.overrun = info->icount.brk = 0;
5435 info->x_char = 0;
5436 info->event = 0;
5437 info->count = 0;
5438 info->blocked_open = 0;
5439 info->default_threshold = 0;
5440 info->default_timeout = 0;
5441 INIT_WORK(&info->tqueue, do_softint);
5442 init_waitqueue_head(&info->open_wait);
5443 init_waitqueue_head(&info->close_wait);
5444 init_waitqueue_head(&info->shutdown_wait);
5445 init_waitqueue_head(&info->delta_msr_wait);
5446 /* info->session */
5447 /* info->pgrp */
5448 info->read_status_mask = 0;
5449 /* info->timeout */
5450 /* Bentson's vars */
5451 info->jiffies[0] = 0;
5452 info->jiffies[1] = 0;
5453 info->jiffies[2] = 0;
5454 info->rflush_count = 0;
5455#ifdef CONFIG_CYZ_INTR
5456 init_timer(&cyz_rx_full_timer[port]);
5457 cyz_rx_full_timer[port].function = NULL;
5458#endif 5185#endif
5459 }
5460 continue;
5461 } else { /* Cyclom-Y of some kind */
5462 index = cinfo->bus_index;
5463 spin_lock_init(&cinfo->card_lock);
5464 cinfo->nports = CyPORTS_PER_CHIP * cinfo->num_chips;
5465 for (port = cinfo->first_line;
5466 port < cinfo->first_line + cinfo->nports; port++) {
5467 info = &cy_port[port];
5468 info->magic = CYCLADES_MAGIC;
5469 info->type = PORT_CIRRUS;
5470 info->card = board;
5471 info->line = port;
5472 info->flags = STD_COM_FLAGS;
5473 info->tty = NULL;
5474 info->xmit_fifo_size = CyMAX_CHAR_FIFO;
5475 info->cor1 =
5476 CyPARITY_NONE | Cy_1_STOP | Cy_8_BITS;
5477 info->cor2 = CyETC;
5478 info->cor3 = 0x08; /* _very_ small rcv threshold */
5479 info->cor4 = 0;
5480 info->cor5 = 0;
5481 info->custom_divisor = 0;
5482 info->close_delay = 5 * HZ / 10;
5483 info->closing_wait = CLOSING_WAIT_DELAY;
5484 info->icount.cts = info->icount.dsr =
5485 info->icount.rng = info->icount.dcd = 0;
5486 info->icount.rx = info->icount.tx = 0;
5487 info->icount.frame = info->icount.parity = 0;
5488 info->icount.overrun = info->icount.brk = 0;
5489 chip_number = (port - cinfo->first_line) / 4;
5490 if ((info->chip_rev =
5491 cy_readb(cinfo->base_addr +
5492 (cy_chip_offset[chip_number] <<
5493 index) + (CyGFRCR << index))) >=
5494 CD1400_REV_J) {
5495 /* It is a CD1400 rev. J or later */
5496 info->tbpr = baud_bpr_60[13]; /* Tx BPR */
5497 info->tco = baud_co_60[13]; /* Tx CO */
5498 info->rbpr = baud_bpr_60[13]; /* Rx BPR */
5499 info->rco = baud_co_60[13]; /* Rx CO */
5500 info->rflow = 0;
5501 info->rtsdtr_inv = 1;
5502 } else {
5503 info->tbpr = baud_bpr_25[13]; /* Tx BPR */
5504 info->tco = baud_co_25[13]; /* Tx CO */
5505 info->rbpr = baud_bpr_25[13]; /* Rx BPR */
5506 info->rco = baud_co_25[13]; /* Rx CO */
5507 info->rflow = 0;
5508 info->rtsdtr_inv = 0;
5509 }
5510 info->x_char = 0;
5511 info->event = 0;
5512 info->count = 0;
5513 info->blocked_open = 0;
5514 info->default_threshold = 0;
5515 info->default_timeout = 0;
5516 INIT_WORK(&info->tqueue, do_softint);
5517 init_waitqueue_head(&info->open_wait);
5518 init_waitqueue_head(&info->close_wait);
5519 init_waitqueue_head(&info->shutdown_wait);
5520 init_waitqueue_head(&info->delta_msr_wait);
5521 /* info->session */
5522 /* info->pgrp */
5523 info->read_status_mask =
5524 CyTIMEOUT | CySPECHAR | CyBREAK
5525 | CyPARITY | CyFRAME | CyOVERRUN;
5526 /* info->timeout */
5527 }
5528 }
5529 }
5530
5531#ifndef CONFIG_CYZ_INTR
5532 if (number_z_boards && !cyz_timeron) {
5533 cyz_timeron++;
5534 cyz_timerlist.expires = jiffies + 1;
5535 add_timer(&cyz_timerlist);
5536#ifdef CY_PCI_DEBUG
5537 printk("Cyclades-Z polling initialized\n");
5538#endif
5539 }
5540#endif /* CONFIG_CYZ_INTR */
5541 5186
5542 return 0; 5187 return 0;
5543 5188err_unr:
5189 tty_unregister_driver(cy_serial_driver);
5190err_frtty:
5191 put_tty_driver(cy_serial_driver);
5192err:
5193 return retval;
5544} /* cy_init */ 5194} /* cy_init */
5545 5195
5546static void __exit cy_cleanup_module(void) 5196static void __exit cy_cleanup_module(void)
5547{ 5197{
5198 struct cyclades_card *card;
5548 int i, e1; 5199 int i, e1;
5549 5200
5550#ifndef CONFIG_CYZ_INTR 5201#ifndef CONFIG_CYZ_INTR
5551 if (cyz_timeron){ 5202 del_timer_sync(&cyz_timerlist);
5552 cyz_timeron = 0;
5553 del_timer(&cyz_timerlist);
5554 }
5555#endif /* CONFIG_CYZ_INTR */ 5203#endif /* CONFIG_CYZ_INTR */
5556 5204
5557 if ((e1 = tty_unregister_driver(cy_serial_driver))) 5205 if ((e1 = tty_unregister_driver(cy_serial_driver)))
5558 printk("cyc: failed to unregister Cyclades serial driver(%d)\n", 5206 printk(KERN_ERR "failed to unregister Cyclades serial "
5559 e1); 5207 "driver(%d)\n", e1);
5560 5208
5561 put_tty_driver(cy_serial_driver); 5209#ifdef CONFIG_PCI
5210 pci_unregister_driver(&cy_pci_driver);
5211#endif
5562 5212
5563 for (i = 0; i < NR_CARDS; i++) { 5213 for (i = 0; i < NR_CARDS; i++) {
5564 if (cy_card[i].base_addr) { 5214 card = &cy_card[i];
5565 iounmap(cy_card[i].base_addr); 5215 if (card->base_addr) {
5566 if (cy_card[i].ctl_addr) 5216 /* clear interrupt */
5567 iounmap(cy_card[i].ctl_addr); 5217 cy_writeb(card->base_addr + Cy_ClrIntr, 0);
5568 if (cy_card[i].irq 5218 iounmap(card->base_addr);
5219 if (card->ctl_addr)
5220 iounmap(card->ctl_addr);
5221 if (card->irq
5569#ifndef CONFIG_CYZ_INTR 5222#ifndef CONFIG_CYZ_INTR
5570 && cy_card[i].num_chips != -1 /* not a Z card */ 5223 && !IS_CYC_Z(*card)
5571#endif /* CONFIG_CYZ_INTR */ 5224#endif /* CONFIG_CYZ_INTR */
5572 ) 5225 )
5573 free_irq(cy_card[i].irq, &cy_card[i]); 5226 free_irq(card->irq, card);
5574#ifdef CONFIG_PCI 5227 for (e1 = card->first_line;
5575 if (cy_card[i].pdev) 5228 e1 < card->first_line +
5576 pci_release_regions(cy_card[i].pdev); 5229 card->nports; e1++)
5577#endif 5230 tty_unregister_device(cy_serial_driver, e1);
5231 kfree(card->ports);
5578 } 5232 }
5579 } 5233 }
5234
5235 put_tty_driver(cy_serial_driver);
5580} /* cy_cleanup_module */ 5236} /* cy_cleanup_module */
5581 5237
5582module_init(cy_init); 5238module_init(cy_init);
5583module_exit(cy_cleanup_module); 5239module_exit(cy_cleanup_module);
5584 5240
5585MODULE_LICENSE("GPL"); 5241MODULE_LICENSE("GPL");
5242MODULE_VERSION(CY_VERSION);
diff --git a/drivers/char/digi.h b/drivers/char/digi.h
deleted file mode 100644
index 19df0e879b1b..000000000000
--- a/drivers/char/digi.h
+++ /dev/null
@@ -1,71 +0,0 @@
1/* Definitions for DigiBoard ditty(1) command. */
2
3#if !defined(TIOCMODG)
4#define TIOCMODG (('d'<<8) | 250) /* get modem ctrl state */
5#define TIOCMODS (('d'<<8) | 251) /* set modem ctrl state */
6#endif
7
8#if !defined(TIOCMSET)
9#define TIOCMSET (('d'<<8) | 252) /* set modem ctrl state */
10#define TIOCMGET (('d'<<8) | 253) /* set modem ctrl state */
11#endif
12
13#if !defined(TIOCMBIC)
14#define TIOCMBIC (('d'<<8) | 254) /* set modem ctrl state */
15#define TIOCMBIS (('d'<<8) | 255) /* set modem ctrl state */
16#endif
17
18#if !defined(TIOCSDTR)
19#define TIOCSDTR (('e'<<8) | 0) /* set DTR */
20#define TIOCCDTR (('e'<<8) | 1) /* clear DTR */
21#endif
22
23/************************************************************************
24 * Ioctl command arguments for DIGI parameters.
25 ************************************************************************/
26#define DIGI_GETA (('e'<<8) | 94) /* Read params */
27
28#define DIGI_SETA (('e'<<8) | 95) /* Set params */
29#define DIGI_SETAW (('e'<<8) | 96) /* Drain & set params */
30#define DIGI_SETAF (('e'<<8) | 97) /* Drain, flush & set params */
31
32#define DIGI_GETFLOW (('e'<<8) | 99) /* Get startc/stopc flow */
33 /* control characters */
34#define DIGI_SETFLOW (('e'<<8) | 100) /* Set startc/stopc flow */
35 /* control characters */
36#define DIGI_GETAFLOW (('e'<<8) | 101) /* Get Aux. startc/stopc */
37 /* flow control chars */
38#define DIGI_SETAFLOW (('e'<<8) | 102) /* Set Aux. startc/stopc */
39 /* flow control chars */
40
41struct digiflow_struct {
42 unsigned char startc; /* flow cntl start char */
43 unsigned char stopc; /* flow cntl stop char */
44};
45
46typedef struct digiflow_struct digiflow_t;
47
48
49/************************************************************************
50 * Values for digi_flags
51 ************************************************************************/
52#define DIGI_IXON 0x0001 /* Handle IXON in the FEP */
53#define DIGI_FAST 0x0002 /* Fast baud rates */
54#define RTSPACE 0x0004 /* RTS input flow control */
55#define CTSPACE 0x0008 /* CTS output flow control */
56#define DSRPACE 0x0010 /* DSR output flow control */
57#define DCDPACE 0x0020 /* DCD output flow control */
58#define DTRPACE 0x0040 /* DTR input flow control */
59#define DIGI_FORCEDCD 0x0100 /* Force carrier */
60#define DIGI_ALTPIN 0x0200 /* Alternate RJ-45 pin config */
61#define DIGI_AIXON 0x0400 /* Aux flow control in fep */
62
63
64/************************************************************************
65 * Structure used with ioctl commands for DIGI parameters.
66 ************************************************************************/
67struct digi_struct {
68 unsigned short digi_flags; /* Flags (see above) */
69};
70
71typedef struct digi_struct digi_t;
diff --git a/drivers/char/ds1620.c b/drivers/char/ds1620.c
index 3d7efc26aad6..334ad5bbe6b6 100644
--- a/drivers/char/ds1620.c
+++ b/drivers/char/ds1620.c
@@ -4,7 +4,6 @@
4 */ 4 */
5#include <linux/module.h> 5#include <linux/module.h>
6#include <linux/miscdevice.h> 6#include <linux/miscdevice.h>
7#include <linux/smp_lock.h>
8#include <linux/delay.h> 7#include <linux/delay.h>
9#include <linux/proc_fs.h> 8#include <linux/proc_fs.h>
10#include <linux/capability.h> 9#include <linux/capability.h>
diff --git a/drivers/char/dsp56k.c b/drivers/char/dsp56k.c
index db984e481d4c..9b8278e1f4f8 100644
--- a/drivers/char/dsp56k.c
+++ b/drivers/char/dsp56k.c
@@ -32,7 +32,6 @@
32#include <linux/fs.h> 32#include <linux/fs.h>
33#include <linux/mm.h> 33#include <linux/mm.h>
34#include <linux/init.h> 34#include <linux/init.h>
35#include <linux/smp_lock.h>
36#include <linux/device.h> 35#include <linux/device.h>
37 36
38#include <asm/atarihw.h> 37#include <asm/atarihw.h>
diff --git a/drivers/char/dtlk.c b/drivers/char/dtlk.c
index d8dbdb916232..abde6ddefe69 100644
--- a/drivers/char/dtlk.c
+++ b/drivers/char/dtlk.c
@@ -62,7 +62,6 @@
62#include <linux/init.h> /* for __init, module_{init,exit} */ 62#include <linux/init.h> /* for __init, module_{init,exit} */
63#include <linux/poll.h> /* for POLLIN, etc. */ 63#include <linux/poll.h> /* for POLLIN, etc. */
64#include <linux/dtlk.h> /* local header file for DoubleTalk values */ 64#include <linux/dtlk.h> /* local header file for DoubleTalk values */
65#include <linux/smp_lock.h>
66 65
67#ifdef TRACING 66#ifdef TRACING
68#define TRACE_TEXT(str) printk(str); 67#define TRACE_TEXT(str) printk(str);
@@ -325,16 +324,22 @@ static int dtlk_release(struct inode *inode, struct file *file)
325 324
326static int __init dtlk_init(void) 325static int __init dtlk_init(void)
327{ 326{
327 int err;
328
328 dtlk_port_lpc = 0; 329 dtlk_port_lpc = 0;
329 dtlk_port_tts = 0; 330 dtlk_port_tts = 0;
330 dtlk_busy = 0; 331 dtlk_busy = 0;
331 dtlk_major = register_chrdev(0, "dtlk", &dtlk_fops); 332 dtlk_major = register_chrdev(0, "dtlk", &dtlk_fops);
332 if (dtlk_major == 0) { 333 if (dtlk_major < 0) {
333 printk(KERN_ERR "DoubleTalk PC - cannot register device\n"); 334 printk(KERN_ERR "DoubleTalk PC - cannot register device\n");
334 return 0; 335 return dtlk_major;
336 }
337 err = dtlk_dev_probe();
338 if (err) {
339 unregister_chrdev(dtlk_major, "dtlk");
340 return err;
335 } 341 }
336 if (dtlk_dev_probe() == 0) 342 printk(", MAJOR %d\n", dtlk_major);
337 printk(", MAJOR %d\n", dtlk_major);
338 343
339 init_waitqueue_head(&dtlk_process_list); 344 init_waitqueue_head(&dtlk_process_list);
340 345
diff --git a/drivers/char/ec3104_keyb.c b/drivers/char/ec3104_keyb.c
index 77f58ed6d59a..020011495d91 100644
--- a/drivers/char/ec3104_keyb.c
+++ b/drivers/char/ec3104_keyb.c
@@ -41,7 +41,6 @@
41#include <linux/miscdevice.h> 41#include <linux/miscdevice.h>
42#include <linux/slab.h> 42#include <linux/slab.h>
43#include <linux/kbd_kern.h> 43#include <linux/kbd_kern.h>
44#include <linux/smp_lock.h>
45#include <linux/bitops.h> 44#include <linux/bitops.h>
46 45
47#include <asm/keyboard.h> 46#include <asm/keyboard.h>
diff --git a/drivers/char/epca.c b/drivers/char/epca.c
index de5be30484ad..c6c56fb8ba50 100644
--- a/drivers/char/epca.c
+++ b/drivers/char/epca.c
@@ -949,7 +949,7 @@ static int block_til_ready(struct tty_struct *tty,
949 949
950 } /* End forever while */ 950 } /* End forever while */
951 951
952 current->state = TASK_RUNNING; 952 __set_current_state(TASK_RUNNING);
953 remove_wait_queue(&ch->open_wait, &wait); 953 remove_wait_queue(&ch->open_wait, &wait);
954 if (!tty_hung_up_p(filp)) 954 if (!tty_hung_up_p(filp))
955 ch->count++; 955 ch->count++;
diff --git a/drivers/char/genrtc.c b/drivers/char/genrtc.c
index 23b25ada65ea..49f914e79216 100644
--- a/drivers/char/genrtc.c
+++ b/drivers/char/genrtc.c
@@ -207,7 +207,7 @@ static ssize_t gen_rtc_read(struct file *file, char __user *buf,
207 sizeof(unsigned long); 207 sizeof(unsigned long);
208 } 208 }
209 out: 209 out:
210 current->state = TASK_RUNNING; 210 __set_current_state(TASK_RUNNING);
211 remove_wait_queue(&gen_rtc_wait, &wait); 211 remove_wait_queue(&gen_rtc_wait, &wait);
212 212
213 return retval; 213 return retval;
diff --git a/drivers/char/hangcheck-timer.c b/drivers/char/hangcheck-timer.c
index ae76a9ffe89f..f0e7263dfcde 100644
--- a/drivers/char/hangcheck-timer.c
+++ b/drivers/char/hangcheck-timer.c
@@ -44,7 +44,6 @@
44#include <linux/fs.h> 44#include <linux/fs.h>
45#include <linux/mm.h> 45#include <linux/mm.h>
46#include <linux/reboot.h> 46#include <linux/reboot.h>
47#include <linux/smp_lock.h>
48#include <linux/init.h> 47#include <linux/init.h>
49#include <linux/delay.h> 48#include <linux/delay.h>
50#include <asm/uaccess.h> 49#include <asm/uaccess.h>
diff --git a/drivers/char/hvc_console.c b/drivers/char/hvc_console.c
index 0f9ed7b46a6d..322bc5f7d86b 100644
--- a/drivers/char/hvc_console.c
+++ b/drivers/char/hvc_console.c
@@ -111,7 +111,7 @@ static int last_hvc = -1;
111 * lock held. If successful, this function increments the kobject reference 111 * lock held. If successful, this function increments the kobject reference
112 * count against the target hvc_struct so it should be released when finished. 112 * count against the target hvc_struct so it should be released when finished.
113 */ 113 */
114struct hvc_struct *hvc_get_by_index(int index) 114static struct hvc_struct *hvc_get_by_index(int index)
115{ 115{
116 struct hvc_struct *hp; 116 struct hvc_struct *hp;
117 unsigned long flags; 117 unsigned long flags;
@@ -150,7 +150,8 @@ static uint32_t vtermnos[MAX_NR_HVC_CONSOLES] =
150 * hvc_console_setup() finds adapters. 150 * hvc_console_setup() finds adapters.
151 */ 151 */
152 152
153void hvc_console_print(struct console *co, const char *b, unsigned count) 153static void hvc_console_print(struct console *co, const char *b,
154 unsigned count)
154{ 155{
155 char c[N_OUTBUF] __ALIGNED__; 156 char c[N_OUTBUF] __ALIGNED__;
156 unsigned i = 0, n = 0; 157 unsigned i = 0, n = 0;
@@ -208,7 +209,7 @@ static int __init hvc_console_setup(struct console *co, char *options)
208 return 0; 209 return 0;
209} 210}
210 211
211struct console hvc_con_driver = { 212static struct console hvc_con_driver = {
212 .name = "hvc", 213 .name = "hvc",
213 .write = hvc_console_print, 214 .write = hvc_console_print,
214 .device = hvc_console_device, 215 .device = hvc_console_device,
@@ -278,7 +279,6 @@ int hvc_instantiate(uint32_t vtermno, int index, struct hv_ops *ops)
278 279
279 return 0; 280 return 0;
280} 281}
281EXPORT_SYMBOL(hvc_instantiate);
282 282
283/* Wake the sleeping khvcd */ 283/* Wake the sleeping khvcd */
284static void hvc_kick(void) 284static void hvc_kick(void)
@@ -792,7 +792,6 @@ struct hvc_struct __devinit *hvc_alloc(uint32_t vtermno, int irq,
792 792
793 return hp; 793 return hp;
794} 794}
795EXPORT_SYMBOL(hvc_alloc);
796 795
797int __devexit hvc_remove(struct hvc_struct *hp) 796int __devexit hvc_remove(struct hvc_struct *hp)
798{ 797{
@@ -828,11 +827,10 @@ int __devexit hvc_remove(struct hvc_struct *hp)
828 tty_hangup(tty); 827 tty_hangup(tty);
829 return 0; 828 return 0;
830} 829}
831EXPORT_SYMBOL(hvc_remove);
832 830
833/* Driver initialization. Follow console initialization. This is where the TTY 831/* Driver initialization. Follow console initialization. This is where the TTY
834 * interfaces start to become available. */ 832 * interfaces start to become available. */
835int __init hvc_init(void) 833static int __init hvc_init(void)
836{ 834{
837 struct tty_driver *drv; 835 struct tty_driver *drv;
838 836
diff --git a/drivers/char/hw_random/intel-rng.c b/drivers/char/hw_random/intel-rng.c
index cc1046e6ee02..4ae9811d1a6c 100644
--- a/drivers/char/hw_random/intel-rng.c
+++ b/drivers/char/hw_random/intel-rng.c
@@ -24,10 +24,11 @@
24 * warranty of any kind, whether express or implied. 24 * warranty of any kind, whether express or implied.
25 */ 25 */
26 26
27#include <linux/module.h> 27#include <linux/hw_random.h>
28#include <linux/kernel.h> 28#include <linux/kernel.h>
29#include <linux/module.h>
29#include <linux/pci.h> 30#include <linux/pci.h>
30#include <linux/hw_random.h> 31#include <linux/stop_machine.h>
31#include <asm/io.h> 32#include <asm/io.h>
32 33
33 34
@@ -217,30 +218,117 @@ static struct hwrng intel_rng = {
217 .data_read = intel_rng_data_read, 218 .data_read = intel_rng_data_read,
218}; 219};
219 220
221struct intel_rng_hw {
222 struct pci_dev *dev;
223 void __iomem *mem;
224 u8 bios_cntl_off;
225 u8 bios_cntl_val;
226 u8 fwh_dec_en1_off;
227 u8 fwh_dec_en1_val;
228};
220 229
221#ifdef CONFIG_SMP 230static int __init intel_rng_hw_init(void *_intel_rng_hw)
222static char __initdata waitflag; 231{
232 struct intel_rng_hw *intel_rng_hw = _intel_rng_hw;
233 u8 mfc, dvc;
234
235 /* interrupts disabled in stop_machine_run call */
236
237 if (!(intel_rng_hw->fwh_dec_en1_val & FWH_F8_EN_MASK))
238 pci_write_config_byte(intel_rng_hw->dev,
239 intel_rng_hw->fwh_dec_en1_off,
240 intel_rng_hw->fwh_dec_en1_val |
241 FWH_F8_EN_MASK);
242 if (!(intel_rng_hw->bios_cntl_val & BIOS_CNTL_WRITE_ENABLE_MASK))
243 pci_write_config_byte(intel_rng_hw->dev,
244 intel_rng_hw->bios_cntl_off,
245 intel_rng_hw->bios_cntl_val |
246 BIOS_CNTL_WRITE_ENABLE_MASK);
247
248 writeb(INTEL_FWH_RESET_CMD, intel_rng_hw->mem);
249 writeb(INTEL_FWH_READ_ID_CMD, intel_rng_hw->mem);
250 mfc = readb(intel_rng_hw->mem + INTEL_FWH_MANUFACTURER_CODE_ADDRESS);
251 dvc = readb(intel_rng_hw->mem + INTEL_FWH_DEVICE_CODE_ADDRESS);
252 writeb(INTEL_FWH_RESET_CMD, intel_rng_hw->mem);
253
254 if (!(intel_rng_hw->bios_cntl_val &
255 (BIOS_CNTL_LOCK_ENABLE_MASK|BIOS_CNTL_WRITE_ENABLE_MASK)))
256 pci_write_config_byte(intel_rng_hw->dev,
257 intel_rng_hw->bios_cntl_off,
258 intel_rng_hw->bios_cntl_val);
259 if (!(intel_rng_hw->fwh_dec_en1_val & FWH_F8_EN_MASK))
260 pci_write_config_byte(intel_rng_hw->dev,
261 intel_rng_hw->fwh_dec_en1_off,
262 intel_rng_hw->fwh_dec_en1_val);
223 263
224static void __init intel_init_wait(void *unused) 264 if (mfc != INTEL_FWH_MANUFACTURER_CODE ||
265 (dvc != INTEL_FWH_DEVICE_CODE_8M &&
266 dvc != INTEL_FWH_DEVICE_CODE_4M)) {
267 printk(KERN_ERR PFX "FWH not detected\n");
268 return -ENODEV;
269 }
270
271 return 0;
272}
273
274static int __init intel_init_hw_struct(struct intel_rng_hw *intel_rng_hw,
275 struct pci_dev *dev)
225{ 276{
226 while (waitflag) 277 intel_rng_hw->bios_cntl_val = 0xff;
227 cpu_relax(); 278 intel_rng_hw->fwh_dec_en1_val = 0xff;
279 intel_rng_hw->dev = dev;
280
281 /* Check for Intel 82802 */
282 if (dev->device < 0x2640) {
283 intel_rng_hw->fwh_dec_en1_off = FWH_DEC_EN1_REG_OLD;
284 intel_rng_hw->bios_cntl_off = BIOS_CNTL_REG_OLD;
285 } else {
286 intel_rng_hw->fwh_dec_en1_off = FWH_DEC_EN1_REG_NEW;
287 intel_rng_hw->bios_cntl_off = BIOS_CNTL_REG_NEW;
288 }
289
290 pci_read_config_byte(dev, intel_rng_hw->fwh_dec_en1_off,
291 &intel_rng_hw->fwh_dec_en1_val);
292 pci_read_config_byte(dev, intel_rng_hw->bios_cntl_off,
293 &intel_rng_hw->bios_cntl_val);
294
295 if ((intel_rng_hw->bios_cntl_val &
296 (BIOS_CNTL_LOCK_ENABLE_MASK|BIOS_CNTL_WRITE_ENABLE_MASK))
297 == BIOS_CNTL_LOCK_ENABLE_MASK) {
298 static __initdata /*const*/ char warning[] =
299 KERN_WARNING PFX "Firmware space is locked read-only. "
300 KERN_WARNING PFX "If you can't or\n don't want to "
301 KERN_WARNING PFX "disable this in firmware setup, and "
302 KERN_WARNING PFX "if\n you are certain that your "
303 KERN_WARNING PFX "system has a functional\n RNG, try"
304 KERN_WARNING PFX "using the 'no_fwh_detect' option.\n";
305
306 if (no_fwh_detect)
307 return -ENODEV;
308 printk(warning);
309 return -EBUSY;
310 }
311
312 intel_rng_hw->mem = ioremap_nocache(INTEL_FWH_ADDR, INTEL_FWH_ADDR_LEN);
313 if (intel_rng_hw->mem == NULL)
314 return -EBUSY;
315
316 return 0;
228} 317}
229#endif 318
230 319
231static int __init mod_init(void) 320static int __init mod_init(void)
232{ 321{
233 int err = -ENODEV; 322 int err = -ENODEV;
234 unsigned i; 323 int i;
235 struct pci_dev *dev = NULL; 324 struct pci_dev *dev = NULL;
236 void __iomem *mem; 325 void __iomem *mem = mem;
237 unsigned long flags; 326 u8 hw_status;
238 u8 bios_cntl_off, fwh_dec_en1_off; 327 struct intel_rng_hw *intel_rng_hw;
239 u8 bios_cntl_val = 0xff, fwh_dec_en1_val = 0xff;
240 u8 hw_status, mfc, dvc;
241 328
242 for (i = 0; !dev && pci_tbl[i].vendor; ++i) 329 for (i = 0; !dev && pci_tbl[i].vendor; ++i)
243 dev = pci_get_device(pci_tbl[i].vendor, pci_tbl[i].device, NULL); 330 dev = pci_get_device(pci_tbl[i].vendor, pci_tbl[i].device,
331 NULL);
244 332
245 if (!dev) 333 if (!dev)
246 goto out; /* Device not found. */ 334 goto out; /* Device not found. */
@@ -250,39 +338,18 @@ static int __init mod_init(void)
250 goto fwh_done; 338 goto fwh_done;
251 } 339 }
252 340
253 /* Check for Intel 82802 */ 341 intel_rng_hw = kmalloc(sizeof(*intel_rng_hw), GFP_KERNEL);
254 if (dev->device < 0x2640) { 342 if (!intel_rng_hw) {
255 fwh_dec_en1_off = FWH_DEC_EN1_REG_OLD;
256 bios_cntl_off = BIOS_CNTL_REG_OLD;
257 } else {
258 fwh_dec_en1_off = FWH_DEC_EN1_REG_NEW;
259 bios_cntl_off = BIOS_CNTL_REG_NEW;
260 }
261
262 pci_read_config_byte(dev, fwh_dec_en1_off, &fwh_dec_en1_val);
263 pci_read_config_byte(dev, bios_cntl_off, &bios_cntl_val);
264
265 if ((bios_cntl_val &
266 (BIOS_CNTL_LOCK_ENABLE_MASK|BIOS_CNTL_WRITE_ENABLE_MASK))
267 == BIOS_CNTL_LOCK_ENABLE_MASK) {
268 static __initdata /*const*/ char warning[] =
269 KERN_WARNING PFX "Firmware space is locked read-only. If you can't or\n"
270 KERN_WARNING PFX "don't want to disable this in firmware setup, and if\n"
271 KERN_WARNING PFX "you are certain that your system has a functional\n"
272 KERN_WARNING PFX "RNG, try using the 'no_fwh_detect' option.\n";
273
274 pci_dev_put(dev); 343 pci_dev_put(dev);
275 if (no_fwh_detect)
276 goto fwh_done;
277 printk(warning);
278 err = -EBUSY;
279 goto out; 344 goto out;
280 } 345 }
281 346
282 mem = ioremap_nocache(INTEL_FWH_ADDR, INTEL_FWH_ADDR_LEN); 347 err = intel_init_hw_struct(intel_rng_hw, dev);
283 if (mem == NULL) { 348 if (err) {
284 pci_dev_put(dev); 349 pci_dev_put(dev);
285 err = -EBUSY; 350 kfree(intel_rng_hw);
351 if (err == -ENODEV)
352 goto fwh_done;
286 goto out; 353 goto out;
287 } 354 }
288 355
@@ -290,59 +357,18 @@ static int __init mod_init(void)
290 * Since the BIOS code/data is going to disappear from its normal 357 * Since the BIOS code/data is going to disappear from its normal
291 * location with the Read ID command, all activity on the system 358 * location with the Read ID command, all activity on the system
292 * must be stopped until the state is back to normal. 359 * must be stopped until the state is back to normal.
360 *
361 * Use stop_machine_run because IPIs can be blocked by disabling
362 * interrupts.
293 */ 363 */
294#ifdef CONFIG_SMP 364 err = stop_machine_run(intel_rng_hw_init, intel_rng_hw, NR_CPUS);
295 set_mb(waitflag, 1);
296 if (smp_call_function(intel_init_wait, NULL, 1, 0) != 0) {
297 set_mb(waitflag, 0);
298 pci_dev_put(dev);
299 printk(KERN_ERR PFX "cannot run on all processors\n");
300 err = -EAGAIN;
301 goto err_unmap;
302 }
303#endif
304 local_irq_save(flags);
305
306 if (!(fwh_dec_en1_val & FWH_F8_EN_MASK))
307 pci_write_config_byte(dev,
308 fwh_dec_en1_off,
309 fwh_dec_en1_val | FWH_F8_EN_MASK);
310 if (!(bios_cntl_val & BIOS_CNTL_WRITE_ENABLE_MASK))
311 pci_write_config_byte(dev,
312 bios_cntl_off,
313 bios_cntl_val | BIOS_CNTL_WRITE_ENABLE_MASK);
314
315 writeb(INTEL_FWH_RESET_CMD, mem);
316 writeb(INTEL_FWH_READ_ID_CMD, mem);
317 mfc = readb(mem + INTEL_FWH_MANUFACTURER_CODE_ADDRESS);
318 dvc = readb(mem + INTEL_FWH_DEVICE_CODE_ADDRESS);
319 writeb(INTEL_FWH_RESET_CMD, mem);
320
321 if (!(bios_cntl_val &
322 (BIOS_CNTL_LOCK_ENABLE_MASK|BIOS_CNTL_WRITE_ENABLE_MASK)))
323 pci_write_config_byte(dev, bios_cntl_off, bios_cntl_val);
324 if (!(fwh_dec_en1_val & FWH_F8_EN_MASK))
325 pci_write_config_byte(dev, fwh_dec_en1_off, fwh_dec_en1_val);
326
327 local_irq_restore(flags);
328#ifdef CONFIG_SMP
329 /* Tell other CPUs to resume. */
330 set_mb(waitflag, 0);
331#endif
332
333 iounmap(mem);
334 pci_dev_put(dev); 365 pci_dev_put(dev);
335 366 iounmap(intel_rng_hw->mem);
336 if (mfc != INTEL_FWH_MANUFACTURER_CODE || 367 kfree(intel_rng_hw);
337 (dvc != INTEL_FWH_DEVICE_CODE_8M && 368 if (err)
338 dvc != INTEL_FWH_DEVICE_CODE_4M)) {
339 printk(KERN_ERR PFX "FWH not detected\n");
340 err = -ENODEV;
341 goto out; 369 goto out;
342 }
343 370
344fwh_done: 371fwh_done:
345
346 err = -ENOMEM; 372 err = -ENOMEM;
347 mem = ioremap(INTEL_RNG_ADDR, INTEL_RNG_ADDR_LEN); 373 mem = ioremap(INTEL_RNG_ADDR, INTEL_RNG_ADDR_LEN);
348 if (!mem) 374 if (!mem)
@@ -352,22 +378,21 @@ fwh_done:
352 /* Check for Random Number Generator */ 378 /* Check for Random Number Generator */
353 err = -ENODEV; 379 err = -ENODEV;
354 hw_status = hwstatus_get(mem); 380 hw_status = hwstatus_get(mem);
355 if ((hw_status & INTEL_RNG_PRESENT) == 0) 381 if ((hw_status & INTEL_RNG_PRESENT) == 0) {
356 goto err_unmap; 382 iounmap(mem);
383 goto out;
384 }
357 385
358 printk(KERN_INFO "Intel 82802 RNG detected\n"); 386 printk(KERN_INFO "Intel 82802 RNG detected\n");
359 err = hwrng_register(&intel_rng); 387 err = hwrng_register(&intel_rng);
360 if (err) { 388 if (err) {
361 printk(KERN_ERR PFX "RNG registering failed (%d)\n", 389 printk(KERN_ERR PFX "RNG registering failed (%d)\n",
362 err); 390 err);
363 goto err_unmap; 391 iounmap(mem);
364 } 392 }
365out: 393out:
366 return err; 394 return err;
367 395
368err_unmap:
369 iounmap(mem);
370 goto out;
371} 396}
372 397
373static void __exit mod_exit(void) 398static void __exit mod_exit(void)
diff --git a/drivers/char/i8k.c b/drivers/char/i8k.c
index 353d9f3cf8d7..0289705967de 100644
--- a/drivers/char/i8k.c
+++ b/drivers/char/i8k.c
@@ -22,6 +22,7 @@
22#include <linux/proc_fs.h> 22#include <linux/proc_fs.h>
23#include <linux/seq_file.h> 23#include <linux/seq_file.h>
24#include <linux/dmi.h> 24#include <linux/dmi.h>
25#include <linux/capability.h>
25#include <asm/uaccess.h> 26#include <asm/uaccess.h>
26#include <asm/io.h> 27#include <asm/io.h>
27 28
diff --git a/drivers/char/ip27-rtc.c b/drivers/char/ip27-rtc.c
index a48da02aad2f..932264a657d0 100644
--- a/drivers/char/ip27-rtc.c
+++ b/drivers/char/ip27-rtc.c
@@ -35,7 +35,6 @@
35#include <linux/init.h> 35#include <linux/init.h>
36#include <linux/poll.h> 36#include <linux/poll.h>
37#include <linux/proc_fs.h> 37#include <linux/proc_fs.h>
38#include <linux/smp_lock.h>
39 38
40#include <asm/m48t35.h> 39#include <asm/m48t35.h>
41#include <asm/sn/ioc3.h> 40#include <asm/sn/ioc3.h>
diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c
index e22146546add..6c5d15de3317 100644
--- a/drivers/char/ipmi/ipmi_si_intf.c
+++ b/drivers/char/ipmi/ipmi_si_intf.c
@@ -9,6 +9,7 @@
9 * source@mvista.com 9 * source@mvista.com
10 * 10 *
11 * Copyright 2002 MontaVista Software Inc. 11 * Copyright 2002 MontaVista Software Inc.
12 * Copyright 2006 IBM Corp., Christian Krafft <krafft@de.ibm.com>
12 * 13 *
13 * This program is free software; you can redistribute it and/or modify it 14 * This program is free software; you can redistribute it and/or modify it
14 * under the terms of the GNU General Public License as published by the 15 * under the terms of the GNU General Public License as published by the
@@ -64,6 +65,11 @@
64#include <linux/string.h> 65#include <linux/string.h>
65#include <linux/ctype.h> 66#include <linux/ctype.h>
66 67
68#ifdef CONFIG_PPC_OF
69#include <asm/of_device.h>
70#include <asm/of_platform.h>
71#endif
72
67#define PFX "ipmi_si: " 73#define PFX "ipmi_si: "
68 74
69/* Measure times between events in the driver. */ 75/* Measure times between events in the driver. */
@@ -76,6 +82,12 @@
76#define SI_SHORT_TIMEOUT_USEC 250 /* .25ms when the SM request a 82#define SI_SHORT_TIMEOUT_USEC 250 /* .25ms when the SM request a
77 short timeout */ 83 short timeout */
78 84
85/* Bit for BMC global enables. */
86#define IPMI_BMC_RCV_MSG_INTR 0x01
87#define IPMI_BMC_EVT_MSG_INTR 0x02
88#define IPMI_BMC_EVT_MSG_BUFF 0x04
89#define IPMI_BMC_SYS_LOG 0x08
90
79enum si_intf_state { 91enum si_intf_state {
80 SI_NORMAL, 92 SI_NORMAL,
81 SI_GETTING_FLAGS, 93 SI_GETTING_FLAGS,
@@ -84,7 +96,9 @@ enum si_intf_state {
84 SI_CLEARING_FLAGS_THEN_SET_IRQ, 96 SI_CLEARING_FLAGS_THEN_SET_IRQ,
85 SI_GETTING_MESSAGES, 97 SI_GETTING_MESSAGES,
86 SI_ENABLE_INTERRUPTS1, 98 SI_ENABLE_INTERRUPTS1,
87 SI_ENABLE_INTERRUPTS2 99 SI_ENABLE_INTERRUPTS2,
100 SI_DISABLE_INTERRUPTS1,
101 SI_DISABLE_INTERRUPTS2
88 /* FIXME - add watchdog stuff. */ 102 /* FIXME - add watchdog stuff. */
89}; 103};
90 104
@@ -333,6 +347,17 @@ static void start_enable_irq(struct smi_info *smi_info)
333 smi_info->si_state = SI_ENABLE_INTERRUPTS1; 347 smi_info->si_state = SI_ENABLE_INTERRUPTS1;
334} 348}
335 349
350static void start_disable_irq(struct smi_info *smi_info)
351{
352 unsigned char msg[2];
353
354 msg[0] = (IPMI_NETFN_APP_REQUEST << 2);
355 msg[1] = IPMI_GET_BMC_GLOBAL_ENABLES_CMD;
356
357 smi_info->handlers->start_transaction(smi_info->si_sm, msg, 2);
358 smi_info->si_state = SI_DISABLE_INTERRUPTS1;
359}
360
336static void start_clear_flags(struct smi_info *smi_info) 361static void start_clear_flags(struct smi_info *smi_info)
337{ 362{
338 unsigned char msg[3]; 363 unsigned char msg[3];
@@ -353,7 +378,7 @@ static void start_clear_flags(struct smi_info *smi_info)
353static inline void disable_si_irq(struct smi_info *smi_info) 378static inline void disable_si_irq(struct smi_info *smi_info)
354{ 379{
355 if ((smi_info->irq) && (!smi_info->interrupt_disabled)) { 380 if ((smi_info->irq) && (!smi_info->interrupt_disabled)) {
356 disable_irq_nosync(smi_info->irq); 381 start_disable_irq(smi_info);
357 smi_info->interrupt_disabled = 1; 382 smi_info->interrupt_disabled = 1;
358 } 383 }
359} 384}
@@ -361,7 +386,7 @@ static inline void disable_si_irq(struct smi_info *smi_info)
361static inline void enable_si_irq(struct smi_info *smi_info) 386static inline void enable_si_irq(struct smi_info *smi_info)
362{ 387{
363 if ((smi_info->irq) && (smi_info->interrupt_disabled)) { 388 if ((smi_info->irq) && (smi_info->interrupt_disabled)) {
364 enable_irq(smi_info->irq); 389 start_enable_irq(smi_info);
365 smi_info->interrupt_disabled = 0; 390 smi_info->interrupt_disabled = 0;
366 } 391 }
367} 392}
@@ -583,7 +608,9 @@ static void handle_transaction_done(struct smi_info *smi_info)
583 } else { 608 } else {
584 msg[0] = (IPMI_NETFN_APP_REQUEST << 2); 609 msg[0] = (IPMI_NETFN_APP_REQUEST << 2);
585 msg[1] = IPMI_SET_BMC_GLOBAL_ENABLES_CMD; 610 msg[1] = IPMI_SET_BMC_GLOBAL_ENABLES_CMD;
586 msg[2] = msg[3] | 1; /* enable msg queue int */ 611 msg[2] = (msg[3] |
612 IPMI_BMC_RCV_MSG_INTR |
613 IPMI_BMC_EVT_MSG_INTR);
587 smi_info->handlers->start_transaction( 614 smi_info->handlers->start_transaction(
588 smi_info->si_sm, msg, 3); 615 smi_info->si_sm, msg, 3);
589 smi_info->si_state = SI_ENABLE_INTERRUPTS2; 616 smi_info->si_state = SI_ENABLE_INTERRUPTS2;
@@ -605,6 +632,45 @@ static void handle_transaction_done(struct smi_info *smi_info)
605 smi_info->si_state = SI_NORMAL; 632 smi_info->si_state = SI_NORMAL;
606 break; 633 break;
607 } 634 }
635
636 case SI_DISABLE_INTERRUPTS1:
637 {
638 unsigned char msg[4];
639
640 /* We got the flags from the SMI, now handle them. */
641 smi_info->handlers->get_result(smi_info->si_sm, msg, 4);
642 if (msg[2] != 0) {
643 printk(KERN_WARNING
644 "ipmi_si: Could not disable interrupts"
645 ", failed get.\n");
646 smi_info->si_state = SI_NORMAL;
647 } else {
648 msg[0] = (IPMI_NETFN_APP_REQUEST << 2);
649 msg[1] = IPMI_SET_BMC_GLOBAL_ENABLES_CMD;
650 msg[2] = (msg[3] &
651 ~(IPMI_BMC_RCV_MSG_INTR |
652 IPMI_BMC_EVT_MSG_INTR));
653 smi_info->handlers->start_transaction(
654 smi_info->si_sm, msg, 3);
655 smi_info->si_state = SI_DISABLE_INTERRUPTS2;
656 }
657 break;
658 }
659
660 case SI_DISABLE_INTERRUPTS2:
661 {
662 unsigned char msg[4];
663
664 /* We got the flags from the SMI, now handle them. */
665 smi_info->handlers->get_result(smi_info->si_sm, msg, 4);
666 if (msg[2] != 0) {
667 printk(KERN_WARNING
668 "ipmi_si: Could not disable interrupts"
669 ", failed set.\n");
670 }
671 smi_info->si_state = SI_NORMAL;
672 break;
673 }
608 } 674 }
609} 675}
610 676
@@ -858,9 +924,6 @@ static void smi_timeout(unsigned long data)
858 struct timeval t; 924 struct timeval t;
859#endif 925#endif
860 926
861 if (atomic_read(&smi_info->stop_operation))
862 return;
863
864 spin_lock_irqsave(&(smi_info->si_lock), flags); 927 spin_lock_irqsave(&(smi_info->si_lock), flags);
865#ifdef DEBUG_TIMING 928#ifdef DEBUG_TIMING
866 do_gettimeofday(&t); 929 do_gettimeofday(&t);
@@ -916,15 +979,11 @@ static irqreturn_t si_irq_handler(int irq, void *data)
916 smi_info->interrupts++; 979 smi_info->interrupts++;
917 spin_unlock(&smi_info->count_lock); 980 spin_unlock(&smi_info->count_lock);
918 981
919 if (atomic_read(&smi_info->stop_operation))
920 goto out;
921
922#ifdef DEBUG_TIMING 982#ifdef DEBUG_TIMING
923 do_gettimeofday(&t); 983 do_gettimeofday(&t);
924 printk("**Interrupt: %d.%9.9d\n", t.tv_sec, t.tv_usec); 984 printk("**Interrupt: %d.%9.9d\n", t.tv_sec, t.tv_usec);
925#endif 985#endif
926 smi_event_handler(smi_info, 0); 986 smi_event_handler(smi_info, 0);
927 out:
928 spin_unlock_irqrestore(&(smi_info->si_lock), flags); 987 spin_unlock_irqrestore(&(smi_info->si_lock), flags);
929 return IRQ_HANDLED; 988 return IRQ_HANDLED;
930} 989}
@@ -1006,6 +1065,7 @@ static DEFINE_MUTEX(smi_infos_lock);
1006static int smi_num; /* Used to sequence the SMIs */ 1065static int smi_num; /* Used to sequence the SMIs */
1007 1066
1008#define DEFAULT_REGSPACING 1 1067#define DEFAULT_REGSPACING 1
1068#define DEFAULT_REGSIZE 1
1009 1069
1010static int si_trydefaults = 1; 1070static int si_trydefaults = 1;
1011static char *si_type[SI_MAX_PARMS]; 1071static char *si_type[SI_MAX_PARMS];
@@ -1111,7 +1171,7 @@ static int std_irq_setup(struct smi_info *info)
1111 if (info->si_type == SI_BT) { 1171 if (info->si_type == SI_BT) {
1112 rv = request_irq(info->irq, 1172 rv = request_irq(info->irq,
1113 si_bt_irq_handler, 1173 si_bt_irq_handler,
1114 IRQF_DISABLED, 1174 IRQF_SHARED | IRQF_DISABLED,
1115 DEVICE_NAME, 1175 DEVICE_NAME,
1116 info); 1176 info);
1117 if (!rv) 1177 if (!rv)
@@ -1121,7 +1181,7 @@ static int std_irq_setup(struct smi_info *info)
1121 } else 1181 } else
1122 rv = request_irq(info->irq, 1182 rv = request_irq(info->irq,
1123 si_irq_handler, 1183 si_irq_handler,
1124 IRQF_DISABLED, 1184 IRQF_SHARED | IRQF_DISABLED,
1125 DEVICE_NAME, 1185 DEVICE_NAME,
1126 info); 1186 info);
1127 if (rv) { 1187 if (rv) {
@@ -1701,15 +1761,11 @@ static u32 ipmi_acpi_gpe(void *context)
1701 smi_info->interrupts++; 1761 smi_info->interrupts++;
1702 spin_unlock(&smi_info->count_lock); 1762 spin_unlock(&smi_info->count_lock);
1703 1763
1704 if (atomic_read(&smi_info->stop_operation))
1705 goto out;
1706
1707#ifdef DEBUG_TIMING 1764#ifdef DEBUG_TIMING
1708 do_gettimeofday(&t); 1765 do_gettimeofday(&t);
1709 printk("**ACPI_GPE: %d.%9.9d\n", t.tv_sec, t.tv_usec); 1766 printk("**ACPI_GPE: %d.%9.9d\n", t.tv_sec, t.tv_usec);
1710#endif 1767#endif
1711 smi_event_handler(smi_info, 0); 1768 smi_event_handler(smi_info, 0);
1712 out:
1713 spin_unlock_irqrestore(&(smi_info->si_lock), flags); 1769 spin_unlock_irqrestore(&(smi_info->si_lock), flags);
1714 1770
1715 return ACPI_INTERRUPT_HANDLED; 1771 return ACPI_INTERRUPT_HANDLED;
@@ -2133,12 +2189,15 @@ static int __devinit ipmi_pci_probe(struct pci_dev *pdev,
2133 info->irq_setup = std_irq_setup; 2189 info->irq_setup = std_irq_setup;
2134 2190
2135 info->dev = &pdev->dev; 2191 info->dev = &pdev->dev;
2192 pci_set_drvdata(pdev, info);
2136 2193
2137 return try_smi_init(info); 2194 return try_smi_init(info);
2138} 2195}
2139 2196
2140static void __devexit ipmi_pci_remove(struct pci_dev *pdev) 2197static void __devexit ipmi_pci_remove(struct pci_dev *pdev)
2141{ 2198{
2199 struct smi_info *info = pci_get_drvdata(pdev);
2200 cleanup_one_si(info);
2142} 2201}
2143 2202
2144#ifdef CONFIG_PM 2203#ifdef CONFIG_PM
@@ -2172,6 +2231,99 @@ static struct pci_driver ipmi_pci_driver = {
2172#endif /* CONFIG_PCI */ 2231#endif /* CONFIG_PCI */
2173 2232
2174 2233
2234#ifdef CONFIG_PPC_OF
2235static int __devinit ipmi_of_probe(struct of_device *dev,
2236 const struct of_device_id *match)
2237{
2238 struct smi_info *info;
2239 struct resource resource;
2240 const int *regsize, *regspacing, *regshift;
2241 struct device_node *np = dev->node;
2242 int ret;
2243 int proplen;
2244
2245 dev_info(&dev->dev, PFX "probing via device tree\n");
2246
2247 ret = of_address_to_resource(np, 0, &resource);
2248 if (ret) {
2249 dev_warn(&dev->dev, PFX "invalid address from OF\n");
2250 return ret;
2251 }
2252
2253 regsize = get_property(np, "reg-size", &proplen);
2254 if (regsize && proplen != 4) {
2255 dev_warn(&dev->dev, PFX "invalid regsize from OF\n");
2256 return -EINVAL;
2257 }
2258
2259 regspacing = get_property(np, "reg-spacing", &proplen);
2260 if (regspacing && proplen != 4) {
2261 dev_warn(&dev->dev, PFX "invalid regspacing from OF\n");
2262 return -EINVAL;
2263 }
2264
2265 regshift = get_property(np, "reg-shift", &proplen);
2266 if (regshift && proplen != 4) {
2267 dev_warn(&dev->dev, PFX "invalid regshift from OF\n");
2268 return -EINVAL;
2269 }
2270
2271 info = kzalloc(sizeof(*info), GFP_KERNEL);
2272
2273 if (!info) {
2274 dev_err(&dev->dev,
2275 PFX "could not allocate memory for OF probe\n");
2276 return -ENOMEM;
2277 }
2278
2279 info->si_type = (enum si_type) match->data;
2280 info->addr_source = "device-tree";
2281 info->io_setup = mem_setup;
2282 info->irq_setup = std_irq_setup;
2283
2284 info->io.addr_type = IPMI_MEM_ADDR_SPACE;
2285 info->io.addr_data = resource.start;
2286
2287 info->io.regsize = regsize ? *regsize : DEFAULT_REGSIZE;
2288 info->io.regspacing = regspacing ? *regspacing : DEFAULT_REGSPACING;
2289 info->io.regshift = regshift ? *regshift : 0;
2290
2291 info->irq = irq_of_parse_and_map(dev->node, 0);
2292 info->dev = &dev->dev;
2293
2294 dev_dbg(&dev->dev, "addr 0x%lx regsize %ld spacing %ld irq %x\n",
2295 info->io.addr_data, info->io.regsize, info->io.regspacing,
2296 info->irq);
2297
2298 dev->dev.driver_data = (void*) info;
2299
2300 return try_smi_init(info);
2301}
2302
2303static int __devexit ipmi_of_remove(struct of_device *dev)
2304{
2305 cleanup_one_si(dev->dev.driver_data);
2306 return 0;
2307}
2308
2309static struct of_device_id ipmi_match[] =
2310{
2311 { .type = "ipmi", .compatible = "ipmi-kcs", .data = (void *)(unsigned long) SI_KCS },
2312 { .type = "ipmi", .compatible = "ipmi-smic", .data = (void *)(unsigned long) SI_SMIC },
2313 { .type = "ipmi", .compatible = "ipmi-bt", .data = (void *)(unsigned long) SI_BT },
2314 {},
2315};
2316
2317static struct of_platform_driver ipmi_of_platform_driver =
2318{
2319 .name = "ipmi",
2320 .match_table = ipmi_match,
2321 .probe = ipmi_of_probe,
2322 .remove = __devexit_p(ipmi_of_remove),
2323};
2324#endif /* CONFIG_PPC_OF */
2325
2326
2175static int try_get_dev_id(struct smi_info *smi_info) 2327static int try_get_dev_id(struct smi_info *smi_info)
2176{ 2328{
2177 unsigned char msg[2]; 2329 unsigned char msg[2];
@@ -2801,6 +2953,10 @@ static __devinit int init_ipmi_si(void)
2801 } 2953 }
2802#endif 2954#endif
2803 2955
2956#ifdef CONFIG_PPC_OF
2957 of_register_platform_driver(&ipmi_of_platform_driver);
2958#endif
2959
2804 if (si_trydefaults) { 2960 if (si_trydefaults) {
2805 mutex_lock(&smi_infos_lock); 2961 mutex_lock(&smi_infos_lock);
2806 if (list_empty(&smi_infos)) { 2962 if (list_empty(&smi_infos)) {
@@ -2838,28 +2994,33 @@ static void cleanup_one_si(struct smi_info *to_clean)
2838 2994
2839 list_del(&to_clean->link); 2995 list_del(&to_clean->link);
2840 2996
2841 /* Tell the timer and interrupt handlers that we are shutting 2997 /* Tell the driver that we are shutting down. */
2842 down. */
2843 spin_lock_irqsave(&(to_clean->si_lock), flags);
2844 spin_lock(&(to_clean->msg_lock));
2845
2846 atomic_inc(&to_clean->stop_operation); 2998 atomic_inc(&to_clean->stop_operation);
2847 2999
2848 if (to_clean->irq_cleanup) 3000 /* Make sure the timer and thread are stopped and will not run
2849 to_clean->irq_cleanup(to_clean); 3001 again. */
2850
2851 spin_unlock(&(to_clean->msg_lock));
2852 spin_unlock_irqrestore(&(to_clean->si_lock), flags);
2853
2854 /* Wait until we know that we are out of any interrupt
2855 handlers might have been running before we freed the
2856 interrupt. */
2857 synchronize_sched();
2858
2859 wait_for_timer_and_thread(to_clean); 3002 wait_for_timer_and_thread(to_clean);
2860 3003
2861 /* Interrupts and timeouts are stopped, now make sure the 3004 /* Timeouts are stopped, now make sure the interrupts are off
2862 interface is in a clean state. */ 3005 for the device. A little tricky with locks to make sure
3006 there are no races. */
3007 spin_lock_irqsave(&to_clean->si_lock, flags);
3008 while (to_clean->curr_msg || (to_clean->si_state != SI_NORMAL)) {
3009 spin_unlock_irqrestore(&to_clean->si_lock, flags);
3010 poll(to_clean);
3011 schedule_timeout_uninterruptible(1);
3012 spin_lock_irqsave(&to_clean->si_lock, flags);
3013 }
3014 disable_si_irq(to_clean);
3015 spin_unlock_irqrestore(&to_clean->si_lock, flags);
3016 while (to_clean->curr_msg || (to_clean->si_state != SI_NORMAL)) {
3017 poll(to_clean);
3018 schedule_timeout_uninterruptible(1);
3019 }
3020
3021 /* Clean up interrupts and make sure that everything is done. */
3022 if (to_clean->irq_cleanup)
3023 to_clean->irq_cleanup(to_clean);
2863 while (to_clean->curr_msg || (to_clean->si_state != SI_NORMAL)) { 3024 while (to_clean->curr_msg || (to_clean->si_state != SI_NORMAL)) {
2864 poll(to_clean); 3025 poll(to_clean);
2865 schedule_timeout_uninterruptible(1); 3026 schedule_timeout_uninterruptible(1);
@@ -2898,6 +3059,10 @@ static __exit void cleanup_ipmi_si(void)
2898 pci_unregister_driver(&ipmi_pci_driver); 3059 pci_unregister_driver(&ipmi_pci_driver);
2899#endif 3060#endif
2900 3061
3062#ifdef CONFIG_PPC_OF
3063 of_unregister_platform_driver(&ipmi_of_platform_driver);
3064#endif
3065
2901 mutex_lock(&smi_infos_lock); 3066 mutex_lock(&smi_infos_lock);
2902 list_for_each_entry_safe(e, tmp_e, &smi_infos, link) 3067 list_for_each_entry_safe(e, tmp_e, &smi_infos, link)
2903 cleanup_one_si(e); 3068 cleanup_one_si(e);
diff --git a/drivers/char/ipmi/ipmi_watchdog.c b/drivers/char/ipmi/ipmi_watchdog.c
index 6b634e8d9519..147c12047cf3 100644
--- a/drivers/char/ipmi/ipmi_watchdog.c
+++ b/drivers/char/ipmi/ipmi_watchdog.c
@@ -39,6 +39,7 @@
39#include <linux/miscdevice.h> 39#include <linux/miscdevice.h>
40#include <linux/init.h> 40#include <linux/init.h>
41#include <linux/completion.h> 41#include <linux/completion.h>
42#include <linux/kdebug.h>
42#include <linux/rwsem.h> 43#include <linux/rwsem.h>
43#include <linux/errno.h> 44#include <linux/errno.h>
44#include <asm/uaccess.h> 45#include <asm/uaccess.h>
@@ -49,9 +50,18 @@
49#include <linux/poll.h> 50#include <linux/poll.h>
50#include <linux/string.h> 51#include <linux/string.h>
51#include <linux/ctype.h> 52#include <linux/ctype.h>
53#include <linux/delay.h>
52#include <asm/atomic.h> 54#include <asm/atomic.h>
53#ifdef CONFIG_X86_LOCAL_APIC 55
54#include <asm/apic.h> 56#ifdef CONFIG_X86
57/* This is ugly, but I've determined that x86 is the only architecture
58 that can reasonably support the IPMI NMI watchdog timeout at this
59 time. If another architecture adds this capability somehow, it
60 will have to be a somewhat different mechanism and I have no idea
61 how it will work. So in the unlikely event that another
62 architecture supports this, we can figure out a good generic
63 mechanism for it at that time. */
64#define HAVE_DIE_NMI_POST
55#endif 65#endif
56 66
57#define PFX "IPMI Watchdog: " 67#define PFX "IPMI Watchdog: "
@@ -317,6 +327,11 @@ static unsigned char ipmi_version_minor;
317/* If a pretimeout occurs, this is used to allow only one panic to happen. */ 327/* If a pretimeout occurs, this is used to allow only one panic to happen. */
318static atomic_t preop_panic_excl = ATOMIC_INIT(-1); 328static atomic_t preop_panic_excl = ATOMIC_INIT(-1);
319 329
330#ifdef HAVE_DIE_NMI_POST
331static int testing_nmi;
332static int nmi_handler_registered;
333#endif
334
320static int ipmi_heartbeat(void); 335static int ipmi_heartbeat(void);
321static void panic_halt_ipmi_heartbeat(void); 336static void panic_halt_ipmi_heartbeat(void);
322 337
@@ -358,6 +373,10 @@ static int i_ipmi_set_timeout(struct ipmi_smi_msg *smi_msg,
358 int hbnow = 0; 373 int hbnow = 0;
359 374
360 375
376 /* These can be cleared as we are setting the timeout. */
377 ipmi_start_timer_on_heartbeat = 0;
378 pretimeout_since_last_heartbeat = 0;
379
361 data[0] = 0; 380 data[0] = 0;
362 WDOG_SET_TIMER_USE(data[0], WDOG_TIMER_USE_SMS_OS); 381 WDOG_SET_TIMER_USE(data[0], WDOG_TIMER_USE_SMS_OS);
363 382
@@ -432,13 +451,12 @@ static int ipmi_set_timeout(int do_heartbeat)
432 451
433 wait_for_completion(&set_timeout_wait); 452 wait_for_completion(&set_timeout_wait);
434 453
454 mutex_unlock(&set_timeout_lock);
455
435 if ((do_heartbeat == IPMI_SET_TIMEOUT_FORCE_HB) 456 if ((do_heartbeat == IPMI_SET_TIMEOUT_FORCE_HB)
436 || ((send_heartbeat_now) 457 || ((send_heartbeat_now)
437 && (do_heartbeat == IPMI_SET_TIMEOUT_HB_IF_NECESSARY))) 458 && (do_heartbeat == IPMI_SET_TIMEOUT_HB_IF_NECESSARY)))
438 {
439 rv = ipmi_heartbeat(); 459 rv = ipmi_heartbeat();
440 }
441 mutex_unlock(&set_timeout_lock);
442 460
443out: 461out:
444 return rv; 462 return rv;
@@ -518,12 +536,10 @@ static int ipmi_heartbeat(void)
518 int rv; 536 int rv;
519 struct ipmi_system_interface_addr addr; 537 struct ipmi_system_interface_addr addr;
520 538
521 if (ipmi_ignore_heartbeat) { 539 if (ipmi_ignore_heartbeat)
522 return 0; 540 return 0;
523 }
524 541
525 if (ipmi_start_timer_on_heartbeat) { 542 if (ipmi_start_timer_on_heartbeat) {
526 ipmi_start_timer_on_heartbeat = 0;
527 ipmi_watchdog_state = action_val; 543 ipmi_watchdog_state = action_val;
528 return ipmi_set_timeout(IPMI_SET_TIMEOUT_FORCE_HB); 544 return ipmi_set_timeout(IPMI_SET_TIMEOUT_FORCE_HB);
529 } else if (pretimeout_since_last_heartbeat) { 545 } else if (pretimeout_since_last_heartbeat) {
@@ -531,7 +547,6 @@ static int ipmi_heartbeat(void)
531 We don't want to set the action, though, we want to 547 We don't want to set the action, though, we want to
532 leave that alone (thus it can't be combined with the 548 leave that alone (thus it can't be combined with the
533 above operation. */ 549 above operation. */
534 pretimeout_since_last_heartbeat = 0;
535 return ipmi_set_timeout(IPMI_SET_TIMEOUT_HB_IF_NECESSARY); 550 return ipmi_set_timeout(IPMI_SET_TIMEOUT_HB_IF_NECESSARY);
536 } 551 }
537 552
@@ -919,6 +934,45 @@ static void ipmi_register_watchdog(int ipmi_intf)
919 printk(KERN_CRIT PFX "Unable to register misc device\n"); 934 printk(KERN_CRIT PFX "Unable to register misc device\n");
920 } 935 }
921 936
937#ifdef HAVE_DIE_NMI_POST
938 if (nmi_handler_registered) {
939 int old_pretimeout = pretimeout;
940 int old_timeout = timeout;
941 int old_preop_val = preop_val;
942
943 /* Set the pretimeout to go off in a second and give
944 ourselves plenty of time to stop the timer. */
945 ipmi_watchdog_state = WDOG_TIMEOUT_RESET;
946 preop_val = WDOG_PREOP_NONE; /* Make sure nothing happens */
947 pretimeout = 99;
948 timeout = 100;
949
950 testing_nmi = 1;
951
952 rv = ipmi_set_timeout(IPMI_SET_TIMEOUT_FORCE_HB);
953 if (rv) {
954 printk(KERN_WARNING PFX "Error starting timer to"
955 " test NMI: 0x%x. The NMI pretimeout will"
956 " likely not work\n", rv);
957 rv = 0;
958 goto out_restore;
959 }
960
961 msleep(1500);
962
963 if (testing_nmi != 2) {
964 printk(KERN_WARNING PFX "IPMI NMI didn't seem to"
965 " occur. The NMI pretimeout will"
966 " likely not work\n");
967 }
968 out_restore:
969 testing_nmi = 0;
970 preop_val = old_preop_val;
971 pretimeout = old_pretimeout;
972 timeout = old_timeout;
973 }
974#endif
975
922 out: 976 out:
923 up_write(&register_sem); 977 up_write(&register_sem);
924 978
@@ -928,6 +982,10 @@ static void ipmi_register_watchdog(int ipmi_intf)
928 ipmi_watchdog_state = action_val; 982 ipmi_watchdog_state = action_val;
929 ipmi_set_timeout(IPMI_SET_TIMEOUT_FORCE_HB); 983 ipmi_set_timeout(IPMI_SET_TIMEOUT_FORCE_HB);
930 printk(KERN_INFO PFX "Starting now!\n"); 984 printk(KERN_INFO PFX "Starting now!\n");
985 } else {
986 /* Stop the timer now. */
987 ipmi_watchdog_state = WDOG_TIMEOUT_NONE;
988 ipmi_set_timeout(IPMI_SET_TIMEOUT_NO_HB);
931 } 989 }
932} 990}
933 991
@@ -964,17 +1022,28 @@ static void ipmi_unregister_watchdog(int ipmi_intf)
964 up_write(&register_sem); 1022 up_write(&register_sem);
965} 1023}
966 1024
967#ifdef HAVE_NMI_HANDLER 1025#ifdef HAVE_DIE_NMI_POST
968static int 1026static int
969ipmi_nmi(void *dev_id, int cpu, int handled) 1027ipmi_nmi(struct notifier_block *self, unsigned long val, void *data)
970{ 1028{
1029 if (val != DIE_NMI_POST)
1030 return NOTIFY_OK;
1031
1032 if (testing_nmi) {
1033 testing_nmi = 2;
1034 return NOTIFY_STOP;
1035 }
1036
971 /* If we are not expecting a timeout, ignore it. */ 1037 /* If we are not expecting a timeout, ignore it. */
972 if (ipmi_watchdog_state == WDOG_TIMEOUT_NONE) 1038 if (ipmi_watchdog_state == WDOG_TIMEOUT_NONE)
973 return NOTIFY_DONE; 1039 return NOTIFY_OK;
1040
1041 if (preaction_val != WDOG_PRETIMEOUT_NMI)
1042 return NOTIFY_OK;
974 1043
975 /* If no one else handled the NMI, we assume it was the IPMI 1044 /* If no one else handled the NMI, we assume it was the IPMI
976 watchdog. */ 1045 watchdog. */
977 if ((!handled) && (preop_val == WDOG_PREOP_PANIC)) { 1046 if (preop_val == WDOG_PREOP_PANIC) {
978 /* On some machines, the heartbeat will give 1047 /* On some machines, the heartbeat will give
979 an error and not work unless we re-enable 1048 an error and not work unless we re-enable
980 the timer. So do so. */ 1049 the timer. So do so. */
@@ -983,18 +1052,12 @@ ipmi_nmi(void *dev_id, int cpu, int handled)
983 panic(PFX "pre-timeout"); 1052 panic(PFX "pre-timeout");
984 } 1053 }
985 1054
986 return NOTIFY_DONE; 1055 return NOTIFY_STOP;
987} 1056}
988 1057
989static struct nmi_handler ipmi_nmi_handler = 1058static struct notifier_block ipmi_nmi_handler = {
990{ 1059 .notifier_call = ipmi_nmi
991 .link = LIST_HEAD_INIT(ipmi_nmi_handler.link),
992 .dev_name = "ipmi_watchdog",
993 .dev_id = NULL,
994 .handler = ipmi_nmi,
995 .priority = 0, /* Call us last. */
996}; 1060};
997int nmi_handler_registered;
998#endif 1061#endif
999 1062
1000static int wdog_reboot_handler(struct notifier_block *this, 1063static int wdog_reboot_handler(struct notifier_block *this,
@@ -1111,7 +1174,7 @@ static int preaction_op(const char *inval, char *outval)
1111 preaction_val = WDOG_PRETIMEOUT_NONE; 1174 preaction_val = WDOG_PRETIMEOUT_NONE;
1112 else if (strcmp(inval, "pre_smi") == 0) 1175 else if (strcmp(inval, "pre_smi") == 0)
1113 preaction_val = WDOG_PRETIMEOUT_SMI; 1176 preaction_val = WDOG_PRETIMEOUT_SMI;
1114#ifdef HAVE_NMI_HANDLER 1177#ifdef HAVE_DIE_NMI_POST
1115 else if (strcmp(inval, "pre_nmi") == 0) 1178 else if (strcmp(inval, "pre_nmi") == 0)
1116 preaction_val = WDOG_PRETIMEOUT_NMI; 1179 preaction_val = WDOG_PRETIMEOUT_NMI;
1117#endif 1180#endif
@@ -1145,7 +1208,7 @@ static int preop_op(const char *inval, char *outval)
1145 1208
1146static void check_parms(void) 1209static void check_parms(void)
1147{ 1210{
1148#ifdef HAVE_NMI_HANDLER 1211#ifdef HAVE_DIE_NMI_POST
1149 int do_nmi = 0; 1212 int do_nmi = 0;
1150 int rv; 1213 int rv;
1151 1214
@@ -1158,20 +1221,9 @@ static void check_parms(void)
1158 preop_op("preop_none", NULL); 1221 preop_op("preop_none", NULL);
1159 do_nmi = 0; 1222 do_nmi = 0;
1160 } 1223 }
1161#ifdef CONFIG_X86_LOCAL_APIC
1162 if (nmi_watchdog == NMI_IO_APIC) {
1163 printk(KERN_WARNING PFX "nmi_watchdog is set to IO APIC"
1164 " mode (value is %d), that is incompatible"
1165 " with using NMI in the IPMI watchdog."
1166 " Disabling IPMI nmi pretimeout.\n",
1167 nmi_watchdog);
1168 preaction_val = WDOG_PRETIMEOUT_NONE;
1169 do_nmi = 0;
1170 }
1171#endif
1172 } 1224 }
1173 if (do_nmi && !nmi_handler_registered) { 1225 if (do_nmi && !nmi_handler_registered) {
1174 rv = request_nmi(&ipmi_nmi_handler); 1226 rv = register_die_notifier(&ipmi_nmi_handler);
1175 if (rv) { 1227 if (rv) {
1176 printk(KERN_WARNING PFX 1228 printk(KERN_WARNING PFX
1177 "Can't register nmi handler\n"); 1229 "Can't register nmi handler\n");
@@ -1179,7 +1231,7 @@ static void check_parms(void)
1179 } else 1231 } else
1180 nmi_handler_registered = 1; 1232 nmi_handler_registered = 1;
1181 } else if (!do_nmi && nmi_handler_registered) { 1233 } else if (!do_nmi && nmi_handler_registered) {
1182 release_nmi(&ipmi_nmi_handler); 1234 unregister_die_notifier(&ipmi_nmi_handler);
1183 nmi_handler_registered = 0; 1235 nmi_handler_registered = 0;
1184 } 1236 }
1185#endif 1237#endif
@@ -1215,9 +1267,9 @@ static int __init ipmi_wdog_init(void)
1215 1267
1216 rv = ipmi_smi_watcher_register(&smi_watcher); 1268 rv = ipmi_smi_watcher_register(&smi_watcher);
1217 if (rv) { 1269 if (rv) {
1218#ifdef HAVE_NMI_HANDLER 1270#ifdef HAVE_DIE_NMI_POST
1219 if (preaction_val == WDOG_PRETIMEOUT_NMI) 1271 if (nmi_handler_registered)
1220 release_nmi(&ipmi_nmi_handler); 1272 unregister_die_notifier(&ipmi_nmi_handler);
1221#endif 1273#endif
1222 atomic_notifier_chain_unregister(&panic_notifier_list, 1274 atomic_notifier_chain_unregister(&panic_notifier_list,
1223 &wdog_panic_notifier); 1275 &wdog_panic_notifier);
@@ -1236,9 +1288,9 @@ static void __exit ipmi_wdog_exit(void)
1236 ipmi_smi_watcher_unregister(&smi_watcher); 1288 ipmi_smi_watcher_unregister(&smi_watcher);
1237 ipmi_unregister_watchdog(watchdog_ifnum); 1289 ipmi_unregister_watchdog(watchdog_ifnum);
1238 1290
1239#ifdef HAVE_NMI_HANDLER 1291#ifdef HAVE_DIE_NMI_POST
1240 if (nmi_handler_registered) 1292 if (nmi_handler_registered)
1241 release_nmi(&ipmi_nmi_handler); 1293 unregister_die_notifier(&ipmi_nmi_handler);
1242#endif 1294#endif
1243 1295
1244 atomic_notifier_chain_unregister(&panic_notifier_list, 1296 atomic_notifier_chain_unregister(&panic_notifier_list,
diff --git a/drivers/char/isicom.c b/drivers/char/isicom.c
index 43ab9edc76f5..761f77740d67 100644
--- a/drivers/char/isicom.c
+++ b/drivers/char/isicom.c
@@ -137,11 +137,10 @@
137#define InterruptTheCard(base) outw(0, (base) + 0xc) 137#define InterruptTheCard(base) outw(0, (base) + 0xc)
138#define ClearInterrupt(base) inw((base) + 0x0a) 138#define ClearInterrupt(base) inw((base) + 0x0a)
139 139
140#define pr_dbg(str...) pr_debug("ISICOM: " str)
140#ifdef DEBUG 141#ifdef DEBUG
141#define pr_dbg(str...) printk(KERN_DEBUG "ISICOM: " str)
142#define isicom_paranoia_check(a, b, c) __isicom_paranoia_check((a), (b), (c)) 142#define isicom_paranoia_check(a, b, c) __isicom_paranoia_check((a), (b), (c))
143#else 143#else
144#define pr_dbg(str...) do { } while (0)
145#define isicom_paranoia_check(a, b, c) 0 144#define isicom_paranoia_check(a, b, c) 0
146#endif 145#endif
147 146
diff --git a/drivers/char/keyboard.c b/drivers/char/keyboard.c
index c06e86ad1dab..1b094509b1d2 100644
--- a/drivers/char/keyboard.c
+++ b/drivers/char/keyboard.c
@@ -109,7 +109,7 @@ struct kbd_struct kbd_table[MAX_NR_CONSOLES];
109static struct kbd_struct *kbd = kbd_table; 109static struct kbd_struct *kbd = kbd_table;
110 110
111struct vt_spawn_console vt_spawn_con = { 111struct vt_spawn_console vt_spawn_con = {
112 .lock = SPIN_LOCK_UNLOCKED, 112 .lock = __SPIN_LOCK_UNLOCKED(vt_spawn_con.lock),
113 .pid = NULL, 113 .pid = NULL,
114 .sig = 0, 114 .sig = 0,
115}; 115};
diff --git a/drivers/char/lp.c b/drivers/char/lp.c
index b51d08be0bcf..62051f8b0910 100644
--- a/drivers/char/lp.c
+++ b/drivers/char/lp.c
@@ -118,7 +118,6 @@
118#include <linux/kernel.h> 118#include <linux/kernel.h>
119#include <linux/major.h> 119#include <linux/major.h>
120#include <linux/sched.h> 120#include <linux/sched.h>
121#include <linux/smp_lock.h>
122#include <linux/slab.h> 121#include <linux/slab.h>
123#include <linux/fcntl.h> 122#include <linux/fcntl.h>
124#include <linux/delay.h> 123#include <linux/delay.h>
@@ -139,9 +138,6 @@
139/* if you have more than 8 printers, remember to increase LP_NO */ 138/* if you have more than 8 printers, remember to increase LP_NO */
140#define LP_NO 8 139#define LP_NO 8
141 140
142/* ROUND_UP macro from fs/select.c */
143#define ROUND_UP(x,y) (((x)+(y)-1)/(y))
144
145static struct lp_struct lp_table[LP_NO]; 141static struct lp_struct lp_table[LP_NO];
146 142
147static unsigned int lp_count = 0; 143static unsigned int lp_count = 0;
@@ -652,7 +648,7 @@ static int lp_ioctl(struct inode *inode, struct file *file,
652 (par_timeout.tv_usec < 0)) { 648 (par_timeout.tv_usec < 0)) {
653 return -EINVAL; 649 return -EINVAL;
654 } 650 }
655 to_jiffies = ROUND_UP(par_timeout.tv_usec, 1000000/HZ); 651 to_jiffies = DIV_ROUND_UP(par_timeout.tv_usec, 1000000/HZ);
656 to_jiffies += par_timeout.tv_sec * (long) HZ; 652 to_jiffies += par_timeout.tv_sec * (long) HZ;
657 if (to_jiffies <= 0) { 653 if (to_jiffies <= 0) {
658 return -EINVAL; 654 return -EINVAL;
@@ -803,7 +799,7 @@ static int lp_register(int nr, struct parport *port)
803 if (reset) 799 if (reset)
804 lp_reset(nr); 800 lp_reset(nr);
805 801
806 class_device_create(lp_class, NULL, MKDEV(LP_MAJOR, nr), NULL, 802 class_device_create(lp_class, NULL, MKDEV(LP_MAJOR, nr), port->dev,
807 "lp%d", nr); 803 "lp%d", nr);
808 804
809 printk(KERN_INFO "lp%d: using %s (%s).\n", nr, port->name, 805 printk(KERN_INFO "lp%d: using %s (%s).\n", nr, port->name,
diff --git a/drivers/char/mem.c b/drivers/char/mem.c
index 5f066963f171..cc9a9d0df979 100644
--- a/drivers/char/mem.c
+++ b/drivers/char/mem.c
@@ -18,7 +18,6 @@
18#include <linux/raw.h> 18#include <linux/raw.h>
19#include <linux/tty.h> 19#include <linux/tty.h>
20#include <linux/capability.h> 20#include <linux/capability.h>
21#include <linux/smp_lock.h>
22#include <linux/ptrace.h> 21#include <linux/ptrace.h>
23#include <linux/device.h> 22#include <linux/device.h>
24#include <linux/highmem.h> 23#include <linux/highmem.h>
@@ -552,7 +551,7 @@ static ssize_t write_kmem(struct file * file, const char __user * buf,
552 return virtr + wrote; 551 return virtr + wrote;
553} 552}
554 553
555#if (defined(CONFIG_ISA) || defined(CONFIG_PCI)) && !defined(__mc68000__) 554#ifdef CONFIG_DEVPORT
556static ssize_t read_port(struct file * file, char __user * buf, 555static ssize_t read_port(struct file * file, char __user * buf,
557 size_t count, loff_t *ppos) 556 size_t count, loff_t *ppos)
558{ 557{
@@ -835,7 +834,7 @@ static const struct file_operations null_fops = {
835 .splice_write = splice_write_null, 834 .splice_write = splice_write_null,
836}; 835};
837 836
838#if (defined(CONFIG_ISA) || defined(CONFIG_PCI)) && !defined(__mc68000__) 837#ifdef CONFIG_DEVPORT
839static const struct file_operations port_fops = { 838static const struct file_operations port_fops = {
840 .llseek = memory_lseek, 839 .llseek = memory_lseek,
841 .read = read_port, 840 .read = read_port,
@@ -913,7 +912,7 @@ static int memory_open(struct inode * inode, struct file * filp)
913 case 3: 912 case 3:
914 filp->f_op = &null_fops; 913 filp->f_op = &null_fops;
915 break; 914 break;
916#if (defined(CONFIG_ISA) || defined(CONFIG_PCI)) && !defined(__mc68000__) 915#ifdef CONFIG_DEVPORT
917 case 4: 916 case 4:
918 filp->f_op = &port_fops; 917 filp->f_op = &port_fops;
919 break; 918 break;
@@ -960,7 +959,7 @@ static const struct {
960 {1, "mem", S_IRUSR | S_IWUSR | S_IRGRP, &mem_fops}, 959 {1, "mem", S_IRUSR | S_IWUSR | S_IRGRP, &mem_fops},
961 {2, "kmem", S_IRUSR | S_IWUSR | S_IRGRP, &kmem_fops}, 960 {2, "kmem", S_IRUSR | S_IWUSR | S_IRGRP, &kmem_fops},
962 {3, "null", S_IRUGO | S_IWUGO, &null_fops}, 961 {3, "null", S_IRUGO | S_IWUGO, &null_fops},
963#if (defined(CONFIG_ISA) || defined(CONFIG_PCI)) && !defined(__mc68000__) 962#ifdef CONFIG_DEVPORT
964 {4, "port", S_IRUSR | S_IWUSR | S_IRGRP, &port_fops}, 963 {4, "port", S_IRUSR | S_IWUSR | S_IRGRP, &port_fops},
965#endif 964#endif
966 {5, "zero", S_IRUGO | S_IWUGO, &zero_fops}, 965 {5, "zero", S_IRUGO | S_IWUGO, &zero_fops},
diff --git a/drivers/char/misc.c b/drivers/char/misc.c
index 7e975f606924..4e6fb9651a16 100644
--- a/drivers/char/misc.c
+++ b/drivers/char/misc.c
@@ -41,6 +41,7 @@
41#include <linux/kernel.h> 41#include <linux/kernel.h>
42#include <linux/major.h> 42#include <linux/major.h>
43#include <linux/slab.h> 43#include <linux/slab.h>
44#include <linux/mutex.h>
44#include <linux/proc_fs.h> 45#include <linux/proc_fs.h>
45#include <linux/seq_file.h> 46#include <linux/seq_file.h>
46#include <linux/stat.h> 47#include <linux/stat.h>
@@ -53,7 +54,7 @@
53 * Head entry for the doubly linked miscdevice list 54 * Head entry for the doubly linked miscdevice list
54 */ 55 */
55static LIST_HEAD(misc_list); 56static LIST_HEAD(misc_list);
56static DECLARE_MUTEX(misc_sem); 57static DEFINE_MUTEX(misc_mtx);
57 58
58/* 59/*
59 * Assigned numbers, used for dynamic minors 60 * Assigned numbers, used for dynamic minors
@@ -69,7 +70,7 @@ static void *misc_seq_start(struct seq_file *seq, loff_t *pos)
69 struct miscdevice *p; 70 struct miscdevice *p;
70 loff_t off = 0; 71 loff_t off = 0;
71 72
72 down(&misc_sem); 73 mutex_lock(&misc_mtx);
73 list_for_each_entry(p, &misc_list, list) { 74 list_for_each_entry(p, &misc_list, list) {
74 if (*pos == off++) 75 if (*pos == off++)
75 return p; 76 return p;
@@ -89,7 +90,7 @@ static void *misc_seq_next(struct seq_file *seq, void *v, loff_t *pos)
89 90
90static void misc_seq_stop(struct seq_file *seq, void *v) 91static void misc_seq_stop(struct seq_file *seq, void *v)
91{ 92{
92 up(&misc_sem); 93 mutex_unlock(&misc_mtx);
93} 94}
94 95
95static int misc_seq_show(struct seq_file *seq, void *v) 96static int misc_seq_show(struct seq_file *seq, void *v)
@@ -129,7 +130,7 @@ static int misc_open(struct inode * inode, struct file * file)
129 int err = -ENODEV; 130 int err = -ENODEV;
130 const struct file_operations *old_fops, *new_fops = NULL; 131 const struct file_operations *old_fops, *new_fops = NULL;
131 132
132 down(&misc_sem); 133 mutex_lock(&misc_mtx);
133 134
134 list_for_each_entry(c, &misc_list, list) { 135 list_for_each_entry(c, &misc_list, list) {
135 if (c->minor == minor) { 136 if (c->minor == minor) {
@@ -139,9 +140,9 @@ static int misc_open(struct inode * inode, struct file * file)
139 } 140 }
140 141
141 if (!new_fops) { 142 if (!new_fops) {
142 up(&misc_sem); 143 mutex_unlock(&misc_mtx);
143 request_module("char-major-%d-%d", MISC_MAJOR, minor); 144 request_module("char-major-%d-%d", MISC_MAJOR, minor);
144 down(&misc_sem); 145 mutex_lock(&misc_mtx);
145 146
146 list_for_each_entry(c, &misc_list, list) { 147 list_for_each_entry(c, &misc_list, list) {
147 if (c->minor == minor) { 148 if (c->minor == minor) {
@@ -165,7 +166,7 @@ static int misc_open(struct inode * inode, struct file * file)
165 } 166 }
166 fops_put(old_fops); 167 fops_put(old_fops);
167fail: 168fail:
168 up(&misc_sem); 169 mutex_unlock(&misc_mtx);
169 return err; 170 return err;
170} 171}
171 172
@@ -201,10 +202,10 @@ int misc_register(struct miscdevice * misc)
201 202
202 INIT_LIST_HEAD(&misc->list); 203 INIT_LIST_HEAD(&misc->list);
203 204
204 down(&misc_sem); 205 mutex_lock(&misc_mtx);
205 list_for_each_entry(c, &misc_list, list) { 206 list_for_each_entry(c, &misc_list, list) {
206 if (c->minor == misc->minor) { 207 if (c->minor == misc->minor) {
207 up(&misc_sem); 208 mutex_unlock(&misc_mtx);
208 return -EBUSY; 209 return -EBUSY;
209 } 210 }
210 } 211 }
@@ -215,7 +216,7 @@ int misc_register(struct miscdevice * misc)
215 if ( (misc_minors[i>>3] & (1 << (i&7))) == 0) 216 if ( (misc_minors[i>>3] & (1 << (i&7))) == 0)
216 break; 217 break;
217 if (i<0) { 218 if (i<0) {
218 up(&misc_sem); 219 mutex_unlock(&misc_mtx);
219 return -EBUSY; 220 return -EBUSY;
220 } 221 }
221 misc->minor = i; 222 misc->minor = i;
@@ -238,7 +239,7 @@ int misc_register(struct miscdevice * misc)
238 */ 239 */
239 list_add(&misc->list, &misc_list); 240 list_add(&misc->list, &misc_list);
240 out: 241 out:
241 up(&misc_sem); 242 mutex_unlock(&misc_mtx);
242 return err; 243 return err;
243} 244}
244 245
@@ -259,13 +260,13 @@ int misc_deregister(struct miscdevice * misc)
259 if (list_empty(&misc->list)) 260 if (list_empty(&misc->list))
260 return -EINVAL; 261 return -EINVAL;
261 262
262 down(&misc_sem); 263 mutex_lock(&misc_mtx);
263 list_del(&misc->list); 264 list_del(&misc->list);
264 device_destroy(misc_class, MKDEV(MISC_MAJOR, misc->minor)); 265 device_destroy(misc_class, MKDEV(MISC_MAJOR, misc->minor));
265 if (i < DYNAMIC_MINORS && i>0) { 266 if (i < DYNAMIC_MINORS && i>0) {
266 misc_minors[i>>3] &= ~(1 << (misc->minor & 7)); 267 misc_minors[i>>3] &= ~(1 << (misc->minor & 7));
267 } 268 }
268 up(&misc_sem); 269 mutex_unlock(&misc_mtx);
269 return 0; 270 return 0;
270} 271}
271 272
diff --git a/drivers/char/moxa.c b/drivers/char/moxa.c
index 7dbaee8d9402..e0d35c20c04f 100644
--- a/drivers/char/moxa.c
+++ b/drivers/char/moxa.c
@@ -1582,7 +1582,7 @@ copy:
1582 1582
1583 if(copy_from_user(&dltmp, argp, sizeof(struct dl_str))) 1583 if(copy_from_user(&dltmp, argp, sizeof(struct dl_str)))
1584 return -EFAULT; 1584 return -EFAULT;
1585 if(dltmp.cardno < 0 || dltmp.cardno >= MAX_BOARDS) 1585 if(dltmp.cardno < 0 || dltmp.cardno >= MAX_BOARDS || dltmp.len < 0)
1586 return -EINVAL; 1586 return -EINVAL;
1587 1587
1588 switch(cmd) 1588 switch(cmd)
@@ -2529,6 +2529,8 @@ static int moxaloadbios(int cardno, unsigned char __user *tmp, int len)
2529 void __iomem *baseAddr; 2529 void __iomem *baseAddr;
2530 int i; 2530 int i;
2531 2531
2532 if(len < 0 || len > sizeof(moxaBuff))
2533 return -EINVAL;
2532 if(copy_from_user(moxaBuff, tmp, len)) 2534 if(copy_from_user(moxaBuff, tmp, len))
2533 return -EFAULT; 2535 return -EFAULT;
2534 baseAddr = moxa_boards[cardno].basemem; 2536 baseAddr = moxa_boards[cardno].basemem;
@@ -2576,7 +2578,7 @@ static int moxaload320b(int cardno, unsigned char __user *tmp, int len)
2576 void __iomem *baseAddr; 2578 void __iomem *baseAddr;
2577 int i; 2579 int i;
2578 2580
2579 if(len > sizeof(moxaBuff)) 2581 if(len < 0 || len > sizeof(moxaBuff))
2580 return -EINVAL; 2582 return -EINVAL;
2581 if(copy_from_user(moxaBuff, tmp, len)) 2583 if(copy_from_user(moxaBuff, tmp, len))
2582 return -EFAULT; 2584 return -EFAULT;
@@ -2596,6 +2598,8 @@ static int moxaloadcode(int cardno, unsigned char __user *tmp, int len)
2596 void __iomem *baseAddr, *ofsAddr; 2598 void __iomem *baseAddr, *ofsAddr;
2597 int retval, port, i; 2599 int retval, port, i;
2598 2600
2601 if(len < 0 || len > sizeof(moxaBuff))
2602 return -EINVAL;
2599 if(copy_from_user(moxaBuff, tmp, len)) 2603 if(copy_from_user(moxaBuff, tmp, len))
2600 return -EFAULT; 2604 return -EFAULT;
2601 baseAddr = moxa_boards[cardno].basemem; 2605 baseAddr = moxa_boards[cardno].basemem;
diff --git a/drivers/char/mxser.c b/drivers/char/mxser.c
index 80a01150b86c..5953a45d7e96 100644
--- a/drivers/char/mxser.c
+++ b/drivers/char/mxser.c
@@ -54,7 +54,6 @@
54#include <linux/gfp.h> 54#include <linux/gfp.h>
55#include <linux/ioport.h> 55#include <linux/ioport.h>
56#include <linux/mm.h> 56#include <linux/mm.h>
57#include <linux/smp_lock.h>
58#include <linux/delay.h> 57#include <linux/delay.h>
59#include <linux/pci.h> 58#include <linux/pci.h>
60 59
diff --git a/drivers/char/mxser_new.c b/drivers/char/mxser_new.c
index f7603b6aeb87..6cde448cd5b2 100644
--- a/drivers/char/mxser_new.c
+++ b/drivers/char/mxser_new.c
@@ -37,7 +37,6 @@
37#include <linux/gfp.h> 37#include <linux/gfp.h>
38#include <linux/ioport.h> 38#include <linux/ioport.h>
39#include <linux/mm.h> 39#include <linux/mm.h>
40#include <linux/smp_lock.h>
41#include <linux/delay.h> 40#include <linux/delay.h>
42#include <linux/pci.h> 41#include <linux/pci.h>
43 42
diff --git a/drivers/char/n_r3964.c b/drivers/char/n_r3964.c
index 65f2d3a96b85..14557a4822c0 100644
--- a/drivers/char/n_r3964.c
+++ b/drivers/char/n_r3964.c
@@ -1088,13 +1088,13 @@ static ssize_t r3964_read(struct tty_struct *tty, struct file *file,
1088 /* block until there is a message: */ 1088 /* block until there is a message: */
1089 add_wait_queue(&pInfo->read_wait, &wait); 1089 add_wait_queue(&pInfo->read_wait, &wait);
1090repeat: 1090repeat:
1091 current->state = TASK_INTERRUPTIBLE; 1091 __set_current_state(TASK_INTERRUPTIBLE);
1092 pMsg = remove_msg(pInfo, pClient); 1092 pMsg = remove_msg(pInfo, pClient);
1093 if (!pMsg && !signal_pending(current)) { 1093 if (!pMsg && !signal_pending(current)) {
1094 schedule(); 1094 schedule();
1095 goto repeat; 1095 goto repeat;
1096 } 1096 }
1097 current->state = TASK_RUNNING; 1097 __set_current_state(TASK_RUNNING);
1098 remove_wait_queue(&pInfo->read_wait, &wait); 1098 remove_wait_queue(&pInfo->read_wait, &wait);
1099 } 1099 }
1100 1100
diff --git a/drivers/char/ppdev.c b/drivers/char/ppdev.c
index 4abd1eff61d6..84ac64fc48a1 100644
--- a/drivers/char/ppdev.c
+++ b/drivers/char/ppdev.c
@@ -66,7 +66,6 @@
66#include <linux/poll.h> 66#include <linux/poll.h>
67#include <linux/major.h> 67#include <linux/major.h>
68#include <linux/ppdev.h> 68#include <linux/ppdev.h>
69#include <linux/smp_lock.h>
70#include <linux/device.h> 69#include <linux/device.h>
71#include <asm/uaccess.h> 70#include <asm/uaccess.h>
72 71
@@ -752,7 +751,7 @@ static const struct file_operations pp_fops = {
752 751
753static void pp_attach(struct parport *port) 752static void pp_attach(struct parport *port)
754{ 753{
755 device_create(ppdev_class, NULL, MKDEV(PP_MAJOR, port->number), 754 device_create(ppdev_class, port->dev, MKDEV(PP_MAJOR, port->number),
756 "parport%d", port->number); 755 "parport%d", port->number);
757} 756}
758 757
diff --git a/drivers/char/riscom8.c b/drivers/char/riscom8.c
index 70145254fb9d..3494e3fc44bf 100644
--- a/drivers/char/riscom8.c
+++ b/drivers/char/riscom8.c
@@ -980,7 +980,7 @@ static int block_til_ready(struct tty_struct *tty, struct file * filp,
980 } 980 }
981 schedule(); 981 schedule();
982 } 982 }
983 current->state = TASK_RUNNING; 983 __set_current_state(TASK_RUNNING);
984 remove_wait_queue(&port->open_wait, &wait); 984 remove_wait_queue(&port->open_wait, &wait);
985 if (!tty_hung_up_p(filp)) 985 if (!tty_hung_up_p(filp))
986 port->count++; 986 port->count++;
diff --git a/drivers/char/rocket.c b/drivers/char/rocket.c
index 76357c855ce3..61a63da420c2 100644
--- a/drivers/char/rocket.c
+++ b/drivers/char/rocket.c
@@ -65,10 +65,6 @@
65 65
66/****** Kernel includes ******/ 66/****** Kernel includes ******/
67 67
68#ifdef MODVERSIONS
69#include <config/modversions.h>
70#endif
71
72#include <linux/module.h> 68#include <linux/module.h>
73#include <linux/errno.h> 69#include <linux/errno.h>
74#include <linux/major.h> 70#include <linux/major.h>
@@ -85,6 +81,7 @@
85#include <linux/string.h> 81#include <linux/string.h>
86#include <linux/fcntl.h> 82#include <linux/fcntl.h>
87#include <linux/ptrace.h> 83#include <linux/ptrace.h>
84#include <linux/mutex.h>
88#include <linux/ioport.h> 85#include <linux/ioport.h>
89#include <linux/delay.h> 86#include <linux/delay.h>
90#include <linux/wait.h> 87#include <linux/wait.h>
@@ -93,7 +90,6 @@
93#include <asm/atomic.h> 90#include <asm/atomic.h>
94#include <linux/bitops.h> 91#include <linux/bitops.h>
95#include <linux/spinlock.h> 92#include <linux/spinlock.h>
96#include <asm/semaphore.h>
97#include <linux/init.h> 93#include <linux/init.h>
98 94
99/****** RocketPort includes ******/ 95/****** RocketPort includes ******/
@@ -702,7 +698,7 @@ static void init_r_port(int board, int aiop, int chan, struct pci_dev *pci_dev)
702 } 698 }
703 } 699 }
704 spin_lock_init(&info->slock); 700 spin_lock_init(&info->slock);
705 sema_init(&info->write_sem, 1); 701 mutex_init(&info->write_mtx);
706 rp_table[line] = info; 702 rp_table[line] = info;
707 if (pci_dev) 703 if (pci_dev)
708 tty_register_device(rocket_driver, line, &pci_dev->dev); 704 tty_register_device(rocket_driver, line, &pci_dev->dev);
@@ -947,7 +943,7 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp,
947#endif 943#endif
948 schedule(); /* Don't hold spinlock here, will hang PC */ 944 schedule(); /* Don't hold spinlock here, will hang PC */
949 } 945 }
950 current->state = TASK_RUNNING; 946 __set_current_state(TASK_RUNNING);
951 remove_wait_queue(&info->open_wait, &wait); 947 remove_wait_queue(&info->open_wait, &wait);
952 948
953 spin_lock_irqsave(&info->slock, flags); 949 spin_lock_irqsave(&info->slock, flags);
@@ -1602,7 +1598,7 @@ static void rp_wait_until_sent(struct tty_struct *tty, int timeout)
1602 if (signal_pending(current)) 1598 if (signal_pending(current))
1603 break; 1599 break;
1604 } 1600 }
1605 current->state = TASK_RUNNING; 1601 __set_current_state(TASK_RUNNING);
1606#ifdef ROCKET_DEBUG_WAIT_UNTIL_SENT 1602#ifdef ROCKET_DEBUG_WAIT_UNTIL_SENT
1607 printk(KERN_INFO "txcnt = %d (jiff=%lu)...done\n", txcnt, jiffies); 1603 printk(KERN_INFO "txcnt = %d (jiff=%lu)...done\n", txcnt, jiffies);
1608#endif 1604#endif
@@ -1661,8 +1657,11 @@ static void rp_put_char(struct tty_struct *tty, unsigned char ch)
1661 if (rocket_paranoia_check(info, "rp_put_char")) 1657 if (rocket_paranoia_check(info, "rp_put_char"))
1662 return; 1658 return;
1663 1659
1664 /* Grab the port write semaphore, locking out other processes that try to write to this port */ 1660 /*
1665 down(&info->write_sem); 1661 * Grab the port write mutex, locking out other processes that try to
1662 * write to this port
1663 */
1664 mutex_lock(&info->write_mtx);
1666 1665
1667#ifdef ROCKET_DEBUG_WRITE 1666#ifdef ROCKET_DEBUG_WRITE
1668 printk(KERN_INFO "rp_put_char %c...", ch); 1667 printk(KERN_INFO "rp_put_char %c...", ch);
@@ -1684,12 +1683,12 @@ static void rp_put_char(struct tty_struct *tty, unsigned char ch)
1684 info->xmit_fifo_room--; 1683 info->xmit_fifo_room--;
1685 } 1684 }
1686 spin_unlock_irqrestore(&info->slock, flags); 1685 spin_unlock_irqrestore(&info->slock, flags);
1687 up(&info->write_sem); 1686 mutex_unlock(&info->write_mtx);
1688} 1687}
1689 1688
1690/* 1689/*
1691 * Exception handler - write routine, called when user app writes to the device. 1690 * Exception handler - write routine, called when user app writes to the device.
1692 * A per port write semaphore is used to protect from another process writing to 1691 * A per port write mutex is used to protect from another process writing to
1693 * this port at the same time. This other process could be running on the other CPU 1692 * this port at the same time. This other process could be running on the other CPU
1694 * or get control of the CPU if the copy_from_user() blocks due to a page fault (swapped out). 1693 * or get control of the CPU if the copy_from_user() blocks due to a page fault (swapped out).
1695 * Spinlocks protect the info xmit members. 1694 * Spinlocks protect the info xmit members.
@@ -1706,7 +1705,7 @@ static int rp_write(struct tty_struct *tty,
1706 if (count <= 0 || rocket_paranoia_check(info, "rp_write")) 1705 if (count <= 0 || rocket_paranoia_check(info, "rp_write"))
1707 return 0; 1706 return 0;
1708 1707
1709 down_interruptible(&info->write_sem); 1708 mutex_lock_interruptible(&info->write_mtx);
1710 1709
1711#ifdef ROCKET_DEBUG_WRITE 1710#ifdef ROCKET_DEBUG_WRITE
1712 printk(KERN_INFO "rp_write %d chars...", count); 1711 printk(KERN_INFO "rp_write %d chars...", count);
@@ -1777,7 +1776,7 @@ end:
1777 wake_up_interruptible(&tty->poll_wait); 1776 wake_up_interruptible(&tty->poll_wait);
1778#endif 1777#endif
1779 } 1778 }
1780 up(&info->write_sem); 1779 mutex_unlock(&info->write_mtx);
1781 return retval; 1780 return retval;
1782} 1781}
1783 1782
@@ -1852,6 +1851,12 @@ static void rp_flush_buffer(struct tty_struct *tty)
1852 1851
1853#ifdef CONFIG_PCI 1852#ifdef CONFIG_PCI
1854 1853
1854static struct pci_device_id __devinitdata rocket_pci_ids[] = {
1855 { PCI_DEVICE(PCI_VENDOR_ID_RP, PCI_ANY_ID) },
1856 { }
1857};
1858MODULE_DEVICE_TABLE(pci, rocket_pci_ids);
1859
1855/* 1860/*
1856 * Called when a PCI card is found. Retrieves and stores model information, 1861 * Called when a PCI card is found. Retrieves and stores model information,
1857 * init's aiopic and serial port hardware. 1862 * init's aiopic and serial port hardware.
diff --git a/drivers/char/rocket_int.h b/drivers/char/rocket_int.h
index 3a8bcc85bc14..89b4d7b10d12 100644
--- a/drivers/char/rocket_int.h
+++ b/drivers/char/rocket_int.h
@@ -15,6 +15,8 @@
15#define ROCKET_TYPE_MODEMIII 3 15#define ROCKET_TYPE_MODEMIII 3
16#define ROCKET_TYPE_PC104 4 16#define ROCKET_TYPE_PC104 4
17 17
18#include <linux/mutex.h>
19
18#include <asm/io.h> 20#include <asm/io.h>
19#include <asm/byteorder.h> 21#include <asm/byteorder.h>
20 22
@@ -1171,7 +1173,7 @@ struct r_port {
1171 struct wait_queue *close_wait; 1173 struct wait_queue *close_wait;
1172#endif 1174#endif
1173 spinlock_t slock; 1175 spinlock_t slock;
1174 struct semaphore write_sem; 1176 struct mutex write_mtx;
1175}; 1177};
1176 1178
1177#define RPORT_MAGIC 0x525001 1179#define RPORT_MAGIC 0x525001
diff --git a/drivers/char/rtc.c b/drivers/char/rtc.c
index c7dac9b13351..20380a2c4dee 100644
--- a/drivers/char/rtc.c
+++ b/drivers/char/rtc.c
@@ -388,7 +388,7 @@ static ssize_t rtc_read(struct file *file, char __user *buf,
388 if (!retval) 388 if (!retval)
389 retval = count; 389 retval = count;
390 out: 390 out:
391 current->state = TASK_RUNNING; 391 __set_current_state(TASK_RUNNING);
392 remove_wait_queue(&rtc_wait, &wait); 392 remove_wait_queue(&rtc_wait, &wait);
393 393
394 return retval; 394 return retval;
diff --git a/drivers/char/selection.c b/drivers/char/selection.c
index 74cff839c857..a69f094d1ed3 100644
--- a/drivers/char/selection.c
+++ b/drivers/char/selection.c
@@ -299,7 +299,7 @@ int paste_selection(struct tty_struct *tty)
299 pasted += count; 299 pasted += count;
300 } 300 }
301 remove_wait_queue(&vc->paste_wait, &wait); 301 remove_wait_queue(&vc->paste_wait, &wait);
302 current->state = TASK_RUNNING; 302 __set_current_state(TASK_RUNNING);
303 303
304 tty_ldisc_deref(ld); 304 tty_ldisc_deref(ld);
305 return 0; 305 return 0;
diff --git a/drivers/char/serial167.c b/drivers/char/serial167.c
index 5fd314adc1f2..c585b4738f86 100644
--- a/drivers/char/serial167.c
+++ b/drivers/char/serial167.c
@@ -1892,7 +1892,7 @@ block_til_ready(struct tty_struct *tty, struct file *filp,
1892#endif 1892#endif
1893 schedule(); 1893 schedule();
1894 } 1894 }
1895 current->state = TASK_RUNNING; 1895 __set_current_state(TASK_RUNNING);
1896 remove_wait_queue(&info->open_wait, &wait); 1896 remove_wait_queue(&info->open_wait, &wait);
1897 if (!tty_hung_up_p(filp)) { 1897 if (!tty_hung_up_p(filp)) {
1898 info->count++; 1898 info->count++;
diff --git a/drivers/char/synclink.c b/drivers/char/synclink.c
index ce4db6f52362..f02a0795983f 100644
--- a/drivers/char/synclink.c
+++ b/drivers/char/synclink.c
@@ -4010,8 +4010,13 @@ static int mgsl_alloc_intermediate_txbuffer_memory(struct mgsl_struct *info)
4010 for ( i=0; i<info->num_tx_holding_buffers; ++i) { 4010 for ( i=0; i<info->num_tx_holding_buffers; ++i) {
4011 info->tx_holding_buffers[i].buffer = 4011 info->tx_holding_buffers[i].buffer =
4012 kmalloc(info->max_frame_size, GFP_KERNEL); 4012 kmalloc(info->max_frame_size, GFP_KERNEL);
4013 if ( info->tx_holding_buffers[i].buffer == NULL ) 4013 if (info->tx_holding_buffers[i].buffer == NULL) {
4014 for (--i; i >= 0; i--) {
4015 kfree(info->tx_holding_buffers[i].buffer);
4016 info->tx_holding_buffers[i].buffer = NULL;
4017 }
4014 return -ENOMEM; 4018 return -ENOMEM;
4019 }
4015 } 4020 }
4016 4021
4017 return 0; 4022 return 0;
diff --git a/drivers/char/synclink_gt.c b/drivers/char/synclink_gt.c
index 0a367cd4121f..2a7736b5f2f7 100644
--- a/drivers/char/synclink_gt.c
+++ b/drivers/char/synclink_gt.c
@@ -3415,6 +3415,9 @@ static void device_init(int adapter_num, struct pci_dev *pdev)
3415 } 3415 }
3416 } 3416 }
3417 } 3417 }
3418
3419 for (i=0; i < port_count; ++i)
3420 tty_register_device(serial_driver, port_array[i]->line, &(port_array[i]->pdev->dev));
3418} 3421}
3419 3422
3420static int __devinit init_one(struct pci_dev *dev, 3423static int __devinit init_one(struct pci_dev *dev,
@@ -3466,6 +3469,8 @@ static void slgt_cleanup(void)
3466 printk("unload %s %s\n", driver_name, driver_version); 3469 printk("unload %s %s\n", driver_name, driver_version);
3467 3470
3468 if (serial_driver) { 3471 if (serial_driver) {
3472 for (info=slgt_device_list ; info != NULL ; info=info->next_device)
3473 tty_unregister_device(serial_driver, info->line);
3469 if ((rc = tty_unregister_driver(serial_driver))) 3474 if ((rc = tty_unregister_driver(serial_driver)))
3470 DBGERR(("tty_unregister_driver error=%d\n", rc)); 3475 DBGERR(("tty_unregister_driver error=%d\n", rc));
3471 put_tty_driver(serial_driver); 3476 put_tty_driver(serial_driver);
@@ -3506,23 +3511,10 @@ static int __init slgt_init(void)
3506 3511
3507 printk("%s %s\n", driver_name, driver_version); 3512 printk("%s %s\n", driver_name, driver_version);
3508 3513
3509 slgt_device_count = 0;
3510 if ((rc = pci_register_driver(&pci_driver)) < 0) {
3511 printk("%s pci_register_driver error=%d\n", driver_name, rc);
3512 return rc;
3513 }
3514 pci_registered = 1;
3515
3516 if (!slgt_device_list) {
3517 printk("%s no devices found\n",driver_name);
3518 pci_unregister_driver(&pci_driver);
3519 return -ENODEV;
3520 }
3521
3522 serial_driver = alloc_tty_driver(MAX_DEVICES); 3514 serial_driver = alloc_tty_driver(MAX_DEVICES);
3523 if (!serial_driver) { 3515 if (!serial_driver) {
3524 rc = -ENOMEM; 3516 printk("%s can't allocate tty driver\n", driver_name);
3525 goto error; 3517 return -ENOMEM;
3526 } 3518 }
3527 3519
3528 /* Initialize the tty_driver structure */ 3520 /* Initialize the tty_driver structure */
@@ -3539,7 +3531,7 @@ static int __init slgt_init(void)
3539 B9600 | CS8 | CREAD | HUPCL | CLOCAL; 3531 B9600 | CS8 | CREAD | HUPCL | CLOCAL;
3540 serial_driver->init_termios.c_ispeed = 9600; 3532 serial_driver->init_termios.c_ispeed = 9600;
3541 serial_driver->init_termios.c_ospeed = 9600; 3533 serial_driver->init_termios.c_ospeed = 9600;
3542 serial_driver->flags = TTY_DRIVER_REAL_RAW; 3534 serial_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV;
3543 tty_set_operations(serial_driver, &ops); 3535 tty_set_operations(serial_driver, &ops);
3544 if ((rc = tty_register_driver(serial_driver)) < 0) { 3536 if ((rc = tty_register_driver(serial_driver)) < 0) {
3545 DBGERR(("%s can't register serial driver\n", driver_name)); 3537 DBGERR(("%s can't register serial driver\n", driver_name));
@@ -3552,6 +3544,16 @@ static int __init slgt_init(void)
3552 driver_name, driver_version, 3544 driver_name, driver_version,
3553 serial_driver->major); 3545 serial_driver->major);
3554 3546
3547 slgt_device_count = 0;
3548 if ((rc = pci_register_driver(&pci_driver)) < 0) {
3549 printk("%s pci_register_driver error=%d\n", driver_name, rc);
3550 goto error;
3551 }
3552 pci_registered = 1;
3553
3554 if (!slgt_device_list)
3555 printk("%s no devices found\n",driver_name);
3556
3555 return 0; 3557 return 0;
3556 3558
3557error: 3559error:
diff --git a/drivers/char/sysrq.c b/drivers/char/sysrq.c
index 1d8c4ae61551..39cc318011ea 100644
--- a/drivers/char/sysrq.c
+++ b/drivers/char/sysrq.c
@@ -24,7 +24,6 @@
24#include <linux/sysrq.h> 24#include <linux/sysrq.h>
25#include <linux/kbd_kern.h> 25#include <linux/kbd_kern.h>
26#include <linux/quotaops.h> 26#include <linux/quotaops.h>
27#include <linux/smp_lock.h>
28#include <linux/kernel.h> 27#include <linux/kernel.h>
29#include <linux/module.h> 28#include <linux/module.h>
30#include <linux/suspend.h> 29#include <linux/suspend.h>
diff --git a/drivers/char/tipar.c b/drivers/char/tipar.c
index 47fb20f69695..35b40b996534 100644
--- a/drivers/char/tipar.c
+++ b/drivers/char/tipar.c
@@ -442,7 +442,7 @@ tipar_register(int nr, struct parport *port)
442 } 442 }
443 443
444 class_device_create(tipar_class, NULL, MKDEV(TIPAR_MAJOR, 444 class_device_create(tipar_class, NULL, MKDEV(TIPAR_MAJOR,
445 TIPAR_MINOR + nr), NULL, "par%d", nr); 445 TIPAR_MINOR + nr), port->dev, "par%d", nr);
446 446
447 /* Display informations */ 447 /* Display informations */
448 pr_info("tipar%d: using %s (%s)\n", nr, port->name, (port->irq == 448 pr_info("tipar%d: using %s (%s)\n", nr, port->name, (port->irq ==
diff --git a/drivers/char/tpm/tpm.c b/drivers/char/tpm/tpm.c
index e5a254a434f8..9bb542913b86 100644
--- a/drivers/char/tpm/tpm.c
+++ b/drivers/char/tpm/tpm.c
@@ -24,7 +24,9 @@
24 */ 24 */
25 25
26#include <linux/poll.h> 26#include <linux/poll.h>
27#include <linux/mutex.h>
27#include <linux/spinlock.h> 28#include <linux/spinlock.h>
29
28#include "tpm.h" 30#include "tpm.h"
29 31
30enum tpm_const { 32enum tpm_const {
@@ -328,10 +330,10 @@ static void timeout_work(struct work_struct *work)
328{ 330{
329 struct tpm_chip *chip = container_of(work, struct tpm_chip, work); 331 struct tpm_chip *chip = container_of(work, struct tpm_chip, work);
330 332
331 down(&chip->buffer_mutex); 333 mutex_lock(&chip->buffer_mutex);
332 atomic_set(&chip->data_pending, 0); 334 atomic_set(&chip->data_pending, 0);
333 memset(chip->data_buffer, 0, TPM_BUFSIZE); 335 memset(chip->data_buffer, 0, TPM_BUFSIZE);
334 up(&chip->buffer_mutex); 336 mutex_unlock(&chip->buffer_mutex);
335} 337}
336 338
337/* 339/*
@@ -380,7 +382,7 @@ static ssize_t tpm_transmit(struct tpm_chip *chip, const char *buf,
380 return -E2BIG; 382 return -E2BIG;
381 } 383 }
382 384
383 down(&chip->tpm_mutex); 385 mutex_lock(&chip->tpm_mutex);
384 386
385 if ((rc = chip->vendor.send(chip, (u8 *) buf, count)) < 0) { 387 if ((rc = chip->vendor.send(chip, (u8 *) buf, count)) < 0) {
386 dev_err(chip->dev, 388 dev_err(chip->dev,
@@ -419,7 +421,7 @@ out_recv:
419 dev_err(chip->dev, 421 dev_err(chip->dev,
420 "tpm_transmit: tpm_recv: error %zd\n", rc); 422 "tpm_transmit: tpm_recv: error %zd\n", rc);
421out: 423out:
422 up(&chip->tpm_mutex); 424 mutex_unlock(&chip->tpm_mutex);
423 return rc; 425 return rc;
424} 426}
425 427
@@ -942,12 +944,12 @@ int tpm_release(struct inode *inode, struct file *file)
942{ 944{
943 struct tpm_chip *chip = file->private_data; 945 struct tpm_chip *chip = file->private_data;
944 946
947 flush_scheduled_work();
945 spin_lock(&driver_lock); 948 spin_lock(&driver_lock);
946 file->private_data = NULL; 949 file->private_data = NULL;
947 chip->num_opens--;
948 del_singleshot_timer_sync(&chip->user_read_timer); 950 del_singleshot_timer_sync(&chip->user_read_timer);
949 flush_scheduled_work();
950 atomic_set(&chip->data_pending, 0); 951 atomic_set(&chip->data_pending, 0);
952 chip->num_opens--;
951 put_device(chip->dev); 953 put_device(chip->dev);
952 kfree(chip->data_buffer); 954 kfree(chip->data_buffer);
953 spin_unlock(&driver_lock); 955 spin_unlock(&driver_lock);
@@ -966,14 +968,14 @@ ssize_t tpm_write(struct file *file, const char __user *buf,
966 while (atomic_read(&chip->data_pending) != 0) 968 while (atomic_read(&chip->data_pending) != 0)
967 msleep(TPM_TIMEOUT); 969 msleep(TPM_TIMEOUT);
968 970
969 down(&chip->buffer_mutex); 971 mutex_lock(&chip->buffer_mutex);
970 972
971 if (in_size > TPM_BUFSIZE) 973 if (in_size > TPM_BUFSIZE)
972 in_size = TPM_BUFSIZE; 974 in_size = TPM_BUFSIZE;
973 975
974 if (copy_from_user 976 if (copy_from_user
975 (chip->data_buffer, (void __user *) buf, in_size)) { 977 (chip->data_buffer, (void __user *) buf, in_size)) {
976 up(&chip->buffer_mutex); 978 mutex_unlock(&chip->buffer_mutex);
977 return -EFAULT; 979 return -EFAULT;
978 } 980 }
979 981
@@ -981,7 +983,7 @@ ssize_t tpm_write(struct file *file, const char __user *buf,
981 out_size = tpm_transmit(chip, chip->data_buffer, TPM_BUFSIZE); 983 out_size = tpm_transmit(chip, chip->data_buffer, TPM_BUFSIZE);
982 984
983 atomic_set(&chip->data_pending, out_size); 985 atomic_set(&chip->data_pending, out_size);
984 up(&chip->buffer_mutex); 986 mutex_unlock(&chip->buffer_mutex);
985 987
986 /* Set a timeout by which the reader must come claim the result */ 988 /* Set a timeout by which the reader must come claim the result */
987 mod_timer(&chip->user_read_timer, jiffies + (60 * HZ)); 989 mod_timer(&chip->user_read_timer, jiffies + (60 * HZ));
@@ -1004,10 +1006,10 @@ ssize_t tpm_read(struct file *file, char __user *buf,
1004 if (size < ret_size) 1006 if (size < ret_size)
1005 ret_size = size; 1007 ret_size = size;
1006 1008
1007 down(&chip->buffer_mutex); 1009 mutex_lock(&chip->buffer_mutex);
1008 if (copy_to_user(buf, chip->data_buffer, ret_size)) 1010 if (copy_to_user(buf, chip->data_buffer, ret_size))
1009 ret_size = -EFAULT; 1011 ret_size = -EFAULT;
1010 up(&chip->buffer_mutex); 1012 mutex_unlock(&chip->buffer_mutex);
1011 } 1013 }
1012 1014
1013 return ret_size; 1015 return ret_size;
@@ -1097,11 +1099,16 @@ struct tpm_chip *tpm_register_hardware(struct device *dev, const struct tpm_vend
1097 1099
1098 /* Driver specific per-device data */ 1100 /* Driver specific per-device data */
1099 chip = kzalloc(sizeof(*chip), GFP_KERNEL); 1101 chip = kzalloc(sizeof(*chip), GFP_KERNEL);
1100 if (chip == NULL) 1102 devname = kmalloc(DEVNAME_SIZE, GFP_KERNEL);
1103
1104 if (chip == NULL || devname == NULL) {
1105 kfree(chip);
1106 kfree(devname);
1101 return NULL; 1107 return NULL;
1108 }
1102 1109
1103 init_MUTEX(&chip->buffer_mutex); 1110 mutex_init(&chip->buffer_mutex);
1104 init_MUTEX(&chip->tpm_mutex); 1111 mutex_init(&chip->tpm_mutex);
1105 INIT_LIST_HEAD(&chip->list); 1112 INIT_LIST_HEAD(&chip->list);
1106 1113
1107 INIT_WORK(&chip->work, timeout_work); 1114 INIT_WORK(&chip->work, timeout_work);
@@ -1124,7 +1131,6 @@ struct tpm_chip *tpm_register_hardware(struct device *dev, const struct tpm_vend
1124 1131
1125 set_bit(chip->dev_num, dev_mask); 1132 set_bit(chip->dev_num, dev_mask);
1126 1133
1127 devname = kmalloc(DEVNAME_SIZE, GFP_KERNEL);
1128 scnprintf(devname, DEVNAME_SIZE, "%s%d", "tpm", chip->dev_num); 1134 scnprintf(devname, DEVNAME_SIZE, "%s%d", "tpm", chip->dev_num);
1129 chip->vendor.miscdev.name = devname; 1135 chip->vendor.miscdev.name = devname;
1130 1136
diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h
index 9f273f032b0f..b2e2b002a1bb 100644
--- a/drivers/char/tpm/tpm.h
+++ b/drivers/char/tpm/tpm.h
@@ -21,6 +21,7 @@
21#include <linux/module.h> 21#include <linux/module.h>
22#include <linux/delay.h> 22#include <linux/delay.h>
23#include <linux/fs.h> 23#include <linux/fs.h>
24#include <linux/mutex.h>
24#include <linux/sched.h> 25#include <linux/sched.h>
25#include <linux/miscdevice.h> 26#include <linux/miscdevice.h>
26#include <linux/platform_device.h> 27#include <linux/platform_device.h>
@@ -94,11 +95,11 @@ struct tpm_chip {
94 /* Data passed to and from the tpm via the read/write calls */ 95 /* Data passed to and from the tpm via the read/write calls */
95 u8 *data_buffer; 96 u8 *data_buffer;
96 atomic_t data_pending; 97 atomic_t data_pending;
97 struct semaphore buffer_mutex; 98 struct mutex buffer_mutex;
98 99
99 struct timer_list user_read_timer; /* user needs to claim result */ 100 struct timer_list user_read_timer; /* user needs to claim result */
100 struct work_struct work; 101 struct work_struct work;
101 struct semaphore tpm_mutex; /* tpm is processing */ 102 struct mutex tpm_mutex; /* tpm is processing */
102 103
103 struct tpm_vendor_specific vendor; 104 struct tpm_vendor_specific vendor;
104 105
diff --git a/drivers/char/tpm/tpm_infineon.c b/drivers/char/tpm/tpm_infineon.c
index 1353b5a6bae8..967002a5a1e5 100644
--- a/drivers/char/tpm/tpm_infineon.c
+++ b/drivers/char/tpm/tpm_infineon.c
@@ -30,12 +30,60 @@
30#define TPM_MAX_TRIES 5000 30#define TPM_MAX_TRIES 5000
31#define TPM_INFINEON_DEV_VEN_VALUE 0x15D1 31#define TPM_INFINEON_DEV_VEN_VALUE 0x15D1
32 32
33/* These values will be filled after PnP-call */ 33#define TPM_INF_IO_PORT 0x0
34static int TPM_INF_DATA; 34#define TPM_INF_IO_MEM 0x1
35static int TPM_INF_ADDR; 35
36static int TPM_INF_BASE; 36#define TPM_INF_ADDR 0x0
37static int TPM_INF_ADDR_LEN; 37#define TPM_INF_DATA 0x1
38static int TPM_INF_PORT_LEN; 38
39struct tpm_inf_dev {
40 int iotype;
41
42 void __iomem *mem_base; /* MMIO ioremap'd addr */
43 unsigned long map_base; /* phys MMIO base */
44 unsigned long map_size; /* MMIO region size */
45 unsigned int index_off; /* index register offset */
46
47 unsigned int data_regs; /* Data registers */
48 unsigned int data_size;
49
50 unsigned int config_port; /* IO Port config index reg */
51 unsigned int config_size;
52};
53
54static struct tpm_inf_dev tpm_dev;
55
56static inline void tpm_data_out(unsigned char data, unsigned char offset)
57{
58 if (tpm_dev.iotype == TPM_INF_IO_PORT)
59 outb(data, tpm_dev.data_regs + offset);
60 else
61 writeb(data, tpm_dev.mem_base + tpm_dev.data_regs + offset);
62}
63
64static inline unsigned char tpm_data_in(unsigned char offset)
65{
66 if (tpm_dev.iotype == TPM_INF_IO_PORT)
67 return inb(tpm_dev.data_regs + offset);
68 else
69 return readb(tpm_dev.mem_base + tpm_dev.data_regs + offset);
70}
71
72static inline void tpm_config_out(unsigned char data, unsigned char offset)
73{
74 if (tpm_dev.iotype == TPM_INF_IO_PORT)
75 outb(data, tpm_dev.config_port + offset);
76 else
77 writeb(data, tpm_dev.mem_base + tpm_dev.index_off + offset);
78}
79
80static inline unsigned char tpm_config_in(unsigned char offset)
81{
82 if (tpm_dev.iotype == TPM_INF_IO_PORT)
83 return inb(tpm_dev.config_port + offset);
84 else
85 return readb(tpm_dev.mem_base + tpm_dev.index_off + offset);
86}
39 87
40/* TPM header definitions */ 88/* TPM header definitions */
41enum infineon_tpm_header { 89enum infineon_tpm_header {
@@ -105,7 +153,7 @@ static int empty_fifo(struct tpm_chip *chip, int clear_wrfifo)
105 153
106 if (clear_wrfifo) { 154 if (clear_wrfifo) {
107 for (i = 0; i < 4096; i++) { 155 for (i = 0; i < 4096; i++) {
108 status = inb(chip->vendor.base + WRFIFO); 156 status = tpm_data_in(WRFIFO);
109 if (status == 0xff) { 157 if (status == 0xff) {
110 if (check == 5) 158 if (check == 5)
111 break; 159 break;
@@ -125,8 +173,8 @@ static int empty_fifo(struct tpm_chip *chip, int clear_wrfifo)
125 */ 173 */
126 i = 0; 174 i = 0;
127 do { 175 do {
128 status = inb(chip->vendor.base + RDFIFO); 176 status = tpm_data_in(RDFIFO);
129 status = inb(chip->vendor.base + STAT); 177 status = tpm_data_in(STAT);
130 i++; 178 i++;
131 if (i == TPM_MAX_TRIES) 179 if (i == TPM_MAX_TRIES)
132 return -EIO; 180 return -EIO;
@@ -139,7 +187,7 @@ static int wait(struct tpm_chip *chip, int wait_for_bit)
139 int status; 187 int status;
140 int i; 188 int i;
141 for (i = 0; i < TPM_MAX_TRIES; i++) { 189 for (i = 0; i < TPM_MAX_TRIES; i++) {
142 status = inb(chip->vendor.base + STAT); 190 status = tpm_data_in(STAT);
143 /* check the status-register if wait_for_bit is set */ 191 /* check the status-register if wait_for_bit is set */
144 if (status & 1 << wait_for_bit) 192 if (status & 1 << wait_for_bit)
145 break; 193 break;
@@ -158,7 +206,7 @@ static int wait(struct tpm_chip *chip, int wait_for_bit)
158static void wait_and_send(struct tpm_chip *chip, u8 sendbyte) 206static void wait_and_send(struct tpm_chip *chip, u8 sendbyte)
159{ 207{
160 wait(chip, STAT_XFE); 208 wait(chip, STAT_XFE);
161 outb(sendbyte, chip->vendor.base + WRFIFO); 209 tpm_data_out(sendbyte, WRFIFO);
162} 210}
163 211
164 /* Note: WTX means Waiting-Time-Extension. Whenever the TPM needs more 212 /* Note: WTX means Waiting-Time-Extension. Whenever the TPM needs more
@@ -205,7 +253,7 @@ recv_begin:
205 ret = wait(chip, STAT_RDA); 253 ret = wait(chip, STAT_RDA);
206 if (ret) 254 if (ret)
207 return -EIO; 255 return -EIO;
208 buf[i] = inb(chip->vendor.base + RDFIFO); 256 buf[i] = tpm_data_in(RDFIFO);
209 } 257 }
210 258
211 if (buf[0] != TPM_VL_VER) { 259 if (buf[0] != TPM_VL_VER) {
@@ -220,7 +268,7 @@ recv_begin:
220 268
221 for (i = 0; i < size; i++) { 269 for (i = 0; i < size; i++) {
222 wait(chip, STAT_RDA); 270 wait(chip, STAT_RDA);
223 buf[i] = inb(chip->vendor.base + RDFIFO); 271 buf[i] = tpm_data_in(RDFIFO);
224 } 272 }
225 273
226 if ((size == 0x6D00) && (buf[1] == 0x80)) { 274 if ((size == 0x6D00) && (buf[1] == 0x80)) {
@@ -269,7 +317,7 @@ static int tpm_inf_send(struct tpm_chip *chip, u8 * buf, size_t count)
269 u8 count_high, count_low, count_4, count_3, count_2, count_1; 317 u8 count_high, count_low, count_4, count_3, count_2, count_1;
270 318
271 /* Disabling Reset, LP and IRQC */ 319 /* Disabling Reset, LP and IRQC */
272 outb(RESET_LP_IRQC_DISABLE, chip->vendor.base + CMD); 320 tpm_data_out(RESET_LP_IRQC_DISABLE, CMD);
273 321
274 ret = empty_fifo(chip, 1); 322 ret = empty_fifo(chip, 1);
275 if (ret) { 323 if (ret) {
@@ -320,7 +368,7 @@ static void tpm_inf_cancel(struct tpm_chip *chip)
320 368
321static u8 tpm_inf_status(struct tpm_chip *chip) 369static u8 tpm_inf_status(struct tpm_chip *chip)
322{ 370{
323 return inb(chip->vendor.base + STAT); 371 return tpm_data_in(STAT);
324} 372}
325 373
326static DEVICE_ATTR(pubek, S_IRUGO, tpm_show_pubek, NULL); 374static DEVICE_ATTR(pubek, S_IRUGO, tpm_show_pubek, NULL);
@@ -381,51 +429,88 @@ static int __devinit tpm_inf_pnp_probe(struct pnp_dev *dev,
381 /* read IO-ports through PnP */ 429 /* read IO-ports through PnP */
382 if (pnp_port_valid(dev, 0) && pnp_port_valid(dev, 1) && 430 if (pnp_port_valid(dev, 0) && pnp_port_valid(dev, 1) &&
383 !(pnp_port_flags(dev, 0) & IORESOURCE_DISABLED)) { 431 !(pnp_port_flags(dev, 0) & IORESOURCE_DISABLED)) {
384 TPM_INF_ADDR = pnp_port_start(dev, 0); 432
385 TPM_INF_ADDR_LEN = pnp_port_len(dev, 0); 433 tpm_dev.iotype = TPM_INF_IO_PORT;
386 TPM_INF_DATA = (TPM_INF_ADDR + 1); 434
387 TPM_INF_BASE = pnp_port_start(dev, 1); 435 tpm_dev.config_port = pnp_port_start(dev, 0);
388 TPM_INF_PORT_LEN = pnp_port_len(dev, 1); 436 tpm_dev.config_size = pnp_port_len(dev, 0);
389 if ((TPM_INF_PORT_LEN < 4) || (TPM_INF_ADDR_LEN < 2)) { 437 tpm_dev.data_regs = pnp_port_start(dev, 1);
438 tpm_dev.data_size = pnp_port_len(dev, 1);
439 if ((tpm_dev.data_size < 4) || (tpm_dev.config_size < 2)) {
390 rc = -EINVAL; 440 rc = -EINVAL;
391 goto err_last; 441 goto err_last;
392 } 442 }
393 dev_info(&dev->dev, "Found %s with ID %s\n", 443 dev_info(&dev->dev, "Found %s with ID %s\n",
394 dev->name, dev_id->id); 444 dev->name, dev_id->id);
395 if (!((TPM_INF_BASE >> 8) & 0xff)) { 445 if (!((tpm_dev.data_regs >> 8) & 0xff)) {
396 rc = -EINVAL; 446 rc = -EINVAL;
397 goto err_last; 447 goto err_last;
398 } 448 }
399 /* publish my base address and request region */ 449 /* publish my base address and request region */
400 if (request_region 450 if (request_region(tpm_dev.data_regs, tpm_dev.data_size,
401 (TPM_INF_BASE, TPM_INF_PORT_LEN, "tpm_infineon0") == NULL) { 451 "tpm_infineon0") == NULL) {
402 rc = -EINVAL; 452 rc = -EINVAL;
403 goto err_last; 453 goto err_last;
404 } 454 }
405 if (request_region 455 if (request_region(tpm_dev.config_port, tpm_dev.config_size,
406 (TPM_INF_ADDR, TPM_INF_ADDR_LEN, "tpm_infineon0") == NULL) { 456 "tpm_infineon0") == NULL) {
457 release_region(tpm_dev.data_regs, tpm_dev.data_size);
407 rc = -EINVAL; 458 rc = -EINVAL;
408 goto err_last; 459 goto err_last;
409 } 460 }
461 } else if (pnp_mem_valid(dev, 0) &&
462 !(pnp_mem_flags(dev, 0) & IORESOURCE_DISABLED)) {
463
464 tpm_dev.iotype = TPM_INF_IO_MEM;
465
466 tpm_dev.map_base = pnp_mem_start(dev, 0);
467 tpm_dev.map_size = pnp_mem_len(dev, 0);
468
469 dev_info(&dev->dev, "Found %s with ID %s\n",
470 dev->name, dev_id->id);
471
472 /* publish my base address and request region */
473 if (request_mem_region(tpm_dev.map_base, tpm_dev.map_size,
474 "tpm_infineon0") == NULL) {
475 rc = -EINVAL;
476 goto err_last;
477 }
478
479 tpm_dev.mem_base = ioremap(tpm_dev.map_base, tpm_dev.map_size);
480 if (tpm_dev.mem_base == NULL) {
481 release_mem_region(tpm_dev.map_base, tpm_dev.map_size);
482 rc = -EINVAL;
483 goto err_last;
484 }
485
486 /*
487 * The only known MMIO based Infineon TPM system provides
488 * a single large mem region with the device config
489 * registers at the default TPM_ADDR. The data registers
490 * seem like they could be placed anywhere within the MMIO
491 * region, but lets just put them at zero offset.
492 */
493 tpm_dev.index_off = TPM_ADDR;
494 tpm_dev.data_regs = 0x0;
410 } else { 495 } else {
411 rc = -EINVAL; 496 rc = -EINVAL;
412 goto err_last; 497 goto err_last;
413 } 498 }
414 499
415 /* query chip for its vendor, its version number a.s.o. */ 500 /* query chip for its vendor, its version number a.s.o. */
416 outb(ENABLE_REGISTER_PAIR, TPM_INF_ADDR); 501 tpm_config_out(ENABLE_REGISTER_PAIR, TPM_INF_ADDR);
417 outb(IDVENL, TPM_INF_ADDR); 502 tpm_config_out(IDVENL, TPM_INF_ADDR);
418 vendorid[1] = inb(TPM_INF_DATA); 503 vendorid[1] = tpm_config_in(TPM_INF_DATA);
419 outb(IDVENH, TPM_INF_ADDR); 504 tpm_config_out(IDVENH, TPM_INF_ADDR);
420 vendorid[0] = inb(TPM_INF_DATA); 505 vendorid[0] = tpm_config_in(TPM_INF_DATA);
421 outb(IDPDL, TPM_INF_ADDR); 506 tpm_config_out(IDPDL, TPM_INF_ADDR);
422 productid[1] = inb(TPM_INF_DATA); 507 productid[1] = tpm_config_in(TPM_INF_DATA);
423 outb(IDPDH, TPM_INF_ADDR); 508 tpm_config_out(IDPDH, TPM_INF_ADDR);
424 productid[0] = inb(TPM_INF_DATA); 509 productid[0] = tpm_config_in(TPM_INF_DATA);
425 outb(CHIP_ID1, TPM_INF_ADDR); 510 tpm_config_out(CHIP_ID1, TPM_INF_ADDR);
426 version[1] = inb(TPM_INF_DATA); 511 version[1] = tpm_config_in(TPM_INF_DATA);
427 outb(CHIP_ID2, TPM_INF_ADDR); 512 tpm_config_out(CHIP_ID2, TPM_INF_ADDR);
428 version[0] = inb(TPM_INF_DATA); 513 version[0] = tpm_config_in(TPM_INF_DATA);
429 514
430 switch ((productid[0] << 8) | productid[1]) { 515 switch ((productid[0] << 8) | productid[1]) {
431 case 6: 516 case 6:
@@ -442,51 +527,54 @@ static int __devinit tpm_inf_pnp_probe(struct pnp_dev *dev,
442 if ((vendorid[0] << 8 | vendorid[1]) == (TPM_INFINEON_DEV_VEN_VALUE)) { 527 if ((vendorid[0] << 8 | vendorid[1]) == (TPM_INFINEON_DEV_VEN_VALUE)) {
443 528
444 /* configure TPM with IO-ports */ 529 /* configure TPM with IO-ports */
445 outb(IOLIMH, TPM_INF_ADDR); 530 tpm_config_out(IOLIMH, TPM_INF_ADDR);
446 outb(((TPM_INF_BASE >> 8) & 0xff), TPM_INF_DATA); 531 tpm_config_out((tpm_dev.data_regs >> 8) & 0xff, TPM_INF_DATA);
447 outb(IOLIML, TPM_INF_ADDR); 532 tpm_config_out(IOLIML, TPM_INF_ADDR);
448 outb((TPM_INF_BASE & 0xff), TPM_INF_DATA); 533 tpm_config_out((tpm_dev.data_regs & 0xff), TPM_INF_DATA);
449 534
450 /* control if IO-ports are set correctly */ 535 /* control if IO-ports are set correctly */
451 outb(IOLIMH, TPM_INF_ADDR); 536 tpm_config_out(IOLIMH, TPM_INF_ADDR);
452 ioh = inb(TPM_INF_DATA); 537 ioh = tpm_config_in(TPM_INF_DATA);
453 outb(IOLIML, TPM_INF_ADDR); 538 tpm_config_out(IOLIML, TPM_INF_ADDR);
454 iol = inb(TPM_INF_DATA); 539 iol = tpm_config_in(TPM_INF_DATA);
455 540
456 if ((ioh << 8 | iol) != TPM_INF_BASE) { 541 if ((ioh << 8 | iol) != tpm_dev.data_regs) {
457 dev_err(&dev->dev, 542 dev_err(&dev->dev,
458 "Could not set IO-ports to 0x%x\n", 543 "Could not set IO-data registers to 0x%x\n",
459 TPM_INF_BASE); 544 tpm_dev.data_regs);
460 rc = -EIO; 545 rc = -EIO;
461 goto err_release_region; 546 goto err_release_region;
462 } 547 }
463 548
464 /* activate register */ 549 /* activate register */
465 outb(TPM_DAR, TPM_INF_ADDR); 550 tpm_config_out(TPM_DAR, TPM_INF_ADDR);
466 outb(0x01, TPM_INF_DATA); 551 tpm_config_out(0x01, TPM_INF_DATA);
467 outb(DISABLE_REGISTER_PAIR, TPM_INF_ADDR); 552 tpm_config_out(DISABLE_REGISTER_PAIR, TPM_INF_ADDR);
468 553
469 /* disable RESET, LP and IRQC */ 554 /* disable RESET, LP and IRQC */
470 outb(RESET_LP_IRQC_DISABLE, TPM_INF_BASE + CMD); 555 tpm_data_out(RESET_LP_IRQC_DISABLE, CMD);
471 556
472 /* Finally, we're done, print some infos */ 557 /* Finally, we're done, print some infos */
473 dev_info(&dev->dev, "TPM found: " 558 dev_info(&dev->dev, "TPM found: "
474 "config base 0x%x, " 559 "config base 0x%lx, "
475 "io base 0x%x, " 560 "data base 0x%lx, "
476 "chip version 0x%02x%02x, " 561 "chip version 0x%02x%02x, "
477 "vendor id 0x%x%x (Infineon), " 562 "vendor id 0x%x%x (Infineon), "
478 "product id 0x%02x%02x" 563 "product id 0x%02x%02x"
479 "%s\n", 564 "%s\n",
480 TPM_INF_ADDR, 565 tpm_dev.iotype == TPM_INF_IO_PORT ?
481 TPM_INF_BASE, 566 tpm_dev.config_port :
567 tpm_dev.map_base + tpm_dev.index_off,
568 tpm_dev.iotype == TPM_INF_IO_PORT ?
569 tpm_dev.data_regs :
570 tpm_dev.map_base + tpm_dev.data_regs,
482 version[0], version[1], 571 version[0], version[1],
483 vendorid[0], vendorid[1], 572 vendorid[0], vendorid[1],
484 productid[0], productid[1], chipname); 573 productid[0], productid[1], chipname);
485 574
486 if (!(chip = tpm_register_hardware(&dev->dev, &tpm_inf))) { 575 if (!(chip = tpm_register_hardware(&dev->dev, &tpm_inf)))
487 goto err_release_region; 576 goto err_release_region;
488 } 577
489 chip->vendor.base = TPM_INF_BASE;
490 return 0; 578 return 0;
491 } else { 579 } else {
492 rc = -ENODEV; 580 rc = -ENODEV;
@@ -494,8 +582,13 @@ static int __devinit tpm_inf_pnp_probe(struct pnp_dev *dev,
494 } 582 }
495 583
496err_release_region: 584err_release_region:
497 release_region(TPM_INF_BASE, TPM_INF_PORT_LEN); 585 if (tpm_dev.iotype == TPM_INF_IO_PORT) {
498 release_region(TPM_INF_ADDR, TPM_INF_ADDR_LEN); 586 release_region(tpm_dev.data_regs, tpm_dev.data_size);
587 release_region(tpm_dev.config_port, tpm_dev.config_size);
588 } else {
589 iounmap(tpm_dev.mem_base);
590 release_mem_region(tpm_dev.map_base, tpm_dev.map_size);
591 }
499 592
500err_last: 593err_last:
501 return rc; 594 return rc;
@@ -506,8 +599,14 @@ static __devexit void tpm_inf_pnp_remove(struct pnp_dev *dev)
506 struct tpm_chip *chip = pnp_get_drvdata(dev); 599 struct tpm_chip *chip = pnp_get_drvdata(dev);
507 600
508 if (chip) { 601 if (chip) {
509 release_region(TPM_INF_BASE, TPM_INF_PORT_LEN); 602 if (tpm_dev.iotype == TPM_INF_IO_PORT) {
510 release_region(TPM_INF_ADDR, TPM_INF_ADDR_LEN); 603 release_region(tpm_dev.data_regs, tpm_dev.data_size);
604 release_region(tpm_dev.config_port,
605 tpm_dev.config_size);
606 } else {
607 iounmap(tpm_dev.mem_base);
608 release_mem_region(tpm_dev.map_base, tpm_dev.map_size);
609 }
511 tpm_remove_hardware(chip->dev); 610 tpm_remove_hardware(chip->dev);
512 } 611 }
513} 612}
@@ -539,5 +638,5 @@ module_exit(cleanup_inf);
539 638
540MODULE_AUTHOR("Marcel Selhorst <selhorst@crypto.rub.de>"); 639MODULE_AUTHOR("Marcel Selhorst <selhorst@crypto.rub.de>");
541MODULE_DESCRIPTION("Driver for Infineon TPM SLD 9630 TT 1.1 / SLB 9635 TT 1.2"); 640MODULE_DESCRIPTION("Driver for Infineon TPM SLD 9630 TT 1.1 / SLB 9635 TT 1.2");
542MODULE_VERSION("1.8"); 641MODULE_VERSION("1.9");
543MODULE_LICENSE("GPL"); 642MODULE_LICENSE("GPL");
diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c
index 389da364e6b6..7710a6a77d97 100644
--- a/drivers/char/tty_io.c
+++ b/drivers/char/tty_io.c
@@ -141,8 +141,6 @@ static DECLARE_MUTEX(allocated_ptys_lock);
141static int ptmx_open(struct inode *, struct file *); 141static int ptmx_open(struct inode *, struct file *);
142#endif 142#endif
143 143
144extern void disable_early_printk(void);
145
146static void initialize_tty_struct(struct tty_struct *tty); 144static void initialize_tty_struct(struct tty_struct *tty);
147 145
148static ssize_t tty_read(struct file *, char __user *, size_t, loff_t *); 146static ssize_t tty_read(struct file *, char __user *, size_t, loff_t *);
@@ -155,8 +153,8 @@ int tty_ioctl(struct inode * inode, struct file * file,
155 unsigned int cmd, unsigned long arg); 153 unsigned int cmd, unsigned long arg);
156static int tty_fasync(int fd, struct file * filp, int on); 154static int tty_fasync(int fd, struct file * filp, int on);
157static void release_tty(struct tty_struct *tty, int idx); 155static void release_tty(struct tty_struct *tty, int idx);
158static struct pid *__proc_set_tty(struct task_struct *tsk, 156static void __proc_set_tty(struct task_struct *tsk, struct tty_struct *tty);
159 struct tty_struct *tty); 157static void proc_set_tty(struct task_struct *tsk, struct tty_struct *tty);
160 158
161/** 159/**
162 * alloc_tty_struct - allocate a tty object 160 * alloc_tty_struct - allocate a tty object
@@ -1534,10 +1532,9 @@ void disassociate_ctty(int on_exit)
1534 } 1532 }
1535 1533
1536 spin_lock_irq(&current->sighand->siglock); 1534 spin_lock_irq(&current->sighand->siglock);
1537 tty_pgrp = current->signal->tty_old_pgrp; 1535 put_pid(current->signal->tty_old_pgrp);
1538 current->signal->tty_old_pgrp = NULL; 1536 current->signal->tty_old_pgrp = NULL;
1539 spin_unlock_irq(&current->sighand->siglock); 1537 spin_unlock_irq(&current->sighand->siglock);
1540 put_pid(tty_pgrp);
1541 1538
1542 mutex_lock(&tty_mutex); 1539 mutex_lock(&tty_mutex);
1543 /* It is possible that do_tty_hangup has free'd this tty */ 1540 /* It is possible that do_tty_hangup has free'd this tty */
@@ -1562,6 +1559,18 @@ void disassociate_ctty(int on_exit)
1562 unlock_kernel(); 1559 unlock_kernel();
1563} 1560}
1564 1561
1562/**
1563 *
1564 * no_tty - Ensure the current process does not have a controlling tty
1565 */
1566void no_tty(void)
1567{
1568 struct task_struct *tsk = current;
1569 if (tsk->signal->leader)
1570 disassociate_ctty(0);
1571 proc_clear_tty(tsk);
1572}
1573
1565 1574
1566/** 1575/**
1567 * stop_tty - propogate flow control 1576 * stop_tty - propogate flow control
@@ -2508,7 +2517,6 @@ static int tty_open(struct inode * inode, struct file * filp)
2508 int index; 2517 int index;
2509 dev_t device = inode->i_rdev; 2518 dev_t device = inode->i_rdev;
2510 unsigned short saved_flags = filp->f_flags; 2519 unsigned short saved_flags = filp->f_flags;
2511 struct pid *old_pgrp;
2512 2520
2513 nonseekable_open(inode, filp); 2521 nonseekable_open(inode, filp);
2514 2522
@@ -2602,17 +2610,15 @@ got_driver:
2602 goto retry_open; 2610 goto retry_open;
2603 } 2611 }
2604 2612
2605 old_pgrp = NULL;
2606 mutex_lock(&tty_mutex); 2613 mutex_lock(&tty_mutex);
2607 spin_lock_irq(&current->sighand->siglock); 2614 spin_lock_irq(&current->sighand->siglock);
2608 if (!noctty && 2615 if (!noctty &&
2609 current->signal->leader && 2616 current->signal->leader &&
2610 !current->signal->tty && 2617 !current->signal->tty &&
2611 tty->session == NULL) 2618 tty->session == NULL)
2612 old_pgrp = __proc_set_tty(current, tty); 2619 __proc_set_tty(current, tty);
2613 spin_unlock_irq(&current->sighand->siglock); 2620 spin_unlock_irq(&current->sighand->siglock);
2614 mutex_unlock(&tty_mutex); 2621 mutex_unlock(&tty_mutex);
2615 put_pid(old_pgrp);
2616 return 0; 2622 return 0;
2617} 2623}
2618 2624
@@ -3287,9 +3293,7 @@ int tty_ioctl(struct inode * inode, struct file * file,
3287 case TIOCNOTTY: 3293 case TIOCNOTTY:
3288 if (current->signal->tty != tty) 3294 if (current->signal->tty != tty)
3289 return -ENOTTY; 3295 return -ENOTTY;
3290 if (current->signal->leader) 3296 no_tty();
3291 disassociate_ctty(0);
3292 proc_clear_tty(current);
3293 return 0; 3297 return 0;
3294 case TIOCSCTTY: 3298 case TIOCSCTTY:
3295 return tiocsctty(tty, arg); 3299 return tiocsctty(tty, arg);
@@ -3766,7 +3770,9 @@ int tty_register_driver(struct tty_driver *driver)
3766 if (!driver->put_char) 3770 if (!driver->put_char)
3767 driver->put_char = tty_default_put_char; 3771 driver->put_char = tty_default_put_char;
3768 3772
3773 mutex_lock(&tty_mutex);
3769 list_add(&driver->tty_drivers, &tty_drivers); 3774 list_add(&driver->tty_drivers, &tty_drivers);
3775 mutex_unlock(&tty_mutex);
3770 3776
3771 if ( !(driver->flags & TTY_DRIVER_DYNAMIC_DEV) ) { 3777 if ( !(driver->flags & TTY_DRIVER_DYNAMIC_DEV) ) {
3772 for(i = 0; i < driver->num; i++) 3778 for(i = 0; i < driver->num; i++)
@@ -3792,8 +3798,9 @@ int tty_unregister_driver(struct tty_driver *driver)
3792 3798
3793 unregister_chrdev_region(MKDEV(driver->major, driver->minor_start), 3799 unregister_chrdev_region(MKDEV(driver->major, driver->minor_start),
3794 driver->num); 3800 driver->num);
3795 3801 mutex_lock(&tty_mutex);
3796 list_del(&driver->tty_drivers); 3802 list_del(&driver->tty_drivers);
3803 mutex_unlock(&tty_mutex);
3797 3804
3798 /* 3805 /*
3799 * Free the termios and termios_locked structures because 3806 * Free the termios and termios_locked structures because
@@ -3836,11 +3843,9 @@ void proc_clear_tty(struct task_struct *p)
3836 p->signal->tty = NULL; 3843 p->signal->tty = NULL;
3837 spin_unlock_irq(&p->sighand->siglock); 3844 spin_unlock_irq(&p->sighand->siglock);
3838} 3845}
3839EXPORT_SYMBOL(proc_clear_tty);
3840 3846
3841static struct pid *__proc_set_tty(struct task_struct *tsk, struct tty_struct *tty) 3847static void __proc_set_tty(struct task_struct *tsk, struct tty_struct *tty)
3842{ 3848{
3843 struct pid *old_pgrp;
3844 if (tty) { 3849 if (tty) {
3845 /* We should not have a session or pgrp to here but.... */ 3850 /* We should not have a session or pgrp to here but.... */
3846 put_pid(tty->session); 3851 put_pid(tty->session);
@@ -3848,21 +3853,16 @@ static struct pid *__proc_set_tty(struct task_struct *tsk, struct tty_struct *tt
3848 tty->session = get_pid(task_session(tsk)); 3853 tty->session = get_pid(task_session(tsk));
3849 tty->pgrp = get_pid(task_pgrp(tsk)); 3854 tty->pgrp = get_pid(task_pgrp(tsk));
3850 } 3855 }
3851 old_pgrp = tsk->signal->tty_old_pgrp; 3856 put_pid(tsk->signal->tty_old_pgrp);
3852 tsk->signal->tty = tty; 3857 tsk->signal->tty = tty;
3853 tsk->signal->tty_old_pgrp = NULL; 3858 tsk->signal->tty_old_pgrp = NULL;
3854 return old_pgrp;
3855} 3859}
3856 3860
3857void proc_set_tty(struct task_struct *tsk, struct tty_struct *tty) 3861static void proc_set_tty(struct task_struct *tsk, struct tty_struct *tty)
3858{ 3862{
3859 struct pid *old_pgrp;
3860
3861 spin_lock_irq(&tsk->sighand->siglock); 3863 spin_lock_irq(&tsk->sighand->siglock);
3862 old_pgrp = __proc_set_tty(tsk, tty); 3864 __proc_set_tty(tsk, tty);
3863 spin_unlock_irq(&tsk->sighand->siglock); 3865 spin_unlock_irq(&tsk->sighand->siglock);
3864
3865 put_pid(old_pgrp);
3866} 3866}
3867 3867
3868struct tty_struct *get_current_tty(void) 3868struct tty_struct *get_current_tty(void)
@@ -3897,9 +3897,6 @@ void __init console_init(void)
3897 * set up the console device so that later boot sequences can 3897 * set up the console device so that later boot sequences can
3898 * inform about problems etc.. 3898 * inform about problems etc..
3899 */ 3899 */
3900#ifdef CONFIG_EARLY_PRINTK
3901 disable_early_printk();
3902#endif
3903 call = __con_initcall_start; 3900 call = __con_initcall_start;
3904 while (call < __con_initcall_end) { 3901 while (call < __con_initcall_end) {
3905 (*call)(); 3902 (*call)();
diff --git a/drivers/char/vc_screen.c b/drivers/char/vc_screen.c
index 791930320a13..83aeedda200c 100644
--- a/drivers/char/vc_screen.c
+++ b/drivers/char/vc_screen.c
@@ -28,12 +28,13 @@
28#include <linux/interrupt.h> 28#include <linux/interrupt.h>
29#include <linux/mm.h> 29#include <linux/mm.h>
30#include <linux/init.h> 30#include <linux/init.h>
31#include <linux/mutex.h>
31#include <linux/vt_kern.h> 32#include <linux/vt_kern.h>
32#include <linux/selection.h> 33#include <linux/selection.h>
33#include <linux/kbd_kern.h> 34#include <linux/kbd_kern.h>
34#include <linux/console.h> 35#include <linux/console.h>
35#include <linux/smp_lock.h>
36#include <linux/device.h> 36#include <linux/device.h>
37
37#include <asm/uaccess.h> 38#include <asm/uaccess.h>
38#include <asm/byteorder.h> 39#include <asm/byteorder.h>
39#include <asm/unaligned.h> 40#include <asm/unaligned.h>
@@ -70,11 +71,11 @@ static loff_t vcs_lseek(struct file *file, loff_t offset, int orig)
70{ 71{
71 int size; 72 int size;
72 73
73 down(&con_buf_sem); 74 mutex_lock(&con_buf_mtx);
74 size = vcs_size(file->f_path.dentry->d_inode); 75 size = vcs_size(file->f_path.dentry->d_inode);
75 switch (orig) { 76 switch (orig) {
76 default: 77 default:
77 up(&con_buf_sem); 78 mutex_unlock(&con_buf_mtx);
78 return -EINVAL; 79 return -EINVAL;
79 case 2: 80 case 2:
80 offset += size; 81 offset += size;
@@ -85,11 +86,11 @@ static loff_t vcs_lseek(struct file *file, loff_t offset, int orig)
85 break; 86 break;
86 } 87 }
87 if (offset < 0 || offset > size) { 88 if (offset < 0 || offset > size) {
88 up(&con_buf_sem); 89 mutex_unlock(&con_buf_mtx);
89 return -EINVAL; 90 return -EINVAL;
90 } 91 }
91 file->f_pos = offset; 92 file->f_pos = offset;
92 up(&con_buf_sem); 93 mutex_unlock(&con_buf_mtx);
93 return file->f_pos; 94 return file->f_pos;
94} 95}
95 96
@@ -106,7 +107,7 @@ vcs_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)
106 unsigned short *org = NULL; 107 unsigned short *org = NULL;
107 ssize_t ret; 108 ssize_t ret;
108 109
109 down(&con_buf_sem); 110 mutex_lock(&con_buf_mtx);
110 111
111 pos = *ppos; 112 pos = *ppos;
112 113
@@ -263,7 +264,7 @@ vcs_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)
263 ret = read; 264 ret = read;
264unlock_out: 265unlock_out:
265 release_console_sem(); 266 release_console_sem();
266 up(&con_buf_sem); 267 mutex_unlock(&con_buf_mtx);
267 return ret; 268 return ret;
268} 269}
269 270
@@ -280,7 +281,7 @@ vcs_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
280 u16 *org0 = NULL, *org = NULL; 281 u16 *org0 = NULL, *org = NULL;
281 size_t ret; 282 size_t ret;
282 283
283 down(&con_buf_sem); 284 mutex_lock(&con_buf_mtx);
284 285
285 pos = *ppos; 286 pos = *ppos;
286 287
@@ -450,7 +451,7 @@ vcs_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
450unlock_out: 451unlock_out:
451 release_console_sem(); 452 release_console_sem();
452 453
453 up(&con_buf_sem); 454 mutex_unlock(&con_buf_mtx);
454 455
455 return ret; 456 return ret;
456} 457}
diff --git a/drivers/char/vt.c b/drivers/char/vt.c
index 1bbb45b937fd..bbd9fc412877 100644
--- a/drivers/char/vt.c
+++ b/drivers/char/vt.c
@@ -86,6 +86,7 @@
86#include <linux/mm.h> 86#include <linux/mm.h>
87#include <linux/console.h> 87#include <linux/console.h>
88#include <linux/init.h> 88#include <linux/init.h>
89#include <linux/mutex.h>
89#include <linux/vt_kern.h> 90#include <linux/vt_kern.h>
90#include <linux/selection.h> 91#include <linux/selection.h>
91#include <linux/tiocl.h> 92#include <linux/tiocl.h>
@@ -157,6 +158,8 @@ static void blank_screen_t(unsigned long dummy);
157static void set_palette(struct vc_data *vc); 158static void set_palette(struct vc_data *vc);
158 159
159static int printable; /* Is console ready for printing? */ 160static int printable; /* Is console ready for printing? */
161static int default_utf8;
162module_param(default_utf8, int, S_IRUGO | S_IWUSR);
160 163
161/* 164/*
162 * ignore_poke: don't unblank the screen when things are typed. This is 165 * ignore_poke: don't unblank the screen when things are typed. This is
@@ -348,10 +351,12 @@ void update_region(struct vc_data *vc, unsigned long start, int count)
348 351
349/* Structure of attributes is hardware-dependent */ 352/* Structure of attributes is hardware-dependent */
350 353
351static u8 build_attr(struct vc_data *vc, u8 _color, u8 _intensity, u8 _blink, u8 _underline, u8 _reverse) 354static u8 build_attr(struct vc_data *vc, u8 _color, u8 _intensity, u8 _blink,
355 u8 _underline, u8 _reverse, u8 _italic)
352{ 356{
353 if (vc->vc_sw->con_build_attr) 357 if (vc->vc_sw->con_build_attr)
354 return vc->vc_sw->con_build_attr(vc, _color, _intensity, _blink, _underline, _reverse); 358 return vc->vc_sw->con_build_attr(vc, _color, _intensity,
359 _blink, _underline, _reverse, _italic);
355 360
356#ifndef VT_BUF_VRAM_ONLY 361#ifndef VT_BUF_VRAM_ONLY
357/* 362/*
@@ -368,10 +373,13 @@ static u8 build_attr(struct vc_data *vc, u8 _color, u8 _intensity, u8 _blink, u8
368 u8 a = vc->vc_color; 373 u8 a = vc->vc_color;
369 if (!vc->vc_can_do_color) 374 if (!vc->vc_can_do_color)
370 return _intensity | 375 return _intensity |
376 (_italic ? 2 : 0) |
371 (_underline ? 4 : 0) | 377 (_underline ? 4 : 0) |
372 (_reverse ? 8 : 0) | 378 (_reverse ? 8 : 0) |
373 (_blink ? 0x80 : 0); 379 (_blink ? 0x80 : 0);
374 if (_underline) 380 if (_italic)
381 a = (a & 0xF0) | vc->vc_itcolor;
382 else if (_underline)
375 a = (a & 0xf0) | vc->vc_ulcolor; 383 a = (a & 0xf0) | vc->vc_ulcolor;
376 else if (_intensity == 0) 384 else if (_intensity == 0)
377 a = (a & 0xf0) | vc->vc_ulcolor; 385 a = (a & 0xf0) | vc->vc_ulcolor;
@@ -392,8 +400,10 @@ static u8 build_attr(struct vc_data *vc, u8 _color, u8 _intensity, u8 _blink, u8
392 400
393static void update_attr(struct vc_data *vc) 401static void update_attr(struct vc_data *vc)
394{ 402{
395 vc->vc_attr = build_attr(vc, vc->vc_color, vc->vc_intensity, vc->vc_blink, vc->vc_underline, vc->vc_reverse ^ vc->vc_decscnm); 403 vc->vc_attr = build_attr(vc, vc->vc_color, vc->vc_intensity,
396 vc->vc_video_erase_char = (build_attr(vc, vc->vc_color, 1, vc->vc_blink, 0, vc->vc_decscnm) << 8) | ' '; 404 vc->vc_blink, vc->vc_underline,
405 vc->vc_reverse ^ vc->vc_decscnm, vc->vc_italic);
406 vc->vc_video_erase_char = (build_attr(vc, vc->vc_color, 1, vc->vc_blink, 0, vc->vc_decscnm, 0) << 8) | ' ';
397} 407}
398 408
399/* Note: inverting the screen twice should revert to the original state */ 409/* Note: inverting the screen twice should revert to the original state */
@@ -934,6 +944,10 @@ int default_grn[] = {0x00,0x00,0xaa,0x55,0x00,0x00,0xaa,0xaa,
934int default_blu[] = {0x00,0x00,0x00,0x00,0xaa,0xaa,0xaa,0xaa, 944int default_blu[] = {0x00,0x00,0x00,0x00,0xaa,0xaa,0xaa,0xaa,
935 0x55,0x55,0x55,0x55,0xff,0xff,0xff,0xff}; 945 0x55,0x55,0x55,0x55,0xff,0xff,0xff,0xff};
936 946
947module_param_array(default_red, int, NULL, S_IRUGO | S_IWUSR);
948module_param_array(default_grn, int, NULL, S_IRUGO | S_IWUSR);
949module_param_array(default_blu, int, NULL, S_IRUGO | S_IWUSR);
950
937/* 951/*
938 * gotoxy() must verify all boundaries, because the arguments 952 * gotoxy() must verify all boundaries, because the arguments
939 * might also be negative. If the given position is out of 953 * might also be negative. If the given position is out of
@@ -1132,6 +1146,7 @@ static void csi_X(struct vc_data *vc, int vpar) /* erase the following vpar posi
1132static void default_attr(struct vc_data *vc) 1146static void default_attr(struct vc_data *vc)
1133{ 1147{
1134 vc->vc_intensity = 1; 1148 vc->vc_intensity = 1;
1149 vc->vc_italic = 0;
1135 vc->vc_underline = 0; 1150 vc->vc_underline = 0;
1136 vc->vc_reverse = 0; 1151 vc->vc_reverse = 0;
1137 vc->vc_blink = 0; 1152 vc->vc_blink = 0;
@@ -1154,6 +1169,9 @@ static void csi_m(struct vc_data *vc)
1154 case 2: 1169 case 2:
1155 vc->vc_intensity = 0; 1170 vc->vc_intensity = 0;
1156 break; 1171 break;
1172 case 3:
1173 vc->vc_italic = 1;
1174 break;
1157 case 4: 1175 case 4:
1158 vc->vc_underline = 1; 1176 vc->vc_underline = 1;
1159 break; 1177 break;
@@ -1194,6 +1212,9 @@ static void csi_m(struct vc_data *vc)
1194 case 22: 1212 case 22:
1195 vc->vc_intensity = 1; 1213 vc->vc_intensity = 1;
1196 break; 1214 break;
1215 case 23:
1216 vc->vc_italic = 0;
1217 break;
1197 case 24: 1218 case 24:
1198 vc->vc_underline = 0; 1219 vc->vc_underline = 0;
1199 break; 1220 break;
@@ -1454,6 +1475,7 @@ static void save_cur(struct vc_data *vc)
1454 vc->vc_saved_x = vc->vc_x; 1475 vc->vc_saved_x = vc->vc_x;
1455 vc->vc_saved_y = vc->vc_y; 1476 vc->vc_saved_y = vc->vc_y;
1456 vc->vc_s_intensity = vc->vc_intensity; 1477 vc->vc_s_intensity = vc->vc_intensity;
1478 vc->vc_s_italic = vc->vc_italic;
1457 vc->vc_s_underline = vc->vc_underline; 1479 vc->vc_s_underline = vc->vc_underline;
1458 vc->vc_s_blink = vc->vc_blink; 1480 vc->vc_s_blink = vc->vc_blink;
1459 vc->vc_s_reverse = vc->vc_reverse; 1481 vc->vc_s_reverse = vc->vc_reverse;
@@ -1468,6 +1490,7 @@ static void restore_cur(struct vc_data *vc)
1468{ 1490{
1469 gotoxy(vc, vc->vc_saved_x, vc->vc_saved_y); 1491 gotoxy(vc, vc->vc_saved_x, vc->vc_saved_y);
1470 vc->vc_intensity = vc->vc_s_intensity; 1492 vc->vc_intensity = vc->vc_s_intensity;
1493 vc->vc_italic = vc->vc_s_italic;
1471 vc->vc_underline = vc->vc_s_underline; 1494 vc->vc_underline = vc->vc_s_underline;
1472 vc->vc_blink = vc->vc_s_blink; 1495 vc->vc_blink = vc->vc_s_blink;
1473 vc->vc_reverse = vc->vc_s_reverse; 1496 vc->vc_reverse = vc->vc_s_reverse;
@@ -1497,7 +1520,7 @@ static void reset_terminal(struct vc_data *vc, int do_clear)
1497 vc->vc_charset = 0; 1520 vc->vc_charset = 0;
1498 vc->vc_need_wrap = 0; 1521 vc->vc_need_wrap = 0;
1499 vc->vc_report_mouse = 0; 1522 vc->vc_report_mouse = 0;
1500 vc->vc_utf = 0; 1523 vc->vc_utf = default_utf8;
1501 vc->vc_utf_count = 0; 1524 vc->vc_utf_count = 0;
1502 1525
1503 vc->vc_disp_ctrl = 0; 1526 vc->vc_disp_ctrl = 0;
@@ -1930,7 +1953,47 @@ static void do_con_trol(struct tty_struct *tty, struct vc_data *vc, int c)
1930 * kernel memory allocation is available. 1953 * kernel memory allocation is available.
1931 */ 1954 */
1932char con_buf[CON_BUF_SIZE]; 1955char con_buf[CON_BUF_SIZE];
1933DECLARE_MUTEX(con_buf_sem); 1956DEFINE_MUTEX(con_buf_mtx);
1957
1958/* is_double_width() is based on the wcwidth() implementation by
1959 * Markus Kuhn -- 2003-05-20 (Unicode 4.0)
1960 * Latest version: http://www.cl.cam.ac.uk/~mgk25/ucs/wcwidth.c
1961 */
1962struct interval {
1963 uint32_t first;
1964 uint32_t last;
1965};
1966
1967static int bisearch(uint32_t ucs, const struct interval *table, int max)
1968{
1969 int min = 0;
1970 int mid;
1971
1972 if (ucs < table[0].first || ucs > table[max].last)
1973 return 0;
1974 while (max >= min) {
1975 mid = (min + max) / 2;
1976 if (ucs > table[mid].last)
1977 min = mid + 1;
1978 else if (ucs < table[mid].first)
1979 max = mid - 1;
1980 else
1981 return 1;
1982 }
1983 return 0;
1984}
1985
1986static int is_double_width(uint32_t ucs)
1987{
1988 static const struct interval double_width[] = {
1989 { 0x1100, 0x115F }, { 0x2329, 0x232A }, { 0x2E80, 0x303E },
1990 { 0x3040, 0xA4CF }, { 0xAC00, 0xD7A3 }, { 0xF900, 0xFAFF },
1991 { 0xFE30, 0xFE6F }, { 0xFF00, 0xFF60 }, { 0xFFE0, 0xFFE6 },
1992 { 0x20000, 0x2FFFD }, { 0x30000, 0x3FFFD }
1993 };
1994 return bisearch(ucs, double_width,
1995 sizeof(double_width) / sizeof(*double_width) - 1);
1996}
1934 1997
1935/* acquires console_sem */ 1998/* acquires console_sem */
1936static int do_con_write(struct tty_struct *tty, const unsigned char *buf, int count) 1999static int do_con_write(struct tty_struct *tty, const unsigned char *buf, int count)
@@ -1948,6 +2011,10 @@ static int do_con_write(struct tty_struct *tty, const unsigned char *buf, int co
1948 unsigned int currcons; 2011 unsigned int currcons;
1949 unsigned long draw_from = 0, draw_to = 0; 2012 unsigned long draw_from = 0, draw_to = 0;
1950 struct vc_data *vc; 2013 struct vc_data *vc;
2014 unsigned char vc_attr;
2015 uint8_t rescan;
2016 uint8_t inverse;
2017 uint8_t width;
1951 u16 himask, charmask; 2018 u16 himask, charmask;
1952 const unsigned char *orig_buf = NULL; 2019 const unsigned char *orig_buf = NULL;
1953 int orig_count; 2020 int orig_count;
@@ -1983,7 +2050,7 @@ static int do_con_write(struct tty_struct *tty, const unsigned char *buf, int co
1983 2050
1984 /* At this point 'buf' is guaranteed to be a kernel buffer 2051 /* At this point 'buf' is guaranteed to be a kernel buffer
1985 * and therefore no access to userspace (and therefore sleeping) 2052 * and therefore no access to userspace (and therefore sleeping)
1986 * will be needed. The con_buf_sem serializes all tty based 2053 * will be needed. The con_buf_mtx serializes all tty based
1987 * console rendering and vcs write/read operations. We hold 2054 * console rendering and vcs write/read operations. We hold
1988 * the console spinlock during the entire write. 2055 * the console spinlock during the entire write.
1989 */ 2056 */
@@ -2010,53 +2077,86 @@ static int do_con_write(struct tty_struct *tty, const unsigned char *buf, int co
2010 buf++; 2077 buf++;
2011 n++; 2078 n++;
2012 count--; 2079 count--;
2080 rescan = 0;
2081 inverse = 0;
2082 width = 1;
2013 2083
2014 /* Do no translation at all in control states */ 2084 /* Do no translation at all in control states */
2015 if (vc->vc_state != ESnormal) { 2085 if (vc->vc_state != ESnormal) {
2016 tc = c; 2086 tc = c;
2017 } else if (vc->vc_utf && !vc->vc_disp_ctrl) { 2087 } else if (vc->vc_utf && !vc->vc_disp_ctrl) {
2018 /* Combine UTF-8 into Unicode */ 2088 /* Combine UTF-8 into Unicode in vc_utf_char.
2019 /* Malformed sequences as sequences of replacement glyphs */ 2089 * vc_utf_count is the number of continuation bytes still
2090 * expected to arrive.
2091 * vc_npar is the number of continuation bytes arrived so
2092 * far
2093 */
2020rescan_last_byte: 2094rescan_last_byte:
2021 if(c > 0x7f) { 2095 if ((c & 0xc0) == 0x80) {
2096 /* Continuation byte received */
2097 static const uint32_t utf8_length_changes[] = { 0x0000007f, 0x000007ff, 0x0000ffff, 0x001fffff, 0x03ffffff, 0x7fffffff };
2022 if (vc->vc_utf_count) { 2098 if (vc->vc_utf_count) {
2023 if ((c & 0xc0) == 0x80) { 2099 vc->vc_utf_char = (vc->vc_utf_char << 6) | (c & 0x3f);
2024 vc->vc_utf_char = (vc->vc_utf_char << 6) | (c & 0x3f); 2100 vc->vc_npar++;
2025 if (--vc->vc_utf_count) { 2101 if (--vc->vc_utf_count) {
2026 vc->vc_npar++; 2102 /* Still need some bytes */
2027 continue;
2028 }
2029 tc = c = vc->vc_utf_char;
2030 } else
2031 goto replacement_glyph;
2032 } else {
2033 vc->vc_npar = 0;
2034 if ((c & 0xe0) == 0xc0) {
2035 vc->vc_utf_count = 1;
2036 vc->vc_utf_char = (c & 0x1f);
2037 } else if ((c & 0xf0) == 0xe0) {
2038 vc->vc_utf_count = 2;
2039 vc->vc_utf_char = (c & 0x0f);
2040 } else if ((c & 0xf8) == 0xf0) {
2041 vc->vc_utf_count = 3;
2042 vc->vc_utf_char = (c & 0x07);
2043 } else if ((c & 0xfc) == 0xf8) {
2044 vc->vc_utf_count = 4;
2045 vc->vc_utf_char = (c & 0x03);
2046 } else if ((c & 0xfe) == 0xfc) {
2047 vc->vc_utf_count = 5;
2048 vc->vc_utf_char = (c & 0x01);
2049 } else
2050 goto replacement_glyph;
2051 continue; 2103 continue;
2052 } 2104 }
2105 /* Got a whole character */
2106 c = vc->vc_utf_char;
2107 /* Reject overlong sequences */
2108 if (c <= utf8_length_changes[vc->vc_npar - 1] ||
2109 c > utf8_length_changes[vc->vc_npar])
2110 c = 0xfffd;
2111 } else {
2112 /* Unexpected continuation byte */
2113 vc->vc_utf_count = 0;
2114 c = 0xfffd;
2115 }
2053 } else { 2116 } else {
2054 if (vc->vc_utf_count) 2117 /* Single ASCII byte or first byte of a sequence received */
2055 goto replacement_glyph; 2118 if (vc->vc_utf_count) {
2056 tc = c; 2119 /* Continuation byte expected */
2120 rescan = 1;
2121 vc->vc_utf_count = 0;
2122 c = 0xfffd;
2123 } else if (c > 0x7f) {
2124 /* First byte of a multibyte sequence received */
2125 vc->vc_npar = 0;
2126 if ((c & 0xe0) == 0xc0) {
2127 vc->vc_utf_count = 1;
2128 vc->vc_utf_char = (c & 0x1f);
2129 } else if ((c & 0xf0) == 0xe0) {
2130 vc->vc_utf_count = 2;
2131 vc->vc_utf_char = (c & 0x0f);
2132 } else if ((c & 0xf8) == 0xf0) {
2133 vc->vc_utf_count = 3;
2134 vc->vc_utf_char = (c & 0x07);
2135 } else if ((c & 0xfc) == 0xf8) {
2136 vc->vc_utf_count = 4;
2137 vc->vc_utf_char = (c & 0x03);
2138 } else if ((c & 0xfe) == 0xfc) {
2139 vc->vc_utf_count = 5;
2140 vc->vc_utf_char = (c & 0x01);
2141 } else {
2142 /* 254 and 255 are invalid */
2143 c = 0xfffd;
2144 }
2145 if (vc->vc_utf_count) {
2146 /* Still need some bytes */
2147 continue;
2148 }
2149 }
2150 /* Nothing to do if an ASCII byte was received */
2057 } 2151 }
2152 /* End of UTF-8 decoding. */
2153 /* c is the received character, or U+FFFD for invalid sequences. */
2154 /* Replace invalid Unicode code points with U+FFFD too */
2155 if ((c >= 0xd800 && c <= 0xdfff) || c == 0xfffe || c == 0xffff)
2156 c = 0xfffd;
2157 tc = c;
2058 } else { /* no utf or alternate charset mode */ 2158 } else { /* no utf or alternate charset mode */
2059 tc = vc->vc_translate[vc->vc_toggle_meta ? (c | 0x80) : c]; 2159 tc = vc->vc_translate[vc->vc_toggle_meta ? (c | 0x80) : c];
2060 } 2160 }
2061 2161
2062 /* If the original code was a control character we 2162 /* If the original code was a control character we
@@ -2076,56 +2176,80 @@ rescan_last_byte:
2076 && (c != 128+27); 2176 && (c != 128+27);
2077 2177
2078 if (vc->vc_state == ESnormal && ok) { 2178 if (vc->vc_state == ESnormal && ok) {
2179 if (vc->vc_utf && !vc->vc_disp_ctrl) {
2180 if (is_double_width(c))
2181 width = 2;
2182 }
2079 /* Now try to find out how to display it */ 2183 /* Now try to find out how to display it */
2080 tc = conv_uni_to_pc(vc, tc); 2184 tc = conv_uni_to_pc(vc, tc);
2081 if (tc & ~charmask) { 2185 if (tc & ~charmask) {
2082 if ( tc == -4 ) { 2186 if (tc == -1 || tc == -2) {
2083 /* If we got -4 (not found) then see if we have 2187 continue; /* nothing to display */
2084 defined a replacement character (U+FFFD) */ 2188 }
2085replacement_glyph: 2189 /* Glyph not found */
2086 tc = conv_uni_to_pc(vc, 0xfffd); 2190 if (!(vc->vc_utf && !vc->vc_disp_ctrl) && !(c & ~charmask)) {
2087 if (!(tc & ~charmask)) 2191 /* In legacy mode use the glyph we get by a 1:1 mapping.
2088 goto display_glyph; 2192 This would make absolutely no sense with Unicode in mind. */
2089 } else if ( tc != -3 ) 2193 tc = c;
2090 continue; /* nothing to display */ 2194 } else {
2091 /* no hash table or no replacement -- 2195 /* Display U+FFFD. If it's not found, display an inverse question mark. */
2092 * hope for the best */ 2196 tc = conv_uni_to_pc(vc, 0xfffd);
2093 if ( c & ~charmask ) 2197 if (tc < 0) {
2094 tc = '?'; 2198 inverse = 1;
2095 else 2199 tc = conv_uni_to_pc(vc, '?');
2096 tc = c; 2200 if (tc < 0) tc = '?';
2201 }
2202 }
2097 } 2203 }
2098 2204
2099display_glyph: 2205 if (!inverse) {
2100 if (vc->vc_need_wrap || vc->vc_decim) 2206 vc_attr = vc->vc_attr;
2101 FLUSH
2102 if (vc->vc_need_wrap) {
2103 cr(vc);
2104 lf(vc);
2105 }
2106 if (vc->vc_decim)
2107 insert_char(vc, 1);
2108 scr_writew(himask ?
2109 ((vc->vc_attr << 8) & ~himask) + ((tc & 0x100) ? himask : 0) + (tc & 0xff) :
2110 (vc->vc_attr << 8) + tc,
2111 (u16 *) vc->vc_pos);
2112 if (DO_UPDATE(vc) && draw_x < 0) {
2113 draw_x = vc->vc_x;
2114 draw_from = vc->vc_pos;
2115 }
2116 if (vc->vc_x == vc->vc_cols - 1) {
2117 vc->vc_need_wrap = vc->vc_decawm;
2118 draw_to = vc->vc_pos + 2;
2119 } else { 2207 } else {
2120 vc->vc_x++; 2208 /* invert vc_attr */
2121 draw_to = (vc->vc_pos += 2); 2209 if (!vc->vc_can_do_color) {
2210 vc_attr = (vc->vc_attr) ^ 0x08;
2211 } else if (vc->vc_hi_font_mask == 0x100) {
2212 vc_attr = ((vc->vc_attr) & 0x11) | (((vc->vc_attr) & 0xe0) >> 4) | (((vc->vc_attr) & 0x0e) << 4);
2213 } else {
2214 vc_attr = ((vc->vc_attr) & 0x88) | (((vc->vc_attr) & 0x70) >> 4) | (((vc->vc_attr) & 0x07) << 4);
2215 }
2122 } 2216 }
2123 if (vc->vc_utf_count) { 2217
2124 if (vc->vc_npar) { 2218 while (1) {
2125 vc->vc_npar--; 2219 if (vc->vc_need_wrap || vc->vc_decim)
2126 goto display_glyph; 2220 FLUSH
2221 if (vc->vc_need_wrap) {
2222 cr(vc);
2223 lf(vc);
2224 }
2225 if (vc->vc_decim)
2226 insert_char(vc, 1);
2227 scr_writew(himask ?
2228 ((vc_attr << 8) & ~himask) + ((tc & 0x100) ? himask : 0) + (tc & 0xff) :
2229 (vc_attr << 8) + tc,
2230 (u16 *) vc->vc_pos);
2231 if (DO_UPDATE(vc) && draw_x < 0) {
2232 draw_x = vc->vc_x;
2233 draw_from = vc->vc_pos;
2234 }
2235 if (vc->vc_x == vc->vc_cols - 1) {
2236 vc->vc_need_wrap = vc->vc_decawm;
2237 draw_to = vc->vc_pos + 2;
2238 } else {
2239 vc->vc_x++;
2240 draw_to = (vc->vc_pos += 2);
2127 } 2241 }
2128 vc->vc_utf_count = 0; 2242
2243 if (!--width) break;
2244
2245 tc = conv_uni_to_pc(vc, ' '); /* A space is printed in the second column */
2246 if (tc < 0) tc = ' ';
2247 }
2248
2249 if (rescan) {
2250 rescan = 0;
2251 inverse = 0;
2252 width = 1;
2129 c = orig; 2253 c = orig;
2130 goto rescan_last_byte; 2254 goto rescan_last_byte;
2131 } 2255 }
@@ -2581,6 +2705,11 @@ static void con_close(struct tty_struct *tty, struct file *filp)
2581 mutex_unlock(&tty_mutex); 2705 mutex_unlock(&tty_mutex);
2582} 2706}
2583 2707
2708static int default_italic_color = 2; // green (ASCII)
2709static int default_underline_color = 3; // cyan (ASCII)
2710module_param_named(italic, default_italic_color, int, S_IRUGO | S_IWUSR);
2711module_param_named(underline, default_underline_color, int, S_IRUGO | S_IWUSR);
2712
2584static void vc_init(struct vc_data *vc, unsigned int rows, 2713static void vc_init(struct vc_data *vc, unsigned int rows,
2585 unsigned int cols, int do_clear) 2714 unsigned int cols, int do_clear)
2586{ 2715{
@@ -2600,7 +2729,8 @@ static void vc_init(struct vc_data *vc, unsigned int rows,
2600 vc->vc_palette[k++] = default_blu[j] ; 2729 vc->vc_palette[k++] = default_blu[j] ;
2601 } 2730 }
2602 vc->vc_def_color = 0x07; /* white */ 2731 vc->vc_def_color = 0x07; /* white */
2603 vc->vc_ulcolor = 0x0f; /* bold white */ 2732 vc->vc_ulcolor = default_underline_color;
2733 vc->vc_itcolor = default_italic_color;
2604 vc->vc_halfcolor = 0x08; /* grey */ 2734 vc->vc_halfcolor = 0x08; /* grey */
2605 init_waitqueue_head(&vc->paste_wait); 2735 init_waitqueue_head(&vc->paste_wait);
2606 reset_terminal(vc, do_clear); 2736 reset_terminal(vc, do_clear);
diff --git a/drivers/char/vt_ioctl.c b/drivers/char/vt_ioctl.c
index c9f2dd620e87..c6f6f4209739 100644
--- a/drivers/char/vt_ioctl.c
+++ b/drivers/char/vt_ioctl.c
@@ -1061,7 +1061,7 @@ int vt_waitactive(int vt)
1061 schedule(); 1061 schedule();
1062 } 1062 }
1063 remove_wait_queue(&vt_activate_queue, &wait); 1063 remove_wait_queue(&vt_activate_queue, &wait);
1064 current->state = TASK_RUNNING; 1064 __set_current_state(TASK_RUNNING);
1065 return retval; 1065 return retval;
1066} 1066}
1067 1067
diff --git a/drivers/char/watchdog/omap_wdt.c b/drivers/char/watchdog/omap_wdt.c
index 84074a697dce..b36fa8de2131 100644
--- a/drivers/char/watchdog/omap_wdt.c
+++ b/drivers/char/watchdog/omap_wdt.c
@@ -34,7 +34,6 @@
34#include <linux/miscdevice.h> 34#include <linux/miscdevice.h>
35#include <linux/watchdog.h> 35#include <linux/watchdog.h>
36#include <linux/reboot.h> 36#include <linux/reboot.h>
37#include <linux/smp_lock.h>
38#include <linux/init.h> 37#include <linux/init.h>
39#include <linux/err.h> 38#include <linux/err.h>
40#include <linux/platform_device.h> 39#include <linux/platform_device.h>
diff --git a/drivers/cpufreq/cpufreq_ondemand.c b/drivers/cpufreq/cpufreq_ondemand.c
index 8d053f500fc2..8532bb79e5fc 100644
--- a/drivers/cpufreq/cpufreq_ondemand.c
+++ b/drivers/cpufreq/cpufreq_ondemand.c
@@ -470,7 +470,7 @@ static inline void dbs_timer_init(struct cpu_dbs_info_s *dbs_info)
470 dbs_info->enable = 1; 470 dbs_info->enable = 1;
471 ondemand_powersave_bias_init(); 471 ondemand_powersave_bias_init();
472 dbs_info->sample_type = DBS_NORMAL_SAMPLE; 472 dbs_info->sample_type = DBS_NORMAL_SAMPLE;
473 INIT_DELAYED_WORK(&dbs_info->work, do_dbs_timer); 473 INIT_DELAYED_WORK_DEFERRABLE(&dbs_info->work, do_dbs_timer);
474 queue_delayed_work_on(dbs_info->cpu, kondemand_wq, &dbs_info->work, 474 queue_delayed_work_on(dbs_info->cpu, kondemand_wq, &dbs_info->work,
475 delay); 475 delay);
476} 476}
diff --git a/drivers/edac/i82875p_edac.c b/drivers/edac/i82875p_edac.c
index 161fe09a6d38..2800b3e614a9 100644
--- a/drivers/edac/i82875p_edac.c
+++ b/drivers/edac/i82875p_edac.c
@@ -261,10 +261,6 @@ static void i82875p_check(struct mem_ctl_info *mci)
261 i82875p_process_error_info(mci, &info, 1); 261 i82875p_process_error_info(mci, &info, 1);
262} 262}
263 263
264#ifdef CONFIG_PROC_FS
265extern int pci_proc_attach_device(struct pci_dev *);
266#endif
267
268/* Return 0 on success or 1 on failure. */ 264/* Return 0 on success or 1 on failure. */
269static int i82875p_setup_overfl_dev(struct pci_dev *pdev, 265static int i82875p_setup_overfl_dev(struct pci_dev *pdev,
270 struct pci_dev **ovrfl_pdev, void __iomem **ovrfl_window) 266 struct pci_dev **ovrfl_pdev, void __iomem **ovrfl_window)
@@ -287,17 +283,12 @@ static int i82875p_setup_overfl_dev(struct pci_dev *pdev,
287 283
288 if (dev == NULL) 284 if (dev == NULL)
289 return 1; 285 return 1;
286
287 pci_bus_add_device(dev);
290 } 288 }
291 289
292 *ovrfl_pdev = dev; 290 *ovrfl_pdev = dev;
293 291
294#ifdef CONFIG_PROC_FS
295 if ((dev->procent == NULL) && pci_proc_attach_device(dev)) {
296 i82875p_printk(KERN_ERR, "%s(): Failed to attach overflow "
297 "device\n", __func__);
298 return 1;
299 }
300#endif /* CONFIG_PROC_FS */
301 if (pci_enable_device(dev)) { 292 if (pci_enable_device(dev)) {
302 i82875p_printk(KERN_ERR, "%s(): Failed to enable overflow " 293 i82875p_printk(KERN_ERR, "%s(): Failed to enable overflow "
303 "device\n", __func__); 294 "device\n", __func__);
diff --git a/drivers/eisa/virtual_root.c b/drivers/eisa/virtual_root.c
index 9b4fcac03ad5..3074879f231f 100644
--- a/drivers/eisa/virtual_root.c
+++ b/drivers/eisa/virtual_root.c
@@ -47,7 +47,7 @@ static void virtual_eisa_release (struct device *dev)
47 /* nothing really to do here */ 47 /* nothing really to do here */
48} 48}
49 49
50static int virtual_eisa_root_init (void) 50static int __init virtual_eisa_root_init (void)
51{ 51{
52 int r; 52 int r;
53 53
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
index 62e21cc73938..6ec04e79f685 100644
--- a/drivers/hid/hid-core.c
+++ b/drivers/hid/hid-core.c
@@ -20,7 +20,6 @@
20#include <linux/kernel.h> 20#include <linux/kernel.h>
21#include <linux/list.h> 21#include <linux/list.h>
22#include <linux/mm.h> 22#include <linux/mm.h>
23#include <linux/smp_lock.h>
24#include <linux/spinlock.h> 23#include <linux/spinlock.h>
25#include <asm/unaligned.h> 24#include <asm/unaligned.h>
26#include <asm/byteorder.h> 25#include <asm/byteorder.h>
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
index 6d105a1d41b1..25b72a491702 100644
--- a/drivers/hwmon/Kconfig
+++ b/drivers/hwmon/Kconfig
@@ -594,6 +594,30 @@ config SENSORS_HDAPS
594 Say Y here if you have an applicable laptop and want to experience 594 Say Y here if you have an applicable laptop and want to experience
595 the awesome power of hdaps. 595 the awesome power of hdaps.
596 596
597config SENSORS_APPLESMC
598 tristate "Apple SMC (Motion sensor, light sensor, keyboard backlight)"
599 depends on HWMON && INPUT && X86
600 select NEW_LEDS
601 select LEDS_CLASS
602 default n
603 help
604 This driver provides support for the Apple System Management
605 Controller, which provides an accelerometer (Apple Sudden Motion
606 Sensor), light sensors, temperature sensors, keyboard backlight
607 control and fan control.
608
609 Only Intel-based Apple's computers are supported (MacBook Pro,
610 MacBook, MacMini).
611
612 Data from the different sensors, keyboard backlight control and fan
613 control are accessible via sysfs.
614
615 This driver also provides an absolute input class device, allowing
616 the laptop to act as a pinball machine-esque joystick.
617
618 Say Y here if you have an applicable laptop and want to experience
619 the awesome power of applesmc.
620
597config HWMON_DEBUG_CHIP 621config HWMON_DEBUG_CHIP
598 bool "Hardware Monitoring Chip debugging messages" 622 bool "Hardware Monitoring Chip debugging messages"
599 depends on HWMON 623 depends on HWMON
diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile
index 4165c27a2f25..544f8d8dff4e 100644
--- a/drivers/hwmon/Makefile
+++ b/drivers/hwmon/Makefile
@@ -20,6 +20,7 @@ obj-$(CONFIG_SENSORS_ADM1026) += adm1026.o
20obj-$(CONFIG_SENSORS_ADM1029) += adm1029.o 20obj-$(CONFIG_SENSORS_ADM1029) += adm1029.o
21obj-$(CONFIG_SENSORS_ADM1031) += adm1031.o 21obj-$(CONFIG_SENSORS_ADM1031) += adm1031.o
22obj-$(CONFIG_SENSORS_ADM9240) += adm9240.o 22obj-$(CONFIG_SENSORS_ADM9240) += adm9240.o
23obj-$(CONFIG_SENSORS_APPLESMC) += applesmc.o
23obj-$(CONFIG_SENSORS_AMS) += ams/ 24obj-$(CONFIG_SENSORS_AMS) += ams/
24obj-$(CONFIG_SENSORS_ATXP1) += atxp1.o 25obj-$(CONFIG_SENSORS_ATXP1) += atxp1.o
25obj-$(CONFIG_SENSORS_DS1621) += ds1621.o 26obj-$(CONFIG_SENSORS_DS1621) += ds1621.o
diff --git a/drivers/hwmon/applesmc.c b/drivers/hwmon/applesmc.c
new file mode 100644
index 000000000000..3215f9c87f32
--- /dev/null
+++ b/drivers/hwmon/applesmc.c
@@ -0,0 +1,1339 @@
1/*
2 * drivers/hwmon/applesmc.c - driver for Apple's SMC (accelerometer, temperature
3 * sensors, fan control, keyboard backlight control) used in Intel-based Apple
4 * computers.
5 *
6 * Copyright (C) 2007 Nicolas Boichat <nicolas@boichat.ch>
7 *
8 * Based on hdaps.c driver:
9 * Copyright (C) 2005 Robert Love <rml@novell.com>
10 * Copyright (C) 2005 Jesper Juhl <jesper.juhl@gmail.com>
11 *
12 * Fan control based on smcFanControl:
13 * Copyright (C) 2006 Hendrik Holtmann <holtmann@mac.com>
14 *
15 * This program is free software; you can redistribute it and/or modify it
16 * under the terms of the GNU General Public License v2 as published by the
17 * Free Software Foundation.
18 *
19 * This program is distributed in the hope that it will be useful, but WITHOUT
20 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
21 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
22 * more details.
23 *
24 * You should have received a copy of the GNU General Public License along with
25 * this program; if not, write to the Free Software Foundation, Inc.,
26 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
27 */
28
29#include <linux/delay.h>
30#include <linux/platform_device.h>
31#include <linux/input.h>
32#include <linux/kernel.h>
33#include <linux/module.h>
34#include <linux/timer.h>
35#include <linux/dmi.h>
36#include <linux/mutex.h>
37#include <linux/hwmon-sysfs.h>
38#include <asm/io.h>
39#include <linux/leds.h>
40#include <linux/hwmon.h>
41#include <linux/workqueue.h>
42
43/* data port used by Apple SMC */
44#define APPLESMC_DATA_PORT 0x300
45/* command/status port used by Apple SMC */
46#define APPLESMC_CMD_PORT 0x304
47
48#define APPLESMC_NR_PORTS 32 /* 0x300-0x31f */
49
50#define APPLESMC_MAX_DATA_LENGTH 32
51
52#define APPLESMC_STATUS_MASK 0x0f
53#define APPLESMC_READ_CMD 0x10
54#define APPLESMC_WRITE_CMD 0x11
55#define APPLESMC_GET_KEY_BY_INDEX_CMD 0x12
56#define APPLESMC_GET_KEY_TYPE_CMD 0x13
57
58#define KEY_COUNT_KEY "#KEY" /* r-o ui32 */
59
60#define LIGHT_SENSOR_LEFT_KEY "ALV0" /* r-o {alv (6 bytes) */
61#define LIGHT_SENSOR_RIGHT_KEY "ALV1" /* r-o {alv (6 bytes) */
62#define BACKLIGHT_KEY "LKSB" /* w-o {lkb (2 bytes) */
63
64#define CLAMSHELL_KEY "MSLD" /* r-o ui8 (unused) */
65
66#define MOTION_SENSOR_X_KEY "MO_X" /* r-o sp78 (2 bytes) */
67#define MOTION_SENSOR_Y_KEY "MO_Y" /* r-o sp78 (2 bytes) */
68#define MOTION_SENSOR_Z_KEY "MO_Z" /* r-o sp78 (2 bytes) */
69#define MOTION_SENSOR_KEY "MOCN" /* r/w ui16 */
70
71#define FANS_COUNT "FNum" /* r-o ui8 */
72#define FANS_MANUAL "FS! " /* r-w ui16 */
73#define FAN_ACTUAL_SPEED "F0Ac" /* r-o fpe2 (2 bytes) */
74#define FAN_MIN_SPEED "F0Mn" /* r-o fpe2 (2 bytes) */
75#define FAN_MAX_SPEED "F0Mx" /* r-o fpe2 (2 bytes) */
76#define FAN_SAFE_SPEED "F0Sf" /* r-o fpe2 (2 bytes) */
77#define FAN_TARGET_SPEED "F0Tg" /* r-w fpe2 (2 bytes) */
78#define FAN_POSITION "F0ID" /* r-o char[16] */
79
80/*
81 * Temperature sensors keys (sp78 - 2 bytes).
82 * First set for Macbook(Pro), second for Macmini.
83 */
84static const char* temperature_sensors_sets[][13] = {
85 { "TA0P", "TB0T", "TC0D", "TC0P", "TG0H", "TG0P", "TG0T", "Th0H",
86 "Th1H", "Tm0P", "Ts0P", "Ts1P", NULL },
87 { "TC0D", "TC0P", NULL }
88};
89
90/* List of keys used to read/write fan speeds */
91static const char* fan_speed_keys[] = {
92 FAN_ACTUAL_SPEED,
93 FAN_MIN_SPEED,
94 FAN_MAX_SPEED,
95 FAN_SAFE_SPEED,
96 FAN_TARGET_SPEED
97};
98
99#define INIT_TIMEOUT_MSECS 5000 /* wait up to 5s for device init ... */
100#define INIT_WAIT_MSECS 50 /* ... in 50ms increments */
101
102#define APPLESMC_POLL_PERIOD (HZ/20) /* poll for input every 1/20s */
103#define APPLESMC_INPUT_FUZZ 4 /* input event threshold */
104#define APPLESMC_INPUT_FLAT 4
105
106#define SENSOR_X 0
107#define SENSOR_Y 1
108#define SENSOR_Z 2
109
110/* Structure to be passed to DMI_MATCH function */
111struct dmi_match_data {
112/* Indicates whether this computer has an accelerometer. */
113 int accelerometer;
114/* Indicates whether this computer has light sensors and keyboard backlight. */
115 int light;
116/* Indicates which temperature sensors set to use. */
117 int temperature_set;
118};
119
120static const int debug;
121static struct platform_device *pdev;
122static s16 rest_x;
123static s16 rest_y;
124static struct timer_list applesmc_timer;
125static struct input_dev *applesmc_idev;
126static struct class_device *hwmon_class_dev;
127
128/* Indicates whether this computer has an accelerometer. */
129static unsigned int applesmc_accelerometer;
130
131/* Indicates whether this computer has light sensors and keyboard backlight. */
132static unsigned int applesmc_light;
133
134/* Indicates which temperature sensors set to use. */
135static unsigned int applesmc_temperature_set;
136
137static struct mutex applesmc_lock;
138
139/*
140 * Last index written to key_at_index sysfs file, and value to use for all other
141 * key_at_index_* sysfs files.
142 */
143static unsigned int key_at_index;
144
145static struct workqueue_struct *applesmc_led_wq;
146
147/*
148 * __wait_status - Wait up to 2ms for the status port to get a certain value
149 * (masked with 0x0f), returning zero if the value is obtained. Callers must
150 * hold applesmc_lock.
151 */
152static int __wait_status(u8 val)
153{
154 unsigned int i;
155
156 val = val & APPLESMC_STATUS_MASK;
157
158 for (i = 0; i < 200; i++) {
159 if ((inb(APPLESMC_CMD_PORT) & APPLESMC_STATUS_MASK) == val) {
160 if (debug)
161 printk(KERN_DEBUG
162 "Waited %d us for status %x\n",
163 i*10, val);
164 return 0;
165 }
166 udelay(10);
167 }
168
169 printk(KERN_WARNING "applesmc: wait status failed: %x != %x\n",
170 val, inb(APPLESMC_CMD_PORT));
171
172 return -EIO;
173}
174
175/*
176 * applesmc_read_key - reads len bytes from a given key, and put them in buffer.
177 * Returns zero on success or a negative error on failure. Callers must
178 * hold applesmc_lock.
179 */
180static int applesmc_read_key(const char* key, u8* buffer, u8 len)
181{
182 int i;
183
184 if (len > APPLESMC_MAX_DATA_LENGTH) {
185 printk(KERN_ERR "applesmc_read_key: cannot read more than "
186 "%d bytes\n", APPLESMC_MAX_DATA_LENGTH);
187 return -EINVAL;
188 }
189
190 outb(APPLESMC_READ_CMD, APPLESMC_CMD_PORT);
191 if (__wait_status(0x0c))
192 return -EIO;
193
194 for (i = 0; i < 4; i++) {
195 outb(key[i], APPLESMC_DATA_PORT);
196 if (__wait_status(0x04))
197 return -EIO;
198 }
199 if (debug)
200 printk(KERN_DEBUG "<%s", key);
201
202 outb(len, APPLESMC_DATA_PORT);
203 if (debug)
204 printk(KERN_DEBUG ">%x", len);
205
206 for (i = 0; i < len; i++) {
207 if (__wait_status(0x05))
208 return -EIO;
209 buffer[i] = inb(APPLESMC_DATA_PORT);
210 if (debug)
211 printk(KERN_DEBUG "<%x", buffer[i]);
212 }
213 if (debug)
214 printk(KERN_DEBUG "\n");
215
216 return 0;
217}
218
219/*
220 * applesmc_write_key - writes len bytes from buffer to a given key.
221 * Returns zero on success or a negative error on failure. Callers must
222 * hold applesmc_lock.
223 */
224static int applesmc_write_key(const char* key, u8* buffer, u8 len)
225{
226 int i;
227
228 if (len > APPLESMC_MAX_DATA_LENGTH) {
229 printk(KERN_ERR "applesmc_write_key: cannot write more than "
230 "%d bytes\n", APPLESMC_MAX_DATA_LENGTH);
231 return -EINVAL;
232 }
233
234 outb(APPLESMC_WRITE_CMD, APPLESMC_CMD_PORT);
235 if (__wait_status(0x0c))
236 return -EIO;
237
238 for (i = 0; i < 4; i++) {
239 outb(key[i], APPLESMC_DATA_PORT);
240 if (__wait_status(0x04))
241 return -EIO;
242 }
243
244 outb(len, APPLESMC_DATA_PORT);
245
246 for (i = 0; i < len; i++) {
247 if (__wait_status(0x04))
248 return -EIO;
249 outb(buffer[i], APPLESMC_DATA_PORT);
250 }
251
252 return 0;
253}
254
255/*
256 * applesmc_get_key_at_index - get key at index, and put the result in key
257 * (char[6]). Returns zero on success or a negative error on failure. Callers
258 * must hold applesmc_lock.
259 */
260static int applesmc_get_key_at_index(int index, char* key)
261{
262 int i;
263 u8 readkey[4];
264 readkey[0] = index >> 24;
265 readkey[1] = index >> 16;
266 readkey[2] = index >> 8;
267 readkey[3] = index;
268
269 outb(APPLESMC_GET_KEY_BY_INDEX_CMD, APPLESMC_CMD_PORT);
270 if (__wait_status(0x0c))
271 return -EIO;
272
273 for (i = 0; i < 4; i++) {
274 outb(readkey[i], APPLESMC_DATA_PORT);
275 if (__wait_status(0x04))
276 return -EIO;
277 }
278
279 outb(4, APPLESMC_DATA_PORT);
280
281 for (i = 0; i < 4; i++) {
282 if (__wait_status(0x05))
283 return -EIO;
284 key[i] = inb(APPLESMC_DATA_PORT);
285 }
286 key[4] = 0;
287
288 return 0;
289}
290
291/*
292 * applesmc_get_key_type - get key type, and put the result in type (char[6]).
293 * Returns zero on success or a negative error on failure. Callers must
294 * hold applesmc_lock.
295 */
296static int applesmc_get_key_type(char* key, char* type)
297{
298 int i;
299
300 outb(APPLESMC_GET_KEY_TYPE_CMD, APPLESMC_CMD_PORT);
301 if (__wait_status(0x0c))
302 return -EIO;
303
304 for (i = 0; i < 4; i++) {
305 outb(key[i], APPLESMC_DATA_PORT);
306 if (__wait_status(0x04))
307 return -EIO;
308 }
309
310 outb(5, APPLESMC_DATA_PORT);
311
312 for (i = 0; i < 6; i++) {
313 if (__wait_status(0x05))
314 return -EIO;
315 type[i] = inb(APPLESMC_DATA_PORT);
316 }
317 type[5] = 0;
318
319 return 0;
320}
321
322/*
323 * applesmc_read_motion_sensor - Read motion sensor (X, Y or Z). Callers must
324 * hold applesmc_lock.
325 */
326static int applesmc_read_motion_sensor(int index, s16* value)
327{
328 u8 buffer[2];
329 int ret;
330
331 switch (index) {
332 case SENSOR_X:
333 ret = applesmc_read_key(MOTION_SENSOR_X_KEY, buffer, 2);
334 break;
335 case SENSOR_Y:
336 ret = applesmc_read_key(MOTION_SENSOR_Y_KEY, buffer, 2);
337 break;
338 case SENSOR_Z:
339 ret = applesmc_read_key(MOTION_SENSOR_Z_KEY, buffer, 2);
340 break;
341 default:
342 ret = -EINVAL;
343 }
344
345 *value = ((s16)buffer[0] << 8) | buffer[1];
346
347 return ret;
348}
349
350/*
351 * applesmc_device_init - initialize the accelerometer. Returns zero on success
352 * and negative error code on failure. Can sleep.
353 */
354static int applesmc_device_init(void)
355{
356 int total, ret = -ENXIO;
357 u8 buffer[2];
358
359 if (!applesmc_accelerometer)
360 return 0;
361
362 mutex_lock(&applesmc_lock);
363
364 for (total = INIT_TIMEOUT_MSECS; total > 0; total -= INIT_WAIT_MSECS) {
365 if (debug)
366 printk(KERN_DEBUG "applesmc try %d\n", total);
367 if (!applesmc_read_key(MOTION_SENSOR_KEY, buffer, 2) &&
368 (buffer[0] != 0x00 || buffer[1] != 0x00)) {
369 if (total == INIT_TIMEOUT_MSECS) {
370 printk(KERN_DEBUG "applesmc: device has"
371 " already been initialized"
372 " (0x%02x, 0x%02x).\n",
373 buffer[0], buffer[1]);
374 } else {
375 printk(KERN_DEBUG "applesmc: device"
376 " successfully initialized"
377 " (0x%02x, 0x%02x).\n",
378 buffer[0], buffer[1]);
379 }
380 ret = 0;
381 goto out;
382 }
383 buffer[0] = 0xe0;
384 buffer[1] = 0x00;
385 applesmc_write_key(MOTION_SENSOR_KEY, buffer, 2);
386 msleep(INIT_WAIT_MSECS);
387 }
388
389 printk(KERN_WARNING "applesmc: failed to init the device\n");
390
391out:
392 mutex_unlock(&applesmc_lock);
393 return ret;
394}
395
396/*
397 * applesmc_get_fan_count - get the number of fans. Callers must NOT hold
398 * applesmc_lock.
399 */
400static int applesmc_get_fan_count(void)
401{
402 int ret;
403 u8 buffer[1];
404
405 mutex_lock(&applesmc_lock);
406
407 ret = applesmc_read_key(FANS_COUNT, buffer, 1);
408
409 mutex_unlock(&applesmc_lock);
410 if (ret)
411 return ret;
412 else
413 return buffer[0];
414}
415
416/* Device model stuff */
417static int applesmc_probe(struct platform_device *dev)
418{
419 int ret;
420
421 ret = applesmc_device_init();
422 if (ret)
423 return ret;
424
425 printk(KERN_INFO "applesmc: device successfully initialized.\n");
426 return 0;
427}
428
429static int applesmc_resume(struct platform_device *dev)
430{
431 return applesmc_device_init();
432}
433
434static struct platform_driver applesmc_driver = {
435 .probe = applesmc_probe,
436 .resume = applesmc_resume,
437 .driver = {
438 .name = "applesmc",
439 .owner = THIS_MODULE,
440 },
441};
442
443/*
444 * applesmc_calibrate - Set our "resting" values. Callers must
445 * hold applesmc_lock.
446 */
447static void applesmc_calibrate(void)
448{
449 applesmc_read_motion_sensor(SENSOR_X, &rest_x);
450 applesmc_read_motion_sensor(SENSOR_Y, &rest_y);
451 rest_x = -rest_x;
452}
453
454static int applesmc_idev_open(struct input_dev *dev)
455{
456 add_timer(&applesmc_timer);
457
458 return 0;
459}
460
461static void applesmc_idev_close(struct input_dev *dev)
462{
463 del_timer_sync(&applesmc_timer);
464}
465
466static void applesmc_idev_poll(unsigned long unused)
467{
468 s16 x, y;
469
470 /* Cannot sleep. Try nonblockingly. If we fail, try again later. */
471 if (!mutex_trylock(&applesmc_lock)) {
472 mod_timer(&applesmc_timer, jiffies + APPLESMC_POLL_PERIOD);
473 return;
474 }
475
476 if (applesmc_read_motion_sensor(SENSOR_X, &x))
477 goto out;
478 if (applesmc_read_motion_sensor(SENSOR_Y, &y))
479 goto out;
480
481 x = -x;
482 input_report_abs(applesmc_idev, ABS_X, x - rest_x);
483 input_report_abs(applesmc_idev, ABS_Y, y - rest_y);
484 input_sync(applesmc_idev);
485
486out:
487 mod_timer(&applesmc_timer, jiffies + APPLESMC_POLL_PERIOD);
488
489 mutex_unlock(&applesmc_lock);
490}
491
492/* Sysfs Files */
493
494static ssize_t applesmc_position_show(struct device *dev,
495 struct device_attribute *attr, char *buf)
496{
497 int ret;
498 s16 x, y, z;
499
500 mutex_lock(&applesmc_lock);
501
502 ret = applesmc_read_motion_sensor(SENSOR_X, &x);
503 if (ret)
504 goto out;
505 ret = applesmc_read_motion_sensor(SENSOR_Y, &y);
506 if (ret)
507 goto out;
508 ret = applesmc_read_motion_sensor(SENSOR_Z, &z);
509 if (ret)
510 goto out;
511
512out:
513 mutex_unlock(&applesmc_lock);
514 if (ret)
515 return ret;
516 else
517 return snprintf(buf, PAGE_SIZE, "(%d,%d,%d)\n", x, y, z);
518}
519
520static ssize_t applesmc_light_show(struct device *dev,
521 struct device_attribute *attr, char *sysfsbuf)
522{
523 int ret;
524 u8 left = 0, right = 0;
525 u8 buffer[6];
526
527 mutex_lock(&applesmc_lock);
528
529 ret = applesmc_read_key(LIGHT_SENSOR_LEFT_KEY, buffer, 6);
530 left = buffer[2];
531 if (ret)
532 goto out;
533 ret = applesmc_read_key(LIGHT_SENSOR_RIGHT_KEY, buffer, 6);
534 right = buffer[2];
535
536out:
537 mutex_unlock(&applesmc_lock);
538 if (ret)
539 return ret;
540 else
541 return snprintf(sysfsbuf, PAGE_SIZE, "(%d,%d)\n", left, right);
542}
543
544/* Displays degree Celsius * 1000 */
545static ssize_t applesmc_show_temperature(struct device *dev,
546 struct device_attribute *devattr, char *sysfsbuf)
547{
548 int ret;
549 u8 buffer[2];
550 unsigned int temp;
551 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
552 const char* key =
553 temperature_sensors_sets[applesmc_temperature_set][attr->index];
554
555 mutex_lock(&applesmc_lock);
556
557 ret = applesmc_read_key(key, buffer, 2);
558 temp = buffer[0]*1000;
559 temp += (buffer[1] >> 6) * 250;
560
561 mutex_unlock(&applesmc_lock);
562
563 if (ret)
564 return ret;
565 else
566 return snprintf(sysfsbuf, PAGE_SIZE, "%u\n", temp);
567}
568
569static ssize_t applesmc_show_fan_speed(struct device *dev,
570 struct device_attribute *attr, char *sysfsbuf)
571{
572 int ret;
573 unsigned int speed = 0;
574 char newkey[5];
575 u8 buffer[2];
576 struct sensor_device_attribute_2 *sensor_attr =
577 to_sensor_dev_attr_2(attr);
578
579 newkey[0] = fan_speed_keys[sensor_attr->nr][0];
580 newkey[1] = '0' + sensor_attr->index;
581 newkey[2] = fan_speed_keys[sensor_attr->nr][2];
582 newkey[3] = fan_speed_keys[sensor_attr->nr][3];
583 newkey[4] = 0;
584
585 mutex_lock(&applesmc_lock);
586
587 ret = applesmc_read_key(newkey, buffer, 2);
588 speed = ((buffer[0] << 8 | buffer[1]) >> 2);
589
590 mutex_unlock(&applesmc_lock);
591 if (ret)
592 return ret;
593 else
594 return snprintf(sysfsbuf, PAGE_SIZE, "%u\n", speed);
595}
596
597static ssize_t applesmc_store_fan_speed(struct device *dev,
598 struct device_attribute *attr,
599 const char *sysfsbuf, size_t count)
600{
601 int ret;
602 u32 speed;
603 char newkey[5];
604 u8 buffer[2];
605 struct sensor_device_attribute_2 *sensor_attr =
606 to_sensor_dev_attr_2(attr);
607
608 speed = simple_strtoul(sysfsbuf, NULL, 10);
609
610 if (speed > 0x4000) /* Bigger than a 14-bit value */
611 return -EINVAL;
612
613 newkey[0] = fan_speed_keys[sensor_attr->nr][0];
614 newkey[1] = '0' + sensor_attr->index;
615 newkey[2] = fan_speed_keys[sensor_attr->nr][2];
616 newkey[3] = fan_speed_keys[sensor_attr->nr][3];
617 newkey[4] = 0;
618
619 mutex_lock(&applesmc_lock);
620
621 buffer[0] = (speed >> 6) & 0xff;
622 buffer[1] = (speed << 2) & 0xff;
623 ret = applesmc_write_key(newkey, buffer, 2);
624
625 mutex_unlock(&applesmc_lock);
626 if (ret)
627 return ret;
628 else
629 return count;
630}
631
632static ssize_t applesmc_show_fan_manual(struct device *dev,
633 struct device_attribute *devattr, char *sysfsbuf)
634{
635 int ret;
636 u16 manual = 0;
637 u8 buffer[2];
638 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
639
640 mutex_lock(&applesmc_lock);
641
642 ret = applesmc_read_key(FANS_MANUAL, buffer, 2);
643 manual = ((buffer[0] << 8 | buffer[1]) >> attr->index) & 0x01;
644
645 mutex_unlock(&applesmc_lock);
646 if (ret)
647 return ret;
648 else
649 return snprintf(sysfsbuf, PAGE_SIZE, "%d\n", manual);
650}
651
652static ssize_t applesmc_store_fan_manual(struct device *dev,
653 struct device_attribute *devattr,
654 const char *sysfsbuf, size_t count)
655{
656 int ret;
657 u8 buffer[2];
658 u32 input;
659 u16 val;
660 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
661
662 input = simple_strtoul(sysfsbuf, NULL, 10);
663
664 mutex_lock(&applesmc_lock);
665
666 ret = applesmc_read_key(FANS_MANUAL, buffer, 2);
667 val = (buffer[0] << 8 | buffer[1]);
668 if (ret)
669 goto out;
670
671 if (input)
672 val = val | (0x01 << attr->index);
673 else
674 val = val & ~(0x01 << attr->index);
675
676 buffer[0] = (val >> 8) & 0xFF;
677 buffer[1] = val & 0xFF;
678
679 ret = applesmc_write_key(FANS_MANUAL, buffer, 2);
680
681out:
682 mutex_unlock(&applesmc_lock);
683 if (ret)
684 return ret;
685 else
686 return count;
687}
688
689static ssize_t applesmc_show_fan_position(struct device *dev,
690 struct device_attribute *attr, char *sysfsbuf)
691{
692 int ret;
693 char newkey[5];
694 u8 buffer[17];
695 struct sensor_device_attribute_2 *sensor_attr =
696 to_sensor_dev_attr_2(attr);
697
698 newkey[0] = FAN_POSITION[0];
699 newkey[1] = '0' + sensor_attr->index;
700 newkey[2] = FAN_POSITION[2];
701 newkey[3] = FAN_POSITION[3];
702 newkey[4] = 0;
703
704 mutex_lock(&applesmc_lock);
705
706 ret = applesmc_read_key(newkey, buffer, 16);
707 buffer[16] = 0;
708
709 mutex_unlock(&applesmc_lock);
710 if (ret)
711 return ret;
712 else
713 return snprintf(sysfsbuf, PAGE_SIZE, "%s\n", buffer+4);
714}
715
716static ssize_t applesmc_calibrate_show(struct device *dev,
717 struct device_attribute *attr, char *sysfsbuf)
718{
719 return snprintf(sysfsbuf, PAGE_SIZE, "(%d,%d)\n", rest_x, rest_y);
720}
721
722static ssize_t applesmc_calibrate_store(struct device *dev,
723 struct device_attribute *attr, const char *sysfsbuf, size_t count)
724{
725 mutex_lock(&applesmc_lock);
726 applesmc_calibrate();
727 mutex_unlock(&applesmc_lock);
728
729 return count;
730}
731
732/* Store the next backlight value to be written by the work */
733static unsigned int backlight_value;
734
735static void applesmc_backlight_set(struct work_struct *work)
736{
737 u8 buffer[2];
738
739 mutex_lock(&applesmc_lock);
740 buffer[0] = backlight_value;
741 buffer[1] = 0x00;
742 applesmc_write_key(BACKLIGHT_KEY, buffer, 2);
743 mutex_unlock(&applesmc_lock);
744}
745static DECLARE_WORK(backlight_work, &applesmc_backlight_set);
746
747static void applesmc_brightness_set(struct led_classdev *led_cdev,
748 enum led_brightness value)
749{
750 int ret;
751
752 backlight_value = value;
753 ret = queue_work(applesmc_led_wq, &backlight_work);
754
755 if (debug && (!ret))
756 printk(KERN_DEBUG "applesmc: work was already on the queue.\n");
757}
758
759static ssize_t applesmc_key_count_show(struct device *dev,
760 struct device_attribute *attr, char *sysfsbuf)
761{
762 int ret;
763 u8 buffer[4];
764 u32 count;
765
766 mutex_lock(&applesmc_lock);
767
768 ret = applesmc_read_key(KEY_COUNT_KEY, buffer, 4);
769 count = ((u32)buffer[0]<<24) + ((u32)buffer[1]<<16) +
770 ((u32)buffer[2]<<8) + buffer[3];
771
772 mutex_unlock(&applesmc_lock);
773 if (ret)
774 return ret;
775 else
776 return snprintf(sysfsbuf, PAGE_SIZE, "%d\n", count);
777}
778
779static ssize_t applesmc_key_at_index_read_show(struct device *dev,
780 struct device_attribute *attr, char *sysfsbuf)
781{
782 char key[5];
783 char info[6];
784 int ret;
785
786 mutex_lock(&applesmc_lock);
787
788 ret = applesmc_get_key_at_index(key_at_index, key);
789
790 if (ret || !key[0]) {
791 mutex_unlock(&applesmc_lock);
792
793 return -EINVAL;
794 }
795
796 ret = applesmc_get_key_type(key, info);
797
798 if (ret) {
799 mutex_unlock(&applesmc_lock);
800
801 return ret;
802 }
803
804 /*
805 * info[0] maximum value (APPLESMC_MAX_DATA_LENGTH) is much lower than
806 * PAGE_SIZE, so we don't need any checks before writing to sysfsbuf.
807 */
808 ret = applesmc_read_key(key, sysfsbuf, info[0]);
809
810 mutex_unlock(&applesmc_lock);
811
812 if (!ret) {
813 return info[0];
814 }
815 else {
816 return ret;
817 }
818}
819
820static ssize_t applesmc_key_at_index_data_length_show(struct device *dev,
821 struct device_attribute *attr, char *sysfsbuf)
822{
823 char key[5];
824 char info[6];
825 int ret;
826
827 mutex_lock(&applesmc_lock);
828
829 ret = applesmc_get_key_at_index(key_at_index, key);
830
831 if (ret || !key[0]) {
832 mutex_unlock(&applesmc_lock);
833
834 return -EINVAL;
835 }
836
837 ret = applesmc_get_key_type(key, info);
838
839 mutex_unlock(&applesmc_lock);
840
841 if (!ret)
842 return snprintf(sysfsbuf, PAGE_SIZE, "%d\n", info[0]);
843 else
844 return ret;
845}
846
847static ssize_t applesmc_key_at_index_type_show(struct device *dev,
848 struct device_attribute *attr, char *sysfsbuf)
849{
850 char key[5];
851 char info[6];
852 int ret;
853
854 mutex_lock(&applesmc_lock);
855
856 ret = applesmc_get_key_at_index(key_at_index, key);
857
858 if (ret || !key[0]) {
859 mutex_unlock(&applesmc_lock);
860
861 return -EINVAL;
862 }
863
864 ret = applesmc_get_key_type(key, info);
865
866 mutex_unlock(&applesmc_lock);
867
868 if (!ret)
869 return snprintf(sysfsbuf, PAGE_SIZE, "%s\n", info+1);
870 else
871 return ret;
872}
873
874static ssize_t applesmc_key_at_index_name_show(struct device *dev,
875 struct device_attribute *attr, char *sysfsbuf)
876{
877 char key[5];
878 int ret;
879
880 mutex_lock(&applesmc_lock);
881
882 ret = applesmc_get_key_at_index(key_at_index, key);
883
884 mutex_unlock(&applesmc_lock);
885
886 if (!ret && key[0])
887 return snprintf(sysfsbuf, PAGE_SIZE, "%s\n", key);
888 else
889 return -EINVAL;
890}
891
892static ssize_t applesmc_key_at_index_show(struct device *dev,
893 struct device_attribute *attr, char *sysfsbuf)
894{
895 return snprintf(sysfsbuf, PAGE_SIZE, "%d\n", key_at_index);
896}
897
898static ssize_t applesmc_key_at_index_store(struct device *dev,
899 struct device_attribute *attr, const char *sysfsbuf, size_t count)
900{
901 mutex_lock(&applesmc_lock);
902
903 key_at_index = simple_strtoul(sysfsbuf, NULL, 10);
904
905 mutex_unlock(&applesmc_lock);
906
907 return count;
908}
909
910static struct led_classdev applesmc_backlight = {
911 .name = "smc:kbd_backlight",
912 .default_trigger = "nand-disk",
913 .brightness_set = applesmc_brightness_set,
914};
915
916static DEVICE_ATTR(position, 0444, applesmc_position_show, NULL);
917static DEVICE_ATTR(calibrate, 0644,
918 applesmc_calibrate_show, applesmc_calibrate_store);
919
920static struct attribute *accelerometer_attributes[] = {
921 &dev_attr_position.attr,
922 &dev_attr_calibrate.attr,
923 NULL
924};
925
926static const struct attribute_group accelerometer_attributes_group =
927 { .attrs = accelerometer_attributes };
928
929static DEVICE_ATTR(light, 0444, applesmc_light_show, NULL);
930
931static DEVICE_ATTR(key_count, 0444, applesmc_key_count_show, NULL);
932static DEVICE_ATTR(key_at_index, 0644,
933 applesmc_key_at_index_show, applesmc_key_at_index_store);
934static DEVICE_ATTR(key_at_index_name, 0444,
935 applesmc_key_at_index_name_show, NULL);
936static DEVICE_ATTR(key_at_index_type, 0444,
937 applesmc_key_at_index_type_show, NULL);
938static DEVICE_ATTR(key_at_index_data_length, 0444,
939 applesmc_key_at_index_data_length_show, NULL);
940static DEVICE_ATTR(key_at_index_data, 0444,
941 applesmc_key_at_index_read_show, NULL);
942
943static struct attribute *key_enumeration_attributes[] = {
944 &dev_attr_key_count.attr,
945 &dev_attr_key_at_index.attr,
946 &dev_attr_key_at_index_name.attr,
947 &dev_attr_key_at_index_type.attr,
948 &dev_attr_key_at_index_data_length.attr,
949 &dev_attr_key_at_index_data.attr,
950 NULL
951};
952
953static const struct attribute_group key_enumeration_group =
954 { .attrs = key_enumeration_attributes };
955
956/*
957 * Macro defining SENSOR_DEVICE_ATTR for a fan sysfs entries.
958 * - show actual speed
959 * - show/store minimum speed
960 * - show maximum speed
961 * - show safe speed
962 * - show/store target speed
963 * - show/store manual mode
964 */
965#define sysfs_fan_speeds_offset(offset) \
966static SENSOR_DEVICE_ATTR_2(fan##offset##_input, S_IRUGO, \
967 applesmc_show_fan_speed, NULL, 0, offset-1); \
968\
969static SENSOR_DEVICE_ATTR_2(fan##offset##_min, S_IRUGO | S_IWUSR, \
970 applesmc_show_fan_speed, applesmc_store_fan_speed, 1, offset-1); \
971\
972static SENSOR_DEVICE_ATTR_2(fan##offset##_max, S_IRUGO, \
973 applesmc_show_fan_speed, NULL, 2, offset-1); \
974\
975static SENSOR_DEVICE_ATTR_2(fan##offset##_safe, S_IRUGO, \
976 applesmc_show_fan_speed, NULL, 3, offset-1); \
977\
978static SENSOR_DEVICE_ATTR_2(fan##offset##_output, S_IRUGO | S_IWUSR, \
979 applesmc_show_fan_speed, applesmc_store_fan_speed, 4, offset-1); \
980\
981static SENSOR_DEVICE_ATTR(fan##offset##_manual, S_IRUGO | S_IWUSR, \
982 applesmc_show_fan_manual, applesmc_store_fan_manual, offset-1); \
983\
984static SENSOR_DEVICE_ATTR(fan##offset##_position, S_IRUGO, \
985 applesmc_show_fan_position, NULL, offset-1); \
986\
987static struct attribute *fan##offset##_attributes[] = { \
988 &sensor_dev_attr_fan##offset##_input.dev_attr.attr, \
989 &sensor_dev_attr_fan##offset##_min.dev_attr.attr, \
990 &sensor_dev_attr_fan##offset##_max.dev_attr.attr, \
991 &sensor_dev_attr_fan##offset##_safe.dev_attr.attr, \
992 &sensor_dev_attr_fan##offset##_output.dev_attr.attr, \
993 &sensor_dev_attr_fan##offset##_manual.dev_attr.attr, \
994 &sensor_dev_attr_fan##offset##_position.dev_attr.attr, \
995 NULL \
996};
997
998/*
999 * Create the needed functions for each fan using the macro defined above
1000 * (2 fans are supported)
1001 */
1002sysfs_fan_speeds_offset(1);
1003sysfs_fan_speeds_offset(2);
1004
1005static const struct attribute_group fan_attribute_groups[] = {
1006 { .attrs = fan1_attributes },
1007 { .attrs = fan2_attributes }
1008};
1009
1010/*
1011 * Temperature sensors sysfs entries.
1012 */
1013static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO,
1014 applesmc_show_temperature, NULL, 0);
1015static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO,
1016 applesmc_show_temperature, NULL, 1);
1017static SENSOR_DEVICE_ATTR(temp3_input, S_IRUGO,
1018 applesmc_show_temperature, NULL, 2);
1019static SENSOR_DEVICE_ATTR(temp4_input, S_IRUGO,
1020 applesmc_show_temperature, NULL, 3);
1021static SENSOR_DEVICE_ATTR(temp5_input, S_IRUGO,
1022 applesmc_show_temperature, NULL, 4);
1023static SENSOR_DEVICE_ATTR(temp6_input, S_IRUGO,
1024 applesmc_show_temperature, NULL, 5);
1025static SENSOR_DEVICE_ATTR(temp7_input, S_IRUGO,
1026 applesmc_show_temperature, NULL, 6);
1027static SENSOR_DEVICE_ATTR(temp8_input, S_IRUGO,
1028 applesmc_show_temperature, NULL, 7);
1029static SENSOR_DEVICE_ATTR(temp9_input, S_IRUGO,
1030 applesmc_show_temperature, NULL, 8);
1031static SENSOR_DEVICE_ATTR(temp10_input, S_IRUGO,
1032 applesmc_show_temperature, NULL, 9);
1033static SENSOR_DEVICE_ATTR(temp11_input, S_IRUGO,
1034 applesmc_show_temperature, NULL, 10);
1035static SENSOR_DEVICE_ATTR(temp12_input, S_IRUGO,
1036 applesmc_show_temperature, NULL, 11);
1037
1038static struct attribute *temperature_attributes[] = {
1039 &sensor_dev_attr_temp1_input.dev_attr.attr,
1040 &sensor_dev_attr_temp2_input.dev_attr.attr,
1041 &sensor_dev_attr_temp3_input.dev_attr.attr,
1042 &sensor_dev_attr_temp4_input.dev_attr.attr,
1043 &sensor_dev_attr_temp5_input.dev_attr.attr,
1044 &sensor_dev_attr_temp6_input.dev_attr.attr,
1045 &sensor_dev_attr_temp7_input.dev_attr.attr,
1046 &sensor_dev_attr_temp8_input.dev_attr.attr,
1047 &sensor_dev_attr_temp9_input.dev_attr.attr,
1048 &sensor_dev_attr_temp10_input.dev_attr.attr,
1049 &sensor_dev_attr_temp11_input.dev_attr.attr,
1050 &sensor_dev_attr_temp12_input.dev_attr.attr,
1051 NULL
1052};
1053
1054static const struct attribute_group temperature_attributes_group =
1055 { .attrs = temperature_attributes };
1056
1057/* Module stuff */
1058
1059/*
1060 * applesmc_dmi_match - found a match. return one, short-circuiting the hunt.
1061 */
1062static int applesmc_dmi_match(struct dmi_system_id *id)
1063{
1064 int i = 0;
1065 struct dmi_match_data* dmi_data = id->driver_data;
1066 printk(KERN_INFO "applesmc: %s detected:\n", id->ident);
1067 applesmc_accelerometer = dmi_data->accelerometer;
1068 printk(KERN_INFO "applesmc: - Model %s accelerometer\n",
1069 applesmc_accelerometer ? "with" : "without");
1070 applesmc_light = dmi_data->light;
1071 printk(KERN_INFO "applesmc: - Model %s light sensors and backlight\n",
1072 applesmc_light ? "with" : "without");
1073
1074 applesmc_temperature_set = dmi_data->temperature_set;
1075 while (temperature_sensors_sets[applesmc_temperature_set][i] != NULL)
1076 i++;
1077 printk(KERN_INFO "applesmc: - Model with %d temperature sensors\n", i);
1078 return 1;
1079}
1080
1081/* Create accelerometer ressources */
1082static int applesmc_create_accelerometer(void)
1083{
1084 int ret;
1085
1086 ret = sysfs_create_group(&pdev->dev.kobj,
1087 &accelerometer_attributes_group);
1088 if (ret)
1089 goto out;
1090
1091 applesmc_idev = input_allocate_device();
1092 if (!applesmc_idev) {
1093 ret = -ENOMEM;
1094 goto out_sysfs;
1095 }
1096
1097 /* initial calibrate for the input device */
1098 applesmc_calibrate();
1099
1100 /* initialize the input class */
1101 applesmc_idev->name = "applesmc";
1102 applesmc_idev->id.bustype = BUS_HOST;
1103 applesmc_idev->cdev.dev = &pdev->dev;
1104 applesmc_idev->evbit[0] = BIT(EV_ABS);
1105 applesmc_idev->open = applesmc_idev_open;
1106 applesmc_idev->close = applesmc_idev_close;
1107 input_set_abs_params(applesmc_idev, ABS_X,
1108 -256, 256, APPLESMC_INPUT_FUZZ, APPLESMC_INPUT_FLAT);
1109 input_set_abs_params(applesmc_idev, ABS_Y,
1110 -256, 256, APPLESMC_INPUT_FUZZ, APPLESMC_INPUT_FLAT);
1111
1112 ret = input_register_device(applesmc_idev);
1113 if (ret)
1114 goto out_idev;
1115
1116 /* start up our timer for the input device */
1117 init_timer(&applesmc_timer);
1118 applesmc_timer.function = applesmc_idev_poll;
1119 applesmc_timer.expires = jiffies + APPLESMC_POLL_PERIOD;
1120
1121 return 0;
1122
1123out_idev:
1124 input_free_device(applesmc_idev);
1125
1126out_sysfs:
1127 sysfs_remove_group(&pdev->dev.kobj, &accelerometer_attributes_group);
1128
1129out:
1130 printk(KERN_WARNING "applesmc: driver init failed (ret=%d)!\n", ret);
1131 return ret;
1132}
1133
1134/* Release all ressources used by the accelerometer */
1135static void applesmc_release_accelerometer(void)
1136{
1137 del_timer_sync(&applesmc_timer);
1138 input_unregister_device(applesmc_idev);
1139 sysfs_remove_group(&pdev->dev.kobj, &accelerometer_attributes_group);
1140}
1141
1142static __initdata struct dmi_match_data applesmc_dmi_data[] = {
1143/* MacBook Pro: accelerometer, backlight and temperature set 0 */
1144 { .accelerometer = 1, .light = 1, .temperature_set = 0 },
1145/* MacBook: accelerometer and temperature set 0 */
1146 { .accelerometer = 1, .light = 0, .temperature_set = 0 },
1147/* MacBook: temperature set 1 */
1148 { .accelerometer = 0, .light = 0, .temperature_set = 1 }
1149};
1150
1151/* Note that DMI_MATCH(...,"MacBook") will match "MacBookPro1,1".
1152 * So we need to put "Apple MacBook Pro" before "Apple MacBook". */
1153static __initdata struct dmi_system_id applesmc_whitelist[] = {
1154 { applesmc_dmi_match, "Apple MacBook Pro", {
1155 DMI_MATCH(DMI_BOARD_VENDOR,"Apple"),
1156 DMI_MATCH(DMI_PRODUCT_NAME,"MacBookPro") },
1157 (void*)&applesmc_dmi_data[0]},
1158 { applesmc_dmi_match, "Apple MacBook", {
1159 DMI_MATCH(DMI_BOARD_VENDOR,"Apple"),
1160 DMI_MATCH(DMI_PRODUCT_NAME,"MacBook") },
1161 (void*)&applesmc_dmi_data[1]},
1162 { applesmc_dmi_match, "Apple Macmini", {
1163 DMI_MATCH(DMI_BOARD_VENDOR,"Apple"),
1164 DMI_MATCH(DMI_PRODUCT_NAME,"Macmini") },
1165 (void*)&applesmc_dmi_data[2]},
1166 { .ident = NULL }
1167};
1168
1169static int __init applesmc_init(void)
1170{
1171 int ret;
1172 int count;
1173 int i;
1174
1175 mutex_init(&applesmc_lock);
1176
1177 if (!dmi_check_system(applesmc_whitelist)) {
1178 printk(KERN_WARNING "applesmc: supported laptop not found!\n");
1179 ret = -ENODEV;
1180 goto out;
1181 }
1182
1183 if (!request_region(APPLESMC_DATA_PORT, APPLESMC_NR_PORTS,
1184 "applesmc")) {
1185 ret = -ENXIO;
1186 goto out;
1187 }
1188
1189 ret = platform_driver_register(&applesmc_driver);
1190 if (ret)
1191 goto out_region;
1192
1193 pdev = platform_device_register_simple("applesmc", -1, NULL, 0);
1194 if (IS_ERR(pdev)) {
1195 ret = PTR_ERR(pdev);
1196 goto out_driver;
1197 }
1198
1199 /* Create key enumeration sysfs files */
1200 ret = sysfs_create_group(&pdev->dev.kobj, &key_enumeration_group);
1201 if (ret)
1202 goto out_device;
1203
1204 /* create fan files */
1205 count = applesmc_get_fan_count();
1206 if (count < 0) {
1207 printk(KERN_ERR "applesmc: Cannot get the number of fans.\n");
1208 } else {
1209 printk(KERN_INFO "applesmc: %d fans found.\n", count);
1210
1211 switch (count) {
1212 default:
1213 printk(KERN_WARNING "applesmc: More than 2 fans found,"
1214 " but at most 2 fans are supported"
1215 " by the driver.\n");
1216 case 2:
1217 ret = sysfs_create_group(&pdev->dev.kobj,
1218 &fan_attribute_groups[1]);
1219 if (ret)
1220 goto out_key_enumeration;
1221 case 1:
1222 ret = sysfs_create_group(&pdev->dev.kobj,
1223 &fan_attribute_groups[0]);
1224 if (ret)
1225 goto out_fan_1;
1226 case 0:
1227 ;
1228 }
1229 }
1230
1231 for (i = 0;
1232 temperature_sensors_sets[applesmc_temperature_set][i] != NULL;
1233 i++) {
1234 if (temperature_attributes[i] == NULL) {
1235 printk(KERN_ERR "applesmc: More temperature sensors "
1236 "in temperature_sensors_sets (at least %i)"
1237 "than available sysfs files in "
1238 "temperature_attributes (%i), please report "
1239 "this bug.\n", i, i-1);
1240 goto out_temperature;
1241 }
1242 ret = sysfs_create_file(&pdev->dev.kobj,
1243 temperature_attributes[i]);
1244 if (ret)
1245 goto out_temperature;
1246 }
1247
1248 if (applesmc_accelerometer) {
1249 ret = applesmc_create_accelerometer();
1250 if (ret)
1251 goto out_temperature;
1252 }
1253
1254 if (applesmc_light) {
1255 /* Add light sensor file */
1256 ret = sysfs_create_file(&pdev->dev.kobj, &dev_attr_light.attr);
1257 if (ret)
1258 goto out_accelerometer;
1259
1260 /* Create the workqueue */
1261 applesmc_led_wq = create_singlethread_workqueue("applesmc-led");
1262 if (!applesmc_led_wq) {
1263 ret = -ENOMEM;
1264 goto out_light_sysfs;
1265 }
1266
1267 /* register as a led device */
1268 ret = led_classdev_register(&pdev->dev, &applesmc_backlight);
1269 if (ret < 0)
1270 goto out_light_wq;
1271 }
1272
1273 hwmon_class_dev = hwmon_device_register(&pdev->dev);
1274 if (IS_ERR(hwmon_class_dev)) {
1275 ret = PTR_ERR(hwmon_class_dev);
1276 goto out_light_ledclass;
1277 }
1278
1279 printk(KERN_INFO "applesmc: driver successfully loaded.\n");
1280
1281 return 0;
1282
1283out_light_ledclass:
1284 if (applesmc_light)
1285 led_classdev_unregister(&applesmc_backlight);
1286out_light_wq:
1287 if (applesmc_light)
1288 destroy_workqueue(applesmc_led_wq);
1289out_light_sysfs:
1290 if (applesmc_light)
1291 sysfs_remove_file(&pdev->dev.kobj, &dev_attr_light.attr);
1292out_accelerometer:
1293 if (applesmc_accelerometer)
1294 applesmc_release_accelerometer();
1295out_temperature:
1296 sysfs_remove_group(&pdev->dev.kobj, &temperature_attributes_group);
1297 sysfs_remove_group(&pdev->dev.kobj, &fan_attribute_groups[0]);
1298out_fan_1:
1299 sysfs_remove_group(&pdev->dev.kobj, &fan_attribute_groups[1]);
1300out_key_enumeration:
1301 sysfs_remove_group(&pdev->dev.kobj, &key_enumeration_group);
1302out_device:
1303 platform_device_unregister(pdev);
1304out_driver:
1305 platform_driver_unregister(&applesmc_driver);
1306out_region:
1307 release_region(APPLESMC_DATA_PORT, APPLESMC_NR_PORTS);
1308out:
1309 printk(KERN_WARNING "applesmc: driver init failed (ret=%d)!\n", ret);
1310 return ret;
1311}
1312
1313static void __exit applesmc_exit(void)
1314{
1315 hwmon_device_unregister(hwmon_class_dev);
1316 if (applesmc_light) {
1317 led_classdev_unregister(&applesmc_backlight);
1318 destroy_workqueue(applesmc_led_wq);
1319 sysfs_remove_file(&pdev->dev.kobj, &dev_attr_light.attr);
1320 }
1321 if (applesmc_accelerometer)
1322 applesmc_release_accelerometer();
1323 sysfs_remove_group(&pdev->dev.kobj, &temperature_attributes_group);
1324 sysfs_remove_group(&pdev->dev.kobj, &fan_attribute_groups[0]);
1325 sysfs_remove_group(&pdev->dev.kobj, &fan_attribute_groups[1]);
1326 sysfs_remove_group(&pdev->dev.kobj, &key_enumeration_group);
1327 platform_device_unregister(pdev);
1328 platform_driver_unregister(&applesmc_driver);
1329 release_region(APPLESMC_DATA_PORT, APPLESMC_NR_PORTS);
1330
1331 printk(KERN_INFO "applesmc: driver unloaded.\n");
1332}
1333
1334module_init(applesmc_init);
1335module_exit(applesmc_exit);
1336
1337MODULE_AUTHOR("Nicolas Boichat");
1338MODULE_DESCRIPTION("Apple SMC");
1339MODULE_LICENSE("GPL v2");
diff --git a/drivers/hwmon/hdaps.c b/drivers/hwmon/hdaps.c
index bf759ea545ac..f82fa2d23f95 100644
--- a/drivers/hwmon/hdaps.c
+++ b/drivers/hwmon/hdaps.c
@@ -30,10 +30,12 @@
30#include <linux/platform_device.h> 30#include <linux/platform_device.h>
31#include <linux/input.h> 31#include <linux/input.h>
32#include <linux/kernel.h> 32#include <linux/kernel.h>
33#include <linux/mutex.h>
33#include <linux/module.h> 34#include <linux/module.h>
34#include <linux/timer.h> 35#include <linux/timer.h>
35#include <linux/dmi.h> 36#include <linux/dmi.h>
36#include <linux/jiffies.h> 37#include <linux/jiffies.h>
38
37#include <asm/io.h> 39#include <asm/io.h>
38 40
39#define HDAPS_LOW_PORT 0x1600 /* first port used by hdaps */ 41#define HDAPS_LOW_PORT 0x1600 /* first port used by hdaps */
@@ -71,10 +73,10 @@ static u8 km_activity;
71static int rest_x; 73static int rest_x;
72static int rest_y; 74static int rest_y;
73 75
74static DECLARE_MUTEX(hdaps_sem); 76static DEFINE_MUTEX(hdaps_mtx);
75 77
76/* 78/*
77 * __get_latch - Get the value from a given port. Callers must hold hdaps_sem. 79 * __get_latch - Get the value from a given port. Callers must hold hdaps_mtx.
78 */ 80 */
79static inline u8 __get_latch(u16 port) 81static inline u8 __get_latch(u16 port)
80{ 82{
@@ -83,7 +85,7 @@ static inline u8 __get_latch(u16 port)
83 85
84/* 86/*
85 * __check_latch - Check a port latch for a given value. Returns zero if the 87 * __check_latch - Check a port latch for a given value. Returns zero if the
86 * port contains the given value. Callers must hold hdaps_sem. 88 * port contains the given value. Callers must hold hdaps_mtx.
87 */ 89 */
88static inline int __check_latch(u16 port, u8 val) 90static inline int __check_latch(u16 port, u8 val)
89{ 91{
@@ -94,7 +96,7 @@ static inline int __check_latch(u16 port, u8 val)
94 96
95/* 97/*
96 * __wait_latch - Wait up to 100us for a port latch to get a certain value, 98 * __wait_latch - Wait up to 100us for a port latch to get a certain value,
97 * returning zero if the value is obtained. Callers must hold hdaps_sem. 99 * returning zero if the value is obtained. Callers must hold hdaps_mtx.
98 */ 100 */
99static int __wait_latch(u16 port, u8 val) 101static int __wait_latch(u16 port, u8 val)
100{ 102{
@@ -111,7 +113,7 @@ static int __wait_latch(u16 port, u8 val)
111 113
112/* 114/*
113 * __device_refresh - request a refresh from the accelerometer. Does not wait 115 * __device_refresh - request a refresh from the accelerometer. Does not wait
114 * for refresh to complete. Callers must hold hdaps_sem. 116 * for refresh to complete. Callers must hold hdaps_mtx.
115 */ 117 */
116static void __device_refresh(void) 118static void __device_refresh(void)
117{ 119{
@@ -125,7 +127,7 @@ static void __device_refresh(void)
125/* 127/*
126 * __device_refresh_sync - request a synchronous refresh from the 128 * __device_refresh_sync - request a synchronous refresh from the
127 * accelerometer. We wait for the refresh to complete. Returns zero if 129 * accelerometer. We wait for the refresh to complete. Returns zero if
128 * successful and nonzero on error. Callers must hold hdaps_sem. 130 * successful and nonzero on error. Callers must hold hdaps_mtx.
129 */ 131 */
130static int __device_refresh_sync(void) 132static int __device_refresh_sync(void)
131{ 133{
@@ -135,7 +137,7 @@ static int __device_refresh_sync(void)
135 137
136/* 138/*
137 * __device_complete - indicate to the accelerometer that we are done reading 139 * __device_complete - indicate to the accelerometer that we are done reading
138 * data, and then initiate an async refresh. Callers must hold hdaps_sem. 140 * data, and then initiate an async refresh. Callers must hold hdaps_mtx.
139 */ 141 */
140static inline void __device_complete(void) 142static inline void __device_complete(void)
141{ 143{
@@ -153,7 +155,7 @@ static int hdaps_readb_one(unsigned int port, u8 *val)
153{ 155{
154 int ret; 156 int ret;
155 157
156 down(&hdaps_sem); 158 mutex_lock(&hdaps_mtx);
157 159
158 /* do a sync refresh -- we need to be sure that we read fresh data */ 160 /* do a sync refresh -- we need to be sure that we read fresh data */
159 ret = __device_refresh_sync(); 161 ret = __device_refresh_sync();
@@ -164,7 +166,7 @@ static int hdaps_readb_one(unsigned int port, u8 *val)
164 __device_complete(); 166 __device_complete();
165 167
166out: 168out:
167 up(&hdaps_sem); 169 mutex_unlock(&hdaps_mtx);
168 return ret; 170 return ret;
169} 171}
170 172
@@ -199,9 +201,9 @@ static int hdaps_read_pair(unsigned int port1, unsigned int port2,
199{ 201{
200 int ret; 202 int ret;
201 203
202 down(&hdaps_sem); 204 mutex_lock(&hdaps_mtx);
203 ret = __hdaps_read_pair(port1, port2, val1, val2); 205 ret = __hdaps_read_pair(port1, port2, val1, val2);
204 up(&hdaps_sem); 206 mutex_unlock(&hdaps_mtx);
205 207
206 return ret; 208 return ret;
207} 209}
@@ -214,7 +216,7 @@ static int hdaps_device_init(void)
214{ 216{
215 int total, ret = -ENXIO; 217 int total, ret = -ENXIO;
216 218
217 down(&hdaps_sem); 219 mutex_lock(&hdaps_mtx);
218 220
219 outb(0x13, 0x1610); 221 outb(0x13, 0x1610);
220 outb(0x01, 0x161f); 222 outb(0x01, 0x161f);
@@ -280,7 +282,7 @@ static int hdaps_device_init(void)
280 } 282 }
281 283
282out: 284out:
283 up(&hdaps_sem); 285 mutex_unlock(&hdaps_mtx);
284 return ret; 286 return ret;
285} 287}
286 288
@@ -314,7 +316,7 @@ static struct platform_driver hdaps_driver = {
314}; 316};
315 317
316/* 318/*
317 * hdaps_calibrate - Set our "resting" values. Callers must hold hdaps_sem. 319 * hdaps_calibrate - Set our "resting" values. Callers must hold hdaps_mtx.
318 */ 320 */
319static void hdaps_calibrate(void) 321static void hdaps_calibrate(void)
320{ 322{
@@ -326,7 +328,7 @@ static void hdaps_mousedev_poll(unsigned long unused)
326 int x, y; 328 int x, y;
327 329
328 /* Cannot sleep. Try nonblockingly. If we fail, try again later. */ 330 /* Cannot sleep. Try nonblockingly. If we fail, try again later. */
329 if (down_trylock(&hdaps_sem)) { 331 if (mutex_trylock(&hdaps_mtx)) {
330 mod_timer(&hdaps_timer,jiffies + HDAPS_POLL_PERIOD); 332 mod_timer(&hdaps_timer,jiffies + HDAPS_POLL_PERIOD);
331 return; 333 return;
332 } 334 }
@@ -341,7 +343,7 @@ static void hdaps_mousedev_poll(unsigned long unused)
341 mod_timer(&hdaps_timer, jiffies + HDAPS_POLL_PERIOD); 343 mod_timer(&hdaps_timer, jiffies + HDAPS_POLL_PERIOD);
342 344
343out: 345out:
344 up(&hdaps_sem); 346 mutex_unlock(&hdaps_mtx);
345} 347}
346 348
347 349
@@ -421,9 +423,9 @@ static ssize_t hdaps_calibrate_store(struct device *dev,
421 struct device_attribute *attr, 423 struct device_attribute *attr,
422 const char *buf, size_t count) 424 const char *buf, size_t count)
423{ 425{
424 down(&hdaps_sem); 426 mutex_lock(&hdaps_mtx);
425 hdaps_calibrate(); 427 hdaps_calibrate();
426 up(&hdaps_sem); 428 mutex_unlock(&hdaps_mtx);
427 429
428 return count; 430 return count;
429} 431}
diff --git a/drivers/i2c/busses/i2c-parport.c b/drivers/i2c/busses/i2c-parport.c
index 8c953707253f..039a07fde908 100644
--- a/drivers/i2c/busses/i2c-parport.c
+++ b/drivers/i2c/busses/i2c-parport.c
@@ -175,6 +175,7 @@ static void i2c_parport_attach (struct parport *port)
175 } 175 }
176 adapter->algo_data.data = port; 176 adapter->algo_data.data = port;
177 adapter->adapter.algo_data = &adapter->algo_data; 177 adapter->adapter.algo_data = &adapter->algo_data;
178 adapter->adapter.dev.parent = port->physport->dev;
178 179
179 if (parport_claim_or_block(adapter->pdev) < 0) { 180 if (parport_claim_or_block(adapter->pdev) < 0) {
180 printk(KERN_ERR "i2c-parport: Could not claim parallel port\n"); 181 printk(KERN_ERR "i2c-parport: Could not claim parallel port\n");
diff --git a/drivers/i2c/busses/scx200_acb.c b/drivers/i2c/busses/scx200_acb.c
index 0db56e7bc34e..0d6bd4f7b7fa 100644
--- a/drivers/i2c/busses/scx200_acb.c
+++ b/drivers/i2c/busses/scx200_acb.c
@@ -28,7 +28,6 @@
28#include <linux/kernel.h> 28#include <linux/kernel.h>
29#include <linux/init.h> 29#include <linux/init.h>
30#include <linux/i2c.h> 30#include <linux/i2c.h>
31#include <linux/smp_lock.h>
32#include <linux/pci.h> 31#include <linux/pci.h>
33#include <linux/delay.h> 32#include <linux/delay.h>
34#include <linux/mutex.h> 33#include <linux/mutex.h>
diff --git a/drivers/i2c/i2c-dev.c b/drivers/i2c/i2c-dev.c
index cb4fa9bef8cd..e7a709710592 100644
--- a/drivers/i2c/i2c-dev.c
+++ b/drivers/i2c/i2c-dev.c
@@ -30,7 +30,6 @@
30#include <linux/module.h> 30#include <linux/module.h>
31#include <linux/fs.h> 31#include <linux/fs.h>
32#include <linux/slab.h> 32#include <linux/slab.h>
33#include <linux/smp_lock.h>
34#include <linux/init.h> 33#include <linux/init.h>
35#include <linux/list.h> 34#include <linux/list.h>
36#include <linux/i2c.h> 35#include <linux/i2c.h>
diff --git a/drivers/ieee1394/dv1394.c b/drivers/ieee1394/dv1394.c
index 026e38face5c..208141377612 100644
--- a/drivers/ieee1394/dv1394.c
+++ b/drivers/ieee1394/dv1394.c
@@ -94,7 +94,6 @@
94#include <linux/pci.h> 94#include <linux/pci.h>
95#include <linux/fs.h> 95#include <linux/fs.h>
96#include <linux/poll.h> 96#include <linux/poll.h>
97#include <linux/smp_lock.h>
98#include <linux/mutex.h> 97#include <linux/mutex.h>
99#include <linux/bitops.h> 98#include <linux/bitops.h>
100#include <asm/byteorder.h> 99#include <asm/byteorder.h>
diff --git a/drivers/ieee1394/raw1394.c b/drivers/ieee1394/raw1394.c
index c6aefd9ad0e8..d382500f4210 100644
--- a/drivers/ieee1394/raw1394.c
+++ b/drivers/ieee1394/raw1394.c
@@ -35,7 +35,6 @@
35#include <linux/poll.h> 35#include <linux/poll.h>
36#include <linux/module.h> 36#include <linux/module.h>
37#include <linux/init.h> 37#include <linux/init.h>
38#include <linux/smp_lock.h>
39#include <linux/interrupt.h> 38#include <linux/interrupt.h>
40#include <linux/vmalloc.h> 39#include <linux/vmalloc.h>
41#include <linux/cdev.h> 40#include <linux/cdev.h>
diff --git a/drivers/ieee1394/video1394.c b/drivers/ieee1394/video1394.c
index 95ca26d75272..87ebd0846c34 100644
--- a/drivers/ieee1394/video1394.c
+++ b/drivers/ieee1394/video1394.c
@@ -39,7 +39,6 @@
39#include <linux/pci.h> 39#include <linux/pci.h>
40#include <linux/fs.h> 40#include <linux/fs.h>
41#include <linux/poll.h> 41#include <linux/poll.h>
42#include <linux/smp_lock.h>
43#include <linux/delay.h> 42#include <linux/delay.h>
44#include <linux/bitops.h> 43#include <linux/bitops.h>
45#include <linux/types.h> 44#include <linux/types.h>
diff --git a/drivers/infiniband/hw/ipath/ipath_fs.c b/drivers/infiniband/hw/ipath/ipath_fs.c
index 036ed1ef1796..ebd5c7bd2cdb 100644
--- a/drivers/infiniband/hw/ipath/ipath_fs.c
+++ b/drivers/infiniband/hw/ipath/ipath_fs.c
@@ -523,7 +523,7 @@ static int ipathfs_fill_super(struct super_block *sb, void *data,
523 int ret; 523 int ret;
524 524
525 static struct tree_descr files[] = { 525 static struct tree_descr files[] = {
526 [1] = {"atomic_stats", &atomic_stats_ops, S_IRUGO}, 526 [2] = {"atomic_stats", &atomic_stats_ops, S_IRUGO},
527 {""}, 527 {""},
528 }; 528 };
529 529
diff --git a/drivers/infiniband/ulp/iser/iser_verbs.c b/drivers/infiniband/ulp/iser/iser_verbs.c
index 89d6008bb673..3702e2375553 100644
--- a/drivers/infiniband/ulp/iser/iser_verbs.c
+++ b/drivers/infiniband/ulp/iser/iser_verbs.c
@@ -35,7 +35,6 @@
35#include <asm/io.h> 35#include <asm/io.h>
36#include <linux/kernel.h> 36#include <linux/kernel.h>
37#include <linux/module.h> 37#include <linux/module.h>
38#include <linux/smp_lock.h>
39#include <linux/delay.h> 38#include <linux/delay.h>
40#include <linux/version.h> 39#include <linux/version.h>
41 40
diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c
index 1f6fcec0c6fc..be3dbc1ae67d 100644
--- a/drivers/input/evdev.c
+++ b/drivers/input/evdev.c
@@ -18,7 +18,6 @@
18#include <linux/init.h> 18#include <linux/init.h>
19#include <linux/input.h> 19#include <linux/input.h>
20#include <linux/major.h> 20#include <linux/major.h>
21#include <linux/smp_lock.h>
22#include <linux/device.h> 21#include <linux/device.h>
23#include <linux/compat.h> 22#include <linux/compat.h>
24 23
diff --git a/drivers/input/input.c b/drivers/input/input.c
index 915e9ab7cab0..ccd8abafcb70 100644
--- a/drivers/input/input.c
+++ b/drivers/input/input.c
@@ -11,7 +11,6 @@
11 */ 11 */
12 12
13#include <linux/init.h> 13#include <linux/init.h>
14#include <linux/smp_lock.h>
15#include <linux/input.h> 14#include <linux/input.h>
16#include <linux/module.h> 15#include <linux/module.h>
17#include <linux/random.h> 16#include <linux/random.h>
diff --git a/drivers/input/joydev.c b/drivers/input/joydev.c
index 9bcc5425049b..06f0541b24da 100644
--- a/drivers/input/joydev.c
+++ b/drivers/input/joydev.c
@@ -24,7 +24,6 @@
24#include <linux/module.h> 24#include <linux/module.h>
25#include <linux/poll.h> 25#include <linux/poll.h>
26#include <linux/init.h> 26#include <linux/init.h>
27#include <linux/smp_lock.h>
28#include <linux/device.h> 27#include <linux/device.h>
29 28
30MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>"); 29MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>");
diff --git a/drivers/input/mousedev.c b/drivers/input/mousedev.c
index 7678e9876550..8675f9509393 100644
--- a/drivers/input/mousedev.c
+++ b/drivers/input/mousedev.c
@@ -19,7 +19,6 @@
19#include <linux/moduleparam.h> 19#include <linux/moduleparam.h>
20#include <linux/init.h> 20#include <linux/init.h>
21#include <linux/input.h> 21#include <linux/input.h>
22#include <linux/smp_lock.h>
23#include <linux/random.h> 22#include <linux/random.h>
24#include <linux/major.h> 23#include <linux/major.h>
25#include <linux/device.h> 24#include <linux/device.h>
diff --git a/drivers/input/tsdev.c b/drivers/input/tsdev.c
index 5e5b5c91d75b..8238b13874c2 100644
--- a/drivers/input/tsdev.c
+++ b/drivers/input/tsdev.c
@@ -48,7 +48,6 @@
48#include <linux/init.h> 48#include <linux/init.h>
49#include <linux/input.h> 49#include <linux/input.h>
50#include <linux/major.h> 50#include <linux/major.h>
51#include <linux/smp_lock.h>
52#include <linux/random.h> 51#include <linux/random.h>
53#include <linux/time.h> 52#include <linux/time.h>
54#include <linux/device.h> 53#include <linux/device.h>
diff --git a/drivers/isdn/capi/capi.c b/drivers/isdn/capi/capi.c
index db1260f73f10..81661b8bd3a8 100644
--- a/drivers/isdn/capi/capi.c
+++ b/drivers/isdn/capi/capi.c
@@ -18,8 +18,8 @@
18#include <linux/fcntl.h> 18#include <linux/fcntl.h>
19#include <linux/fs.h> 19#include <linux/fs.h>
20#include <linux/signal.h> 20#include <linux/signal.h>
21#include <linux/mutex.h>
21#include <linux/mm.h> 22#include <linux/mm.h>
22#include <linux/smp_lock.h>
23#include <linux/timer.h> 23#include <linux/timer.h>
24#include <linux/wait.h> 24#include <linux/wait.h>
25#ifdef CONFIG_ISDN_CAPI_MIDDLEWARE 25#ifdef CONFIG_ISDN_CAPI_MIDDLEWARE
@@ -147,7 +147,7 @@ struct capidev {
147 147
148 struct capincci *nccis; 148 struct capincci *nccis;
149 149
150 struct semaphore ncci_list_sem; 150 struct mutex ncci_list_mtx;
151}; 151};
152 152
153/* -------- global variables ---------------------------------------- */ 153/* -------- global variables ---------------------------------------- */
@@ -395,7 +395,7 @@ static struct capidev *capidev_alloc(void)
395 if (!cdev) 395 if (!cdev)
396 return NULL; 396 return NULL;
397 397
398 init_MUTEX(&cdev->ncci_list_sem); 398 mutex_init(&cdev->ncci_list_mtx);
399 skb_queue_head_init(&cdev->recvqueue); 399 skb_queue_head_init(&cdev->recvqueue);
400 init_waitqueue_head(&cdev->recvwait); 400 init_waitqueue_head(&cdev->recvwait);
401 write_lock_irqsave(&capidev_list_lock, flags); 401 write_lock_irqsave(&capidev_list_lock, flags);
@@ -414,9 +414,9 @@ static void capidev_free(struct capidev *cdev)
414 } 414 }
415 skb_queue_purge(&cdev->recvqueue); 415 skb_queue_purge(&cdev->recvqueue);
416 416
417 down(&cdev->ncci_list_sem); 417 mutex_lock(&cdev->ncci_list_mtx);
418 capincci_free(cdev, 0xffffffff); 418 capincci_free(cdev, 0xffffffff);
419 up(&cdev->ncci_list_sem); 419 mutex_unlock(&cdev->ncci_list_mtx);
420 420
421 write_lock_irqsave(&capidev_list_lock, flags); 421 write_lock_irqsave(&capidev_list_lock, flags);
422 list_del(&cdev->list); 422 list_del(&cdev->list);
@@ -603,15 +603,15 @@ static void capi_recv_message(struct capi20_appl *ap, struct sk_buff *skb)
603 if (CAPIMSG_CMD(skb->data) == CAPI_CONNECT_B3_CONF) { 603 if (CAPIMSG_CMD(skb->data) == CAPI_CONNECT_B3_CONF) {
604 u16 info = CAPIMSG_U16(skb->data, 12); // Info field 604 u16 info = CAPIMSG_U16(skb->data, 12); // Info field
605 if (info == 0) { 605 if (info == 0) {
606 down(&cdev->ncci_list_sem); 606 mutex_lock(&cdev->ncci_list_mtx);
607 capincci_alloc(cdev, CAPIMSG_NCCI(skb->data)); 607 capincci_alloc(cdev, CAPIMSG_NCCI(skb->data));
608 up(&cdev->ncci_list_sem); 608 mutex_unlock(&cdev->ncci_list_mtx);
609 } 609 }
610 } 610 }
611 if (CAPIMSG_CMD(skb->data) == CAPI_CONNECT_B3_IND) { 611 if (CAPIMSG_CMD(skb->data) == CAPI_CONNECT_B3_IND) {
612 down(&cdev->ncci_list_sem); 612 mutex_lock(&cdev->ncci_list_mtx);
613 capincci_alloc(cdev, CAPIMSG_NCCI(skb->data)); 613 capincci_alloc(cdev, CAPIMSG_NCCI(skb->data));
614 up(&cdev->ncci_list_sem); 614 mutex_unlock(&cdev->ncci_list_mtx);
615 } 615 }
616 spin_lock_irqsave(&workaround_lock, flags); 616 spin_lock_irqsave(&workaround_lock, flags);
617 if (CAPIMSG_COMMAND(skb->data) != CAPI_DATA_B3) { 617 if (CAPIMSG_COMMAND(skb->data) != CAPI_DATA_B3) {
@@ -752,9 +752,9 @@ capi_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos
752 CAPIMSG_SETAPPID(skb->data, cdev->ap.applid); 752 CAPIMSG_SETAPPID(skb->data, cdev->ap.applid);
753 753
754 if (CAPIMSG_CMD(skb->data) == CAPI_DISCONNECT_B3_RESP) { 754 if (CAPIMSG_CMD(skb->data) == CAPI_DISCONNECT_B3_RESP) {
755 down(&cdev->ncci_list_sem); 755 mutex_lock(&cdev->ncci_list_mtx);
756 capincci_free(cdev, CAPIMSG_NCCI(skb->data)); 756 capincci_free(cdev, CAPIMSG_NCCI(skb->data));
757 up(&cdev->ncci_list_sem); 757 mutex_unlock(&cdev->ncci_list_mtx);
758 } 758 }
759 759
760 cdev->errcode = capi20_put_message(&cdev->ap, skb); 760 cdev->errcode = capi20_put_message(&cdev->ap, skb);
@@ -939,9 +939,9 @@ capi_ioctl(struct inode *inode, struct file *file,
939 if (copy_from_user(&ncci, argp, sizeof(ncci))) 939 if (copy_from_user(&ncci, argp, sizeof(ncci)))
940 return -EFAULT; 940 return -EFAULT;
941 941
942 down(&cdev->ncci_list_sem); 942 mutex_lock(&cdev->ncci_list_mtx);
943 if ((nccip = capincci_find(cdev, (u32) ncci)) == 0) { 943 if ((nccip = capincci_find(cdev, (u32) ncci)) == 0) {
944 up(&cdev->ncci_list_sem); 944 mutex_unlock(&cdev->ncci_list_mtx);
945 return 0; 945 return 0;
946 } 946 }
947#ifdef CONFIG_ISDN_CAPI_MIDDLEWARE 947#ifdef CONFIG_ISDN_CAPI_MIDDLEWARE
@@ -949,7 +949,7 @@ capi_ioctl(struct inode *inode, struct file *file,
949 count += atomic_read(&mp->ttyopencount); 949 count += atomic_read(&mp->ttyopencount);
950 } 950 }
951#endif /* CONFIG_ISDN_CAPI_MIDDLEWARE */ 951#endif /* CONFIG_ISDN_CAPI_MIDDLEWARE */
952 up(&cdev->ncci_list_sem); 952 mutex_unlock(&cdev->ncci_list_mtx);
953 return count; 953 return count;
954 } 954 }
955 return 0; 955 return 0;
@@ -964,14 +964,14 @@ capi_ioctl(struct inode *inode, struct file *file,
964 if (copy_from_user(&ncci, argp, 964 if (copy_from_user(&ncci, argp,
965 sizeof(ncci))) 965 sizeof(ncci)))
966 return -EFAULT; 966 return -EFAULT;
967 down(&cdev->ncci_list_sem); 967 mutex_lock(&cdev->ncci_list_mtx);
968 nccip = capincci_find(cdev, (u32) ncci); 968 nccip = capincci_find(cdev, (u32) ncci);
969 if (!nccip || (mp = nccip->minorp) == 0) { 969 if (!nccip || (mp = nccip->minorp) == 0) {
970 up(&cdev->ncci_list_sem); 970 mutex_unlock(&cdev->ncci_list_mtx);
971 return -ESRCH; 971 return -ESRCH;
972 } 972 }
973 unit = mp->minor; 973 unit = mp->minor;
974 up(&cdev->ncci_list_sem); 974 mutex_unlock(&cdev->ncci_list_mtx);
975 return unit; 975 return unit;
976 } 976 }
977 return 0; 977 return 0;
diff --git a/drivers/isdn/capi/capiutil.c b/drivers/isdn/capi/capiutil.c
index ad1e2702c2d1..22379b94e88f 100644
--- a/drivers/isdn/capi/capiutil.c
+++ b/drivers/isdn/capi/capiutil.c
@@ -855,7 +855,7 @@ static _cdebbuf *g_debbuf;
855static u_long g_debbuf_lock; 855static u_long g_debbuf_lock;
856static _cmsg *g_cmsg; 856static _cmsg *g_cmsg;
857 857
858_cdebbuf *cdebbuf_alloc(void) 858static _cdebbuf *cdebbuf_alloc(void)
859{ 859{
860 _cdebbuf *cdb; 860 _cdebbuf *cdb;
861 861
@@ -989,11 +989,6 @@ _cdebbuf *capi_cmsg2str(_cmsg * cmsg)
989 return &g_debbuf; 989 return &g_debbuf;
990} 990}
991 991
992_cdebbuf *cdebbuf_alloc(void)
993{
994 return &g_debbuf;
995}
996
997void cdebbuf_free(_cdebbuf *cdb) 992void cdebbuf_free(_cdebbuf *cdb)
998{ 993{
999} 994}
@@ -1009,7 +1004,6 @@ void __exit cdebug_exit(void)
1009 1004
1010#endif 1005#endif
1011 1006
1012EXPORT_SYMBOL(cdebbuf_alloc);
1013EXPORT_SYMBOL(cdebbuf_free); 1007EXPORT_SYMBOL(cdebbuf_free);
1014EXPORT_SYMBOL(capi_cmsg2message); 1008EXPORT_SYMBOL(capi_cmsg2message);
1015EXPORT_SYMBOL(capi_message2cmsg); 1009EXPORT_SYMBOL(capi_message2cmsg);
diff --git a/drivers/isdn/divert/divert_procfs.c b/drivers/isdn/divert/divert_procfs.c
index 53a189003355..be77ee625bb7 100644
--- a/drivers/isdn/divert/divert_procfs.c
+++ b/drivers/isdn/divert/divert_procfs.c
@@ -11,7 +11,6 @@
11 11
12#include <linux/module.h> 12#include <linux/module.h>
13#include <linux/poll.h> 13#include <linux/poll.h>
14#include <linux/smp_lock.h>
15#ifdef CONFIG_PROC_FS 14#ifdef CONFIG_PROC_FS
16#include <linux/proc_fs.h> 15#include <linux/proc_fs.h>
17#else 16#else
diff --git a/drivers/isdn/hardware/eicon/capimain.c b/drivers/isdn/hardware/eicon/capimain.c
index 7a74ed35b1bf..98fcdfc7ca55 100644
--- a/drivers/isdn/hardware/eicon/capimain.c
+++ b/drivers/isdn/hardware/eicon/capimain.c
@@ -13,7 +13,6 @@
13#include <linux/module.h> 13#include <linux/module.h>
14#include <linux/init.h> 14#include <linux/init.h>
15#include <asm/uaccess.h> 15#include <asm/uaccess.h>
16#include <linux/smp_lock.h>
17#include <linux/skbuff.h> 16#include <linux/skbuff.h>
18 17
19#include "os_capi.h" 18#include "os_capi.h"
diff --git a/drivers/isdn/hardware/eicon/dbgioctl.h b/drivers/isdn/hardware/eicon/dbgioctl.h
deleted file mode 100644
index 0fb6f5e88b60..000000000000
--- a/drivers/isdn/hardware/eicon/dbgioctl.h
+++ /dev/null
@@ -1,198 +0,0 @@
1
2/*
3 *
4 Copyright (c) Eicon Technology Corporation, 2000.
5 *
6 This source file is supplied for the use with Eicon
7 Technology Corporation's range of DIVA Server Adapters.
8 *
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2, or (at your option)
12 any later version.
13 *
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
16 implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
17 See the GNU General Public License for more details.
18 *
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 *
23 */
24/*------------------------------------------------------------------*/
25/* file: dbgioctl.h */
26/*------------------------------------------------------------------*/
27
28#if !defined(__DBGIOCTL_H__)
29
30#define __DBGIOCTL_H__
31
32#ifdef NOT_YET_NEEDED
33/*
34 * The requested operation is passed in arg0 of DbgIoctlArgs,
35 * additional arguments (if any) in arg1, arg2 and arg3.
36 */
37
38typedef struct
39{ ULONG arg0 ;
40 ULONG arg1 ;
41 ULONG arg2 ;
42 ULONG arg3 ;
43} DbgIoctlArgs ;
44
45#define DBG_COPY_LOGS 0 /* copy debugs to user until buffer full */
46 /* arg1: size threshold */
47 /* arg2: timeout in milliseconds */
48
49#define DBG_FLUSH_LOGS 1 /* flush pending debugs to user buffer */
50 /* arg1: internal driver id */
51
52#define DBG_LIST_DRVS 2 /* return the list of registered drivers */
53
54#define DBG_GET_MASK 3 /* get current debug mask of driver */
55 /* arg1: internal driver id */
56
57#define DBG_SET_MASK 4 /* set/change debug mask of driver */
58 /* arg1: internal driver id */
59 /* arg2: new debug mask */
60
61#define DBG_GET_BUFSIZE 5 /* get current buffer size of driver */
62 /* arg1: internal driver id */
63 /* arg2: new debug mask */
64
65#define DBG_SET_BUFSIZE 6 /* set new buffer size of driver */
66 /* arg1: new buffer size */
67
68/*
69 * common internal debug message structure
70 */
71
72typedef struct
73{ unsigned short id ; /* virtual driver id */
74 unsigned short type ; /* special message type */
75 unsigned long seq ; /* sequence number of message */
76 unsigned long size ; /* size of message in bytes */
77 unsigned long next ; /* offset to next buffered message */
78 LARGE_INTEGER NTtime ; /* 100 ns since 1.1.1601 */
79 unsigned char data[4] ;/* message data */
80} OldDbgMessage ;
81
82typedef struct
83{ LARGE_INTEGER NTtime ; /* 100 ns since 1.1.1601 */
84 unsigned short size ; /* size of message in bytes */
85 unsigned short ffff ; /* always 0xffff to indicate new msg */
86 unsigned short id ; /* virtual driver id */
87 unsigned short type ; /* special message type */
88 unsigned long seq ; /* sequence number of message */
89 unsigned char data[4] ;/* message data */
90} DbgMessage ;
91
92#endif
93
94#define DRV_ID_UNKNOWN 0x0C /* for messages via prtComp() */
95
96#define MSG_PROC_FLAG 0x80
97#define MSG_PROC_NO_GET(x) (((x) & MSG_PROC_FLAG) ? (((x) >> 4) & 7) : -1)
98#define MSG_PROC_NO_SET(x) (MSG_PROC_FLAG | (((x) & 7) << 4))
99
100#define MSG_TYPE_DRV_ID 0x0001
101#define MSG_TYPE_FLAGS 0x0002
102#define MSG_TYPE_STRING 0x0003
103#define MSG_TYPE_BINARY 0x0004
104
105#define MSG_HEAD_SIZE ((unsigned long)&(((DbgMessage *)0)->data[0]))
106#define MSG_ALIGN(len) (((unsigned long)(len) + MSG_HEAD_SIZE + 3) & ~3)
107#define MSG_SIZE(pMsg) MSG_ALIGN((pMsg)->size)
108#define MSG_NEXT(pMsg) ((DbgMessage *)( ((char *)(pMsg)) + MSG_SIZE(pMsg) ))
109
110#define OLD_MSG_HEAD_SIZE ((unsigned long)&(((OldDbgMessage *)0)->data[0]))
111#define OLD_MSG_ALIGN(len) (((unsigned long)(len)+OLD_MSG_HEAD_SIZE+3) & ~3)
112
113/*
114 * manifest constants
115 */
116
117#define MSG_FRAME_MAX_SIZE 2150 /* maximum size of B1 frame */
118#define MSG_TEXT_MAX_SIZE 1024 /* maximum size of msg text */
119#define MSG_MAX_SIZE MSG_ALIGN(MSG_FRAME_MAX_SIZE)
120#define DBG_MIN_BUFFER_SIZE 0x00008000 /* minimal total buffer size 32 KB */
121#define DBG_DEF_BUFFER_SIZE 0x00020000 /* default total buffer size 128 KB */
122#define DBG_MAX_BUFFER_SIZE 0x00400000 /* maximal total buffer size 4 MB */
123
124#define DBGDRV_NAME "Diehl_DIMAINT"
125#define UNIDBG_DRIVER L"\\Device\\Diehl_DIMAINT" /* UNICODE name for kernel */
126#define DEBUG_DRIVER "\\\\.\\" DBGDRV_NAME /* traditional string for apps */
127#define DBGVXD_NAME "DIMAINT"
128#define DEBUG_VXD "\\\\.\\" DBGVXD_NAME /* traditional string for apps */
129
130/*
131 * Special IDI interface debug construction
132 */
133
134#define DBG_IDI_SIG_REQ (unsigned long)0xF479C402
135#define DBG_IDI_SIG_IND (unsigned long)0xF479C403
136#define DBG_IDI_NL_REQ (unsigned long)0xF479C404
137#define DBG_IDI_NL_IND (unsigned long)0xF479C405
138
139typedef struct
140{ unsigned long magic_type ;
141 unsigned short data_len ;
142 unsigned char layer_ID ;
143 unsigned char entity_ID ;
144 unsigned char request ;
145 unsigned char ret_code ;
146 unsigned char indication ;
147 unsigned char complete ;
148 unsigned char data[4] ;
149} DbgIdiAct, *DbgIdiAction ;
150
151/*
152 * We want to use the same IOCTL codes in Win95 and WinNT.
153 * The official constructor for IOCTL codes is the CTL_CODE macro
154 * from <winoctl.h> (<devioctl.h> in WinNT DDK environment).
155 * The problem here is that we don't know how to get <winioctl.h>
156 * working in a Win95 DDK environment!
157 */
158
159# ifdef CTL_CODE /*{*/
160
161/* Assert that we have the same idea of the CTL_CODE macro. */
162
163#define CTL_CODE( DeviceType, Function, Method, Access ) ( \
164 ((DeviceType) << 16) | ((Access) << 14) | ((Function) << 2) | (Method) \
165)
166
167# else /* !CTL_CODE */ /*}{*/
168
169/* Use the definitions stolen from <winioctl.h>. */
170
171#define CTL_CODE( DeviceType, Function, Method, Access ) ( \
172 ((DeviceType) << 16) | ((Access) << 14) | ((Function) << 2) | (Method) \
173)
174
175#define METHOD_BUFFERED 0
176#define METHOD_IN_DIRECT 1
177#define METHOD_OUT_DIRECT 2
178#define METHOD_NEITHER 3
179
180#define FILE_ANY_ACCESS 0
181#define FILE_READ_ACCESS ( 0x0001 ) // file & pipe
182#define FILE_WRITE_ACCESS ( 0x0002 ) // file & pipe
183
184# endif /* CTL_CODE */ /*}*/
185
186/*
187 * Now we can define WinNT/Win95 DeviceIoControl codes.
188 *
189 * These codes are defined in di_defs.h too, a possible mismatch will be
190 * detected when the dbgtool is compiled.
191 */
192
193#define IOCTL_DRIVER_LNK \
194 CTL_CODE(0x8001U,0x701,METHOD_OUT_DIRECT,FILE_ANY_ACCESS)
195#define IOCTL_DRIVER_DBG \
196 CTL_CODE(0x8001U,0x702,METHOD_OUT_DIRECT,FILE_ANY_ACCESS)
197
198#endif /* __DBGIOCTL_H__ */
diff --git a/drivers/isdn/hardware/eicon/divamnt.c b/drivers/isdn/hardware/eicon/divamnt.c
index 4aba5c502d8e..c90928974249 100644
--- a/drivers/isdn/hardware/eicon/divamnt.c
+++ b/drivers/isdn/hardware/eicon/divamnt.c
@@ -13,7 +13,6 @@
13#include <linux/module.h> 13#include <linux/module.h>
14#include <linux/init.h> 14#include <linux/init.h>
15#include <linux/kernel.h> 15#include <linux/kernel.h>
16#include <linux/smp_lock.h>
17#include <linux/poll.h> 16#include <linux/poll.h>
18#include <asm/uaccess.h> 17#include <asm/uaccess.h>
19 18
diff --git a/drivers/isdn/hardware/eicon/divasi.c b/drivers/isdn/hardware/eicon/divasi.c
index 556b19615bc7..78f141e77466 100644
--- a/drivers/isdn/hardware/eicon/divasi.c
+++ b/drivers/isdn/hardware/eicon/divasi.c
@@ -14,7 +14,6 @@
14#include <linux/init.h> 14#include <linux/init.h>
15#include <linux/kernel.h> 15#include <linux/kernel.h>
16#include <linux/sched.h> 16#include <linux/sched.h>
17#include <linux/smp_lock.h>
18#include <linux/poll.h> 17#include <linux/poll.h>
19#include <linux/proc_fs.h> 18#include <linux/proc_fs.h>
20#include <linux/skbuff.h> 19#include <linux/skbuff.h>
diff --git a/drivers/isdn/hardware/eicon/divasmain.c b/drivers/isdn/hardware/eicon/divasmain.c
index 5e862e244117..6d39f9360766 100644
--- a/drivers/isdn/hardware/eicon/divasmain.c
+++ b/drivers/isdn/hardware/eicon/divasmain.c
@@ -17,7 +17,6 @@
17#include <linux/ioport.h> 17#include <linux/ioport.h>
18#include <linux/workqueue.h> 18#include <linux/workqueue.h>
19#include <linux/pci.h> 19#include <linux/pci.h>
20#include <linux/smp_lock.h>
21#include <linux/interrupt.h> 20#include <linux/interrupt.h>
22#include <linux/list.h> 21#include <linux/list.h>
23#include <linux/poll.h> 22#include <linux/poll.h>
diff --git a/drivers/isdn/hardware/eicon/main_if.h b/drivers/isdn/hardware/eicon/main_if.h
deleted file mode 100644
index 0ea339afd424..000000000000
--- a/drivers/isdn/hardware/eicon/main_if.h
+++ /dev/null
@@ -1,50 +0,0 @@
1/*
2 *
3 Copyright (c) Eicon Technology Corporation, 2000.
4 *
5 This source file is supplied for the use with Eicon
6 Technology Corporation's range of DIVA Server Adapters.
7 *
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2, or (at your option)
11 any later version.
12 *
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
15 implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
16 See the GNU General Public License for more details.
17 *
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 *
22 */
23/*------------------------------------------------------------------*/
24/* file: main_if.h */
25/*------------------------------------------------------------------*/
26# ifndef MAIN_IF___H
27# define MAIN_IF___H
28
29# include "debug_if.h"
30
31void DI_lock (void) ;
32void DI_unlock (void) ;
33
34#ifdef NOT_YET_NEEDED
35void DI_nttime (LARGE_INTEGER *NTtime) ;
36void DI_ntlcltime(LARGE_INTEGER *NTtime, LARGE_INTEGER *lclNTtime) ;
37void DI_nttimefields(LARGE_INTEGER *NTtime, TIME_FIELDS *TimeFields);
38unsigned long DI_wintime(LARGE_INTEGER *NTtime) ;
39
40unsigned short DiInsertProcessorNumber (int type) ;
41void DiProcessEventLog (unsigned short id, unsigned long msgID, va_list ap);
42
43void StartIoctlTimer (void (*Handler)(void), unsigned long msec) ;
44void StopIoctlTimer (void) ;
45void UnpendIoctl (DbgRequest *pDbgReq) ;
46#endif
47
48void add_to_q(int, char* , unsigned int);
49# endif /* MAIN_IF___H */
50
diff --git a/drivers/isdn/hardware/eicon/platform.h b/drivers/isdn/hardware/eicon/platform.h
index ff09f07f440a..15d4942de53b 100644
--- a/drivers/isdn/hardware/eicon/platform.h
+++ b/drivers/isdn/hardware/eicon/platform.h
@@ -26,7 +26,6 @@
26#include <linux/vmalloc.h> 26#include <linux/vmalloc.h>
27#include <linux/proc_fs.h> 27#include <linux/proc_fs.h>
28#include <linux/interrupt.h> 28#include <linux/interrupt.h>
29#include <linux/smp_lock.h>
30#include <linux/delay.h> 29#include <linux/delay.h>
31#include <linux/list.h> 30#include <linux/list.h>
32#include <asm/types.h> 31#include <asm/types.h>
diff --git a/drivers/isdn/hisax/hfc_usb.c b/drivers/isdn/hisax/hfc_usb.c
index 9f44d3e69fb0..99e70d4103b6 100644
--- a/drivers/isdn/hisax/hfc_usb.c
+++ b/drivers/isdn/hisax/hfc_usb.c
@@ -37,7 +37,6 @@
37#include <linux/kernel_stat.h> 37#include <linux/kernel_stat.h>
38#include <linux/usb.h> 38#include <linux/usb.h>
39#include <linux/kernel.h> 39#include <linux/kernel.h>
40#include <linux/smp_lock.h>
41#include "hisax.h" 40#include "hisax.h"
42#include "hisax_if.h" 41#include "hisax_if.h"
43#include "hfc_usb.h" 42#include "hfc_usb.h"
diff --git a/drivers/isdn/hysdn/boardergo.c b/drivers/isdn/hysdn/boardergo.c
index 84dccd526ac0..6cdbad3a9926 100644
--- a/drivers/isdn/hysdn/boardergo.c
+++ b/drivers/isdn/hysdn/boardergo.c
@@ -443,7 +443,7 @@ ergo_inithardware(hysdn_card * card)
443 card->waitpofready = ergo_waitpofready; 443 card->waitpofready = ergo_waitpofready;
444 card->set_errlog_state = ergo_set_errlog_state; 444 card->set_errlog_state = ergo_set_errlog_state;
445 INIT_WORK(&card->irq_queue, ergo_irq_bh); 445 INIT_WORK(&card->irq_queue, ergo_irq_bh);
446 card->hysdn_lock = SPIN_LOCK_UNLOCKED; 446 spin_lock_init(&card->hysdn_lock);
447 447
448 return (0); 448 return (0);
449} /* ergo_inithardware */ 449} /* ergo_inithardware */
diff --git a/drivers/isdn/hysdn/hysdn_proclog.c b/drivers/isdn/hysdn/hysdn_proclog.c
index 4c7dedac0e51..27b3991fb0ec 100644
--- a/drivers/isdn/hysdn/hysdn_proclog.c
+++ b/drivers/isdn/hysdn/hysdn_proclog.c
@@ -297,8 +297,6 @@ hysdn_log_close(struct inode *ino, struct file *filep)
297 struct procdata *pd; 297 struct procdata *pd;
298 hysdn_card *card; 298 hysdn_card *card;
299 int retval = 0; 299 int retval = 0;
300 unsigned long flags;
301 spinlock_t hysdn_lock = SPIN_LOCK_UNLOCKED;
302 300
303 lock_kernel(); 301 lock_kernel();
304 if ((filep->f_mode & (FMODE_READ | FMODE_WRITE)) == FMODE_WRITE) { 302 if ((filep->f_mode & (FMODE_READ | FMODE_WRITE)) == FMODE_WRITE) {
@@ -308,7 +306,6 @@ hysdn_log_close(struct inode *ino, struct file *filep)
308 /* read access -> log/debug read, mark one further file as closed */ 306 /* read access -> log/debug read, mark one further file as closed */
309 307
310 pd = NULL; 308 pd = NULL;
311 spin_lock_irqsave(&hysdn_lock, flags);
312 inf = *((struct log_data **) filep->private_data); /* get first log entry */ 309 inf = *((struct log_data **) filep->private_data); /* get first log entry */
313 if (inf) 310 if (inf)
314 pd = (struct procdata *) inf->proc_ctrl; /* still entries there */ 311 pd = (struct procdata *) inf->proc_ctrl; /* still entries there */
@@ -331,7 +328,6 @@ hysdn_log_close(struct inode *ino, struct file *filep)
331 inf->usage_cnt--; /* decrement usage count for buffers */ 328 inf->usage_cnt--; /* decrement usage count for buffers */
332 inf = inf->next; 329 inf = inf->next;
333 } 330 }
334 spin_unlock_irqrestore(&hysdn_lock, flags);
335 331
336 if (pd) 332 if (pd)
337 if (pd->if_used <= 0) /* delete buffers if last file closed */ 333 if (pd->if_used <= 0) /* delete buffers if last file closed */
diff --git a/drivers/isdn/isdnloop/isdnloop.c b/drivers/isdn/isdnloop/isdnloop.c
index e93ad59f60bf..bb92e3cd9334 100644
--- a/drivers/isdn/isdnloop/isdnloop.c
+++ b/drivers/isdn/isdnloop/isdnloop.c
@@ -1462,7 +1462,7 @@ isdnloop_initcard(char *id)
1462 skb_queue_head_init(&card->bqueue[i]); 1462 skb_queue_head_init(&card->bqueue[i]);
1463 } 1463 }
1464 skb_queue_head_init(&card->dqueue); 1464 skb_queue_head_init(&card->dqueue);
1465 card->isdnloop_lock = SPIN_LOCK_UNLOCKED; 1465 spin_lock_init(&card->isdnloop_lock);
1466 card->next = cards; 1466 card->next = cards;
1467 cards = card; 1467 cards = card;
1468 if (!register_isdn(&card->interface)) { 1468 if (!register_isdn(&card->interface)) {
diff --git a/drivers/macintosh/therm_adt746x.c b/drivers/macintosh/therm_adt746x.c
index 178afa1fd56c..bd55e6ab99fc 100644
--- a/drivers/macintosh/therm_adt746x.c
+++ b/drivers/macintosh/therm_adt746x.c
@@ -19,7 +19,6 @@
19#include <linux/slab.h> 19#include <linux/slab.h>
20#include <linux/init.h> 20#include <linux/init.h>
21#include <linux/spinlock.h> 21#include <linux/spinlock.h>
22#include <linux/smp_lock.h>
23#include <linux/wait.h> 22#include <linux/wait.h>
24#include <linux/suspend.h> 23#include <linux/suspend.h>
25#include <linux/kthread.h> 24#include <linux/kthread.h>
diff --git a/drivers/macintosh/therm_pm72.c b/drivers/macintosh/therm_pm72.c
index 78ff18617139..dbb22403979f 100644
--- a/drivers/macintosh/therm_pm72.c
+++ b/drivers/macintosh/therm_pm72.c
@@ -117,7 +117,6 @@
117#include <linux/slab.h> 117#include <linux/slab.h>
118#include <linux/init.h> 118#include <linux/init.h>
119#include <linux/spinlock.h> 119#include <linux/spinlock.h>
120#include <linux/smp_lock.h>
121#include <linux/wait.h> 120#include <linux/wait.h>
122#include <linux/reboot.h> 121#include <linux/reboot.h>
123#include <linux/kmod.h> 122#include <linux/kmod.h>
diff --git a/drivers/macintosh/windfarm_core.c b/drivers/macintosh/windfarm_core.c
index 94c117ef20c1..192b26e97777 100644
--- a/drivers/macintosh/windfarm_core.c
+++ b/drivers/macintosh/windfarm_core.c
@@ -27,7 +27,6 @@
27#include <linux/kernel.h> 27#include <linux/kernel.h>
28#include <linux/init.h> 28#include <linux/init.h>
29#include <linux/spinlock.h> 29#include <linux/spinlock.h>
30#include <linux/smp_lock.h>
31#include <linux/kthread.h> 30#include <linux/kthread.h>
32#include <linux/jiffies.h> 31#include <linux/jiffies.h>
33#include <linux/reboot.h> 32#include <linux/reboot.h>
diff --git a/drivers/md/bitmap.c b/drivers/md/bitmap.c
index e61e0efe9ec7..5a4a74c1097c 100644
--- a/drivers/md/bitmap.c
+++ b/drivers/md/bitmap.c
@@ -1456,10 +1456,10 @@ int bitmap_create(mddev_t *mddev)
1456 bitmap->offset = mddev->bitmap_offset; 1456 bitmap->offset = mddev->bitmap_offset;
1457 if (file) { 1457 if (file) {
1458 get_file(file); 1458 get_file(file);
1459 do_sync_file_range(file, 0, LLONG_MAX, 1459 do_sync_mapping_range(file->f_mapping, 0, LLONG_MAX,
1460 SYNC_FILE_RANGE_WAIT_BEFORE | 1460 SYNC_FILE_RANGE_WAIT_BEFORE |
1461 SYNC_FILE_RANGE_WRITE | 1461 SYNC_FILE_RANGE_WRITE |
1462 SYNC_FILE_RANGE_WAIT_AFTER); 1462 SYNC_FILE_RANGE_WAIT_AFTER);
1463 } 1463 }
1464 /* read superblock from bitmap file (this sets bitmap->chunksize) */ 1464 /* read superblock from bitmap file (this sets bitmap->chunksize) */
1465 err = bitmap_read_sb(bitmap); 1465 err = bitmap_read_sb(bitmap);
diff --git a/drivers/media/dvb/bt8xx/dst_common.h b/drivers/media/dvb/bt8xx/dst_common.h
index 3bf084f2e522..87623d203a89 100644
--- a/drivers/media/dvb/bt8xx/dst_common.h
+++ b/drivers/media/dvb/bt8xx/dst_common.h
@@ -22,7 +22,6 @@
22#ifndef DST_COMMON_H 22#ifndef DST_COMMON_H
23#define DST_COMMON_H 23#define DST_COMMON_H
24 24
25#include <linux/smp_lock.h>
26#include <linux/dvb/frontend.h> 25#include <linux/dvb/frontend.h>
27#include <linux/device.h> 26#include <linux/device.h>
28#include <linux/mutex.h> 27#include <linux/mutex.h>
diff --git a/drivers/media/dvb/ttpci/av7110_av.c b/drivers/media/dvb/ttpci/av7110_av.c
index 654c9e919e04..58678c05aa53 100644
--- a/drivers/media/dvb/ttpci/av7110_av.c
+++ b/drivers/media/dvb/ttpci/av7110_av.c
@@ -32,7 +32,6 @@
32#include <linux/kernel.h> 32#include <linux/kernel.h>
33#include <linux/string.h> 33#include <linux/string.h>
34#include <linux/delay.h> 34#include <linux/delay.h>
35#include <linux/smp_lock.h>
36#include <linux/fs.h> 35#include <linux/fs.h>
37 36
38#include "av7110.h" 37#include "av7110.h"
diff --git a/drivers/media/dvb/ttpci/av7110_ca.c b/drivers/media/dvb/ttpci/av7110_ca.c
index e9b4e88e7932..e1c1294bb767 100644
--- a/drivers/media/dvb/ttpci/av7110_ca.c
+++ b/drivers/media/dvb/ttpci/av7110_ca.c
@@ -34,7 +34,6 @@
34#include <linux/fs.h> 34#include <linux/fs.h>
35#include <linux/timer.h> 35#include <linux/timer.h>
36#include <linux/poll.h> 36#include <linux/poll.h>
37#include <linux/smp_lock.h>
38 37
39#include "av7110.h" 38#include "av7110.h"
40#include "av7110_hw.h" 39#include "av7110_hw.h"
diff --git a/drivers/media/dvb/ttpci/av7110_hw.c b/drivers/media/dvb/ttpci/av7110_hw.c
index 4d7150e15d1e..70aee4eb5da4 100644
--- a/drivers/media/dvb/ttpci/av7110_hw.c
+++ b/drivers/media/dvb/ttpci/av7110_hw.c
@@ -33,7 +33,6 @@
33#include <linux/kernel.h> 33#include <linux/kernel.h>
34#include <linux/string.h> 34#include <linux/string.h>
35#include <linux/delay.h> 35#include <linux/delay.h>
36#include <linux/smp_lock.h>
37#include <linux/fs.h> 36#include <linux/fs.h>
38 37
39#include "av7110.h" 38#include "av7110.h"
diff --git a/drivers/media/dvb/ttpci/av7110_v4l.c b/drivers/media/dvb/ttpci/av7110_v4l.c
index cde5d3ae7ec7..fcd9994058d0 100644
--- a/drivers/media/dvb/ttpci/av7110_v4l.c
+++ b/drivers/media/dvb/ttpci/av7110_v4l.c
@@ -31,7 +31,6 @@
31#include <linux/fs.h> 31#include <linux/fs.h>
32#include <linux/timer.h> 32#include <linux/timer.h>
33#include <linux/poll.h> 33#include <linux/poll.h>
34#include <linux/smp_lock.h>
35 34
36#include "av7110.h" 35#include "av7110.h"
37#include "av7110_hw.h" 36#include "av7110_hw.h"
diff --git a/drivers/media/radio/dsbr100.c b/drivers/media/radio/dsbr100.c
index df8d0520d1d1..449df1bb00d3 100644
--- a/drivers/media/radio/dsbr100.c
+++ b/drivers/media/radio/dsbr100.c
@@ -79,7 +79,6 @@
79#include <linux/videodev2.h> 79#include <linux/videodev2.h>
80#include <media/v4l2-common.h> 80#include <media/v4l2-common.h>
81#include <linux/usb.h> 81#include <linux/usb.h>
82#include <linux/smp_lock.h>
83 82
84/* 83/*
85 * Version Information 84 * Version Information
diff --git a/drivers/media/video/cpia.h b/drivers/media/video/cpia.h
index 6eaa692021c5..78392fb6f94e 100644
--- a/drivers/media/video/cpia.h
+++ b/drivers/media/video/cpia.h
@@ -47,7 +47,6 @@
47#include <linux/videodev.h> 47#include <linux/videodev.h>
48#include <media/v4l2-common.h> 48#include <media/v4l2-common.h>
49#include <linux/list.h> 49#include <linux/list.h>
50#include <linux/smp_lock.h>
51#include <linux/mutex.h> 50#include <linux/mutex.h>
52 51
53struct cpia_camera_ops 52struct cpia_camera_ops
diff --git a/drivers/media/video/cpia_pp.c b/drivers/media/video/cpia_pp.c
index 19711aaf9a3e..c431df8248d6 100644
--- a/drivers/media/video/cpia_pp.c
+++ b/drivers/media/video/cpia_pp.c
@@ -34,7 +34,6 @@
34#include <linux/interrupt.h> 34#include <linux/interrupt.h>
35#include <linux/delay.h> 35#include <linux/delay.h>
36#include <linux/workqueue.h> 36#include <linux/workqueue.h>
37#include <linux/smp_lock.h>
38#include <linux/sched.h> 37#include <linux/sched.h>
39 38
40#include <linux/kmod.h> 39#include <linux/kmod.h>
diff --git a/drivers/media/video/cx88/cx88-tvaudio.c b/drivers/media/video/cx88/cx88-tvaudio.c
index e627062fde3a..259ea08e784f 100644
--- a/drivers/media/video/cx88/cx88-tvaudio.c
+++ b/drivers/media/video/cx88/cx88-tvaudio.c
@@ -49,7 +49,6 @@
49#include <linux/interrupt.h> 49#include <linux/interrupt.h>
50#include <linux/vmalloc.h> 50#include <linux/vmalloc.h>
51#include <linux/init.h> 51#include <linux/init.h>
52#include <linux/smp_lock.h>
53#include <linux/delay.h> 52#include <linux/delay.h>
54#include <linux/kthread.h> 53#include <linux/kthread.h>
55 54
diff --git a/drivers/media/video/dabusb.c b/drivers/media/video/dabusb.c
index ff4b238090ac..a5731f90be0f 100644
--- a/drivers/media/video/dabusb.c
+++ b/drivers/media/video/dabusb.c
@@ -37,7 +37,6 @@
37#include <asm/atomic.h> 37#include <asm/atomic.h>
38#include <linux/delay.h> 38#include <linux/delay.h>
39#include <linux/usb.h> 39#include <linux/usb.h>
40#include <linux/smp_lock.h>
41#include <linux/mutex.h> 40#include <linux/mutex.h>
42 41
43#include "dabusb.h" 42#include "dabusb.h"
diff --git a/drivers/media/video/ov511.h b/drivers/media/video/ov511.h
index 68b082bcee1d..18c64222dd11 100644
--- a/drivers/media/video/ov511.h
+++ b/drivers/media/video/ov511.h
@@ -4,7 +4,6 @@
4#include <asm/uaccess.h> 4#include <asm/uaccess.h>
5#include <linux/videodev.h> 5#include <linux/videodev.h>
6#include <media/v4l2-common.h> 6#include <media/v4l2-common.h>
7#include <linux/smp_lock.h>
8#include <linux/usb.h> 7#include <linux/usb.h>
9#include <linux/mutex.h> 8#include <linux/mutex.h>
10 9
diff --git a/drivers/media/video/pvrusb2/pvrusb2-main.c b/drivers/media/video/pvrusb2/pvrusb2-main.c
index e976c484c058..9ea41c6699bb 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-main.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-main.c
@@ -25,7 +25,6 @@
25#include <linux/slab.h> 25#include <linux/slab.h>
26#include <linux/module.h> 26#include <linux/module.h>
27#include <linux/moduleparam.h> 27#include <linux/moduleparam.h>
28#include <linux/smp_lock.h>
29#include <linux/usb.h> 28#include <linux/usb.h>
30#include <linux/videodev2.h> 29#include <linux/videodev2.h>
31 30
diff --git a/drivers/media/video/saa7134/saa7134-tvaudio.c b/drivers/media/video/saa7134/saa7134-tvaudio.c
index dd759d6d8d25..7b56041186dc 100644
--- a/drivers/media/video/saa7134/saa7134-tvaudio.c
+++ b/drivers/media/video/saa7134/saa7134-tvaudio.c
@@ -27,7 +27,6 @@
27#include <linux/kernel.h> 27#include <linux/kernel.h>
28#include <linux/slab.h> 28#include <linux/slab.h>
29#include <linux/delay.h> 29#include <linux/delay.h>
30#include <linux/smp_lock.h>
31#include <asm/div64.h> 30#include <asm/div64.h>
32 31
33#include "saa7134-reg.h" 32#include "saa7134-reg.h"
diff --git a/drivers/media/video/se401.h b/drivers/media/video/se401.h
index c0891b3e0018..835ef872e803 100644
--- a/drivers/media/video/se401.h
+++ b/drivers/media/video/se401.h
@@ -5,7 +5,6 @@
5#include <asm/uaccess.h> 5#include <asm/uaccess.h>
6#include <linux/videodev.h> 6#include <linux/videodev.h>
7#include <media/v4l2-common.h> 7#include <media/v4l2-common.h>
8#include <linux/smp_lock.h>
9#include <linux/mutex.h> 8#include <linux/mutex.h>
10 9
11#define se401_DEBUG /* Turn on debug messages */ 10#define se401_DEBUG /* Turn on debug messages */
diff --git a/drivers/media/video/tvaudio.c b/drivers/media/video/tvaudio.c
index a2da5d2affff..c9bf9dbc2ea3 100644
--- a/drivers/media/video/tvaudio.c
+++ b/drivers/media/video/tvaudio.c
@@ -26,7 +26,6 @@
26#include <linux/videodev.h> 26#include <linux/videodev.h>
27#include <linux/i2c.h> 27#include <linux/i2c.h>
28#include <linux/init.h> 28#include <linux/init.h>
29#include <linux/smp_lock.h>
30#include <linux/kthread.h> 29#include <linux/kthread.h>
31#include <linux/freezer.h> 30#include <linux/freezer.h>
32 31
diff --git a/drivers/media/video/usbvideo/usbvideo.c b/drivers/media/video/usbvideo/usbvideo.c
index 687f026753b2..37ce36b9e587 100644
--- a/drivers/media/video/usbvideo/usbvideo.c
+++ b/drivers/media/video/usbvideo/usbvideo.c
@@ -20,7 +20,6 @@
20#include <linux/slab.h> 20#include <linux/slab.h>
21#include <linux/module.h> 21#include <linux/module.h>
22#include <linux/mm.h> 22#include <linux/mm.h>
23#include <linux/smp_lock.h>
24#include <linux/vmalloc.h> 23#include <linux/vmalloc.h>
25#include <linux/init.h> 24#include <linux/init.h>
26#include <linux/spinlock.h> 25#include <linux/spinlock.h>
diff --git a/drivers/media/video/usbvision/usbvision-core.c b/drivers/media/video/usbvision/usbvision-core.c
index bcb551adb7e6..9118a6227ea6 100644
--- a/drivers/media/video/usbvision/usbvision-core.c
+++ b/drivers/media/video/usbvision/usbvision-core.c
@@ -30,7 +30,6 @@
30#include <linux/mm.h> 30#include <linux/mm.h>
31#include <linux/utsname.h> 31#include <linux/utsname.h>
32#include <linux/highmem.h> 32#include <linux/highmem.h>
33#include <linux/smp_lock.h>
34#include <linux/videodev.h> 33#include <linux/videodev.h>
35#include <linux/vmalloc.h> 34#include <linux/vmalloc.h>
36#include <linux/module.h> 35#include <linux/module.h>
diff --git a/drivers/media/video/usbvision/usbvision-video.c b/drivers/media/video/usbvision/usbvision-video.c
index 216704170a4c..aa3258bbb4af 100644
--- a/drivers/media/video/usbvision/usbvision-video.c
+++ b/drivers/media/video/usbvision/usbvision-video.c
@@ -52,7 +52,6 @@
52#include <linux/mm.h> 52#include <linux/mm.h>
53#include <linux/utsname.h> 53#include <linux/utsname.h>
54#include <linux/highmem.h> 54#include <linux/highmem.h>
55#include <linux/smp_lock.h>
56#include <linux/videodev.h> 55#include <linux/videodev.h>
57#include <linux/vmalloc.h> 56#include <linux/vmalloc.h>
58#include <linux/module.h> 57#include <linux/module.h>
diff --git a/drivers/media/video/v4l1-compat.c b/drivers/media/video/v4l1-compat.c
index d2c1ae0dbfba..a861e150865e 100644
--- a/drivers/media/video/v4l1-compat.c
+++ b/drivers/media/video/v4l1-compat.c
@@ -23,7 +23,6 @@
23#include <linux/types.h> 23#include <linux/types.h>
24#include <linux/kernel.h> 24#include <linux/kernel.h>
25#include <linux/sched.h> 25#include <linux/sched.h>
26#include <linux/smp_lock.h>
27#include <linux/mm.h> 26#include <linux/mm.h>
28#include <linux/fs.h> 27#include <linux/fs.h>
29#include <linux/file.h> 28#include <linux/file.h>
diff --git a/drivers/media/video/v4l2-common.c b/drivers/media/video/v4l2-common.c
index 49f1df74aa21..13ee550d3215 100644
--- a/drivers/media/video/v4l2-common.c
+++ b/drivers/media/video/v4l2-common.c
@@ -47,7 +47,6 @@
47#include <linux/module.h> 47#include <linux/module.h>
48#include <linux/types.h> 48#include <linux/types.h>
49#include <linux/kernel.h> 49#include <linux/kernel.h>
50#include <linux/smp_lock.h>
51#include <linux/mm.h> 50#include <linux/mm.h>
52#include <linux/string.h> 51#include <linux/string.h>
53#include <linux/errno.h> 52#include <linux/errno.h>
diff --git a/drivers/media/video/videodev.c b/drivers/media/video/videodev.c
index 80ac5f86d9e5..5263b50463e1 100644
--- a/drivers/media/video/videodev.c
+++ b/drivers/media/video/videodev.c
@@ -30,7 +30,6 @@
30#include <linux/module.h> 30#include <linux/module.h>
31#include <linux/types.h> 31#include <linux/types.h>
32#include <linux/kernel.h> 32#include <linux/kernel.h>
33#include <linux/smp_lock.h>
34#include <linux/mm.h> 33#include <linux/mm.h>
35#include <linux/string.h> 34#include <linux/string.h>
36#include <linux/errno.h> 35#include <linux/errno.h>
diff --git a/drivers/media/video/zoran_driver.c b/drivers/media/video/zoran_driver.c
index 074323733352..cf0ed6cbb0e3 100644
--- a/drivers/media/video/zoran_driver.c
+++ b/drivers/media/video/zoran_driver.c
@@ -2034,7 +2034,7 @@ zoran_do_ioctl (struct inode *inode,
2034 * but moving the free code outside the munmap() handler fixes 2034 * but moving the free code outside the munmap() handler fixes
2035 * all this... If someone knows why, please explain me (Ronald) 2035 * all this... If someone knows why, please explain me (Ronald)
2036 */ 2036 */
2037 if (!!mutex_trylock(&zr->resource_lock)) { 2037 if (mutex_trylock(&zr->resource_lock)) {
2038 /* we obtained it! Let's try to free some things */ 2038 /* we obtained it! Let's try to free some things */
2039 if (fh->jpg_buffers.ready_to_be_freed) 2039 if (fh->jpg_buffers.ready_to_be_freed)
2040 jpg_fbuffer_free(file); 2040 jpg_fbuffer_free(file);
diff --git a/drivers/message/i2o/i2o_lan.h b/drivers/message/i2o/i2o_lan.h
deleted file mode 100644
index 6502b817df58..000000000000
--- a/drivers/message/i2o/i2o_lan.h
+++ /dev/null
@@ -1,159 +0,0 @@
1/*
2 * i2o_lan.h I2O LAN Class definitions
3 *
4 * I2O LAN CLASS OSM May 26th 2000
5 *
6 * (C) Copyright 1999, 2000 University of Helsinki,
7 * Department of Computer Science
8 *
9 * This code is still under development / test.
10 *
11 * Author: Auvo Häkkinen <Auvo.Hakkinen@cs.Helsinki.FI>
12 * Juha Sievänen <Juha.Sievanen@cs.Helsinki.FI>
13 * Taneli Vähäkangas <Taneli.Vahakangas@cs.Helsinki.FI>
14 */
15
16#ifndef _I2O_LAN_H
17#define _I2O_LAN_H
18
19/* Default values for tunable parameters first */
20
21#define I2O_LAN_MAX_BUCKETS_OUT 96
22#define I2O_LAN_BUCKET_THRESH 18 /* 9 buckets in one message */
23#define I2O_LAN_RX_COPYBREAK 200
24#define I2O_LAN_TX_TIMEOUT (1*HZ)
25#define I2O_LAN_TX_BATCH_MODE 2 /* 2=automatic, 1=on, 0=off */
26#define I2O_LAN_EVENT_MASK 0 /* 0=None, 0xFFC00002=All */
27
28/* LAN types */
29#define I2O_LAN_ETHERNET 0x0030
30#define I2O_LAN_100VG 0x0040
31#define I2O_LAN_TR 0x0050
32#define I2O_LAN_FDDI 0x0060
33#define I2O_LAN_FIBRE_CHANNEL 0x0070
34#define I2O_LAN_UNKNOWN 0x00000000
35
36/* Connector types */
37
38/* Ethernet */
39#define I2O_LAN_AUI (I2O_LAN_ETHERNET << 4) + 0x00000001
40#define I2O_LAN_10BASE5 (I2O_LAN_ETHERNET << 4) + 0x00000002
41#define I2O_LAN_FIORL (I2O_LAN_ETHERNET << 4) + 0x00000003
42#define I2O_LAN_10BASE2 (I2O_LAN_ETHERNET << 4) + 0x00000004
43#define I2O_LAN_10BROAD36 (I2O_LAN_ETHERNET << 4) + 0x00000005
44#define I2O_LAN_10BASE_T (I2O_LAN_ETHERNET << 4) + 0x00000006
45#define I2O_LAN_10BASE_FP (I2O_LAN_ETHERNET << 4) + 0x00000007
46#define I2O_LAN_10BASE_FB (I2O_LAN_ETHERNET << 4) + 0x00000008
47#define I2O_LAN_10BASE_FL (I2O_LAN_ETHERNET << 4) + 0x00000009
48#define I2O_LAN_100BASE_TX (I2O_LAN_ETHERNET << 4) + 0x0000000A
49#define I2O_LAN_100BASE_FX (I2O_LAN_ETHERNET << 4) + 0x0000000B
50#define I2O_LAN_100BASE_T4 (I2O_LAN_ETHERNET << 4) + 0x0000000C
51#define I2O_LAN_1000BASE_SX (I2O_LAN_ETHERNET << 4) + 0x0000000D
52#define I2O_LAN_1000BASE_LX (I2O_LAN_ETHERNET << 4) + 0x0000000E
53#define I2O_LAN_1000BASE_CX (I2O_LAN_ETHERNET << 4) + 0x0000000F
54#define I2O_LAN_1000BASE_T (I2O_LAN_ETHERNET << 4) + 0x00000010
55
56/* AnyLAN */
57#define I2O_LAN_100VG_ETHERNET (I2O_LAN_100VG << 4) + 0x00000001
58#define I2O_LAN_100VG_TR (I2O_LAN_100VG << 4) + 0x00000002
59
60/* Token Ring */
61#define I2O_LAN_4MBIT (I2O_LAN_TR << 4) + 0x00000001
62#define I2O_LAN_16MBIT (I2O_LAN_TR << 4) + 0x00000002
63
64/* FDDI */
65#define I2O_LAN_125MBAUD (I2O_LAN_FDDI << 4) + 0x00000001
66
67/* Fibre Channel */
68#define I2O_LAN_POINT_POINT (I2O_LAN_FIBRE_CHANNEL << 4) + 0x00000001
69#define I2O_LAN_ARB_LOOP (I2O_LAN_FIBRE_CHANNEL << 4) + 0x00000002
70#define I2O_LAN_PUBLIC_LOOP (I2O_LAN_FIBRE_CHANNEL << 4) + 0x00000003
71#define I2O_LAN_FABRIC (I2O_LAN_FIBRE_CHANNEL << 4) + 0x00000004
72
73#define I2O_LAN_EMULATION 0x00000F00
74#define I2O_LAN_OTHER 0x00000F01
75#define I2O_LAN_DEFAULT 0xFFFFFFFF
76
77/* LAN class functions */
78
79#define LAN_PACKET_SEND 0x3B
80#define LAN_SDU_SEND 0x3D
81#define LAN_RECEIVE_POST 0x3E
82#define LAN_RESET 0x35
83#define LAN_SUSPEND 0x37
84
85/* LAN DetailedStatusCode defines */
86#define I2O_LAN_DSC_SUCCESS 0x00
87#define I2O_LAN_DSC_DEVICE_FAILURE 0x01
88#define I2O_LAN_DSC_DESTINATION_NOT_FOUND 0x02
89#define I2O_LAN_DSC_TRANSMIT_ERROR 0x03
90#define I2O_LAN_DSC_TRANSMIT_ABORTED 0x04
91#define I2O_LAN_DSC_RECEIVE_ERROR 0x05
92#define I2O_LAN_DSC_RECEIVE_ABORTED 0x06
93#define I2O_LAN_DSC_DMA_ERROR 0x07
94#define I2O_LAN_DSC_BAD_PACKET_DETECTED 0x08
95#define I2O_LAN_DSC_OUT_OF_MEMORY 0x09
96#define I2O_LAN_DSC_BUCKET_OVERRUN 0x0A
97#define I2O_LAN_DSC_IOP_INTERNAL_ERROR 0x0B
98#define I2O_LAN_DSC_CANCELED 0x0C
99#define I2O_LAN_DSC_INVALID_TRANSACTION_CONTEXT 0x0D
100#define I2O_LAN_DSC_DEST_ADDRESS_DETECTED 0x0E
101#define I2O_LAN_DSC_DEST_ADDRESS_OMITTED 0x0F
102#define I2O_LAN_DSC_PARTIAL_PACKET_RETURNED 0x10
103#define I2O_LAN_DSC_SUSPENDED 0x11
104
105struct i2o_packet_info {
106 u32 offset:24;
107 u32 flags:8;
108 u32 len:24;
109 u32 status:8;
110};
111
112struct i2o_bucket_descriptor {
113 u32 context; /* FIXME: 64bit support */
114 struct i2o_packet_info packet_info[1];
115};
116
117/* Event Indicator Mask Flags for LAN OSM */
118
119#define I2O_LAN_EVT_LINK_DOWN 0x01
120#define I2O_LAN_EVT_LINK_UP 0x02
121#define I2O_LAN_EVT_MEDIA_CHANGE 0x04
122
123#include <linux/netdevice.h>
124#include <linux/fddidevice.h>
125
126struct i2o_lan_local {
127 u8 unit;
128 struct i2o_device *i2o_dev;
129
130 struct fddi_statistics stats; /* see also struct net_device_stats */
131 unsigned short (*type_trans) (struct sk_buff *, struct net_device *);
132 atomic_t buckets_out; /* nbr of unused buckets on DDM */
133 atomic_t tx_out; /* outstanding TXes */
134 u8 tx_count; /* packets in one TX message frame */
135 u16 tx_max_out; /* DDM's Tx queue len */
136 u8 sgl_max; /* max SGLs in one message frame */
137 u32 m; /* IOP address of the batch msg frame */
138
139 struct work_struct i2o_batch_send_task;
140 int send_active;
141 struct sk_buff **i2o_fbl; /* Free bucket list (to reuse skbs) */
142 int i2o_fbl_tail;
143 spinlock_t fbl_lock;
144
145 spinlock_t tx_lock;
146
147 u32 max_size_mc_table; /* max number of multicast addresses */
148
149 /* LAN OSM configurable parameters are here: */
150
151 u16 max_buckets_out; /* max nbr of buckets to send to DDM */
152 u16 bucket_thresh; /* send more when this many used */
153 u16 rx_copybreak;
154
155 u8 tx_batch_mode; /* Set when using batch mode sends */
156 u32 i2o_event_mask; /* To turn on interesting event flags */
157};
158
159#endif /* _I2O_LAN_H */
diff --git a/drivers/mfd/ucb1x00-ts.c b/drivers/mfd/ucb1x00-ts.c
index ce1a48108210..cb8c264eaff0 100644
--- a/drivers/mfd/ucb1x00-ts.c
+++ b/drivers/mfd/ucb1x00-ts.c
@@ -21,7 +21,6 @@
21#include <linux/moduleparam.h> 21#include <linux/moduleparam.h>
22#include <linux/init.h> 22#include <linux/init.h>
23#include <linux/smp.h> 23#include <linux/smp.h>
24#include <linux/smp_lock.h>
25#include <linux/sched.h> 24#include <linux/sched.h>
26#include <linux/completion.h> 25#include <linux/completion.h>
27#include <linux/delay.h> 26#include <linux/delay.h>
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index a3c525b2616a..877e7909a0e5 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -25,6 +25,15 @@ config IBM_ASM
25 information on the specific driver level and support statement 25 information on the specific driver level and support statement
26 for your IBM server. 26 for your IBM server.
27 27
28config PHANTOM
29 tristate "Sensable PHANToM"
30 depends on PCI
31 help
32 Say Y here if you want to build a driver for Sensable PHANToM device.
33
34 If you choose to build module, its name will be phantom. If unsure,
35 say N here.
36
28 37
29 If unsure, say N. 38 If unsure, say N.
30 39
@@ -178,4 +187,13 @@ config THINKPAD_ACPI_BAY
178 187
179 If you are not sure, say Y here. 188 If you are not sure, say Y here.
180 189
190config BLINK
191 tristate "Keyboard blink driver"
192 help
193 Driver that when loaded will blink the keyboard LEDs continuously.
194 This is useful for debugging and for kernels that cannot necessarily
195 output something to the screen like kexec kernels to give the user
196 a visual indication that the kernel is doing something.
197
198
181endmenu 199endmenu
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index e32516459138..5b6d46de005c 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -7,9 +7,11 @@ obj-$(CONFIG_IBM_ASM) += ibmasm/
7obj-$(CONFIG_HDPU_FEATURES) += hdpuftrs/ 7obj-$(CONFIG_HDPU_FEATURES) += hdpuftrs/
8obj-$(CONFIG_MSI_LAPTOP) += msi-laptop.o 8obj-$(CONFIG_MSI_LAPTOP) += msi-laptop.o
9obj-$(CONFIG_ASUS_LAPTOP) += asus-laptop.o 9obj-$(CONFIG_ASUS_LAPTOP) += asus-laptop.o
10obj-$(CONFIG_BLINK) += blink.o
10obj-$(CONFIG_LKDTM) += lkdtm.o 11obj-$(CONFIG_LKDTM) += lkdtm.o
11obj-$(CONFIG_TIFM_CORE) += tifm_core.o 12obj-$(CONFIG_TIFM_CORE) += tifm_core.o
12obj-$(CONFIG_TIFM_7XX1) += tifm_7xx1.o 13obj-$(CONFIG_TIFM_7XX1) += tifm_7xx1.o
14obj-$(CONFIG_PHANTOM) += phantom.o
13obj-$(CONFIG_SGI_IOC4) += ioc4.o 15obj-$(CONFIG_SGI_IOC4) += ioc4.o
14obj-$(CONFIG_SONY_LAPTOP) += sony-laptop.o 16obj-$(CONFIG_SONY_LAPTOP) += sony-laptop.o
15obj-$(CONFIG_THINKPAD_ACPI) += thinkpad_acpi.o 17obj-$(CONFIG_THINKPAD_ACPI) += thinkpad_acpi.o
diff --git a/drivers/misc/blink.c b/drivers/misc/blink.c
new file mode 100644
index 000000000000..634431ce1184
--- /dev/null
+++ b/drivers/misc/blink.c
@@ -0,0 +1,27 @@
1#include <linux/kernel.h>
2#include <linux/module.h>
3#include <linux/timer.h>
4#include <linux/jiffies.h>
5
6static void do_blink(unsigned long data);
7
8static DEFINE_TIMER(blink_timer, do_blink, 0 ,0);
9
10static void do_blink(unsigned long data)
11{
12 static long count;
13 if (panic_blink)
14 panic_blink(count++);
15 blink_timer.expires = jiffies + msecs_to_jiffies(1);
16 add_timer(&blink_timer);
17}
18
19static int blink_init(void)
20{
21 printk(KERN_INFO "Enabling keyboard blinking\n");
22 do_blink(0);
23 return 0;
24}
25
26module_init(blink_init);
27
diff --git a/drivers/misc/phantom.c b/drivers/misc/phantom.c
new file mode 100644
index 000000000000..35b139b0e5f2
--- /dev/null
+++ b/drivers/misc/phantom.c
@@ -0,0 +1,463 @@
1/*
2 * Copyright (C) 2005-2007 Jiri Slaby <jirislaby@gmail.com>
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 of the License, or
7 * (at your option) any later version.
8 *
9 * You need an userspace library to cooperate with this driver. It (and other
10 * info) may be obtained here:
11 * http://www.fi.muni.cz/~xslaby/phantom.html
12 */
13
14#include <linux/kernel.h>
15#include <linux/module.h>
16#include <linux/device.h>
17#include <linux/pci.h>
18#include <linux/fs.h>
19#include <linux/poll.h>
20#include <linux/interrupt.h>
21#include <linux/cdev.h>
22#include <linux/phantom.h>
23
24#include <asm/atomic.h>
25#include <asm/io.h>
26
27#define PHANTOM_VERSION "n0.9.5"
28
29#define PHANTOM_MAX_MINORS 8
30
31#define PHN_IRQCTL 0x4c /* irq control in caddr space */
32
33#define PHB_RUNNING 1
34
35static struct class *phantom_class;
36static int phantom_major;
37
38struct phantom_device {
39 unsigned int opened;
40 void __iomem *caddr;
41 u32 __iomem *iaddr;
42 u32 __iomem *oaddr;
43 unsigned long status;
44 atomic_t counter;
45
46 wait_queue_head_t wait;
47 struct cdev cdev;
48
49 struct mutex open_lock;
50};
51
52static unsigned char phantom_devices[PHANTOM_MAX_MINORS];
53
54static int phantom_status(struct phantom_device *dev, unsigned long newstat)
55{
56 pr_debug("phantom_status %lx %lx\n", dev->status, newstat);
57
58 if (!(dev->status & PHB_RUNNING) && (newstat & PHB_RUNNING)) {
59 atomic_set(&dev->counter, 0);
60 iowrite32(PHN_CTL_IRQ, dev->iaddr + PHN_CONTROL);
61 iowrite32(0x43, dev->caddr + PHN_IRQCTL);
62 } else if ((dev->status & PHB_RUNNING) && !(newstat & PHB_RUNNING))
63 iowrite32(0, dev->caddr + PHN_IRQCTL);
64
65 dev->status = newstat;
66
67 return 0;
68}
69
70/*
71 * File ops
72 */
73
74static int phantom_ioctl(struct inode *inode, struct file *file, u_int cmd,
75 u_long arg)
76{
77 struct phantom_device *dev = file->private_data;
78 struct phm_regs rs;
79 struct phm_reg r;
80 void __user *argp = (void __user *)arg;
81 unsigned int i;
82
83 if (_IOC_TYPE(cmd) != PH_IOC_MAGIC ||
84 _IOC_NR(cmd) > PH_IOC_MAXNR)
85 return -ENOTTY;
86
87 switch (cmd) {
88 case PHN_SET_REG:
89 if (copy_from_user(&r, argp, sizeof(r)))
90 return -EFAULT;
91
92 if (r.reg > 7)
93 return -EINVAL;
94
95 if (r.reg == PHN_CONTROL && (r.value & PHN_CTL_IRQ) &&
96 phantom_status(dev, dev->status | PHB_RUNNING))
97 return -ENODEV;
98
99 pr_debug("phantom: writing %x to %u\n", r.value, r.reg);
100 iowrite32(r.value, dev->iaddr + r.reg);
101
102 if (r.reg == PHN_CONTROL && !(r.value & PHN_CTL_IRQ))
103 phantom_status(dev, dev->status & ~PHB_RUNNING);
104 break;
105 case PHN_SET_REGS:
106 if (copy_from_user(&rs, argp, sizeof(rs)))
107 return -EFAULT;
108
109 pr_debug("phantom: SRS %u regs %x\n", rs.count, rs.mask);
110 for (i = 0; i < min(rs.count, 8U); i++)
111 if ((1 << i) & rs.mask)
112 iowrite32(rs.values[i], dev->oaddr + i);
113 break;
114 case PHN_GET_REG:
115 if (copy_from_user(&r, argp, sizeof(r)))
116 return -EFAULT;
117
118 if (r.reg > 7)
119 return -EINVAL;
120
121 r.value = ioread32(dev->iaddr + r.reg);
122
123 if (copy_to_user(argp, &r, sizeof(r)))
124 return -EFAULT;
125 break;
126 case PHN_GET_REGS:
127 if (copy_from_user(&rs, argp, sizeof(rs)))
128 return -EFAULT;
129
130 pr_debug("phantom: GRS %u regs %x\n", rs.count, rs.mask);
131 for (i = 0; i < min(rs.count, 8U); i++)
132 if ((1 << i) & rs.mask)
133 rs.values[i] = ioread32(dev->iaddr + i);
134
135 if (copy_to_user(argp, &rs, sizeof(rs)))
136 return -EFAULT;
137 break;
138 default:
139 return -ENOTTY;
140 }
141
142 return 0;
143}
144
145static int phantom_open(struct inode *inode, struct file *file)
146{
147 struct phantom_device *dev = container_of(inode->i_cdev,
148 struct phantom_device, cdev);
149
150 nonseekable_open(inode, file);
151
152 if (mutex_lock_interruptible(&dev->open_lock))
153 return -ERESTARTSYS;
154
155 if (dev->opened) {
156 mutex_unlock(&dev->open_lock);
157 return -EINVAL;
158 }
159
160 file->private_data = dev;
161
162 dev->opened++;
163 mutex_unlock(&dev->open_lock);
164
165 return 0;
166}
167
168static int phantom_release(struct inode *inode, struct file *file)
169{
170 struct phantom_device *dev = file->private_data;
171
172 mutex_lock(&dev->open_lock);
173
174 dev->opened = 0;
175 phantom_status(dev, dev->status & ~PHB_RUNNING);
176
177 mutex_unlock(&dev->open_lock);
178
179 return 0;
180}
181
182static unsigned int phantom_poll(struct file *file, poll_table *wait)
183{
184 struct phantom_device *dev = file->private_data;
185 unsigned int mask = 0;
186
187 pr_debug("phantom_poll: %d\n", atomic_read(&dev->counter));
188 poll_wait(file, &dev->wait, wait);
189 if (atomic_read(&dev->counter)) {
190 mask = POLLIN | POLLRDNORM;
191 atomic_dec(&dev->counter);
192 } else if ((dev->status & PHB_RUNNING) == 0)
193 mask = POLLIN | POLLRDNORM | POLLERR;
194 pr_debug("phantom_poll end: %x/%d\n", mask, atomic_read(&dev->counter));
195
196 return mask;
197}
198
199static struct file_operations phantom_file_ops = {
200 .open = phantom_open,
201 .release = phantom_release,
202 .ioctl = phantom_ioctl,
203 .poll = phantom_poll,
204};
205
206static irqreturn_t phantom_isr(int irq, void *data)
207{
208 struct phantom_device *dev = data;
209
210 if (!(ioread32(dev->iaddr + PHN_CONTROL) & PHN_CTL_IRQ))
211 return IRQ_NONE;
212
213 iowrite32(0, dev->iaddr);
214 iowrite32(0xc0, dev->iaddr);
215
216 atomic_inc(&dev->counter);
217 wake_up_interruptible(&dev->wait);
218
219 return IRQ_HANDLED;
220}
221
222/*
223 * Init and deinit driver
224 */
225
226static unsigned int __devinit phantom_get_free(void)
227{
228 unsigned int i;
229
230 for (i = 0; i < PHANTOM_MAX_MINORS; i++)
231 if (phantom_devices[i] == 0)
232 break;
233
234 return i;
235}
236
237static int __devinit phantom_probe(struct pci_dev *pdev,
238 const struct pci_device_id *pci_id)
239{
240 struct phantom_device *pht;
241 unsigned int minor;
242 int retval;
243
244 retval = pci_enable_device(pdev);
245 if (retval)
246 goto err;
247
248 minor = phantom_get_free();
249 if (minor == PHANTOM_MAX_MINORS) {
250 dev_err(&pdev->dev, "too many devices found!\n");
251 retval = -EIO;
252 goto err_dis;
253 }
254
255 phantom_devices[minor] = 1;
256
257 retval = pci_request_regions(pdev, "phantom");
258 if (retval)
259 goto err_null;
260
261 retval = -ENOMEM;
262 pht = kzalloc(sizeof(*pht), GFP_KERNEL);
263 if (pht == NULL) {
264 dev_err(&pdev->dev, "unable to allocate device\n");
265 goto err_reg;
266 }
267
268 pht->caddr = pci_iomap(pdev, 0, 0);
269 if (pht->caddr == NULL) {
270 dev_err(&pdev->dev, "can't remap conf space\n");
271 goto err_fr;
272 }
273 pht->iaddr = pci_iomap(pdev, 2, 0);
274 if (pht->iaddr == NULL) {
275 dev_err(&pdev->dev, "can't remap input space\n");
276 goto err_unmc;
277 }
278 pht->oaddr = pci_iomap(pdev, 3, 0);
279 if (pht->oaddr == NULL) {
280 dev_err(&pdev->dev, "can't remap output space\n");
281 goto err_unmi;
282 }
283
284 mutex_init(&pht->open_lock);
285 init_waitqueue_head(&pht->wait);
286 cdev_init(&pht->cdev, &phantom_file_ops);
287 pht->cdev.owner = THIS_MODULE;
288
289 iowrite32(0, pht->caddr + PHN_IRQCTL);
290 retval = request_irq(pdev->irq, phantom_isr,
291 IRQF_SHARED | IRQF_DISABLED, "phantom", pht);
292 if (retval) {
293 dev_err(&pdev->dev, "can't establish ISR\n");
294 goto err_unmo;
295 }
296
297 retval = cdev_add(&pht->cdev, MKDEV(phantom_major, minor), 1);
298 if (retval) {
299 dev_err(&pdev->dev, "chardev registration failed\n");
300 goto err_irq;
301 }
302
303 if (IS_ERR(device_create(phantom_class, &pdev->dev, MKDEV(phantom_major,
304 minor), "phantom%u", minor)))
305 dev_err(&pdev->dev, "can't create device\n");
306
307 pci_set_drvdata(pdev, pht);
308
309 return 0;
310err_irq:
311 free_irq(pdev->irq, pht);
312err_unmo:
313 pci_iounmap(pdev, pht->oaddr);
314err_unmi:
315 pci_iounmap(pdev, pht->iaddr);
316err_unmc:
317 pci_iounmap(pdev, pht->caddr);
318err_fr:
319 kfree(pht);
320err_reg:
321 pci_release_regions(pdev);
322err_null:
323 phantom_devices[minor] = 0;
324err_dis:
325 pci_disable_device(pdev);
326err:
327 return retval;
328}
329
330static void __devexit phantom_remove(struct pci_dev *pdev)
331{
332 struct phantom_device *pht = pci_get_drvdata(pdev);
333 unsigned int minor = MINOR(pht->cdev.dev);
334
335 device_destroy(phantom_class, MKDEV(phantom_major, minor));
336
337 cdev_del(&pht->cdev);
338
339 iowrite32(0, pht->caddr + PHN_IRQCTL);
340 free_irq(pdev->irq, pht);
341
342 pci_iounmap(pdev, pht->oaddr);
343 pci_iounmap(pdev, pht->iaddr);
344 pci_iounmap(pdev, pht->caddr);
345
346 kfree(pht);
347
348 pci_release_regions(pdev);
349
350 phantom_devices[minor] = 0;
351
352 pci_disable_device(pdev);
353}
354
355#ifdef CONFIG_PM
356static int phantom_suspend(struct pci_dev *pdev, pm_message_t state)
357{
358 struct phantom_device *dev = pci_get_drvdata(pdev);
359
360 iowrite32(0, dev->caddr + PHN_IRQCTL);
361
362 return 0;
363}
364
365static int phantom_resume(struct pci_dev *pdev)
366{
367 struct phantom_device *dev = pci_get_drvdata(pdev);
368
369 iowrite32(0, dev->caddr + PHN_IRQCTL);
370
371 return 0;
372}
373#else
374#define phantom_suspend NULL
375#define phantom_resume NULL
376#endif
377
378static struct pci_device_id phantom_pci_tbl[] __devinitdata = {
379 { PCI_DEVICE(PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050),
380 .class = PCI_CLASS_BRIDGE_OTHER << 8, .class_mask = 0xffff00 },
381 { 0, }
382};
383MODULE_DEVICE_TABLE(pci, phantom_pci_tbl);
384
385static struct pci_driver phantom_pci_driver = {
386 .name = "phantom",
387 .id_table = phantom_pci_tbl,
388 .probe = phantom_probe,
389 .remove = __devexit_p(phantom_remove),
390 .suspend = phantom_suspend,
391 .resume = phantom_resume
392};
393
394static ssize_t phantom_show_version(struct class *cls, char *buf)
395{
396 return sprintf(buf, PHANTOM_VERSION "\n");
397}
398
399static CLASS_ATTR(version, 0444, phantom_show_version, NULL);
400
401static int __init phantom_init(void)
402{
403 int retval;
404 dev_t dev;
405
406 phantom_class = class_create(THIS_MODULE, "phantom");
407 if (IS_ERR(phantom_class)) {
408 retval = PTR_ERR(phantom_class);
409 printk(KERN_ERR "phantom: can't register phantom class\n");
410 goto err;
411 }
412 retval = class_create_file(phantom_class, &class_attr_version);
413 if (retval) {
414 printk(KERN_ERR "phantom: can't create sysfs version file\n");
415 goto err_class;
416 }
417
418 retval = alloc_chrdev_region(&dev, 0, PHANTOM_MAX_MINORS, "phantom");
419 if (retval) {
420 printk(KERN_ERR "phantom: can't register character device\n");
421 goto err_attr;
422 }
423 phantom_major = MAJOR(dev);
424
425 retval = pci_register_driver(&phantom_pci_driver);
426 if (retval) {
427 printk(KERN_ERR "phantom: can't register pci driver\n");
428 goto err_unchr;
429 }
430
431 printk(KERN_INFO "Phantom Linux Driver, version " PHANTOM_VERSION ", "
432 "init OK\n");
433
434 return 0;
435err_unchr:
436 unregister_chrdev_region(dev, PHANTOM_MAX_MINORS);
437err_attr:
438 class_remove_file(phantom_class, &class_attr_version);
439err_class:
440 class_destroy(phantom_class);
441err:
442 return retval;
443}
444
445static void __exit phantom_exit(void)
446{
447 pci_unregister_driver(&phantom_pci_driver);
448
449 unregister_chrdev_region(MKDEV(phantom_major, 0), PHANTOM_MAX_MINORS);
450
451 class_remove_file(phantom_class, &class_attr_version);
452 class_destroy(phantom_class);
453
454 pr_debug("phantom: module successfully removed\n");
455}
456
457module_init(phantom_init);
458module_exit(phantom_exit);
459
460MODULE_AUTHOR("Jiri Slaby <jirislaby@gmail.com>");
461MODULE_DESCRIPTION("Sensable Phantom driver");
462MODULE_LICENSE("GPL");
463MODULE_VERSION(PHANTOM_VERSION);
diff --git a/drivers/mtd/mtd_blkdevs.c b/drivers/mtd/mtd_blkdevs.c
index 524b83b5ebf5..51bc7e2f1f22 100644
--- a/drivers/mtd/mtd_blkdevs.c
+++ b/drivers/mtd/mtd_blkdevs.c
@@ -216,7 +216,7 @@ int add_mtd_blktrans_dev(struct mtd_blktrans_dev *new)
216 int last_devnum = -1; 216 int last_devnum = -1;
217 struct gendisk *gd; 217 struct gendisk *gd;
218 218
219 if (!!mutex_trylock(&mtd_table_mutex)) { 219 if (mutex_trylock(&mtd_table_mutex)) {
220 mutex_unlock(&mtd_table_mutex); 220 mutex_unlock(&mtd_table_mutex);
221 BUG(); 221 BUG();
222 } 222 }
@@ -294,7 +294,7 @@ int add_mtd_blktrans_dev(struct mtd_blktrans_dev *new)
294 294
295int del_mtd_blktrans_dev(struct mtd_blktrans_dev *old) 295int del_mtd_blktrans_dev(struct mtd_blktrans_dev *old)
296{ 296{
297 if (!!mutex_trylock(&mtd_table_mutex)) { 297 if (mutex_trylock(&mtd_table_mutex)) {
298 mutex_unlock(&mtd_table_mutex); 298 mutex_unlock(&mtd_table_mutex);
299 BUG(); 299 BUG();
300 } 300 }
diff --git a/drivers/net/irda/sir_dev.c b/drivers/net/irda/sir_dev.c
index 17b0c3ab6201..9d6c8f391b2d 100644
--- a/drivers/net/irda/sir_dev.c
+++ b/drivers/net/irda/sir_dev.c
@@ -14,7 +14,6 @@
14#include <linux/module.h> 14#include <linux/module.h>
15#include <linux/kernel.h> 15#include <linux/kernel.h>
16#include <linux/init.h> 16#include <linux/init.h>
17#include <linux/smp_lock.h>
18#include <linux/delay.h> 17#include <linux/delay.h>
19 18
20#include <net/irda/irda.h> 19#include <net/irda/irda.h>
diff --git a/drivers/net/irda/sir_dongle.c b/drivers/net/irda/sir_dongle.c
index d7e32d9554fc..25d5b8a96bdc 100644
--- a/drivers/net/irda/sir_dongle.c
+++ b/drivers/net/irda/sir_dongle.c
@@ -14,7 +14,6 @@
14#include <linux/module.h> 14#include <linux/module.h>
15#include <linux/kernel.h> 15#include <linux/kernel.h>
16#include <linux/init.h> 16#include <linux/init.h>
17#include <linux/smp_lock.h>
18#include <linux/kmod.h> 17#include <linux/kmod.h>
19#include <linux/mutex.h> 18#include <linux/mutex.h>
20 19
diff --git a/drivers/net/irda/smsc-ircc2.c b/drivers/net/irda/smsc-ircc2.c
index 198bf3bfa70f..9043bf4aa49e 100644
--- a/drivers/net/irda/smsc-ircc2.c
+++ b/drivers/net/irda/smsc-ircc2.c
@@ -79,11 +79,17 @@ MODULE_AUTHOR("Daniele Peri <peri@csai.unipa.it>");
79MODULE_DESCRIPTION("SMC IrCC SIR/FIR controller driver"); 79MODULE_DESCRIPTION("SMC IrCC SIR/FIR controller driver");
80MODULE_LICENSE("GPL"); 80MODULE_LICENSE("GPL");
81 81
82static int ircc_dma = 255; 82static int smsc_nopnp;
83module_param_named(nopnp, smsc_nopnp, bool, 0);
84MODULE_PARM_DESC(nopnp, "Do not use PNP to detect controller settings");
85
86#define DMA_INVAL 255
87static int ircc_dma = DMA_INVAL;
83module_param(ircc_dma, int, 0); 88module_param(ircc_dma, int, 0);
84MODULE_PARM_DESC(ircc_dma, "DMA channel"); 89MODULE_PARM_DESC(ircc_dma, "DMA channel");
85 90
86static int ircc_irq = 255; 91#define IRQ_INVAL 255
92static int ircc_irq = IRQ_INVAL;
87module_param(ircc_irq, int, 0); 93module_param(ircc_irq, int, 0);
88MODULE_PARM_DESC(ircc_irq, "IRQ line"); 94MODULE_PARM_DESC(ircc_irq, "IRQ line");
89 95
@@ -360,7 +366,6 @@ static inline void register_bank(int iobase, int bank)
360 iobase + IRCC_MASTER); 366 iobase + IRCC_MASTER);
361} 367}
362 368
363#ifdef CONFIG_PNP
364/* PNP hotplug support */ 369/* PNP hotplug support */
365static const struct pnp_device_id smsc_ircc_pnp_table[] = { 370static const struct pnp_device_id smsc_ircc_pnp_table[] = {
366 { .id = "SMCf010", .driver_data = 0 }, 371 { .id = "SMCf010", .driver_data = 0 },
@@ -368,7 +373,35 @@ static const struct pnp_device_id smsc_ircc_pnp_table[] = {
368 { } 373 { }
369}; 374};
370MODULE_DEVICE_TABLE(pnp, smsc_ircc_pnp_table); 375MODULE_DEVICE_TABLE(pnp, smsc_ircc_pnp_table);
371#endif 376
377static int pnp_driver_registered;
378
379static int __init smsc_ircc_pnp_probe(struct pnp_dev *dev,
380 const struct pnp_device_id *dev_id)
381{
382 unsigned int firbase, sirbase;
383 u8 dma, irq;
384
385 if (!(pnp_port_valid(dev, 0) && pnp_port_valid(dev, 1) &&
386 pnp_dma_valid(dev, 0) && pnp_irq_valid(dev, 0)))
387 return -EINVAL;
388
389 sirbase = pnp_port_start(dev, 0);
390 firbase = pnp_port_start(dev, 1);
391 dma = pnp_dma(dev, 0);
392 irq = pnp_irq(dev, 0);
393
394 if (smsc_ircc_open(firbase, sirbase, dma, irq))
395 return -ENODEV;
396
397 return 0;
398}
399
400static struct pnp_driver smsc_ircc_pnp_driver = {
401 .name = "smsc-ircc2",
402 .id_table = smsc_ircc_pnp_table,
403 .probe = smsc_ircc_pnp_probe,
404};
372 405
373 406
374/******************************************************************************* 407/*******************************************************************************
@@ -379,6 +412,35 @@ MODULE_DEVICE_TABLE(pnp, smsc_ircc_pnp_table);
379 * 412 *
380 *******************************************************************************/ 413 *******************************************************************************/
381 414
415static int __init smsc_ircc_legacy_probe(void)
416{
417 int ret = 0;
418
419 if (ircc_fir > 0 && ircc_sir > 0) {
420 IRDA_MESSAGE(" Overriding FIR address 0x%04x\n", ircc_fir);
421 IRDA_MESSAGE(" Overriding SIR address 0x%04x\n", ircc_sir);
422
423 if (smsc_ircc_open(ircc_fir, ircc_sir, ircc_dma, ircc_irq))
424 ret = -ENODEV;
425 } else {
426 ret = -ENODEV;
427
428 /* try user provided configuration register base address */
429 if (ircc_cfg > 0) {
430 IRDA_MESSAGE(" Overriding configuration address "
431 "0x%04x\n", ircc_cfg);
432 if (!smsc_superio_fdc(ircc_cfg))
433 ret = 0;
434 if (!smsc_superio_lpc(ircc_cfg))
435 ret = 0;
436 }
437
438 if (smsc_ircc_look_for_chips() > 0)
439 ret = 0;
440 }
441 return ret;
442}
443
382/* 444/*
383 * Function smsc_ircc_init () 445 * Function smsc_ircc_init ()
384 * 446 *
@@ -406,31 +468,20 @@ static int __init smsc_ircc_init(void)
406 468
407 dev_count = 0; 469 dev_count = 0;
408 470
409 if (ircc_fir > 0 && ircc_sir > 0) { 471 if (smsc_nopnp || !pnp_platform_devices ||
410 IRDA_MESSAGE(" Overriding FIR address 0x%04x\n", ircc_fir); 472 ircc_cfg || ircc_fir || ircc_sir ||
411 IRDA_MESSAGE(" Overriding SIR address 0x%04x\n", ircc_sir); 473 ircc_dma != DMA_INVAL || ircc_irq != IRQ_INVAL) {
412 474 ret = smsc_ircc_legacy_probe();
413 if (smsc_ircc_open(ircc_fir, ircc_sir, ircc_dma, ircc_irq))
414 ret = -ENODEV;
415 } else { 475 } else {
416 ret = -ENODEV; 476 if (pnp_register_driver(&smsc_ircc_pnp_driver) == 0)
417 477 pnp_driver_registered = 1;
418 /* try user provided configuration register base address */
419 if (ircc_cfg > 0) {
420 IRDA_MESSAGE(" Overriding configuration address "
421 "0x%04x\n", ircc_cfg);
422 if (!smsc_superio_fdc(ircc_cfg))
423 ret = 0;
424 if (!smsc_superio_lpc(ircc_cfg))
425 ret = 0;
426 }
427
428 if (smsc_ircc_look_for_chips() > 0)
429 ret = 0;
430 } 478 }
431 479
432 if (ret) 480 if (ret) {
481 if (pnp_driver_registered)
482 pnp_unregister_driver(&smsc_ircc_pnp_driver);
433 platform_driver_unregister(&smsc_ircc_driver); 483 platform_driver_unregister(&smsc_ircc_driver);
484 }
434 485
435 return ret; 486 return ret;
436} 487}
@@ -646,7 +697,7 @@ static void smsc_ircc_setup_io(struct smsc_ircc_cb *self,
646 self->io.fifo_size = SMSC_IRCC2_FIFO_SIZE; 697 self->io.fifo_size = SMSC_IRCC2_FIFO_SIZE;
647 self->io.speed = SMSC_IRCC2_C_IRDA_FALLBACK_SPEED; 698 self->io.speed = SMSC_IRCC2_C_IRDA_FALLBACK_SPEED;
648 699
649 if (irq < 255) { 700 if (irq != IRQ_INVAL) {
650 if (irq != chip_irq) 701 if (irq != chip_irq)
651 IRDA_MESSAGE("%s, Overriding IRQ - chip says %d, using %d\n", 702 IRDA_MESSAGE("%s, Overriding IRQ - chip says %d, using %d\n",
652 driver_name, chip_irq, irq); 703 driver_name, chip_irq, irq);
@@ -654,7 +705,7 @@ static void smsc_ircc_setup_io(struct smsc_ircc_cb *self,
654 } else 705 } else
655 self->io.irq = chip_irq; 706 self->io.irq = chip_irq;
656 707
657 if (dma < 255) { 708 if (dma != DMA_INVAL) {
658 if (dma != chip_dma) 709 if (dma != chip_dma)
659 IRDA_MESSAGE("%s, Overriding DMA - chip says %d, using %d\n", 710 IRDA_MESSAGE("%s, Overriding DMA - chip says %d, using %d\n",
660 driver_name, chip_dma, dma); 711 driver_name, chip_dma, dma);
@@ -1840,6 +1891,9 @@ static void __exit smsc_ircc_cleanup(void)
1840 smsc_ircc_close(dev_self[i]); 1891 smsc_ircc_close(dev_self[i]);
1841 } 1892 }
1842 1893
1894 if (pnp_driver_registered)
1895 pnp_unregister_driver(&smsc_ircc_pnp_driver);
1896
1843 platform_driver_unregister(&smsc_ircc_driver); 1897 platform_driver_unregister(&smsc_ircc_driver);
1844} 1898}
1845 1899
@@ -2836,9 +2890,9 @@ static int __init smsc_ircc_preconfigure_subsystems(unsigned short ircc_cfg,
2836 tmpconf.fir_io = ircc_fir; 2890 tmpconf.fir_io = ircc_fir;
2837 if (ircc_sir != 0) 2891 if (ircc_sir != 0)
2838 tmpconf.sir_io = ircc_sir; 2892 tmpconf.sir_io = ircc_sir;
2839 if (ircc_dma != 0xff) 2893 if (ircc_dma != DMA_INVAL)
2840 tmpconf.fir_dma = ircc_dma; 2894 tmpconf.fir_dma = ircc_dma;
2841 if (ircc_irq != 0xff) 2895 if (ircc_irq != IRQ_INVAL)
2842 tmpconf.fir_irq = ircc_irq; 2896 tmpconf.fir_irq = ircc_irq;
2843 2897
2844 IRDA_MESSAGE("Detected unconfigured %s SMSC IrDA chip, pre-configuring device.\n", conf->name); 2898 IRDA_MESSAGE("Detected unconfigured %s SMSC IrDA chip, pre-configuring device.\n", conf->name);
diff --git a/drivers/net/irda/vlsi_ir.c b/drivers/net/irda/vlsi_ir.c
index c4be973867a6..bf78ef1120ad 100644
--- a/drivers/net/irda/vlsi_ir.c
+++ b/drivers/net/irda/vlsi_ir.c
@@ -44,7 +44,6 @@ MODULE_LICENSE("GPL");
44#include <linux/time.h> 44#include <linux/time.h>
45#include <linux/proc_fs.h> 45#include <linux/proc_fs.h>
46#include <linux/seq_file.h> 46#include <linux/seq_file.h>
47#include <linux/smp_lock.h>
48#include <asm/uaccess.h> 47#include <asm/uaccess.h>
49#include <asm/byteorder.h> 48#include <asm/byteorder.h>
50 49
diff --git a/drivers/net/ns83820.c b/drivers/net/ns83820.c
index 6a32338623f1..3439f8c649f9 100644
--- a/drivers/net/ns83820.c
+++ b/drivers/net/ns83820.c
@@ -104,7 +104,6 @@
104#include <linux/netdevice.h> 104#include <linux/netdevice.h>
105#include <linux/etherdevice.h> 105#include <linux/etherdevice.h>
106#include <linux/delay.h> 106#include <linux/delay.h>
107#include <linux/smp_lock.h>
108#include <linux/workqueue.h> 107#include <linux/workqueue.h>
109#include <linux/init.h> 108#include <linux/init.h>
110#include <linux/ip.h> /* for iph */ 109#include <linux/ip.h> /* for iph */
diff --git a/drivers/net/ppp_generic.c b/drivers/net/ppp_generic.c
index 6d596ca50cfd..541168713f1f 100644
--- a/drivers/net/ppp_generic.c
+++ b/drivers/net/ppp_generic.c
@@ -40,7 +40,6 @@
40#include <linux/ip.h> 40#include <linux/ip.h>
41#include <linux/tcp.h> 41#include <linux/tcp.h>
42#include <linux/spinlock.h> 42#include <linux/spinlock.h>
43#include <linux/smp_lock.h>
44#include <linux/rwsem.h> 43#include <linux/rwsem.h>
45#include <linux/stddef.h> 44#include <linux/stddef.h>
46#include <linux/device.h> 45#include <linux/device.h>
diff --git a/drivers/net/wan/cosa.c b/drivers/net/wan/cosa.c
index 23464735fa88..9ef49ce148b2 100644
--- a/drivers/net/wan/cosa.c
+++ b/drivers/net/wan/cosa.c
@@ -90,7 +90,6 @@
90#include <linux/ioport.h> 90#include <linux/ioport.h>
91#include <linux/netdevice.h> 91#include <linux/netdevice.h>
92#include <linux/spinlock.h> 92#include <linux/spinlock.h>
93#include <linux/smp_lock.h>
94#include <linux/device.h> 93#include <linux/device.h>
95 94
96#undef COSA_SLOW_IO /* for testing purposes only */ 95#undef COSA_SLOW_IO /* for testing purposes only */
diff --git a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c
index f21bbafcb728..2d3a180dada0 100644
--- a/drivers/net/wireless/airo.c
+++ b/drivers/net/wireless/airo.c
@@ -25,7 +25,6 @@
25#include <linux/kernel.h> 25#include <linux/kernel.h>
26#include <linux/module.h> 26#include <linux/module.h>
27#include <linux/proc_fs.h> 27#include <linux/proc_fs.h>
28#include <linux/smp_lock.h>
29 28
30#include <linux/sched.h> 29#include <linux/sched.h>
31#include <linux/ptrace.h> 30#include <linux/ptrace.h>
diff --git a/drivers/net/wireless/hostap/hostap_ioctl.c b/drivers/net/wireless/hostap/hostap_ioctl.c
index cb08bc5db2bd..cdea7f71b9eb 100644
--- a/drivers/net/wireless/hostap/hostap_ioctl.c
+++ b/drivers/net/wireless/hostap/hostap_ioctl.c
@@ -1,7 +1,6 @@
1/* ioctl() (mostly Linux Wireless Extensions) routines for Host AP driver */ 1/* ioctl() (mostly Linux Wireless Extensions) routines for Host AP driver */
2 2
3#include <linux/types.h> 3#include <linux/types.h>
4#include <linux/smp_lock.h>
5#include <linux/ethtool.h> 4#include <linux/ethtool.h>
6#include <net/ieee80211_crypt.h> 5#include <net/ieee80211_crypt.h>
7 6
diff --git a/drivers/parisc/lba_pci.c b/drivers/parisc/lba_pci.c
index 21c4c299b3d6..5b86ee5c1eeb 100644
--- a/drivers/parisc/lba_pci.c
+++ b/drivers/parisc/lba_pci.c
@@ -38,7 +38,6 @@
38#include <linux/pci.h> 38#include <linux/pci.h>
39#include <linux/ioport.h> 39#include <linux/ioport.h>
40#include <linux/slab.h> 40#include <linux/slab.h>
41#include <linux/smp_lock.h>
42 41
43#include <asm/byteorder.h> 42#include <asm/byteorder.h>
44#include <asm/pdc.h> 43#include <asm/pdc.h>
diff --git a/drivers/parport/parport_cs.c b/drivers/parport/parport_cs.c
index 316c06f4423c..8b7d84eca05d 100644
--- a/drivers/parport/parport_cs.c
+++ b/drivers/parport/parport_cs.c
@@ -201,7 +201,7 @@ static int parport_config(struct pcmcia_device *link)
201 201
202 p = parport_pc_probe_port(link->io.BasePort1, link->io.BasePort2, 202 p = parport_pc_probe_port(link->io.BasePort1, link->io.BasePort2,
203 link->irq.AssignedIRQ, PARPORT_DMA_NONE, 203 link->irq.AssignedIRQ, PARPORT_DMA_NONE,
204 NULL); 204 &link->dev);
205 if (p == NULL) { 205 if (p == NULL) {
206 printk(KERN_NOTICE "parport_cs: parport_pc_probe_port() at " 206 printk(KERN_NOTICE "parport_cs: parport_pc_probe_port() at "
207 "0x%3x, irq %u failed\n", link->io.BasePort1, 207 "0x%3x, irq %u failed\n", link->io.BasePort1,
diff --git a/drivers/parport/parport_mfc3.c b/drivers/parport/parport_mfc3.c
index e5b0a544de40..77726fc49766 100644
--- a/drivers/parport/parport_mfc3.c
+++ b/drivers/parport/parport_mfc3.c
@@ -356,6 +356,7 @@ static int __init parport_mfc3_init(void)
356 if (request_irq(IRQ_AMIGA_PORTS, mfc3_interrupt, IRQF_SHARED, p->name, &pp_mfc3_ops)) 356 if (request_irq(IRQ_AMIGA_PORTS, mfc3_interrupt, IRQF_SHARED, p->name, &pp_mfc3_ops))
357 goto out_irq; 357 goto out_irq;
358 } 358 }
359 p->dev = &z->dev;
359 360
360 this_port[pias++] = p; 361 this_port[pias++] = p;
361 printk(KERN_INFO "%s: Multiface III port using irq\n", p->name); 362 printk(KERN_INFO "%s: Multiface III port using irq\n", p->name);
diff --git a/drivers/parport/parport_pc.c b/drivers/parport/parport_pc.c
index 3de2623afa13..02c0d52c9f76 100644
--- a/drivers/parport/parport_pc.c
+++ b/drivers/parport/parport_pc.c
@@ -53,6 +53,7 @@
53#include <linux/slab.h> 53#include <linux/slab.h>
54#include <linux/pci.h> 54#include <linux/pci.h>
55#include <linux/pnp.h> 55#include <linux/pnp.h>
56#include <linux/platform_device.h>
56#include <linux/sysctl.h> 57#include <linux/sysctl.h>
57 58
58#include <asm/io.h> 59#include <asm/io.h>
@@ -620,6 +621,7 @@ static size_t parport_pc_fifo_write_block_dma (struct parport *port,
620 unsigned long dmaflag; 621 unsigned long dmaflag;
621 size_t left = length; 622 size_t left = length;
622 const struct parport_pc_private *priv = port->physport->private_data; 623 const struct parport_pc_private *priv = port->physport->private_data;
624 struct device *dev = port->physport->dev;
623 dma_addr_t dma_addr, dma_handle; 625 dma_addr_t dma_addr, dma_handle;
624 size_t maxlen = 0x10000; /* max 64k per DMA transfer */ 626 size_t maxlen = 0x10000; /* max 64k per DMA transfer */
625 unsigned long start = (unsigned long) buf; 627 unsigned long start = (unsigned long) buf;
@@ -631,8 +633,8 @@ dump_parport_state ("enter fifo_write_block_dma", port);
631 if ((start ^ end) & ~0xffffUL) 633 if ((start ^ end) & ~0xffffUL)
632 maxlen = 0x10000 - (start & 0xffff); 634 maxlen = 0x10000 - (start & 0xffff);
633 635
634 dma_addr = dma_handle = pci_map_single(priv->dev, (void *)buf, length, 636 dma_addr = dma_handle = dma_map_single(dev, (void *)buf, length,
635 PCI_DMA_TODEVICE); 637 DMA_TO_DEVICE);
636 } else { 638 } else {
637 /* above 16 MB we use a bounce buffer as ISA-DMA is not possible */ 639 /* above 16 MB we use a bounce buffer as ISA-DMA is not possible */
638 maxlen = PAGE_SIZE; /* sizeof(priv->dma_buf) */ 640 maxlen = PAGE_SIZE; /* sizeof(priv->dma_buf) */
@@ -728,9 +730,9 @@ dump_parport_state ("enter fifo_write_block_dma", port);
728 730
729 /* Turn off DMA mode */ 731 /* Turn off DMA mode */
730 frob_econtrol (port, 1<<3, 0); 732 frob_econtrol (port, 1<<3, 0);
731 733
732 if (dma_handle) 734 if (dma_handle)
733 pci_unmap_single(priv->dev, dma_handle, length, PCI_DMA_TODEVICE); 735 dma_unmap_single(dev, dma_handle, length, DMA_TO_DEVICE);
734 736
735dump_parport_state ("leave fifo_write_block_dma", port); 737dump_parport_state ("leave fifo_write_block_dma", port);
736 return length - left; 738 return length - left;
@@ -2146,7 +2148,7 @@ static DEFINE_SPINLOCK(ports_lock);
2146struct parport *parport_pc_probe_port (unsigned long int base, 2148struct parport *parport_pc_probe_port (unsigned long int base,
2147 unsigned long int base_hi, 2149 unsigned long int base_hi,
2148 int irq, int dma, 2150 int irq, int dma,
2149 struct pci_dev *dev) 2151 struct device *dev)
2150{ 2152{
2151 struct parport_pc_private *priv; 2153 struct parport_pc_private *priv;
2152 struct parport_operations *ops; 2154 struct parport_operations *ops;
@@ -2155,6 +2157,17 @@ struct parport *parport_pc_probe_port (unsigned long int base,
2155 struct resource *base_res; 2157 struct resource *base_res;
2156 struct resource *ECR_res = NULL; 2158 struct resource *ECR_res = NULL;
2157 struct resource *EPP_res = NULL; 2159 struct resource *EPP_res = NULL;
2160 struct platform_device *pdev = NULL;
2161
2162 if (!dev) {
2163 /* We need a physical device to attach to, but none was
2164 * provided. Create our own. */
2165 pdev = platform_device_register_simple("parport_pc",
2166 base, NULL, 0);
2167 if (IS_ERR(pdev))
2168 return NULL;
2169 dev = &pdev->dev;
2170 }
2158 2171
2159 ops = kmalloc(sizeof (struct parport_operations), GFP_KERNEL); 2172 ops = kmalloc(sizeof (struct parport_operations), GFP_KERNEL);
2160 if (!ops) 2173 if (!ops)
@@ -2180,9 +2193,10 @@ struct parport *parport_pc_probe_port (unsigned long int base,
2180 priv->fifo_depth = 0; 2193 priv->fifo_depth = 0;
2181 priv->dma_buf = NULL; 2194 priv->dma_buf = NULL;
2182 priv->dma_handle = 0; 2195 priv->dma_handle = 0;
2183 priv->dev = dev;
2184 INIT_LIST_HEAD(&priv->list); 2196 INIT_LIST_HEAD(&priv->list);
2185 priv->port = p; 2197 priv->port = p;
2198
2199 p->dev = dev;
2186 p->base_hi = base_hi; 2200 p->base_hi = base_hi;
2187 p->modes = PARPORT_MODE_PCSPP | PARPORT_MODE_SAFEININT; 2201 p->modes = PARPORT_MODE_PCSPP | PARPORT_MODE_SAFEININT;
2188 p->private_data = priv; 2202 p->private_data = priv;
@@ -2305,9 +2319,10 @@ struct parport *parport_pc_probe_port (unsigned long int base,
2305 p->dma = PARPORT_DMA_NONE; 2319 p->dma = PARPORT_DMA_NONE;
2306 } else { 2320 } else {
2307 priv->dma_buf = 2321 priv->dma_buf =
2308 pci_alloc_consistent(priv->dev, 2322 dma_alloc_coherent(dev,
2309 PAGE_SIZE, 2323 PAGE_SIZE,
2310 &priv->dma_handle); 2324 &priv->dma_handle,
2325 GFP_KERNEL);
2311 if (! priv->dma_buf) { 2326 if (! priv->dma_buf) {
2312 printk (KERN_WARNING "%s: " 2327 printk (KERN_WARNING "%s: "
2313 "cannot get buffer for DMA, " 2328 "cannot get buffer for DMA, "
@@ -2356,6 +2371,8 @@ out3:
2356out2: 2371out2:
2357 kfree (ops); 2372 kfree (ops);
2358out1: 2373out1:
2374 if (pdev)
2375 platform_device_unregister(pdev);
2359 return NULL; 2376 return NULL;
2360} 2377}
2361 2378
@@ -2383,7 +2400,7 @@ void parport_pc_unregister_port (struct parport *p)
2383 release_region(p->base_hi, 3); 2400 release_region(p->base_hi, 3);
2384#if defined(CONFIG_PARPORT_PC_FIFO) && defined(HAS_DMA) 2401#if defined(CONFIG_PARPORT_PC_FIFO) && defined(HAS_DMA)
2385 if (priv->dma_buf) 2402 if (priv->dma_buf)
2386 pci_free_consistent(priv->dev, PAGE_SIZE, 2403 dma_free_coherent(p->physport->dev, PAGE_SIZE,
2387 priv->dma_buf, 2404 priv->dma_buf,
2388 priv->dma_handle); 2405 priv->dma_handle);
2389#endif 2406#endif
@@ -2489,7 +2506,7 @@ static int __devinit sio_ite_8872_probe (struct pci_dev *pdev, int autoirq,
2489 */ 2506 */
2490 release_resource(base_res); 2507 release_resource(base_res);
2491 if (parport_pc_probe_port (ite8872_lpt, ite8872_lpthi, 2508 if (parport_pc_probe_port (ite8872_lpt, ite8872_lpthi,
2492 irq, PARPORT_DMA_NONE, NULL)) { 2509 irq, PARPORT_DMA_NONE, &pdev->dev)) {
2493 printk (KERN_INFO 2510 printk (KERN_INFO
2494 "parport_pc: ITE 8872 parallel port: io=0x%X", 2511 "parport_pc: ITE 8872 parallel port: io=0x%X",
2495 ite8872_lpt); 2512 ite8872_lpt);
@@ -2672,7 +2689,7 @@ static int __devinit sio_via_probe (struct pci_dev *pdev, int autoirq,
2672 } 2689 }
2673 2690
2674 /* finally, do the probe with values obtained */ 2691 /* finally, do the probe with values obtained */
2675 if (parport_pc_probe_port (port1, port2, irq, dma, NULL)) { 2692 if (parport_pc_probe_port (port1, port2, irq, dma, &pdev->dev)) {
2676 printk (KERN_INFO 2693 printk (KERN_INFO
2677 "parport_pc: VIA parallel port: io=0x%X", port1); 2694 "parport_pc: VIA parallel port: io=0x%X", port1);
2678 if (irq != PARPORT_IRQ_NONE) 2695 if (irq != PARPORT_IRQ_NONE)
@@ -2970,7 +2987,7 @@ static int parport_pc_pci_probe (struct pci_dev *dev,
2970 parport_pc_pci_tbl[i + last_sio].device, io_lo, io_hi); 2987 parport_pc_pci_tbl[i + last_sio].device, io_lo, io_hi);
2971 data->ports[count] = 2988 data->ports[count] =
2972 parport_pc_probe_port (io_lo, io_hi, PARPORT_IRQ_NONE, 2989 parport_pc_probe_port (io_lo, io_hi, PARPORT_IRQ_NONE,
2973 PARPORT_DMA_NONE, dev); 2990 PARPORT_DMA_NONE, &dev->dev);
2974 if (data->ports[count]) 2991 if (data->ports[count])
2975 count++; 2992 count++;
2976 } 2993 }
@@ -3077,8 +3094,8 @@ static int parport_pc_pnp_probe(struct pnp_dev *dev, const struct pnp_device_id
3077 } else 3094 } else
3078 dma = PARPORT_DMA_NONE; 3095 dma = PARPORT_DMA_NONE;
3079 3096
3080 printk(KERN_INFO "parport: PnPBIOS parport detected.\n"); 3097 dev_info(&dev->dev, "reported by %s\n", dev->protocol->name);
3081 if (!(pdata = parport_pc_probe_port (io_lo, io_hi, irq, dma, NULL))) 3098 if (!(pdata = parport_pc_probe_port (io_lo, io_hi, irq, dma, &dev->dev)))
3082 return -ENODEV; 3099 return -ENODEV;
3083 3100
3084 pnp_set_drvdata(dev,pdata); 3101 pnp_set_drvdata(dev,pdata);
@@ -3103,6 +3120,21 @@ static struct pnp_driver parport_pc_pnp_driver = {
3103}; 3120};
3104 3121
3105 3122
3123static int __devinit parport_pc_platform_probe(struct platform_device *pdev)
3124{
3125 /* Always succeed, the actual probing is done in
3126 * parport_pc_probe_port(). */
3127 return 0;
3128}
3129
3130static struct platform_driver parport_pc_platform_driver = {
3131 .driver = {
3132 .owner = THIS_MODULE,
3133 .name = "parport_pc",
3134 },
3135 .probe = parport_pc_platform_probe,
3136};
3137
3106/* This is called by parport_pc_find_nonpci_ports (in asm/parport.h) */ 3138/* This is called by parport_pc_find_nonpci_ports (in asm/parport.h) */
3107static int __devinit __attribute__((unused)) 3139static int __devinit __attribute__((unused))
3108parport_pc_find_isa_ports (int autoirq, int autodma) 3140parport_pc_find_isa_ports (int autoirq, int autodma)
@@ -3378,9 +3410,15 @@ __setup("parport_init_mode=",parport_init_mode_setup);
3378 3410
3379static int __init parport_pc_init(void) 3411static int __init parport_pc_init(void)
3380{ 3412{
3413 int err;
3414
3381 if (parse_parport_params()) 3415 if (parse_parport_params())
3382 return -EINVAL; 3416 return -EINVAL;
3383 3417
3418 err = platform_driver_register(&parport_pc_platform_driver);
3419 if (err)
3420 return err;
3421
3384 if (io[0]) { 3422 if (io[0]) {
3385 int i; 3423 int i;
3386 /* Only probe the ports we were given. */ 3424 /* Only probe the ports we were given. */
@@ -3405,6 +3443,7 @@ static void __exit parport_pc_exit(void)
3405 pci_unregister_driver (&parport_pc_pci_driver); 3443 pci_unregister_driver (&parport_pc_pci_driver);
3406 if (pnp_registered_parport) 3444 if (pnp_registered_parport)
3407 pnp_unregister_driver (&parport_pc_pnp_driver); 3445 pnp_unregister_driver (&parport_pc_pnp_driver);
3446 platform_driver_unregister(&parport_pc_platform_driver);
3408 3447
3409 spin_lock(&ports_lock); 3448 spin_lock(&ports_lock);
3410 while (!list_empty(&ports_list)) { 3449 while (!list_empty(&ports_list)) {
@@ -3413,6 +3452,9 @@ static void __exit parport_pc_exit(void)
3413 priv = list_entry(ports_list.next, 3452 priv = list_entry(ports_list.next,
3414 struct parport_pc_private, list); 3453 struct parport_pc_private, list);
3415 port = priv->port; 3454 port = priv->port;
3455 if (port->dev && port->dev->bus == &platform_bus_type)
3456 platform_device_unregister(
3457 to_platform_device(port->dev));
3416 spin_unlock(&ports_lock); 3458 spin_unlock(&ports_lock);
3417 parport_pc_unregister_port(port); 3459 parport_pc_unregister_port(port);
3418 spin_lock(&ports_lock); 3460 spin_lock(&ports_lock);
diff --git a/drivers/parport/parport_serial.c b/drivers/parport/parport_serial.c
index 78c0a269a2ba..90ea3b8b99b0 100644
--- a/drivers/parport/parport_serial.c
+++ b/drivers/parport/parport_serial.c
@@ -305,7 +305,7 @@ static int __devinit parport_register (struct pci_dev *dev,
305 dev_dbg(&dev->dev, "PCI parallel port detected: I/O at " 305 dev_dbg(&dev->dev, "PCI parallel port detected: I/O at "
306 "%#lx(%#lx)\n", io_lo, io_hi); 306 "%#lx(%#lx)\n", io_lo, io_hi);
307 port = parport_pc_probe_port (io_lo, io_hi, PARPORT_IRQ_NONE, 307 port = parport_pc_probe_port (io_lo, io_hi, PARPORT_IRQ_NONE,
308 PARPORT_DMA_NONE, dev); 308 PARPORT_DMA_NONE, &dev->dev);
309 if (port) { 309 if (port) {
310 priv->port[priv->num_par++] = port; 310 priv->port[priv->num_par++] = port;
311 success = 1; 311 success = 1;
@@ -392,6 +392,7 @@ static int parport_serial_pci_suspend(struct pci_dev *dev, pm_message_t state)
392static int parport_serial_pci_resume(struct pci_dev *dev) 392static int parport_serial_pci_resume(struct pci_dev *dev)
393{ 393{
394 struct parport_serial_private *priv = pci_get_drvdata(dev); 394 struct parport_serial_private *priv = pci_get_drvdata(dev);
395 int err;
395 396
396 pci_set_power_state(dev, PCI_D0); 397 pci_set_power_state(dev, PCI_D0);
397 pci_restore_state(dev); 398 pci_restore_state(dev);
@@ -399,7 +400,12 @@ static int parport_serial_pci_resume(struct pci_dev *dev)
399 /* 400 /*
400 * The device may have been disabled. Re-enable it. 401 * The device may have been disabled. Re-enable it.
401 */ 402 */
402 pci_enable_device(dev); 403 err = pci_enable_device(dev);
404 if (err) {
405 printk(KERN_ERR "parport_serial: %s: error enabling "
406 "device for resume (%d)\n", pci_name(dev), err);
407 return err;
408 }
403 409
404 if (priv->serial) 410 if (priv->serial)
405 pciserial_resume_ports(priv->serial); 411 pciserial_resume_ports(priv->serial);
diff --git a/drivers/parport/parport_sunbpp.c b/drivers/parport/parport_sunbpp.c
index 400bb90084cf..d27019c2f860 100644
--- a/drivers/parport/parport_sunbpp.c
+++ b/drivers/parport/parport_sunbpp.c
@@ -322,6 +322,7 @@ static int __devinit init_one_port(struct sbus_dev *sdev)
322 goto out_free_ops; 322 goto out_free_ops;
323 323
324 p->size = size; 324 p->size = size;
325 p->dev = &sdev->ofdev.dev;
325 326
326 if ((err = request_irq(p->irq, parport_sunbpp_interrupt, 327 if ((err = request_irq(p->irq, parport_sunbpp_interrupt,
327 IRQF_SHARED, p->name, p)) != 0) { 328 IRQF_SHARED, p->name, p)) != 0) {
diff --git a/drivers/parport/share.c b/drivers/parport/share.c
index fd9129e424f9..cd66442acfee 100644
--- a/drivers/parport/share.c
+++ b/drivers/parport/share.c
@@ -365,6 +365,11 @@ void parport_announce_port (struct parport *port)
365 parport_daisy_init(port); 365 parport_daisy_init(port);
366#endif 366#endif
367 367
368 if (!port->dev)
369 printk(KERN_WARNING "%s: fix this legacy "
370 "no-device port driver!\n",
371 port->name);
372
368 parport_proc_register(port); 373 parport_proc_register(port);
369 mutex_lock(&registration_lock); 374 mutex_lock(&registration_lock);
370 spin_lock_irq(&parportlist_lock); 375 spin_lock_irq(&parportlist_lock);
diff --git a/drivers/pci/hotplug/acpiphp_core.c b/drivers/pci/hotplug/acpiphp_core.c
index 40c79b03c7ef..fa5c0197d571 100644
--- a/drivers/pci/hotplug/acpiphp_core.c
+++ b/drivers/pci/hotplug/acpiphp_core.c
@@ -40,7 +40,6 @@
40#include <linux/pci_hotplug.h> 40#include <linux/pci_hotplug.h>
41#include <linux/slab.h> 41#include <linux/slab.h>
42#include <linux/smp.h> 42#include <linux/smp.h>
43#include <linux/smp_lock.h>
44#include "acpiphp.h" 43#include "acpiphp.h"
45 44
46#define MY_NAME "acpiphp" 45#define MY_NAME "acpiphp"
diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c
index fca978fb158e..9ef4e989afc4 100644
--- a/drivers/pci/hotplug/acpiphp_glue.c
+++ b/drivers/pci/hotplug/acpiphp_glue.c
@@ -46,7 +46,6 @@
46#include <linux/kernel.h> 46#include <linux/kernel.h>
47#include <linux/pci.h> 47#include <linux/pci.h>
48#include <linux/pci_hotplug.h> 48#include <linux/pci_hotplug.h>
49#include <linux/smp_lock.h>
50#include <linux/mutex.h> 49#include <linux/mutex.h>
51 50
52#include "../pci.h" 51#include "../pci.h"
diff --git a/drivers/pci/hotplug/ibmphp_core.c b/drivers/pci/hotplug/ibmphp_core.c
index 59392946c2bd..0316eeaaeb29 100644
--- a/drivers/pci/hotplug/ibmphp_core.c
+++ b/drivers/pci/hotplug/ibmphp_core.c
@@ -34,7 +34,6 @@
34#include <linux/interrupt.h> 34#include <linux/interrupt.h>
35#include <linux/delay.h> 35#include <linux/delay.h>
36#include <linux/wait.h> 36#include <linux/wait.h>
37#include <linux/smp_lock.h>
38#include "../pci.h" 37#include "../pci.h"
39#include "../../../arch/i386/pci/pci.h" /* for struct irq_routing_table */ 38#include "../../../arch/i386/pci/pci.h" /* for struct irq_routing_table */
40#include "ibmphp.h" 39#include "ibmphp.h"
diff --git a/drivers/pci/hotplug/ibmphp_hpc.c b/drivers/pci/hotplug/ibmphp_hpc.c
index f55ac3885cb3..46abaa8c41f1 100644
--- a/drivers/pci/hotplug/ibmphp_hpc.c
+++ b/drivers/pci/hotplug/ibmphp_hpc.c
@@ -32,7 +32,6 @@
32#include <linux/delay.h> 32#include <linux/delay.h>
33#include <linux/module.h> 33#include <linux/module.h>
34#include <linux/pci.h> 34#include <linux/pci.h>
35#include <linux/smp_lock.h>
36#include <linux/init.h> 35#include <linux/init.h>
37#include <linux/mutex.h> 36#include <linux/mutex.h>
38 37
diff --git a/drivers/pci/hotplug/pci_hotplug_core.c b/drivers/pci/hotplug/pci_hotplug_core.c
index 63f3bd1eecc4..bd433ef6bfc6 100644
--- a/drivers/pci/hotplug/pci_hotplug_core.c
+++ b/drivers/pci/hotplug/pci_hotplug_core.c
@@ -34,7 +34,6 @@
34#include <linux/sysfs.h> 34#include <linux/sysfs.h>
35#include <linux/pagemap.h> 35#include <linux/pagemap.h>
36#include <linux/slab.h> 36#include <linux/slab.h>
37#include <linux/smp_lock.h>
38#include <linux/init.h> 37#include <linux/init.h>
39#include <linux/mount.h> 38#include <linux/mount.h>
40#include <linux/namei.h> 39#include <linux/namei.h>
diff --git a/drivers/pci/hotplug/rpaphp_core.c b/drivers/pci/hotplug/rpaphp_core.c
index 899eed002748..458c08ef2654 100644
--- a/drivers/pci/hotplug/rpaphp_core.c
+++ b/drivers/pci/hotplug/rpaphp_core.c
@@ -29,7 +29,6 @@
29#include <linux/pci_hotplug.h> 29#include <linux/pci_hotplug.h>
30#include <linux/slab.h> 30#include <linux/slab.h>
31#include <linux/smp.h> 31#include <linux/smp.h>
32#include <linux/smp_lock.h>
33#include <linux/init.h> 32#include <linux/init.h>
34#include <asm/eeh.h> /* for eeh_add_device() */ 33#include <asm/eeh.h> /* for eeh_add_device() */
35#include <asm/rtas.h> /* rtas_call */ 34#include <asm/rtas.h> /* rtas_call */
diff --git a/drivers/pci/hotplug/shpchp_ctrl.c b/drivers/pci/hotplug/shpchp_ctrl.c
index 2c94d44279a3..d2fc35598cdd 100644
--- a/drivers/pci/hotplug/shpchp_ctrl.c
+++ b/drivers/pci/hotplug/shpchp_ctrl.c
@@ -30,7 +30,6 @@
30#include <linux/module.h> 30#include <linux/module.h>
31#include <linux/kernel.h> 31#include <linux/kernel.h>
32#include <linux/types.h> 32#include <linux/types.h>
33#include <linux/smp_lock.h>
34#include <linux/pci.h> 33#include <linux/pci.h>
35#include <linux/workqueue.h> 34#include <linux/workqueue.h>
36#include "../pci.h" 35#include "../pci.h"
diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c
index 9e1321d0d5e6..e6740d1a0824 100644
--- a/drivers/pci/msi.c
+++ b/drivers/pci/msi.c
@@ -12,7 +12,6 @@
12#include <linux/interrupt.h> 12#include <linux/interrupt.h>
13#include <linux/init.h> 13#include <linux/init.h>
14#include <linux/ioport.h> 14#include <linux/ioport.h>
15#include <linux/smp_lock.h>
16#include <linux/pci.h> 15#include <linux/pci.h>
17#include <linux/proc_fs.h> 16#include <linux/proc_fs.h>
18#include <linux/msi.h> 17#include <linux/msi.h>
diff --git a/drivers/pci/proc.c b/drivers/pci/proc.c
index ed87aa59f0b1..0425a7b7350d 100644
--- a/drivers/pci/proc.c
+++ b/drivers/pci/proc.c
@@ -11,7 +11,6 @@
11#include <linux/module.h> 11#include <linux/module.h>
12#include <linux/proc_fs.h> 12#include <linux/proc_fs.h>
13#include <linux/seq_file.h> 13#include <linux/seq_file.h>
14#include <linux/smp_lock.h>
15 14
16#include <asm/uaccess.h> 15#include <asm/uaccess.h>
17#include <asm/byteorder.h> 16#include <asm/byteorder.h>
diff --git a/drivers/pcmcia/pxa2xx_mainstone.c b/drivers/pcmcia/pxa2xx_mainstone.c
index fda06941e730..383107ba4bd3 100644
--- a/drivers/pcmcia/pxa2xx_mainstone.c
+++ b/drivers/pcmcia/pxa2xx_mainstone.c
@@ -175,6 +175,7 @@ static int __init mst_pcmcia_init(void)
175 if (!mst_pcmcia_device) 175 if (!mst_pcmcia_device)
176 return -ENOMEM; 176 return -ENOMEM;
177 177
178 mst_pcmcia_device->dev.uevent_suppress = 0;
178 mst_pcmcia_device->dev.platform_data = &mst_pcmcia_ops; 179 mst_pcmcia_device->dev.platform_data = &mst_pcmcia_ops;
179 180
180 ret = platform_device_add(mst_pcmcia_device); 181 ret = platform_device_add(mst_pcmcia_device);
diff --git a/drivers/pcmcia/pxa2xx_sharpsl.c b/drivers/pcmcia/pxa2xx_sharpsl.c
index b7b9e149c5b9..a2daa3f531b2 100644
--- a/drivers/pcmcia/pxa2xx_sharpsl.c
+++ b/drivers/pcmcia/pxa2xx_sharpsl.c
@@ -261,6 +261,7 @@ static int __init sharpsl_pcmcia_init(void)
261 if (!sharpsl_pcmcia_device) 261 if (!sharpsl_pcmcia_device)
262 return -ENOMEM; 262 return -ENOMEM;
263 263
264 sharpsl_pcmcia_device->dev.uevent_suppress = 0;
264 sharpsl_pcmcia_device->dev.platform_data = &sharpsl_pcmcia_ops; 265 sharpsl_pcmcia_device->dev.platform_data = &sharpsl_pcmcia_ops;
265 sharpsl_pcmcia_device->dev.parent = platform_scoop_config->devs[0].dev; 266 sharpsl_pcmcia_device->dev.parent = platform_scoop_config->devs[0].dev;
266 267
diff --git a/drivers/pnp/core.c b/drivers/pnp/core.c
index aec83ec5ea23..3e20b1cc7778 100644
--- a/drivers/pnp/core.c
+++ b/drivers/pnp/core.c
@@ -14,6 +14,7 @@
14#include <linux/string.h> 14#include <linux/string.h>
15#include <linux/slab.h> 15#include <linux/slab.h>
16#include <linux/errno.h> 16#include <linux/errno.h>
17#include <linux/dma-mapping.h>
17 18
18#include "base.h" 19#include "base.h"
19 20
@@ -22,6 +23,14 @@ static LIST_HEAD(pnp_protocols);
22LIST_HEAD(pnp_global); 23LIST_HEAD(pnp_global);
23DEFINE_SPINLOCK(pnp_lock); 24DEFINE_SPINLOCK(pnp_lock);
24 25
26/*
27 * ACPI or PNPBIOS should tell us about all platform devices, so we can
28 * skip some blind probes. ISAPNP typically enumerates only plug-in ISA
29 * devices, not built-in things like COM ports.
30 */
31int pnp_platform_devices;
32EXPORT_SYMBOL(pnp_platform_devices);
33
25void *pnp_alloc(long size) 34void *pnp_alloc(long size)
26{ 35{
27 void *result; 36 void *result;
@@ -114,6 +123,8 @@ int __pnp_add_device(struct pnp_dev *dev)
114 int ret; 123 int ret;
115 pnp_fixup_device(dev); 124 pnp_fixup_device(dev);
116 dev->dev.bus = &pnp_bus_type; 125 dev->dev.bus = &pnp_bus_type;
126 dev->dev.dma_mask = &dev->dma_mask;
127 dev->dma_mask = dev->dev.coherent_dma_mask = DMA_24BIT_MASK;
117 dev->dev.release = &pnp_release_device; 128 dev->dev.release = &pnp_release_device;
118 dev->status = PNP_READY; 129 dev->status = PNP_READY;
119 spin_lock(&pnp_lock); 130 spin_lock(&pnp_lock);
diff --git a/drivers/pnp/pnpacpi/core.c b/drivers/pnp/pnpacpi/core.c
index 62eda5d59024..a00548799e98 100644
--- a/drivers/pnp/pnpacpi/core.c
+++ b/drivers/pnp/pnpacpi/core.c
@@ -3,7 +3,7 @@
3 * 3 *
4 * Copyright (c) 2004 Matthieu Castet <castet.matthieu@free.fr> 4 * Copyright (c) 2004 Matthieu Castet <castet.matthieu@free.fr>
5 * Copyright (c) 2004 Li Shaohua <shaohua.li@intel.com> 5 * Copyright (c) 2004 Li Shaohua <shaohua.li@intel.com>
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify it 7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the 8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2, or (at your option) any 9 * Free Software Foundation; either version 2, or (at your option) any
@@ -18,7 +18,7 @@
18 * along with this program; if not, write to the Free Software 18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 */ 20 */
21 21
22#include <linux/acpi.h> 22#include <linux/acpi.h>
23#include <linux/pnp.h> 23#include <linux/pnp.h>
24#include <acpi/acpi_bus.h> 24#include <acpi/acpi_bus.h>
@@ -82,7 +82,7 @@ static void __init pnpidacpi_to_pnpid(char *id, char *str)
82static int pnpacpi_get_resources(struct pnp_dev * dev, struct pnp_resource_table * res) 82static int pnpacpi_get_resources(struct pnp_dev * dev, struct pnp_resource_table * res)
83{ 83{
84 acpi_status status; 84 acpi_status status;
85 status = pnpacpi_parse_allocated_resource((acpi_handle)dev->data, 85 status = pnpacpi_parse_allocated_resource((acpi_handle)dev->data,
86 &dev->res); 86 &dev->res);
87 return ACPI_FAILURE(status) ? -ENODEV : 0; 87 return ACPI_FAILURE(status) ? -ENODEV : 0;
88} 88}
@@ -112,9 +112,9 @@ static int pnpacpi_set_resources(struct pnp_dev * dev, struct pnp_resource_table
112static int pnpacpi_disable_resources(struct pnp_dev *dev) 112static int pnpacpi_disable_resources(struct pnp_dev *dev)
113{ 113{
114 acpi_status status; 114 acpi_status status;
115 115
116 /* acpi_unregister_gsi(pnp_irq(dev, 0)); */ 116 /* acpi_unregister_gsi(pnp_irq(dev, 0)); */
117 status = acpi_evaluate_object((acpi_handle)dev->data, 117 status = acpi_evaluate_object((acpi_handle)dev->data,
118 "_DIS", NULL, NULL); 118 "_DIS", NULL, NULL);
119 return ACPI_FAILURE(status) ? -ENODEV : 0; 119 return ACPI_FAILURE(status) ? -ENODEV : 0;
120} 120}
@@ -167,7 +167,7 @@ static int __init pnpacpi_add_device(struct acpi_device *device)
167 strncpy(dev->name, acpi_device_bid(device), sizeof(dev->name)); 167 strncpy(dev->name, acpi_device_bid(device), sizeof(dev->name));
168 168
169 dev->number = num; 169 dev->number = num;
170 170
171 /* set the initial values for the PnP device */ 171 /* set the initial values for the PnP device */
172 dev_id = kzalloc(sizeof(struct pnp_id), GFP_KERNEL); 172 dev_id = kzalloc(sizeof(struct pnp_id), GFP_KERNEL);
173 if (!dev_id) 173 if (!dev_id)
@@ -185,14 +185,14 @@ static int __init pnpacpi_add_device(struct acpi_device *device)
185 } 185 }
186 186
187 if(dev->capabilities & PNP_CONFIGURABLE) { 187 if(dev->capabilities & PNP_CONFIGURABLE) {
188 status = pnpacpi_parse_resource_option_data(device->handle, 188 status = pnpacpi_parse_resource_option_data(device->handle,
189 dev); 189 dev);
190 if (ACPI_FAILURE(status) && (status != AE_NOT_FOUND)) { 190 if (ACPI_FAILURE(status) && (status != AE_NOT_FOUND)) {
191 pnp_err("PnPACPI: METHOD_NAME__PRS failure for %s", dev_id->id); 191 pnp_err("PnPACPI: METHOD_NAME__PRS failure for %s", dev_id->id);
192 goto err1; 192 goto err1;
193 } 193 }
194 } 194 }
195 195
196 /* parse compatible ids */ 196 /* parse compatible ids */
197 if (device->flags.compatible_ids) { 197 if (device->flags.compatible_ids) {
198 struct acpi_compatible_id_list *cid_list = device->pnp.cid_list; 198 struct acpi_compatible_id_list *cid_list = device->pnp.cid_list;
@@ -236,6 +236,42 @@ static acpi_status __init pnpacpi_add_device_handler(acpi_handle handle,
236 return AE_OK; 236 return AE_OK;
237} 237}
238 238
239static int __init acpi_pnp_match(struct device *dev, void *_pnp)
240{
241 struct acpi_device *acpi = to_acpi_device(dev);
242 struct pnp_dev *pnp = _pnp;
243
244 /* true means it matched */
245 return acpi->flags.hardware_id
246 && !acpi_get_physical_device(acpi->handle)
247 && compare_pnp_id(pnp->id, acpi->pnp.hardware_id);
248}
249
250static int __init acpi_pnp_find_device(struct device *dev, acpi_handle *handle)
251{
252 struct device *adev;
253 struct acpi_device *acpi;
254
255 adev = bus_find_device(&acpi_bus_type, NULL,
256 to_pnp_dev(dev),
257 acpi_pnp_match);
258 if (!adev)
259 return -ENODEV;
260
261 acpi = to_acpi_device(adev);
262 *handle = acpi->handle;
263 put_device(adev);
264 return 0;
265}
266
267/* complete initialization of a PNPACPI device includes having
268 * pnpdev->dev.archdata.acpi_handle point to its ACPI sibling.
269 */
270static struct acpi_bus_type __initdata acpi_pnp_bus = {
271 .bus = &pnp_bus_type,
272 .find_device = acpi_pnp_find_device,
273};
274
239int pnpacpi_disabled __initdata; 275int pnpacpi_disabled __initdata;
240static int __init pnpacpi_init(void) 276static int __init pnpacpi_init(void)
241{ 277{
@@ -245,8 +281,11 @@ static int __init pnpacpi_init(void)
245 } 281 }
246 pnp_info("PnP ACPI init"); 282 pnp_info("PnP ACPI init");
247 pnp_register_protocol(&pnpacpi_protocol); 283 pnp_register_protocol(&pnpacpi_protocol);
284 register_acpi_bus_type(&acpi_pnp_bus);
248 acpi_get_devices(NULL, pnpacpi_add_device_handler, NULL, NULL); 285 acpi_get_devices(NULL, pnpacpi_add_device_handler, NULL, NULL);
249 pnp_info("PnP ACPI: found %d devices", num); 286 pnp_info("PnP ACPI: found %d devices", num);
287 unregister_acpi_bus_type(&acpi_pnp_bus);
288 pnp_platform_devices = 1;
250 return 0; 289 return 0;
251} 290}
252subsys_initcall(pnpacpi_init); 291subsys_initcall(pnpacpi_init);
diff --git a/drivers/pnp/pnpbios/core.c b/drivers/pnp/pnpbios/core.c
index 95738dbd5d45..3a201b77b963 100644
--- a/drivers/pnp/pnpbios/core.c
+++ b/drivers/pnp/pnpbios/core.c
@@ -62,6 +62,7 @@
62#include <linux/delay.h> 62#include <linux/delay.h>
63#include <linux/acpi.h> 63#include <linux/acpi.h>
64#include <linux/freezer.h> 64#include <linux/freezer.h>
65#include <linux/kthread.h>
65 66
66#include <asm/page.h> 67#include <asm/page.h>
67#include <asm/desc.h> 68#include <asm/desc.h>
@@ -159,9 +160,7 @@ static int pnp_dock_thread(void * unused)
159{ 160{
160 static struct pnp_docking_station_info now; 161 static struct pnp_docking_station_info now;
161 int docked = -1, d = 0; 162 int docked = -1, d = 0;
162 daemonize("kpnpbiosd"); 163 while (!unloading)
163 allow_signal(SIGKILL);
164 while(!unloading && !signal_pending(current))
165 { 164 {
166 int status; 165 int status;
167 166
@@ -170,11 +169,8 @@ static int pnp_dock_thread(void * unused)
170 */ 169 */
171 msleep_interruptible(2000); 170 msleep_interruptible(2000);
172 171
173 if(signal_pending(current)) { 172 if (try_to_freeze())
174 if (try_to_freeze()) 173 continue;
175 continue;
176 break;
177 }
178 174
179 status = pnp_bios_dock_station_info(&now); 175 status = pnp_bios_dock_station_info(&now);
180 176
@@ -574,6 +570,7 @@ static int __init pnpbios_init(void)
574 /* scan for pnpbios devices */ 570 /* scan for pnpbios devices */
575 build_devlist(); 571 build_devlist();
576 572
573 pnp_platform_devices = 1;
577 return 0; 574 return 0;
578} 575}
579 576
@@ -581,6 +578,7 @@ subsys_initcall(pnpbios_init);
581 578
582static int __init pnpbios_thread_init(void) 579static int __init pnpbios_thread_init(void)
583{ 580{
581 struct task_struct *task;
584#if defined(CONFIG_PPC_MERGE) 582#if defined(CONFIG_PPC_MERGE)
585 if (check_legacy_ioport(PNPBIOS_BASE)) 583 if (check_legacy_ioport(PNPBIOS_BASE))
586 return 0; 584 return 0;
@@ -589,7 +587,8 @@ static int __init pnpbios_thread_init(void)
589 return 0; 587 return 0;
590#ifdef CONFIG_HOTPLUG 588#ifdef CONFIG_HOTPLUG
591 init_completion(&unload_sem); 589 init_completion(&unload_sem);
592 if (kernel_thread(pnp_dock_thread, NULL, CLONE_KERNEL) > 0) 590 task = kthread_run(pnp_dock_thread, NULL, "kpnpbiosd");
591 if (!IS_ERR(task))
593 unloading = 0; 592 unloading = 0;
594#endif 593#endif
595 return 0; 594 return 0;
diff --git a/drivers/pnp/quirks.c b/drivers/pnp/quirks.c
index e97ecefe8584..277df50c89ae 100644
--- a/drivers/pnp/quirks.c
+++ b/drivers/pnp/quirks.c
@@ -16,6 +16,7 @@
16#include <linux/string.h> 16#include <linux/string.h>
17#include <linux/slab.h> 17#include <linux/slab.h>
18#include <linux/pnp.h> 18#include <linux/pnp.h>
19#include <linux/io.h>
19#include "base.h" 20#include "base.h"
20 21
21 22
@@ -106,6 +107,34 @@ static void quirk_sb16audio_resources(struct pnp_dev *dev)
106 return; 107 return;
107} 108}
108 109
110static void quirk_smc_enable(struct pnp_dev *dev)
111{
112 unsigned int firbase;
113
114 if (!dev->active || !pnp_port_valid(dev, 1))
115 return;
116
117 /*
118 * On the HP/Compaq nw8240 (and probably other similar machines),
119 * there is an SMCF010 device with two I/O port regions:
120 *
121 * 0x3e8-0x3ef SIR
122 * 0x100-0x10f FIR
123 *
124 * _STA reports the device is enabled, but in fact, the BIOS
125 * neglects to enable the FIR range. Fortunately, it does fully
126 * enable the device if we call _SRS.
127 */
128 firbase = pnp_port_start(dev, 1);
129 if (inb(firbase + 0x7 /* IRCC_MASTER */) == 0xff) {
130 pnp_err("%s (%s) enabled but not responding, disabling and "
131 "re-enabling", dev->dev.bus_id, pnp_dev_name(dev));
132 pnp_disable_dev(dev);
133 pnp_activate_dev(dev);
134 }
135}
136
137
109/* 138/*
110 * PnP Quirks 139 * PnP Quirks
111 * Cards or devices that need some tweaking due to incomplete resource info 140 * Cards or devices that need some tweaking due to incomplete resource info
@@ -126,6 +155,7 @@ static struct pnp_fixup pnp_fixups[] = {
126 { "CTL0043", quirk_sb16audio_resources }, 155 { "CTL0043", quirk_sb16audio_resources },
127 { "CTL0044", quirk_sb16audio_resources }, 156 { "CTL0044", quirk_sb16audio_resources },
128 { "CTL0045", quirk_sb16audio_resources }, 157 { "CTL0045", quirk_sb16audio_resources },
158 { "SMCf010", quirk_smc_enable },
129 { "" } 159 { "" }
130}; 160};
131 161
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
index ef1eae98ba44..5e439836db2d 100644
--- a/drivers/rtc/Kconfig
+++ b/drivers/rtc/Kconfig
@@ -21,21 +21,31 @@ config RTC_CLASS
21 will be called rtc-class. 21 will be called rtc-class.
22 22
23config RTC_HCTOSYS 23config RTC_HCTOSYS
24 bool "Set system time from RTC on startup" 24 bool "Set system time from RTC on startup and resume"
25 depends on RTC_CLASS = y 25 depends on RTC_CLASS = y
26 default y 26 default y
27 help 27 help
28 If you say yes here, the system time will be set using 28 If you say yes here, the system time (wall clock) will be set using
29 the value read from the specified RTC device. This is useful 29 the value read from a specified RTC device. This is useful to avoid
30 in order to avoid unnecessary fsck runs. 30 unnecessary fsck runs at boot time, and to network better.
31 31
32config RTC_HCTOSYS_DEVICE 32config RTC_HCTOSYS_DEVICE
33 string "The RTC to read the time from" 33 string "RTC used to set the system time"
34 depends on RTC_HCTOSYS = y 34 depends on RTC_HCTOSYS = y
35 default "rtc0" 35 default "rtc0"
36 help 36 help
37 The RTC device that will be used as the source for 37 The RTC device that will be used to (re)initialize the system
38 the system time, usually rtc0. 38 clock, usually rtc0. Initialization is done when the system
39 starts up, and when it resumes from a low power state.
40
41 This clock should be battery-backed, so that it reads the correct
42 time when the system boots from a power-off state. Otherwise, your
43 system will need an external clock source (like an NTP server).
44
45 If the clock you specify here is not battery backed, it may still
46 be useful to reinitialize system time when resuming from system
47 sleep states. Do not specify an RTC here unless it stays powered
48 during all this system's supported sleep states.
39 49
40config RTC_DEBUG 50config RTC_DEBUG
41 bool "RTC debug support" 51 bool "RTC debug support"
@@ -48,7 +58,7 @@ comment "RTC interfaces"
48 depends on RTC_CLASS 58 depends on RTC_CLASS
49 59
50config RTC_INTF_SYSFS 60config RTC_INTF_SYSFS
51 tristate "sysfs" 61 boolean "sysfs"
52 depends on RTC_CLASS && SYSFS 62 depends on RTC_CLASS && SYSFS
53 default RTC_CLASS 63 default RTC_CLASS
54 help 64 help
@@ -59,7 +69,7 @@ config RTC_INTF_SYSFS
59 will be called rtc-sysfs. 69 will be called rtc-sysfs.
60 70
61config RTC_INTF_PROC 71config RTC_INTF_PROC
62 tristate "proc" 72 boolean "proc"
63 depends on RTC_CLASS && PROC_FS 73 depends on RTC_CLASS && PROC_FS
64 default RTC_CLASS 74 default RTC_CLASS
65 help 75 help
@@ -71,7 +81,7 @@ config RTC_INTF_PROC
71 will be called rtc-proc. 81 will be called rtc-proc.
72 82
73config RTC_INTF_DEV 83config RTC_INTF_DEV
74 tristate "dev" 84 boolean "dev"
75 depends on RTC_CLASS 85 depends on RTC_CLASS
76 default RTC_CLASS 86 default RTC_CLASS
77 help 87 help
@@ -92,44 +102,26 @@ config RTC_INTF_DEV_UIE_EMUL
92 driver does not expose RTC_UIE ioctls. Those requests generate 102 driver does not expose RTC_UIE ioctls. Those requests generate
93 once-per-second update interrupts, used for synchronization. 103 once-per-second update interrupts, used for synchronization.
94 104
95comment "RTC drivers" 105config RTC_DRV_TEST
106 tristate "Test driver/device"
96 depends on RTC_CLASS 107 depends on RTC_CLASS
97
98# this 'CMOS' RTC driver is arch dependent because <asm-generic/rtc.h>
99# requires <asm/mc146818rtc.h> defining CMOS_READ/CMOS_WRITE, and a
100# global rtc_lock ... it's not yet just another platform_device.
101
102config RTC_DRV_CMOS
103 tristate "PC-style 'CMOS' real time clock"
104 depends on RTC_CLASS && (X86 || ALPHA || ARM26 || ARM \
105 || M32R || ATARI || POWERPC)
106 help
107 Say "yes" here to get direct support for the real time clock
108 found in every PC or ACPI-based system, and some other boards.
109 Specifically the original MC146818, compatibles like those in
110 PC south bridges, the DS12887 or M48T86, some multifunction
111 or LPC bus chips, and so on.
112
113 Your system will need to define the platform device used by
114 this driver, otherwise it won't be accessible. This means
115 you can safely enable this driver if you don't know whether
116 or not your board has this kind of hardware.
117
118 This driver can also be built as a module. If so, the module
119 will be called rtc-cmos.
120
121config RTC_DRV_X1205
122 tristate "Xicor/Intersil X1205"
123 depends on RTC_CLASS && I2C
124 help 108 help
125 If you say yes here you get support for the 109 If you say yes here you get support for the
126 Xicor/Intersil X1205 RTC chip. 110 RTC test driver. It's a software RTC which can be
111 used to test the RTC subsystem APIs. It gets
112 the time from the system clock.
113 You want this driver only if you are doing development
114 on the RTC subsystem. Please read the source code
115 for further details.
127 116
128 This driver can also be built as a module. If so, the module 117 This driver can also be built as a module. If so, the module
129 will be called rtc-x1205. 118 will be called rtc-test.
119
120comment "I2C RTC drivers"
121 depends on RTC_CLASS
130 122
131config RTC_DRV_DS1307 123config RTC_DRV_DS1307
132 tristate "Dallas/Maxim DS1307 and similar I2C RTC chips" 124 tristate "Dallas/Maxim DS1307/37/38/39/40, ST M41T00"
133 depends on RTC_CLASS && I2C 125 depends on RTC_CLASS && I2C
134 help 126 help
135 If you say yes here you get support for various compatible RTC 127 If you say yes here you get support for various compatible RTC
@@ -146,53 +138,55 @@ config RTC_DRV_DS1307
146 This driver can also be built as a module. If so, the module 138 This driver can also be built as a module. If so, the module
147 will be called rtc-ds1307. 139 will be called rtc-ds1307.
148 140
149config RTC_DRV_DS1553 141config RTC_DRV_DS1672
150 tristate "Dallas DS1553" 142 tristate "Dallas/Maxim DS1672"
151 depends on RTC_CLASS 143 depends on RTC_CLASS && I2C
152 help 144 help
153 If you say yes here you get support for the 145 If you say yes here you get support for the
154 Dallas DS1553 timekeeping chip. 146 Dallas/Maxim DS1672 timekeeping chip.
155 147
156 This driver can also be built as a module. If so, the module 148 This driver can also be built as a module. If so, the module
157 will be called rtc-ds1553. 149 will be called rtc-ds1672.
158 150
159config RTC_DRV_ISL1208 151config RTC_DRV_MAX6900
160 tristate "Intersil 1208" 152 tristate "Maxim 6900"
161 depends on RTC_CLASS && I2C 153 depends on RTC_CLASS && I2C
162 help 154 help
163 If you say yes here you get support for the 155 If you say yes here you will get support for the
164 Intersil 1208 RTC chip. 156 Maxim MAX6900 I2C RTC chip.
165 157
166 This driver can also be built as a module. If so, the module 158 This driver can also be built as a module. If so, the module
167 will be called rtc-isl1208. 159 will be called rtc-max6900.
168 160
169config RTC_DRV_DS1672 161config RTC_DRV_RS5C372
170 tristate "Dallas/Maxim DS1672" 162 tristate "Ricoh RS5C372A/B"
171 depends on RTC_CLASS && I2C 163 depends on RTC_CLASS && I2C
172 help 164 help
173 If you say yes here you get support for the 165 If you say yes here you get support for the
174 Dallas/Maxim DS1672 timekeeping chip. 166 Ricoh RS5C372A and RS5C372B RTC chips.
175 167
176 This driver can also be built as a module. If so, the module 168 This driver can also be built as a module. If so, the module
177 will be called rtc-ds1672. 169 will be called rtc-rs5c372.
178 170
179config RTC_DRV_DS1742 171config RTC_DRV_ISL1208
180 tristate "Dallas DS1742/1743" 172 tristate "Intersil 1208"
181 depends on RTC_CLASS 173 depends on RTC_CLASS && I2C
182 help 174 help
183 If you say yes here you get support for the 175 If you say yes here you get support for the
184 Dallas DS1742/1743 timekeeping chip. 176 Intersil 1208 RTC chip.
185 177
186 This driver can also be built as a module. If so, the module 178 This driver can also be built as a module. If so, the module
187 will be called rtc-ds1742. 179 will be called rtc-isl1208.
188 180
189config RTC_DRV_OMAP 181config RTC_DRV_X1205
190 tristate "TI OMAP1" 182 tristate "Xicor/Intersil X1205"
191 depends on RTC_CLASS && ( \ 183 depends on RTC_CLASS && I2C
192 ARCH_OMAP15XX || ARCH_OMAP16XX || ARCH_OMAP730 )
193 help 184 help
194 Say "yes" here to support the real time clock on TI OMAP1 chips. 185 If you say yes here you get support for the
195 This driver can also be built as a module called rtc-omap. 186 Xicor/Intersil X1205 RTC chip.
187
188 This driver can also be built as a module. If so, the module
189 will be called rtc-x1205.
196 190
197config RTC_DRV_PCF8563 191config RTC_DRV_PCF8563
198 tristate "Philips PCF8563/Epson RTC8564" 192 tristate "Philips PCF8563/Epson RTC8564"
@@ -207,16 +201,20 @@ config RTC_DRV_PCF8563
207 201
208config RTC_DRV_PCF8583 202config RTC_DRV_PCF8583
209 tristate "Philips PCF8583" 203 tristate "Philips PCF8583"
210 depends on RTC_CLASS && I2C && ARCH_RPC 204 depends on RTC_CLASS && I2C
211 help 205 help
212 If you say yes here you get support for the Philips PCF8583 206 If you say yes here you get support for the Philips PCF8583
213 RTC chip found on Acorn RiscPCs. This driver supports the 207 RTC chip found on Acorn RiscPCs. This driver supports the
214 platform specific method of retrieving the current year from 208 platform specific method of retrieving the current year from
215 the RTC's SRAM. 209 the RTC's SRAM. It will work on other platforms with the same
210 chip, but the year will probably have to be tweaked.
216 211
217 This driver can also be built as a module. If so, the module 212 This driver can also be built as a module. If so, the module
218 will be called rtc-pcf8583. 213 will be called rtc-pcf8583.
219 214
215comment "SPI RTC drivers"
216 depends on RTC_CLASS
217
220config RTC_DRV_RS5C348 218config RTC_DRV_RS5C348
221 tristate "Ricoh RS5C348A/B" 219 tristate "Ricoh RS5C348A/B"
222 depends on RTC_CLASS && SPI 220 depends on RTC_CLASS && SPI
@@ -227,15 +225,92 @@ config RTC_DRV_RS5C348
227 This driver can also be built as a module. If so, the module 225 This driver can also be built as a module. If so, the module
228 will be called rtc-rs5c348. 226 will be called rtc-rs5c348.
229 227
230config RTC_DRV_RS5C372 228config RTC_DRV_MAX6902
231 tristate "Ricoh RS5C372A/B" 229 tristate "Maxim 6902"
232 depends on RTC_CLASS && I2C 230 depends on RTC_CLASS && SPI
231 help
232 If you say yes here you will get support for the
233 Maxim MAX6902 SPI RTC chip.
234
235 This driver can also be built as a module. If so, the module
236 will be called rtc-max6902.
237
238comment "Platform RTC drivers"
239 depends on RTC_CLASS
240
241# this 'CMOS' RTC driver is arch dependent because <asm-generic/rtc.h>
242# requires <asm/mc146818rtc.h> defining CMOS_READ/CMOS_WRITE, and a
243# global rtc_lock ... it's not yet just another platform_device.
244
245config RTC_DRV_CMOS
246 tristate "PC-style 'CMOS'"
247 depends on RTC_CLASS && (X86 || ALPHA || ARM26 || ARM \
248 || M32R || ATARI || POWERPC)
249 help
250 Say "yes" here to get direct support for the real time clock
251 found in every PC or ACPI-based system, and some other boards.
252 Specifically the original MC146818, compatibles like those in
253 PC south bridges, the DS12887 or M48T86, some multifunction
254 or LPC bus chips, and so on.
255
256 Your system will need to define the platform device used by
257 this driver, otherwise it won't be accessible. This means
258 you can safely enable this driver if you don't know whether
259 or not your board has this kind of hardware.
260
261 This driver can also be built as a module. If so, the module
262 will be called rtc-cmos.
263
264config RTC_DRV_DS1553
265 tristate "Dallas DS1553"
266 depends on RTC_CLASS
233 help 267 help
234 If you say yes here you get support for the 268 If you say yes here you get support for the
235 Ricoh RS5C372A and RS5C372B RTC chips. 269 Dallas DS1553 timekeeping chip.
236 270
237 This driver can also be built as a module. If so, the module 271 This driver can also be built as a module. If so, the module
238 will be called rtc-rs5c372. 272 will be called rtc-ds1553.
273
274config RTC_DRV_DS1742
275 tristate "Dallas DS1742/1743"
276 depends on RTC_CLASS
277 help
278 If you say yes here you get support for the
279 Dallas DS1742/1743 timekeeping chip.
280
281 This driver can also be built as a module. If so, the module
282 will be called rtc-ds1742.
283
284config RTC_DRV_M48T86
285 tristate "ST M48T86/Dallas DS12887"
286 depends on RTC_CLASS
287 help
288 If you say Y here you will get support for the
289 ST M48T86 and Dallas DS12887 RTC chips.
290
291 This driver can also be built as a module. If so, the module
292 will be called rtc-m48t86.
293
294config RTC_DRV_V3020
295 tristate "EM Microelectronic V3020"
296 depends on RTC_CLASS
297 help
298 If you say yes here you will get support for the
299 EM Microelectronic v3020 RTC chip.
300
301 This driver can also be built as a module. If so, the module
302 will be called rtc-v3020.
303
304comment "on-CPU RTC drivers"
305 depends on RTC_CLASS
306
307config RTC_DRV_OMAP
308 tristate "TI OMAP1"
309 depends on RTC_CLASS && ( \
310 ARCH_OMAP15XX || ARCH_OMAP16XX || ARCH_OMAP730 )
311 help
312 Say "yes" here to support the real time clock on TI OMAP1 chips.
313 This driver can also be built as a module called rtc-omap.
239 314
240config RTC_DRV_S3C 315config RTC_DRV_S3C
241 tristate "Samsung S3C series SoC RTC" 316 tristate "Samsung S3C series SoC RTC"
@@ -253,16 +328,6 @@ config RTC_DRV_S3C
253 This driver can also be build as a module. If so, the module 328 This driver can also be build as a module. If so, the module
254 will be called rtc-s3c. 329 will be called rtc-s3c.
255 330
256config RTC_DRV_M48T86
257 tristate "ST M48T86/Dallas DS12887"
258 depends on RTC_CLASS
259 help
260 If you say Y here you will get support for the
261 ST M48T86 and Dallas DS12887 RTC chips.
262
263 This driver can also be built as a module. If so, the module
264 will be called rtc-m48t86.
265
266config RTC_DRV_EP93XX 331config RTC_DRV_EP93XX
267 tristate "Cirrus Logic EP93XX" 332 tristate "Cirrus Logic EP93XX"
268 depends on RTC_CLASS && ARCH_EP93XX 333 depends on RTC_CLASS && ARCH_EP93XX
@@ -308,7 +373,7 @@ config RTC_DRV_PL031
308 depends on RTC_CLASS && ARM_AMBA 373 depends on RTC_CLASS && ARM_AMBA
309 help 374 help
310 If you say Y here you will get access to ARM AMBA 375 If you say Y here you will get access to ARM AMBA
311 PrimeCell PL031 UART found on certain ARM SOCs. 376 PrimeCell PL031 RTC found on certain ARM SOCs.
312 377
313 To compile this driver as a module, choose M here: the 378 To compile this driver as a module, choose M here: the
314 module will be called rtc-pl031. 379 module will be called rtc-pl031.
@@ -319,41 +384,6 @@ config RTC_DRV_AT91RM9200
319 help 384 help
320 Driver for the Atmel AT91RM9200's internal RTC (Realtime Clock). 385 Driver for the Atmel AT91RM9200's internal RTC (Realtime Clock).
321 386
322config RTC_DRV_TEST
323 tristate "Test driver/device"
324 depends on RTC_CLASS
325 help
326 If you say yes here you get support for the
327 RTC test driver. It's a software RTC which can be
328 used to test the RTC subsystem APIs. It gets
329 the time from the system clock.
330 You want this driver only if you are doing development
331 on the RTC subsystem. Please read the source code
332 for further details.
333
334 This driver can also be built as a module. If so, the module
335 will be called rtc-test.
336
337config RTC_DRV_MAX6902
338 tristate "Maxim 6902"
339 depends on RTC_CLASS && SPI
340 help
341 If you say yes here you will get support for the
342 Maxim MAX6902 spi RTC chip.
343
344 This driver can also be built as a module. If so, the module
345 will be called rtc-max6902.
346
347config RTC_DRV_V3020
348 tristate "EM Microelectronic V3020"
349 depends on RTC_CLASS
350 help
351 If you say yes here you will get support for the
352 EM Microelectronic v3020 RTC chip.
353
354 This driver can also be built as a module. If so, the module
355 will be called rtc-v3020.
356
357config RTC_DRV_BFIN 387config RTC_DRV_BFIN
358 tristate "Blackfin On-Chip RTC" 388 tristate "Blackfin On-Chip RTC"
359 depends on RTC_CLASS && BFIN 389 depends on RTC_CLASS && BFIN
@@ -364,4 +394,10 @@ config RTC_DRV_BFIN
364 This driver can also be built as a module. If so, the module 394 This driver can also be built as a module. If so, the module
365 will be called rtc-bfin. 395 will be called rtc-bfin.
366 396
397config RTC_DRV_RS5C313
398 tristate "Ricoh RS5C313"
399 depends on RTC_CLASS && BROKEN
400 help
401 If you say yes here you get support for the Ricoh RS5C313 RTC chips.
402
367endmenu 403endmenu
diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile
index 9218cf28d6ed..a1afbc236073 100644
--- a/drivers/rtc/Makefile
+++ b/drivers/rtc/Makefile
@@ -11,9 +11,9 @@ obj-$(CONFIG_RTC_HCTOSYS) += hctosys.o
11obj-$(CONFIG_RTC_CLASS) += rtc-core.o 11obj-$(CONFIG_RTC_CLASS) += rtc-core.o
12rtc-core-y := class.o interface.o 12rtc-core-y := class.o interface.o
13 13
14obj-$(CONFIG_RTC_INTF_SYSFS) += rtc-sysfs.o 14rtc-core-$(CONFIG_RTC_INTF_DEV) += rtc-dev.o
15obj-$(CONFIG_RTC_INTF_PROC) += rtc-proc.o 15rtc-core-$(CONFIG_RTC_INTF_PROC) += rtc-proc.o
16obj-$(CONFIG_RTC_INTF_DEV) += rtc-dev.o 16rtc-core-$(CONFIG_RTC_INTF_SYSFS) += rtc-sysfs.o
17 17
18obj-$(CONFIG_RTC_DRV_CMOS) += rtc-cmos.o 18obj-$(CONFIG_RTC_DRV_CMOS) += rtc-cmos.o
19obj-$(CONFIG_RTC_DRV_X1205) += rtc-x1205.o 19obj-$(CONFIG_RTC_DRV_X1205) += rtc-x1205.o
@@ -30,10 +30,12 @@ obj-$(CONFIG_RTC_DRV_S3C) += rtc-s3c.o
30obj-$(CONFIG_RTC_DRV_RS5C348) += rtc-rs5c348.o 30obj-$(CONFIG_RTC_DRV_RS5C348) += rtc-rs5c348.o
31obj-$(CONFIG_RTC_DRV_M48T86) += rtc-m48t86.o 31obj-$(CONFIG_RTC_DRV_M48T86) += rtc-m48t86.o
32obj-$(CONFIG_RTC_DRV_DS1553) += rtc-ds1553.o 32obj-$(CONFIG_RTC_DRV_DS1553) += rtc-ds1553.o
33obj-$(CONFIG_RTC_DRV_RS5C313) += rtc-rs5c313.o
33obj-$(CONFIG_RTC_DRV_EP93XX) += rtc-ep93xx.o 34obj-$(CONFIG_RTC_DRV_EP93XX) += rtc-ep93xx.o
34obj-$(CONFIG_RTC_DRV_SA1100) += rtc-sa1100.o 35obj-$(CONFIG_RTC_DRV_SA1100) += rtc-sa1100.o
35obj-$(CONFIG_RTC_DRV_VR41XX) += rtc-vr41xx.o 36obj-$(CONFIG_RTC_DRV_VR41XX) += rtc-vr41xx.o
36obj-$(CONFIG_RTC_DRV_PL031) += rtc-pl031.o 37obj-$(CONFIG_RTC_DRV_PL031) += rtc-pl031.o
38obj-$(CONFIG_RTC_DRV_MAX6900) += rtc-max6900.o
37obj-$(CONFIG_RTC_DRV_MAX6902) += rtc-max6902.o 39obj-$(CONFIG_RTC_DRV_MAX6902) += rtc-max6902.o
38obj-$(CONFIG_RTC_DRV_V3020) += rtc-v3020.o 40obj-$(CONFIG_RTC_DRV_V3020) += rtc-v3020.o
39obj-$(CONFIG_RTC_DRV_AT91RM9200)+= rtc-at91rm9200.o 41obj-$(CONFIG_RTC_DRV_AT91RM9200)+= rtc-at91rm9200.o
diff --git a/drivers/rtc/class.c b/drivers/rtc/class.c
index 04aaa6347234..8b3cd31d6a61 100644
--- a/drivers/rtc/class.c
+++ b/drivers/rtc/class.c
@@ -16,19 +16,94 @@
16#include <linux/kdev_t.h> 16#include <linux/kdev_t.h>
17#include <linux/idr.h> 17#include <linux/idr.h>
18 18
19#include "rtc-core.h"
20
21
19static DEFINE_IDR(rtc_idr); 22static DEFINE_IDR(rtc_idr);
20static DEFINE_MUTEX(idr_lock); 23static DEFINE_MUTEX(idr_lock);
21struct class *rtc_class; 24struct class *rtc_class;
22 25
23static void rtc_device_release(struct class_device *class_dev) 26static void rtc_device_release(struct device *dev)
24{ 27{
25 struct rtc_device *rtc = to_rtc_device(class_dev); 28 struct rtc_device *rtc = to_rtc_device(dev);
26 mutex_lock(&idr_lock); 29 mutex_lock(&idr_lock);
27 idr_remove(&rtc_idr, rtc->id); 30 idr_remove(&rtc_idr, rtc->id);
28 mutex_unlock(&idr_lock); 31 mutex_unlock(&idr_lock);
29 kfree(rtc); 32 kfree(rtc);
30} 33}
31 34
35#if defined(CONFIG_PM) && defined(CONFIG_RTC_HCTOSYS_DEVICE)
36
37/*
38 * On suspend(), measure the delta between one RTC and the
39 * system's wall clock; restore it on resume().
40 */
41
42static struct timespec delta;
43static time_t oldtime;
44
45static int rtc_suspend(struct device *dev, pm_message_t mesg)
46{
47 struct rtc_device *rtc = to_rtc_device(dev);
48 struct rtc_time tm;
49
50 if (strncmp(rtc->dev.bus_id,
51 CONFIG_RTC_HCTOSYS_DEVICE,
52 BUS_ID_SIZE) != 0)
53 return 0;
54
55 rtc_read_time(rtc, &tm);
56 rtc_tm_to_time(&tm, &oldtime);
57
58 /* RTC precision is 1 second; adjust delta for avg 1/2 sec err */
59 set_normalized_timespec(&delta,
60 xtime.tv_sec - oldtime,
61 xtime.tv_nsec - (NSEC_PER_SEC >> 1));
62
63 return 0;
64}
65
66static int rtc_resume(struct device *dev)
67{
68 struct rtc_device *rtc = to_rtc_device(dev);
69 struct rtc_time tm;
70 time_t newtime;
71 struct timespec time;
72
73 if (strncmp(rtc->dev.bus_id,
74 CONFIG_RTC_HCTOSYS_DEVICE,
75 BUS_ID_SIZE) != 0)
76 return 0;
77
78 rtc_read_time(rtc, &tm);
79 if (rtc_valid_tm(&tm) != 0) {
80 pr_debug("%s: bogus resume time\n", rtc->dev.bus_id);
81 return 0;
82 }
83 rtc_tm_to_time(&tm, &newtime);
84 if (newtime <= oldtime) {
85 if (newtime < oldtime)
86 pr_debug("%s: time travel!\n", rtc->dev.bus_id);
87 return 0;
88 }
89
90 /* restore wall clock using delta against this RTC;
91 * adjust again for avg 1/2 second RTC sampling error
92 */
93 set_normalized_timespec(&time,
94 newtime + delta.tv_sec,
95 (NSEC_PER_SEC >> 1) + delta.tv_nsec);
96 do_settimeofday(&time);
97
98 return 0;
99}
100
101#else
102#define rtc_suspend NULL
103#define rtc_resume NULL
104#endif
105
106
32/** 107/**
33 * rtc_device_register - register w/ RTC class 108 * rtc_device_register - register w/ RTC class
34 * @dev: the device to register 109 * @dev: the device to register
@@ -70,23 +145,29 @@ struct rtc_device *rtc_device_register(const char *name, struct device *dev,
70 rtc->ops = ops; 145 rtc->ops = ops;
71 rtc->owner = owner; 146 rtc->owner = owner;
72 rtc->max_user_freq = 64; 147 rtc->max_user_freq = 64;
73 rtc->class_dev.dev = dev; 148 rtc->dev.parent = dev;
74 rtc->class_dev.class = rtc_class; 149 rtc->dev.class = rtc_class;
75 rtc->class_dev.release = rtc_device_release; 150 rtc->dev.release = rtc_device_release;
76 151
77 mutex_init(&rtc->ops_lock); 152 mutex_init(&rtc->ops_lock);
78 spin_lock_init(&rtc->irq_lock); 153 spin_lock_init(&rtc->irq_lock);
79 spin_lock_init(&rtc->irq_task_lock); 154 spin_lock_init(&rtc->irq_task_lock);
80 155
81 strlcpy(rtc->name, name, RTC_DEVICE_NAME_SIZE); 156 strlcpy(rtc->name, name, RTC_DEVICE_NAME_SIZE);
82 snprintf(rtc->class_dev.class_id, BUS_ID_SIZE, "rtc%d", id); 157 snprintf(rtc->dev.bus_id, BUS_ID_SIZE, "rtc%d", id);
83 158
84 err = class_device_register(&rtc->class_dev); 159 rtc_dev_prepare(rtc);
160
161 err = device_register(&rtc->dev);
85 if (err) 162 if (err)
86 goto exit_kfree; 163 goto exit_kfree;
87 164
165 rtc_dev_add_device(rtc);
166 rtc_sysfs_add_device(rtc);
167 rtc_proc_add_device(rtc);
168
88 dev_info(dev, "rtc core: registered %s as %s\n", 169 dev_info(dev, "rtc core: registered %s as %s\n",
89 rtc->name, rtc->class_dev.class_id); 170 rtc->name, rtc->dev.bus_id);
90 171
91 return rtc; 172 return rtc;
92 173
@@ -113,26 +194,22 @@ EXPORT_SYMBOL_GPL(rtc_device_register);
113 */ 194 */
114void rtc_device_unregister(struct rtc_device *rtc) 195void rtc_device_unregister(struct rtc_device *rtc)
115{ 196{
116 if (class_device_get(&rtc->class_dev) != NULL) { 197 if (get_device(&rtc->dev) != NULL) {
117 mutex_lock(&rtc->ops_lock); 198 mutex_lock(&rtc->ops_lock);
118 /* remove innards of this RTC, then disable it, before 199 /* remove innards of this RTC, then disable it, before
119 * letting any rtc_class_open() users access it again 200 * letting any rtc_class_open() users access it again
120 */ 201 */
121 class_device_unregister(&rtc->class_dev); 202 rtc_sysfs_del_device(rtc);
203 rtc_dev_del_device(rtc);
204 rtc_proc_del_device(rtc);
205 device_unregister(&rtc->dev);
122 rtc->ops = NULL; 206 rtc->ops = NULL;
123 mutex_unlock(&rtc->ops_lock); 207 mutex_unlock(&rtc->ops_lock);
124 class_device_put(&rtc->class_dev); 208 put_device(&rtc->dev);
125 } 209 }
126} 210}
127EXPORT_SYMBOL_GPL(rtc_device_unregister); 211EXPORT_SYMBOL_GPL(rtc_device_unregister);
128 212
129int rtc_interface_register(struct class_interface *intf)
130{
131 intf->class = rtc_class;
132 return class_interface_register(intf);
133}
134EXPORT_SYMBOL_GPL(rtc_interface_register);
135
136static int __init rtc_init(void) 213static int __init rtc_init(void)
137{ 214{
138 rtc_class = class_create(THIS_MODULE, "rtc"); 215 rtc_class = class_create(THIS_MODULE, "rtc");
@@ -140,11 +217,16 @@ static int __init rtc_init(void)
140 printk(KERN_ERR "%s: couldn't create class\n", __FILE__); 217 printk(KERN_ERR "%s: couldn't create class\n", __FILE__);
141 return PTR_ERR(rtc_class); 218 return PTR_ERR(rtc_class);
142 } 219 }
220 rtc_class->suspend = rtc_suspend;
221 rtc_class->resume = rtc_resume;
222 rtc_dev_init();
223 rtc_sysfs_init(rtc_class);
143 return 0; 224 return 0;
144} 225}
145 226
146static void __exit rtc_exit(void) 227static void __exit rtc_exit(void)
147{ 228{
229 rtc_dev_exit();
148 class_destroy(rtc_class); 230 class_destroy(rtc_class);
149} 231}
150 232
diff --git a/drivers/rtc/hctosys.c b/drivers/rtc/hctosys.c
index d02fe9a0001f..178527252c6a 100644
--- a/drivers/rtc/hctosys.c
+++ b/drivers/rtc/hctosys.c
@@ -26,15 +26,15 @@ static int __init rtc_hctosys(void)
26{ 26{
27 int err; 27 int err;
28 struct rtc_time tm; 28 struct rtc_time tm;
29 struct class_device *class_dev = rtc_class_open(CONFIG_RTC_HCTOSYS_DEVICE); 29 struct rtc_device *rtc = rtc_class_open(CONFIG_RTC_HCTOSYS_DEVICE);
30 30
31 if (class_dev == NULL) { 31 if (rtc == NULL) {
32 printk("%s: unable to open rtc device (%s)\n", 32 printk("%s: unable to open rtc device (%s)\n",
33 __FILE__, CONFIG_RTC_HCTOSYS_DEVICE); 33 __FILE__, CONFIG_RTC_HCTOSYS_DEVICE);
34 return -ENODEV; 34 return -ENODEV;
35 } 35 }
36 36
37 err = rtc_read_time(class_dev, &tm); 37 err = rtc_read_time(rtc, &tm);
38 if (err == 0) { 38 if (err == 0) {
39 err = rtc_valid_tm(&tm); 39 err = rtc_valid_tm(&tm);
40 if (err == 0) { 40 if (err == 0) {
@@ -46,7 +46,7 @@ static int __init rtc_hctosys(void)
46 46
47 do_settimeofday(&tv); 47 do_settimeofday(&tv);
48 48
49 dev_info(class_dev->dev, 49 dev_info(rtc->dev.parent,
50 "setting the system clock to " 50 "setting the system clock to "
51 "%d-%02d-%02d %02d:%02d:%02d (%u)\n", 51 "%d-%02d-%02d %02d:%02d:%02d (%u)\n",
52 tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, 52 tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,
@@ -54,14 +54,14 @@ static int __init rtc_hctosys(void)
54 (unsigned int) tv.tv_sec); 54 (unsigned int) tv.tv_sec);
55 } 55 }
56 else 56 else
57 dev_err(class_dev->dev, 57 dev_err(rtc->dev.parent,
58 "hctosys: invalid date/time\n"); 58 "hctosys: invalid date/time\n");
59 } 59 }
60 else 60 else
61 dev_err(class_dev->dev, 61 dev_err(rtc->dev.parent,
62 "hctosys: unable to read the hardware clock\n"); 62 "hctosys: unable to read the hardware clock\n");
63 63
64 rtc_class_close(class_dev); 64 rtc_class_close(rtc);
65 65
66 return 0; 66 return 0;
67} 67}
diff --git a/drivers/rtc/interface.c b/drivers/rtc/interface.c
index ef40df0f169d..ad66c6ecf365 100644
--- a/drivers/rtc/interface.c
+++ b/drivers/rtc/interface.c
@@ -13,10 +13,9 @@
13 13
14#include <linux/rtc.h> 14#include <linux/rtc.h>
15 15
16int rtc_read_time(struct class_device *class_dev, struct rtc_time *tm) 16int rtc_read_time(struct rtc_device *rtc, struct rtc_time *tm)
17{ 17{
18 int err; 18 int err;
19 struct rtc_device *rtc = to_rtc_device(class_dev);
20 19
21 err = mutex_lock_interruptible(&rtc->ops_lock); 20 err = mutex_lock_interruptible(&rtc->ops_lock);
22 if (err) 21 if (err)
@@ -28,7 +27,7 @@ int rtc_read_time(struct class_device *class_dev, struct rtc_time *tm)
28 err = -EINVAL; 27 err = -EINVAL;
29 else { 28 else {
30 memset(tm, 0, sizeof(struct rtc_time)); 29 memset(tm, 0, sizeof(struct rtc_time));
31 err = rtc->ops->read_time(class_dev->dev, tm); 30 err = rtc->ops->read_time(rtc->dev.parent, tm);
32 } 31 }
33 32
34 mutex_unlock(&rtc->ops_lock); 33 mutex_unlock(&rtc->ops_lock);
@@ -36,10 +35,9 @@ int rtc_read_time(struct class_device *class_dev, struct rtc_time *tm)
36} 35}
37EXPORT_SYMBOL_GPL(rtc_read_time); 36EXPORT_SYMBOL_GPL(rtc_read_time);
38 37
39int rtc_set_time(struct class_device *class_dev, struct rtc_time *tm) 38int rtc_set_time(struct rtc_device *rtc, struct rtc_time *tm)
40{ 39{
41 int err; 40 int err;
42 struct rtc_device *rtc = to_rtc_device(class_dev);
43 41
44 err = rtc_valid_tm(tm); 42 err = rtc_valid_tm(tm);
45 if (err != 0) 43 if (err != 0)
@@ -54,17 +52,16 @@ int rtc_set_time(struct class_device *class_dev, struct rtc_time *tm)
54 else if (!rtc->ops->set_time) 52 else if (!rtc->ops->set_time)
55 err = -EINVAL; 53 err = -EINVAL;
56 else 54 else
57 err = rtc->ops->set_time(class_dev->dev, tm); 55 err = rtc->ops->set_time(rtc->dev.parent, tm);
58 56
59 mutex_unlock(&rtc->ops_lock); 57 mutex_unlock(&rtc->ops_lock);
60 return err; 58 return err;
61} 59}
62EXPORT_SYMBOL_GPL(rtc_set_time); 60EXPORT_SYMBOL_GPL(rtc_set_time);
63 61
64int rtc_set_mmss(struct class_device *class_dev, unsigned long secs) 62int rtc_set_mmss(struct rtc_device *rtc, unsigned long secs)
65{ 63{
66 int err; 64 int err;
67 struct rtc_device *rtc = to_rtc_device(class_dev);
68 65
69 err = mutex_lock_interruptible(&rtc->ops_lock); 66 err = mutex_lock_interruptible(&rtc->ops_lock);
70 if (err) 67 if (err)
@@ -73,11 +70,11 @@ int rtc_set_mmss(struct class_device *class_dev, unsigned long secs)
73 if (!rtc->ops) 70 if (!rtc->ops)
74 err = -ENODEV; 71 err = -ENODEV;
75 else if (rtc->ops->set_mmss) 72 else if (rtc->ops->set_mmss)
76 err = rtc->ops->set_mmss(class_dev->dev, secs); 73 err = rtc->ops->set_mmss(rtc->dev.parent, secs);
77 else if (rtc->ops->read_time && rtc->ops->set_time) { 74 else if (rtc->ops->read_time && rtc->ops->set_time) {
78 struct rtc_time new, old; 75 struct rtc_time new, old;
79 76
80 err = rtc->ops->read_time(class_dev->dev, &old); 77 err = rtc->ops->read_time(rtc->dev.parent, &old);
81 if (err == 0) { 78 if (err == 0) {
82 rtc_time_to_tm(secs, &new); 79 rtc_time_to_tm(secs, &new);
83 80
@@ -89,7 +86,8 @@ int rtc_set_mmss(struct class_device *class_dev, unsigned long secs)
89 */ 86 */
90 if (!((old.tm_hour == 23 && old.tm_min == 59) || 87 if (!((old.tm_hour == 23 && old.tm_min == 59) ||
91 (new.tm_hour == 23 && new.tm_min == 59))) 88 (new.tm_hour == 23 && new.tm_min == 59)))
92 err = rtc->ops->set_time(class_dev->dev, &new); 89 err = rtc->ops->set_time(rtc->dev.parent,
90 &new);
93 } 91 }
94 } 92 }
95 else 93 else
@@ -101,10 +99,9 @@ int rtc_set_mmss(struct class_device *class_dev, unsigned long secs)
101} 99}
102EXPORT_SYMBOL_GPL(rtc_set_mmss); 100EXPORT_SYMBOL_GPL(rtc_set_mmss);
103 101
104int rtc_read_alarm(struct class_device *class_dev, struct rtc_wkalrm *alarm) 102int rtc_read_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm)
105{ 103{
106 int err; 104 int err;
107 struct rtc_device *rtc = to_rtc_device(class_dev);
108 105
109 err = mutex_lock_interruptible(&rtc->ops_lock); 106 err = mutex_lock_interruptible(&rtc->ops_lock);
110 if (err) 107 if (err)
@@ -116,7 +113,7 @@ int rtc_read_alarm(struct class_device *class_dev, struct rtc_wkalrm *alarm)
116 err = -EINVAL; 113 err = -EINVAL;
117 else { 114 else {
118 memset(alarm, 0, sizeof(struct rtc_wkalrm)); 115 memset(alarm, 0, sizeof(struct rtc_wkalrm));
119 err = rtc->ops->read_alarm(class_dev->dev, alarm); 116 err = rtc->ops->read_alarm(rtc->dev.parent, alarm);
120 } 117 }
121 118
122 mutex_unlock(&rtc->ops_lock); 119 mutex_unlock(&rtc->ops_lock);
@@ -124,10 +121,13 @@ int rtc_read_alarm(struct class_device *class_dev, struct rtc_wkalrm *alarm)
124} 121}
125EXPORT_SYMBOL_GPL(rtc_read_alarm); 122EXPORT_SYMBOL_GPL(rtc_read_alarm);
126 123
127int rtc_set_alarm(struct class_device *class_dev, struct rtc_wkalrm *alarm) 124int rtc_set_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm)
128{ 125{
129 int err; 126 int err;
130 struct rtc_device *rtc = to_rtc_device(class_dev); 127
128 err = rtc_valid_tm(&alarm->time);
129 if (err != 0)
130 return err;
131 131
132 err = mutex_lock_interruptible(&rtc->ops_lock); 132 err = mutex_lock_interruptible(&rtc->ops_lock);
133 if (err) 133 if (err)
@@ -138,7 +138,7 @@ int rtc_set_alarm(struct class_device *class_dev, struct rtc_wkalrm *alarm)
138 else if (!rtc->ops->set_alarm) 138 else if (!rtc->ops->set_alarm)
139 err = -EINVAL; 139 err = -EINVAL;
140 else 140 else
141 err = rtc->ops->set_alarm(class_dev->dev, alarm); 141 err = rtc->ops->set_alarm(rtc->dev.parent, alarm);
142 142
143 mutex_unlock(&rtc->ops_lock); 143 mutex_unlock(&rtc->ops_lock);
144 return err; 144 return err;
@@ -147,16 +147,14 @@ EXPORT_SYMBOL_GPL(rtc_set_alarm);
147 147
148/** 148/**
149 * rtc_update_irq - report RTC periodic, alarm, and/or update irqs 149 * rtc_update_irq - report RTC periodic, alarm, and/or update irqs
150 * @class_dev: the rtc's class device 150 * @rtc: the rtc device
151 * @num: how many irqs are being reported (usually one) 151 * @num: how many irqs are being reported (usually one)
152 * @events: mask of RTC_IRQF with one or more of RTC_PF, RTC_AF, RTC_UF 152 * @events: mask of RTC_IRQF with one or more of RTC_PF, RTC_AF, RTC_UF
153 * Context: in_interrupt(), irqs blocked 153 * Context: in_interrupt(), irqs blocked
154 */ 154 */
155void rtc_update_irq(struct class_device *class_dev, 155void rtc_update_irq(struct rtc_device *rtc,
156 unsigned long num, unsigned long events) 156 unsigned long num, unsigned long events)
157{ 157{
158 struct rtc_device *rtc = to_rtc_device(class_dev);
159
160 spin_lock(&rtc->irq_lock); 158 spin_lock(&rtc->irq_lock);
161 rtc->irq_data = (rtc->irq_data + (num << 8)) | events; 159 rtc->irq_data = (rtc->irq_data + (num << 8)) | events;
162 spin_unlock(&rtc->irq_lock); 160 spin_unlock(&rtc->irq_lock);
@@ -171,40 +169,43 @@ void rtc_update_irq(struct class_device *class_dev,
171} 169}
172EXPORT_SYMBOL_GPL(rtc_update_irq); 170EXPORT_SYMBOL_GPL(rtc_update_irq);
173 171
174struct class_device *rtc_class_open(char *name) 172struct rtc_device *rtc_class_open(char *name)
175{ 173{
176 struct class_device *class_dev = NULL, 174 struct device *dev;
177 *class_dev_tmp; 175 struct rtc_device *rtc = NULL;
178 176
179 down(&rtc_class->sem); 177 down(&rtc_class->sem);
180 list_for_each_entry(class_dev_tmp, &rtc_class->children, node) { 178 list_for_each_entry(dev, &rtc_class->devices, node) {
181 if (strncmp(class_dev_tmp->class_id, name, BUS_ID_SIZE) == 0) { 179 if (strncmp(dev->bus_id, name, BUS_ID_SIZE) == 0) {
182 class_dev = class_device_get(class_dev_tmp); 180 dev = get_device(dev);
181 if (dev)
182 rtc = to_rtc_device(dev);
183 break; 183 break;
184 } 184 }
185 } 185 }
186 186
187 if (class_dev) { 187 if (rtc) {
188 if (!try_module_get(to_rtc_device(class_dev)->owner)) 188 if (!try_module_get(rtc->owner)) {
189 class_dev = NULL; 189 put_device(dev);
190 rtc = NULL;
191 }
190 } 192 }
191 up(&rtc_class->sem); 193 up(&rtc_class->sem);
192 194
193 return class_dev; 195 return rtc;
194} 196}
195EXPORT_SYMBOL_GPL(rtc_class_open); 197EXPORT_SYMBOL_GPL(rtc_class_open);
196 198
197void rtc_class_close(struct class_device *class_dev) 199void rtc_class_close(struct rtc_device *rtc)
198{ 200{
199 module_put(to_rtc_device(class_dev)->owner); 201 module_put(rtc->owner);
200 class_device_put(class_dev); 202 put_device(&rtc->dev);
201} 203}
202EXPORT_SYMBOL_GPL(rtc_class_close); 204EXPORT_SYMBOL_GPL(rtc_class_close);
203 205
204int rtc_irq_register(struct class_device *class_dev, struct rtc_task *task) 206int rtc_irq_register(struct rtc_device *rtc, struct rtc_task *task)
205{ 207{
206 int retval = -EBUSY; 208 int retval = -EBUSY;
207 struct rtc_device *rtc = to_rtc_device(class_dev);
208 209
209 if (task == NULL || task->func == NULL) 210 if (task == NULL || task->func == NULL)
210 return -EINVAL; 211 return -EINVAL;
@@ -220,9 +221,8 @@ int rtc_irq_register(struct class_device *class_dev, struct rtc_task *task)
220} 221}
221EXPORT_SYMBOL_GPL(rtc_irq_register); 222EXPORT_SYMBOL_GPL(rtc_irq_register);
222 223
223void rtc_irq_unregister(struct class_device *class_dev, struct rtc_task *task) 224void rtc_irq_unregister(struct rtc_device *rtc, struct rtc_task *task)
224{ 225{
225 struct rtc_device *rtc = to_rtc_device(class_dev);
226 226
227 spin_lock_irq(&rtc->irq_task_lock); 227 spin_lock_irq(&rtc->irq_task_lock);
228 if (rtc->irq_task == task) 228 if (rtc->irq_task == task)
@@ -231,11 +231,10 @@ void rtc_irq_unregister(struct class_device *class_dev, struct rtc_task *task)
231} 231}
232EXPORT_SYMBOL_GPL(rtc_irq_unregister); 232EXPORT_SYMBOL_GPL(rtc_irq_unregister);
233 233
234int rtc_irq_set_state(struct class_device *class_dev, struct rtc_task *task, int enabled) 234int rtc_irq_set_state(struct rtc_device *rtc, struct rtc_task *task, int enabled)
235{ 235{
236 int err = 0; 236 int err = 0;
237 unsigned long flags; 237 unsigned long flags;
238 struct rtc_device *rtc = to_rtc_device(class_dev);
239 238
240 if (rtc->ops->irq_set_state == NULL) 239 if (rtc->ops->irq_set_state == NULL)
241 return -ENXIO; 240 return -ENXIO;
@@ -246,17 +245,16 @@ int rtc_irq_set_state(struct class_device *class_dev, struct rtc_task *task, int
246 spin_unlock_irqrestore(&rtc->irq_task_lock, flags); 245 spin_unlock_irqrestore(&rtc->irq_task_lock, flags);
247 246
248 if (err == 0) 247 if (err == 0)
249 err = rtc->ops->irq_set_state(class_dev->dev, enabled); 248 err = rtc->ops->irq_set_state(rtc->dev.parent, enabled);
250 249
251 return err; 250 return err;
252} 251}
253EXPORT_SYMBOL_GPL(rtc_irq_set_state); 252EXPORT_SYMBOL_GPL(rtc_irq_set_state);
254 253
255int rtc_irq_set_freq(struct class_device *class_dev, struct rtc_task *task, int freq) 254int rtc_irq_set_freq(struct rtc_device *rtc, struct rtc_task *task, int freq)
256{ 255{
257 int err = 0; 256 int err = 0;
258 unsigned long flags; 257 unsigned long flags;
259 struct rtc_device *rtc = to_rtc_device(class_dev);
260 258
261 if (rtc->ops->irq_set_freq == NULL) 259 if (rtc->ops->irq_set_freq == NULL)
262 return -ENXIO; 260 return -ENXIO;
@@ -267,7 +265,7 @@ int rtc_irq_set_freq(struct class_device *class_dev, struct rtc_task *task, int
267 spin_unlock_irqrestore(&rtc->irq_task_lock, flags); 265 spin_unlock_irqrestore(&rtc->irq_task_lock, flags);
268 266
269 if (err == 0) { 267 if (err == 0) {
270 err = rtc->ops->irq_set_freq(class_dev->dev, freq); 268 err = rtc->ops->irq_set_freq(rtc->dev.parent, freq);
271 if (err == 0) 269 if (err == 0)
272 rtc->irq_freq = freq; 270 rtc->irq_freq = freq;
273 } 271 }
diff --git a/drivers/rtc/rtc-at91rm9200.c b/drivers/rtc/rtc-at91rm9200.c
index ac0e68e2f025..33795e5a5595 100644
--- a/drivers/rtc/rtc-at91rm9200.c
+++ b/drivers/rtc/rtc-at91rm9200.c
@@ -263,7 +263,7 @@ static irqreturn_t at91_rtc_interrupt(int irq, void *dev_id)
263 263
264 at91_sys_write(AT91_RTC_SCCR, rtsr); /* clear status reg */ 264 at91_sys_write(AT91_RTC_SCCR, rtsr); /* clear status reg */
265 265
266 rtc_update_irq(&rtc->class_dev, 1, events); 266 rtc_update_irq(rtc, 1, events);
267 267
268 pr_debug("%s(): num=%ld, events=0x%02lx\n", __FUNCTION__, 268 pr_debug("%s(): num=%ld, events=0x%02lx\n", __FUNCTION__,
269 events >> 8, events & 0x000000FF); 269 events >> 8, events & 0x000000FF);
@@ -348,21 +348,10 @@ static int __exit at91_rtc_remove(struct platform_device *pdev)
348 348
349/* AT91RM9200 RTC Power management control */ 349/* AT91RM9200 RTC Power management control */
350 350
351static struct timespec at91_rtc_delta;
352static u32 at91_rtc_imr; 351static u32 at91_rtc_imr;
353 352
354static int at91_rtc_suspend(struct platform_device *pdev, pm_message_t state) 353static int at91_rtc_suspend(struct platform_device *pdev, pm_message_t state)
355{ 354{
356 struct rtc_time tm;
357 struct timespec time;
358
359 time.tv_nsec = 0;
360
361 /* calculate time delta for suspend */
362 at91_rtc_readtime(&pdev->dev, &tm);
363 rtc_tm_to_time(&tm, &time.tv_sec);
364 save_time_delta(&at91_rtc_delta, &time);
365
366 /* this IRQ is shared with DBGU and other hardware which isn't 355 /* this IRQ is shared with DBGU and other hardware which isn't
367 * necessarily doing PM like we are... 356 * necessarily doing PM like we are...
368 */ 357 */
@@ -374,36 +363,17 @@ static int at91_rtc_suspend(struct platform_device *pdev, pm_message_t state)
374 else 363 else
375 at91_sys_write(AT91_RTC_IDR, at91_rtc_imr); 364 at91_sys_write(AT91_RTC_IDR, at91_rtc_imr);
376 } 365 }
377
378 pr_debug("%s(): %4d-%02d-%02d %02d:%02d:%02d\n", __FUNCTION__,
379 1900 + tm.tm_year, tm.tm_mon, tm.tm_mday,
380 tm.tm_hour, tm.tm_min, tm.tm_sec);
381
382 return 0; 366 return 0;
383} 367}
384 368
385static int at91_rtc_resume(struct platform_device *pdev) 369static int at91_rtc_resume(struct platform_device *pdev)
386{ 370{
387 struct rtc_time tm;
388 struct timespec time;
389
390 time.tv_nsec = 0;
391
392 at91_rtc_readtime(&pdev->dev, &tm);
393 rtc_tm_to_time(&tm, &time.tv_sec);
394 restore_time_delta(&at91_rtc_delta, &time);
395
396 if (at91_rtc_imr) { 371 if (at91_rtc_imr) {
397 if (device_may_wakeup(&pdev->dev)) 372 if (device_may_wakeup(&pdev->dev))
398 disable_irq_wake(AT91_ID_SYS); 373 disable_irq_wake(AT91_ID_SYS);
399 else 374 else
400 at91_sys_write(AT91_RTC_IER, at91_rtc_imr); 375 at91_sys_write(AT91_RTC_IER, at91_rtc_imr);
401 } 376 }
402
403 pr_debug("%s(): %4d-%02d-%02d %02d:%02d:%02d\n", __FUNCTION__,
404 1900 + tm.tm_year, tm.tm_mon, tm.tm_mday,
405 tm.tm_hour, tm.tm_min, tm.tm_sec);
406
407 return 0; 377 return 0;
408} 378}
409#else 379#else
diff --git a/drivers/rtc/rtc-cmos.c b/drivers/rtc/rtc-cmos.c
index 7c0d60910077..6085261aa2c1 100644
--- a/drivers/rtc/rtc-cmos.c
+++ b/drivers/rtc/rtc-cmos.c
@@ -46,6 +46,10 @@ struct cmos_rtc {
46 int irq; 46 int irq;
47 struct resource *iomem; 47 struct resource *iomem;
48 48
49 void (*wake_on)(struct device *);
50 void (*wake_off)(struct device *);
51
52 u8 enabled_wake;
49 u8 suspend_ctrl; 53 u8 suspend_ctrl;
50 54
51 /* newer hardware extends the original register set */ 55 /* newer hardware extends the original register set */
@@ -203,7 +207,7 @@ static int cmos_set_alarm(struct device *dev, struct rtc_wkalrm *t)
203 rtc_intr = CMOS_READ(RTC_INTR_FLAGS); 207 rtc_intr = CMOS_READ(RTC_INTR_FLAGS);
204 rtc_intr &= (rtc_control & RTC_IRQMASK) | RTC_IRQF; 208 rtc_intr &= (rtc_control & RTC_IRQMASK) | RTC_IRQF;
205 if (is_intr(rtc_intr)) 209 if (is_intr(rtc_intr))
206 rtc_update_irq(&cmos->rtc->class_dev, 1, rtc_intr); 210 rtc_update_irq(cmos->rtc, 1, rtc_intr);
207 211
208 /* update alarm */ 212 /* update alarm */
209 CMOS_WRITE(hrs, RTC_HOURS_ALARM); 213 CMOS_WRITE(hrs, RTC_HOURS_ALARM);
@@ -223,7 +227,7 @@ static int cmos_set_alarm(struct device *dev, struct rtc_wkalrm *t)
223 rtc_intr = CMOS_READ(RTC_INTR_FLAGS); 227 rtc_intr = CMOS_READ(RTC_INTR_FLAGS);
224 rtc_intr &= (rtc_control & RTC_IRQMASK) | RTC_IRQF; 228 rtc_intr &= (rtc_control & RTC_IRQMASK) | RTC_IRQF;
225 if (is_intr(rtc_intr)) 229 if (is_intr(rtc_intr))
226 rtc_update_irq(&cmos->rtc->class_dev, 1, rtc_intr); 230 rtc_update_irq(cmos->rtc, 1, rtc_intr);
227 } 231 }
228 232
229 spin_unlock_irq(&rtc_lock); 233 spin_unlock_irq(&rtc_lock);
@@ -304,7 +308,7 @@ cmos_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
304 rtc_intr = CMOS_READ(RTC_INTR_FLAGS); 308 rtc_intr = CMOS_READ(RTC_INTR_FLAGS);
305 rtc_intr &= (rtc_control & RTC_IRQMASK) | RTC_IRQF; 309 rtc_intr &= (rtc_control & RTC_IRQMASK) | RTC_IRQF;
306 if (is_intr(rtc_intr)) 310 if (is_intr(rtc_intr))
307 rtc_update_irq(&cmos->rtc->class_dev, 1, rtc_intr); 311 rtc_update_irq(cmos->rtc, 1, rtc_intr);
308 spin_unlock_irqrestore(&rtc_lock, flags); 312 spin_unlock_irqrestore(&rtc_lock, flags);
309 return 0; 313 return 0;
310} 314}
@@ -379,12 +383,12 @@ static irqreturn_t cmos_interrupt(int irq, void *p)
379 return IRQ_NONE; 383 return IRQ_NONE;
380} 384}
381 385
382#ifdef CONFIG_PNPACPI 386#ifdef CONFIG_PNP
383#define is_pnpacpi() 1 387#define is_pnp() 1
384#define INITSECTION 388#define INITSECTION
385 389
386#else 390#else
387#define is_pnpacpi() 0 391#define is_pnp() 0
388#define INITSECTION __init 392#define INITSECTION __init
389#endif 393#endif
390 394
@@ -405,13 +409,20 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq)
405 cmos_rtc.irq = rtc_irq; 409 cmos_rtc.irq = rtc_irq;
406 cmos_rtc.iomem = ports; 410 cmos_rtc.iomem = ports;
407 411
408 /* For ACPI systems the info comes from the FADT. On others, 412 /* For ACPI systems extension info comes from the FADT. On others,
409 * board specific setup provides it as appropriate. 413 * board specific setup provides it as appropriate. Systems where
414 * the alarm IRQ isn't automatically a wakeup IRQ (like ACPI, and
415 * some almost-clones) can provide hooks to make that behave.
410 */ 416 */
411 if (info) { 417 if (info) {
412 cmos_rtc.day_alrm = info->rtc_day_alarm; 418 cmos_rtc.day_alrm = info->rtc_day_alarm;
413 cmos_rtc.mon_alrm = info->rtc_mon_alarm; 419 cmos_rtc.mon_alrm = info->rtc_mon_alarm;
414 cmos_rtc.century = info->rtc_century; 420 cmos_rtc.century = info->rtc_century;
421
422 if (info->wake_on && info->wake_off) {
423 cmos_rtc.wake_on = info->wake_on;
424 cmos_rtc.wake_off = info->wake_off;
425 }
415 } 426 }
416 427
417 cmos_rtc.rtc = rtc_device_register(driver_name, dev, 428 cmos_rtc.rtc = rtc_device_register(driver_name, dev,
@@ -427,14 +438,14 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq)
427 * REVISIT for non-x86 systems we may need to handle io memory 438 * REVISIT for non-x86 systems we may need to handle io memory
428 * resources: ioremap them, and request_mem_region(). 439 * resources: ioremap them, and request_mem_region().
429 */ 440 */
430 if (is_pnpacpi()) { 441 if (is_pnp()) {
431 retval = request_resource(&ioport_resource, ports); 442 retval = request_resource(&ioport_resource, ports);
432 if (retval < 0) { 443 if (retval < 0) {
433 dev_dbg(dev, "i/o registers already in use\n"); 444 dev_dbg(dev, "i/o registers already in use\n");
434 goto cleanup0; 445 goto cleanup0;
435 } 446 }
436 } 447 }
437 rename_region(ports, cmos_rtc.rtc->class_dev.class_id); 448 rename_region(ports, cmos_rtc.rtc->dev.bus_id);
438 449
439 spin_lock_irq(&rtc_lock); 450 spin_lock_irq(&rtc_lock);
440 451
@@ -470,8 +481,8 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq)
470 481
471 if (is_valid_irq(rtc_irq)) 482 if (is_valid_irq(rtc_irq))
472 retval = request_irq(rtc_irq, cmos_interrupt, IRQF_DISABLED, 483 retval = request_irq(rtc_irq, cmos_interrupt, IRQF_DISABLED,
473 cmos_rtc.rtc->class_dev.class_id, 484 cmos_rtc.rtc->dev.bus_id,
474 &cmos_rtc.rtc->class_dev); 485 cmos_rtc.rtc);
475 if (retval < 0) { 486 if (retval < 0) {
476 dev_dbg(dev, "IRQ %d is already in use\n", rtc_irq); 487 dev_dbg(dev, "IRQ %d is already in use\n", rtc_irq);
477 goto cleanup1; 488 goto cleanup1;
@@ -483,7 +494,7 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq)
483 */ 494 */
484 495
485 pr_info("%s: alarms up to one %s%s\n", 496 pr_info("%s: alarms up to one %s%s\n",
486 cmos_rtc.rtc->class_dev.class_id, 497 cmos_rtc.rtc->dev.bus_id,
487 is_valid_irq(rtc_irq) 498 is_valid_irq(rtc_irq)
488 ? (cmos_rtc.mon_alrm 499 ? (cmos_rtc.mon_alrm
489 ? "year" 500 ? "year"
@@ -520,12 +531,12 @@ static void __exit cmos_do_remove(struct device *dev)
520 531
521 cmos_do_shutdown(); 532 cmos_do_shutdown();
522 533
523 if (is_pnpacpi()) 534 if (is_pnp())
524 release_resource(cmos->iomem); 535 release_resource(cmos->iomem);
525 rename_region(cmos->iomem, NULL); 536 rename_region(cmos->iomem, NULL);
526 537
527 if (is_valid_irq(cmos->irq)) 538 if (is_valid_irq(cmos->irq))
528 free_irq(cmos->irq, &cmos_rtc.rtc->class_dev); 539 free_irq(cmos->irq, cmos_rtc.rtc);
529 540
530 rtc_device_unregister(cmos_rtc.rtc); 541 rtc_device_unregister(cmos_rtc.rtc);
531 542
@@ -555,16 +566,20 @@ static int cmos_suspend(struct device *dev, pm_message_t mesg)
555 irqstat = CMOS_READ(RTC_INTR_FLAGS); 566 irqstat = CMOS_READ(RTC_INTR_FLAGS);
556 irqstat &= (tmp & RTC_IRQMASK) | RTC_IRQF; 567 irqstat &= (tmp & RTC_IRQMASK) | RTC_IRQF;
557 if (is_intr(irqstat)) 568 if (is_intr(irqstat))
558 rtc_update_irq(&cmos->rtc->class_dev, 1, irqstat); 569 rtc_update_irq(cmos->rtc, 1, irqstat);
559 } 570 }
560 spin_unlock_irq(&rtc_lock); 571 spin_unlock_irq(&rtc_lock);
561 572
562 /* ACPI HOOK: enable ACPI_EVENT_RTC when (tmp & RTC_AIE) 573 if (tmp & RTC_AIE) {
563 * ... it'd be best if we could do that under rtc_lock. 574 cmos->enabled_wake = 1;
564 */ 575 if (cmos->wake_on)
576 cmos->wake_on(dev);
577 else
578 enable_irq_wake(cmos->irq);
579 }
565 580
566 pr_debug("%s: suspend%s, ctrl %02x\n", 581 pr_debug("%s: suspend%s, ctrl %02x\n",
567 cmos_rtc.rtc->class_dev.class_id, 582 cmos_rtc.rtc->dev.bus_id,
568 (tmp & RTC_AIE) ? ", alarm may wake" : "", 583 (tmp & RTC_AIE) ? ", alarm may wake" : "",
569 tmp); 584 tmp);
570 585
@@ -576,26 +591,28 @@ static int cmos_resume(struct device *dev)
576 struct cmos_rtc *cmos = dev_get_drvdata(dev); 591 struct cmos_rtc *cmos = dev_get_drvdata(dev);
577 unsigned char tmp = cmos->suspend_ctrl; 592 unsigned char tmp = cmos->suspend_ctrl;
578 593
579 /* REVISIT: a mechanism to resync the system clock (jiffies)
580 * on resume should be portable between platforms ...
581 */
582
583 /* re-enable any irqs previously active */ 594 /* re-enable any irqs previously active */
584 if (tmp & (RTC_PIE|RTC_AIE|RTC_UIE)) { 595 if (tmp & (RTC_PIE|RTC_AIE|RTC_UIE)) {
585 596
586 /* ACPI HOOK: disable ACPI_EVENT_RTC when (tmp & RTC_AIE) */ 597 if (cmos->enabled_wake) {
598 if (cmos->wake_off)
599 cmos->wake_off(dev);
600 else
601 disable_irq_wake(cmos->irq);
602 cmos->enabled_wake = 0;
603 }
587 604
588 spin_lock_irq(&rtc_lock); 605 spin_lock_irq(&rtc_lock);
589 CMOS_WRITE(tmp, RTC_CONTROL); 606 CMOS_WRITE(tmp, RTC_CONTROL);
590 tmp = CMOS_READ(RTC_INTR_FLAGS); 607 tmp = CMOS_READ(RTC_INTR_FLAGS);
591 tmp &= (cmos->suspend_ctrl & RTC_IRQMASK) | RTC_IRQF; 608 tmp &= (cmos->suspend_ctrl & RTC_IRQMASK) | RTC_IRQF;
592 if (is_intr(tmp)) 609 if (is_intr(tmp))
593 rtc_update_irq(&cmos->rtc->class_dev, 1, tmp); 610 rtc_update_irq(cmos->rtc, 1, tmp);
594 spin_unlock_irq(&rtc_lock); 611 spin_unlock_irq(&rtc_lock);
595 } 612 }
596 613
597 pr_debug("%s: resume, ctrl %02x\n", 614 pr_debug("%s: resume, ctrl %02x\n",
598 cmos_rtc.rtc->class_dev.class_id, 615 cmos_rtc.rtc->dev.bus_id,
599 cmos->suspend_ctrl); 616 cmos->suspend_ctrl);
600 617
601 618
@@ -613,7 +630,7 @@ static int cmos_resume(struct device *dev)
613 * the device node will always be created as a PNPACPI device. 630 * the device node will always be created as a PNPACPI device.
614 */ 631 */
615 632
616#ifdef CONFIG_PNPACPI 633#ifdef CONFIG_PNP
617 634
618#include <linux/pnp.h> 635#include <linux/pnp.h>
619 636
@@ -684,11 +701,11 @@ static void __exit cmos_exit(void)
684} 701}
685module_exit(cmos_exit); 702module_exit(cmos_exit);
686 703
687#else /* no PNPACPI */ 704#else /* no PNP */
688 705
689/*----------------------------------------------------------------*/ 706/*----------------------------------------------------------------*/
690 707
691/* Platform setup should have set up an RTC device, when PNPACPI is 708/* Platform setup should have set up an RTC device, when PNP is
692 * unavailable ... this could happen even on (older) PCs. 709 * unavailable ... this could happen even on (older) PCs.
693 */ 710 */
694 711
@@ -734,7 +751,7 @@ static void __exit cmos_exit(void)
734module_exit(cmos_exit); 751module_exit(cmos_exit);
735 752
736 753
737#endif /* !PNPACPI */ 754#endif /* !PNP */
738 755
739MODULE_AUTHOR("David Brownell"); 756MODULE_AUTHOR("David Brownell");
740MODULE_DESCRIPTION("Driver for PC-style 'CMOS' RTCs"); 757MODULE_DESCRIPTION("Driver for PC-style 'CMOS' RTCs");
diff --git a/drivers/rtc/rtc-core.h b/drivers/rtc/rtc-core.h
new file mode 100644
index 000000000000..5f9df7430a22
--- /dev/null
+++ b/drivers/rtc/rtc-core.h
@@ -0,0 +1,70 @@
1#ifdef CONFIG_RTC_INTF_DEV
2
3extern void __init rtc_dev_init(void);
4extern void __exit rtc_dev_exit(void);
5extern void rtc_dev_prepare(struct rtc_device *rtc);
6extern void rtc_dev_add_device(struct rtc_device *rtc);
7extern void rtc_dev_del_device(struct rtc_device *rtc);
8
9#else
10
11static inline void rtc_dev_init(void)
12{
13}
14
15static inline void rtc_dev_exit(void)
16{
17}
18
19static inline void rtc_dev_prepare(struct rtc_device *rtc)
20{
21}
22
23static inline void rtc_dev_add_device(struct rtc_device *rtc)
24{
25}
26
27static inline void rtc_dev_del_device(struct rtc_device *rtc)
28{
29}
30
31#endif
32
33#ifdef CONFIG_RTC_INTF_PROC
34
35extern void rtc_proc_add_device(struct rtc_device *rtc);
36extern void rtc_proc_del_device(struct rtc_device *rtc);
37
38#else
39
40static inline void rtc_proc_add_device(struct rtc_device *rtc)
41{
42}
43
44static inline void rtc_proc_del_device(struct rtc_device *rtc)
45{
46}
47
48#endif
49
50#ifdef CONFIG_RTC_INTF_SYSFS
51
52extern void __init rtc_sysfs_init(struct class *);
53extern void rtc_sysfs_add_device(struct rtc_device *rtc);
54extern void rtc_sysfs_del_device(struct rtc_device *rtc);
55
56#else
57
58static inline void rtc_sysfs_init(struct class *rtc)
59{
60}
61
62static inline void rtc_sysfs_add_device(struct rtc_device *rtc)
63{
64}
65
66static inline void rtc_sysfs_del_device(struct rtc_device *rtc)
67{
68}
69
70#endif
diff --git a/drivers/rtc/rtc-dev.c b/drivers/rtc/rtc-dev.c
index 137330b8636b..f4e5f0040ff7 100644
--- a/drivers/rtc/rtc-dev.c
+++ b/drivers/rtc/rtc-dev.c
@@ -13,8 +13,8 @@
13 13
14#include <linux/module.h> 14#include <linux/module.h>
15#include <linux/rtc.h> 15#include <linux/rtc.h>
16#include "rtc-core.h"
16 17
17static struct class *rtc_dev_class;
18static dev_t rtc_devt; 18static dev_t rtc_devt;
19 19
20#define RTC_DEV_MAX 16 /* 16 RTCs should be enough for everyone... */ 20#define RTC_DEV_MAX 16 /* 16 RTCs should be enough for everyone... */
@@ -32,9 +32,9 @@ static int rtc_dev_open(struct inode *inode, struct file *file)
32 if (!(mutex_trylock(&rtc->char_lock))) 32 if (!(mutex_trylock(&rtc->char_lock)))
33 return -EBUSY; 33 return -EBUSY;
34 34
35 file->private_data = &rtc->class_dev; 35 file->private_data = rtc;
36 36
37 err = ops->open ? ops->open(rtc->class_dev.dev) : 0; 37 err = ops->open ? ops->open(rtc->dev.parent) : 0;
38 if (err == 0) { 38 if (err == 0) {
39 spin_lock_irq(&rtc->irq_lock); 39 spin_lock_irq(&rtc->irq_lock);
40 rtc->irq_data = 0; 40 rtc->irq_data = 0;
@@ -61,7 +61,7 @@ static void rtc_uie_task(struct work_struct *work)
61 int num = 0; 61 int num = 0;
62 int err; 62 int err;
63 63
64 err = rtc_read_time(&rtc->class_dev, &tm); 64 err = rtc_read_time(rtc, &tm);
65 65
66 local_irq_disable(); 66 local_irq_disable();
67 spin_lock(&rtc->irq_lock); 67 spin_lock(&rtc->irq_lock);
@@ -79,7 +79,7 @@ static void rtc_uie_task(struct work_struct *work)
79 } 79 }
80 spin_unlock(&rtc->irq_lock); 80 spin_unlock(&rtc->irq_lock);
81 if (num) 81 if (num)
82 rtc_update_irq(&rtc->class_dev, num, RTC_UF | RTC_IRQF); 82 rtc_update_irq(rtc, num, RTC_UF | RTC_IRQF);
83 local_irq_enable(); 83 local_irq_enable();
84} 84}
85static void rtc_uie_timer(unsigned long data) 85static void rtc_uie_timer(unsigned long data)
@@ -121,7 +121,7 @@ static int set_uie(struct rtc_device *rtc)
121 struct rtc_time tm; 121 struct rtc_time tm;
122 int err; 122 int err;
123 123
124 err = rtc_read_time(&rtc->class_dev, &tm); 124 err = rtc_read_time(rtc, &tm);
125 if (err) 125 if (err)
126 return err; 126 return err;
127 spin_lock_irq(&rtc->irq_lock); 127 spin_lock_irq(&rtc->irq_lock);
@@ -180,7 +180,7 @@ rtc_dev_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)
180 if (ret == 0) { 180 if (ret == 0) {
181 /* Check for any data updates */ 181 /* Check for any data updates */
182 if (rtc->ops->read_callback) 182 if (rtc->ops->read_callback)
183 data = rtc->ops->read_callback(rtc->class_dev.dev, 183 data = rtc->ops->read_callback(rtc->dev.parent,
184 data); 184 data);
185 185
186 if (sizeof(int) != sizeof(long) && 186 if (sizeof(int) != sizeof(long) &&
@@ -210,8 +210,7 @@ static int rtc_dev_ioctl(struct inode *inode, struct file *file,
210 unsigned int cmd, unsigned long arg) 210 unsigned int cmd, unsigned long arg)
211{ 211{
212 int err = 0; 212 int err = 0;
213 struct class_device *class_dev = file->private_data; 213 struct rtc_device *rtc = file->private_data;
214 struct rtc_device *rtc = to_rtc_device(class_dev);
215 const struct rtc_class_ops *ops = rtc->ops; 214 const struct rtc_class_ops *ops = rtc->ops;
216 struct rtc_time tm; 215 struct rtc_time tm;
217 struct rtc_wkalrm alarm; 216 struct rtc_wkalrm alarm;
@@ -252,7 +251,7 @@ static int rtc_dev_ioctl(struct inode *inode, struct file *file,
252 251
253 /* try the driver's ioctl interface */ 252 /* try the driver's ioctl interface */
254 if (ops->ioctl) { 253 if (ops->ioctl) {
255 err = ops->ioctl(class_dev->dev, cmd, arg); 254 err = ops->ioctl(rtc->dev.parent, cmd, arg);
256 if (err != -ENOIOCTLCMD) 255 if (err != -ENOIOCTLCMD)
257 return err; 256 return err;
258 } 257 }
@@ -264,7 +263,7 @@ static int rtc_dev_ioctl(struct inode *inode, struct file *file,
264 263
265 switch (cmd) { 264 switch (cmd) {
266 case RTC_ALM_READ: 265 case RTC_ALM_READ:
267 err = rtc_read_alarm(class_dev, &alarm); 266 err = rtc_read_alarm(rtc, &alarm);
268 if (err < 0) 267 if (err < 0)
269 return err; 268 return err;
270 269
@@ -278,17 +277,53 @@ static int rtc_dev_ioctl(struct inode *inode, struct file *file,
278 277
279 alarm.enabled = 0; 278 alarm.enabled = 0;
280 alarm.pending = 0; 279 alarm.pending = 0;
281 alarm.time.tm_mday = -1;
282 alarm.time.tm_mon = -1;
283 alarm.time.tm_year = -1;
284 alarm.time.tm_wday = -1; 280 alarm.time.tm_wday = -1;
285 alarm.time.tm_yday = -1; 281 alarm.time.tm_yday = -1;
286 alarm.time.tm_isdst = -1; 282 alarm.time.tm_isdst = -1;
287 err = rtc_set_alarm(class_dev, &alarm); 283
284 /* RTC_ALM_SET alarms may be up to 24 hours in the future.
285 * Rather than expecting every RTC to implement "don't care"
286 * for day/month/year fields, just force the alarm to have
287 * the right values for those fields.
288 *
289 * RTC_WKALM_SET should be used instead. Not only does it
290 * eliminate the need for a separate RTC_AIE_ON call, it
291 * doesn't have the "alarm 23:59:59 in the future" race.
292 *
293 * NOTE: some legacy code may have used invalid fields as
294 * wildcards, exposing hardware "periodic alarm" capabilities.
295 * Not supported here.
296 */
297 {
298 unsigned long now, then;
299
300 err = rtc_read_time(rtc, &tm);
301 if (err < 0)
302 return err;
303 rtc_tm_to_time(&tm, &now);
304
305 alarm.time.tm_mday = tm.tm_mday;
306 alarm.time.tm_mon = tm.tm_mon;
307 alarm.time.tm_year = tm.tm_year;
308 err = rtc_valid_tm(&alarm.time);
309 if (err < 0)
310 return err;
311 rtc_tm_to_time(&alarm.time, &then);
312
313 /* alarm may need to wrap into tomorrow */
314 if (then < now) {
315 rtc_time_to_tm(now + 24 * 60 * 60, &tm);
316 alarm.time.tm_mday = tm.tm_mday;
317 alarm.time.tm_mon = tm.tm_mon;
318 alarm.time.tm_year = tm.tm_year;
319 }
320 }
321
322 err = rtc_set_alarm(rtc, &alarm);
288 break; 323 break;
289 324
290 case RTC_RD_TIME: 325 case RTC_RD_TIME:
291 err = rtc_read_time(class_dev, &tm); 326 err = rtc_read_time(rtc, &tm);
292 if (err < 0) 327 if (err < 0)
293 return err; 328 return err;
294 329
@@ -300,7 +335,7 @@ static int rtc_dev_ioctl(struct inode *inode, struct file *file,
300 if (copy_from_user(&tm, uarg, sizeof(tm))) 335 if (copy_from_user(&tm, uarg, sizeof(tm)))
301 return -EFAULT; 336 return -EFAULT;
302 337
303 err = rtc_set_time(class_dev, &tm); 338 err = rtc_set_time(rtc, &tm);
304 break; 339 break;
305 340
306 case RTC_IRQP_READ: 341 case RTC_IRQP_READ:
@@ -310,7 +345,7 @@ static int rtc_dev_ioctl(struct inode *inode, struct file *file,
310 345
311 case RTC_IRQP_SET: 346 case RTC_IRQP_SET:
312 if (ops->irq_set_freq) 347 if (ops->irq_set_freq)
313 err = rtc_irq_set_freq(class_dev, rtc->irq_task, arg); 348 err = rtc_irq_set_freq(rtc, rtc->irq_task, arg);
314 break; 349 break;
315 350
316#if 0 351#if 0
@@ -336,11 +371,11 @@ static int rtc_dev_ioctl(struct inode *inode, struct file *file,
336 if (copy_from_user(&alarm, uarg, sizeof(alarm))) 371 if (copy_from_user(&alarm, uarg, sizeof(alarm)))
337 return -EFAULT; 372 return -EFAULT;
338 373
339 err = rtc_set_alarm(class_dev, &alarm); 374 err = rtc_set_alarm(rtc, &alarm);
340 break; 375 break;
341 376
342 case RTC_WKALM_RD: 377 case RTC_WKALM_RD:
343 err = rtc_read_alarm(class_dev, &alarm); 378 err = rtc_read_alarm(rtc, &alarm);
344 if (err < 0) 379 if (err < 0)
345 return err; 380 return err;
346 381
@@ -372,7 +407,7 @@ static int rtc_dev_release(struct inode *inode, struct file *file)
372 clear_uie(rtc); 407 clear_uie(rtc);
373#endif 408#endif
374 if (rtc->ops->release) 409 if (rtc->ops->release)
375 rtc->ops->release(rtc->class_dev.dev); 410 rtc->ops->release(rtc->dev.parent);
376 411
377 mutex_unlock(&rtc->char_lock); 412 mutex_unlock(&rtc->char_lock);
378 return 0; 413 return 0;
@@ -397,17 +432,18 @@ static const struct file_operations rtc_dev_fops = {
397 432
398/* insertion/removal hooks */ 433/* insertion/removal hooks */
399 434
400static int rtc_dev_add_device(struct class_device *class_dev, 435void rtc_dev_prepare(struct rtc_device *rtc)
401 struct class_interface *class_intf)
402{ 436{
403 int err = 0; 437 if (!rtc_devt)
404 struct rtc_device *rtc = to_rtc_device(class_dev); 438 return;
405 439
406 if (rtc->id >= RTC_DEV_MAX) { 440 if (rtc->id >= RTC_DEV_MAX) {
407 dev_err(class_dev->dev, "too many RTCs\n"); 441 pr_debug("%s: too many RTC devices\n", rtc->name);
408 return -EINVAL; 442 return;
409 } 443 }
410 444
445 rtc->dev.devt = MKDEV(MAJOR(rtc_devt), rtc->id);
446
411 mutex_init(&rtc->char_lock); 447 mutex_init(&rtc->char_lock);
412 spin_lock_init(&rtc->irq_lock); 448 spin_lock_init(&rtc->irq_lock);
413 init_waitqueue_head(&rtc->irq_queue); 449 init_waitqueue_head(&rtc->irq_queue);
@@ -418,100 +454,36 @@ static int rtc_dev_add_device(struct class_device *class_dev,
418 454
419 cdev_init(&rtc->char_dev, &rtc_dev_fops); 455 cdev_init(&rtc->char_dev, &rtc_dev_fops);
420 rtc->char_dev.owner = rtc->owner; 456 rtc->char_dev.owner = rtc->owner;
457}
421 458
422 if (cdev_add(&rtc->char_dev, MKDEV(MAJOR(rtc_devt), rtc->id), 1)) { 459void rtc_dev_add_device(struct rtc_device *rtc)
423 dev_err(class_dev->dev, 460{
424 "failed to add char device %d:%d\n", 461 if (cdev_add(&rtc->char_dev, rtc->dev.devt, 1))
462 printk(KERN_WARNING "%s: failed to add char device %d:%d\n",
463 rtc->name, MAJOR(rtc_devt), rtc->id);
464 else
465 pr_debug("%s: dev (%d:%d)\n", rtc->name,
425 MAJOR(rtc_devt), rtc->id); 466 MAJOR(rtc_devt), rtc->id);
426 return -ENODEV;
427 }
428
429 rtc->rtc_dev = class_device_create(rtc_dev_class, NULL,
430 MKDEV(MAJOR(rtc_devt), rtc->id),
431 class_dev->dev, "rtc%d", rtc->id);
432 if (IS_ERR(rtc->rtc_dev)) {
433 dev_err(class_dev->dev, "cannot create rtc_dev device\n");
434 err = PTR_ERR(rtc->rtc_dev);
435 goto err_cdev_del;
436 }
437
438 dev_dbg(class_dev->dev, "rtc intf: dev (%d:%d)\n",
439 MAJOR(rtc->rtc_dev->devt),
440 MINOR(rtc->rtc_dev->devt));
441
442 return 0;
443
444err_cdev_del:
445
446 cdev_del(&rtc->char_dev);
447 return err;
448} 467}
449 468
450static void rtc_dev_remove_device(struct class_device *class_dev, 469void rtc_dev_del_device(struct rtc_device *rtc)
451 struct class_interface *class_intf)
452{ 470{
453 struct rtc_device *rtc = to_rtc_device(class_dev); 471 if (rtc->dev.devt)
454
455 if (rtc->rtc_dev) {
456 dev_dbg(class_dev->dev, "removing char %d:%d\n",
457 MAJOR(rtc->rtc_dev->devt),
458 MINOR(rtc->rtc_dev->devt));
459
460 class_device_unregister(rtc->rtc_dev);
461 cdev_del(&rtc->char_dev); 472 cdev_del(&rtc->char_dev);
462 }
463} 473}
464 474
465/* interface registration */ 475void __init rtc_dev_init(void)
466
467static struct class_interface rtc_dev_interface = {
468 .add = &rtc_dev_add_device,
469 .remove = &rtc_dev_remove_device,
470};
471
472static int __init rtc_dev_init(void)
473{ 476{
474 int err; 477 int err;
475 478
476 rtc_dev_class = class_create(THIS_MODULE, "rtc-dev");
477 if (IS_ERR(rtc_dev_class))
478 return PTR_ERR(rtc_dev_class);
479
480 err = alloc_chrdev_region(&rtc_devt, 0, RTC_DEV_MAX, "rtc"); 479 err = alloc_chrdev_region(&rtc_devt, 0, RTC_DEV_MAX, "rtc");
481 if (err < 0) { 480 if (err < 0)
482 printk(KERN_ERR "%s: failed to allocate char dev region\n", 481 printk(KERN_ERR "%s: failed to allocate char dev region\n",
483 __FILE__); 482 __FILE__);
484 goto err_destroy_class;
485 }
486
487 err = rtc_interface_register(&rtc_dev_interface);
488 if (err < 0) {
489 printk(KERN_ERR "%s: failed to register the interface\n",
490 __FILE__);
491 goto err_unregister_chrdev;
492 }
493
494 return 0;
495
496err_unregister_chrdev:
497 unregister_chrdev_region(rtc_devt, RTC_DEV_MAX);
498
499err_destroy_class:
500 class_destroy(rtc_dev_class);
501
502 return err;
503} 483}
504 484
505static void __exit rtc_dev_exit(void) 485void __exit rtc_dev_exit(void)
506{ 486{
507 class_interface_unregister(&rtc_dev_interface); 487 if (rtc_devt)
508 class_destroy(rtc_dev_class); 488 unregister_chrdev_region(rtc_devt, RTC_DEV_MAX);
509 unregister_chrdev_region(rtc_devt, RTC_DEV_MAX);
510} 489}
511
512subsys_initcall(rtc_dev_init);
513module_exit(rtc_dev_exit);
514
515MODULE_AUTHOR("Alessandro Zummo <a.zummo@towertech.it>");
516MODULE_DESCRIPTION("RTC class dev interface");
517MODULE_LICENSE("GPL");
diff --git a/drivers/rtc/rtc-ds1553.c b/drivers/rtc/rtc-ds1553.c
index e27176c0e18f..afa64c7fa2e2 100644
--- a/drivers/rtc/rtc-ds1553.c
+++ b/drivers/rtc/rtc-ds1553.c
@@ -203,7 +203,7 @@ static irqreturn_t ds1553_rtc_interrupt(int irq, void *dev_id)
203 events |= RTC_UF; 203 events |= RTC_UF;
204 else 204 else
205 events |= RTC_AF; 205 events |= RTC_AF;
206 rtc_update_irq(&pdata->rtc->class_dev, 1, events); 206 rtc_update_irq(pdata->rtc, 1, events);
207 return IRQ_HANDLED; 207 return IRQ_HANDLED;
208} 208}
209 209
diff --git a/drivers/rtc/rtc-lib.c b/drivers/rtc/rtc-lib.c
index 7bbc26a34bd2..ba795a4db1e9 100644
--- a/drivers/rtc/rtc-lib.c
+++ b/drivers/rtc/rtc-lib.c
@@ -117,85 +117,4 @@ int rtc_tm_to_time(struct rtc_time *tm, unsigned long *time)
117} 117}
118EXPORT_SYMBOL(rtc_tm_to_time); 118EXPORT_SYMBOL(rtc_tm_to_time);
119 119
120
121/* Merge the valid (i.e. non-negative) fields of alarm into the current
122 * time. If the valid alarm fields are earlier than the equivalent
123 * fields in the time, carry one into the least significant invalid
124 * field, so that the alarm expiry is in the future. It assumes that the
125 * least significant invalid field is more significant than the most
126 * significant valid field, and that the seconds field is valid.
127 *
128 * This is used by alarms that take relative (rather than absolute)
129 * times, and/or have a simple binary second counter instead of
130 * day/hour/minute/sec registers.
131 */
132void rtc_merge_alarm(struct rtc_time *now, struct rtc_time *alarm)
133{
134 int *alarmp = &alarm->tm_sec;
135 int *timep = &now->tm_sec;
136 int carry_into, i;
137
138 /* Ignore everything past the 6th element (tm_year). */
139 for (i = 5; i > 0; i--) {
140 if (alarmp[i] < 0)
141 alarmp[i] = timep[i];
142 else
143 break;
144 }
145
146 /* No carry needed if all fields are valid. */
147 if (i == 5)
148 return;
149
150 for (carry_into = i + 1; i >= 0; i--) {
151 if (alarmp[i] < timep[i])
152 break;
153
154 if (alarmp[i] > timep[i])
155 return;
156 }
157
158 switch (carry_into) {
159 case 1:
160 alarm->tm_min++;
161
162 if (alarm->tm_min < 60)
163 return;
164
165 alarm->tm_min = 0;
166 /* fall-through */
167
168 case 2:
169 alarm->tm_hour++;
170
171 if (alarm->tm_hour < 60)
172 return;
173
174 alarm->tm_hour = 0;
175 /* fall-through */
176
177 case 3:
178 alarm->tm_mday++;
179
180 if (alarm->tm_mday <= rtc_days_in_month[alarm->tm_mon])
181 return;
182
183 alarm->tm_mday = 1;
184 /* fall-through */
185
186 case 4:
187 alarm->tm_mon++;
188
189 if (alarm->tm_mon <= 12)
190 return;
191
192 alarm->tm_mon = 1;
193 /* fall-through */
194
195 case 5:
196 alarm->tm_year++;
197 }
198}
199EXPORT_SYMBOL(rtc_merge_alarm);
200
201MODULE_LICENSE("GPL"); 120MODULE_LICENSE("GPL");
diff --git a/drivers/rtc/rtc-max6900.c b/drivers/rtc/rtc-max6900.c
new file mode 100644
index 000000000000..eee4ee5bb75a
--- /dev/null
+++ b/drivers/rtc/rtc-max6900.c
@@ -0,0 +1,311 @@
1/*
2 * rtc class driver for the Maxim MAX6900 chip
3 *
4 * Author: Dale Farnsworth <dale@farnsworth.org>
5 *
6 * based on previously existing rtc class drivers
7 *
8 * 2007 (c) MontaVista, Software, Inc. This file is licensed under
9 * the terms of the GNU General Public License version 2. This program
10 * is licensed "as is" without any warranty of any kind, whether express
11 * or implied.
12 */
13
14#include <linux/module.h>
15#include <linux/i2c.h>
16#include <linux/bcd.h>
17#include <linux/rtc.h>
18#include <linux/delay.h>
19
20#define DRV_NAME "max6900"
21#define DRV_VERSION "0.1"
22
23/*
24 * register indices
25 */
26#define MAX6900_REG_SC 0 /* seconds 00-59 */
27#define MAX6900_REG_MN 1 /* minutes 00-59 */
28#define MAX6900_REG_HR 2 /* hours 00-23 */
29#define MAX6900_REG_DT 3 /* day of month 00-31 */
30#define MAX6900_REG_MO 4 /* month 01-12 */
31#define MAX6900_REG_DW 5 /* day of week 1-7 */
32#define MAX6900_REG_YR 6 /* year 00-99 */
33#define MAX6900_REG_CT 7 /* control */
34#define MAX6900_REG_LEN 8
35
36#define MAX6900_REG_CT_WP (1 << 7) /* Write Protect */
37
38/*
39 * register read/write commands
40 */
41#define MAX6900_REG_CONTROL_WRITE 0x8e
42#define MAX6900_REG_BURST_READ 0xbf
43#define MAX6900_REG_BURST_WRITE 0xbe
44#define MAX6900_REG_RESERVED_READ 0x96
45
46#define MAX6900_IDLE_TIME_AFTER_WRITE 3 /* specification says 2.5 mS */
47
48#define MAX6900_I2C_ADDR 0xa0
49
50static unsigned short normal_i2c[] = {
51 MAX6900_I2C_ADDR >> 1,
52 I2C_CLIENT_END
53};
54
55I2C_CLIENT_INSMOD; /* defines addr_data */
56
57static int max6900_probe(struct i2c_adapter *adapter, int addr, int kind);
58
59static int max6900_i2c_read_regs(struct i2c_client *client, u8 *buf)
60{
61 u8 reg_addr[1] = { MAX6900_REG_BURST_READ };
62 struct i2c_msg msgs[2] = {
63 {
64 .addr = client->addr,
65 .flags = 0, /* write */
66 .len = sizeof(reg_addr),
67 .buf = reg_addr
68 },
69 {
70 .addr = client->addr,
71 .flags = I2C_M_RD,
72 .len = MAX6900_REG_LEN,
73 .buf = buf
74 }
75 };
76 int rc;
77
78 rc = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
79 if (rc != ARRAY_SIZE(msgs)) {
80 dev_err(&client->dev, "%s: register read failed\n",
81 __FUNCTION__);
82 return -EIO;
83 }
84 return 0;
85}
86
87static int max6900_i2c_write_regs(struct i2c_client *client, u8 const *buf)
88{
89 u8 i2c_buf[MAX6900_REG_LEN + 1] = { MAX6900_REG_BURST_WRITE };
90 struct i2c_msg msgs[1] = {
91 {
92 .addr = client->addr,
93 .flags = 0, /* write */
94 .len = MAX6900_REG_LEN + 1,
95 .buf = i2c_buf
96 }
97 };
98 int rc;
99
100 memcpy(&i2c_buf[1], buf, MAX6900_REG_LEN);
101
102 rc = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
103 if (rc != ARRAY_SIZE(msgs)) {
104 dev_err(&client->dev, "%s: register write failed\n",
105 __FUNCTION__);
106 return -EIO;
107 }
108 msleep(MAX6900_IDLE_TIME_AFTER_WRITE);
109 return 0;
110}
111
112static int max6900_i2c_validate_client(struct i2c_client *client)
113{
114 u8 regs[MAX6900_REG_LEN];
115 u8 zero_mask[MAX6900_REG_LEN] = {
116 0x80, /* seconds */
117 0x80, /* minutes */
118 0x40, /* hours */
119 0xc0, /* day of month */
120 0xe0, /* month */
121 0xf8, /* day of week */
122 0x00, /* year */
123 0x7f, /* control */
124 };
125 int i;
126 int rc;
127 int reserved;
128
129 reserved = i2c_smbus_read_byte_data(client, MAX6900_REG_RESERVED_READ);
130 if (reserved != 0x07)
131 return -ENODEV;
132
133 rc = max6900_i2c_read_regs(client, regs);
134 if (rc < 0)
135 return rc;
136
137 for (i = 0; i < MAX6900_REG_LEN; ++i) {
138 if (regs[i] & zero_mask[i])
139 return -ENODEV;
140 }
141
142 return 0;
143}
144
145static int max6900_i2c_read_time(struct i2c_client *client, struct rtc_time *tm)
146{
147 int rc;
148 u8 regs[MAX6900_REG_LEN];
149
150 rc = max6900_i2c_read_regs(client, regs);
151 if (rc < 0)
152 return rc;
153
154 tm->tm_sec = BCD2BIN(regs[MAX6900_REG_SC]);
155 tm->tm_min = BCD2BIN(regs[MAX6900_REG_MN]);
156 tm->tm_hour = BCD2BIN(regs[MAX6900_REG_HR] & 0x3f);
157 tm->tm_mday = BCD2BIN(regs[MAX6900_REG_DT]);
158 tm->tm_mon = BCD2BIN(regs[MAX6900_REG_MO]) - 1;
159 tm->tm_year = BCD2BIN(regs[MAX6900_REG_YR]) + 100;
160 tm->tm_wday = BCD2BIN(regs[MAX6900_REG_DW]);
161
162 return 0;
163}
164
165static int max6900_i2c_clear_write_protect(struct i2c_client *client)
166{
167 int rc;
168 rc = i2c_smbus_write_byte_data (client, MAX6900_REG_CONTROL_WRITE, 0);
169 if (rc < 0) {
170 dev_err(&client->dev, "%s: control register write failed\n",
171 __FUNCTION__);
172 return -EIO;
173 }
174 return 0;
175}
176
177static int max6900_i2c_set_time(struct i2c_client *client,
178 struct rtc_time const *tm)
179{
180 u8 regs[MAX6900_REG_LEN];
181 int rc;
182
183 rc = max6900_i2c_clear_write_protect(client);
184 if (rc < 0)
185 return rc;
186
187 regs[MAX6900_REG_SC] = BIN2BCD(tm->tm_sec);
188 regs[MAX6900_REG_MN] = BIN2BCD(tm->tm_min);
189 regs[MAX6900_REG_HR] = BIN2BCD(tm->tm_hour);
190 regs[MAX6900_REG_DT] = BIN2BCD(tm->tm_mday);
191 regs[MAX6900_REG_MO] = BIN2BCD(tm->tm_mon + 1);
192 regs[MAX6900_REG_YR] = BIN2BCD(tm->tm_year - 100);
193 regs[MAX6900_REG_DW] = BIN2BCD(tm->tm_wday);
194 regs[MAX6900_REG_CT] = MAX6900_REG_CT_WP; /* set write protect */
195
196 rc = max6900_i2c_write_regs(client, regs);
197 if (rc < 0)
198 return rc;
199
200 return 0;
201}
202
203static int max6900_rtc_read_time(struct device *dev, struct rtc_time *tm)
204{
205 return max6900_i2c_read_time(to_i2c_client(dev), tm);
206}
207
208static int max6900_rtc_set_time(struct device *dev, struct rtc_time *tm)
209{
210 return max6900_i2c_set_time(to_i2c_client(dev), tm);
211}
212
213static int max6900_attach_adapter(struct i2c_adapter *adapter)
214{
215 return i2c_probe(adapter, &addr_data, max6900_probe);
216}
217
218static int max6900_detach_client(struct i2c_client *client)
219{
220 struct rtc_device *const rtc = i2c_get_clientdata(client);
221
222 if (rtc)
223 rtc_device_unregister(rtc);
224
225 return i2c_detach_client(client);
226}
227
228static struct i2c_driver max6900_driver = {
229 .driver = {
230 .name = DRV_NAME,
231 },
232 .id = I2C_DRIVERID_MAX6900,
233 .attach_adapter = max6900_attach_adapter,
234 .detach_client = max6900_detach_client,
235};
236
237static const struct rtc_class_ops max6900_rtc_ops = {
238 .read_time = max6900_rtc_read_time,
239 .set_time = max6900_rtc_set_time,
240};
241
242static int max6900_probe(struct i2c_adapter *adapter, int addr, int kind)
243{
244 int rc = 0;
245 struct i2c_client *client = NULL;
246 struct rtc_device *rtc = NULL;
247
248 if (!i2c_check_functionality(adapter, I2C_FUNC_I2C)) {
249 rc = -ENODEV;
250 goto failout;
251 }
252
253 client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL);
254 if (client == NULL) {
255 rc = -ENOMEM;
256 goto failout;
257 }
258
259 client->addr = addr;
260 client->adapter = adapter;
261 client->driver = &max6900_driver;
262 strlcpy(client->name, DRV_NAME, I2C_NAME_SIZE);
263
264 if (kind < 0) {
265 rc = max6900_i2c_validate_client(client);
266 if (rc < 0)
267 goto failout;
268 }
269
270 rc = i2c_attach_client(client);
271 if (rc < 0)
272 goto failout;
273
274 dev_info(&client->dev,
275 "chip found, driver version " DRV_VERSION "\n");
276
277 rtc = rtc_device_register(max6900_driver.driver.name,
278 &client->dev,
279 &max6900_rtc_ops, THIS_MODULE);
280 if (IS_ERR(rtc)) {
281 rc = PTR_ERR(rtc);
282 goto failout_detach;
283 }
284
285 i2c_set_clientdata(client, rtc);
286
287 return 0;
288
289failout_detach:
290 i2c_detach_client(client);
291failout:
292 kfree(client);
293 return rc;
294}
295
296static int __init max6900_init(void)
297{
298 return i2c_add_driver(&max6900_driver);
299}
300
301static void __exit max6900_exit(void)
302{
303 i2c_del_driver(&max6900_driver);
304}
305
306MODULE_DESCRIPTION("Maxim MAX6900 RTC driver");
307MODULE_LICENSE("GPL");
308MODULE_VERSION(DRV_VERSION);
309
310module_init(max6900_init);
311module_exit(max6900_exit);
diff --git a/drivers/rtc/rtc-omap.c b/drivers/rtc/rtc-omap.c
index 9de8d67f4f8d..60a8a4bb8bd2 100644
--- a/drivers/rtc/rtc-omap.c
+++ b/drivers/rtc/rtc-omap.c
@@ -124,7 +124,7 @@ static void rtc_wait_not_busy(void)
124 /* now we have ~15 usec to read/write various registers */ 124 /* now we have ~15 usec to read/write various registers */
125} 125}
126 126
127static irqreturn_t rtc_irq(int irq, void *class_dev) 127static irqreturn_t rtc_irq(int irq, void *rtc)
128{ 128{
129 unsigned long events = 0; 129 unsigned long events = 0;
130 u8 irq_data; 130 u8 irq_data;
@@ -141,7 +141,7 @@ static irqreturn_t rtc_irq(int irq, void *class_dev)
141 if (irq_data & OMAP_RTC_STATUS_1S_EVENT) 141 if (irq_data & OMAP_RTC_STATUS_1S_EVENT)
142 events |= RTC_IRQF | RTC_UF; 142 events |= RTC_IRQF | RTC_UF;
143 143
144 rtc_update_irq(class_dev, 1, events); 144 rtc_update_irq(rtc, 1, events);
145 145
146 return IRQ_HANDLED; 146 return IRQ_HANDLED;
147} 147}
@@ -289,34 +289,6 @@ static int omap_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm)
289{ 289{
290 u8 reg; 290 u8 reg;
291 291
292 /* Much userspace code uses RTC_ALM_SET, thus "don't care" for
293 * day/month/year specifies alarms up to 24 hours in the future.
294 * So we need to handle that ... but let's ignore the "don't care"
295 * values for hours/minutes/seconds.
296 */
297 if (alm->time.tm_mday <= 0
298 && alm->time.tm_mon < 0
299 && alm->time.tm_year < 0) {
300 struct rtc_time tm;
301 unsigned long now, then;
302
303 omap_rtc_read_time(dev, &tm);
304 rtc_tm_to_time(&tm, &now);
305
306 alm->time.tm_mday = tm.tm_mday;
307 alm->time.tm_mon = tm.tm_mon;
308 alm->time.tm_year = tm.tm_year;
309 rtc_tm_to_time(&alm->time, &then);
310
311 /* sometimes the alarm wraps into tomorrow */
312 if (then < now) {
313 rtc_time_to_tm(now + 24 * 60 * 60, &tm);
314 alm->time.tm_mday = tm.tm_mday;
315 alm->time.tm_mon = tm.tm_mon;
316 alm->time.tm_year = tm.tm_year;
317 }
318 }
319
320 if (tm2bcd(&alm->time) < 0) 292 if (tm2bcd(&alm->time) < 0)
321 return -EINVAL; 293 return -EINVAL;
322 294
@@ -399,7 +371,7 @@ static int __devinit omap_rtc_probe(struct platform_device *pdev)
399 goto fail; 371 goto fail;
400 } 372 }
401 platform_set_drvdata(pdev, rtc); 373 platform_set_drvdata(pdev, rtc);
402 class_set_devdata(&rtc->class_dev, mem); 374 dev_set_devdata(&rtc->dev, mem);
403 375
404 /* clear pending irqs, and set 1/second periodic, 376 /* clear pending irqs, and set 1/second periodic,
405 * which we'll use instead of update irqs 377 * which we'll use instead of update irqs
@@ -418,13 +390,13 @@ static int __devinit omap_rtc_probe(struct platform_device *pdev)
418 390
419 /* handle periodic and alarm irqs */ 391 /* handle periodic and alarm irqs */
420 if (request_irq(omap_rtc_timer, rtc_irq, IRQF_DISABLED, 392 if (request_irq(omap_rtc_timer, rtc_irq, IRQF_DISABLED,
421 rtc->class_dev.class_id, &rtc->class_dev)) { 393 rtc->dev.bus_id, rtc)) {
422 pr_debug("%s: RTC timer interrupt IRQ%d already claimed\n", 394 pr_debug("%s: RTC timer interrupt IRQ%d already claimed\n",
423 pdev->name, omap_rtc_timer); 395 pdev->name, omap_rtc_timer);
424 goto fail0; 396 goto fail0;
425 } 397 }
426 if (request_irq(omap_rtc_alarm, rtc_irq, IRQF_DISABLED, 398 if (request_irq(omap_rtc_alarm, rtc_irq, IRQF_DISABLED,
427 rtc->class_dev.class_id, &rtc->class_dev)) { 399 rtc->dev.bus_id, rtc)) {
428 pr_debug("%s: RTC alarm interrupt IRQ%d already claimed\n", 400 pr_debug("%s: RTC alarm interrupt IRQ%d already claimed\n",
429 pdev->name, omap_rtc_alarm); 401 pdev->name, omap_rtc_alarm);
430 goto fail1; 402 goto fail1;
@@ -481,26 +453,17 @@ static int __devexit omap_rtc_remove(struct platform_device *pdev)
481 free_irq(omap_rtc_timer, rtc); 453 free_irq(omap_rtc_timer, rtc);
482 free_irq(omap_rtc_alarm, rtc); 454 free_irq(omap_rtc_alarm, rtc);
483 455
484 release_resource(class_get_devdata(&rtc->class_dev)); 456 release_resource(dev_get_devdata(&rtc->dev));
485 rtc_device_unregister(rtc); 457 rtc_device_unregister(rtc);
486 return 0; 458 return 0;
487} 459}
488 460
489#ifdef CONFIG_PM 461#ifdef CONFIG_PM
490 462
491static struct timespec rtc_delta;
492static u8 irqstat; 463static u8 irqstat;
493 464
494static int omap_rtc_suspend(struct platform_device *pdev, pm_message_t state) 465static int omap_rtc_suspend(struct platform_device *pdev, pm_message_t state)
495{ 466{
496 struct rtc_time rtc_tm;
497 struct timespec time;
498
499 time.tv_nsec = 0;
500 omap_rtc_read_time(NULL, &rtc_tm);
501 rtc_tm_to_time(&rtc_tm, &time.tv_sec);
502
503 save_time_delta(&rtc_delta, &time);
504 irqstat = rtc_read(OMAP_RTC_INTERRUPTS_REG); 467 irqstat = rtc_read(OMAP_RTC_INTERRUPTS_REG);
505 468
506 /* FIXME the RTC alarm is not currently acting as a wakeup event 469 /* FIXME the RTC alarm is not currently acting as a wakeup event
@@ -517,14 +480,6 @@ static int omap_rtc_suspend(struct platform_device *pdev, pm_message_t state)
517 480
518static int omap_rtc_resume(struct platform_device *pdev) 481static int omap_rtc_resume(struct platform_device *pdev)
519{ 482{
520 struct rtc_time rtc_tm;
521 struct timespec time;
522
523 time.tv_nsec = 0;
524 omap_rtc_read_time(NULL, &rtc_tm);
525 rtc_tm_to_time(&rtc_tm, &time.tv_sec);
526
527 restore_time_delta(&rtc_delta, &time);
528 if (device_may_wakeup(&pdev->dev)) 483 if (device_may_wakeup(&pdev->dev))
529 disable_irq_wake(omap_rtc_alarm); 484 disable_irq_wake(omap_rtc_alarm);
530 else 485 else
diff --git a/drivers/rtc/rtc-pl031.c b/drivers/rtc/rtc-pl031.c
index f13daa9fecaa..e4bf68ca96f7 100644
--- a/drivers/rtc/rtc-pl031.c
+++ b/drivers/rtc/rtc-pl031.c
@@ -51,7 +51,7 @@ static irqreturn_t pl031_interrupt(int irq, void *dev_id)
51{ 51{
52 struct rtc_device *rtc = dev_id; 52 struct rtc_device *rtc = dev_id;
53 53
54 rtc_update_irq(&rtc->class_dev, 1, RTC_AF); 54 rtc_update_irq(rtc, 1, RTC_AF);
55 55
56 return IRQ_HANDLED; 56 return IRQ_HANDLED;
57} 57}
diff --git a/drivers/rtc/rtc-proc.c b/drivers/rtc/rtc-proc.c
index 1bd624fc685c..8d300e6d0d9e 100644
--- a/drivers/rtc/rtc-proc.c
+++ b/drivers/rtc/rtc-proc.c
@@ -16,18 +16,18 @@
16#include <linux/proc_fs.h> 16#include <linux/proc_fs.h>
17#include <linux/seq_file.h> 17#include <linux/seq_file.h>
18 18
19static struct class_device *rtc_dev = NULL; 19#include "rtc-core.h"
20static DEFINE_MUTEX(rtc_lock); 20
21 21
22static int rtc_proc_show(struct seq_file *seq, void *offset) 22static int rtc_proc_show(struct seq_file *seq, void *offset)
23{ 23{
24 int err; 24 int err;
25 struct class_device *class_dev = seq->private; 25 struct rtc_device *rtc = seq->private;
26 const struct rtc_class_ops *ops = to_rtc_device(class_dev)->ops; 26 const struct rtc_class_ops *ops = rtc->ops;
27 struct rtc_wkalrm alrm; 27 struct rtc_wkalrm alrm;
28 struct rtc_time tm; 28 struct rtc_time tm;
29 29
30 err = rtc_read_time(class_dev, &tm); 30 err = rtc_read_time(rtc, &tm);
31 if (err == 0) { 31 if (err == 0) {
32 seq_printf(seq, 32 seq_printf(seq,
33 "rtc_time\t: %02d:%02d:%02d\n" 33 "rtc_time\t: %02d:%02d:%02d\n"
@@ -36,7 +36,7 @@ static int rtc_proc_show(struct seq_file *seq, void *offset)
36 tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday); 36 tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday);
37 } 37 }
38 38
39 err = rtc_read_alarm(class_dev, &alrm); 39 err = rtc_read_alarm(rtc, &alrm);
40 if (err == 0) { 40 if (err == 0) {
41 seq_printf(seq, "alrm_time\t: "); 41 seq_printf(seq, "alrm_time\t: ");
42 if ((unsigned int)alrm.time.tm_hour <= 24) 42 if ((unsigned int)alrm.time.tm_hour <= 24)
@@ -74,19 +74,19 @@ static int rtc_proc_show(struct seq_file *seq, void *offset)
74 seq_printf(seq, "24hr\t\t: yes\n"); 74 seq_printf(seq, "24hr\t\t: yes\n");
75 75
76 if (ops->proc) 76 if (ops->proc)
77 ops->proc(class_dev->dev, seq); 77 ops->proc(rtc->dev.parent, seq);
78 78
79 return 0; 79 return 0;
80} 80}
81 81
82static int rtc_proc_open(struct inode *inode, struct file *file) 82static int rtc_proc_open(struct inode *inode, struct file *file)
83{ 83{
84 struct class_device *class_dev = PDE(inode)->data; 84 struct rtc_device *rtc = PDE(inode)->data;
85 85
86 if (!try_module_get(THIS_MODULE)) 86 if (!try_module_get(THIS_MODULE))
87 return -ENODEV; 87 return -ENODEV;
88 88
89 return single_open(file, rtc_proc_show, class_dev); 89 return single_open(file, rtc_proc_show, rtc);
90} 90}
91 91
92static int rtc_proc_release(struct inode *inode, struct file *file) 92static int rtc_proc_release(struct inode *inode, struct file *file)
@@ -103,62 +103,22 @@ static const struct file_operations rtc_proc_fops = {
103 .release = rtc_proc_release, 103 .release = rtc_proc_release,
104}; 104};
105 105
106static int rtc_proc_add_device(struct class_device *class_dev, 106void rtc_proc_add_device(struct rtc_device *rtc)
107 struct class_interface *class_intf)
108{ 107{
109 mutex_lock(&rtc_lock); 108 if (rtc->id == 0) {
110 if (rtc_dev == NULL) {
111 struct proc_dir_entry *ent; 109 struct proc_dir_entry *ent;
112 110
113 rtc_dev = class_dev;
114
115 ent = create_proc_entry("driver/rtc", 0, NULL); 111 ent = create_proc_entry("driver/rtc", 0, NULL);
116 if (ent) { 112 if (ent) {
117 struct rtc_device *rtc = to_rtc_device(class_dev);
118
119 ent->proc_fops = &rtc_proc_fops; 113 ent->proc_fops = &rtc_proc_fops;
120 ent->owner = rtc->owner; 114 ent->owner = rtc->owner;
121 ent->data = class_dev; 115 ent->data = rtc;
122
123 dev_dbg(class_dev->dev, "rtc intf: proc\n");
124 } 116 }
125 else
126 rtc_dev = NULL;
127 } 117 }
128 mutex_unlock(&rtc_lock);
129
130 return 0;
131} 118}
132 119
133static void rtc_proc_remove_device(struct class_device *class_dev, 120void rtc_proc_del_device(struct rtc_device *rtc)
134 struct class_interface *class_intf)
135{ 121{
136 mutex_lock(&rtc_lock); 122 if (rtc->id == 0)
137 if (rtc_dev == class_dev) {
138 remove_proc_entry("driver/rtc", NULL); 123 remove_proc_entry("driver/rtc", NULL);
139 rtc_dev = NULL;
140 }
141 mutex_unlock(&rtc_lock);
142}
143
144static struct class_interface rtc_proc_interface = {
145 .add = &rtc_proc_add_device,
146 .remove = &rtc_proc_remove_device,
147};
148
149static int __init rtc_proc_init(void)
150{
151 return rtc_interface_register(&rtc_proc_interface);
152} 124}
153
154static void __exit rtc_proc_exit(void)
155{
156 class_interface_unregister(&rtc_proc_interface);
157}
158
159subsys_initcall(rtc_proc_init);
160module_exit(rtc_proc_exit);
161
162MODULE_AUTHOR("Alessandro Zummo <a.zummo@towertech.it>");
163MODULE_DESCRIPTION("RTC class proc interface");
164MODULE_LICENSE("GPL");
diff --git a/drivers/rtc/rtc-rs5c313.c b/drivers/rtc/rtc-rs5c313.c
new file mode 100644
index 000000000000..9d6de371495b
--- /dev/null
+++ b/drivers/rtc/rtc-rs5c313.c
@@ -0,0 +1,405 @@
1/*
2 * Ricoh RS5C313 RTC device/driver
3 * Copyright (C) 2007 Nobuhiro Iwamatsu
4 *
5 * 2005-09-19 modifed by kogiidena
6 *
7 * Based on the old drivers/char/rs5c313_rtc.c by:
8 * Copyright (C) 2000 Philipp Rumpf <prumpf@tux.org>
9 * Copyright (C) 1999 Tetsuya Okada & Niibe Yutaka
10 *
11 * Based on code written by Paul Gortmaker.
12 * Copyright (C) 1996 Paul Gortmaker
13 *
14 * This file is subject to the terms and conditions of the GNU General Public
15 * License. See the file "COPYING" in the main directory of this archive
16 * for more details.
17 *
18 * Based on other minimal char device drivers, like Alan's
19 * watchdog, Ted's random, etc. etc.
20 *
21 * 1.07 Paul Gortmaker.
22 * 1.08 Miquel van Smoorenburg: disallow certain things on the
23 * DEC Alpha as the CMOS clock is also used for other things.
24 * 1.09 Nikita Schmidt: epoch support and some Alpha cleanup.
25 * 1.09a Pete Zaitcev: Sun SPARC
26 * 1.09b Jeff Garzik: Modularize, init cleanup
27 * 1.09c Jeff Garzik: SMP cleanup
28 * 1.10 Paul Barton-Davis: add support for async I/O
29 * 1.10a Andrea Arcangeli: Alpha updates
30 * 1.10b Andrew Morton: SMP lock fix
31 * 1.10c Cesar Barros: SMP locking fixes and cleanup
32 * 1.10d Paul Gortmaker: delete paranoia check in rtc_exit
33 * 1.10e Maciej W. Rozycki: Handle DECstation's year weirdness.
34 * 1.11 Takashi Iwai: Kernel access functions
35 * rtc_register/rtc_unregister/rtc_control
36 * 1.11a Daniele Bellucci: Audit create_proc_read_entry in rtc_init
37 * 1.12 Venkatesh Pallipadi: Hooks for emulating rtc on HPET base-timer
38 * CONFIG_HPET_EMULATE_RTC
39 * 1.13 Nobuhiro Iwamatsu: Updata driver.
40 */
41
42#include <linux/module.h>
43#include <linux/err.h>
44#include <linux/rtc.h>
45#include <linux/platform_device.h>
46#include <linux/bcd.h>
47#include <linux/delay.h>
48#include <asm/io.h>
49
50#define DRV_NAME "rs5c313"
51#define DRV_VERSION "1.13"
52
53#ifdef CONFIG_SH_LANDISK
54/*****************************************************/
55/* LANDISK dependence part of RS5C313 */
56/*****************************************************/
57
58#define SCSMR1 0xFFE00000
59#define SCSCR1 0xFFE00008
60#define SCSMR1_CA 0x80
61#define SCSCR1_CKE 0x03
62#define SCSPTR1 0xFFE0001C
63#define SCSPTR1_EIO 0x80
64#define SCSPTR1_SPB1IO 0x08
65#define SCSPTR1_SPB1DT 0x04
66#define SCSPTR1_SPB0IO 0x02
67#define SCSPTR1_SPB0DT 0x01
68
69#define SDA_OEN SCSPTR1_SPB1IO
70#define SDA SCSPTR1_SPB1DT
71#define SCL_OEN SCSPTR1_SPB0IO
72#define SCL SCSPTR1_SPB0DT
73
74/* RICOH RS5C313 CE port */
75#define RS5C313_CE 0xB0000003
76
77/* RICOH RS5C313 CE port bit */
78#define RS5C313_CE_RTCCE 0x02
79
80/* SCSPTR1 data */
81unsigned char scsptr1_data;
82
83#define RS5C313_CEENABLE ctrl_outb(RS5C313_CE_RTCCE, RS5C313_CE);
84#define RS5C313_CEDISABLE ctrl_outb(0x00, RS5C313_CE)
85#define RS5C313_MISCOP ctrl_outb(0x02, 0xB0000008)
86
87static void rs5c313_init_port(void)
88{
89 /* Set SCK as I/O port and Initialize SCSPTR1 data & I/O port. */
90 ctrl_outb(ctrl_inb(SCSMR1) & ~SCSMR1_CA, SCSMR1);
91 ctrl_outb(ctrl_inb(SCSCR1) & ~SCSCR1_CKE, SCSCR1);
92
93 /* And Initialize SCL for RS5C313 clock */
94 scsptr1_data = ctrl_inb(SCSPTR1) | SCL; /* SCL:H */
95 ctrl_outb(scsptr1_data, SCSPTR1);
96 scsptr1_data = ctrl_inb(SCSPTR1) | SCL_OEN; /* SCL output enable */
97 ctrl_outb(scsptr1_data, SCSPTR1);
98 RS5C313_CEDISABLE; /* CE:L */
99}
100
101static void rs5c313_write_data(unsigned char data)
102{
103 int i;
104
105 for (i = 0; i < 8; i++) {
106 /* SDA:Write Data */
107 scsptr1_data = (scsptr1_data & ~SDA) |
108 ((((0x80 >> i) & data) >> (7 - i)) << 2);
109 ctrl_outb(scsptr1_data, SCSPTR1);
110 if (i == 0) {
111 scsptr1_data |= SDA_OEN; /* SDA:output enable */
112 ctrl_outb(scsptr1_data, SCSPTR1);
113 }
114 ndelay(700);
115 scsptr1_data &= ~SCL; /* SCL:L */
116 ctrl_outb(scsptr1_data, SCSPTR1);
117 ndelay(700);
118 scsptr1_data |= SCL; /* SCL:H */
119 ctrl_outb(scsptr1_data, SCSPTR1);
120 }
121
122 scsptr1_data &= ~SDA_OEN; /* SDA:output disable */
123 ctrl_outb(scsptr1_data, SCSPTR1);
124}
125
126static unsigned char rs5c313_read_data(void)
127{
128 int i;
129 unsigned char data;
130
131 for (i = 0; i < 8; i++) {
132 ndelay(700);
133 /* SDA:Read Data */
134 data |= ((ctrl_inb(SCSPTR1) & SDA) >> 2) << (7 - i);
135 scsptr1_data &= ~SCL; /* SCL:L */
136 ctrl_outb(scsptr1_data, SCSPTR1);
137 ndelay(700);
138 scsptr1_data |= SCL; /* SCL:H */
139 ctrl_outb(scsptr1_data, SCSPTR1);
140 }
141 return data & 0x0F;
142}
143
144#endif /* CONFIG_SH_LANDISK */
145
146/*****************************************************/
147/* machine independence part of RS5C313 */
148/*****************************************************/
149
150/* RICOH RS5C313 address */
151#define RS5C313_ADDR_SEC 0x00
152#define RS5C313_ADDR_SEC10 0x01
153#define RS5C313_ADDR_MIN 0x02
154#define RS5C313_ADDR_MIN10 0x03
155#define RS5C313_ADDR_HOUR 0x04
156#define RS5C313_ADDR_HOUR10 0x05
157#define RS5C313_ADDR_WEEK 0x06
158#define RS5C313_ADDR_INTINTVREG 0x07
159#define RS5C313_ADDR_DAY 0x08
160#define RS5C313_ADDR_DAY10 0x09
161#define RS5C313_ADDR_MON 0x0A
162#define RS5C313_ADDR_MON10 0x0B
163#define RS5C313_ADDR_YEAR 0x0C
164#define RS5C313_ADDR_YEAR10 0x0D
165#define RS5C313_ADDR_CNTREG 0x0E
166#define RS5C313_ADDR_TESTREG 0x0F
167
168/* RICOH RS5C313 control register */
169#define RS5C313_CNTREG_ADJ_BSY 0x01
170#define RS5C313_CNTREG_WTEN_XSTP 0x02
171#define RS5C313_CNTREG_12_24 0x04
172#define RS5C313_CNTREG_CTFG 0x08
173
174/* RICOH RS5C313 test register */
175#define RS5C313_TESTREG_TEST 0x01
176
177/* RICOH RS5C313 control bit */
178#define RS5C313_CNTBIT_READ 0x40
179#define RS5C313_CNTBIT_AD 0x20
180#define RS5C313_CNTBIT_DT 0x10
181
182static unsigned char rs5c313_read_reg(unsigned char addr)
183{
184
185 rs5c313_write_data(addr | RS5C313_CNTBIT_READ | RS5C313_CNTBIT_AD);
186 return rs5c313_read_data();
187}
188
189static void rs5c313_write_reg(unsigned char addr, unsigned char data)
190{
191 data &= 0x0f;
192 rs5c313_write_data(addr | RS5C313_CNTBIT_AD);
193 rs5c313_write_data(data | RS5C313_CNTBIT_DT);
194 return;
195}
196
197static inline unsigned char rs5c313_read_cntreg(unsigned char addr)
198{
199 return rs5c313_read_reg(RS5C313_ADDR_CNTREG);
200}
201
202static inline void rs5c313_write_cntreg(unsigned char data)
203{
204 rs5c313_write_reg(RS5C313_ADDR_CNTREG, data);
205}
206
207static inline void rs5c313_write_intintvreg(unsigned char data)
208{
209 rs5c313_write_reg(RS5C313_ADDR_INTINTVREG, data);
210}
211
212static int rs5c313_rtc_read_time(struct device *dev, struct rtc_time *tm)
213{
214 int data;
215
216 while (1) {
217 RS5C313_CEENABLE; /* CE:H */
218
219 /* Initialize control reg. 24 hour */
220 rs5c313_write_cntreg(0x04);
221
222 if (!(rs5c313_read_cntreg() & RS5C313_CNTREG_ADJ_BSY))
223 break;
224
225 RS5C313_CEDISABLE;
226 ndelay(700); /* CE:L */
227
228 }
229
230 data = rs5c313_read_reg(RS5C313_ADDR_SEC);
231 data |= (rs5c313_read_reg(RS5C313_ADDR_SEC10) << 4);
232 tm->tm_sec = BCD2BIN(data);
233
234 data = rs5c313_read_reg(RS5C313_ADDR_MIN);
235 data |= (rs5c313_read_reg(RS5C313_ADDR_MIN10) << 4);
236 tm->tm_min = BCD2BIN(data);
237
238 data = rs5c313_read_reg(RS5C313_ADDR_HOUR);
239 data |= (rs5c313_read_reg(RS5C313_ADDR_HOUR10) << 4);
240 tm->tm_hour = BCD2BIN(data);
241
242 data = rs5c313_read_reg(RS5C313_ADDR_DAY);
243 data |= (rs5c313_read_reg(RS5C313_ADDR_DAY10) << 4);
244 tm->tm_mday = BCD2BIN(data);
245
246 data = rs5c313_read_reg(RS5C313_ADDR_MON);
247 data |= (rs5c313_read_reg(RS5C313_ADDR_MON10) << 4);
248 tm->tm_mon = BCD2BIN(data) - 1;
249
250 data = rs5c313_read_reg(RS5C313_ADDR_YEAR);
251 data |= (rs5c313_read_reg(RS5C313_ADDR_YEAR10) << 4);
252 tm->tm_year = BCD2BIN(data);
253
254 if (tm->tm_year < 70)
255 tm->tm_year += 100;
256
257 data = rs5c313_read_reg(RS5C313_ADDR_WEEK);
258 tm->tm_wday = BCD2BIN(data);
259
260 RS5C313_CEDISABLE;
261 ndelay(700); /* CE:L */
262
263 return 0;
264}
265
266static int rs5c313_rtc_set_time(struct device *dev, struct rtc_time *tm)
267{
268 int data;
269
270 /* busy check. */
271 while (1) {
272 RS5C313_CEENABLE; /* CE:H */
273
274 /* Initiatlize control reg. 24 hour */
275 rs5c313_write_cntreg(0x04);
276
277 if (!(rs5c313_read_cntreg() & RS5C313_CNTREG_ADJ_BSY))
278 break;
279 RS5C313_MISCOP;
280 RS5C313_CEDISABLE;
281 ndelay(700); /* CE:L */
282 }
283
284 data = BIN2BCD(tm->tm_sec);
285 rs5c313_write_reg(RS5C313_ADDR_SEC, data);
286 rs5c313_write_reg(RS5C313_ADDR_SEC10, (data >> 4));
287
288 data = BIN2BCD(tm->tm_min);
289 rs5c313_write_reg(RS5C313_ADDR_MIN, data );
290 rs5c313_write_reg(RS5C313_ADDR_MIN10, (data >> 4));
291
292 data = BIN2BCD(tm->tm_hour);
293 rs5c313_write_reg(RS5C313_ADDR_HOUR, data);
294 rs5c313_write_reg(RS5C313_ADDR_HOUR10, (data >> 4));
295
296 data = BIN2BCD(tm->tm_mday);
297 rs5c313_write_reg(RS5C313_ADDR_DAY, data);
298 rs5c313_write_reg(RS5C313_ADDR_DAY10, (data>> 4));
299
300 data = BIN2BCD(tm->tm_mon + 1);
301 rs5c313_write_reg(RS5C313_ADDR_MON, data);
302 rs5c313_write_reg(RS5C313_ADDR_MON10, (data >> 4));
303
304 data = BIN2BCD(tm->tm_year % 100);
305 rs5c313_write_reg(RS5C313_ADDR_YEAR, data);
306 rs5c313_write_reg(RS5C313_ADDR_YEAR10, (data >> 4));
307
308 data = BIN2BCD(tm->tm_wday);
309 rs5c313_write_reg(RS5C313_ADDR_WEEK, data);
310
311 RS5C313_CEDISABLE; /* CE:H */
312 ndelay(700);
313
314 return 0;
315}
316
317static void rs5c313_check_xstp_bit(void)
318{
319 struct rtc_time tm;
320
321 RS5C313_CEENABLE; /* CE:H */
322 if (rs5c313_read_cntreg() & RS5C313_CNTREG_WTEN_XSTP) {
323 /* INT interval reg. OFF */
324 rs5c313_write_intintvreg(0x00);
325 /* Initialize control reg. 24 hour & adjust */
326 rs5c313_write_cntreg(0x07);
327
328 /* busy check. */
329 while (rs5c313_read_cntreg() & RS5C313_CNTREG_ADJ_BSY)
330 RS5C313_MISCOP;
331
332 memset(&tm, 0, sizeof(struct rtc_time));
333 tm.tm_mday = 1;
334 tm.tm_mon = 1;
335
336 rs5c313_rtc_set_time(NULL, &tm);
337 printk(KERN_ERR "RICHO RS5C313: invalid value, resetting to "
338 "1 Jan 2000\n");
339 }
340 RS5C313_CEDISABLE;
341 ndelay(700); /* CE:L */
342}
343
344static const struct rtc_class_ops rs5c313_rtc_ops = {
345 .read_time = rs5c313_rtc_read_time,
346 .set_time = rs5c313_rtc_set_time,
347};
348
349static int rs5c313_rtc_probe(struct platform_device *pdev)
350{
351 struct rtc_device *rtc = rtc_device_register("rs5c313", &pdev->dev,
352 &rs5c313_rtc_ops, THIS_MODULE);
353
354 if (IS_ERR(rtc))
355 return PTR_ERR(rtc);
356
357 platform_set_drvdata(pdev, rtc);
358
359 return err;
360}
361
362static int __devexit rs5c313_rtc_remove(struct platform_device *pdev)
363{
364 struct rtc_device *rtc = platform_get_drvdata( pdev );
365
366 rtc_device_unregister(rtc);
367
368 return 0;
369}
370
371static struct platform_driver rs5c313_rtc_platform_driver = {
372 .driver = {
373 .name = DRV_NAME,
374 .owner = THIS_MODULE,
375 },
376 .probe = rs5c313_rtc_probe,
377 .remove = __devexit_p( rs5c313_rtc_remove ),
378};
379
380static int __init rs5c313_rtc_init(void)
381{
382 int err;
383
384 err = platform_driver_register(&rs5c313_rtc_platform_driver);
385 if (err)
386 return err;
387
388 rs5c313_init_port();
389 rs5c313_check_xstp_bit();
390
391 return 0;
392}
393
394static void __exit rs5c313_rtc_exit(void)
395{
396 platform_driver_unregister( &rs5c313_rtc_platform_driver );
397}
398
399module_init(rs5c313_rtc_init);
400module_exit(rs5c313_rtc_exit);
401
402MODULE_VERSION(DRV_VERSION);
403MODULE_AUTHOR("kogiidena , Nobuhiro Iwamatsu <iwamatsu@nigauri.org>");
404MODULE_DESCRIPTION("Ricoh RS5C313 RTC device driver");
405MODULE_LICENSE("GPL");
diff --git a/drivers/rtc/rtc-s3c.c b/drivers/rtc/rtc-s3c.c
index 9a79a24a7487..54b613053468 100644
--- a/drivers/rtc/rtc-s3c.c
+++ b/drivers/rtc/rtc-s3c.c
@@ -50,7 +50,7 @@ static irqreturn_t s3c_rtc_alarmirq(int irq, void *id)
50{ 50{
51 struct rtc_device *rdev = id; 51 struct rtc_device *rdev = id;
52 52
53 rtc_update_irq(&rdev->class_dev, 1, RTC_AF | RTC_IRQF); 53 rtc_update_irq(rdev, 1, RTC_AF | RTC_IRQF);
54 return IRQ_HANDLED; 54 return IRQ_HANDLED;
55} 55}
56 56
@@ -58,7 +58,7 @@ static irqreturn_t s3c_rtc_tickirq(int irq, void *id)
58{ 58{
59 struct rtc_device *rdev = id; 59 struct rtc_device *rdev = id;
60 60
61 rtc_update_irq(&rdev->class_dev, tick_count++, RTC_PF | RTC_IRQF); 61 rtc_update_irq(rdev, tick_count++, RTC_PF | RTC_IRQF);
62 return IRQ_HANDLED; 62 return IRQ_HANDLED;
63} 63}
64 64
@@ -548,37 +548,15 @@ static int ticnt_save;
548 548
549static int s3c_rtc_suspend(struct platform_device *pdev, pm_message_t state) 549static int s3c_rtc_suspend(struct platform_device *pdev, pm_message_t state)
550{ 550{
551 struct rtc_time tm;
552 struct timespec time;
553
554 time.tv_nsec = 0;
555
556 /* save TICNT for anyone using periodic interrupts */ 551 /* save TICNT for anyone using periodic interrupts */
557
558 ticnt_save = readb(s3c_rtc_base + S3C2410_TICNT); 552 ticnt_save = readb(s3c_rtc_base + S3C2410_TICNT);
559
560 /* calculate time delta for suspend */
561
562 s3c_rtc_gettime(&pdev->dev, &tm);
563 rtc_tm_to_time(&tm, &time.tv_sec);
564 save_time_delta(&s3c_rtc_delta, &time);
565 s3c_rtc_enable(pdev, 0); 553 s3c_rtc_enable(pdev, 0);
566
567 return 0; 554 return 0;
568} 555}
569 556
570static int s3c_rtc_resume(struct platform_device *pdev) 557static int s3c_rtc_resume(struct platform_device *pdev)
571{ 558{
572 struct rtc_time tm;
573 struct timespec time;
574
575 time.tv_nsec = 0;
576
577 s3c_rtc_enable(pdev, 1); 559 s3c_rtc_enable(pdev, 1);
578 s3c_rtc_gettime(&pdev->dev, &tm);
579 rtc_tm_to_time(&tm, &time.tv_sec);
580 restore_time_delta(&s3c_rtc_delta, &time);
581
582 writeb(ticnt_save, s3c_rtc_base + S3C2410_TICNT); 560 writeb(ticnt_save, s3c_rtc_base + S3C2410_TICNT);
583 return 0; 561 return 0;
584} 562}
diff --git a/drivers/rtc/rtc-sa1100.c b/drivers/rtc/rtc-sa1100.c
index 677bae820dc3..0918b787c4dd 100644
--- a/drivers/rtc/rtc-sa1100.c
+++ b/drivers/rtc/rtc-sa1100.c
@@ -93,7 +93,7 @@ static irqreturn_t sa1100_rtc_interrupt(int irq, void *dev_id)
93 if (rtsr & RTSR_HZ) 93 if (rtsr & RTSR_HZ)
94 events |= RTC_UF | RTC_IRQF; 94 events |= RTC_UF | RTC_IRQF;
95 95
96 rtc_update_irq(&rtc->class_dev, 1, events); 96 rtc_update_irq(rtc, 1, events);
97 97
98 if (rtsr & RTSR_AL && rtc_periodic_alarm(&rtc_alarm)) 98 if (rtsr & RTSR_AL && rtc_periodic_alarm(&rtc_alarm))
99 rtc_update_alarm(&rtc_alarm); 99 rtc_update_alarm(&rtc_alarm);
@@ -119,7 +119,7 @@ static irqreturn_t timer1_interrupt(int irq, void *dev_id)
119 */ 119 */
120 OSSR = OSSR_M1; /* clear match on timer1 */ 120 OSSR = OSSR_M1; /* clear match on timer1 */
121 121
122 rtc_update_irq(&rtc->class_dev, rtc_timer1_count, RTC_PF | RTC_IRQF); 122 rtc_update_irq(rtc, rtc_timer1_count, RTC_PF | RTC_IRQF);
123 123
124 if (rtc_timer1_count == 1) 124 if (rtc_timer1_count == 1)
125 rtc_timer1_count = (rtc_freq * ((1<<30)/(TIMER_FREQ>>2))); 125 rtc_timer1_count = (rtc_freq * ((1<<30)/(TIMER_FREQ>>2)));
diff --git a/drivers/rtc/rtc-sh.c b/drivers/rtc/rtc-sh.c
index 198b9f22fbff..6abf4811958c 100644
--- a/drivers/rtc/rtc-sh.c
+++ b/drivers/rtc/rtc-sh.c
@@ -104,7 +104,7 @@ static irqreturn_t sh_rtc_interrupt(int irq, void *dev_id)
104 104
105 writeb(tmp, rtc->regbase + RCR1); 105 writeb(tmp, rtc->regbase + RCR1);
106 106
107 rtc_update_irq(&rtc->rtc_dev->class_dev, 1, events); 107 rtc_update_irq(&rtc->rtc_dev, 1, events);
108 108
109 spin_unlock(&rtc->lock); 109 spin_unlock(&rtc->lock);
110 110
@@ -139,7 +139,7 @@ static irqreturn_t sh_rtc_alarm(int irq, void *dev_id)
139 139
140 rtc->rearm_aie = 1; 140 rtc->rearm_aie = 1;
141 141
142 rtc_update_irq(&rtc->rtc_dev->class_dev, 1, events); 142 rtc_update_irq(&rtc->rtc_dev, 1, events);
143 } 143 }
144 144
145 spin_unlock(&rtc->lock); 145 spin_unlock(&rtc->lock);
@@ -153,7 +153,7 @@ static irqreturn_t sh_rtc_periodic(int irq, void *dev_id)
153 153
154 spin_lock(&rtc->lock); 154 spin_lock(&rtc->lock);
155 155
156 rtc_update_irq(&rtc->rtc_dev->class_dev, 1, RTC_PF | RTC_IRQF); 156 rtc_update_irq(&rtc->rtc_dev, 1, RTC_PF | RTC_IRQF);
157 157
158 spin_unlock(&rtc->lock); 158 spin_unlock(&rtc->lock);
159 159
diff --git a/drivers/rtc/rtc-sysfs.c b/drivers/rtc/rtc-sysfs.c
index 899ab8c514fa..69df94b44841 100644
--- a/drivers/rtc/rtc-sysfs.c
+++ b/drivers/rtc/rtc-sysfs.c
@@ -12,20 +12,26 @@
12#include <linux/module.h> 12#include <linux/module.h>
13#include <linux/rtc.h> 13#include <linux/rtc.h>
14 14
15#include "rtc-core.h"
16
17
15/* device attributes */ 18/* device attributes */
16 19
17static ssize_t rtc_sysfs_show_name(struct class_device *dev, char *buf) 20static ssize_t
21rtc_sysfs_show_name(struct device *dev, struct device_attribute *attr,
22 char *buf)
18{ 23{
19 return sprintf(buf, "%s\n", to_rtc_device(dev)->name); 24 return sprintf(buf, "%s\n", to_rtc_device(dev)->name);
20} 25}
21static CLASS_DEVICE_ATTR(name, S_IRUGO, rtc_sysfs_show_name, NULL);
22 26
23static ssize_t rtc_sysfs_show_date(struct class_device *dev, char *buf) 27static ssize_t
28rtc_sysfs_show_date(struct device *dev, struct device_attribute *attr,
29 char *buf)
24{ 30{
25 ssize_t retval; 31 ssize_t retval;
26 struct rtc_time tm; 32 struct rtc_time tm;
27 33
28 retval = rtc_read_time(dev, &tm); 34 retval = rtc_read_time(to_rtc_device(dev), &tm);
29 if (retval == 0) { 35 if (retval == 0) {
30 retval = sprintf(buf, "%04d-%02d-%02d\n", 36 retval = sprintf(buf, "%04d-%02d-%02d\n",
31 tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday); 37 tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday);
@@ -33,14 +39,15 @@ static ssize_t rtc_sysfs_show_date(struct class_device *dev, char *buf)
33 39
34 return retval; 40 return retval;
35} 41}
36static CLASS_DEVICE_ATTR(date, S_IRUGO, rtc_sysfs_show_date, NULL);
37 42
38static ssize_t rtc_sysfs_show_time(struct class_device *dev, char *buf) 43static ssize_t
44rtc_sysfs_show_time(struct device *dev, struct device_attribute *attr,
45 char *buf)
39{ 46{
40 ssize_t retval; 47 ssize_t retval;
41 struct rtc_time tm; 48 struct rtc_time tm;
42 49
43 retval = rtc_read_time(dev, &tm); 50 retval = rtc_read_time(to_rtc_device(dev), &tm);
44 if (retval == 0) { 51 if (retval == 0) {
45 retval = sprintf(buf, "%02d:%02d:%02d\n", 52 retval = sprintf(buf, "%02d:%02d:%02d\n",
46 tm.tm_hour, tm.tm_min, tm.tm_sec); 53 tm.tm_hour, tm.tm_min, tm.tm_sec);
@@ -48,14 +55,15 @@ static ssize_t rtc_sysfs_show_time(struct class_device *dev, char *buf)
48 55
49 return retval; 56 return retval;
50} 57}
51static CLASS_DEVICE_ATTR(time, S_IRUGO, rtc_sysfs_show_time, NULL);
52 58
53static ssize_t rtc_sysfs_show_since_epoch(struct class_device *dev, char *buf) 59static ssize_t
60rtc_sysfs_show_since_epoch(struct device *dev, struct device_attribute *attr,
61 char *buf)
54{ 62{
55 ssize_t retval; 63 ssize_t retval;
56 struct rtc_time tm; 64 struct rtc_time tm;
57 65
58 retval = rtc_read_time(dev, &tm); 66 retval = rtc_read_time(to_rtc_device(dev), &tm);
59 if (retval == 0) { 67 if (retval == 0) {
60 unsigned long time; 68 unsigned long time;
61 rtc_tm_to_time(&tm, &time); 69 rtc_tm_to_time(&tm, &time);
@@ -64,23 +72,18 @@ static ssize_t rtc_sysfs_show_since_epoch(struct class_device *dev, char *buf)
64 72
65 return retval; 73 return retval;
66} 74}
67static CLASS_DEVICE_ATTR(since_epoch, S_IRUGO, rtc_sysfs_show_since_epoch, NULL);
68
69static struct attribute *rtc_attrs[] = {
70 &class_device_attr_name.attr,
71 &class_device_attr_date.attr,
72 &class_device_attr_time.attr,
73 &class_device_attr_since_epoch.attr,
74 NULL,
75};
76 75
77static struct attribute_group rtc_attr_group = { 76static struct device_attribute rtc_attrs[] = {
78 .attrs = rtc_attrs, 77 __ATTR(name, S_IRUGO, rtc_sysfs_show_name, NULL),
78 __ATTR(date, S_IRUGO, rtc_sysfs_show_date, NULL),
79 __ATTR(time, S_IRUGO, rtc_sysfs_show_time, NULL),
80 __ATTR(since_epoch, S_IRUGO, rtc_sysfs_show_since_epoch, NULL),
81 { },
79}; 82};
80 83
81
82static ssize_t 84static ssize_t
83rtc_sysfs_show_wakealarm(struct class_device *dev, char *buf) 85rtc_sysfs_show_wakealarm(struct device *dev, struct device_attribute *attr,
86 char *buf)
84{ 87{
85 ssize_t retval; 88 ssize_t retval;
86 unsigned long alarm; 89 unsigned long alarm;
@@ -94,7 +97,7 @@ rtc_sysfs_show_wakealarm(struct class_device *dev, char *buf)
94 * REVISIT maybe we should require RTC implementations to 97 * REVISIT maybe we should require RTC implementations to
95 * disable the RTC alarm after it triggers, for uniformity. 98 * disable the RTC alarm after it triggers, for uniformity.
96 */ 99 */
97 retval = rtc_read_alarm(dev, &alm); 100 retval = rtc_read_alarm(to_rtc_device(dev), &alm);
98 if (retval == 0 && alm.enabled) { 101 if (retval == 0 && alm.enabled) {
99 rtc_tm_to_time(&alm.time, &alarm); 102 rtc_tm_to_time(&alm.time, &alarm);
100 retval = sprintf(buf, "%lu\n", alarm); 103 retval = sprintf(buf, "%lu\n", alarm);
@@ -104,16 +107,18 @@ rtc_sysfs_show_wakealarm(struct class_device *dev, char *buf)
104} 107}
105 108
106static ssize_t 109static ssize_t
107rtc_sysfs_set_wakealarm(struct class_device *dev, const char *buf, size_t n) 110rtc_sysfs_set_wakealarm(struct device *dev, struct device_attribute *attr,
111 const char *buf, size_t n)
108{ 112{
109 ssize_t retval; 113 ssize_t retval;
110 unsigned long now, alarm; 114 unsigned long now, alarm;
111 struct rtc_wkalrm alm; 115 struct rtc_wkalrm alm;
116 struct rtc_device *rtc = to_rtc_device(dev);
112 117
113 /* Only request alarms that trigger in the future. Disable them 118 /* Only request alarms that trigger in the future. Disable them
114 * by writing another time, e.g. 0 meaning Jan 1 1970 UTC. 119 * by writing another time, e.g. 0 meaning Jan 1 1970 UTC.
115 */ 120 */
116 retval = rtc_read_time(dev, &alm.time); 121 retval = rtc_read_time(rtc, &alm.time);
117 if (retval < 0) 122 if (retval < 0)
118 return retval; 123 return retval;
119 rtc_tm_to_time(&alm.time, &now); 124 rtc_tm_to_time(&alm.time, &now);
@@ -124,7 +129,7 @@ rtc_sysfs_set_wakealarm(struct class_device *dev, const char *buf, size_t n)
124 * entirely prevent that here, without even the minimal 129 * entirely prevent that here, without even the minimal
125 * locking from the /dev/rtcN api. 130 * locking from the /dev/rtcN api.
126 */ 131 */
127 retval = rtc_read_alarm(dev, &alm); 132 retval = rtc_read_alarm(rtc, &alm);
128 if (retval < 0) 133 if (retval < 0)
129 return retval; 134 return retval;
130 if (alm.enabled) 135 if (alm.enabled)
@@ -141,10 +146,10 @@ rtc_sysfs_set_wakealarm(struct class_device *dev, const char *buf, size_t n)
141 } 146 }
142 rtc_time_to_tm(alarm, &alm.time); 147 rtc_time_to_tm(alarm, &alm.time);
143 148
144 retval = rtc_set_alarm(dev, &alm); 149 retval = rtc_set_alarm(rtc, &alm);
145 return (retval < 0) ? retval : n; 150 return (retval < 0) ? retval : n;
146} 151}
147static const CLASS_DEVICE_ATTR(wakealarm, S_IRUGO | S_IWUSR, 152static DEVICE_ATTR(wakealarm, S_IRUGO | S_IWUSR,
148 rtc_sysfs_show_wakealarm, rtc_sysfs_set_wakealarm); 153 rtc_sysfs_show_wakealarm, rtc_sysfs_set_wakealarm);
149 154
150 155
@@ -153,71 +158,37 @@ static const CLASS_DEVICE_ATTR(wakealarm, S_IRUGO | S_IWUSR,
153 * suspend-to-disk. So: no attribute unless that side effect is possible. 158 * suspend-to-disk. So: no attribute unless that side effect is possible.
154 * (Userspace may disable that mechanism later.) 159 * (Userspace may disable that mechanism later.)
155 */ 160 */
156static inline int rtc_does_wakealarm(struct class_device *class_dev) 161static inline int rtc_does_wakealarm(struct rtc_device *rtc)
157{ 162{
158 struct rtc_device *rtc; 163 if (!device_can_wakeup(rtc->dev.parent))
159
160 if (!device_can_wakeup(class_dev->dev))
161 return 0; 164 return 0;
162 rtc = to_rtc_device(class_dev);
163 return rtc->ops->set_alarm != NULL; 165 return rtc->ops->set_alarm != NULL;
164} 166}
165 167
166 168
167static int rtc_sysfs_add_device(struct class_device *class_dev, 169void rtc_sysfs_add_device(struct rtc_device *rtc)
168 struct class_interface *class_intf)
169{ 170{
170 int err; 171 int err;
171 172
172 dev_dbg(class_dev->dev, "rtc intf: sysfs\n"); 173 /* not all RTCs support both alarms and wakeup */
174 if (!rtc_does_wakealarm(rtc))
175 return;
173 176
174 err = sysfs_create_group(&class_dev->kobj, &rtc_attr_group); 177 err = device_create_file(&rtc->dev, &dev_attr_wakealarm);
175 if (err) 178 if (err)
176 dev_err(class_dev->dev, "failed to create %s\n", 179 dev_err(rtc->dev.parent, "failed to create "
177 "sysfs attributes"); 180 "alarm attribute, %d",
178 else if (rtc_does_wakealarm(class_dev)) { 181 err);
179 /* not all RTCs support both alarms and wakeup */
180 err = class_device_create_file(class_dev,
181 &class_device_attr_wakealarm);
182 if (err) {
183 dev_err(class_dev->dev, "failed to create %s\n",
184 "alarm attribute");
185 sysfs_remove_group(&class_dev->kobj, &rtc_attr_group);
186 }
187 }
188
189 return err;
190} 182}
191 183
192static void rtc_sysfs_remove_device(struct class_device *class_dev, 184void rtc_sysfs_del_device(struct rtc_device *rtc)
193 struct class_interface *class_intf)
194{ 185{
195 if (rtc_does_wakealarm(class_dev)) 186 /* REVISIT did we add it successfully? */
196 class_device_remove_file(class_dev, 187 if (rtc_does_wakealarm(rtc))
197 &class_device_attr_wakealarm); 188 device_remove_file(&rtc->dev, &dev_attr_wakealarm);
198 sysfs_remove_group(&class_dev->kobj, &rtc_attr_group);
199} 189}
200 190
201/* interface registration */ 191void __init rtc_sysfs_init(struct class *rtc_class)
202
203static struct class_interface rtc_sysfs_interface = {
204 .add = &rtc_sysfs_add_device,
205 .remove = &rtc_sysfs_remove_device,
206};
207
208static int __init rtc_sysfs_init(void)
209{ 192{
210 return rtc_interface_register(&rtc_sysfs_interface); 193 rtc_class->dev_attrs = rtc_attrs;
211} 194}
212
213static void __exit rtc_sysfs_exit(void)
214{
215 class_interface_unregister(&rtc_sysfs_interface);
216}
217
218subsys_initcall(rtc_sysfs_init);
219module_exit(rtc_sysfs_exit);
220
221MODULE_AUTHOR("Alessandro Zummo <a.zummo@towertech.it>");
222MODULE_DESCRIPTION("RTC class sysfs interface");
223MODULE_LICENSE("GPL");
diff --git a/drivers/rtc/rtc-test.c b/drivers/rtc/rtc-test.c
index f50a1b8e1607..254c9fce27da 100644
--- a/drivers/rtc/rtc-test.c
+++ b/drivers/rtc/rtc-test.c
@@ -101,11 +101,11 @@ static ssize_t test_irq_store(struct device *dev,
101 retval = count; 101 retval = count;
102 local_irq_disable(); 102 local_irq_disable();
103 if (strncmp(buf, "tick", 4) == 0) 103 if (strncmp(buf, "tick", 4) == 0)
104 rtc_update_irq(&rtc->class_dev, 1, RTC_PF | RTC_IRQF); 104 rtc_update_irq(rtc, 1, RTC_PF | RTC_IRQF);
105 else if (strncmp(buf, "alarm", 5) == 0) 105 else if (strncmp(buf, "alarm", 5) == 0)
106 rtc_update_irq(&rtc->class_dev, 1, RTC_AF | RTC_IRQF); 106 rtc_update_irq(rtc, 1, RTC_AF | RTC_IRQF);
107 else if (strncmp(buf, "update", 6) == 0) 107 else if (strncmp(buf, "update", 6) == 0)
108 rtc_update_irq(&rtc->class_dev, 1, RTC_UF | RTC_IRQF); 108 rtc_update_irq(rtc, 1, RTC_UF | RTC_IRQF);
109 else 109 else
110 retval = -EINVAL; 110 retval = -EINVAL;
111 local_irq_enable(); 111 local_irq_enable();
diff --git a/drivers/rtc/rtc-vr41xx.c b/drivers/rtc/rtc-vr41xx.c
index e40322b71938..af7596ef29e2 100644
--- a/drivers/rtc/rtc-vr41xx.c
+++ b/drivers/rtc/rtc-vr41xx.c
@@ -97,6 +97,7 @@ static DEFINE_SPINLOCK(rtc_lock);
97static char rtc_name[] = "RTC"; 97static char rtc_name[] = "RTC";
98static unsigned long periodic_frequency; 98static unsigned long periodic_frequency;
99static unsigned long periodic_count; 99static unsigned long periodic_count;
100static unsigned int alarm_enabled;
100 101
101struct resource rtc_resource[2] = { 102struct resource rtc_resource[2] = {
102 { .name = rtc_name, 103 { .name = rtc_name,
@@ -188,6 +189,7 @@ static int vr41xx_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *wkalrm)
188 low = rtc1_read(ECMPLREG); 189 low = rtc1_read(ECMPLREG);
189 mid = rtc1_read(ECMPMREG); 190 mid = rtc1_read(ECMPMREG);
190 high = rtc1_read(ECMPHREG); 191 high = rtc1_read(ECMPHREG);
192 wkalrm->enabled = alarm_enabled;
191 193
192 spin_unlock_irq(&rtc_lock); 194 spin_unlock_irq(&rtc_lock);
193 195
@@ -206,10 +208,18 @@ static int vr41xx_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *wkalrm)
206 208
207 spin_lock_irq(&rtc_lock); 209 spin_lock_irq(&rtc_lock);
208 210
211 if (alarm_enabled)
212 disable_irq(ELAPSEDTIME_IRQ);
213
209 rtc1_write(ECMPLREG, (uint16_t)(alarm_sec << 15)); 214 rtc1_write(ECMPLREG, (uint16_t)(alarm_sec << 15));
210 rtc1_write(ECMPMREG, (uint16_t)(alarm_sec >> 1)); 215 rtc1_write(ECMPMREG, (uint16_t)(alarm_sec >> 1));
211 rtc1_write(ECMPHREG, (uint16_t)(alarm_sec >> 17)); 216 rtc1_write(ECMPHREG, (uint16_t)(alarm_sec >> 17));
212 217
218 if (wkalrm->enabled)
219 enable_irq(ELAPSEDTIME_IRQ);
220
221 alarm_enabled = wkalrm->enabled;
222
213 spin_unlock_irq(&rtc_lock); 223 spin_unlock_irq(&rtc_lock);
214 224
215 return 0; 225 return 0;
@@ -221,10 +231,24 @@ static int vr41xx_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long
221 231
222 switch (cmd) { 232 switch (cmd) {
223 case RTC_AIE_ON: 233 case RTC_AIE_ON:
224 enable_irq(ELAPSEDTIME_IRQ); 234 spin_lock_irq(&rtc_lock);
235
236 if (!alarm_enabled) {
237 enable_irq(ELAPSEDTIME_IRQ);
238 alarm_enabled = 1;
239 }
240
241 spin_unlock_irq(&rtc_lock);
225 break; 242 break;
226 case RTC_AIE_OFF: 243 case RTC_AIE_OFF:
227 disable_irq(ELAPSEDTIME_IRQ); 244 spin_lock_irq(&rtc_lock);
245
246 if (alarm_enabled) {
247 disable_irq(ELAPSEDTIME_IRQ);
248 alarm_enabled = 0;
249 }
250
251 spin_unlock_irq(&rtc_lock);
228 break; 252 break;
229 case RTC_PIE_ON: 253 case RTC_PIE_ON:
230 enable_irq(RTCLONG1_IRQ); 254 enable_irq(RTCLONG1_IRQ);
@@ -275,7 +299,7 @@ static irqreturn_t elapsedtime_interrupt(int irq, void *dev_id)
275 299
276 rtc2_write(RTCINTREG, ELAPSEDTIME_INT); 300 rtc2_write(RTCINTREG, ELAPSEDTIME_INT);
277 301
278 rtc_update_irq(&rtc->class_dev, 1, RTC_AF); 302 rtc_update_irq(rtc, 1, RTC_AF);
279 303
280 return IRQ_HANDLED; 304 return IRQ_HANDLED;
281} 305}
@@ -291,7 +315,7 @@ static irqreturn_t rtclong1_interrupt(int irq, void *dev_id)
291 rtc1_write(RTCL1LREG, count); 315 rtc1_write(RTCL1LREG, count);
292 rtc1_write(RTCL1HREG, count >> 16); 316 rtc1_write(RTCL1HREG, count >> 16);
293 317
294 rtc_update_irq(&rtc->class_dev, 1, RTC_PF); 318 rtc_update_irq(rtc, 1, RTC_PF);
295 319
296 return IRQ_HANDLED; 320 return IRQ_HANDLED;
297} 321}
diff --git a/drivers/sbus/char/bpp.c b/drivers/sbus/char/bpp.c
index a39ee80c9715..74b999d77bbf 100644
--- a/drivers/sbus/char/bpp.c
+++ b/drivers/sbus/char/bpp.c
@@ -15,7 +15,6 @@
15#include <linux/fs.h> 15#include <linux/fs.h>
16#include <linux/errno.h> 16#include <linux/errno.h>
17#include <linux/sched.h> 17#include <linux/sched.h>
18#include <linux/smp_lock.h>
19#include <linux/spinlock.h> 18#include <linux/spinlock.h>
20#include <linux/timer.h> 19#include <linux/timer.h>
21#include <linux/ioport.h> 20#include <linux/ioport.h>
diff --git a/drivers/sbus/char/rtc.c b/drivers/sbus/char/rtc.c
index 94d185829119..18d18f1a114e 100644
--- a/drivers/sbus/char/rtc.c
+++ b/drivers/sbus/char/rtc.c
@@ -19,7 +19,6 @@
19#include <linux/fcntl.h> 19#include <linux/fcntl.h>
20#include <linux/poll.h> 20#include <linux/poll.h>
21#include <linux/init.h> 21#include <linux/init.h>
22#include <linux/smp_lock.h>
23#include <asm/io.h> 22#include <asm/io.h>
24#include <asm/mostek.h> 23#include <asm/mostek.h>
25#include <asm/system.h> 24#include <asm/system.h>
diff --git a/drivers/sbus/char/vfc_dev.c b/drivers/sbus/char/vfc_dev.c
index c3135e2fbd5a..6afc7e5df0d4 100644
--- a/drivers/sbus/char/vfc_dev.c
+++ b/drivers/sbus/char/vfc_dev.c
@@ -20,7 +20,6 @@
20#include <linux/slab.h> 20#include <linux/slab.h>
21#include <linux/errno.h> 21#include <linux/errno.h>
22#include <linux/fs.h> 22#include <linux/fs.h>
23#include <linux/smp_lock.h>
24#include <linux/delay.h> 23#include <linux/delay.h>
25#include <linux/spinlock.h> 24#include <linux/spinlock.h>
26#include <linux/mm.h> 25#include <linux/mm.h>
diff --git a/drivers/scsi/aic7xxx/aic79xx_osm.h b/drivers/scsi/aic7xxx/aic79xx_osm.h
index 9218f29314fa..ad9761b237dc 100644
--- a/drivers/scsi/aic7xxx/aic79xx_osm.h
+++ b/drivers/scsi/aic7xxx/aic79xx_osm.h
@@ -47,7 +47,6 @@
47#include <linux/delay.h> 47#include <linux/delay.h>
48#include <linux/ioport.h> 48#include <linux/ioport.h>
49#include <linux/pci.h> 49#include <linux/pci.h>
50#include <linux/smp_lock.h>
51#include <linux/interrupt.h> 50#include <linux/interrupt.h>
52#include <linux/module.h> 51#include <linux/module.h>
53#include <linux/slab.h> 52#include <linux/slab.h>
diff --git a/drivers/scsi/aic7xxx/aic7xxx_osm.h b/drivers/scsi/aic7xxx/aic7xxx_osm.h
index 85ae5d836fa4..8fee7edc6eb3 100644
--- a/drivers/scsi/aic7xxx/aic7xxx_osm.h
+++ b/drivers/scsi/aic7xxx/aic7xxx_osm.h
@@ -64,7 +64,6 @@
64#include <linux/delay.h> 64#include <linux/delay.h>
65#include <linux/ioport.h> 65#include <linux/ioport.h>
66#include <linux/pci.h> 66#include <linux/pci.h>
67#include <linux/smp_lock.h>
68#include <linux/interrupt.h> 67#include <linux/interrupt.h>
69#include <linux/module.h> 68#include <linux/module.h>
70#include <linux/slab.h> 69#include <linux/slab.h>
diff --git a/drivers/scsi/dpt_i2o.c b/drivers/scsi/dpt_i2o.c
index f7b9dbd64a96..fb6433a56989 100644
--- a/drivers/scsi/dpt_i2o.c
+++ b/drivers/scsi/dpt_i2o.c
@@ -55,7 +55,6 @@ MODULE_DESCRIPTION("Adaptec I2O RAID Driver");
55#include <linux/sched.h> 55#include <linux/sched.h>
56#include <linux/reboot.h> 56#include <linux/reboot.h>
57#include <linux/spinlock.h> 57#include <linux/spinlock.h>
58#include <linux/smp_lock.h>
59#include <linux/dma-mapping.h> 58#include <linux/dma-mapping.h>
60 59
61#include <linux/timer.h> 60#include <linux/timer.h>
diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c
index 3e2930b7ee23..06229f225ee9 100644
--- a/drivers/scsi/scsi_debug.c
+++ b/drivers/scsi/scsi_debug.c
@@ -36,7 +36,6 @@
36#include <linux/fs.h> 36#include <linux/fs.h>
37#include <linux/init.h> 37#include <linux/init.h>
38#include <linux/proc_fs.h> 38#include <linux/proc_fs.h>
39#include <linux/smp_lock.h>
40#include <linux/vmalloc.h> 39#include <linux/vmalloc.h>
41#include <linux/moduleparam.h> 40#include <linux/moduleparam.h>
42 41
diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c
index 570977cf9efb..0c691a60a756 100644
--- a/drivers/scsi/sg.c
+++ b/drivers/scsi/sg.c
@@ -41,7 +41,6 @@ static int sg_version_num = 30534; /* 2 digits for each component */
41#include <linux/fcntl.h> 41#include <linux/fcntl.h>
42#include <linux/init.h> 42#include <linux/init.h>
43#include <linux/poll.h> 43#include <linux/poll.h>
44#include <linux/smp_lock.h>
45#include <linux/moduleparam.h> 44#include <linux/moduleparam.h>
46#include <linux/cdev.h> 45#include <linux/cdev.h>
47#include <linux/seq_file.h> 46#include <linux/seq_file.h>
diff --git a/drivers/scsi/sni_53c710.c b/drivers/scsi/sni_53c710.c
index 6bc505115841..a7dfb65fb842 100644
--- a/drivers/scsi/sni_53c710.c
+++ b/drivers/scsi/sni_53c710.c
@@ -98,7 +98,7 @@ static int __init snirm710_probe(struct platform_device *dev)
98 host->this_id = 7; 98 host->this_id = 7;
99 host->base = base; 99 host->base = base;
100 host->irq = platform_get_irq(dev, 0); 100 host->irq = platform_get_irq(dev, 0);
101 if(request_irq(host->irq, NCR_700_intr, SA_SHIRQ, "snirm710", host)) { 101 if(request_irq(host->irq, NCR_700_intr, IRQF_SHARED, "snirm710", host)) {
102 printk(KERN_ERR "snirm710: request_irq failed!\n"); 102 printk(KERN_ERR "snirm710: request_irq failed!\n");
103 goto out_put_host; 103 goto out_put_host;
104 } 104 }
diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c
index c9832d963f1e..48e259a0167d 100644
--- a/drivers/serial/8250.c
+++ b/drivers/serial/8250.c
@@ -994,7 +994,6 @@ static void autoconfig(struct uart_8250_port *up, unsigned int probeflags)
994 * be frobbing the chips IRQ enable register to see if it exists. 994 * be frobbing the chips IRQ enable register to see if it exists.
995 */ 995 */
996 spin_lock_irqsave(&up->port.lock, flags); 996 spin_lock_irqsave(&up->port.lock, flags);
997// save_flags(flags); cli();
998 997
999 up->capabilities = 0; 998 up->capabilities = 0;
1000 up->bugs = 0; 999 up->bugs = 0;
@@ -1151,7 +1150,6 @@ static void autoconfig(struct uart_8250_port *up, unsigned int probeflags)
1151 1150
1152 out: 1151 out:
1153 spin_unlock_irqrestore(&up->port.lock, flags); 1152 spin_unlock_irqrestore(&up->port.lock, flags);
1154// restore_flags(flags);
1155 DEBUG_AUTOCONF("type=%s\n", uart_config[up->port.type].name); 1153 DEBUG_AUTOCONF("type=%s\n", uart_config[up->port.type].name);
1156} 1154}
1157 1155
diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig
index 924e9bd757f0..e8efe938c4e7 100644
--- a/drivers/serial/Kconfig
+++ b/drivers/serial/Kconfig
@@ -73,17 +73,21 @@ config SERIAL_8250_PCI
73 depends on SERIAL_8250 && PCI 73 depends on SERIAL_8250 && PCI
74 default SERIAL_8250 74 default SERIAL_8250
75 help 75 help
76 This builds standard PCI serial support. You may be able to 76 Say Y here if you have PCI serial ports.
77 disable this feature if you only need legacy serial support. 77
78 Saves about 9K. 78 To compile this driver as a module, choose M here: the module
79 will be called 8250_pci.
79 80
80config SERIAL_8250_PNP 81config SERIAL_8250_PNP
81 tristate "8250/16550 PNP device support" if EMBEDDED 82 tristate "8250/16550 PNP device support" if EMBEDDED
82 depends on SERIAL_8250 && PNP 83 depends on SERIAL_8250 && PNP
83 default SERIAL_8250 84 default SERIAL_8250
84 help 85 help
85 This builds standard PNP serial support. You may be able to 86 Say Y here if you have serial ports described by PNPBIOS or ACPI.
86 disable this feature if you only need legacy serial support. 87 These are typically ports built into the system board.
88
89 To compile this driver as a module, choose M here: the module
90 will be called 8250_pnp.
87 91
88config SERIAL_8250_HP300 92config SERIAL_8250_HP300
89 tristate 93 tristate
diff --git a/drivers/serial/cpm_uart/cpm_uart_core.c b/drivers/serial/cpm_uart/cpm_uart_core.c
index 7a3b97fdf8d1..f23972bc00c0 100644
--- a/drivers/serial/cpm_uart/cpm_uart_core.c
+++ b/drivers/serial/cpm_uart/cpm_uart_core.c
@@ -934,7 +934,7 @@ struct uart_cpm_port cpm_uart_ports[UART_NR] = {
934 .irq = SMC1_IRQ, 934 .irq = SMC1_IRQ,
935 .ops = &cpm_uart_pops, 935 .ops = &cpm_uart_pops,
936 .iotype = UPIO_MEM, 936 .iotype = UPIO_MEM,
937 .lock = SPIN_LOCK_UNLOCKED, 937 .lock = __SPIN_LOCK_UNLOCKED(cpm_uart_ports[UART_SMC1].port.lock),
938 }, 938 },
939 .flags = FLAG_SMC, 939 .flags = FLAG_SMC,
940 .tx_nrfifos = TX_NUM_FIFO, 940 .tx_nrfifos = TX_NUM_FIFO,
@@ -948,7 +948,7 @@ struct uart_cpm_port cpm_uart_ports[UART_NR] = {
948 .irq = SMC2_IRQ, 948 .irq = SMC2_IRQ,
949 .ops = &cpm_uart_pops, 949 .ops = &cpm_uart_pops,
950 .iotype = UPIO_MEM, 950 .iotype = UPIO_MEM,
951 .lock = SPIN_LOCK_UNLOCKED, 951 .lock = __SPIN_LOCK_UNLOCKED(cpm_uart_ports[UART_SMC2].port.lock),
952 }, 952 },
953 .flags = FLAG_SMC, 953 .flags = FLAG_SMC,
954 .tx_nrfifos = TX_NUM_FIFO, 954 .tx_nrfifos = TX_NUM_FIFO,
@@ -965,7 +965,7 @@ struct uart_cpm_port cpm_uart_ports[UART_NR] = {
965 .irq = SCC1_IRQ, 965 .irq = SCC1_IRQ,
966 .ops = &cpm_uart_pops, 966 .ops = &cpm_uart_pops,
967 .iotype = UPIO_MEM, 967 .iotype = UPIO_MEM,
968 .lock = SPIN_LOCK_UNLOCKED, 968 .lock = __SPIN_LOCK_UNLOCKED(cpm_uart_ports[UART_SCC1].port.lock),
969 }, 969 },
970 .tx_nrfifos = TX_NUM_FIFO, 970 .tx_nrfifos = TX_NUM_FIFO,
971 .tx_fifosize = TX_BUF_SIZE, 971 .tx_fifosize = TX_BUF_SIZE,
@@ -979,7 +979,7 @@ struct uart_cpm_port cpm_uart_ports[UART_NR] = {
979 .irq = SCC2_IRQ, 979 .irq = SCC2_IRQ,
980 .ops = &cpm_uart_pops, 980 .ops = &cpm_uart_pops,
981 .iotype = UPIO_MEM, 981 .iotype = UPIO_MEM,
982 .lock = SPIN_LOCK_UNLOCKED, 982 .lock = __SPIN_LOCK_UNLOCKED(cpm_uart_ports[UART_SCC2].port.lock),
983 }, 983 },
984 .tx_nrfifos = TX_NUM_FIFO, 984 .tx_nrfifos = TX_NUM_FIFO,
985 .tx_fifosize = TX_BUF_SIZE, 985 .tx_fifosize = TX_BUF_SIZE,
@@ -993,7 +993,7 @@ struct uart_cpm_port cpm_uart_ports[UART_NR] = {
993 .irq = SCC3_IRQ, 993 .irq = SCC3_IRQ,
994 .ops = &cpm_uart_pops, 994 .ops = &cpm_uart_pops,
995 .iotype = UPIO_MEM, 995 .iotype = UPIO_MEM,
996 .lock = SPIN_LOCK_UNLOCKED, 996 .lock = __SPIN_LOCK_UNLOCKED(cpm_uart_ports[UART_SCC3].port.lock),
997 }, 997 },
998 .tx_nrfifos = TX_NUM_FIFO, 998 .tx_nrfifos = TX_NUM_FIFO,
999 .tx_fifosize = TX_BUF_SIZE, 999 .tx_fifosize = TX_BUF_SIZE,
@@ -1007,7 +1007,7 @@ struct uart_cpm_port cpm_uart_ports[UART_NR] = {
1007 .irq = SCC4_IRQ, 1007 .irq = SCC4_IRQ,
1008 .ops = &cpm_uart_pops, 1008 .ops = &cpm_uart_pops,
1009 .iotype = UPIO_MEM, 1009 .iotype = UPIO_MEM,
1010 .lock = SPIN_LOCK_UNLOCKED, 1010 .lock = __SPIN_LOCK_UNLOCKED(cpm_uart_ports[UART_SCC4].port.lock),
1011 }, 1011 },
1012 .tx_nrfifos = TX_NUM_FIFO, 1012 .tx_nrfifos = TX_NUM_FIFO,
1013 .tx_fifosize = TX_BUF_SIZE, 1013 .tx_fifosize = TX_BUF_SIZE,
diff --git a/drivers/serial/icom.c b/drivers/serial/icom.c
index 246c5572667b..6202995e8211 100644
--- a/drivers/serial/icom.c
+++ b/drivers/serial/icom.c
@@ -47,7 +47,6 @@
47#include <linux/pci.h> 47#include <linux/pci.h>
48#include <linux/vmalloc.h> 48#include <linux/vmalloc.h>
49#include <linux/smp.h> 49#include <linux/smp.h>
50#include <linux/smp_lock.h>
51#include <linux/spinlock.h> 50#include <linux/spinlock.h>
52#include <linux/kobject.h> 51#include <linux/kobject.h>
53#include <linux/firmware.h> 52#include <linux/firmware.h>
diff --git a/drivers/serial/jsm/jsm_neo.c b/drivers/serial/jsm/jsm_neo.c
index 8be8da37f629..b2d6f5b1a7c2 100644
--- a/drivers/serial/jsm/jsm_neo.c
+++ b/drivers/serial/jsm/jsm_neo.c
@@ -581,8 +581,13 @@ static void neo_parse_modem(struct jsm_channel *ch, u8 signals)
581 return; 581 return;
582 582
583 /* Scrub off lower bits. They signify delta's, which I don't care about */ 583 /* Scrub off lower bits. They signify delta's, which I don't care about */
584 msignals &= 0xf0; 584 /* Keep DDCD and DDSR though */
585 msignals &= 0xf8;
585 586
587 if (msignals & UART_MSR_DDCD)
588 uart_handle_dcd_change(&ch->uart_port, msignals & UART_MSR_DCD);
589 if (msignals & UART_MSR_DDSR)
590 uart_handle_cts_change(&ch->uart_port, msignals & UART_MSR_CTS);
586 if (msignals & UART_MSR_DCD) 591 if (msignals & UART_MSR_DCD)
587 ch->ch_mistat |= UART_MSR_DCD; 592 ch->ch_mistat |= UART_MSR_DCD;
588 else 593 else
diff --git a/drivers/serial/jsm/jsm_tty.c b/drivers/serial/jsm/jsm_tty.c
index be22bbdbc8e5..281f23a371b2 100644
--- a/drivers/serial/jsm/jsm_tty.c
+++ b/drivers/serial/jsm/jsm_tty.c
@@ -448,6 +448,7 @@ int jsm_uart_port_init(struct jsm_board *brd)
448 continue; 448 continue;
449 449
450 brd->channels[i]->uart_port.irq = brd->irq; 450 brd->channels[i]->uart_port.irq = brd->irq;
451 brd->channels[i]->uart_port.uartclk = 14745600;
451 brd->channels[i]->uart_port.type = PORT_JSM; 452 brd->channels[i]->uart_port.type = PORT_JSM;
452 brd->channels[i]->uart_port.iotype = UPIO_MEM; 453 brd->channels[i]->uart_port.iotype = UPIO_MEM;
453 brd->channels[i]->uart_port.membase = brd->re_map_membase; 454 brd->channels[i]->uart_port.membase = brd->re_map_membase;
diff --git a/drivers/serial/s3c2410.c b/drivers/serial/s3c2410.c
index 3ba9208ebd0c..10bc0209cd66 100644
--- a/drivers/serial/s3c2410.c
+++ b/drivers/serial/s3c2410.c
@@ -957,7 +957,7 @@ static struct uart_driver s3c24xx_uart_drv = {
957static struct s3c24xx_uart_port s3c24xx_serial_ports[NR_PORTS] = { 957static struct s3c24xx_uart_port s3c24xx_serial_ports[NR_PORTS] = {
958 [0] = { 958 [0] = {
959 .port = { 959 .port = {
960 .lock = SPIN_LOCK_UNLOCKED, 960 .lock = __SPIN_LOCK_UNLOCKED(s3c24xx_serial_ports[0].port.lock),
961 .iotype = UPIO_MEM, 961 .iotype = UPIO_MEM,
962 .irq = IRQ_S3CUART_RX0, 962 .irq = IRQ_S3CUART_RX0,
963 .uartclk = 0, 963 .uartclk = 0,
@@ -969,7 +969,7 @@ static struct s3c24xx_uart_port s3c24xx_serial_ports[NR_PORTS] = {
969 }, 969 },
970 [1] = { 970 [1] = {
971 .port = { 971 .port = {
972 .lock = SPIN_LOCK_UNLOCKED, 972 .lock = __SPIN_LOCK_UNLOCKED(s3c24xx_serial_ports[1].port.lock),
973 .iotype = UPIO_MEM, 973 .iotype = UPIO_MEM,
974 .irq = IRQ_S3CUART_RX1, 974 .irq = IRQ_S3CUART_RX1,
975 .uartclk = 0, 975 .uartclk = 0,
@@ -983,7 +983,7 @@ static struct s3c24xx_uart_port s3c24xx_serial_ports[NR_PORTS] = {
983 983
984 [2] = { 984 [2] = {
985 .port = { 985 .port = {
986 .lock = SPIN_LOCK_UNLOCKED, 986 .lock = __SPIN_LOCK_UNLOCKED(s3c24xx_serial_ports[2].port.lock),
987 .iotype = UPIO_MEM, 987 .iotype = UPIO_MEM,
988 .irq = IRQ_S3CUART_RX2, 988 .irq = IRQ_S3CUART_RX2,
989 .uartclk = 0, 989 .uartclk = 0,
diff --git a/drivers/serial/serial_txx9.c b/drivers/serial/serial_txx9.c
index 509ace7e6881..1deb5764326d 100644
--- a/drivers/serial/serial_txx9.c
+++ b/drivers/serial/serial_txx9.c
@@ -15,31 +15,6 @@
15 * published by the Free Software Foundation. 15 * published by the Free Software Foundation.
16 * 16 *
17 * Serial driver for TX3927/TX4927/TX4925/TX4938 internal SIO controller 17 * Serial driver for TX3927/TX4927/TX4925/TX4938 internal SIO controller
18 *
19 * Revision History:
20 * 0.30 Initial revision. (Renamed from serial_txx927.c)
21 * 0.31 Use save_flags instead of local_irq_save.
22 * 0.32 Support SCLK.
23 * 0.33 Switch TXX9_TTY_NAME by CONFIG_SERIAL_TXX9_STDSERIAL.
24 * Support TIOCSERGETLSR.
25 * 0.34 Support slow baudrate.
26 * 0.40 Merge codes from mainstream kernel (2.4.22).
27 * 0.41 Fix console checking in rs_shutdown_port().
28 * Disable flow-control in serial_console_write().
29 * 0.42 Fix minor compiler warning.
30 * 1.00 Kernel 2.6. Converted to new serial core (based on 8250.c).
31 * 1.01 Set fifosize to make tx_empry called properly.
32 * Use standard uart_get_divisor.
33 * 1.02 Cleanup. (import 8250.c changes)
34 * 1.03 Fix low-latency mode. (import 8250.c changes)
35 * 1.04 Remove usage of deprecated functions, cleanup.
36 * 1.05 More strict check in verify_port. Cleanup.
37 * 1.06 Do not insert a char caused previous overrun.
38 * Fix some spin_locks.
39 * Do not call uart_add_one_port for absent ports.
40 * 1.07 Use CONFIG_SERIAL_TXX9_NR_UARTS. Cleanup.
41 * 1.08 Use platform_device.
42 * Fix and cleanup suspend/resume/initialization codes.
43 */ 18 */
44 19
45#if defined(CONFIG_SERIAL_TXX9_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) 20#if defined(CONFIG_SERIAL_TXX9_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
@@ -62,7 +37,7 @@
62 37
63#include <asm/io.h> 38#include <asm/io.h>
64 39
65static char *serial_version = "1.08"; 40static char *serial_version = "1.09";
66static char *serial_name = "TX39/49 Serial driver"; 41static char *serial_name = "TX39/49 Serial driver";
67 42
68#define PASS_LIMIT 256 43#define PASS_LIMIT 256
@@ -70,13 +45,14 @@ static char *serial_name = "TX39/49 Serial driver";
70#if !defined(CONFIG_SERIAL_TXX9_STDSERIAL) 45#if !defined(CONFIG_SERIAL_TXX9_STDSERIAL)
71/* "ttyS" is used for standard serial driver */ 46/* "ttyS" is used for standard serial driver */
72#define TXX9_TTY_NAME "ttyTX" 47#define TXX9_TTY_NAME "ttyTX"
73#define TXX9_TTY_MINOR_START (64 + 64) /* ttyTX0(128), ttyTX1(129) */ 48#define TXX9_TTY_MINOR_START 196
49#define TXX9_TTY_MAJOR 204
74#else 50#else
75/* acts like standard serial driver */ 51/* acts like standard serial driver */
76#define TXX9_TTY_NAME "ttyS" 52#define TXX9_TTY_NAME "ttyS"
77#define TXX9_TTY_MINOR_START 64 53#define TXX9_TTY_MINOR_START 64
78#endif
79#define TXX9_TTY_MAJOR TTY_MAJOR 54#define TXX9_TTY_MAJOR TTY_MAJOR
55#endif
80 56
81/* flag aliases */ 57/* flag aliases */
82#define UPF_TXX9_HAVE_CTS_LINE UPF_BUGGY_UART 58#define UPF_TXX9_HAVE_CTS_LINE UPF_BUGGY_UART
diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
index 4a012d9acbff..07c587ec71be 100644
--- a/drivers/spi/Kconfig
+++ b/drivers/spi/Kconfig
@@ -64,6 +64,17 @@ config SPI_BFIN
64 help 64 help
65 This is the SPI controller master driver for Blackfin 5xx processor. 65 This is the SPI controller master driver for Blackfin 5xx processor.
66 66
67config SPI_AU1550
68 tristate "Au1550/Au12x0 SPI Controller"
69 depends on SPI_MASTER && (SOC_AU1550 || SOC_AU1200) && EXPERIMENTAL
70 select SPI_BITBANG
71 help
72 If you say yes to this option, support will be included for the
73 Au1550 SPI controller (may also work with Au1200,Au1210,Au1250).
74
75 This driver can also be built as a module. If so, the module
76 will be called au1550_spi.
77
67config SPI_BITBANG 78config SPI_BITBANG
68 tristate "Bitbanging SPI master" 79 tristate "Bitbanging SPI master"
69 depends on SPI_MASTER && EXPERIMENTAL 80 depends on SPI_MASTER && EXPERIMENTAL
@@ -159,6 +170,15 @@ config SPI_AT25
159 This driver can also be built as a module. If so, the module 170 This driver can also be built as a module. If so, the module
160 will be called at25. 171 will be called at25.
161 172
173config SPI_SPIDEV
174 tristate "User mode SPI device driver support"
175 depends on SPI_MASTER && EXPERIMENTAL
176 help
177 This supports user mode SPI protocol drivers.
178
179 Note that this application programming interface is EXPERIMENTAL
180 and hence SUBJECT TO CHANGE WITHOUT NOTICE while it stabilizes.
181
162# 182#
163# Add new SPI protocol masters in alphabetical order above this line 183# Add new SPI protocol masters in alphabetical order above this line
164# 184#
diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile
index a95ade857a2f..624b6363f490 100644
--- a/drivers/spi/Makefile
+++ b/drivers/spi/Makefile
@@ -14,6 +14,7 @@ obj-$(CONFIG_SPI_MASTER) += spi.o
14obj-$(CONFIG_SPI_ATMEL) += atmel_spi.o 14obj-$(CONFIG_SPI_ATMEL) += atmel_spi.o
15obj-$(CONFIG_SPI_BFIN) += spi_bfin5xx.o 15obj-$(CONFIG_SPI_BFIN) += spi_bfin5xx.o
16obj-$(CONFIG_SPI_BITBANG) += spi_bitbang.o 16obj-$(CONFIG_SPI_BITBANG) += spi_bitbang.o
17obj-$(CONFIG_SPI_AU1550) += au1550_spi.o
17obj-$(CONFIG_SPI_BUTTERFLY) += spi_butterfly.o 18obj-$(CONFIG_SPI_BUTTERFLY) += spi_butterfly.o
18obj-$(CONFIG_SPI_IMX) += spi_imx.o 19obj-$(CONFIG_SPI_IMX) += spi_imx.o
19obj-$(CONFIG_SPI_PXA2XX) += pxa2xx_spi.o 20obj-$(CONFIG_SPI_PXA2XX) += pxa2xx_spi.o
@@ -25,6 +26,7 @@ obj-$(CONFIG_SPI_S3C24XX) += spi_s3c24xx.o
25 26
26# SPI protocol drivers (device/link on bus) 27# SPI protocol drivers (device/link on bus)
27obj-$(CONFIG_SPI_AT25) += at25.o 28obj-$(CONFIG_SPI_AT25) += at25.o
29obj-$(CONFIG_SPI_SPIDEV) += spidev.o
28# ... add above this line ... 30# ... add above this line ...
29 31
30# SPI slave controller drivers (upstream link) 32# SPI slave controller drivers (upstream link)
diff --git a/drivers/spi/au1550_spi.c b/drivers/spi/au1550_spi.c
new file mode 100644
index 000000000000..ae2b1af0dba4
--- /dev/null
+++ b/drivers/spi/au1550_spi.c
@@ -0,0 +1,974 @@
1/*
2 * au1550_spi.c - au1550 psc spi controller driver
3 * may work also with au1200, au1210, au1250
4 * will not work on au1000, au1100 and au1500 (no full spi controller there)
5 *
6 * Copyright (c) 2006 ATRON electronic GmbH
7 * Author: Jan Nikitenko <jan.nikitenko@gmail.com>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 */
23
24#include <linux/init.h>
25#include <linux/interrupt.h>
26#include <linux/errno.h>
27#include <linux/device.h>
28#include <linux/platform_device.h>
29#include <linux/spi/spi.h>
30#include <linux/spi/spi_bitbang.h>
31#include <linux/dma-mapping.h>
32#include <linux/completion.h>
33#include <asm/mach-au1x00/au1000.h>
34#include <asm/mach-au1x00/au1xxx_psc.h>
35#include <asm/mach-au1x00/au1xxx_dbdma.h>
36
37#include <asm/mach-au1x00/au1550_spi.h>
38
39static unsigned usedma = 1;
40module_param(usedma, uint, 0644);
41
42/*
43#define AU1550_SPI_DEBUG_LOOPBACK
44*/
45
46
47#define AU1550_SPI_DBDMA_DESCRIPTORS 1
48#define AU1550_SPI_DMA_RXTMP_MINSIZE 2048U
49
50struct au1550_spi {
51 struct spi_bitbang bitbang;
52
53 volatile psc_spi_t __iomem *regs;
54 int irq;
55 unsigned freq_max;
56 unsigned freq_min;
57
58 unsigned len;
59 unsigned tx_count;
60 unsigned rx_count;
61 const u8 *tx;
62 u8 *rx;
63
64 void (*rx_word)(struct au1550_spi *hw);
65 void (*tx_word)(struct au1550_spi *hw);
66 int (*txrx_bufs)(struct spi_device *spi, struct spi_transfer *t);
67 irqreturn_t (*irq_callback)(struct au1550_spi *hw);
68
69 struct completion master_done;
70
71 unsigned usedma;
72 u32 dma_tx_id;
73 u32 dma_rx_id;
74 u32 dma_tx_ch;
75 u32 dma_rx_ch;
76
77 u8 *dma_rx_tmpbuf;
78 unsigned dma_rx_tmpbuf_size;
79 u32 dma_rx_tmpbuf_addr;
80
81 struct spi_master *master;
82 struct device *dev;
83 struct au1550_spi_info *pdata;
84};
85
86
87/* we use an 8-bit memory device for dma transfers to/from spi fifo */
88static dbdev_tab_t au1550_spi_mem_dbdev =
89{
90 .dev_id = DBDMA_MEM_CHAN,
91 .dev_flags = DEV_FLAGS_ANYUSE|DEV_FLAGS_SYNC,
92 .dev_tsize = 0,
93 .dev_devwidth = 8,
94 .dev_physaddr = 0x00000000,
95 .dev_intlevel = 0,
96 .dev_intpolarity = 0
97};
98
99static void au1550_spi_bits_handlers_set(struct au1550_spi *hw, int bpw);
100
101
102/**
103 * compute BRG and DIV bits to setup spi clock based on main input clock rate
104 * that was specified in platform data structure
105 * according to au1550 datasheet:
106 * psc_tempclk = psc_mainclk / (2 << DIV)
107 * spiclk = psc_tempclk / (2 * (BRG + 1))
108 * BRG valid range is 4..63
109 * DIV valid range is 0..3
110 */
111static u32 au1550_spi_baudcfg(struct au1550_spi *hw, unsigned speed_hz)
112{
113 u32 mainclk_hz = hw->pdata->mainclk_hz;
114 u32 div, brg;
115
116 for (div = 0; div < 4; div++) {
117 brg = mainclk_hz / speed_hz / (4 << div);
118 /* now we have BRG+1 in brg, so count with that */
119 if (brg < (4 + 1)) {
120 brg = (4 + 1); /* speed_hz too big */
121 break; /* set lowest brg (div is == 0) */
122 }
123 if (brg <= (63 + 1))
124 break; /* we have valid brg and div */
125 }
126 if (div == 4) {
127 div = 3; /* speed_hz too small */
128 brg = (63 + 1); /* set highest brg and div */
129 }
130 brg--;
131 return PSC_SPICFG_SET_BAUD(brg) | PSC_SPICFG_SET_DIV(div);
132}
133
134static inline void au1550_spi_mask_ack_all(struct au1550_spi *hw)
135{
136 hw->regs->psc_spimsk =
137 PSC_SPIMSK_MM | PSC_SPIMSK_RR | PSC_SPIMSK_RO
138 | PSC_SPIMSK_RU | PSC_SPIMSK_TR | PSC_SPIMSK_TO
139 | PSC_SPIMSK_TU | PSC_SPIMSK_SD | PSC_SPIMSK_MD;
140 au_sync();
141
142 hw->regs->psc_spievent =
143 PSC_SPIEVNT_MM | PSC_SPIEVNT_RR | PSC_SPIEVNT_RO
144 | PSC_SPIEVNT_RU | PSC_SPIEVNT_TR | PSC_SPIEVNT_TO
145 | PSC_SPIEVNT_TU | PSC_SPIEVNT_SD | PSC_SPIEVNT_MD;
146 au_sync();
147}
148
149static void au1550_spi_reset_fifos(struct au1550_spi *hw)
150{
151 u32 pcr;
152
153 hw->regs->psc_spipcr = PSC_SPIPCR_RC | PSC_SPIPCR_TC;
154 au_sync();
155 do {
156 pcr = hw->regs->psc_spipcr;
157 au_sync();
158 } while (pcr != 0);
159}
160
161/*
162 * dma transfers are used for the most common spi word size of 8-bits
163 * we cannot easily change already set up dma channels' width, so if we wanted
164 * dma support for more than 8-bit words (up to 24 bits), we would need to
165 * setup dma channels from scratch on each spi transfer, based on bits_per_word
166 * instead we have pre set up 8 bit dma channels supporting spi 4 to 8 bits
167 * transfers, and 9 to 24 bits spi transfers will be done in pio irq based mode
168 * callbacks to handle dma or pio are set up in au1550_spi_bits_handlers_set()
169 */
170static void au1550_spi_chipsel(struct spi_device *spi, int value)
171{
172 struct au1550_spi *hw = spi_master_get_devdata(spi->master);
173 unsigned cspol = spi->mode & SPI_CS_HIGH ? 1 : 0;
174 u32 cfg, stat;
175
176 switch (value) {
177 case BITBANG_CS_INACTIVE:
178 if (hw->pdata->deactivate_cs)
179 hw->pdata->deactivate_cs(hw->pdata, spi->chip_select,
180 cspol);
181 break;
182
183 case BITBANG_CS_ACTIVE:
184 au1550_spi_bits_handlers_set(hw, spi->bits_per_word);
185
186 cfg = hw->regs->psc_spicfg;
187 au_sync();
188 hw->regs->psc_spicfg = cfg & ~PSC_SPICFG_DE_ENABLE;
189 au_sync();
190
191 if (spi->mode & SPI_CPOL)
192 cfg |= PSC_SPICFG_BI;
193 else
194 cfg &= ~PSC_SPICFG_BI;
195 if (spi->mode & SPI_CPHA)
196 cfg &= ~PSC_SPICFG_CDE;
197 else
198 cfg |= PSC_SPICFG_CDE;
199
200 if (spi->mode & SPI_LSB_FIRST)
201 cfg |= PSC_SPICFG_MLF;
202 else
203 cfg &= ~PSC_SPICFG_MLF;
204
205 if (hw->usedma && spi->bits_per_word <= 8)
206 cfg &= ~PSC_SPICFG_DD_DISABLE;
207 else
208 cfg |= PSC_SPICFG_DD_DISABLE;
209 cfg = PSC_SPICFG_CLR_LEN(cfg);
210 cfg |= PSC_SPICFG_SET_LEN(spi->bits_per_word);
211
212 cfg = PSC_SPICFG_CLR_BAUD(cfg);
213 cfg &= ~PSC_SPICFG_SET_DIV(3);
214 cfg |= au1550_spi_baudcfg(hw, spi->max_speed_hz);
215
216 hw->regs->psc_spicfg = cfg | PSC_SPICFG_DE_ENABLE;
217 au_sync();
218 do {
219 stat = hw->regs->psc_spistat;
220 au_sync();
221 } while ((stat & PSC_SPISTAT_DR) == 0);
222
223 if (hw->pdata->activate_cs)
224 hw->pdata->activate_cs(hw->pdata, spi->chip_select,
225 cspol);
226 break;
227 }
228}
229
230static int au1550_spi_setupxfer(struct spi_device *spi, struct spi_transfer *t)
231{
232 struct au1550_spi *hw = spi_master_get_devdata(spi->master);
233 unsigned bpw, hz;
234 u32 cfg, stat;
235
236 bpw = t ? t->bits_per_word : spi->bits_per_word;
237 hz = t ? t->speed_hz : spi->max_speed_hz;
238
239 if (bpw < 4 || bpw > 24) {
240 dev_err(&spi->dev, "setupxfer: invalid bits_per_word=%d\n",
241 bpw);
242 return -EINVAL;
243 }
244 if (hz > spi->max_speed_hz || hz > hw->freq_max || hz < hw->freq_min) {
245 dev_err(&spi->dev, "setupxfer: clock rate=%d out of range\n",
246 hz);
247 return -EINVAL;
248 }
249
250 au1550_spi_bits_handlers_set(hw, spi->bits_per_word);
251
252 cfg = hw->regs->psc_spicfg;
253 au_sync();
254 hw->regs->psc_spicfg = cfg & ~PSC_SPICFG_DE_ENABLE;
255 au_sync();
256
257 if (hw->usedma && bpw <= 8)
258 cfg &= ~PSC_SPICFG_DD_DISABLE;
259 else
260 cfg |= PSC_SPICFG_DD_DISABLE;
261 cfg = PSC_SPICFG_CLR_LEN(cfg);
262 cfg |= PSC_SPICFG_SET_LEN(bpw);
263
264 cfg = PSC_SPICFG_CLR_BAUD(cfg);
265 cfg &= ~PSC_SPICFG_SET_DIV(3);
266 cfg |= au1550_spi_baudcfg(hw, hz);
267
268 hw->regs->psc_spicfg = cfg;
269 au_sync();
270
271 if (cfg & PSC_SPICFG_DE_ENABLE) {
272 do {
273 stat = hw->regs->psc_spistat;
274 au_sync();
275 } while ((stat & PSC_SPISTAT_DR) == 0);
276 }
277
278 au1550_spi_reset_fifos(hw);
279 au1550_spi_mask_ack_all(hw);
280 return 0;
281}
282
283static int au1550_spi_setup(struct spi_device *spi)
284{
285 struct au1550_spi *hw = spi_master_get_devdata(spi->master);
286
287 if (spi->bits_per_word == 0)
288 spi->bits_per_word = 8;
289 if (spi->bits_per_word < 4 || spi->bits_per_word > 24) {
290 dev_err(&spi->dev, "setup: invalid bits_per_word=%d\n",
291 spi->bits_per_word);
292 return -EINVAL;
293 }
294
295 if (spi->max_speed_hz == 0)
296 spi->max_speed_hz = hw->freq_max;
297 if (spi->max_speed_hz > hw->freq_max
298 || spi->max_speed_hz < hw->freq_min)
299 return -EINVAL;
300 /*
301 * NOTE: cannot change speed and other hw settings immediately,
302 * otherwise sharing of spi bus is not possible,
303 * so do not call setupxfer(spi, NULL) here
304 */
305 return 0;
306}
307
308/*
309 * for dma spi transfers, we have to setup rx channel, otherwise there is
310 * no reliable way how to recognize that spi transfer is done
311 * dma complete callbacks are called before real spi transfer is finished
312 * and if only tx dma channel is set up (and rx fifo overflow event masked)
313 * spi master done event irq is not generated unless rx fifo is empty (emptied)
314 * so we need rx tmp buffer to use for rx dma if user does not provide one
315 */
316static int au1550_spi_dma_rxtmp_alloc(struct au1550_spi *hw, unsigned size)
317{
318 hw->dma_rx_tmpbuf = kmalloc(size, GFP_KERNEL);
319 if (!hw->dma_rx_tmpbuf)
320 return -ENOMEM;
321 hw->dma_rx_tmpbuf_size = size;
322 hw->dma_rx_tmpbuf_addr = dma_map_single(hw->dev, hw->dma_rx_tmpbuf,
323 size, DMA_FROM_DEVICE);
324 if (dma_mapping_error(hw->dma_rx_tmpbuf_addr)) {
325 kfree(hw->dma_rx_tmpbuf);
326 hw->dma_rx_tmpbuf = 0;
327 hw->dma_rx_tmpbuf_size = 0;
328 return -EFAULT;
329 }
330 return 0;
331}
332
333static void au1550_spi_dma_rxtmp_free(struct au1550_spi *hw)
334{
335 dma_unmap_single(hw->dev, hw->dma_rx_tmpbuf_addr,
336 hw->dma_rx_tmpbuf_size, DMA_FROM_DEVICE);
337 kfree(hw->dma_rx_tmpbuf);
338 hw->dma_rx_tmpbuf = 0;
339 hw->dma_rx_tmpbuf_size = 0;
340}
341
342static int au1550_spi_dma_txrxb(struct spi_device *spi, struct spi_transfer *t)
343{
344 struct au1550_spi *hw = spi_master_get_devdata(spi->master);
345 dma_addr_t dma_tx_addr;
346 dma_addr_t dma_rx_addr;
347 u32 res;
348
349 hw->len = t->len;
350 hw->tx_count = 0;
351 hw->rx_count = 0;
352
353 hw->tx = t->tx_buf;
354 hw->rx = t->rx_buf;
355 dma_tx_addr = t->tx_dma;
356 dma_rx_addr = t->rx_dma;
357
358 /*
359 * check if buffers are already dma mapped, map them otherwise
360 * use rx buffer in place of tx if tx buffer was not provided
361 * use temp rx buffer (preallocated or realloc to fit) for rx dma
362 */
363 if (t->rx_buf) {
364 if (t->rx_dma == 0) { /* if DMA_ADDR_INVALID, map it */
365 dma_rx_addr = dma_map_single(hw->dev,
366 (void *)t->rx_buf,
367 t->len, DMA_FROM_DEVICE);
368 if (dma_mapping_error(dma_rx_addr))
369 dev_err(hw->dev, "rx dma map error\n");
370 }
371 } else {
372 if (t->len > hw->dma_rx_tmpbuf_size) {
373 int ret;
374
375 au1550_spi_dma_rxtmp_free(hw);
376 ret = au1550_spi_dma_rxtmp_alloc(hw, max(t->len,
377 AU1550_SPI_DMA_RXTMP_MINSIZE));
378 if (ret < 0)
379 return ret;
380 }
381 hw->rx = hw->dma_rx_tmpbuf;
382 dma_rx_addr = hw->dma_rx_tmpbuf_addr;
383 dma_sync_single_for_device(hw->dev, dma_rx_addr,
384 t->len, DMA_FROM_DEVICE);
385 }
386 if (t->tx_buf) {
387 if (t->tx_dma == 0) { /* if DMA_ADDR_INVALID, map it */
388 dma_tx_addr = dma_map_single(hw->dev,
389 (void *)t->tx_buf,
390 t->len, DMA_TO_DEVICE);
391 if (dma_mapping_error(dma_tx_addr))
392 dev_err(hw->dev, "tx dma map error\n");
393 }
394 } else {
395 dma_sync_single_for_device(hw->dev, dma_rx_addr,
396 t->len, DMA_BIDIRECTIONAL);
397 hw->tx = hw->rx;
398 }
399
400 /* put buffers on the ring */
401 res = au1xxx_dbdma_put_dest(hw->dma_rx_ch, hw->rx, t->len);
402 if (!res)
403 dev_err(hw->dev, "rx dma put dest error\n");
404
405 res = au1xxx_dbdma_put_source(hw->dma_tx_ch, (void *)hw->tx, t->len);
406 if (!res)
407 dev_err(hw->dev, "tx dma put source error\n");
408
409 au1xxx_dbdma_start(hw->dma_rx_ch);
410 au1xxx_dbdma_start(hw->dma_tx_ch);
411
412 /* by default enable nearly all events interrupt */
413 hw->regs->psc_spimsk = PSC_SPIMSK_SD;
414 au_sync();
415
416 /* start the transfer */
417 hw->regs->psc_spipcr = PSC_SPIPCR_MS;
418 au_sync();
419
420 wait_for_completion(&hw->master_done);
421
422 au1xxx_dbdma_stop(hw->dma_tx_ch);
423 au1xxx_dbdma_stop(hw->dma_rx_ch);
424
425 if (!t->rx_buf) {
426 /* using the temporal preallocated and premapped buffer */
427 dma_sync_single_for_cpu(hw->dev, dma_rx_addr, t->len,
428 DMA_FROM_DEVICE);
429 }
430 /* unmap buffers if mapped above */
431 if (t->rx_buf && t->rx_dma == 0 )
432 dma_unmap_single(hw->dev, dma_rx_addr, t->len,
433 DMA_FROM_DEVICE);
434 if (t->tx_buf && t->tx_dma == 0 )
435 dma_unmap_single(hw->dev, dma_tx_addr, t->len,
436 DMA_TO_DEVICE);
437
438 return hw->rx_count < hw->tx_count ? hw->rx_count : hw->tx_count;
439}
440
441static irqreturn_t au1550_spi_dma_irq_callback(struct au1550_spi *hw)
442{
443 u32 stat, evnt;
444
445 stat = hw->regs->psc_spistat;
446 evnt = hw->regs->psc_spievent;
447 au_sync();
448 if ((stat & PSC_SPISTAT_DI) == 0) {
449 dev_err(hw->dev, "Unexpected IRQ!\n");
450 return IRQ_NONE;
451 }
452
453 if ((evnt & (PSC_SPIEVNT_MM | PSC_SPIEVNT_RO
454 | PSC_SPIEVNT_RU | PSC_SPIEVNT_TO
455 | PSC_SPIEVNT_TU | PSC_SPIEVNT_SD))
456 != 0) {
457 /*
458 * due to an spi error we consider transfer as done,
459 * so mask all events until before next transfer start
460 * and stop the possibly running dma immediatelly
461 */
462 au1550_spi_mask_ack_all(hw);
463 au1xxx_dbdma_stop(hw->dma_rx_ch);
464 au1xxx_dbdma_stop(hw->dma_tx_ch);
465
466 /* get number of transfered bytes */
467 hw->rx_count = hw->len - au1xxx_get_dma_residue(hw->dma_rx_ch);
468 hw->tx_count = hw->len - au1xxx_get_dma_residue(hw->dma_tx_ch);
469
470 au1xxx_dbdma_reset(hw->dma_rx_ch);
471 au1xxx_dbdma_reset(hw->dma_tx_ch);
472 au1550_spi_reset_fifos(hw);
473
474 dev_err(hw->dev,
475 "Unexpected SPI error: event=0x%x stat=0x%x!\n",
476 evnt, stat);
477
478 complete(&hw->master_done);
479 return IRQ_HANDLED;
480 }
481
482 if ((evnt & PSC_SPIEVNT_MD) != 0) {
483 /* transfer completed successfully */
484 au1550_spi_mask_ack_all(hw);
485 hw->rx_count = hw->len;
486 hw->tx_count = hw->len;
487 complete(&hw->master_done);
488 }
489 return IRQ_HANDLED;
490}
491
492
493/* routines to handle different word sizes in pio mode */
494#define AU1550_SPI_RX_WORD(size, mask) \
495static void au1550_spi_rx_word_##size(struct au1550_spi *hw) \
496{ \
497 u32 fifoword = hw->regs->psc_spitxrx & (u32)(mask); \
498 au_sync(); \
499 if (hw->rx) { \
500 *(u##size *)hw->rx = (u##size)fifoword; \
501 hw->rx += (size) / 8; \
502 } \
503 hw->rx_count += (size) / 8; \
504}
505
506#define AU1550_SPI_TX_WORD(size, mask) \
507static void au1550_spi_tx_word_##size(struct au1550_spi *hw) \
508{ \
509 u32 fifoword = 0; \
510 if (hw->tx) { \
511 fifoword = *(u##size *)hw->tx & (u32)(mask); \
512 hw->tx += (size) / 8; \
513 } \
514 hw->tx_count += (size) / 8; \
515 if (hw->tx_count >= hw->len) \
516 fifoword |= PSC_SPITXRX_LC; \
517 hw->regs->psc_spitxrx = fifoword; \
518 au_sync(); \
519}
520
521AU1550_SPI_RX_WORD(8,0xff)
522AU1550_SPI_RX_WORD(16,0xffff)
523AU1550_SPI_RX_WORD(32,0xffffff)
524AU1550_SPI_TX_WORD(8,0xff)
525AU1550_SPI_TX_WORD(16,0xffff)
526AU1550_SPI_TX_WORD(32,0xffffff)
527
528static int au1550_spi_pio_txrxb(struct spi_device *spi, struct spi_transfer *t)
529{
530 u32 stat, mask;
531 struct au1550_spi *hw = spi_master_get_devdata(spi->master);
532
533 hw->tx = t->tx_buf;
534 hw->rx = t->rx_buf;
535 hw->len = t->len;
536 hw->tx_count = 0;
537 hw->rx_count = 0;
538
539 /* by default enable nearly all events after filling tx fifo */
540 mask = PSC_SPIMSK_SD;
541
542 /* fill the transmit FIFO */
543 while (hw->tx_count < hw->len) {
544
545 hw->tx_word(hw);
546
547 if (hw->tx_count >= hw->len) {
548 /* mask tx fifo request interrupt as we are done */
549 mask |= PSC_SPIMSK_TR;
550 }
551
552 stat = hw->regs->psc_spistat;
553 au_sync();
554 if (stat & PSC_SPISTAT_TF)
555 break;
556 }
557
558 /* enable event interrupts */
559 hw->regs->psc_spimsk = mask;
560 au_sync();
561
562 /* start the transfer */
563 hw->regs->psc_spipcr = PSC_SPIPCR_MS;
564 au_sync();
565
566 wait_for_completion(&hw->master_done);
567
568 return hw->rx_count < hw->tx_count ? hw->rx_count : hw->tx_count;
569}
570
571static irqreturn_t au1550_spi_pio_irq_callback(struct au1550_spi *hw)
572{
573 int busy;
574 u32 stat, evnt;
575
576 stat = hw->regs->psc_spistat;
577 evnt = hw->regs->psc_spievent;
578 au_sync();
579 if ((stat & PSC_SPISTAT_DI) == 0) {
580 dev_err(hw->dev, "Unexpected IRQ!\n");
581 return IRQ_NONE;
582 }
583
584 if ((evnt & (PSC_SPIEVNT_MM | PSC_SPIEVNT_RO
585 | PSC_SPIEVNT_RU | PSC_SPIEVNT_TO
586 | PSC_SPIEVNT_TU | PSC_SPIEVNT_SD))
587 != 0) {
588 dev_err(hw->dev,
589 "Unexpected SPI error: event=0x%x stat=0x%x!\n",
590 evnt, stat);
591 /*
592 * due to an error we consider transfer as done,
593 * so mask all events until before next transfer start
594 */
595 au1550_spi_mask_ack_all(hw);
596 au1550_spi_reset_fifos(hw);
597 complete(&hw->master_done);
598 return IRQ_HANDLED;
599 }
600
601 /*
602 * while there is something to read from rx fifo
603 * or there is a space to write to tx fifo:
604 */
605 do {
606 busy = 0;
607 stat = hw->regs->psc_spistat;
608 au_sync();
609
610 if ((stat & PSC_SPISTAT_RE) == 0 && hw->rx_count < hw->len) {
611 hw->rx_word(hw);
612 /* ack the receive request event */
613 hw->regs->psc_spievent = PSC_SPIEVNT_RR;
614 au_sync();
615 busy = 1;
616 }
617
618 if ((stat & PSC_SPISTAT_TF) == 0 && hw->tx_count < hw->len) {
619 hw->tx_word(hw);
620 /* ack the transmit request event */
621 hw->regs->psc_spievent = PSC_SPIEVNT_TR;
622 au_sync();
623 busy = 1;
624 }
625 } while (busy);
626
627 evnt = hw->regs->psc_spievent;
628 au_sync();
629
630 if (hw->rx_count >= hw->len || (evnt & PSC_SPIEVNT_MD) != 0) {
631 /* transfer completed successfully */
632 au1550_spi_mask_ack_all(hw);
633 complete(&hw->master_done);
634 }
635 return IRQ_HANDLED;
636}
637
638static int au1550_spi_txrx_bufs(struct spi_device *spi, struct spi_transfer *t)
639{
640 struct au1550_spi *hw = spi_master_get_devdata(spi->master);
641 return hw->txrx_bufs(spi, t);
642}
643
644static irqreturn_t au1550_spi_irq(int irq, void *dev, struct pt_regs *regs)
645{
646 struct au1550_spi *hw = dev;
647 return hw->irq_callback(hw);
648}
649
650static void au1550_spi_bits_handlers_set(struct au1550_spi *hw, int bpw)
651{
652 if (bpw <= 8) {
653 if (hw->usedma) {
654 hw->txrx_bufs = &au1550_spi_dma_txrxb;
655 hw->irq_callback = &au1550_spi_dma_irq_callback;
656 } else {
657 hw->rx_word = &au1550_spi_rx_word_8;
658 hw->tx_word = &au1550_spi_tx_word_8;
659 hw->txrx_bufs = &au1550_spi_pio_txrxb;
660 hw->irq_callback = &au1550_spi_pio_irq_callback;
661 }
662 } else if (bpw <= 16) {
663 hw->rx_word = &au1550_spi_rx_word_16;
664 hw->tx_word = &au1550_spi_tx_word_16;
665 hw->txrx_bufs = &au1550_spi_pio_txrxb;
666 hw->irq_callback = &au1550_spi_pio_irq_callback;
667 } else {
668 hw->rx_word = &au1550_spi_rx_word_32;
669 hw->tx_word = &au1550_spi_tx_word_32;
670 hw->txrx_bufs = &au1550_spi_pio_txrxb;
671 hw->irq_callback = &au1550_spi_pio_irq_callback;
672 }
673}
674
675static void __init au1550_spi_setup_psc_as_spi(struct au1550_spi *hw)
676{
677 u32 stat, cfg;
678
679 /* set up the PSC for SPI mode */
680 hw->regs->psc_ctrl = PSC_CTRL_DISABLE;
681 au_sync();
682 hw->regs->psc_sel = PSC_SEL_PS_SPIMODE;
683 au_sync();
684
685 hw->regs->psc_spicfg = 0;
686 au_sync();
687
688 hw->regs->psc_ctrl = PSC_CTRL_ENABLE;
689 au_sync();
690
691 do {
692 stat = hw->regs->psc_spistat;
693 au_sync();
694 } while ((stat & PSC_SPISTAT_SR) == 0);
695
696
697 cfg = hw->usedma ? 0 : PSC_SPICFG_DD_DISABLE;
698 cfg |= PSC_SPICFG_SET_LEN(8);
699 cfg |= PSC_SPICFG_RT_FIFO8 | PSC_SPICFG_TT_FIFO8;
700 /* use minimal allowed brg and div values as initial setting: */
701 cfg |= PSC_SPICFG_SET_BAUD(4) | PSC_SPICFG_SET_DIV(0);
702
703#ifdef AU1550_SPI_DEBUG_LOOPBACK
704 cfg |= PSC_SPICFG_LB;
705#endif
706
707 hw->regs->psc_spicfg = cfg;
708 au_sync();
709
710 au1550_spi_mask_ack_all(hw);
711
712 hw->regs->psc_spicfg |= PSC_SPICFG_DE_ENABLE;
713 au_sync();
714
715 do {
716 stat = hw->regs->psc_spistat;
717 au_sync();
718 } while ((stat & PSC_SPISTAT_DR) == 0);
719}
720
721
722static int __init au1550_spi_probe(struct platform_device *pdev)
723{
724 struct au1550_spi *hw;
725 struct spi_master *master;
726 int err = 0;
727
728 master = spi_alloc_master(&pdev->dev, sizeof(struct au1550_spi));
729 if (master == NULL) {
730 dev_err(&pdev->dev, "No memory for spi_master\n");
731 err = -ENOMEM;
732 goto err_nomem;
733 }
734
735 hw = spi_master_get_devdata(master);
736
737 hw->master = spi_master_get(master);
738 hw->pdata = pdev->dev.platform_data;
739 hw->dev = &pdev->dev;
740
741 if (hw->pdata == NULL) {
742 dev_err(&pdev->dev, "No platform data supplied\n");
743 err = -ENOENT;
744 goto err_no_pdata;
745 }
746
747 platform_set_drvdata(pdev, hw);
748
749 init_completion(&hw->master_done);
750
751 hw->bitbang.master = hw->master;
752 hw->bitbang.setup_transfer = au1550_spi_setupxfer;
753 hw->bitbang.chipselect = au1550_spi_chipsel;
754 hw->bitbang.master->setup = au1550_spi_setup;
755 hw->bitbang.txrx_bufs = au1550_spi_txrx_bufs;
756
757 switch (hw->pdata->bus_num) {
758 case 0:
759 hw->irq = AU1550_PSC0_INT;
760 hw->regs = (volatile psc_spi_t *)PSC0_BASE_ADDR;
761 hw->dma_rx_id = DSCR_CMD0_PSC0_RX;
762 hw->dma_tx_id = DSCR_CMD0_PSC0_TX;
763 break;
764 case 1:
765 hw->irq = AU1550_PSC1_INT;
766 hw->regs = (volatile psc_spi_t *)PSC1_BASE_ADDR;
767 hw->dma_rx_id = DSCR_CMD0_PSC1_RX;
768 hw->dma_tx_id = DSCR_CMD0_PSC1_TX;
769 break;
770 case 2:
771 hw->irq = AU1550_PSC2_INT;
772 hw->regs = (volatile psc_spi_t *)PSC2_BASE_ADDR;
773 hw->dma_rx_id = DSCR_CMD0_PSC2_RX;
774 hw->dma_tx_id = DSCR_CMD0_PSC2_TX;
775 break;
776 case 3:
777 hw->irq = AU1550_PSC3_INT;
778 hw->regs = (volatile psc_spi_t *)PSC3_BASE_ADDR;
779 hw->dma_rx_id = DSCR_CMD0_PSC3_RX;
780 hw->dma_tx_id = DSCR_CMD0_PSC3_TX;
781 break;
782 default:
783 dev_err(&pdev->dev, "Wrong bus_num of SPI\n");
784 err = -ENOENT;
785 goto err_no_pdata;
786 }
787
788 if (request_mem_region((unsigned long)hw->regs, sizeof(psc_spi_t),
789 pdev->name) == NULL) {
790 dev_err(&pdev->dev, "Cannot reserve iomem region\n");
791 err = -ENXIO;
792 goto err_no_iores;
793 }
794
795
796 if (usedma) {
797 if (pdev->dev.dma_mask == NULL)
798 dev_warn(&pdev->dev, "no dma mask\n");
799 else
800 hw->usedma = 1;
801 }
802
803 if (hw->usedma) {
804 /*
805 * create memory device with 8 bits dev_devwidth
806 * needed for proper byte ordering to spi fifo
807 */
808 int memid = au1xxx_ddma_add_device(&au1550_spi_mem_dbdev);
809 if (!memid) {
810 dev_err(&pdev->dev,
811 "Cannot create dma 8 bit mem device\n");
812 err = -ENXIO;
813 goto err_dma_add_dev;
814 }
815
816 hw->dma_tx_ch = au1xxx_dbdma_chan_alloc(memid,
817 hw->dma_tx_id, NULL, (void *)hw);
818 if (hw->dma_tx_ch == 0) {
819 dev_err(&pdev->dev,
820 "Cannot allocate tx dma channel\n");
821 err = -ENXIO;
822 goto err_no_txdma;
823 }
824 au1xxx_dbdma_set_devwidth(hw->dma_tx_ch, 8);
825 if (au1xxx_dbdma_ring_alloc(hw->dma_tx_ch,
826 AU1550_SPI_DBDMA_DESCRIPTORS) == 0) {
827 dev_err(&pdev->dev,
828 "Cannot allocate tx dma descriptors\n");
829 err = -ENXIO;
830 goto err_no_txdma_descr;
831 }
832
833
834 hw->dma_rx_ch = au1xxx_dbdma_chan_alloc(hw->dma_rx_id,
835 memid, NULL, (void *)hw);
836 if (hw->dma_rx_ch == 0) {
837 dev_err(&pdev->dev,
838 "Cannot allocate rx dma channel\n");
839 err = -ENXIO;
840 goto err_no_rxdma;
841 }
842 au1xxx_dbdma_set_devwidth(hw->dma_rx_ch, 8);
843 if (au1xxx_dbdma_ring_alloc(hw->dma_rx_ch,
844 AU1550_SPI_DBDMA_DESCRIPTORS) == 0) {
845 dev_err(&pdev->dev,
846 "Cannot allocate rx dma descriptors\n");
847 err = -ENXIO;
848 goto err_no_rxdma_descr;
849 }
850
851 err = au1550_spi_dma_rxtmp_alloc(hw,
852 AU1550_SPI_DMA_RXTMP_MINSIZE);
853 if (err < 0) {
854 dev_err(&pdev->dev,
855 "Cannot allocate initial rx dma tmp buffer\n");
856 goto err_dma_rxtmp_alloc;
857 }
858 }
859
860 au1550_spi_bits_handlers_set(hw, 8);
861
862 err = request_irq(hw->irq, au1550_spi_irq, 0, pdev->name, hw);
863 if (err) {
864 dev_err(&pdev->dev, "Cannot claim IRQ\n");
865 goto err_no_irq;
866 }
867
868 master->bus_num = hw->pdata->bus_num;
869 master->num_chipselect = hw->pdata->num_chipselect;
870
871 /*
872 * precompute valid range for spi freq - from au1550 datasheet:
873 * psc_tempclk = psc_mainclk / (2 << DIV)
874 * spiclk = psc_tempclk / (2 * (BRG + 1))
875 * BRG valid range is 4..63
876 * DIV valid range is 0..3
877 * round the min and max frequencies to values that would still
878 * produce valid brg and div
879 */
880 {
881 int min_div = (2 << 0) * (2 * (4 + 1));
882 int max_div = (2 << 3) * (2 * (63 + 1));
883 hw->freq_max = hw->pdata->mainclk_hz / min_div;
884 hw->freq_min = hw->pdata->mainclk_hz / (max_div + 1) + 1;
885 }
886
887 au1550_spi_setup_psc_as_spi(hw);
888
889 err = spi_bitbang_start(&hw->bitbang);
890 if (err) {
891 dev_err(&pdev->dev, "Failed to register SPI master\n");
892 goto err_register;
893 }
894
895 dev_info(&pdev->dev,
896 "spi master registered: bus_num=%d num_chipselect=%d\n",
897 master->bus_num, master->num_chipselect);
898
899 return 0;
900
901err_register:
902 free_irq(hw->irq, hw);
903
904err_no_irq:
905 au1550_spi_dma_rxtmp_free(hw);
906
907err_dma_rxtmp_alloc:
908err_no_rxdma_descr:
909 if (hw->usedma)
910 au1xxx_dbdma_chan_free(hw->dma_rx_ch);
911
912err_no_rxdma:
913err_no_txdma_descr:
914 if (hw->usedma)
915 au1xxx_dbdma_chan_free(hw->dma_tx_ch);
916
917err_no_txdma:
918err_dma_add_dev:
919 release_mem_region((unsigned long)hw->regs, sizeof(psc_spi_t));
920
921err_no_iores:
922err_no_pdata:
923 spi_master_put(hw->master);
924
925err_nomem:
926 return err;
927}
928
929static int __exit au1550_spi_remove(struct platform_device *pdev)
930{
931 struct au1550_spi *hw = platform_get_drvdata(pdev);
932
933 dev_info(&pdev->dev, "spi master remove: bus_num=%d\n",
934 hw->master->bus_num);
935
936 spi_bitbang_stop(&hw->bitbang);
937 free_irq(hw->irq, hw);
938 release_mem_region((unsigned long)hw->regs, sizeof(psc_spi_t));
939
940 if (hw->usedma) {
941 au1550_spi_dma_rxtmp_free(hw);
942 au1xxx_dbdma_chan_free(hw->dma_rx_ch);
943 au1xxx_dbdma_chan_free(hw->dma_tx_ch);
944 }
945
946 platform_set_drvdata(pdev, NULL);
947
948 spi_master_put(hw->master);
949 return 0;
950}
951
952static struct platform_driver au1550_spi_drv = {
953 .remove = __exit_p(au1550_spi_remove),
954 .driver = {
955 .name = "au1550-spi",
956 .owner = THIS_MODULE,
957 },
958};
959
960static int __init au1550_spi_init(void)
961{
962 return platform_driver_probe(&au1550_spi_drv, au1550_spi_probe);
963}
964module_init(au1550_spi_init);
965
966static void __exit au1550_spi_exit(void)
967{
968 platform_driver_unregister(&au1550_spi_drv);
969}
970module_exit(au1550_spi_exit);
971
972MODULE_DESCRIPTION("Au1550 PSC SPI Driver");
973MODULE_AUTHOR("Jan Nikitenko <jan.nikitenko@gmail.com>");
974MODULE_LICENSE("GPL");
diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c
index 6657331eed93..c3219b29b5ac 100644
--- a/drivers/spi/spi.c
+++ b/drivers/spi/spi.c
@@ -152,6 +152,11 @@ static void spi_drv_shutdown(struct device *dev)
152 sdrv->shutdown(to_spi_device(dev)); 152 sdrv->shutdown(to_spi_device(dev));
153} 153}
154 154
155/**
156 * spi_register_driver - register a SPI driver
157 * @sdrv: the driver to register
158 * Context: can sleep
159 */
155int spi_register_driver(struct spi_driver *sdrv) 160int spi_register_driver(struct spi_driver *sdrv)
156{ 161{
157 sdrv->driver.bus = &spi_bus_type; 162 sdrv->driver.bus = &spi_bus_type;
@@ -183,7 +188,13 @@ static LIST_HEAD(board_list);
183static DECLARE_MUTEX(board_lock); 188static DECLARE_MUTEX(board_lock);
184 189
185 190
186/* On typical mainboards, this is purely internal; and it's not needed 191/**
192 * spi_new_device - instantiate one new SPI device
193 * @master: Controller to which device is connected
194 * @chip: Describes the SPI device
195 * Context: can sleep
196 *
197 * On typical mainboards, this is purely internal; and it's not needed
187 * after board init creates the hard-wired devices. Some development 198 * after board init creates the hard-wired devices. Some development
188 * platforms may not be able to use spi_register_board_info though, and 199 * platforms may not be able to use spi_register_board_info though, and
189 * this is exported so that for example a USB or parport based adapter 200 * this is exported so that for example a USB or parport based adapter
@@ -251,7 +262,12 @@ fail:
251} 262}
252EXPORT_SYMBOL_GPL(spi_new_device); 263EXPORT_SYMBOL_GPL(spi_new_device);
253 264
254/* 265/**
266 * spi_register_board_info - register SPI devices for a given board
267 * @info: array of chip descriptors
268 * @n: how many descriptors are provided
269 * Context: can sleep
270 *
255 * Board-specific early init code calls this (probably during arch_initcall) 271 * Board-specific early init code calls this (probably during arch_initcall)
256 * with segments of the SPI device table. Any device nodes are created later, 272 * with segments of the SPI device table. Any device nodes are created later,
257 * after the relevant parent SPI controller (bus_num) is defined. We keep 273 * after the relevant parent SPI controller (bus_num) is defined. We keep
@@ -337,9 +353,10 @@ static struct class spi_master_class = {
337/** 353/**
338 * spi_alloc_master - allocate SPI master controller 354 * spi_alloc_master - allocate SPI master controller
339 * @dev: the controller, possibly using the platform_bus 355 * @dev: the controller, possibly using the platform_bus
340 * @size: how much driver-private data to preallocate; the pointer to this 356 * @size: how much zeroed driver-private data to allocate; the pointer to this
341 * memory is in the class_data field of the returned class_device, 357 * memory is in the class_data field of the returned class_device,
342 * accessible with spi_master_get_devdata(). 358 * accessible with spi_master_get_devdata().
359 * Context: can sleep
343 * 360 *
344 * This call is used only by SPI master controller drivers, which are the 361 * This call is used only by SPI master controller drivers, which are the
345 * only ones directly touching chip registers. It's how they allocate 362 * only ones directly touching chip registers. It's how they allocate
@@ -375,6 +392,7 @@ EXPORT_SYMBOL_GPL(spi_alloc_master);
375/** 392/**
376 * spi_register_master - register SPI master controller 393 * spi_register_master - register SPI master controller
377 * @master: initialized master, originally from spi_alloc_master() 394 * @master: initialized master, originally from spi_alloc_master()
395 * Context: can sleep
378 * 396 *
379 * SPI master controllers connect to their drivers using some non-SPI bus, 397 * SPI master controllers connect to their drivers using some non-SPI bus,
380 * such as the platform bus. The final stage of probe() in that code 398 * such as the platform bus. The final stage of probe() in that code
@@ -437,6 +455,7 @@ static int __unregister(struct device *dev, void *unused)
437/** 455/**
438 * spi_unregister_master - unregister SPI master controller 456 * spi_unregister_master - unregister SPI master controller
439 * @master: the master being unregistered 457 * @master: the master being unregistered
458 * Context: can sleep
440 * 459 *
441 * This call is used only by SPI master controller drivers, which are the 460 * This call is used only by SPI master controller drivers, which are the
442 * only ones directly touching chip registers. 461 * only ones directly touching chip registers.
@@ -455,6 +474,7 @@ EXPORT_SYMBOL_GPL(spi_unregister_master);
455/** 474/**
456 * spi_busnum_to_master - look up master associated with bus_num 475 * spi_busnum_to_master - look up master associated with bus_num
457 * @bus_num: the master's bus number 476 * @bus_num: the master's bus number
477 * Context: can sleep
458 * 478 *
459 * This call may be used with devices that are registered after 479 * This call may be used with devices that are registered after
460 * arch init time. It returns a refcounted pointer to the relevant 480 * arch init time. It returns a refcounted pointer to the relevant
@@ -492,6 +512,7 @@ static void spi_complete(void *arg)
492 * spi_sync - blocking/synchronous SPI data transfers 512 * spi_sync - blocking/synchronous SPI data transfers
493 * @spi: device with which data will be exchanged 513 * @spi: device with which data will be exchanged
494 * @message: describes the data transfers 514 * @message: describes the data transfers
515 * Context: can sleep
495 * 516 *
496 * This call may only be used from a context that may sleep. The sleep 517 * This call may only be used from a context that may sleep. The sleep
497 * is non-interruptible, and has no timeout. Low-overhead controller 518 * is non-interruptible, and has no timeout. Low-overhead controller
@@ -508,7 +529,7 @@ static void spi_complete(void *arg)
508 * 529 *
509 * The return value is a negative error code if the message could not be 530 * The return value is a negative error code if the message could not be
510 * submitted, else zero. When the value is zero, then message->status is 531 * submitted, else zero. When the value is zero, then message->status is
511 * also defined: it's the completion code for the transfer, either zero 532 * also defined; it's the completion code for the transfer, either zero
512 * or a negative error code from the controller driver. 533 * or a negative error code from the controller driver.
513 */ 534 */
514int spi_sync(struct spi_device *spi, struct spi_message *message) 535int spi_sync(struct spi_device *spi, struct spi_message *message)
@@ -538,6 +559,7 @@ static u8 *buf;
538 * @n_tx: size of txbuf, in bytes 559 * @n_tx: size of txbuf, in bytes
539 * @rxbuf: buffer into which data will be read 560 * @rxbuf: buffer into which data will be read
540 * @n_rx: size of rxbuf, in bytes (need not be dma-safe) 561 * @n_rx: size of rxbuf, in bytes (need not be dma-safe)
562 * Context: can sleep
541 * 563 *
542 * This performs a half duplex MicroWire style transaction with the 564 * This performs a half duplex MicroWire style transaction with the
543 * device, sending txbuf and then reading rxbuf. The return value 565 * device, sending txbuf and then reading rxbuf. The return value
@@ -545,7 +567,8 @@ static u8 *buf;
545 * This call may only be used from a context that may sleep. 567 * This call may only be used from a context that may sleep.
546 * 568 *
547 * Parameters to this routine are always copied using a small buffer; 569 * Parameters to this routine are always copied using a small buffer;
548 * performance-sensitive or bulk transfer code should instead use 570 * portable code should never use this for more than 32 bytes.
571 * Performance-sensitive or bulk transfer code should instead use
549 * spi_{async,sync}() calls with dma-safe buffers. 572 * spi_{async,sync}() calls with dma-safe buffers.
550 */ 573 */
551int spi_write_then_read(struct spi_device *spi, 574int spi_write_then_read(struct spi_device *spi,
diff --git a/drivers/spi/spi_butterfly.c b/drivers/spi/spi_butterfly.c
index 312987a03210..0ee2b2090252 100644
--- a/drivers/spi/spi_butterfly.c
+++ b/drivers/spi/spi_butterfly.c
@@ -20,7 +20,7 @@
20#include <linux/kernel.h> 20#include <linux/kernel.h>
21#include <linux/init.h> 21#include <linux/init.h>
22#include <linux/delay.h> 22#include <linux/delay.h>
23#include <linux/platform_device.h> 23#include <linux/device.h>
24#include <linux/parport.h> 24#include <linux/parport.h>
25 25
26#include <linux/sched.h> 26#include <linux/sched.h>
@@ -40,8 +40,6 @@
40 * and use this custom parallel port cable. 40 * and use this custom parallel port cable.
41 */ 41 */
42 42
43#undef HAVE_USI /* nyet */
44
45 43
46/* DATA output bits (pins 2..9 == D0..D7) */ 44/* DATA output bits (pins 2..9 == D0..D7) */
47#define butterfly_nreset (1 << 1) /* pin 3 */ 45#define butterfly_nreset (1 << 1) /* pin 3 */
@@ -49,19 +47,13 @@
49#define spi_sck_bit (1 << 0) /* pin 2 */ 47#define spi_sck_bit (1 << 0) /* pin 2 */
50#define spi_mosi_bit (1 << 7) /* pin 9 */ 48#define spi_mosi_bit (1 << 7) /* pin 9 */
51 49
52#define usi_sck_bit (1 << 3) /* pin 5 */
53#define usi_mosi_bit (1 << 4) /* pin 6 */
54
55#define vcc_bits ((1 << 6) | (1 << 5)) /* pins 7, 8 */ 50#define vcc_bits ((1 << 6) | (1 << 5)) /* pins 7, 8 */
56 51
57/* STATUS input bits */ 52/* STATUS input bits */
58#define spi_miso_bit PARPORT_STATUS_BUSY /* pin 11 */ 53#define spi_miso_bit PARPORT_STATUS_BUSY /* pin 11 */
59 54
60#define usi_miso_bit PARPORT_STATUS_PAPEROUT /* pin 12 */
61
62/* CONTROL output bits */ 55/* CONTROL output bits */
63#define spi_cs_bit PARPORT_CONTROL_SELECT /* pin 17 */ 56#define spi_cs_bit PARPORT_CONTROL_SELECT /* pin 17 */
64/* USI uses no chipselect */
65 57
66 58
67 59
@@ -70,15 +62,6 @@ static inline struct butterfly *spidev_to_pp(struct spi_device *spi)
70 return spi->controller_data; 62 return spi->controller_data;
71} 63}
72 64
73static inline int is_usidev(struct spi_device *spi)
74{
75#ifdef HAVE_USI
76 return spi->chip_select != 1;
77#else
78 return 0;
79#endif
80}
81
82 65
83struct butterfly { 66struct butterfly {
84 /* REVISIT ... for now, this must be first */ 67 /* REVISIT ... for now, this must be first */
@@ -97,23 +80,13 @@ struct butterfly {
97 80
98/*----------------------------------------------------------------------*/ 81/*----------------------------------------------------------------------*/
99 82
100/*
101 * these routines may be slower than necessary because they're hiding
102 * the fact that there are two different SPI busses on this cable: one
103 * to the DataFlash chip (or AVR SPI controller), the other to the
104 * AVR USI controller.
105 */
106
107static inline void 83static inline void
108setsck(struct spi_device *spi, int is_on) 84setsck(struct spi_device *spi, int is_on)
109{ 85{
110 struct butterfly *pp = spidev_to_pp(spi); 86 struct butterfly *pp = spidev_to_pp(spi);
111 u8 bit, byte = pp->lastbyte; 87 u8 bit, byte = pp->lastbyte;
112 88
113 if (is_usidev(spi)) 89 bit = spi_sck_bit;
114 bit = usi_sck_bit;
115 else
116 bit = spi_sck_bit;
117 90
118 if (is_on) 91 if (is_on)
119 byte |= bit; 92 byte |= bit;
@@ -129,10 +102,7 @@ setmosi(struct spi_device *spi, int is_on)
129 struct butterfly *pp = spidev_to_pp(spi); 102 struct butterfly *pp = spidev_to_pp(spi);
130 u8 bit, byte = pp->lastbyte; 103 u8 bit, byte = pp->lastbyte;
131 104
132 if (is_usidev(spi)) 105 bit = spi_mosi_bit;
133 bit = usi_mosi_bit;
134 else
135 bit = spi_mosi_bit;
136 106
137 if (is_on) 107 if (is_on)
138 byte |= bit; 108 byte |= bit;
@@ -148,10 +118,7 @@ static inline int getmiso(struct spi_device *spi)
148 int value; 118 int value;
149 u8 bit; 119 u8 bit;
150 120
151 if (is_usidev(spi)) 121 bit = spi_miso_bit;
152 bit = usi_miso_bit;
153 else
154 bit = spi_miso_bit;
155 122
156 /* only STATUS_BUSY is NOT negated */ 123 /* only STATUS_BUSY is NOT negated */
157 value = !(parport_read_status(pp->port) & bit); 124 value = !(parport_read_status(pp->port) & bit);
@@ -166,10 +133,6 @@ static void butterfly_chipselect(struct spi_device *spi, int value)
166 if (value != BITBANG_CS_INACTIVE) 133 if (value != BITBANG_CS_INACTIVE)
167 setsck(spi, spi->mode & SPI_CPOL); 134 setsck(spi, spi->mode & SPI_CPOL);
168 135
169 /* no chipselect on this USI link config */
170 if (is_usidev(spi))
171 return;
172
173 /* here, value == "activate or not"; 136 /* here, value == "activate or not";
174 * most PARPORT_CONTROL_* bits are negated, so we must 137 * most PARPORT_CONTROL_* bits are negated, so we must
175 * morph it to value == "bit value to write in control register" 138 * morph it to value == "bit value to write in control register"
@@ -237,24 +200,16 @@ static void butterfly_attach(struct parport *p)
237 int status; 200 int status;
238 struct butterfly *pp; 201 struct butterfly *pp;
239 struct spi_master *master; 202 struct spi_master *master;
240 struct platform_device *pdev; 203 struct device *dev = p->physport->dev;
241 204
242 if (butterfly) 205 if (butterfly || !dev)
243 return; 206 return;
244 207
245 /* REVISIT: this just _assumes_ a butterfly is there ... no probe, 208 /* REVISIT: this just _assumes_ a butterfly is there ... no probe,
246 * and no way to be selective about what it binds to. 209 * and no way to be selective about what it binds to.
247 */ 210 */
248 211
249 /* FIXME where should master->cdev.dev come from? 212 master = spi_alloc_master(dev, sizeof *pp);
250 * e.g. /sys/bus/pnp0/00:0b, some PCI thing, etc
251 * setting up a platform device like this is an ugly kluge...
252 */
253 pdev = platform_device_register_simple("butterfly", -1, NULL, 0);
254 if (IS_ERR(pdev))
255 return;
256
257 master = spi_alloc_master(&pdev->dev, sizeof *pp);
258 if (!master) { 213 if (!master) {
259 status = -ENOMEM; 214 status = -ENOMEM;
260 goto done; 215 goto done;
@@ -300,7 +255,7 @@ static void butterfly_attach(struct parport *p)
300 parport_frob_control(pp->port, spi_cs_bit, 0); 255 parport_frob_control(pp->port, spi_cs_bit, 0);
301 256
302 /* stabilize power with chip in reset (nRESET), and 257 /* stabilize power with chip in reset (nRESET), and
303 * both spi_sck_bit and usi_sck_bit clear (CPOL=0) 258 * spi_sck_bit clear (CPOL=0)
304 */ 259 */
305 pp->lastbyte |= vcc_bits; 260 pp->lastbyte |= vcc_bits;
306 parport_write_data(pp->port, pp->lastbyte); 261 parport_write_data(pp->port, pp->lastbyte);
@@ -334,23 +289,6 @@ static void butterfly_attach(struct parport *p)
334 pr_debug("%s: dataflash at %s\n", p->name, 289 pr_debug("%s: dataflash at %s\n", p->name,
335 pp->dataflash->dev.bus_id); 290 pp->dataflash->dev.bus_id);
336 291
337#ifdef HAVE_USI
338 /* Bus 2 is only for talking to the AVR, and it can work no
339 * matter who masters bus 1; needs appropriate AVR firmware.
340 */
341 pp->info[1].max_speed_hz = 10 /* ?? */ * 1000 * 1000;
342 strcpy(pp->info[1].modalias, "butterfly");
343 // pp->info[1].platform_data = ... TBD ... ;
344 pp->info[1].chip_select = 2,
345 pp->info[1].controller_data = pp;
346 pp->butterfly = spi_new_device(pp->bitbang.master, &pp->info[1]);
347 if (pp->butterfly)
348 pr_debug("%s: butterfly at %s\n", p->name,
349 pp->butterfly->dev.bus_id);
350
351 /* FIXME setup ACK for the IRQ line ... */
352#endif
353
354 // dev_info(_what?_, ...) 292 // dev_info(_what?_, ...)
355 pr_info("%s: AVR Butterfly\n", p->name); 293 pr_info("%s: AVR Butterfly\n", p->name);
356 butterfly = pp; 294 butterfly = pp;
@@ -366,14 +304,12 @@ clean1:
366clean0: 304clean0:
367 (void) spi_master_put(pp->bitbang.master); 305 (void) spi_master_put(pp->bitbang.master);
368done: 306done:
369 platform_device_unregister(pdev);
370 pr_debug("%s: butterfly probe, fail %d\n", p->name, status); 307 pr_debug("%s: butterfly probe, fail %d\n", p->name, status);
371} 308}
372 309
373static void butterfly_detach(struct parport *p) 310static void butterfly_detach(struct parport *p)
374{ 311{
375 struct butterfly *pp; 312 struct butterfly *pp;
376 struct platform_device *pdev;
377 int status; 313 int status;
378 314
379 /* FIXME this global is ugly ... but, how to quickly get from 315 /* FIXME this global is ugly ... but, how to quickly get from
@@ -386,7 +322,6 @@ static void butterfly_detach(struct parport *p)
386 butterfly = NULL; 322 butterfly = NULL;
387 323
388 /* stop() unregisters child devices too */ 324 /* stop() unregisters child devices too */
389 pdev = to_platform_device(pp->bitbang.master->cdev.dev);
390 status = spi_bitbang_stop(&pp->bitbang); 325 status = spi_bitbang_stop(&pp->bitbang);
391 326
392 /* turn off VCC */ 327 /* turn off VCC */
@@ -397,8 +332,6 @@ static void butterfly_detach(struct parport *p)
397 parport_unregister_device(pp->pd); 332 parport_unregister_device(pp->pd);
398 333
399 (void) spi_master_put(pp->bitbang.master); 334 (void) spi_master_put(pp->bitbang.master);
400
401 platform_device_unregister(pdev);
402} 335}
403 336
404static struct parport_driver butterfly_driver = { 337static struct parport_driver butterfly_driver = {
diff --git a/drivers/spi/spidev.c b/drivers/spi/spidev.c
new file mode 100644
index 000000000000..c0a6dce800a3
--- /dev/null
+++ b/drivers/spi/spidev.c
@@ -0,0 +1,584 @@
1/*
2 * spidev.c -- simple synchronous userspace interface to SPI devices
3 *
4 * Copyright (C) 2006 SWAPP
5 * Andrea Paterniani <a.paterniani@swapp-eng.it>
6 * Copyright (C) 2007 David Brownell (simplification, cleanup)
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22
23#include <linux/init.h>
24#include <linux/module.h>
25#include <linux/ioctl.h>
26#include <linux/fs.h>
27#include <linux/device.h>
28#include <linux/list.h>
29#include <linux/errno.h>
30#include <linux/mutex.h>
31#include <linux/slab.h>
32
33#include <linux/spi/spi.h>
34#include <linux/spi/spidev.h>
35
36#include <asm/uaccess.h>
37
38
39/*
40 * This supports acccess to SPI devices using normal userspace I/O calls.
41 * Note that while traditional UNIX/POSIX I/O semantics are half duplex,
42 * and often mask message boundaries, full SPI support requires full duplex
43 * transfers. There are several kinds of of internal message boundaries to
44 * handle chipselect management and other protocol options.
45 *
46 * SPI has a character major number assigned. We allocate minor numbers
47 * dynamically using a bitmask. You must use hotplug tools, such as udev
48 * (or mdev with busybox) to create and destroy the /dev/spidevB.C device
49 * nodes, since there is no fixed association of minor numbers with any
50 * particular SPI bus or device.
51 */
52#define SPIDEV_MAJOR 153 /* assigned */
53#define N_SPI_MINORS 32 /* ... up to 256 */
54
55static unsigned long minors[N_SPI_MINORS / BITS_PER_LONG];
56
57
58/* Bit masks for spi_device.mode management */
59#define SPI_MODE_MASK (SPI_CPHA | SPI_CPOL)
60
61
62struct spidev_data {
63 struct device dev;
64 struct spi_device *spi;
65 struct list_head device_entry;
66
67 struct mutex buf_lock;
68 unsigned users;
69 u8 *buffer;
70};
71
72static LIST_HEAD(device_list);
73static DEFINE_MUTEX(device_list_lock);
74
75static unsigned bufsiz = 4096;
76module_param(bufsiz, uint, S_IRUGO);
77MODULE_PARM_DESC(bufsiz, "data bytes in biggest supported SPI message");
78
79/*-------------------------------------------------------------------------*/
80
81/* Read-only message with current device setup */
82static ssize_t
83spidev_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos)
84{
85 struct spidev_data *spidev;
86 struct spi_device *spi;
87 ssize_t status = 0;
88
89 /* chipselect only toggles at start or end of operation */
90 if (count > bufsiz)
91 return -EMSGSIZE;
92
93 spidev = filp->private_data;
94 spi = spidev->spi;
95
96 mutex_lock(&spidev->buf_lock);
97 status = spi_read(spi, spidev->buffer, count);
98 if (status == 0) {
99 unsigned long missing;
100
101 missing = copy_to_user(buf, spidev->buffer, count);
102 if (count && missing == count)
103 status = -EFAULT;
104 else
105 status = count - missing;
106 }
107 mutex_unlock(&spidev->buf_lock);
108
109 return status;
110}
111
112/* Write-only message with current device setup */
113static ssize_t
114spidev_write(struct file *filp, const char __user *buf,
115 size_t count, loff_t *f_pos)
116{
117 struct spidev_data *spidev;
118 struct spi_device *spi;
119 ssize_t status = 0;
120 unsigned long missing;
121
122 /* chipselect only toggles at start or end of operation */
123 if (count > bufsiz)
124 return -EMSGSIZE;
125
126 spidev = filp->private_data;
127 spi = spidev->spi;
128
129 mutex_lock(&spidev->buf_lock);
130 missing = copy_from_user(spidev->buffer, buf, count);
131 if (missing == 0) {
132 status = spi_write(spi, spidev->buffer, count);
133 if (status == 0)
134 status = count;
135 } else
136 status = -EFAULT;
137 mutex_unlock(&spidev->buf_lock);
138
139 return status;
140}
141
142static int spidev_message(struct spidev_data *spidev,
143 struct spi_ioc_transfer *u_xfers, unsigned n_xfers)
144{
145 struct spi_message msg;
146 struct spi_transfer *k_xfers;
147 struct spi_transfer *k_tmp;
148 struct spi_ioc_transfer *u_tmp;
149 struct spi_device *spi = spidev->spi;
150 unsigned n, total;
151 u8 *buf;
152 int status = -EFAULT;
153
154 spi_message_init(&msg);
155 k_xfers = kcalloc(n_xfers, sizeof(*k_tmp), GFP_KERNEL);
156 if (k_xfers == NULL)
157 return -ENOMEM;
158
159 /* Construct spi_message, copying any tx data to bounce buffer.
160 * We walk the array of user-provided transfers, using each one
161 * to initialize a kernel version of the same transfer.
162 */
163 mutex_lock(&spidev->buf_lock);
164 buf = spidev->buffer;
165 total = 0;
166 for (n = n_xfers, k_tmp = k_xfers, u_tmp = u_xfers;
167 n;
168 n--, k_tmp++, u_tmp++) {
169 k_tmp->len = u_tmp->len;
170
171 if (u_tmp->rx_buf) {
172 k_tmp->rx_buf = buf;
173 if (!access_ok(VERIFY_WRITE, u_tmp->rx_buf, u_tmp->len))
174 goto done;
175 }
176 if (u_tmp->tx_buf) {
177 k_tmp->tx_buf = buf;
178 if (copy_from_user(buf, (const u8 __user *)u_tmp->tx_buf,
179 u_tmp->len))
180 goto done;
181 }
182
183 total += k_tmp->len;
184 if (total > bufsiz) {
185 status = -EMSGSIZE;
186 goto done;
187 }
188 buf += k_tmp->len;
189
190 k_tmp->cs_change = !!u_tmp->cs_change;
191 k_tmp->bits_per_word = u_tmp->bits_per_word;
192 k_tmp->delay_usecs = u_tmp->delay_usecs;
193 k_tmp->speed_hz = u_tmp->speed_hz;
194#ifdef VERBOSE
195 dev_dbg(&spi->dev,
196 " xfer len %zd %s%s%s%dbits %u usec %uHz\n",
197 u_tmp->len,
198 u_tmp->rx_buf ? "rx " : "",
199 u_tmp->tx_buf ? "tx " : "",
200 u_tmp->cs_change ? "cs " : "",
201 u_tmp->bits_per_word ? : spi->bits_per_word,
202 u_tmp->delay_usecs,
203 u_tmp->speed_hz ? : spi->max_speed_hz);
204#endif
205 spi_message_add_tail(k_tmp, &msg);
206 }
207
208 status = spi_sync(spi, &msg);
209 if (status < 0)
210 goto done;
211
212 /* copy any rx data out of bounce buffer */
213 buf = spidev->buffer;
214 for (n = n_xfers, u_tmp = u_xfers; n; n--, u_tmp++) {
215 if (u_tmp->rx_buf) {
216 if (__copy_to_user((u8 __user *)u_tmp->rx_buf, buf,
217 u_tmp->len)) {
218 status = -EFAULT;
219 goto done;
220 }
221 }
222 buf += u_tmp->len;
223 }
224 status = total;
225
226done:
227 mutex_unlock(&spidev->buf_lock);
228 kfree(k_xfers);
229 return status;
230}
231
232static int
233spidev_ioctl(struct inode *inode, struct file *filp,
234 unsigned int cmd, unsigned long arg)
235{
236 int err = 0;
237 int retval = 0;
238 struct spidev_data *spidev;
239 struct spi_device *spi;
240 u32 tmp;
241 unsigned n_ioc;
242 struct spi_ioc_transfer *ioc;
243
244 /* Check type and command number */
245 if (_IOC_TYPE(cmd) != SPI_IOC_MAGIC)
246 return -ENOTTY;
247
248 /* Check access direction once here; don't repeat below.
249 * IOC_DIR is from the user perspective, while access_ok is
250 * from the kernel perspective; so they look reversed.
251 */
252 if (_IOC_DIR(cmd) & _IOC_READ)
253 err = !access_ok(VERIFY_WRITE,
254 (void __user *)arg, _IOC_SIZE(cmd));
255 if (err == 0 && _IOC_DIR(cmd) & _IOC_WRITE)
256 err = !access_ok(VERIFY_READ,
257 (void __user *)arg, _IOC_SIZE(cmd));
258 if (err)
259 return -EFAULT;
260
261 spidev = filp->private_data;
262 spi = spidev->spi;
263
264 switch (cmd) {
265 /* read requests */
266 case SPI_IOC_RD_MODE:
267 retval = __put_user(spi->mode & SPI_MODE_MASK,
268 (__u8 __user *)arg);
269 break;
270 case SPI_IOC_RD_LSB_FIRST:
271 retval = __put_user((spi->mode & SPI_LSB_FIRST) ? 1 : 0,
272 (__u8 __user *)arg);
273 break;
274 case SPI_IOC_RD_BITS_PER_WORD:
275 retval = __put_user(spi->bits_per_word, (__u8 __user *)arg);
276 break;
277 case SPI_IOC_RD_MAX_SPEED_HZ:
278 retval = __put_user(spi->max_speed_hz, (__u32 __user *)arg);
279 break;
280
281 /* write requests */
282 case SPI_IOC_WR_MODE:
283 retval = __get_user(tmp, (u8 __user *)arg);
284 if (retval == 0) {
285 u8 save = spi->mode;
286
287 if (tmp & ~SPI_MODE_MASK) {
288 retval = -EINVAL;
289 break;
290 }
291
292 tmp |= spi->mode & ~SPI_MODE_MASK;
293 spi->mode = (u8)tmp;
294 retval = spi_setup(spi);
295 if (retval < 0)
296 spi->mode = save;
297 else
298 dev_dbg(&spi->dev, "spi mode %02x\n", tmp);
299 }
300 break;
301 case SPI_IOC_WR_LSB_FIRST:
302 retval = __get_user(tmp, (__u8 __user *)arg);
303 if (retval == 0) {
304 u8 save = spi->mode;
305
306 if (tmp)
307 spi->mode |= SPI_LSB_FIRST;
308 else
309 spi->mode &= ~SPI_LSB_FIRST;
310 retval = spi_setup(spi);
311 if (retval < 0)
312 spi->mode = save;
313 else
314 dev_dbg(&spi->dev, "%csb first\n",
315 tmp ? 'l' : 'm');
316 }
317 break;
318 case SPI_IOC_WR_BITS_PER_WORD:
319 retval = __get_user(tmp, (__u8 __user *)arg);
320 if (retval == 0) {
321 u8 save = spi->bits_per_word;
322
323 spi->bits_per_word = tmp;
324 retval = spi_setup(spi);
325 if (retval < 0)
326 spi->bits_per_word = save;
327 else
328 dev_dbg(&spi->dev, "%d bits per word\n", tmp);
329 }
330 break;
331 case SPI_IOC_WR_MAX_SPEED_HZ:
332 retval = __get_user(tmp, (__u32 __user *)arg);
333 if (retval == 0) {
334 u32 save = spi->max_speed_hz;
335
336 spi->max_speed_hz = tmp;
337 retval = spi_setup(spi);
338 if (retval < 0)
339 spi->max_speed_hz = save;
340 else
341 dev_dbg(&spi->dev, "%d Hz (max)\n", tmp);
342 }
343 break;
344
345 default:
346 /* segmented and/or full-duplex I/O request */
347 if (_IOC_NR(cmd) != _IOC_NR(SPI_IOC_MESSAGE(0))
348 || _IOC_DIR(cmd) != _IOC_WRITE)
349 return -ENOTTY;
350
351 tmp = _IOC_SIZE(cmd);
352 if ((tmp % sizeof(struct spi_ioc_transfer)) != 0) {
353 retval = -EINVAL;
354 break;
355 }
356 n_ioc = tmp / sizeof(struct spi_ioc_transfer);
357 if (n_ioc == 0)
358 break;
359
360 /* copy into scratch area */
361 ioc = kmalloc(tmp, GFP_KERNEL);
362 if (!ioc) {
363 retval = -ENOMEM;
364 break;
365 }
366 if (__copy_from_user(ioc, (void __user *)arg, tmp)) {
367 retval = -EFAULT;
368 break;
369 }
370
371 /* translate to spi_message, execute */
372 retval = spidev_message(spidev, ioc, n_ioc);
373 kfree(ioc);
374 break;
375 }
376 return retval;
377}
378
379static int spidev_open(struct inode *inode, struct file *filp)
380{
381 struct spidev_data *spidev;
382 int status = -ENXIO;
383
384 mutex_lock(&device_list_lock);
385
386 list_for_each_entry(spidev, &device_list, device_entry) {
387 if (spidev->dev.devt == inode->i_rdev) {
388 status = 0;
389 break;
390 }
391 }
392 if (status == 0) {
393 if (!spidev->buffer) {
394 spidev->buffer = kmalloc(bufsiz, GFP_KERNEL);
395 if (!spidev->buffer) {
396 dev_dbg(&spidev->spi->dev, "open/ENOMEM\n");
397 status = -ENOMEM;
398 }
399 }
400 if (status == 0) {
401 spidev->users++;
402 filp->private_data = spidev;
403 nonseekable_open(inode, filp);
404 }
405 } else
406 pr_debug("spidev: nothing for minor %d\n", iminor(inode));
407
408 mutex_unlock(&device_list_lock);
409 return status;
410}
411
412static int spidev_release(struct inode *inode, struct file *filp)
413{
414 struct spidev_data *spidev;
415 int status = 0;
416
417 mutex_lock(&device_list_lock);
418 spidev = filp->private_data;
419 filp->private_data = NULL;
420 spidev->users--;
421 if (!spidev->users) {
422 kfree(spidev->buffer);
423 spidev->buffer = NULL;
424 }
425 mutex_unlock(&device_list_lock);
426
427 return status;
428}
429
430static struct file_operations spidev_fops = {
431 .owner = THIS_MODULE,
432 /* REVISIT switch to aio primitives, so that userspace
433 * gets more complete API coverage. It'll simplify things
434 * too, except for the locking.
435 */
436 .write = spidev_write,
437 .read = spidev_read,
438 .ioctl = spidev_ioctl,
439 .open = spidev_open,
440 .release = spidev_release,
441};
442
443/*-------------------------------------------------------------------------*/
444
445/* The main reason to have this class is to make mdev/udev create the
446 * /dev/spidevB.C character device nodes exposing our userspace API.
447 * It also simplifies memory management.
448 */
449
450static void spidev_classdev_release(struct device *dev)
451{
452 struct spidev_data *spidev;
453
454 spidev = container_of(dev, struct spidev_data, dev);
455 kfree(spidev);
456}
457
458static struct class spidev_class = {
459 .name = "spidev",
460 .owner = THIS_MODULE,
461 .dev_release = spidev_classdev_release,
462};
463
464/*-------------------------------------------------------------------------*/
465
466static int spidev_probe(struct spi_device *spi)
467{
468 struct spidev_data *spidev;
469 int status;
470 unsigned long minor;
471
472 /* Allocate driver data */
473 spidev = kzalloc(sizeof(*spidev), GFP_KERNEL);
474 if (!spidev)
475 return -ENOMEM;
476
477 /* Initialize the driver data */
478 spidev->spi = spi;
479 mutex_init(&spidev->buf_lock);
480
481 INIT_LIST_HEAD(&spidev->device_entry);
482
483 /* If we can allocate a minor number, hook up this device.
484 * Reusing minors is fine so long as udev or mdev is working.
485 */
486 mutex_lock(&device_list_lock);
487 minor = find_first_zero_bit(minors, ARRAY_SIZE(minors));
488 if (minor < N_SPI_MINORS) {
489 spidev->dev.parent = &spi->dev;
490 spidev->dev.class = &spidev_class;
491 spidev->dev.devt = MKDEV(SPIDEV_MAJOR, minor);
492 snprintf(spidev->dev.bus_id, sizeof spidev->dev.bus_id,
493 "spidev%d.%d",
494 spi->master->bus_num, spi->chip_select);
495 status = device_register(&spidev->dev);
496 } else {
497 dev_dbg(&spi->dev, "no minor number available!\n");
498 status = -ENODEV;
499 }
500 if (status == 0) {
501 set_bit(minor, minors);
502 dev_set_drvdata(&spi->dev, spidev);
503 list_add(&spidev->device_entry, &device_list);
504 }
505 mutex_unlock(&device_list_lock);
506
507 if (status != 0)
508 kfree(spidev);
509
510 return status;
511}
512
513static int spidev_remove(struct spi_device *spi)
514{
515 struct spidev_data *spidev = dev_get_drvdata(&spi->dev);
516
517 mutex_lock(&device_list_lock);
518
519 list_del(&spidev->device_entry);
520 dev_set_drvdata(&spi->dev, NULL);
521 clear_bit(MINOR(spidev->dev.devt), minors);
522 device_unregister(&spidev->dev);
523
524 mutex_unlock(&device_list_lock);
525
526 return 0;
527}
528
529static struct spi_driver spidev_spi = {
530 .driver = {
531 .name = "spidev",
532 .owner = THIS_MODULE,
533 },
534 .probe = spidev_probe,
535 .remove = __devexit_p(spidev_remove),
536
537 /* NOTE: suspend/resume methods are not necessary here.
538 * We don't do anything except pass the requests to/from
539 * the underlying controller. The refrigerator handles
540 * most issues; the controller driver handles the rest.
541 */
542};
543
544/*-------------------------------------------------------------------------*/
545
546static int __init spidev_init(void)
547{
548 int status;
549
550 /* Claim our 256 reserved device numbers. Then register a class
551 * that will key udev/mdev to add/remove /dev nodes. Last, register
552 * the driver which manages those device numbers.
553 */
554 BUILD_BUG_ON(N_SPI_MINORS > 256);
555 status = register_chrdev(SPIDEV_MAJOR, "spi", &spidev_fops);
556 if (status < 0)
557 return status;
558
559 status = class_register(&spidev_class);
560 if (status < 0) {
561 unregister_chrdev(SPIDEV_MAJOR, spidev_spi.driver.name);
562 return status;
563 }
564
565 status = spi_register_driver(&spidev_spi);
566 if (status < 0) {
567 class_unregister(&spidev_class);
568 unregister_chrdev(SPIDEV_MAJOR, spidev_spi.driver.name);
569 }
570 return status;
571}
572module_init(spidev_init);
573
574static void __exit spidev_exit(void)
575{
576 spi_unregister_driver(&spidev_spi);
577 class_unregister(&spidev_class);
578 unregister_chrdev(SPIDEV_MAJOR, spidev_spi.driver.name);
579}
580module_exit(spidev_exit);
581
582MODULE_AUTHOR("Andrea Paterniani, <a.paterniani@swapp-eng.it>");
583MODULE_DESCRIPTION("User mode SPI device interface");
584MODULE_LICENSE("GPL");
diff --git a/drivers/telephony/ixj.c b/drivers/telephony/ixj.c
index 71cb64e41a1b..c7b0a357b04a 100644
--- a/drivers/telephony/ixj.c
+++ b/drivers/telephony/ixj.c
@@ -7692,7 +7692,7 @@ static int __init ixj_probe_pci(int *cnt)
7692 IXJ *j = NULL; 7692 IXJ *j = NULL;
7693 7693
7694 for (i = 0; i < IXJMAX - *cnt; i++) { 7694 for (i = 0; i < IXJMAX - *cnt; i++) {
7695 pci = pci_find_device(PCI_VENDOR_ID_QUICKNET, 7695 pci = pci_get_device(PCI_VENDOR_ID_QUICKNET,
7696 PCI_DEVICE_ID_QUICKNET_XJ, pci); 7696 PCI_DEVICE_ID_QUICKNET_XJ, pci);
7697 if (!pci) 7697 if (!pci)
7698 break; 7698 break;
@@ -7712,6 +7712,7 @@ static int __init ixj_probe_pci(int *cnt)
7712 printk(KERN_INFO "ixj: found Internet PhoneJACK PCI at 0x%x\n", j->DSPbase); 7712 printk(KERN_INFO "ixj: found Internet PhoneJACK PCI at 0x%x\n", j->DSPbase);
7713 ++*cnt; 7713 ++*cnt;
7714 } 7714 }
7715 pci_dev_put(pci);
7715 return probe; 7716 return probe;
7716} 7717}
7717 7718
diff --git a/drivers/usb/atm/usbatm.c b/drivers/usb/atm/usbatm.c
index b3f779f5933a..b082d95bbbaa 100644
--- a/drivers/usb/atm/usbatm.c
+++ b/drivers/usb/atm/usbatm.c
@@ -77,7 +77,6 @@
77#include <linux/sched.h> 77#include <linux/sched.h>
78#include <linux/signal.h> 78#include <linux/signal.h>
79#include <linux/slab.h> 79#include <linux/slab.h>
80#include <linux/smp_lock.h>
81#include <linux/stat.h> 80#include <linux/stat.h>
82#include <linux/timer.h> 81#include <linux/timer.h>
83#include <linux/wait.h> 82#include <linux/wait.h>
diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c
index 14de3b1b6a20..0081c1d12687 100644
--- a/drivers/usb/class/cdc-acm.c
+++ b/drivers/usb/class/cdc-acm.c
@@ -59,7 +59,6 @@
59#include <linux/tty_driver.h> 59#include <linux/tty_driver.h>
60#include <linux/tty_flip.h> 60#include <linux/tty_flip.h>
61#include <linux/module.h> 61#include <linux/module.h>
62#include <linux/smp_lock.h>
63#include <linux/mutex.h> 62#include <linux/mutex.h>
64#include <asm/uaccess.h> 63#include <asm/uaccess.h>
65#include <linux/usb.h> 64#include <linux/usb.h>
diff --git a/drivers/usb/class/usblp.c b/drivers/usb/class/usblp.c
index 6584cf00f7f3..15e740e3a5c4 100644
--- a/drivers/usb/class/usblp.c
+++ b/drivers/usb/class/usblp.c
@@ -49,7 +49,6 @@
49#include <linux/module.h> 49#include <linux/module.h>
50#include <linux/kernel.h> 50#include <linux/kernel.h>
51#include <linux/sched.h> 51#include <linux/sched.h>
52#include <linux/smp_lock.h>
53#include <linux/signal.h> 52#include <linux/signal.h>
54#include <linux/poll.h> 53#include <linux/poll.h>
55#include <linux/init.h> 54#include <linux/init.h>
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index bde29ab2b504..f6b74a678de5 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -16,7 +16,6 @@
16#include <linux/sched.h> 16#include <linux/sched.h>
17#include <linux/list.h> 17#include <linux/list.h>
18#include <linux/slab.h> 18#include <linux/slab.h>
19#include <linux/smp_lock.h>
20#include <linux/ioctl.h> 19#include <linux/ioctl.h>
21#include <linux/usb.h> 20#include <linux/usb.h>
22#include <linux/usbdevice_fs.h> 21#include <linux/usbdevice_fs.h>
diff --git a/drivers/usb/core/inode.c b/drivers/usb/core/inode.c
index cddfc62c4611..cd4f11157280 100644
--- a/drivers/usb/core/inode.c
+++ b/drivers/usb/core/inode.c
@@ -36,7 +36,6 @@
36#include <linux/usb.h> 36#include <linux/usb.h>
37#include <linux/namei.h> 37#include <linux/namei.h>
38#include <linux/usbdevice_fs.h> 38#include <linux/usbdevice_fs.h>
39#include <linux/smp_lock.h>
40#include <linux/parser.h> 39#include <linux/parser.h>
41#include <linux/notifier.h> 40#include <linux/notifier.h>
42#include <asm/byteorder.h> 41#include <asm/byteorder.h>
diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c
index dfd1b5c87ca3..18ddc5e67e39 100644
--- a/drivers/usb/core/usb.c
+++ b/drivers/usb/core/usb.c
@@ -31,7 +31,6 @@
31#include <linux/init.h> 31#include <linux/init.h>
32#include <linux/spinlock.h> 32#include <linux/spinlock.h>
33#include <linux/errno.h> 33#include <linux/errno.h>
34#include <linux/smp_lock.h>
35#include <linux/usb.h> 34#include <linux/usb.h>
36#include <linux/mutex.h> 35#include <linux/mutex.h>
37#include <linux/workqueue.h> 36#include <linux/workqueue.h>
diff --git a/drivers/usb/gadget/at91_udc.c b/drivers/usb/gadget/at91_udc.c
index 2a6e3163d944..ba163f35bf21 100644
--- a/drivers/usb/gadget/at91_udc.c
+++ b/drivers/usb/gadget/at91_udc.c
@@ -31,7 +31,6 @@
31#include <linux/delay.h> 31#include <linux/delay.h>
32#include <linux/ioport.h> 32#include <linux/ioport.h>
33#include <linux/slab.h> 33#include <linux/slab.h>
34#include <linux/smp_lock.h>
35#include <linux/errno.h> 34#include <linux/errno.h>
36#include <linux/init.h> 35#include <linux/init.h>
37#include <linux/list.h> 36#include <linux/list.h>
diff --git a/drivers/usb/gadget/dummy_hcd.c b/drivers/usb/gadget/dummy_hcd.c
index 7d7909cf2558..fcb5526cb085 100644
--- a/drivers/usb/gadget/dummy_hcd.c
+++ b/drivers/usb/gadget/dummy_hcd.c
@@ -41,7 +41,6 @@
41#include <linux/delay.h> 41#include <linux/delay.h>
42#include <linux/ioport.h> 42#include <linux/ioport.h>
43#include <linux/slab.h> 43#include <linux/slab.h>
44#include <linux/smp_lock.h>
45#include <linux/errno.h> 44#include <linux/errno.h>
46#include <linux/init.h> 45#include <linux/init.h>
47#include <linux/timer.h> 46#include <linux/timer.h>
diff --git a/drivers/usb/gadget/ether.c b/drivers/usb/gadget/ether.c
index 1dd8b57f4420..325bf7cfb83f 100644
--- a/drivers/usb/gadget/ether.c
+++ b/drivers/usb/gadget/ether.c
@@ -28,7 +28,6 @@
28#include <linux/delay.h> 28#include <linux/delay.h>
29#include <linux/ioport.h> 29#include <linux/ioport.h>
30#include <linux/slab.h> 30#include <linux/slab.h>
31#include <linux/smp_lock.h>
32#include <linux/errno.h> 31#include <linux/errno.h>
33#include <linux/init.h> 32#include <linux/init.h>
34#include <linux/timer.h> 33#include <linux/timer.h>
diff --git a/drivers/usb/gadget/goku_udc.c b/drivers/usb/gadget/goku_udc.c
index 65c91d3735de..ae931af05cef 100644
--- a/drivers/usb/gadget/goku_udc.c
+++ b/drivers/usb/gadget/goku_udc.c
@@ -30,7 +30,6 @@
30#include <linux/delay.h> 30#include <linux/delay.h>
31#include <linux/ioport.h> 31#include <linux/ioport.h>
32#include <linux/slab.h> 32#include <linux/slab.h>
33#include <linux/smp_lock.h>
34#include <linux/errno.h> 33#include <linux/errno.h>
35#include <linux/init.h> 34#include <linux/init.h>
36#include <linux/timer.h> 35#include <linux/timer.h>
diff --git a/drivers/usb/gadget/net2280.c b/drivers/usb/gadget/net2280.c
index 49d737725f70..52779c52b56d 100644
--- a/drivers/usb/gadget/net2280.c
+++ b/drivers/usb/gadget/net2280.c
@@ -54,7 +54,6 @@
54#include <linux/delay.h> 54#include <linux/delay.h>
55#include <linux/ioport.h> 55#include <linux/ioport.h>
56#include <linux/slab.h> 56#include <linux/slab.h>
57#include <linux/smp_lock.h>
58#include <linux/errno.h> 57#include <linux/errno.h>
59#include <linux/init.h> 58#include <linux/init.h>
60#include <linux/timer.h> 59#include <linux/timer.h>
diff --git a/drivers/usb/gadget/serial.c b/drivers/usb/gadget/serial.c
index e552668d36b3..f847c3414be3 100644
--- a/drivers/usb/gadget/serial.c
+++ b/drivers/usb/gadget/serial.c
@@ -22,7 +22,6 @@
22#include <linux/delay.h> 22#include <linux/delay.h>
23#include <linux/ioport.h> 23#include <linux/ioport.h>
24#include <linux/slab.h> 24#include <linux/slab.h>
25#include <linux/smp_lock.h>
26#include <linux/errno.h> 25#include <linux/errno.h>
27#include <linux/init.h> 26#include <linux/init.h>
28#include <linux/timer.h> 27#include <linux/timer.h>
diff --git a/drivers/usb/gadget/zero.c b/drivers/usb/gadget/zero.c
index 8c85e33f74a4..7078374d0b79 100644
--- a/drivers/usb/gadget/zero.c
+++ b/drivers/usb/gadget/zero.c
@@ -67,7 +67,6 @@
67#include <linux/delay.h> 67#include <linux/delay.h>
68#include <linux/ioport.h> 68#include <linux/ioport.h>
69#include <linux/slab.h> 69#include <linux/slab.h>
70#include <linux/smp_lock.h>
71#include <linux/errno.h> 70#include <linux/errno.h>
72#include <linux/init.h> 71#include <linux/init.h>
73#include <linux/timer.h> 72#include <linux/timer.h>
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index c7458f7e56cc..099aff64f536 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -24,7 +24,6 @@
24#include <linux/ioport.h> 24#include <linux/ioport.h>
25#include <linux/sched.h> 25#include <linux/sched.h>
26#include <linux/slab.h> 26#include <linux/slab.h>
27#include <linux/smp_lock.h>
28#include <linux/errno.h> 27#include <linux/errno.h>
29#include <linux/init.h> 28#include <linux/init.h>
30#include <linux/timer.h> 29#include <linux/timer.h>
diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c
index e8bbe8bc2598..a66637e725f3 100644
--- a/drivers/usb/host/ohci-hcd.c
+++ b/drivers/usb/host/ohci-hcd.c
@@ -26,7 +26,6 @@
26#include <linux/ioport.h> 26#include <linux/ioport.h>
27#include <linux/sched.h> 27#include <linux/sched.h>
28#include <linux/slab.h> 28#include <linux/slab.h>
29#include <linux/smp_lock.h>
30#include <linux/errno.h> 29#include <linux/errno.h>
31#include <linux/init.h> 30#include <linux/init.h>
32#include <linux/timer.h> 31#include <linux/timer.h>
diff --git a/drivers/usb/host/sl811-hcd.c b/drivers/usb/host/sl811-hcd.c
index 5fa5647ea095..4cfa3ff2c993 100644
--- a/drivers/usb/host/sl811-hcd.c
+++ b/drivers/usb/host/sl811-hcd.c
@@ -38,7 +38,6 @@
38#include <linux/ioport.h> 38#include <linux/ioport.h>
39#include <linux/sched.h> 39#include <linux/sched.h>
40#include <linux/slab.h> 40#include <linux/slab.h>
41#include <linux/smp_lock.h>
42#include <linux/errno.h> 41#include <linux/errno.h>
43#include <linux/init.h> 42#include <linux/init.h>
44#include <linux/timer.h> 43#include <linux/timer.h>
diff --git a/drivers/usb/host/u132-hcd.c b/drivers/usb/host/u132-hcd.c
index a7fa0d75567d..ff0dba01f1c7 100644
--- a/drivers/usb/host/u132-hcd.c
+++ b/drivers/usb/host/u132-hcd.c
@@ -43,7 +43,6 @@
43#include <linux/pci_ids.h> 43#include <linux/pci_ids.h>
44#include <linux/sched.h> 44#include <linux/sched.h>
45#include <linux/slab.h> 45#include <linux/slab.h>
46#include <linux/smp_lock.h>
47#include <linux/errno.h> 46#include <linux/errno.h>
48#include <linux/init.h> 47#include <linux/init.h>
49#include <linux/timer.h> 48#include <linux/timer.h>
diff --git a/drivers/usb/image/mdc800.c b/drivers/usb/image/mdc800.c
index d308afd06935..36502a06f73a 100644
--- a/drivers/usb/image/mdc800.c
+++ b/drivers/usb/image/mdc800.c
@@ -94,7 +94,6 @@
94#include <linux/init.h> 94#include <linux/init.h>
95#include <linux/slab.h> 95#include <linux/slab.h>
96#include <linux/module.h> 96#include <linux/module.h>
97#include <linux/smp_lock.h>
98#include <linux/wait.h> 97#include <linux/wait.h>
99#include <linux/mutex.h> 98#include <linux/mutex.h>
100 99
diff --git a/drivers/usb/image/microtek.c b/drivers/usb/image/microtek.c
index 896cb2b71020..51bd80d2b8cc 100644
--- a/drivers/usb/image/microtek.c
+++ b/drivers/usb/image/microtek.c
@@ -128,7 +128,6 @@
128#include <linux/init.h> 128#include <linux/init.h>
129#include <linux/slab.h> 129#include <linux/slab.h>
130#include <linux/spinlock.h> 130#include <linux/spinlock.h>
131#include <linux/smp_lock.h>
132#include <linux/usb.h> 131#include <linux/usb.h>
133#include <linux/proc_fs.h> 132#include <linux/proc_fs.h>
134 133
diff --git a/drivers/usb/input/xpad.c b/drivers/usb/input/xpad.c
index 735723912950..8c8cd95a6989 100644
--- a/drivers/usb/input/xpad.c
+++ b/drivers/usb/input/xpad.c
@@ -74,7 +74,6 @@
74#include <linux/stat.h> 74#include <linux/stat.h>
75#include <linux/module.h> 75#include <linux/module.h>
76#include <linux/moduleparam.h> 76#include <linux/moduleparam.h>
77#include <linux/smp_lock.h>
78#include <linux/usb/input.h> 77#include <linux/usb/input.h>
79 78
80#define DRIVER_VERSION "v0.0.6" 79#define DRIVER_VERSION "v0.0.6"
diff --git a/drivers/usb/misc/idmouse.c b/drivers/usb/misc/idmouse.c
index 15c70bd048c4..8d0e360636e6 100644
--- a/drivers/usb/misc/idmouse.c
+++ b/drivers/usb/misc/idmouse.c
@@ -22,7 +22,6 @@
22#include <linux/init.h> 22#include <linux/init.h>
23#include <linux/slab.h> 23#include <linux/slab.h>
24#include <linux/module.h> 24#include <linux/module.h>
25#include <linux/smp_lock.h>
26#include <linux/completion.h> 25#include <linux/completion.h>
27#include <linux/mutex.h> 26#include <linux/mutex.h>
28#include <asm/uaccess.h> 27#include <asm/uaccess.h>
diff --git a/drivers/usb/misc/legousbtower.c b/drivers/usb/misc/legousbtower.c
index 5dce797bddb7..1713e19a7899 100644
--- a/drivers/usb/misc/legousbtower.c
+++ b/drivers/usb/misc/legousbtower.c
@@ -80,7 +80,6 @@
80#include <linux/init.h> 80#include <linux/init.h>
81#include <linux/slab.h> 81#include <linux/slab.h>
82#include <linux/module.h> 82#include <linux/module.h>
83#include <linux/smp_lock.h>
84#include <linux/completion.h> 83#include <linux/completion.h>
85#include <linux/mutex.h> 84#include <linux/mutex.h>
86#include <asm/uaccess.h> 85#include <asm/uaccess.h>
diff --git a/drivers/usb/misc/rio500.c b/drivers/usb/misc/rio500.c
index fdf68479a166..88f6abe73624 100644
--- a/drivers/usb/misc/rio500.c
+++ b/drivers/usb/misc/rio500.c
@@ -39,7 +39,6 @@
39#include <linux/slab.h> 39#include <linux/slab.h>
40#include <linux/spinlock.h> 40#include <linux/spinlock.h>
41#include <linux/usb.h> 41#include <linux/usb.h>
42#include <linux/smp_lock.h>
43#include <linux/wait.h> 42#include <linux/wait.h>
44 43
45#include "rio500_usb.h" 44#include "rio500_usb.h"
diff --git a/drivers/usb/misc/sisusbvga/sisusb_con.c b/drivers/usb/misc/sisusbvga/sisusb_con.c
index 1730d8642a47..5947afb0017e 100644
--- a/drivers/usb/misc/sisusbvga/sisusb_con.c
+++ b/drivers/usb/misc/sisusbvga/sisusb_con.c
@@ -62,7 +62,6 @@
62#include <linux/selection.h> 62#include <linux/selection.h>
63#include <linux/spinlock.h> 63#include <linux/spinlock.h>
64#include <linux/kref.h> 64#include <linux/kref.h>
65#include <linux/smp_lock.h>
66#include <linux/ioport.h> 65#include <linux/ioport.h>
67#include <linux/interrupt.h> 66#include <linux/interrupt.h>
68#include <linux/vmalloc.h> 67#include <linux/vmalloc.h>
@@ -322,7 +321,7 @@ sisusbcon_deinit(struct vc_data *c)
322/* interface routine */ 321/* interface routine */
323static u8 322static u8
324sisusbcon_build_attr(struct vc_data *c, u8 color, u8 intensity, 323sisusbcon_build_attr(struct vc_data *c, u8 color, u8 intensity,
325 u8 blink, u8 underline, u8 reverse) 324 u8 blink, u8 underline, u8 reverse, u8 unused)
326{ 325{
327 u8 attr = color; 326 u8 attr = color;
328 327
diff --git a/drivers/usb/mon/mon_main.c b/drivers/usb/mon/mon_main.c
index 8a1df2c9c73e..8977ec0d0f99 100644
--- a/drivers/usb/mon/mon_main.c
+++ b/drivers/usb/mon/mon_main.c
@@ -9,7 +9,6 @@
9#include <linux/kernel.h> 9#include <linux/kernel.h>
10#include <linux/module.h> 10#include <linux/module.h>
11#include <linux/usb.h> 11#include <linux/usb.h>
12#include <linux/smp_lock.h>
13#include <linux/notifier.h> 12#include <linux/notifier.h>
14#include <linux/mutex.h> 13#include <linux/mutex.h>
15 14
diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c
index 7639022cdf84..87f378806db6 100644
--- a/drivers/usb/serial/usb-serial.c
+++ b/drivers/usb/serial/usb-serial.c
@@ -28,7 +28,6 @@
28#include <linux/spinlock.h> 28#include <linux/spinlock.h>
29#include <linux/mutex.h> 29#include <linux/mutex.h>
30#include <linux/list.h> 30#include <linux/list.h>
31#include <linux/smp_lock.h>
32#include <asm/uaccess.h> 31#include <asm/uaccess.h>
33#include <linux/usb.h> 32#include <linux/usb.h>
34#include <linux/usb/serial.h> 33#include <linux/usb/serial.h>
diff --git a/drivers/usb/storage/usb.h b/drivers/usb/storage/usb.h
index 21f3ddbc9080..6dac1ffdde86 100644
--- a/drivers/usb/storage/usb.h
+++ b/drivers/usb/storage/usb.h
@@ -47,7 +47,6 @@
47#include <linux/usb.h> 47#include <linux/usb.h>
48#include <linux/usb_usual.h> 48#include <linux/usb_usual.h>
49#include <linux/blkdev.h> 49#include <linux/blkdev.h>
50#include <linux/smp_lock.h>
51#include <linux/completion.h> 50#include <linux/completion.h>
52#include <linux/mutex.h> 51#include <linux/mutex.h>
53#include <scsi/scsi_host.h> 52#include <scsi/scsi_host.h>
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index 344c37595305..1132ba5ff391 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -5,6 +5,11 @@
5menu "Graphics support" 5menu "Graphics support"
6 6
7source "drivers/video/backlight/Kconfig" 7source "drivers/video/backlight/Kconfig"
8source "drivers/video/display/Kconfig"
9
10config VGASTATE
11 tristate
12 default n
8 13
9config FB 14config FB
10 tristate "Support for frame buffer devices" 15 tristate "Support for frame buffer devices"
@@ -90,6 +95,43 @@ config FB_CFB_IMAGEBLIT
90 blitting. This is used by drivers that don't provide their own 95 blitting. This is used by drivers that don't provide their own
91 (accelerated) version. 96 (accelerated) version.
92 97
98config FB_SYS_FILLRECT
99 tristate
100 depends on FB
101 default n
102 ---help---
103 Include the sys_fillrect function for generic software rectangle
104 filling. This is used by drivers that don't provide their own
105 (accelerated) version and the framebuffer is in system RAM.
106
107config FB_SYS_COPYAREA
108 tristate
109 depends on FB
110 default n
111 ---help---
112 Include the sys_copyarea function for generic software area copying.
113 This is used by drivers that don't provide their own (accelerated)
114 version and the framebuffer is in system RAM.
115
116config FB_SYS_IMAGEBLIT
117 tristate
118 depends on FB
119 default n
120 ---help---
121 Include the sys_imageblit function for generic software image
122 blitting. This is used by drivers that don't provide their own
123 (accelerated) version and the framebuffer is in system RAM.
124
125config FB_SYS_FOPS
126 tristate
127 depends on FB
128 default n
129
130config FB_DEFERRED_IO
131 bool
132 depends on FB
133 default y
134
93config FB_SVGALIB 135config FB_SVGALIB
94 tristate 136 tristate
95 depends on FB 137 depends on FB
@@ -375,9 +417,10 @@ config FB_FM2
375config FB_ARC 417config FB_ARC
376 tristate "Arc Monochrome LCD board support" 418 tristate "Arc Monochrome LCD board support"
377 depends on FB && X86 419 depends on FB && X86
378 select FB_CFB_FILLRECT 420 select FB_SYS_FILLRECT
379 select FB_CFB_COPYAREA 421 select FB_SYS_COPYAREA
380 select FB_CFB_IMAGEBLIT 422 select FB_SYS_IMAGEBLIT
423 select FB_SYS_FOPS
381 help 424 help
382 This enables support for the Arc Monochrome LCD board. The board 425 This enables support for the Arc Monochrome LCD board. The board
383 is based on the KS-108 lcd controller and is typically a matrix 426 is based on the KS-108 lcd controller and is typically a matrix
@@ -475,6 +518,8 @@ config FB_VGA16
475 select FB_CFB_FILLRECT 518 select FB_CFB_FILLRECT
476 select FB_CFB_COPYAREA 519 select FB_CFB_COPYAREA
477 select FB_CFB_IMAGEBLIT 520 select FB_CFB_IMAGEBLIT
521 select VGASTATE
522 select FONT_8x16 if FRAMEBUFFER_CONSOLE
478 help 523 help
479 This is the frame buffer device driver for VGA 16 color graphic 524 This is the frame buffer device driver for VGA 16 color graphic
480 cards. Say Y if you have such a card. 525 cards. Say Y if you have such a card.
@@ -519,15 +564,25 @@ config FB_HP300
519 default y 564 default y
520 565
521config FB_TGA 566config FB_TGA
522 tristate "TGA framebuffer support" 567 tristate "TGA/SFB+ framebuffer support"
523 depends on FB && ALPHA 568 depends on FB && (ALPHA || TC)
524 select FB_CFB_FILLRECT 569 select FB_CFB_FILLRECT
525 select FB_CFB_COPYAREA 570 select FB_CFB_COPYAREA
526 select FB_CFB_IMAGEBLIT 571 select FB_CFB_IMAGEBLIT
527 select BITREVERSE 572 select BITREVERSE
528 help 573 ---help---
529 This is the frame buffer device driver for generic TGA graphic 574 This is the frame buffer device driver for generic TGA and SFB+
530 cards. Say Y if you have one of those. 575 graphic cards. These include DEC ZLXp-E1, -E2 and -E3 PCI cards,
576 also known as PBXGA-A, -B and -C, and DEC ZLX-E1, -E2 and -E3
577 TURBOchannel cards, also known as PMAGD-A, -B and -C.
578
579 Due to hardware limitations ZLX-E2 and E3 cards are not supported
580 for DECstation 5000/200 systems. Additionally due to firmware
581 limitations these cards may cause troubles with booting DECstation
582 5000/240 and /260 systems, but are fully supported under Linux if
583 you manage to get it going. ;-)
584
585 Say Y if you have one of those.
531 586
532config FB_VESA 587config FB_VESA
533 bool "VESA VGA graphics support" 588 bool "VESA VGA graphics support"
@@ -551,6 +606,21 @@ config FB_IMAC
551 help 606 help
552 This is the frame buffer device driver for the Intel-based Macintosh 607 This is the frame buffer device driver for the Intel-based Macintosh
553 608
609config FB_HECUBA
610 tristate "Hecuba board support"
611 depends on FB && X86 && MMU
612 select FB_SYS_FILLRECT
613 select FB_SYS_COPYAREA
614 select FB_SYS_IMAGEBLIT
615 select FB_SYS_FOPS
616 select FB_DEFERRED_IO
617 help
618 This enables support for the Hecuba board. This driver was tested
619 with an E-Ink 800x600 display and x86 SBCs through a 16 bit GPIO
620 interface (8 bit data, 4 bit control). If you anticpate using
621 this driver, say Y or M; otherwise say N. You must specify the
622 GPIO IO address to be used for setting control and data.
623
554config FB_HGA 624config FB_HGA
555 tristate "Hercules mono graphics support" 625 tristate "Hercules mono graphics support"
556 depends on FB && X86 626 depends on FB && X86
@@ -686,6 +756,7 @@ config FB_NVIDIA
686 select FB_CFB_COPYAREA 756 select FB_CFB_COPYAREA
687 select FB_CFB_IMAGEBLIT 757 select FB_CFB_IMAGEBLIT
688 select BITREVERSE 758 select BITREVERSE
759 select VGASTATE
689 help 760 help
690 This driver supports graphics boards with the nVidia chips, TNT 761 This driver supports graphics boards with the nVidia chips, TNT
691 and newer. For very old chipsets, such as the RIVA128, then use 762 and newer. For very old chipsets, such as the RIVA128, then use
@@ -724,6 +795,7 @@ config FB_RIVA
724 select FB_CFB_COPYAREA 795 select FB_CFB_COPYAREA
725 select FB_CFB_IMAGEBLIT 796 select FB_CFB_IMAGEBLIT
726 select BITREVERSE 797 select BITREVERSE
798 select VGASTATE
727 help 799 help
728 This driver supports graphics boards with the nVidia Riva/Geforce 800 This driver supports graphics boards with the nVidia Riva/Geforce
729 chips. 801 chips.
@@ -770,6 +842,7 @@ config FB_I810
770 select FB_CFB_FILLRECT 842 select FB_CFB_FILLRECT
771 select FB_CFB_COPYAREA 843 select FB_CFB_COPYAREA
772 select FB_CFB_IMAGEBLIT 844 select FB_CFB_IMAGEBLIT
845 select VGASTATE
773 help 846 help
774 This driver supports the on-board graphics built in to the Intel 810 847 This driver supports the on-board graphics built in to the Intel 810
775 and 815 chipsets. Say Y if you have and plan to use such a board. 848 and 815 chipsets. Say Y if you have and plan to use such a board.
@@ -809,6 +882,22 @@ config FB_I810_I2C
809 select FB_DDC 882 select FB_DDC
810 help 883 help
811 884
885config FB_LE80578
886 tristate "Intel LE80578 (Vermilion) support"
887 depends on FB && PCI && X86
888 select FB_MODE_HELPERS
889 select FB_CFB_FILLRECT
890 select FB_CFB_COPYAREA
891 select FB_CFB_IMAGEBLIT
892 help
893 This driver supports the LE80578 (Vermilion Range) chipset
894
895config FB_CARILLO_RANCH
896 tristate "Intel Carillo Ranch support"
897 depends on FB_LE80578 && FB && PCI && X86
898 help
899 This driver supports the LE80578 (Carillo Ranch) board
900
812config FB_INTEL 901config FB_INTEL
813 tristate "Intel 830M/845G/852GM/855GM/865G/915G/945G support (EXPERIMENTAL)" 902 tristate "Intel 830M/845G/852GM/855GM/865G/915G/945G support (EXPERIMENTAL)"
814 depends on FB && EXPERIMENTAL && PCI && X86 903 depends on FB && EXPERIMENTAL && PCI && X86
@@ -1120,6 +1209,8 @@ config FB_S3
1120 select FB_CFB_IMAGEBLIT 1209 select FB_CFB_IMAGEBLIT
1121 select FB_TILEBLITTING 1210 select FB_TILEBLITTING
1122 select FB_SVGALIB 1211 select FB_SVGALIB
1212 select VGASTATE
1213 select FONT_8x16 if FRAMEBUFFER_CONSOLE
1123 ---help--- 1214 ---help---
1124 Driver for graphics boards with S3 Trio / S3 Virge chip. 1215 Driver for graphics boards with S3 Trio / S3 Virge chip.
1125 1216
@@ -1130,6 +1221,7 @@ config FB_SAVAGE
1130 select FB_CFB_FILLRECT 1221 select FB_CFB_FILLRECT
1131 select FB_CFB_COPYAREA 1222 select FB_CFB_COPYAREA
1132 select FB_CFB_IMAGEBLIT 1223 select FB_CFB_IMAGEBLIT
1224 select VGASTATE
1133 help 1225 help
1134 This driver supports notebooks and computers with S3 Savage PCI/AGP 1226 This driver supports notebooks and computers with S3 Savage PCI/AGP
1135 chips. 1227 chips.
@@ -1196,6 +1288,7 @@ config FB_NEOMAGIC
1196 select FB_CFB_FILLRECT 1288 select FB_CFB_FILLRECT
1197 select FB_CFB_COPYAREA 1289 select FB_CFB_COPYAREA
1198 select FB_CFB_IMAGEBLIT 1290 select FB_CFB_IMAGEBLIT
1291 select VGASTATE
1199 help 1292 help
1200 This driver supports notebooks with NeoMagic PCI chips. 1293 This driver supports notebooks with NeoMagic PCI chips.
1201 Say Y if you have such a graphics card. 1294 Say Y if you have such a graphics card.
@@ -1662,13 +1755,25 @@ config FB_PS3_DEFAULT_SIZE_M
1662 The default value can be overridden on the kernel command line 1755 The default value can be overridden on the kernel command line
1663 using the "ps3fb" option (e.g. "ps3fb=9M"); 1756 using the "ps3fb" option (e.g. "ps3fb=9M");
1664 1757
1665config FB_VIRTUAL 1758config FB_XILINX
1666 tristate "Virtual Frame Buffer support (ONLY FOR TESTING!)" 1759 tristate "Xilinx frame buffer support"
1667 depends on FB 1760 depends on FB && XILINX_VIRTEX
1668 select FB_CFB_FILLRECT 1761 select FB_CFB_FILLRECT
1669 select FB_CFB_COPYAREA 1762 select FB_CFB_COPYAREA
1670 select FB_CFB_IMAGEBLIT 1763 select FB_CFB_IMAGEBLIT
1671 ---help--- 1764 ---help---
1765 Include support for the Xilinx ML300/ML403 reference design
1766 framebuffer. ML300 carries a 640*480 LCD display on the board,
1767 ML403 uses a standard DB15 VGA connector.
1768
1769config FB_VIRTUAL
1770 tristate "Virtual Frame Buffer support (ONLY FOR TESTING!)"
1771 depends on FB
1772 select FB_SYS_FILLRECT
1773 select FB_SYS_COPYAREA
1774 select FB_SYS_IMAGEBLIT
1775 select FB_SYS_FOPS
1776 ---help---
1672 This is a `virtual' frame buffer device. It operates on a chunk of 1777 This is a `virtual' frame buffer device. It operates on a chunk of
1673 unswappable kernel memory instead of on the memory of a graphics 1778 unswappable kernel memory instead of on the memory of a graphics
1674 board. This means you cannot see any output sent to this frame 1779 board. This means you cannot see any output sent to this frame
diff --git a/drivers/video/Makefile b/drivers/video/Makefile
index 558473d040d6..a916c204274f 100644
--- a/drivers/video/Makefile
+++ b/drivers/video/Makefile
@@ -4,6 +4,7 @@
4 4
5# Each configuration option enables a list of files. 5# Each configuration option enables a list of files.
6 6
7obj-$(CONFIG_VGASTATE) += vgastate.o
7obj-y += fb_notify.o 8obj-y += fb_notify.o
8obj-$(CONFIG_FB) += fb.o 9obj-$(CONFIG_FB) += fb.o
9fb-y := fbmem.o fbmon.o fbcmap.o fbsysfs.o \ 10fb-y := fbmem.o fbmon.o fbcmap.o fbsysfs.o \
@@ -12,14 +13,19 @@ fb-objs := $(fb-y)
12 13
13obj-$(CONFIG_VT) += console/ 14obj-$(CONFIG_VT) += console/
14obj-$(CONFIG_LOGO) += logo/ 15obj-$(CONFIG_LOGO) += logo/
15obj-y += backlight/ 16obj-y += backlight/ display/
16 17
17obj-$(CONFIG_FB_CFB_FILLRECT) += cfbfillrect.o 18obj-$(CONFIG_FB_CFB_FILLRECT) += cfbfillrect.o
18obj-$(CONFIG_FB_CFB_COPYAREA) += cfbcopyarea.o 19obj-$(CONFIG_FB_CFB_COPYAREA) += cfbcopyarea.o
19obj-$(CONFIG_FB_CFB_IMAGEBLIT) += cfbimgblt.o 20obj-$(CONFIG_FB_CFB_IMAGEBLIT) += cfbimgblt.o
21obj-$(CONFIG_FB_SYS_FILLRECT) += sysfillrect.o
22obj-$(CONFIG_FB_SYS_COPYAREA) += syscopyarea.o
23obj-$(CONFIG_FB_SYS_IMAGEBLIT) += sysimgblt.o
24obj-$(CONFIG_FB_SYS_FOPS) += fb_sys_fops.o
20obj-$(CONFIG_FB_SVGALIB) += svgalib.o 25obj-$(CONFIG_FB_SVGALIB) += svgalib.o
21obj-$(CONFIG_FB_MACMODES) += macmodes.o 26obj-$(CONFIG_FB_MACMODES) += macmodes.o
22obj-$(CONFIG_FB_DDC) += fb_ddc.o 27obj-$(CONFIG_FB_DDC) += fb_ddc.o
28obj-$(CONFIG_FB_DEFERRED_IO) += fb_defio.o
23 29
24# Hardware specific drivers go first 30# Hardware specific drivers go first
25obj-$(CONFIG_FB_AMIGA) += amifb.o c2p.o 31obj-$(CONFIG_FB_AMIGA) += amifb.o c2p.o
@@ -30,7 +36,7 @@ obj-$(CONFIG_FB_PM2) += pm2fb.o
30obj-$(CONFIG_FB_PM3) += pm3fb.o 36obj-$(CONFIG_FB_PM3) += pm3fb.o
31 37
32obj-$(CONFIG_FB_MATROX) += matrox/ 38obj-$(CONFIG_FB_MATROX) += matrox/
33obj-$(CONFIG_FB_RIVA) += riva/ vgastate.o 39obj-$(CONFIG_FB_RIVA) += riva/
34obj-$(CONFIG_FB_NVIDIA) += nvidia/ 40obj-$(CONFIG_FB_NVIDIA) += nvidia/
35obj-$(CONFIG_FB_ATY) += aty/ macmodes.o 41obj-$(CONFIG_FB_ATY) += aty/ macmodes.o
36obj-$(CONFIG_FB_ATY128) += aty/ macmodes.o 42obj-$(CONFIG_FB_ATY128) += aty/ macmodes.o
@@ -40,8 +46,7 @@ obj-$(CONFIG_FB_KYRO) += kyro/
40obj-$(CONFIG_FB_SAVAGE) += savage/ 46obj-$(CONFIG_FB_SAVAGE) += savage/
41obj-$(CONFIG_FB_GEODE) += geode/ 47obj-$(CONFIG_FB_GEODE) += geode/
42obj-$(CONFIG_FB_MBX) += mbx/ 48obj-$(CONFIG_FB_MBX) += mbx/
43obj-$(CONFIG_FB_I810) += vgastate.o 49obj-$(CONFIG_FB_NEOMAGIC) += neofb.o
44obj-$(CONFIG_FB_NEOMAGIC) += neofb.o vgastate.o
45obj-$(CONFIG_FB_3DFX) += tdfxfb.o 50obj-$(CONFIG_FB_3DFX) += tdfxfb.o
46obj-$(CONFIG_FB_CONTROL) += controlfb.o 51obj-$(CONFIG_FB_CONTROL) += controlfb.o
47obj-$(CONFIG_FB_PLATINUM) += platinumfb.o 52obj-$(CONFIG_FB_PLATINUM) += platinumfb.o
@@ -51,7 +56,8 @@ obj-$(CONFIG_FB_IMSTT) += imsttfb.o
51obj-$(CONFIG_FB_FM2) += fm2fb.o 56obj-$(CONFIG_FB_FM2) += fm2fb.o
52obj-$(CONFIG_FB_CYBLA) += cyblafb.o 57obj-$(CONFIG_FB_CYBLA) += cyblafb.o
53obj-$(CONFIG_FB_TRIDENT) += tridentfb.o 58obj-$(CONFIG_FB_TRIDENT) += tridentfb.o
54obj-$(CONFIG_FB_S3) += s3fb.o vgastate.o 59obj-$(CONFIG_FB_LE80578) += vermilion/
60obj-$(CONFIG_FB_S3) += s3fb.o
55obj-$(CONFIG_FB_STI) += stifb.o 61obj-$(CONFIG_FB_STI) += stifb.o
56obj-$(CONFIG_FB_FFB) += ffb.o sbuslib.o 62obj-$(CONFIG_FB_FFB) += ffb.o sbuslib.o
57obj-$(CONFIG_FB_CG6) += cg6.o sbuslib.o 63obj-$(CONFIG_FB_CG6) += cg6.o sbuslib.o
@@ -66,6 +72,7 @@ obj-$(CONFIG_FB_ACORN) += acornfb.o
66obj-$(CONFIG_FB_ATARI) += atafb.o c2p.o atafb_mfb.o \ 72obj-$(CONFIG_FB_ATARI) += atafb.o c2p.o atafb_mfb.o \
67 atafb_iplan2p2.o atafb_iplan2p4.o atafb_iplan2p8.o 73 atafb_iplan2p2.o atafb_iplan2p4.o atafb_iplan2p8.o
68obj-$(CONFIG_FB_MAC) += macfb.o 74obj-$(CONFIG_FB_MAC) += macfb.o
75obj-$(CONFIG_FB_HECUBA) += hecubafb.o
69obj-$(CONFIG_FB_HGA) += hgafb.o 76obj-$(CONFIG_FB_HGA) += hgafb.o
70obj-$(CONFIG_FB_XVR500) += sunxvr500.o 77obj-$(CONFIG_FB_XVR500) += sunxvr500.o
71obj-$(CONFIG_FB_XVR2500) += sunxvr2500.o 78obj-$(CONFIG_FB_XVR2500) += sunxvr2500.o
@@ -102,11 +109,12 @@ obj-$(CONFIG_FB_PNX4008_DUM_RGB) += pnx4008/
102obj-$(CONFIG_FB_IBM_GXT4500) += gxt4500.o 109obj-$(CONFIG_FB_IBM_GXT4500) += gxt4500.o
103obj-$(CONFIG_FB_PS3) += ps3fb.o 110obj-$(CONFIG_FB_PS3) += ps3fb.o
104obj-$(CONFIG_FB_SM501) += sm501fb.o 111obj-$(CONFIG_FB_SM501) += sm501fb.o
112obj-$(CONFIG_FB_XILINX) += xilinxfb.o
105 113
106# Platform or fallback drivers go here 114# Platform or fallback drivers go here
107obj-$(CONFIG_FB_VESA) += vesafb.o 115obj-$(CONFIG_FB_VESA) += vesafb.o
108obj-$(CONFIG_FB_IMAC) += imacfb.o 116obj-$(CONFIG_FB_IMAC) += imacfb.o
109obj-$(CONFIG_FB_VGA16) += vga16fb.o vgastate.o 117obj-$(CONFIG_FB_VGA16) += vga16fb.o
110obj-$(CONFIG_FB_OF) += offb.o 118obj-$(CONFIG_FB_OF) += offb.o
111 119
112# the test framebuffer is last 120# the test framebuffer is last
diff --git a/drivers/video/arcfb.c b/drivers/video/arcfb.c
index 30a8369757e7..db15baca3f7b 100644
--- a/drivers/video/arcfb.c
+++ b/drivers/video/arcfb.c
@@ -262,7 +262,8 @@ static void arcfb_lcd_update_page(struct arcfb_par *par, unsigned int upper,
262 ks108_set_yaddr(par, chipindex, upper/8); 262 ks108_set_yaddr(par, chipindex, upper/8);
263 263
264 linesize = par->info->var.xres/8; 264 linesize = par->info->var.xres/8;
265 src = par->info->screen_base + (left/8) + (upper * linesize); 265 src = (unsigned char __force *) par->info->screen_base + (left/8) +
266 (upper * linesize);
266 ks108_set_xaddr(par, chipindex, left); 267 ks108_set_xaddr(par, chipindex, left);
267 268
268 bitmask=1; 269 bitmask=1;
@@ -368,7 +369,7 @@ static void arcfb_fillrect(struct fb_info *info,
368{ 369{
369 struct arcfb_par *par = info->par; 370 struct arcfb_par *par = info->par;
370 371
371 cfb_fillrect(info, rect); 372 sys_fillrect(info, rect);
372 373
373 /* update the physical lcd */ 374 /* update the physical lcd */
374 arcfb_lcd_update(par, rect->dx, rect->dy, rect->width, rect->height); 375 arcfb_lcd_update(par, rect->dx, rect->dy, rect->width, rect->height);
@@ -379,7 +380,7 @@ static void arcfb_copyarea(struct fb_info *info,
379{ 380{
380 struct arcfb_par *par = info->par; 381 struct arcfb_par *par = info->par;
381 382
382 cfb_copyarea(info, area); 383 sys_copyarea(info, area);
383 384
384 /* update the physical lcd */ 385 /* update the physical lcd */
385 arcfb_lcd_update(par, area->dx, area->dy, area->width, area->height); 386 arcfb_lcd_update(par, area->dx, area->dy, area->width, area->height);
@@ -389,7 +390,7 @@ static void arcfb_imageblit(struct fb_info *info, const struct fb_image *image)
389{ 390{
390 struct arcfb_par *par = info->par; 391 struct arcfb_par *par = info->par;
391 392
392 cfb_imageblit(info, image); 393 sys_imageblit(info, image);
393 394
394 /* update the physical lcd */ 395 /* update the physical lcd */
395 arcfb_lcd_update(par, image->dx, image->dy, image->width, 396 arcfb_lcd_update(par, image->dx, image->dy, image->width,
@@ -439,14 +440,11 @@ static int arcfb_ioctl(struct fb_info *info,
439 * the fb. it's inefficient for them to do anything less than 64*8 440 * the fb. it's inefficient for them to do anything less than 64*8
440 * writes since we update the lcd in each write() anyway. 441 * writes since we update the lcd in each write() anyway.
441 */ 442 */
442static ssize_t arcfb_write(struct file *file, const char __user *buf, size_t count, 443static ssize_t arcfb_write(struct fb_info *info, const char __user *buf,
443 loff_t *ppos) 444 size_t count, loff_t *ppos)
444{ 445{
445 /* modded from epson 1355 */ 446 /* modded from epson 1355 */
446 447
447 struct inode *inode;
448 int fbidx;
449 struct fb_info *info;
450 unsigned long p; 448 unsigned long p;
451 int err=-EINVAL; 449 int err=-EINVAL;
452 unsigned int fbmemlength,x,y,w,h, bitppos, startpos, endpos, bitcount; 450 unsigned int fbmemlength,x,y,w,h, bitppos, startpos, endpos, bitcount;
@@ -454,13 +452,6 @@ static ssize_t arcfb_write(struct file *file, const char __user *buf, size_t cou
454 unsigned int xres; 452 unsigned int xres;
455 453
456 p = *ppos; 454 p = *ppos;
457 inode = file->f_path.dentry->d_inode;
458 fbidx = iminor(inode);
459 info = registered_fb[fbidx];
460
461 if (!info || !info->screen_base)
462 return -ENODEV;
463
464 par = info->par; 455 par = info->par;
465 xres = info->var.xres; 456 xres = info->var.xres;
466 fbmemlength = (xres * info->var.yres)/8; 457 fbmemlength = (xres * info->var.yres)/8;
@@ -477,7 +468,7 @@ static ssize_t arcfb_write(struct file *file, const char __user *buf, size_t cou
477 if (count) { 468 if (count) {
478 char *base_addr; 469 char *base_addr;
479 470
480 base_addr = info->screen_base; 471 base_addr = (char __force *)info->screen_base;
481 count -= copy_from_user(base_addr + p, buf, count); 472 count -= copy_from_user(base_addr + p, buf, count);
482 *ppos += count; 473 *ppos += count;
483 err = -EFAULT; 474 err = -EFAULT;
@@ -503,6 +494,7 @@ static ssize_t arcfb_write(struct file *file, const char __user *buf, size_t cou
503static struct fb_ops arcfb_ops = { 494static struct fb_ops arcfb_ops = {
504 .owner = THIS_MODULE, 495 .owner = THIS_MODULE,
505 .fb_open = arcfb_open, 496 .fb_open = arcfb_open,
497 .fb_read = fb_sys_read,
506 .fb_write = arcfb_write, 498 .fb_write = arcfb_write,
507 .fb_release = arcfb_release, 499 .fb_release = arcfb_release,
508 .fb_pan_display = arcfb_pan_display, 500 .fb_pan_display = arcfb_pan_display,
@@ -603,7 +595,7 @@ static int arcfb_remove(struct platform_device *dev)
603 595
604 if (info) { 596 if (info) {
605 unregister_framebuffer(info); 597 unregister_framebuffer(info);
606 vfree(info->screen_base); 598 vfree((void __force *)info->screen_base);
607 framebuffer_release(info); 599 framebuffer_release(info);
608 } 600 }
609 return 0; 601 return 0;
diff --git a/drivers/video/aty/ati_ids.h b/drivers/video/aty/ati_ids.h
index 39ab483fc250..90e7df22f508 100644
--- a/drivers/video/aty/ati_ids.h
+++ b/drivers/video/aty/ati_ids.h
@@ -209,4 +209,4 @@
209#define PCI_CHIP_R423_5D57 0x5D57 209#define PCI_CHIP_R423_5D57 0x5D57
210#define PCI_CHIP_RS350_7834 0x7834 210#define PCI_CHIP_RS350_7834 0x7834
211#define PCI_CHIP_RS350_7835 0x7835 211#define PCI_CHIP_RS350_7835 0x7835
212 212#define PCI_CHIP_RS480_5955 0x5955
diff --git a/drivers/video/aty/aty128fb.c b/drivers/video/aty/aty128fb.c
index e86d7e0c9825..7fea4d8ae8e2 100644
--- a/drivers/video/aty/aty128fb.c
+++ b/drivers/video/aty/aty128fb.c
@@ -2165,18 +2165,29 @@ static void __devexit aty128_remove(struct pci_dev *pdev)
2165static int aty128fb_blank(int blank, struct fb_info *fb) 2165static int aty128fb_blank(int blank, struct fb_info *fb)
2166{ 2166{
2167 struct aty128fb_par *par = fb->par; 2167 struct aty128fb_par *par = fb->par;
2168 u8 state = 0; 2168 u8 state;
2169 2169
2170 if (par->lock_blank || par->asleep) 2170 if (par->lock_blank || par->asleep)
2171 return 0; 2171 return 0;
2172 2172
2173 if (blank & FB_BLANK_VSYNC_SUSPEND) 2173 switch (blank) {
2174 state |= 2; 2174 case FB_BLANK_NORMAL:
2175 if (blank & FB_BLANK_HSYNC_SUSPEND) 2175 state = 4;
2176 state |= 1; 2176 break;
2177 if (blank & FB_BLANK_POWERDOWN) 2177 case FB_BLANK_VSYNC_SUSPEND:
2178 state |= 4; 2178 state = 6;
2179 2179 break;
2180 case FB_BLANK_HSYNC_SUSPEND:
2181 state = 5;
2182 break;
2183 case FB_BLANK_POWERDOWN:
2184 state = 7;
2185 break;
2186 case FB_BLANK_UNBLANK:
2187 default:
2188 state = 0;
2189 break;
2190 }
2180 aty_st_8(CRTC_EXT_CNTL+1, state); 2191 aty_st_8(CRTC_EXT_CNTL+1, state);
2181 2192
2182 if (par->chip_gen == rage_M3) { 2193 if (par->chip_gen == rage_M3) {
@@ -2430,7 +2441,7 @@ static int aty128_pci_suspend(struct pci_dev *pdev, pm_message_t state)
2430 wait_for_idle(par); 2441 wait_for_idle(par);
2431 2442
2432 /* Blank display and LCD */ 2443 /* Blank display and LCD */
2433 aty128fb_blank(VESA_POWERDOWN, info); 2444 aty128fb_blank(FB_BLANK_POWERDOWN, info);
2434 2445
2435 /* Sleep */ 2446 /* Sleep */
2436 par->asleep = 1; 2447 par->asleep = 1;
diff --git a/drivers/video/aty/atyfb_base.c b/drivers/video/aty/atyfb_base.c
index 8514f2a6f060..ea67dd902d4e 100644
--- a/drivers/video/aty/atyfb_base.c
+++ b/drivers/video/aty/atyfb_base.c
@@ -2297,20 +2297,6 @@ static int __devinit aty_init(struct fb_info *info)
2297 par->pll_limits.xclk = 53; 2297 par->pll_limits.xclk = 53;
2298 } 2298 }
2299#endif 2299#endif
2300 if (pll)
2301 par->pll_limits.pll_max = pll;
2302 if (mclk)
2303 par->pll_limits.mclk = mclk;
2304 if (xclk)
2305 par->pll_limits.xclk = xclk;
2306
2307 aty_calc_mem_refresh(par, par->pll_limits.xclk);
2308 par->pll_per = 1000000/par->pll_limits.pll_max;
2309 par->mclk_per = 1000000/par->pll_limits.mclk;
2310 par->xclk_per = 1000000/par->pll_limits.xclk;
2311
2312 par->ref_clk_per = 1000000000000ULL / 14318180;
2313 xtal = "14.31818";
2314 2300
2315#ifdef CONFIG_FB_ATY_GX 2301#ifdef CONFIG_FB_ATY_GX
2316 if (!M64_HAS(INTEGRATED)) { 2302 if (!M64_HAS(INTEGRATED)) {
@@ -2338,6 +2324,7 @@ static int __devinit aty_init(struct fb_info *info)
2338 case DAC_IBMRGB514: 2324 case DAC_IBMRGB514:
2339 par->dac_ops = &aty_dac_ibm514; 2325 par->dac_ops = &aty_dac_ibm514;
2340 break; 2326 break;
2327#ifdef CONFIG_ATARI
2341 case DAC_ATI68860_B: 2328 case DAC_ATI68860_B:
2342 case DAC_ATI68860_C: 2329 case DAC_ATI68860_C:
2343 par->dac_ops = &aty_dac_ati68860b; 2330 par->dac_ops = &aty_dac_ati68860b;
@@ -2346,6 +2333,7 @@ static int __devinit aty_init(struct fb_info *info)
2346 case DAC_ATT21C498: 2333 case DAC_ATT21C498:
2347 par->dac_ops = &aty_dac_att21c498; 2334 par->dac_ops = &aty_dac_att21c498;
2348 break; 2335 break;
2336#endif
2349 default: 2337 default:
2350 PRINTKI("aty_init: DAC type not implemented yet!\n"); 2338 PRINTKI("aty_init: DAC type not implemented yet!\n");
2351 par->dac_ops = &aty_dac_unsupported; 2339 par->dac_ops = &aty_dac_unsupported;
@@ -2389,8 +2377,29 @@ static int __devinit aty_init(struct fb_info *info)
2389 /* for many chips, the mclk is 67 MHz for SDRAM, 63 MHz otherwise */ 2377 /* for many chips, the mclk is 67 MHz for SDRAM, 63 MHz otherwise */
2390 if (par->pll_limits.mclk == 67 && par->ram_type < SDRAM) 2378 if (par->pll_limits.mclk == 67 && par->ram_type < SDRAM)
2391 par->pll_limits.mclk = 63; 2379 par->pll_limits.mclk = 63;
2380 /* Mobility + 32bit memory interface need halved XCLK. */
2381 if (M64_HAS(MOBIL_BUS) && par->ram_type == SDRAM32)
2382 par->pll_limits.xclk = (par->pll_limits.xclk + 1) >> 1;
2392 } 2383 }
2384#endif
2393 2385
2386 /* Allow command line to override clocks. */
2387 if (pll)
2388 par->pll_limits.pll_max = pll;
2389 if (mclk)
2390 par->pll_limits.mclk = mclk;
2391 if (xclk)
2392 par->pll_limits.xclk = xclk;
2393
2394 aty_calc_mem_refresh(par, par->pll_limits.xclk);
2395 par->pll_per = 1000000/par->pll_limits.pll_max;
2396 par->mclk_per = 1000000/par->pll_limits.mclk;
2397 par->xclk_per = 1000000/par->pll_limits.xclk;
2398
2399 par->ref_clk_per = 1000000000000ULL / 14318180;
2400 xtal = "14.31818";
2401
2402#ifdef CONFIG_FB_ATY_CT
2394 if (M64_HAS(GTB_DSP)) { 2403 if (M64_HAS(GTB_DSP)) {
2395 u8 pll_ref_div = aty_ld_pll_ct(PLL_REF_DIV, par); 2404 u8 pll_ref_div = aty_ld_pll_ct(PLL_REF_DIV, par);
2396 2405
diff --git a/drivers/video/aty/mach64_ct.c b/drivers/video/aty/mach64_ct.c
index 1fdcfdbf669b..cc9e9779b75f 100644
--- a/drivers/video/aty/mach64_ct.c
+++ b/drivers/video/aty/mach64_ct.c
@@ -608,12 +608,10 @@ static void aty_resume_pll_ct(const struct fb_info *info,
608 aty_st_pll_ct(SCLK_FB_DIV, pll->ct.sclk_fb_div, par); 608 aty_st_pll_ct(SCLK_FB_DIV, pll->ct.sclk_fb_div, par);
609 aty_st_pll_ct(SPLL_CNTL2, pll->ct.spll_cntl2, par); 609 aty_st_pll_ct(SPLL_CNTL2, pll->ct.spll_cntl2, par);
610 /* 610 /*
611 * The sclk has been started. However, I believe the first clock 611 * SCLK has been started. Wait for the PLL to lock. 5 ms
612 * ticks it generates are not very stable. Hope this primitive loop 612 * should be enough according to mach64 programmer's guide.
613 * helps for Rage Mobilities that sometimes crash when
614 * we switch to sclk. (Daniel Mantione, 13-05-2003)
615 */ 613 */
616 udelay(500); 614 mdelay(5);
617 } 615 }
618 616
619 aty_st_pll_ct(PLL_REF_DIV, pll->ct.pll_ref_div, par); 617 aty_st_pll_ct(PLL_REF_DIV, pll->ct.pll_ref_div, par);
diff --git a/drivers/video/aty/radeon_base.c b/drivers/video/aty/radeon_base.c
index 9d629fe1709d..2ce050193018 100644
--- a/drivers/video/aty/radeon_base.c
+++ b/drivers/video/aty/radeon_base.c
@@ -100,6 +100,8 @@
100 { PCI_VENDOR_ID_ATI, id, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (flags) | (CHIP_FAMILY_##family) } 100 { PCI_VENDOR_ID_ATI, id, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (flags) | (CHIP_FAMILY_##family) }
101 101
102static struct pci_device_id radeonfb_pci_table[] = { 102static struct pci_device_id radeonfb_pci_table[] = {
103 /* Radeon Xpress 200m */
104 CHIP_DEF(PCI_CHIP_RS480_5955, RS480, CHIP_HAS_CRTC2 | CHIP_IS_IGP | CHIP_IS_MOBILITY),
103 /* Mobility M6 */ 105 /* Mobility M6 */
104 CHIP_DEF(PCI_CHIP_RADEON_LY, RV100, CHIP_HAS_CRTC2 | CHIP_IS_MOBILITY), 106 CHIP_DEF(PCI_CHIP_RADEON_LY, RV100, CHIP_HAS_CRTC2 | CHIP_IS_MOBILITY),
105 CHIP_DEF(PCI_CHIP_RADEON_LZ, RV100, CHIP_HAS_CRTC2 | CHIP_IS_MOBILITY), 107 CHIP_DEF(PCI_CHIP_RADEON_LZ, RV100, CHIP_HAS_CRTC2 | CHIP_IS_MOBILITY),
@@ -1994,7 +1996,8 @@ static void radeon_identify_vram(struct radeonfb_info *rinfo)
1994 /* framebuffer size */ 1996 /* framebuffer size */
1995 if ((rinfo->family == CHIP_FAMILY_RS100) || 1997 if ((rinfo->family == CHIP_FAMILY_RS100) ||
1996 (rinfo->family == CHIP_FAMILY_RS200) || 1998 (rinfo->family == CHIP_FAMILY_RS200) ||
1997 (rinfo->family == CHIP_FAMILY_RS300)) { 1999 (rinfo->family == CHIP_FAMILY_RS300) ||
2000 (rinfo->family == CHIP_FAMILY_RS480) ) {
1998 u32 tom = INREG(NB_TOM); 2001 u32 tom = INREG(NB_TOM);
1999 tmp = ((((tom >> 16) - (tom & 0xffff) + 1) << 6) * 1024); 2002 tmp = ((((tom >> 16) - (tom & 0xffff) + 1) << 6) * 1024);
2000 2003
diff --git a/drivers/video/aty/radeon_pm.c b/drivers/video/aty/radeon_pm.c
index 1786ae188322..be1d57bf9dc8 100644
--- a/drivers/video/aty/radeon_pm.c
+++ b/drivers/video/aty/radeon_pm.c
@@ -2826,11 +2826,15 @@ void radeonfb_pm_init(struct radeonfb_info *rinfo, int dynclk, int ignore_devlis
2826 rinfo->pm_reg = pci_find_capability(rinfo->pdev, PCI_CAP_ID_PM); 2826 rinfo->pm_reg = pci_find_capability(rinfo->pdev, PCI_CAP_ID_PM);
2827 2827
2828 /* Enable/Disable dynamic clocks: TODO add sysfs access */ 2828 /* Enable/Disable dynamic clocks: TODO add sysfs access */
2829 rinfo->dynclk = dynclk; 2829 if (rinfo->family == CHIP_FAMILY_RS480)
2830 if (dynclk == 1) { 2830 rinfo->dynclk = -1;
2831 else
2832 rinfo->dynclk = dynclk;
2833
2834 if (rinfo->dynclk == 1) {
2831 radeon_pm_enable_dynamic_mode(rinfo); 2835 radeon_pm_enable_dynamic_mode(rinfo);
2832 printk("radeonfb: Dynamic Clock Power Management enabled\n"); 2836 printk("radeonfb: Dynamic Clock Power Management enabled\n");
2833 } else if (dynclk == 0) { 2837 } else if (rinfo->dynclk == 0) {
2834 radeon_pm_disable_dynamic_mode(rinfo); 2838 radeon_pm_disable_dynamic_mode(rinfo);
2835 printk("radeonfb: Dynamic Clock Power Management disabled\n"); 2839 printk("radeonfb: Dynamic Clock Power Management disabled\n");
2836 } 2840 }
diff --git a/drivers/video/aty/radeonfb.h b/drivers/video/aty/radeonfb.h
index 319000360285..7ebffcdfd1e3 100644
--- a/drivers/video/aty/radeonfb.h
+++ b/drivers/video/aty/radeonfb.h
@@ -48,6 +48,7 @@ enum radeon_family {
48 CHIP_FAMILY_RV350, 48 CHIP_FAMILY_RV350,
49 CHIP_FAMILY_RV380, /* RV370/RV380/M22/M24 */ 49 CHIP_FAMILY_RV380, /* RV370/RV380/M22/M24 */
50 CHIP_FAMILY_R420, /* R420/R423/M18 */ 50 CHIP_FAMILY_R420, /* R420/R423/M18 */
51 CHIP_FAMILY_RS480,
51 CHIP_FAMILY_LAST, 52 CHIP_FAMILY_LAST,
52}; 53};
53 54
@@ -64,7 +65,8 @@ enum radeon_family {
64 ((rinfo)->family == CHIP_FAMILY_RV350) || \ 65 ((rinfo)->family == CHIP_FAMILY_RV350) || \
65 ((rinfo)->family == CHIP_FAMILY_R350) || \ 66 ((rinfo)->family == CHIP_FAMILY_R350) || \
66 ((rinfo)->family == CHIP_FAMILY_RV380) || \ 67 ((rinfo)->family == CHIP_FAMILY_RV380) || \
67 ((rinfo)->family == CHIP_FAMILY_R420)) 68 ((rinfo)->family == CHIP_FAMILY_R420) || \
69 ((rinfo)->family == CHIP_FAMILY_RS480) )
68 70
69/* 71/*
70 * Chip flags 72 * Chip flags
diff --git a/drivers/video/backlight/Kconfig b/drivers/video/backlight/Kconfig
index 47d15b5d985a..fbef663fc057 100644
--- a/drivers/video/backlight/Kconfig
+++ b/drivers/video/backlight/Kconfig
@@ -63,3 +63,11 @@ config BACKLIGHT_PROGEAR
63 help 63 help
64 If you have a Frontpath ProGear say Y to enable the 64 If you have a Frontpath ProGear say Y to enable the
65 backlight driver. 65 backlight driver.
66
67config BACKLIGHT_CARILLO_RANCH
68 tristate "Intel Carillo Ranch Backlight Driver"
69 depends on BACKLIGHT_CLASS_DEVICE && LCD_CLASS_DEVICE && PCI && X86 && FB_LE80578
70 default n
71 help
72 If you have a Intel LE80578 (Carillo Ranch) say Y to enable the
73 backlight driver.
diff --git a/drivers/video/backlight/Makefile b/drivers/video/backlight/Makefile
index 0c3ce46f5094..c6e2266f63e2 100644
--- a/drivers/video/backlight/Makefile
+++ b/drivers/video/backlight/Makefile
@@ -6,3 +6,4 @@ obj-$(CONFIG_BACKLIGHT_CORGI) += corgi_bl.o
6obj-$(CONFIG_BACKLIGHT_HP680) += hp680_bl.o 6obj-$(CONFIG_BACKLIGHT_HP680) += hp680_bl.o
7obj-$(CONFIG_BACKLIGHT_LOCOMO) += locomolcd.o 7obj-$(CONFIG_BACKLIGHT_LOCOMO) += locomolcd.o
8obj-$(CONFIG_BACKLIGHT_PROGEAR) += progear_bl.o 8obj-$(CONFIG_BACKLIGHT_PROGEAR) += progear_bl.o
9obj-$(CONFIG_BACKLIGHT_CARILLO_RANCH) += cr_bllcd.o
diff --git a/drivers/video/backlight/cr_bllcd.c b/drivers/video/backlight/cr_bllcd.c
new file mode 100644
index 000000000000..e9bbc3455c94
--- /dev/null
+++ b/drivers/video/backlight/cr_bllcd.c
@@ -0,0 +1,287 @@
1/*
2 * Copyright (c) Intel Corp. 2007.
3 * All Rights Reserved.
4 *
5 * Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to
6 * develop this driver.
7 *
8 * This file is part of the Carillo Ranch video subsystem driver.
9 * The Carillo Ranch video subsystem driver is free software;
10 * you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * The Carillo Ranch video subsystem driver is distributed
16 * in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this driver; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
24 *
25 * Authors:
26 * Thomas Hellstrom <thomas-at-tungstengraphics-dot-com>
27 * Alan Hourihane <alanh-at-tungstengraphics-dot-com>
28 */
29
30#include <linux/module.h>
31#include <linux/kernel.h>
32#include <linux/init.h>
33#include <linux/platform_device.h>
34#include <linux/mutex.h>
35#include <linux/fb.h>
36#include <linux/backlight.h>
37#include <linux/lcd.h>
38#include <linux/pci.h>
39#include <asm/uaccess.h>
40
41/* The LVDS- and panel power controls sits on the
42 * GPIO port of the ISA bridge.
43 */
44
45#define CRVML_DEVICE_LPC 0x27B8
46#define CRVML_REG_GPIOBAR 0x48
47#define CRVML_REG_GPIOEN 0x4C
48#define CRVML_GPIOEN_BIT (1 << 4)
49#define CRVML_PANEL_PORT 0x38
50#define CRVML_LVDS_ON 0x00000001
51#define CRVML_PANEL_ON 0x00000002
52#define CRVML_BACKLIGHT_OFF 0x00000004
53
54/* The PLL Clock register sits on Host bridge */
55#define CRVML_DEVICE_MCH 0x5001
56#define CRVML_REG_MCHBAR 0x44
57#define CRVML_REG_MCHEN 0x54
58#define CRVML_MCHEN_BIT (1 << 28)
59#define CRVML_MCHMAP_SIZE 4096
60#define CRVML_REG_CLOCK 0xc3c
61#define CRVML_CLOCK_SHIFT 8
62#define CRVML_CLOCK_MASK 0x00000f00
63
64static struct pci_dev *lpc_dev;
65static u32 gpio_bar;
66
67struct cr_panel {
68 struct backlight_device *cr_backlight_device;
69 struct lcd_device *cr_lcd_device;
70};
71
72static int cr_backlight_set_intensity(struct backlight_device *bd)
73{
74 int intensity = bd->props.brightness;
75 u32 addr = gpio_bar + CRVML_PANEL_PORT;
76 u32 cur = inl(addr);
77
78 if (bd->props.power == FB_BLANK_UNBLANK)
79 intensity = FB_BLANK_UNBLANK;
80 if (bd->props.fb_blank == FB_BLANK_UNBLANK)
81 intensity = FB_BLANK_UNBLANK;
82 if (bd->props.power == FB_BLANK_POWERDOWN)
83 intensity = FB_BLANK_POWERDOWN;
84 if (bd->props.fb_blank == FB_BLANK_POWERDOWN)
85 intensity = FB_BLANK_POWERDOWN;
86
87 if (intensity == FB_BLANK_UNBLANK) { /* FULL ON */
88 cur &= ~CRVML_BACKLIGHT_OFF;
89 outl(cur, addr);
90 } else if (intensity == FB_BLANK_POWERDOWN) { /* OFF */
91 cur |= CRVML_BACKLIGHT_OFF;
92 outl(cur, addr);
93 } /* anything else, don't bother */
94
95 return 0;
96}
97
98static int cr_backlight_get_intensity(struct backlight_device *bd)
99{
100 u32 addr = gpio_bar + CRVML_PANEL_PORT;
101 u32 cur = inl(addr);
102 u8 intensity;
103
104 if (cur & CRVML_BACKLIGHT_OFF)
105 intensity = FB_BLANK_POWERDOWN;
106 else
107 intensity = FB_BLANK_UNBLANK;
108
109 return intensity;
110}
111
112static struct backlight_ops cr_backlight_ops = {
113 .get_brightness = cr_backlight_get_intensity,
114 .update_status = cr_backlight_set_intensity,
115};
116
117static void cr_panel_on(void)
118{
119 u32 addr = gpio_bar + CRVML_PANEL_PORT;
120 u32 cur = inl(addr);
121
122 if (!(cur & CRVML_PANEL_ON)) {
123 /* Make sure LVDS controller is down. */
124 if (cur & 0x00000001) {
125 cur &= ~CRVML_LVDS_ON;
126 outl(cur, addr);
127 }
128 /* Power up Panel */
129 schedule_timeout(HZ / 10);
130 cur |= CRVML_PANEL_ON;
131 outl(cur, addr);
132 }
133
134 /* Power up LVDS controller */
135
136 if (!(cur & CRVML_LVDS_ON)) {
137 schedule_timeout(HZ / 10);
138 outl(cur | CRVML_LVDS_ON, addr);
139 }
140}
141
142static void cr_panel_off(void)
143{
144 u32 addr = gpio_bar + CRVML_PANEL_PORT;
145 u32 cur = inl(addr);
146
147 /* Power down LVDS controller first to avoid high currents */
148 if (cur & CRVML_LVDS_ON) {
149 cur &= ~CRVML_LVDS_ON;
150 outl(cur, addr);
151 }
152 if (cur & CRVML_PANEL_ON) {
153 schedule_timeout(HZ / 10);
154 outl(cur & ~CRVML_PANEL_ON, addr);
155 }
156}
157
158static int cr_lcd_set_power(struct lcd_device *ld, int power)
159{
160 if (power == FB_BLANK_UNBLANK)
161 cr_panel_on();
162 if (power == FB_BLANK_POWERDOWN)
163 cr_panel_off();
164
165 return 0;
166}
167
168static struct lcd_ops cr_lcd_ops = {
169 .set_power = cr_lcd_set_power,
170};
171
172static int cr_backlight_probe(struct platform_device *pdev)
173{
174 struct cr_panel *crp;
175 u8 dev_en;
176
177 crp = kzalloc(sizeof(crp), GFP_KERNEL);
178 if (crp == NULL)
179 return -ENOMEM;
180
181 lpc_dev = pci_get_device(PCI_VENDOR_ID_INTEL,
182 CRVML_DEVICE_LPC, NULL);
183 if (!lpc_dev) {
184 printk("INTEL CARILLO RANCH LPC not found.\n");
185 return -ENODEV;
186 }
187
188 pci_read_config_byte(lpc_dev, CRVML_REG_GPIOEN, &dev_en);
189 if (!(dev_en & CRVML_GPIOEN_BIT)) {
190 printk(KERN_ERR
191 "Carillo Ranch GPIO device was not enabled.\n");
192 pci_dev_put(lpc_dev);
193 return -ENODEV;
194 }
195
196 crp->cr_backlight_device = backlight_device_register("cr-backlight",
197 &pdev->dev, NULL,
198 &cr_backlight_ops);
199 if (IS_ERR(crp->cr_backlight_device)) {
200 pci_dev_put(lpc_dev);
201 return PTR_ERR(crp->cr_backlight_device);
202 }
203
204 crp->cr_lcd_device = lcd_device_register("cr-lcd",
205 &pdev->dev,
206 &cr_lcd_ops);
207
208 if (IS_ERR(crp->cr_lcd_device)) {
209 pci_dev_put(lpc_dev);
210 return PTR_ERR(crp->cr_backlight_device);
211 }
212
213 pci_read_config_dword(lpc_dev, CRVML_REG_GPIOBAR,
214 &gpio_bar);
215 gpio_bar &= ~0x3F;
216
217 crp->cr_backlight_device->props.power = FB_BLANK_UNBLANK;
218 crp->cr_backlight_device->props.brightness = 0;
219 crp->cr_backlight_device->props.max_brightness = 0;
220 cr_backlight_set_intensity(crp->cr_backlight_device);
221
222 cr_lcd_set_power(crp->cr_lcd_device, FB_BLANK_UNBLANK);
223
224 platform_set_drvdata(pdev, crp);
225
226 return 0;
227}
228
229static int cr_backlight_remove(struct platform_device *pdev)
230{
231 struct cr_panel *crp = platform_get_drvdata(pdev);
232 crp->cr_backlight_device->props.power = FB_BLANK_POWERDOWN;
233 crp->cr_backlight_device->props.brightness = 0;
234 crp->cr_backlight_device->props.max_brightness = 0;
235 cr_backlight_set_intensity(crp->cr_backlight_device);
236 cr_lcd_set_power(crp->cr_lcd_device, FB_BLANK_POWERDOWN);
237 backlight_device_unregister(crp->cr_backlight_device);
238 lcd_device_unregister(crp->cr_lcd_device);
239 pci_dev_put(lpc_dev);
240
241 return 0;
242}
243
244static struct platform_driver cr_backlight_driver = {
245 .probe = cr_backlight_probe,
246 .remove = cr_backlight_remove,
247 .driver = {
248 .name = "cr_backlight",
249 },
250};
251
252static struct platform_device *crp;
253
254static int __init cr_backlight_init(void)
255{
256 int ret = platform_driver_register(&cr_backlight_driver);
257
258 if (!ret) {
259 crp = platform_device_alloc("cr_backlight", -1);
260 if (!crp)
261 return -ENOMEM;
262
263 ret = platform_device_add(crp);
264
265 if (ret) {
266 platform_device_put(crp);
267 platform_driver_unregister(&cr_backlight_driver);
268 }
269 }
270
271 printk("Carillo Ranch Backlight Driver Initialized.\n");
272
273 return ret;
274}
275
276static void __exit cr_backlight_exit(void)
277{
278 platform_device_unregister(crp);
279 platform_driver_unregister(&cr_backlight_driver);
280}
281
282module_init(cr_backlight_init);
283module_exit(cr_backlight_exit);
284
285MODULE_AUTHOR("Tungsten Graphics Inc.");
286MODULE_DESCRIPTION("Carillo Ranch Backlight Driver");
287MODULE_LICENSE("GPL");
diff --git a/drivers/video/cfbcopyarea.c b/drivers/video/cfbcopyarea.c
index 6faea4034e3d..032210f45be3 100644
--- a/drivers/video/cfbcopyarea.c
+++ b/drivers/video/cfbcopyarea.c
@@ -22,8 +22,6 @@
22 * help moving some redundant computations and branches out of the loop, too. 22 * help moving some redundant computations and branches out of the loop, too.
23 */ 23 */
24 24
25
26
27#include <linux/module.h> 25#include <linux/module.h>
28#include <linux/kernel.h> 26#include <linux/kernel.h>
29#include <linux/string.h> 27#include <linux/string.h>
@@ -31,6 +29,7 @@
31#include <linux/slab.h> 29#include <linux/slab.h>
32#include <asm/types.h> 30#include <asm/types.h>
33#include <asm/io.h> 31#include <asm/io.h>
32#include "fb_draw.h"
34 33
35#if BITS_PER_LONG == 32 34#if BITS_PER_LONG == 32
36# define FB_WRITEL fb_writel 35# define FB_WRITEL fb_writel
@@ -41,17 +40,6 @@
41#endif 40#endif
42 41
43 /* 42 /*
44 * Compose two values, using a bitmask as decision value
45 * This is equivalent to (a & mask) | (b & ~mask)
46 */
47
48static inline unsigned long
49comp(unsigned long a, unsigned long b, unsigned long mask)
50{
51 return ((a ^ b) & mask) ^ b;
52}
53
54 /*
55 * Generic bitwise copy algorithm 43 * Generic bitwise copy algorithm
56 */ 44 */
57 45
diff --git a/drivers/video/cfbfillrect.c b/drivers/video/cfbfillrect.c
index f00b50aab606..71623b4f8ca2 100644
--- a/drivers/video/cfbfillrect.c
+++ b/drivers/video/cfbfillrect.c
@@ -21,6 +21,7 @@
21#include <linux/string.h> 21#include <linux/string.h>
22#include <linux/fb.h> 22#include <linux/fb.h>
23#include <asm/types.h> 23#include <asm/types.h>
24#include "fb_draw.h"
24 25
25#if BITS_PER_LONG == 32 26#if BITS_PER_LONG == 32
26# define FB_WRITEL fb_writel 27# define FB_WRITEL fb_writel
@@ -31,73 +32,6 @@
31#endif 32#endif
32 33
33 /* 34 /*
34 * Compose two values, using a bitmask as decision value
35 * This is equivalent to (a & mask) | (b & ~mask)
36 */
37
38static inline unsigned long
39comp(unsigned long a, unsigned long b, unsigned long mask)
40{
41 return ((a ^ b) & mask) ^ b;
42}
43
44 /*
45 * Create a pattern with the given pixel's color
46 */
47
48#if BITS_PER_LONG == 64
49static inline unsigned long
50pixel_to_pat( u32 bpp, u32 pixel)
51{
52 switch (bpp) {
53 case 1:
54 return 0xfffffffffffffffful*pixel;
55 case 2:
56 return 0x5555555555555555ul*pixel;
57 case 4:
58 return 0x1111111111111111ul*pixel;
59 case 8:
60 return 0x0101010101010101ul*pixel;
61 case 12:
62 return 0x0001001001001001ul*pixel;
63 case 16:
64 return 0x0001000100010001ul*pixel;
65 case 24:
66 return 0x0000000001000001ul*pixel;
67 case 32:
68 return 0x0000000100000001ul*pixel;
69 default:
70 panic("pixel_to_pat(): unsupported pixelformat\n");
71 }
72}
73#else
74static inline unsigned long
75pixel_to_pat( u32 bpp, u32 pixel)
76{
77 switch (bpp) {
78 case 1:
79 return 0xfffffffful*pixel;
80 case 2:
81 return 0x55555555ul*pixel;
82 case 4:
83 return 0x11111111ul*pixel;
84 case 8:
85 return 0x01010101ul*pixel;
86 case 12:
87 return 0x00001001ul*pixel;
88 case 16:
89 return 0x00010001ul*pixel;
90 case 24:
91 return 0x00000001ul*pixel;
92 case 32:
93 return 0x00000001ul*pixel;
94 default:
95 panic("pixel_to_pat(): unsupported pixelformat\n");
96 }
97}
98#endif
99
100 /*
101 * Aligned pattern fill using 32/64-bit memory accesses 35 * Aligned pattern fill using 32/64-bit memory accesses
102 */ 36 */
103 37
diff --git a/drivers/video/cirrusfb.c b/drivers/video/cirrusfb.c
index 2c4bc6205738..8269d704ab2a 100644
--- a/drivers/video/cirrusfb.c
+++ b/drivers/video/cirrusfb.c
@@ -98,15 +98,6 @@
98#define assert(expr) 98#define assert(expr)
99#endif 99#endif
100 100
101#ifdef TRUE
102#undef TRUE
103#endif
104#ifdef FALSE
105#undef FALSE
106#endif
107#define TRUE 1
108#define FALSE 0
109
110#define MB_ (1024*1024) 101#define MB_ (1024*1024)
111#define KB_ (1024) 102#define KB_ (1024)
112 103
@@ -146,9 +137,9 @@ static const struct cirrusfb_board_info_rec {
146 char *name; /* ASCII name of chipset */ 137 char *name; /* ASCII name of chipset */
147 long maxclock[5]; /* maximum video clock */ 138 long maxclock[5]; /* maximum video clock */
148 /* for 1/4bpp, 8bpp 15/16bpp, 24bpp, 32bpp - numbers from xorg code */ 139 /* for 1/4bpp, 8bpp 15/16bpp, 24bpp, 32bpp - numbers from xorg code */
149 unsigned init_sr07 : 1; /* init SR07 during init_vgachip() */ 140 bool init_sr07 : 1; /* init SR07 during init_vgachip() */
150 unsigned init_sr1f : 1; /* write SR1F during init_vgachip() */ 141 bool init_sr1f : 1; /* write SR1F during init_vgachip() */
151 unsigned scrn_start_bit19 : 1; /* construct bit 19 of screen start address */ 142 bool scrn_start_bit19 : 1; /* construct bit 19 of screen start address */
152 143
153 /* initial SR07 value, then for each mode */ 144 /* initial SR07 value, then for each mode */
154 unsigned char sr07; 145 unsigned char sr07;
@@ -166,9 +157,9 @@ static const struct cirrusfb_board_info_rec {
166 /* the SD64/P4 have a higher max. videoclock */ 157 /* the SD64/P4 have a higher max. videoclock */
167 140000, 140000, 140000, 140000, 140000, 158 140000, 140000, 140000, 140000, 140000,
168 }, 159 },
169 .init_sr07 = TRUE, 160 .init_sr07 = true,
170 .init_sr1f = TRUE, 161 .init_sr1f = true,
171 .scrn_start_bit19 = TRUE, 162 .scrn_start_bit19 = true,
172 .sr07 = 0xF0, 163 .sr07 = 0xF0,
173 .sr07_1bpp = 0xF0, 164 .sr07_1bpp = 0xF0,
174 .sr07_8bpp = 0xF1, 165 .sr07_8bpp = 0xF1,
@@ -180,9 +171,9 @@ static const struct cirrusfb_board_info_rec {
180 /* guess */ 171 /* guess */
181 90000, 90000, 90000, 90000, 90000 172 90000, 90000, 90000, 90000, 90000
182 }, 173 },
183 .init_sr07 = TRUE, 174 .init_sr07 = true,
184 .init_sr1f = TRUE, 175 .init_sr1f = true,
185 .scrn_start_bit19 = FALSE, 176 .scrn_start_bit19 = false,
186 .sr07 = 0x80, 177 .sr07 = 0x80,
187 .sr07_1bpp = 0x80, 178 .sr07_1bpp = 0x80,
188 .sr07_8bpp = 0x81, 179 .sr07_8bpp = 0x81,
@@ -194,9 +185,9 @@ static const struct cirrusfb_board_info_rec {
194 /* guess */ 185 /* guess */
195 90000, 90000, 90000, 90000, 90000 186 90000, 90000, 90000, 90000, 90000
196 }, 187 },
197 .init_sr07 = TRUE, 188 .init_sr07 = true,
198 .init_sr1f = TRUE, 189 .init_sr1f = true,
199 .scrn_start_bit19 = FALSE, 190 .scrn_start_bit19 = false,
200 .sr07 = 0x20, 191 .sr07 = 0x20,
201 .sr07_1bpp = 0x20, 192 .sr07_1bpp = 0x20,
202 .sr07_8bpp = 0x21, 193 .sr07_8bpp = 0x21,
@@ -208,9 +199,9 @@ static const struct cirrusfb_board_info_rec {
208 /* guess */ 199 /* guess */
209 90000, 90000, 90000, 90000, 90000 200 90000, 90000, 90000, 90000, 90000
210 }, 201 },
211 .init_sr07 = TRUE, 202 .init_sr07 = true,
212 .init_sr1f = TRUE, 203 .init_sr1f = true,
213 .scrn_start_bit19 = FALSE, 204 .scrn_start_bit19 = false,
214 .sr07 = 0x80, 205 .sr07 = 0x80,
215 .sr07_1bpp = 0x80, 206 .sr07_1bpp = 0x80,
216 .sr07_8bpp = 0x81, 207 .sr07_8bpp = 0x81,
@@ -221,9 +212,9 @@ static const struct cirrusfb_board_info_rec {
221 .maxclock = { 212 .maxclock = {
222 135100, 135100, 85500, 85500, 0 213 135100, 135100, 85500, 85500, 0
223 }, 214 },
224 .init_sr07 = TRUE, 215 .init_sr07 = true,
225 .init_sr1f = FALSE, 216 .init_sr1f = false,
226 .scrn_start_bit19 = TRUE, 217 .scrn_start_bit19 = true,
227 .sr07 = 0x20, 218 .sr07 = 0x20,
228 .sr07_1bpp = 0x20, 219 .sr07_1bpp = 0x20,
229 .sr07_8bpp = 0x21, 220 .sr07_8bpp = 0x21,
@@ -235,9 +226,9 @@ static const struct cirrusfb_board_info_rec {
235 /* for the GD5430. GD5446 can do more... */ 226 /* for the GD5430. GD5446 can do more... */
236 85500, 85500, 50000, 28500, 0 227 85500, 85500, 50000, 28500, 0
237 }, 228 },
238 .init_sr07 = TRUE, 229 .init_sr07 = true,
239 .init_sr1f = TRUE, 230 .init_sr1f = true,
240 .scrn_start_bit19 = TRUE, 231 .scrn_start_bit19 = true,
241 .sr07 = 0xA0, 232 .sr07 = 0xA0,
242 .sr07_1bpp = 0xA1, 233 .sr07_1bpp = 0xA1,
243 .sr07_1bpp_mux = 0xA7, 234 .sr07_1bpp_mux = 0xA7,
@@ -250,9 +241,9 @@ static const struct cirrusfb_board_info_rec {
250 .maxclock = { 241 .maxclock = {
251 135100, 200000, 200000, 135100, 135100 242 135100, 200000, 200000, 135100, 135100
252 }, 243 },
253 .init_sr07 = TRUE, 244 .init_sr07 = true,
254 .init_sr1f = TRUE, 245 .init_sr1f = true,
255 .scrn_start_bit19 = TRUE, 246 .scrn_start_bit19 = true,
256 .sr07 = 0x10, 247 .sr07 = 0x10,
257 .sr07_1bpp = 0x11, 248 .sr07_1bpp = 0x11,
258 .sr07_8bpp = 0x11, 249 .sr07_8bpp = 0x11,
@@ -264,9 +255,9 @@ static const struct cirrusfb_board_info_rec {
264 /* guess */ 255 /* guess */
265 135100, 135100, 135100, 135100, 135100, 256 135100, 135100, 135100, 135100, 135100,
266 }, 257 },
267 .init_sr07 = FALSE, 258 .init_sr07 = false,
268 .init_sr1f = FALSE, 259 .init_sr1f = false,
269 .scrn_start_bit19 = TRUE, 260 .scrn_start_bit19 = true,
270 } 261 }
271}; 262};
272 263
@@ -815,7 +806,7 @@ static int cirrusfb_check_var(struct fb_var_screeninfo *var,
815 806
816 default: 807 default:
817 DPRINTK("Unsupported bpp size: %d\n", var->bits_per_pixel); 808 DPRINTK("Unsupported bpp size: %d\n", var->bits_per_pixel);
818 assert (FALSE); 809 assert(false);
819 /* should never occur */ 810 /* should never occur */
820 break; 811 break;
821 } 812 }
@@ -886,7 +877,7 @@ static int cirrusfb_decode_var (const struct fb_var_screeninfo *var,
886 877
887 default: 878 default:
888 DPRINTK("Unsupported bpp size: %d\n", var->bits_per_pixel); 879 DPRINTK("Unsupported bpp size: %d\n", var->bits_per_pixel);
889 assert (FALSE); 880 assert(false);
890 /* should never occur */ 881 /* should never occur */
891 break; 882 break;
892 } 883 }
@@ -3203,7 +3194,7 @@ void cirrusfb_dbg_print_regs (caddr_t regbase, cirrusfb_dbg_reg_class_t reg_clas
3203 break; 3194 break;
3204 default: 3195 default:
3205 /* should never occur */ 3196 /* should never occur */
3206 assert (FALSE); 3197 assert(false);
3207 break; 3198 break;
3208 } 3199 }
3209 3200
diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c
index 0429fd2cece0..73813c60d03a 100644
--- a/drivers/video/console/fbcon.c
+++ b/drivers/video/console/fbcon.c
@@ -107,7 +107,9 @@ static struct display fb_display[MAX_NR_CONSOLES];
107 107
108static signed char con2fb_map[MAX_NR_CONSOLES]; 108static signed char con2fb_map[MAX_NR_CONSOLES];
109static signed char con2fb_map_boot[MAX_NR_CONSOLES]; 109static signed char con2fb_map_boot[MAX_NR_CONSOLES];
110#ifndef MODULE
110static int logo_height; 111static int logo_height;
112#endif
111static int logo_lines; 113static int logo_lines;
112/* logo_shown is an index to vc_cons when >= 0; otherwise follows FBCON_LOGO 114/* logo_shown is an index to vc_cons when >= 0; otherwise follows FBCON_LOGO
113 enums. */ 115 enums. */
@@ -576,6 +578,13 @@ static int fbcon_takeover(int show_logo)
576 return err; 578 return err;
577} 579}
578 580
581#ifdef MODULE
582static void fbcon_prepare_logo(struct vc_data *vc, struct fb_info *info,
583 int cols, int rows, int new_cols, int new_rows)
584{
585 logo_shown = FBCON_LOGO_DONTSHOW;
586}
587#else
579static void fbcon_prepare_logo(struct vc_data *vc, struct fb_info *info, 588static void fbcon_prepare_logo(struct vc_data *vc, struct fb_info *info,
580 int cols, int rows, int new_cols, int new_rows) 589 int cols, int rows, int new_cols, int new_rows)
581{ 590{
@@ -584,6 +593,11 @@ static void fbcon_prepare_logo(struct vc_data *vc, struct fb_info *info,
584 int cnt, erase = vc->vc_video_erase_char, step; 593 int cnt, erase = vc->vc_video_erase_char, step;
585 unsigned short *save = NULL, *r, *q; 594 unsigned short *save = NULL, *r, *q;
586 595
596 if (info->flags & FBINFO_MODULE) {
597 logo_shown = FBCON_LOGO_DONTSHOW;
598 return;
599 }
600
587 /* 601 /*
588 * remove underline attribute from erase character 602 * remove underline attribute from erase character
589 * if black and white framebuffer. 603 * if black and white framebuffer.
@@ -618,8 +632,13 @@ static void fbcon_prepare_logo(struct vc_data *vc, struct fb_info *info,
618 r -= cols; 632 r -= cols;
619 } 633 }
620 if (!save) { 634 if (!save) {
621 vc->vc_y += logo_lines; 635 int lines;
622 vc->vc_pos += logo_lines * vc->vc_size_row; 636 if (vc->vc_y + logo_lines >= rows)
637 lines = rows - vc->vc_y - 1;
638 else
639 lines = logo_lines;
640 vc->vc_y += lines;
641 vc->vc_pos += lines * vc->vc_size_row;
623 } 642 }
624 } 643 }
625 scr_memsetw((unsigned short *) vc->vc_origin, 644 scr_memsetw((unsigned short *) vc->vc_origin,
@@ -650,6 +669,7 @@ static void fbcon_prepare_logo(struct vc_data *vc, struct fb_info *info,
650 vc->vc_top = logo_lines; 669 vc->vc_top = logo_lines;
651 } 670 }
652} 671}
672#endif /* MODULE */
653 673
654#ifdef CONFIG_FB_TILEBLITTING 674#ifdef CONFIG_FB_TILEBLITTING
655static void set_blitting_type(struct vc_data *vc, struct fb_info *info) 675static void set_blitting_type(struct vc_data *vc, struct fb_info *info)
@@ -665,6 +685,17 @@ static void set_blitting_type(struct vc_data *vc, struct fb_info *info)
665 fbcon_set_bitops(ops); 685 fbcon_set_bitops(ops);
666 } 686 }
667} 687}
688
689static int fbcon_invalid_charcount(struct fb_info *info, unsigned charcount)
690{
691 int err = 0;
692
693 if (info->flags & FBINFO_MISC_TILEBLITTING &&
694 info->tileops->fb_get_tilemax(info) < charcount)
695 err = 1;
696
697 return err;
698}
668#else 699#else
669static void set_blitting_type(struct vc_data *vc, struct fb_info *info) 700static void set_blitting_type(struct vc_data *vc, struct fb_info *info)
670{ 701{
@@ -675,6 +706,12 @@ static void set_blitting_type(struct vc_data *vc, struct fb_info *info)
675 fbcon_set_rotation(info); 706 fbcon_set_rotation(info);
676 fbcon_set_bitops(ops); 707 fbcon_set_bitops(ops);
677} 708}
709
710static int fbcon_invalid_charcount(struct fb_info *info, unsigned charcount)
711{
712 return 0;
713}
714
678#endif /* CONFIG_MISC_TILEBLITTING */ 715#endif /* CONFIG_MISC_TILEBLITTING */
679 716
680 717
@@ -968,7 +1005,9 @@ static const char *fbcon_startup(void)
968 if (!p->fontdata) { 1005 if (!p->fontdata) {
969 if (!fontname[0] || !(font = find_font(fontname))) 1006 if (!fontname[0] || !(font = find_font(fontname)))
970 font = get_default_font(info->var.xres, 1007 font = get_default_font(info->var.xres,
971 info->var.yres); 1008 info->var.yres,
1009 info->pixmap.blit_x,
1010 info->pixmap.blit_y);
972 vc->vc_font.width = font->width; 1011 vc->vc_font.width = font->width;
973 vc->vc_font.height = font->height; 1012 vc->vc_font.height = font->height;
974 vc->vc_font.data = (void *)(p->fontdata = font->data); 1013 vc->vc_font.data = (void *)(p->fontdata = font->data);
@@ -1088,7 +1127,9 @@ static void fbcon_init(struct vc_data *vc, int init)
1088 1127
1089 if (!fontname[0] || !(font = find_font(fontname))) 1128 if (!fontname[0] || !(font = find_font(fontname)))
1090 font = get_default_font(info->var.xres, 1129 font = get_default_font(info->var.xres,
1091 info->var.yres); 1130 info->var.yres,
1131 info->pixmap.blit_x,
1132 info->pixmap.blit_y);
1092 vc->vc_font.width = font->width; 1133 vc->vc_font.width = font->width;
1093 vc->vc_font.height = font->height; 1134 vc->vc_font.height = font->height;
1094 vc->vc_font.data = (void *)(p->fontdata = font->data); 1135 vc->vc_font.data = (void *)(p->fontdata = font->data);
@@ -1305,7 +1346,7 @@ static void fbcon_cursor(struct vc_data *vc, int mode)
1305 int y; 1346 int y;
1306 int c = scr_readw((u16 *) vc->vc_pos); 1347 int c = scr_readw((u16 *) vc->vc_pos);
1307 1348
1308 if (fbcon_is_inactive(vc, info)) 1349 if (fbcon_is_inactive(vc, info) || vc->vc_deccm != 1)
1309 return; 1350 return;
1310 1351
1311 ops->cursor_flash = (mode == CM_ERASE) ? 0 : 1; 1352 ops->cursor_flash = (mode == CM_ERASE) ? 0 : 1;
@@ -2475,6 +2516,7 @@ static int fbcon_copy_font(struct vc_data *vc, int con)
2475 2516
2476static int fbcon_set_font(struct vc_data *vc, struct console_font *font, unsigned flags) 2517static int fbcon_set_font(struct vc_data *vc, struct console_font *font, unsigned flags)
2477{ 2518{
2519 struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];
2478 unsigned charcount = font->charcount; 2520 unsigned charcount = font->charcount;
2479 int w = font->width; 2521 int w = font->width;
2480 int h = font->height; 2522 int h = font->height;
@@ -2488,6 +2530,15 @@ static int fbcon_set_font(struct vc_data *vc, struct console_font *font, unsigne
2488 if (charcount != 256 && charcount != 512) 2530 if (charcount != 256 && charcount != 512)
2489 return -EINVAL; 2531 return -EINVAL;
2490 2532
2533 /* Make sure drawing engine can handle the font */
2534 if (!(info->pixmap.blit_x & (1 << (font->width - 1))) ||
2535 !(info->pixmap.blit_y & (1 << (font->height - 1))))
2536 return -EINVAL;
2537
2538 /* Make sure driver can handle the font length */
2539 if (fbcon_invalid_charcount(info, charcount))
2540 return -EINVAL;
2541
2491 size = h * pitch * charcount; 2542 size = h * pitch * charcount;
2492 2543
2493 new_data = kmalloc(FONT_EXTRA_WORDS * sizeof(int) + size, GFP_USER); 2544 new_data = kmalloc(FONT_EXTRA_WORDS * sizeof(int) + size, GFP_USER);
@@ -2532,7 +2583,8 @@ static int fbcon_set_def_font(struct vc_data *vc, struct console_font *font, cha
2532 const struct font_desc *f; 2583 const struct font_desc *f;
2533 2584
2534 if (!name) 2585 if (!name)
2535 f = get_default_font(info->var.xres, info->var.yres); 2586 f = get_default_font(info->var.xres, info->var.yres,
2587 info->pixmap.blit_x, info->pixmap.blit_y);
2536 else if (!(f = find_font(name))) 2588 else if (!(f = find_font(name)))
2537 return -ENOENT; 2589 return -ENOENT;
2538 2590
@@ -2829,7 +2881,7 @@ static void fbcon_set_all_vcs(struct fb_info *info)
2829 struct fbcon_ops *ops = info->fbcon_par; 2881 struct fbcon_ops *ops = info->fbcon_par;
2830 struct vc_data *vc; 2882 struct vc_data *vc;
2831 struct display *p; 2883 struct display *p;
2832 int i, rows, cols; 2884 int i, rows, cols, fg = -1;
2833 2885
2834 if (!ops || ops->currcon < 0) 2886 if (!ops || ops->currcon < 0)
2835 return; 2887 return;
@@ -2840,34 +2892,23 @@ static void fbcon_set_all_vcs(struct fb_info *info)
2840 registered_fb[con2fb_map[i]] != info) 2892 registered_fb[con2fb_map[i]] != info)
2841 continue; 2893 continue;
2842 2894
2895 if (CON_IS_VISIBLE(vc)) {
2896 fg = i;
2897 continue;
2898 }
2899
2843 p = &fb_display[vc->vc_num]; 2900 p = &fb_display[vc->vc_num];
2844 set_blitting_type(vc, info); 2901 set_blitting_type(vc, info);
2845 var_to_display(p, &info->var, info); 2902 var_to_display(p, &info->var, info);
2846 cols = FBCON_SWAP(ops->rotate, info->var.xres, info->var.yres); 2903 cols = FBCON_SWAP(p->rotate, info->var.xres, info->var.yres);
2847 rows = FBCON_SWAP(ops->rotate, info->var.yres, info->var.xres); 2904 rows = FBCON_SWAP(p->rotate, info->var.yres, info->var.xres);
2848 cols /= vc->vc_font.width; 2905 cols /= vc->vc_font.width;
2849 rows /= vc->vc_font.height; 2906 rows /= vc->vc_font.height;
2850 vc_resize(vc, cols, rows); 2907 vc_resize(vc, cols, rows);
2851
2852 if (CON_IS_VISIBLE(vc)) {
2853 updatescrollmode(p, info, vc);
2854 scrollback_max = 0;
2855 scrollback_current = 0;
2856
2857 if (!fbcon_is_inactive(vc, info)) {
2858 ops->var.xoffset = ops->var.yoffset =
2859 p->yscroll = 0;
2860 ops->update_start(info);
2861 }
2862
2863 fbcon_set_palette(vc, color_table);
2864 update_screen(vc);
2865 if (softback_buf)
2866 fbcon_update_softback(vc);
2867 }
2868 } 2908 }
2869 2909
2870 ops->p = &fb_display[ops->currcon]; 2910 if (fg != -1)
2911 fbcon_modechanged(info);
2871} 2912}
2872 2913
2873static int fbcon_mode_deleted(struct fb_info *info, 2914static int fbcon_mode_deleted(struct fb_info *info,
@@ -3002,6 +3043,42 @@ static void fbcon_new_modelist(struct fb_info *info)
3002 } 3043 }
3003} 3044}
3004 3045
3046static void fbcon_get_requirement(struct fb_info *info,
3047 struct fb_blit_caps *caps)
3048{
3049 struct vc_data *vc;
3050 struct display *p;
3051
3052 if (caps->flags) {
3053 int i, charcnt;
3054
3055 for (i = first_fb_vc; i <= last_fb_vc; i++) {
3056 vc = vc_cons[i].d;
3057 if (vc && vc->vc_mode == KD_TEXT &&
3058 info->node == con2fb_map[i]) {
3059 p = &fb_display[i];
3060 caps->x |= 1 << (vc->vc_font.width - 1);
3061 caps->y |= 1 << (vc->vc_font.height - 1);
3062 charcnt = (p->userfont) ?
3063 FNTCHARCNT(p->fontdata) : 256;
3064 if (caps->len < charcnt)
3065 caps->len = charcnt;
3066 }
3067 }
3068 } else {
3069 vc = vc_cons[fg_console].d;
3070
3071 if (vc && vc->vc_mode == KD_TEXT &&
3072 info->node == con2fb_map[fg_console]) {
3073 p = &fb_display[fg_console];
3074 caps->x = 1 << (vc->vc_font.width - 1);
3075 caps->y = 1 << (vc->vc_font.height - 1);
3076 caps->len = (p->userfont) ?
3077 FNTCHARCNT(p->fontdata) : 256;
3078 }
3079 }
3080}
3081
3005static int fbcon_event_notify(struct notifier_block *self, 3082static int fbcon_event_notify(struct notifier_block *self,
3006 unsigned long action, void *data) 3083 unsigned long action, void *data)
3007{ 3084{
@@ -3009,6 +3086,7 @@ static int fbcon_event_notify(struct notifier_block *self,
3009 struct fb_info *info = event->info; 3086 struct fb_info *info = event->info;
3010 struct fb_videomode *mode; 3087 struct fb_videomode *mode;
3011 struct fb_con2fbmap *con2fb; 3088 struct fb_con2fbmap *con2fb;
3089 struct fb_blit_caps *caps;
3012 int ret = 0; 3090 int ret = 0;
3013 3091
3014 /* 3092 /*
@@ -3057,6 +3135,10 @@ static int fbcon_event_notify(struct notifier_block *self,
3057 case FB_EVENT_NEW_MODELIST: 3135 case FB_EVENT_NEW_MODELIST:
3058 fbcon_new_modelist(info); 3136 fbcon_new_modelist(info);
3059 break; 3137 break;
3138 case FB_EVENT_GET_REQ:
3139 caps = event->data;
3140 fbcon_get_requirement(info, caps);
3141 break;
3060 } 3142 }
3061 3143
3062done: 3144done:
diff --git a/drivers/video/console/fonts.c b/drivers/video/console/fonts.c
index c960728b7e82..a6828d0a4c56 100644
--- a/drivers/video/console/fonts.c
+++ b/drivers/video/console/fonts.c
@@ -98,6 +98,8 @@ const struct font_desc *find_font(const char *name)
98 * get_default_font - get default font 98 * get_default_font - get default font
99 * @xres: screen size of X 99 * @xres: screen size of X
100 * @yres: screen size of Y 100 * @yres: screen size of Y
101 * @font_w: bit array of supported widths (1 - 32)
102 * @font_h: bit array of supported heights (1 - 32)
101 * 103 *
102 * Get the default font for a specified screen size. 104 * Get the default font for a specified screen size.
103 * Dimensions are in pixels. 105 * Dimensions are in pixels.
@@ -107,7 +109,8 @@ const struct font_desc *find_font(const char *name)
107 * 109 *
108 */ 110 */
109 111
110const struct font_desc *get_default_font(int xres, int yres) 112const struct font_desc *get_default_font(int xres, int yres, u32 font_w,
113 u32 font_h)
111{ 114{
112 int i, c, cc; 115 int i, c, cc;
113 const struct font_desc *f, *g; 116 const struct font_desc *f, *g;
@@ -129,6 +132,11 @@ const struct font_desc *get_default_font(int xres, int yres)
129#endif 132#endif
130 if ((yres < 400) == (f->height <= 8)) 133 if ((yres < 400) == (f->height <= 8))
131 c += 1000; 134 c += 1000;
135
136 if (!(font_w & (1 << (f->width - 1))) ||
137 !(font_w & (1 << (f->height - 1))))
138 c += 1000;
139
132 if (c > cc) { 140 if (c > cc) {
133 cc = c; 141 cc = c;
134 g = f; 142 g = f;
diff --git a/drivers/video/console/mdacon.c b/drivers/video/console/mdacon.c
index 124ecbe6f88c..bd8d995fe25d 100644
--- a/drivers/video/console/mdacon.c
+++ b/drivers/video/console/mdacon.c
@@ -384,7 +384,7 @@ static inline u16 mda_convert_attr(u16 ch)
384} 384}
385 385
386static u8 mdacon_build_attr(struct vc_data *c, u8 color, u8 intensity, 386static u8 mdacon_build_attr(struct vc_data *c, u8 color, u8 intensity,
387 u8 blink, u8 underline, u8 reverse) 387 u8 blink, u8 underline, u8 reverse, u8 italic)
388{ 388{
389 /* The attribute is just a bit vector: 389 /* The attribute is just a bit vector:
390 * 390 *
@@ -397,6 +397,7 @@ static u8 mdacon_build_attr(struct vc_data *c, u8 color, u8 intensity,
397 return (intensity & 3) | 397 return (intensity & 3) |
398 ((underline & 1) << 2) | 398 ((underline & 1) << 2) |
399 ((reverse & 1) << 3) | 399 ((reverse & 1) << 3) |
400 (!!italic << 4) |
400 ((blink & 1) << 7); 401 ((blink & 1) << 7);
401} 402}
402 403
diff --git a/drivers/video/console/promcon.c b/drivers/video/console/promcon.c
index b78eac63459f..ae02e4eb18e7 100644
--- a/drivers/video/console/promcon.c
+++ b/drivers/video/console/promcon.c
@@ -548,7 +548,8 @@ promcon_scroll(struct vc_data *conp, int t, int b, int dir, int count)
548} 548}
549 549
550#if !(PROMCON_COLOR) 550#if !(PROMCON_COLOR)
551static u8 promcon_build_attr(struct vc_data *conp, u8 _color, u8 _intensity, u8 _blink, u8 _underline, u8 _reverse) 551static u8 promcon_build_attr(struct vc_data *conp, u8 _color, u8 _intensity,
552 u8 _blink, u8 _underline, u8 _reverse, u8 _italic)
552{ 553{
553 return (_reverse) ? 0xf : 0x7; 554 return (_reverse) ? 0xf : 0x7;
554} 555}
diff --git a/drivers/video/console/sticon.c b/drivers/video/console/sticon.c
index 57b21e533036..67a682d6cc7b 100644
--- a/drivers/video/console/sticon.c
+++ b/drivers/video/console/sticon.c
@@ -314,7 +314,7 @@ static unsigned long sticon_getxy(struct vc_data *conp, unsigned long pos,
314} 314}
315 315
316static u8 sticon_build_attr(struct vc_data *conp, u8 color, u8 intens, 316static u8 sticon_build_attr(struct vc_data *conp, u8 color, u8 intens,
317 u8 blink, u8 underline, u8 reverse) 317 u8 blink, u8 underline, u8 reverse, u8 italic)
318{ 318{
319 u8 attr = ((color & 0x70) >> 1) | ((color & 7)); 319 u8 attr = ((color & 0x70) >> 1) | ((color & 7));
320 320
diff --git a/drivers/video/console/sticore.c b/drivers/video/console/sticore.c
index 88e7038eab88..717b360d0415 100644
--- a/drivers/video/console/sticore.c
+++ b/drivers/video/console/sticore.c
@@ -495,7 +495,7 @@ sti_select_fbfont(struct sti_cooked_rom *cooked_rom, const char *fbfont_name)
495 return NULL; 495 return NULL;
496 fbfont = find_font(fbfont_name); 496 fbfont = find_font(fbfont_name);
497 if (!fbfont) 497 if (!fbfont)
498 fbfont = get_default_font(1024,768); 498 fbfont = get_default_font(1024,768, ~(u32)0, ~(u32)0);
499 if (!fbfont) 499 if (!fbfont)
500 return NULL; 500 return NULL;
501 501
diff --git a/drivers/video/console/vgacon.c b/drivers/video/console/vgacon.c
index 3e67c34df9a5..2460b82a1d93 100644
--- a/drivers/video/console/vgacon.c
+++ b/drivers/video/console/vgacon.c
@@ -86,8 +86,6 @@ static int vgacon_set_origin(struct vc_data *c);
86static void vgacon_save_screen(struct vc_data *c); 86static void vgacon_save_screen(struct vc_data *c);
87static int vgacon_scroll(struct vc_data *c, int t, int b, int dir, 87static int vgacon_scroll(struct vc_data *c, int t, int b, int dir,
88 int lines); 88 int lines);
89static u8 vgacon_build_attr(struct vc_data *c, u8 color, u8 intensity,
90 u8 blink, u8 underline, u8 reverse);
91static void vgacon_invert_region(struct vc_data *c, u16 * p, int count); 89static void vgacon_invert_region(struct vc_data *c, u16 * p, int count);
92static unsigned long vgacon_uni_pagedir[2]; 90static unsigned long vgacon_uni_pagedir[2];
93 91
@@ -578,12 +576,14 @@ static void vgacon_deinit(struct vc_data *c)
578} 576}
579 577
580static u8 vgacon_build_attr(struct vc_data *c, u8 color, u8 intensity, 578static u8 vgacon_build_attr(struct vc_data *c, u8 color, u8 intensity,
581 u8 blink, u8 underline, u8 reverse) 579 u8 blink, u8 underline, u8 reverse, u8 italic)
582{ 580{
583 u8 attr = color; 581 u8 attr = color;
584 582
585 if (vga_can_do_color) { 583 if (vga_can_do_color) {
586 if (underline) 584 if (italic)
585 attr = (attr & 0xF0) | c->vc_itcolor;
586 else if (underline)
587 attr = (attr & 0xf0) | c->vc_ulcolor; 587 attr = (attr & 0xf0) | c->vc_ulcolor;
588 else if (intensity == 0) 588 else if (intensity == 0)
589 attr = (attr & 0xf0) | c->vc_halfcolor; 589 attr = (attr & 0xf0) | c->vc_halfcolor;
@@ -597,7 +597,9 @@ static u8 vgacon_build_attr(struct vc_data *c, u8 color, u8 intensity,
597 if (intensity == 2) 597 if (intensity == 2)
598 attr ^= 0x08; 598 attr ^= 0x08;
599 if (!vga_can_do_color) { 599 if (!vga_can_do_color) {
600 if (underline) 600 if (italic)
601 attr = (attr & 0xF8) | 0x02;
602 else if (underline)
601 attr = (attr & 0xf8) | 0x01; 603 attr = (attr & 0xf8) | 0x01;
602 else if (intensity == 0) 604 else if (intensity == 0)
603 attr = (attr & 0xf0) | 0x08; 605 attr = (attr & 0xf0) | 0x08;
@@ -658,6 +660,9 @@ static void vgacon_set_cursor_size(int xpos, int from, int to)
658 660
659static void vgacon_cursor(struct vc_data *c, int mode) 661static void vgacon_cursor(struct vc_data *c, int mode)
660{ 662{
663 if (c->vc_mode != KD_TEXT)
664 return;
665
661 vgacon_restore_screen(c); 666 vgacon_restore_screen(c);
662 667
663 switch (mode) { 668 switch (mode) {
@@ -1316,7 +1321,7 @@ static int vgacon_scroll(struct vc_data *c, int t, int b, int dir,
1316 unsigned long oldo; 1321 unsigned long oldo;
1317 unsigned int delta; 1322 unsigned int delta;
1318 1323
1319 if (t || b != c->vc_rows || vga_is_gfx) 1324 if (t || b != c->vc_rows || vga_is_gfx || c->vc_mode != KD_TEXT)
1320 return 0; 1325 return 0;
1321 1326
1322 if (!vga_hardscroll_enabled || lines >= c->vc_rows / 2) 1327 if (!vga_hardscroll_enabled || lines >= c->vc_rows / 2)
diff --git a/drivers/video/display/Kconfig b/drivers/video/display/Kconfig
new file mode 100644
index 000000000000..f99af931d4f8
--- /dev/null
+++ b/drivers/video/display/Kconfig
@@ -0,0 +1,24 @@
1#
2# Display drivers configuration
3#
4
5menu "Display device support"
6
7config DISPLAY_SUPPORT
8 tristate "Display panel/monitor support"
9 ---help---
10 This framework adds support for low-level control of a display.
11 This includes support for power.
12
13 Enable this to be able to choose the drivers for controlling the
14 physical display panel/monitor on some platforms. This not only
15 covers LCD displays for PDAs but also other types of displays
16 such as CRT, TVout etc.
17
18 To have support for your specific display panel you will have to
19 select the proper drivers which depend on this option.
20
21comment "Display hardware drivers"
22 depends on DISPLAY_SUPPORT
23
24endmenu
diff --git a/drivers/video/display/Makefile b/drivers/video/display/Makefile
new file mode 100644
index 000000000000..c0ea832bf171
--- /dev/null
+++ b/drivers/video/display/Makefile
@@ -0,0 +1,6 @@
1# Display drivers
2
3display-objs := display-sysfs.o
4
5obj-$(CONFIG_DISPLAY_SUPPORT) += display.o
6
diff --git a/drivers/video/display/display-sysfs.c b/drivers/video/display/display-sysfs.c
new file mode 100644
index 000000000000..35477177bef4
--- /dev/null
+++ b/drivers/video/display/display-sysfs.c
@@ -0,0 +1,217 @@
1/*
2 * display-sysfs.c - Display output driver sysfs interface
3 *
4 * Copyright (C) 2007 James Simmons <jsimmons@infradead.org>
5 *
6 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or (at
11 * your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License along
19 * with this program; if not, write to the Free Software Foundation, Inc.,
20 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
21 *
22 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
23 */
24#include <linux/module.h>
25#include <linux/display.h>
26#include <linux/ctype.h>
27#include <linux/idr.h>
28#include <linux/err.h>
29
30static ssize_t display_show_name(struct device *dev,
31 struct device_attribute *attr, char *buf)
32{
33 struct display_device *dsp = dev_get_drvdata(dev);
34 return snprintf(buf, PAGE_SIZE, "%s\n", dsp->name);
35}
36
37static ssize_t display_show_type(struct device *dev,
38 struct device_attribute *attr, char *buf)
39{
40 struct display_device *dsp = dev_get_drvdata(dev);
41 return snprintf(buf, PAGE_SIZE, "%s\n", dsp->type);
42}
43
44static ssize_t display_show_contrast(struct device *dev,
45 struct device_attribute *attr, char *buf)
46{
47 struct display_device *dsp = dev_get_drvdata(dev);
48 ssize_t rc = -ENXIO;
49
50 mutex_lock(&dsp->lock);
51 if (likely(dsp->driver) && dsp->driver->get_contrast)
52 rc = sprintf(buf, "%d\n", dsp->driver->get_contrast(dsp));
53 mutex_unlock(&dsp->lock);
54 return rc;
55}
56
57static ssize_t display_store_contrast(struct device *dev,
58 struct device_attribute *attr,
59 const char *buf, size_t count)
60{
61 struct display_device *dsp = dev_get_drvdata(dev);
62 ssize_t ret = -EINVAL, size;
63 int contrast;
64 char *endp;
65
66 contrast = simple_strtoul(buf, &endp, 0);
67 size = endp - buf;
68
69 if (*endp && isspace(*endp))
70 size++;
71
72 if (size != count)
73 return ret;
74
75 mutex_lock(&dsp->lock);
76 if (likely(dsp->driver && dsp->driver->set_contrast)) {
77 pr_debug("display: set contrast to %d\n", contrast);
78 dsp->driver->set_contrast(dsp, contrast);
79 ret = count;
80 }
81 mutex_unlock(&dsp->lock);
82 return ret;
83}
84
85static ssize_t display_show_max_contrast(struct device *dev,
86 struct device_attribute *attr,
87 char *buf)
88{
89 struct display_device *dsp = dev_get_drvdata(dev);
90 ssize_t rc = -ENXIO;
91
92 mutex_lock(&dsp->lock);
93 if (likely(dsp->driver))
94 rc = sprintf(buf, "%d\n", dsp->driver->max_contrast);
95 mutex_unlock(&dsp->lock);
96 return rc;
97}
98
99static struct device_attribute display_attrs[] = {
100 __ATTR(name, S_IRUGO, display_show_name, NULL),
101 __ATTR(type, S_IRUGO, display_show_type, NULL),
102 __ATTR(contrast, S_IRUGO | S_IWUSR, display_show_contrast, display_store_contrast),
103 __ATTR(max_contrast, S_IRUGO, display_show_max_contrast, NULL),
104};
105
106static int display_suspend(struct device *dev, pm_message_t state)
107{
108 struct display_device *dsp = dev_get_drvdata(dev);
109
110 mutex_lock(&dsp->lock);
111 if (likely(dsp->driver->suspend))
112 dsp->driver->suspend(dsp, state);
113 mutex_unlock(&dsp->lock);
114 return 0;
115};
116
117static int display_resume(struct device *dev)
118{
119 struct display_device *dsp = dev_get_drvdata(dev);
120
121 mutex_lock(&dsp->lock);
122 if (likely(dsp->driver->resume))
123 dsp->driver->resume(dsp);
124 mutex_unlock(&dsp->lock);
125 return 0;
126};
127
128static struct mutex allocated_dsp_lock;
129static DEFINE_IDR(allocated_dsp);
130static struct class *display_class;
131
132struct display_device *display_device_register(struct display_driver *driver,
133 struct device *parent, void *devdata)
134{
135 struct display_device *new_dev = NULL;
136 int ret = -EINVAL;
137
138 if (unlikely(!driver))
139 return ERR_PTR(ret);
140
141 mutex_lock(&allocated_dsp_lock);
142 ret = idr_pre_get(&allocated_dsp, GFP_KERNEL);
143 mutex_unlock(&allocated_dsp_lock);
144 if (!ret)
145 return ERR_PTR(ret);
146
147 new_dev = kzalloc(sizeof(struct display_device), GFP_KERNEL);
148 if (likely(new_dev) && unlikely(driver->probe(new_dev, devdata))) {
149 // Reserve the index for this display
150 mutex_lock(&allocated_dsp_lock);
151 ret = idr_get_new(&allocated_dsp, new_dev, &new_dev->idx);
152 mutex_unlock(&allocated_dsp_lock);
153
154 if (!ret) {
155 new_dev->dev = device_create(display_class, parent, 0,
156 "display%d", new_dev->idx);
157 if (!IS_ERR(new_dev->dev)) {
158 dev_set_drvdata(new_dev->dev, new_dev);
159 new_dev->parent = parent;
160 new_dev->driver = driver;
161 mutex_init(&new_dev->lock);
162 return new_dev;
163 }
164 mutex_lock(&allocated_dsp_lock);
165 idr_remove(&allocated_dsp, new_dev->idx);
166 mutex_unlock(&allocated_dsp_lock);
167 ret = -EINVAL;
168 }
169 }
170 kfree(new_dev);
171 return ERR_PTR(ret);
172}
173EXPORT_SYMBOL(display_device_register);
174
175void display_device_unregister(struct display_device *ddev)
176{
177 if (!ddev)
178 return;
179 // Free device
180 mutex_lock(&ddev->lock);
181 device_unregister(ddev->dev);
182 mutex_unlock(&ddev->lock);
183 // Mark device index as avaliable
184 mutex_lock(&allocated_dsp_lock);
185 idr_remove(&allocated_dsp, ddev->idx);
186 mutex_unlock(&allocated_dsp_lock);
187 kfree(ddev);
188}
189EXPORT_SYMBOL(display_device_unregister);
190
191static int __init display_class_init(void)
192{
193 display_class = class_create(THIS_MODULE, "display");
194 if (IS_ERR(display_class)) {
195 printk(KERN_ERR "Failed to create display class\n");
196 display_class = NULL;
197 return -EINVAL;
198 }
199 display_class->dev_attrs = display_attrs;
200 display_class->suspend = display_suspend;
201 display_class->resume = display_resume;
202 mutex_init(&allocated_dsp_lock);
203 return 0;
204}
205
206static void __exit display_class_exit(void)
207{
208 class_destroy(display_class);
209}
210
211module_init(display_class_init);
212module_exit(display_class_exit);
213
214MODULE_DESCRIPTION("Display Hardware handling");
215MODULE_AUTHOR("James Simmons <jsimmons@infradead.org>");
216MODULE_LICENSE("GPL");
217
diff --git a/drivers/video/epson1355fb.c b/drivers/video/epson1355fb.c
index 29e07c109887..ca2c54ce508e 100644
--- a/drivers/video/epson1355fb.c
+++ b/drivers/video/epson1355fb.c
@@ -403,17 +403,10 @@ static inline unsigned long copy_to_user16(void *to, const void *from,
403 403
404 404
405static ssize_t 405static ssize_t
406epson1355fb_read(struct file *file, char *buf, size_t count, loff_t * ppos) 406epson1355fb_read(struct fb_info *info, char *buf, size_t count, loff_t * ppos)
407{ 407{
408 struct inode *inode = file->f_path.dentry->d_inode;
409 int fbidx = iminor(inode);
410 struct fb_info *info = registered_fb[fbidx];
411 unsigned long p = *ppos; 408 unsigned long p = *ppos;
412 409
413 /* from fbmem.c except for our own copy_*_user */
414 if (!info || !info->screen_base)
415 return -ENODEV;
416
417 if (p >= info->fix.smem_len) 410 if (p >= info->fix.smem_len)
418 return 0; 411 return 0;
419 if (count >= info->fix.smem_len) 412 if (count >= info->fix.smem_len)
@@ -434,20 +427,13 @@ epson1355fb_read(struct file *file, char *buf, size_t count, loff_t * ppos)
434} 427}
435 428
436static ssize_t 429static ssize_t
437epson1355fb_write(struct file *file, const char *buf, 430epson1355fb_write(struct fb_info *info, const char *buf,
438 size_t count, loff_t * ppos) 431 size_t count, loff_t * ppos)
439{ 432{
440 struct inode *inode = file->f_path.dentry->d_inode;
441 int fbidx = iminor(inode);
442 struct fb_info *info = registered_fb[fbidx];
443 unsigned long p = *ppos; 433 unsigned long p = *ppos;
444 int err; 434 int err;
445 435
446 /* from fbmem.c except for our own copy_*_user */ 436 /* from fbmem.c except for our own copy_*_user */
447 if (!info || !info->screen_base)
448 return -ENODEV;
449
450 /* from fbmem.c except for our own copy_*_user */
451 if (p > info->fix.smem_len) 437 if (p > info->fix.smem_len)
452 return -ENOSPC; 438 return -ENOSPC;
453 if (count >= info->fix.smem_len) 439 if (count >= info->fix.smem_len)
@@ -650,9 +636,10 @@ int __init epson1355fb_probe(struct platform_device *dev)
650 } 636 }
651 637
652 info = framebuffer_alloc(sizeof(struct epson1355_par) + sizeof(u32) * 256, &dev->dev); 638 info = framebuffer_alloc(sizeof(struct epson1355_par) + sizeof(u32) * 256, &dev->dev);
653 if (!info) 639 if (!info) {
654 rc = -ENOMEM; 640 rc = -ENOMEM;
655 goto bail; 641 goto bail;
642 }
656 643
657 default_par = info->par; 644 default_par = info->par;
658 default_par->reg_addr = (unsigned long) ioremap(EPSON1355FB_REGS_PHYS, EPSON1355FB_REGS_LEN); 645 default_par->reg_addr = (unsigned long) ioremap(EPSON1355FB_REGS_PHYS, EPSON1355FB_REGS_LEN);
diff --git a/drivers/video/fb_defio.c b/drivers/video/fb_defio.c
new file mode 100644
index 000000000000..1a8643f053d8
--- /dev/null
+++ b/drivers/video/fb_defio.c
@@ -0,0 +1,151 @@
1/*
2 * linux/drivers/video/fb_defio.c
3 *
4 * Copyright (C) 2006 Jaya Kumar
5 *
6 * This file is subject to the terms and conditions of the GNU General Public
7 * License. See the file COPYING in the main directory of this archive
8 * for more details.
9 */
10
11#include <linux/module.h>
12#include <linux/kernel.h>
13#include <linux/errno.h>
14#include <linux/string.h>
15#include <linux/mm.h>
16#include <linux/slab.h>
17#include <linux/vmalloc.h>
18#include <linux/delay.h>
19#include <linux/interrupt.h>
20#include <linux/fb.h>
21#include <linux/list.h>
22#include <asm/uaccess.h>
23
24/* to support deferred IO */
25#include <linux/rmap.h>
26#include <linux/pagemap.h>
27
28/* this is to find and return the vmalloc-ed fb pages */
29static struct page* fb_deferred_io_nopage(struct vm_area_struct *vma,
30 unsigned long vaddr, int *type)
31{
32 unsigned long offset;
33 struct page *page;
34 struct fb_info *info = vma->vm_private_data;
35 /* info->screen_base is in System RAM */
36 void *screen_base = (void __force *) info->screen_base;
37
38 offset = (vaddr - vma->vm_start) + (vma->vm_pgoff << PAGE_SHIFT);
39 if (offset >= info->fix.smem_len)
40 return NOPAGE_SIGBUS;
41
42 page = vmalloc_to_page(screen_base + offset);
43 if (!page)
44 return NOPAGE_OOM;
45
46 get_page(page);
47 if (type)
48 *type = VM_FAULT_MINOR;
49 return page;
50}
51
52int fb_deferred_io_fsync(struct file *file, struct dentry *dentry, int datasync)
53{
54 struct fb_info *info = file->private_data;
55
56 /* Kill off the delayed work */
57 cancel_rearming_delayed_work(&info->deferred_work);
58
59 /* Run it immediately */
60 return schedule_delayed_work(&info->deferred_work, 0);
61}
62EXPORT_SYMBOL_GPL(fb_deferred_io_fsync);
63
64/* vm_ops->page_mkwrite handler */
65static int fb_deferred_io_mkwrite(struct vm_area_struct *vma,
66 struct page *page)
67{
68 struct fb_info *info = vma->vm_private_data;
69 struct fb_deferred_io *fbdefio = info->fbdefio;
70
71 /* this is a callback we get when userspace first tries to
72 write to the page. we schedule a workqueue. that workqueue
73 will eventually mkclean the touched pages and execute the
74 deferred framebuffer IO. then if userspace touches a page
75 again, we repeat the same scheme */
76
77 /* protect against the workqueue changing the page list */
78 mutex_lock(&fbdefio->lock);
79 list_add(&page->lru, &fbdefio->pagelist);
80 mutex_unlock(&fbdefio->lock);
81
82 /* come back after delay to process the deferred IO */
83 schedule_delayed_work(&info->deferred_work, fbdefio->delay);
84 return 0;
85}
86
87static struct vm_operations_struct fb_deferred_io_vm_ops = {
88 .nopage = fb_deferred_io_nopage,
89 .page_mkwrite = fb_deferred_io_mkwrite,
90};
91
92static int fb_deferred_io_mmap(struct fb_info *info, struct vm_area_struct *vma)
93{
94 vma->vm_ops = &fb_deferred_io_vm_ops;
95 vma->vm_flags |= ( VM_IO | VM_RESERVED | VM_DONTEXPAND );
96 vma->vm_private_data = info;
97 return 0;
98}
99
100/* workqueue callback */
101static void fb_deferred_io_work(struct work_struct *work)
102{
103 struct fb_info *info = container_of(work, struct fb_info,
104 deferred_work.work);
105 struct list_head *node, *next;
106 struct page *cur;
107 struct fb_deferred_io *fbdefio = info->fbdefio;
108
109 /* here we mkclean the pages, then do all deferred IO */
110 mutex_lock(&fbdefio->lock);
111 list_for_each_entry(cur, &fbdefio->pagelist, lru) {
112 lock_page(cur);
113 page_mkclean(cur);
114 unlock_page(cur);
115 }
116
117 /* driver's callback with pagelist */
118 fbdefio->deferred_io(info, &fbdefio->pagelist);
119
120 /* clear the list */
121 list_for_each_safe(node, next, &fbdefio->pagelist) {
122 list_del(node);
123 }
124 mutex_unlock(&fbdefio->lock);
125}
126
127void fb_deferred_io_init(struct fb_info *info)
128{
129 struct fb_deferred_io *fbdefio = info->fbdefio;
130
131 BUG_ON(!fbdefio);
132 mutex_init(&fbdefio->lock);
133 info->fbops->fb_mmap = fb_deferred_io_mmap;
134 INIT_DELAYED_WORK(&info->deferred_work, fb_deferred_io_work);
135 INIT_LIST_HEAD(&fbdefio->pagelist);
136 if (fbdefio->delay == 0) /* set a default of 1 s */
137 fbdefio->delay = HZ;
138}
139EXPORT_SYMBOL_GPL(fb_deferred_io_init);
140
141void fb_deferred_io_cleanup(struct fb_info *info)
142{
143 struct fb_deferred_io *fbdefio = info->fbdefio;
144
145 BUG_ON(!fbdefio);
146 cancel_delayed_work(&info->deferred_work);
147 flush_scheduled_work();
148}
149EXPORT_SYMBOL_GPL(fb_deferred_io_cleanup);
150
151MODULE_LICENSE("GPL");
diff --git a/drivers/video/fb_draw.h b/drivers/video/fb_draw.h
new file mode 100644
index 000000000000..c5c45203833b
--- /dev/null
+++ b/drivers/video/fb_draw.h
@@ -0,0 +1,72 @@
1#ifndef _FB_DRAW_H
2#define _FB_DRAW_H
3
4#include <asm/types.h>
5
6 /*
7 * Compose two values, using a bitmask as decision value
8 * This is equivalent to (a & mask) | (b & ~mask)
9 */
10
11static inline unsigned long
12comp(unsigned long a, unsigned long b, unsigned long mask)
13{
14 return ((a ^ b) & mask) ^ b;
15}
16
17 /*
18 * Create a pattern with the given pixel's color
19 */
20
21#if BITS_PER_LONG == 64
22static inline unsigned long
23pixel_to_pat( u32 bpp, u32 pixel)
24{
25 switch (bpp) {
26 case 1:
27 return 0xfffffffffffffffful*pixel;
28 case 2:
29 return 0x5555555555555555ul*pixel;
30 case 4:
31 return 0x1111111111111111ul*pixel;
32 case 8:
33 return 0x0101010101010101ul*pixel;
34 case 12:
35 return 0x0001001001001001ul*pixel;
36 case 16:
37 return 0x0001000100010001ul*pixel;
38 case 24:
39 return 0x0000000001000001ul*pixel;
40 case 32:
41 return 0x0000000100000001ul*pixel;
42 default:
43 panic("pixel_to_pat(): unsupported pixelformat\n");
44 }
45}
46#else
47static inline unsigned long
48pixel_to_pat( u32 bpp, u32 pixel)
49{
50 switch (bpp) {
51 case 1:
52 return 0xfffffffful*pixel;
53 case 2:
54 return 0x55555555ul*pixel;
55 case 4:
56 return 0x11111111ul*pixel;
57 case 8:
58 return 0x01010101ul*pixel;
59 case 12:
60 return 0x00001001ul*pixel;
61 case 16:
62 return 0x00010001ul*pixel;
63 case 24:
64 return 0x00000001ul*pixel;
65 case 32:
66 return 0x00000001ul*pixel;
67 default:
68 panic("pixel_to_pat(): unsupported pixelformat\n");
69 }
70}
71#endif
72#endif /* FB_DRAW_H */
diff --git a/drivers/video/fb_sys_fops.c b/drivers/video/fb_sys_fops.c
new file mode 100644
index 000000000000..cf2538d669cd
--- /dev/null
+++ b/drivers/video/fb_sys_fops.c
@@ -0,0 +1,104 @@
1/*
2 * linux/drivers/video/fb_sys_read.c - Generic file operations where
3 * framebuffer is in system RAM
4 *
5 * Copyright (C) 2007 Antonino Daplas <adaplas@pol.net>
6 *
7 * This file is subject to the terms and conditions of the GNU General Public
8 * License. See the file COPYING in the main directory of this archive
9 * for more details.
10 *
11 */
12#include <linux/fb.h>
13#include <linux/module.h>
14#include <asm/uaccess.h>
15
16ssize_t fb_sys_read(struct fb_info *info, char __user *buf, size_t count,
17 loff_t *ppos)
18{
19 unsigned long p = *ppos;
20 void *src;
21 int err = 0;
22 unsigned long total_size;
23
24 if (info->state != FBINFO_STATE_RUNNING)
25 return -EPERM;
26
27 total_size = info->screen_size;
28
29 if (total_size == 0)
30 total_size = info->fix.smem_len;
31
32 if (p >= total_size)
33 return 0;
34
35 if (count >= total_size)
36 count = total_size;
37
38 if (count + p > total_size)
39 count = total_size - p;
40
41 src = (void __force *)(info->screen_base + p);
42
43 if (info->fbops->fb_sync)
44 info->fbops->fb_sync(info);
45
46 if (copy_to_user(buf, src, count))
47 err = -EFAULT;
48
49 if (!err)
50 *ppos += count;
51
52 return (err) ? err : count;
53}
54EXPORT_SYMBOL_GPL(fb_sys_read);
55
56ssize_t fb_sys_write(struct fb_info *info, const char __user *buf,
57 size_t count, loff_t *ppos)
58{
59 unsigned long p = *ppos;
60 void *dst;
61 int err = 0;
62 unsigned long total_size;
63
64 if (info->state != FBINFO_STATE_RUNNING)
65 return -EPERM;
66
67 total_size = info->screen_size;
68
69 if (total_size == 0)
70 total_size = info->fix.smem_len;
71
72 if (p > total_size)
73 return -EFBIG;
74
75 if (count > total_size) {
76 err = -EFBIG;
77 count = total_size;
78 }
79
80 if (count + p > total_size) {
81 if (!err)
82 err = -ENOSPC;
83
84 count = total_size - p;
85 }
86
87 dst = (void __force *) (info->screen_base + p);
88
89 if (info->fbops->fb_sync)
90 info->fbops->fb_sync(info);
91
92 if (copy_from_user(dst, buf, count))
93 err = -EFAULT;
94
95 if (!err)
96 *ppos += count;
97
98 return (err) ? err : count;
99}
100EXPORT_SYMBOL_GPL(fb_sys_write);
101
102MODULE_AUTHOR("Antonino Daplas <adaplas@pol.net>");
103MODULE_DESCRIPTION("Generic file read (fb in system RAM)");
104MODULE_LICENSE("GPL");
diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c
index 28225265159a..08d4e11d9121 100644
--- a/drivers/video/fbmem.c
+++ b/drivers/video/fbmem.c
@@ -354,59 +354,59 @@ static void fb_rotate_logo(struct fb_info *info, u8 *dst,
354 if (rotate == FB_ROTATE_UD) { 354 if (rotate == FB_ROTATE_UD) {
355 fb_rotate_logo_ud(image->data, dst, image->width, 355 fb_rotate_logo_ud(image->data, dst, image->width,
356 image->height); 356 image->height);
357 image->dx = info->var.xres - image->width; 357 image->dx = info->var.xres - image->width - image->dx;
358 image->dy = info->var.yres - image->height; 358 image->dy = info->var.yres - image->height - image->dy;
359 } else if (rotate == FB_ROTATE_CW) { 359 } else if (rotate == FB_ROTATE_CW) {
360 fb_rotate_logo_cw(image->data, dst, image->width, 360 fb_rotate_logo_cw(image->data, dst, image->width,
361 image->height); 361 image->height);
362 tmp = image->width; 362 tmp = image->width;
363 image->width = image->height; 363 image->width = image->height;
364 image->height = tmp; 364 image->height = tmp;
365 image->dx = info->var.xres - image->width; 365 tmp = image->dy;
366 image->dy = image->dx;
367 image->dx = info->var.xres - image->width - tmp;
366 } else if (rotate == FB_ROTATE_CCW) { 368 } else if (rotate == FB_ROTATE_CCW) {
367 fb_rotate_logo_ccw(image->data, dst, image->width, 369 fb_rotate_logo_ccw(image->data, dst, image->width,
368 image->height); 370 image->height);
369 tmp = image->width; 371 tmp = image->width;
370 image->width = image->height; 372 image->width = image->height;
371 image->height = tmp; 373 image->height = tmp;
372 image->dy = info->var.yres - image->height; 374 tmp = image->dx;
375 image->dx = image->dy;
376 image->dy = info->var.yres - image->height - tmp;
373 } 377 }
374 378
375 image->data = dst; 379 image->data = dst;
376} 380}
377 381
378static void fb_do_show_logo(struct fb_info *info, struct fb_image *image, 382static void fb_do_show_logo(struct fb_info *info, struct fb_image *image,
379 int rotate) 383 int rotate, unsigned int num)
380{ 384{
381 int x; 385 unsigned int x;
382 386
383 if (rotate == FB_ROTATE_UR) { 387 if (rotate == FB_ROTATE_UR) {
384 for (x = 0; x < num_online_cpus() && 388 for (x = 0;
385 x * (fb_logo.logo->width + 8) <= 389 x < num && image->dx + image->width <= info->var.xres;
386 info->var.xres - fb_logo.logo->width; x++) { 390 x++) {
387 info->fbops->fb_imageblit(info, image); 391 info->fbops->fb_imageblit(info, image);
388 image->dx += fb_logo.logo->width + 8; 392 image->dx += image->width + 8;
389 } 393 }
390 } else if (rotate == FB_ROTATE_UD) { 394 } else if (rotate == FB_ROTATE_UD) {
391 for (x = 0; x < num_online_cpus() && 395 for (x = 0; x < num && image->dx >= 0; x++) {
392 x * (fb_logo.logo->width + 8) <=
393 info->var.xres - fb_logo.logo->width; x++) {
394 info->fbops->fb_imageblit(info, image); 396 info->fbops->fb_imageblit(info, image);
395 image->dx -= fb_logo.logo->width + 8; 397 image->dx -= image->width + 8;
396 } 398 }
397 } else if (rotate == FB_ROTATE_CW) { 399 } else if (rotate == FB_ROTATE_CW) {
398 for (x = 0; x < num_online_cpus() && 400 for (x = 0;
399 x * (fb_logo.logo->width + 8) <= 401 x < num && image->dy + image->height <= info->var.yres;
400 info->var.yres - fb_logo.logo->width; x++) { 402 x++) {
401 info->fbops->fb_imageblit(info, image); 403 info->fbops->fb_imageblit(info, image);
402 image->dy += fb_logo.logo->width + 8; 404 image->dy += image->height + 8;
403 } 405 }
404 } else if (rotate == FB_ROTATE_CCW) { 406 } else if (rotate == FB_ROTATE_CCW) {
405 for (x = 0; x < num_online_cpus() && 407 for (x = 0; x < num && image->dy >= 0; x++) {
406 x * (fb_logo.logo->width + 8) <=
407 info->var.yres - fb_logo.logo->width; x++) {
408 info->fbops->fb_imageblit(info, image); 408 info->fbops->fb_imageblit(info, image);
409 image->dy -= fb_logo.logo->width + 8; 409 image->dy -= image->height + 8;
410 } 410 }
411 } 411 }
412} 412}
@@ -418,7 +418,8 @@ int fb_prepare_logo(struct fb_info *info, int rotate)
418 418
419 memset(&fb_logo, 0, sizeof(struct logo_data)); 419 memset(&fb_logo, 0, sizeof(struct logo_data));
420 420
421 if (info->flags & FBINFO_MISC_TILEBLITTING) 421 if (info->flags & FBINFO_MISC_TILEBLITTING ||
422 info->flags & FBINFO_MODULE)
422 return 0; 423 return 0;
423 424
424 if (info->fix.visual == FB_VISUAL_DIRECTCOLOR) { 425 if (info->fix.visual == FB_VISUAL_DIRECTCOLOR) {
@@ -483,7 +484,8 @@ int fb_show_logo(struct fb_info *info, int rotate)
483 struct fb_image image; 484 struct fb_image image;
484 485
485 /* Return if the frame buffer is not mapped or suspended */ 486 /* Return if the frame buffer is not mapped or suspended */
486 if (fb_logo.logo == NULL || info->state != FBINFO_STATE_RUNNING) 487 if (fb_logo.logo == NULL || info->state != FBINFO_STATE_RUNNING ||
488 info->flags & FBINFO_MODULE)
487 return 0; 489 return 0;
488 490
489 image.depth = 8; 491 image.depth = 8;
@@ -532,7 +534,7 @@ int fb_show_logo(struct fb_info *info, int rotate)
532 fb_rotate_logo(info, logo_rotate, &image, rotate); 534 fb_rotate_logo(info, logo_rotate, &image, rotate);
533 } 535 }
534 536
535 fb_do_show_logo(info, &image, rotate); 537 fb_do_show_logo(info, &image, rotate, num_online_cpus());
536 538
537 kfree(palette); 539 kfree(palette);
538 if (saved_pseudo_palette != NULL) 540 if (saved_pseudo_palette != NULL)
@@ -586,7 +588,7 @@ fb_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)
586 return -EPERM; 588 return -EPERM;
587 589
588 if (info->fbops->fb_read) 590 if (info->fbops->fb_read)
589 return info->fbops->fb_read(file, buf, count, ppos); 591 return info->fbops->fb_read(info, buf, count, ppos);
590 592
591 total_size = info->screen_size; 593 total_size = info->screen_size;
592 594
@@ -661,7 +663,7 @@ fb_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
661 return -EPERM; 663 return -EPERM;
662 664
663 if (info->fbops->fb_write) 665 if (info->fbops->fb_write)
664 return info->fbops->fb_write(file, buf, count, ppos); 666 return info->fbops->fb_write(info, buf, count, ppos);
665 667
666 total_size = info->screen_size; 668 total_size = info->screen_size;
667 669
@@ -771,14 +773,37 @@ fb_pan_display(struct fb_info *info, struct fb_var_screeninfo *var)
771 return 0; 773 return 0;
772} 774}
773 775
776static int fb_check_caps(struct fb_info *info, struct fb_var_screeninfo *var,
777 u32 activate)
778{
779 struct fb_event event;
780 struct fb_blit_caps caps, fbcaps;
781 int err = 0;
782
783 memset(&caps, 0, sizeof(caps));
784 memset(&fbcaps, 0, sizeof(fbcaps));
785 caps.flags = (activate & FB_ACTIVATE_ALL) ? 1 : 0;
786 event.info = info;
787 event.data = &caps;
788 fb_notifier_call_chain(FB_EVENT_GET_REQ, &event);
789 info->fbops->fb_get_caps(info, &fbcaps, var);
790
791 if (((fbcaps.x ^ caps.x) & caps.x) ||
792 ((fbcaps.y ^ caps.y) & caps.y) ||
793 (fbcaps.len < caps.len))
794 err = -EINVAL;
795
796 return err;
797}
798
774int 799int
775fb_set_var(struct fb_info *info, struct fb_var_screeninfo *var) 800fb_set_var(struct fb_info *info, struct fb_var_screeninfo *var)
776{ 801{
777 int err, flags = info->flags; 802 int flags = info->flags;
803 int ret = 0;
778 804
779 if (var->activate & FB_ACTIVATE_INV_MODE) { 805 if (var->activate & FB_ACTIVATE_INV_MODE) {
780 struct fb_videomode mode1, mode2; 806 struct fb_videomode mode1, mode2;
781 int ret = 0;
782 807
783 fb_var_to_videomode(&mode1, var); 808 fb_var_to_videomode(&mode1, var);
784 fb_var_to_videomode(&mode2, &info->var); 809 fb_var_to_videomode(&mode2, &info->var);
@@ -796,40 +821,51 @@ fb_set_var(struct fb_info *info, struct fb_var_screeninfo *var)
796 if (!ret) 821 if (!ret)
797 fb_delete_videomode(&mode1, &info->modelist); 822 fb_delete_videomode(&mode1, &info->modelist);
798 823
799 return ret; 824
825 ret = (ret) ? -EINVAL : 0;
826 goto done;
800 } 827 }
801 828
802 if ((var->activate & FB_ACTIVATE_FORCE) || 829 if ((var->activate & FB_ACTIVATE_FORCE) ||
803 memcmp(&info->var, var, sizeof(struct fb_var_screeninfo))) { 830 memcmp(&info->var, var, sizeof(struct fb_var_screeninfo))) {
831 u32 activate = var->activate;
832
804 if (!info->fbops->fb_check_var) { 833 if (!info->fbops->fb_check_var) {
805 *var = info->var; 834 *var = info->var;
806 return 0; 835 goto done;
807 } 836 }
808 837
809 if ((err = info->fbops->fb_check_var(var, info))) 838 ret = info->fbops->fb_check_var(var, info);
810 return err; 839
840 if (ret)
841 goto done;
811 842
812 if ((var->activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW) { 843 if ((var->activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW) {
813 struct fb_videomode mode; 844 struct fb_videomode mode;
814 int err = 0; 845
846 if (info->fbops->fb_get_caps) {
847 ret = fb_check_caps(info, var, activate);
848
849 if (ret)
850 goto done;
851 }
815 852
816 info->var = *var; 853 info->var = *var;
854
817 if (info->fbops->fb_set_par) 855 if (info->fbops->fb_set_par)
818 info->fbops->fb_set_par(info); 856 info->fbops->fb_set_par(info);
819 857
820 fb_pan_display(info, &info->var); 858 fb_pan_display(info, &info->var);
821
822 fb_set_cmap(&info->cmap, info); 859 fb_set_cmap(&info->cmap, info);
823
824 fb_var_to_videomode(&mode, &info->var); 860 fb_var_to_videomode(&mode, &info->var);
825 861
826 if (info->modelist.prev && info->modelist.next && 862 if (info->modelist.prev && info->modelist.next &&
827 !list_empty(&info->modelist)) 863 !list_empty(&info->modelist))
828 err = fb_add_videomode(&mode, &info->modelist); 864 ret = fb_add_videomode(&mode, &info->modelist);
829 865
830 if (!err && (flags & FBINFO_MISC_USEREVENT)) { 866 if (!ret && (flags & FBINFO_MISC_USEREVENT)) {
831 struct fb_event event; 867 struct fb_event event;
832 int evnt = (var->activate & FB_ACTIVATE_ALL) ? 868 int evnt = (activate & FB_ACTIVATE_ALL) ?
833 FB_EVENT_MODE_CHANGE_ALL : 869 FB_EVENT_MODE_CHANGE_ALL :
834 FB_EVENT_MODE_CHANGE; 870 FB_EVENT_MODE_CHANGE;
835 871
@@ -839,7 +875,9 @@ fb_set_var(struct fb_info *info, struct fb_var_screeninfo *var)
839 } 875 }
840 } 876 }
841 } 877 }
842 return 0; 878
879 done:
880 return ret;
843} 881}
844 882
845int 883int
@@ -1266,6 +1304,9 @@ static const struct file_operations fb_fops = {
1266#ifdef HAVE_ARCH_FB_UNMAPPED_AREA 1304#ifdef HAVE_ARCH_FB_UNMAPPED_AREA
1267 .get_unmapped_area = get_fb_unmapped_area, 1305 .get_unmapped_area = get_fb_unmapped_area,
1268#endif 1306#endif
1307#ifdef CONFIG_FB_DEFERRED_IO
1308 .fsync = fb_deferred_io_fsync,
1309#endif
1269}; 1310};
1270 1311
1271struct class *fb_class; 1312struct class *fb_class;
@@ -1316,6 +1357,12 @@ register_framebuffer(struct fb_info *fb_info)
1316 } 1357 }
1317 fb_info->pixmap.offset = 0; 1358 fb_info->pixmap.offset = 0;
1318 1359
1360 if (!fb_info->pixmap.blit_x)
1361 fb_info->pixmap.blit_x = ~(u32)0;
1362
1363 if (!fb_info->pixmap.blit_y)
1364 fb_info->pixmap.blit_y = ~(u32)0;
1365
1319 if (!fb_info->modelist.prev || !fb_info->modelist.next) 1366 if (!fb_info->modelist.prev || !fb_info->modelist.next)
1320 INIT_LIST_HEAD(&fb_info->modelist); 1367 INIT_LIST_HEAD(&fb_info->modelist);
1321 1368
diff --git a/drivers/video/fbmon.c b/drivers/video/fbmon.c
index 6b385c39b8b5..438b9411905c 100644
--- a/drivers/video/fbmon.c
+++ b/drivers/video/fbmon.c
@@ -48,8 +48,9 @@
48#define DPRINTK(fmt, args...) 48#define DPRINTK(fmt, args...)
49#endif 49#endif
50 50
51#define FBMON_FIX_HEADER 1 51#define FBMON_FIX_HEADER 1
52#define FBMON_FIX_INPUT 2 52#define FBMON_FIX_INPUT 2
53#define FBMON_FIX_TIMINGS 3
53 54
54#ifdef CONFIG_FB_MODE_HELPERS 55#ifdef CONFIG_FB_MODE_HELPERS
55struct broken_edid { 56struct broken_edid {
@@ -71,6 +72,12 @@ static const struct broken_edid brokendb[] = {
71 .model = 0x5a44, 72 .model = 0x5a44,
72 .fix = FBMON_FIX_INPUT, 73 .fix = FBMON_FIX_INPUT,
73 }, 74 },
75 /* Sharp UXGA? */
76 {
77 .manufacturer = "SHP",
78 .model = 0x138e,
79 .fix = FBMON_FIX_TIMINGS,
80 },
74}; 81};
75 82
76static const unsigned char edid_v1_header[] = { 0x00, 0xff, 0xff, 0xff, 83static const unsigned char edid_v1_header[] = { 0x00, 0xff, 0xff, 0xff,
@@ -87,6 +94,55 @@ static void copy_string(unsigned char *c, unsigned char *s)
87 while (i-- && (*--s == 0x20)) *s = 0; 94 while (i-- && (*--s == 0x20)) *s = 0;
88} 95}
89 96
97static int edid_is_serial_block(unsigned char *block)
98{
99 if ((block[0] == 0x00) && (block[1] == 0x00) &&
100 (block[2] == 0x00) && (block[3] == 0xff) &&
101 (block[4] == 0x00))
102 return 1;
103 else
104 return 0;
105}
106
107static int edid_is_ascii_block(unsigned char *block)
108{
109 if ((block[0] == 0x00) && (block[1] == 0x00) &&
110 (block[2] == 0x00) && (block[3] == 0xfe) &&
111 (block[4] == 0x00))
112 return 1;
113 else
114 return 0;
115}
116
117static int edid_is_limits_block(unsigned char *block)
118{
119 if ((block[0] == 0x00) && (block[1] == 0x00) &&
120 (block[2] == 0x00) && (block[3] == 0xfd) &&
121 (block[4] == 0x00))
122 return 1;
123 else
124 return 0;
125}
126
127static int edid_is_monitor_block(unsigned char *block)
128{
129 if ((block[0] == 0x00) && (block[1] == 0x00) &&
130 (block[2] == 0x00) && (block[3] == 0xfc) &&
131 (block[4] == 0x00))
132 return 1;
133 else
134 return 0;
135}
136
137static int edid_is_timing_block(unsigned char *block)
138{
139 if ((block[0] != 0x00) || (block[1] != 0x00) ||
140 (block[2] != 0x00) || (block[4] != 0x00))
141 return 1;
142 else
143 return 0;
144}
145
90static int check_edid(unsigned char *edid) 146static int check_edid(unsigned char *edid)
91{ 147{
92 unsigned char *block = edid + ID_MANUFACTURER_NAME, manufacturer[4]; 148 unsigned char *block = edid + ID_MANUFACTURER_NAME, manufacturer[4];
@@ -104,9 +160,6 @@ static int check_edid(unsigned char *edid)
104 for (i = 0; i < ARRAY_SIZE(brokendb); i++) { 160 for (i = 0; i < ARRAY_SIZE(brokendb); i++) {
105 if (!strncmp(manufacturer, brokendb[i].manufacturer, 4) && 161 if (!strncmp(manufacturer, brokendb[i].manufacturer, 4) &&
106 brokendb[i].model == model) { 162 brokendb[i].model == model) {
107 printk("fbmon: The EDID Block of "
108 "Manufacturer: %s Model: 0x%x is known to "
109 "be broken,\n", manufacturer, model);
110 fix = brokendb[i].fix; 163 fix = brokendb[i].fix;
111 break; 164 break;
112 } 165 }
@@ -115,8 +168,10 @@ static int check_edid(unsigned char *edid)
115 switch (fix) { 168 switch (fix) {
116 case FBMON_FIX_HEADER: 169 case FBMON_FIX_HEADER:
117 for (i = 0; i < 8; i++) { 170 for (i = 0; i < 8; i++) {
118 if (edid[i] != edid_v1_header[i]) 171 if (edid[i] != edid_v1_header[i]) {
119 ret = fix; 172 ret = fix;
173 break;
174 }
120 } 175 }
121 break; 176 break;
122 case FBMON_FIX_INPUT: 177 case FBMON_FIX_INPUT:
@@ -126,14 +181,34 @@ static int check_edid(unsigned char *edid)
126 if (b[4] & 0x01 && b[0] & 0x80) 181 if (b[4] & 0x01 && b[0] & 0x80)
127 ret = fix; 182 ret = fix;
128 break; 183 break;
184 case FBMON_FIX_TIMINGS:
185 b = edid + DETAILED_TIMING_DESCRIPTIONS_START;
186 ret = fix;
187
188 for (i = 0; i < 4; i++) {
189 if (edid_is_limits_block(b)) {
190 ret = 0;
191 break;
192 }
193
194 b += DETAILED_TIMING_DESCRIPTION_SIZE;
195 }
196
197 break;
129 } 198 }
130 199
200 if (ret)
201 printk("fbmon: The EDID Block of "
202 "Manufacturer: %s Model: 0x%x is known to "
203 "be broken,\n", manufacturer, model);
204
131 return ret; 205 return ret;
132} 206}
133 207
134static void fix_edid(unsigned char *edid, int fix) 208static void fix_edid(unsigned char *edid, int fix)
135{ 209{
136 unsigned char *b; 210 int i;
211 unsigned char *b, csum = 0;
137 212
138 switch (fix) { 213 switch (fix) {
139 case FBMON_FIX_HEADER: 214 case FBMON_FIX_HEADER:
@@ -145,6 +220,37 @@ static void fix_edid(unsigned char *edid, int fix)
145 b = edid + EDID_STRUCT_DISPLAY; 220 b = edid + EDID_STRUCT_DISPLAY;
146 b[0] &= ~0x80; 221 b[0] &= ~0x80;
147 edid[127] += 0x80; 222 edid[127] += 0x80;
223 break;
224 case FBMON_FIX_TIMINGS:
225 printk("fbmon: trying to fix monitor timings\n");
226 b = edid + DETAILED_TIMING_DESCRIPTIONS_START;
227 for (i = 0; i < 4; i++) {
228 if (!(edid_is_serial_block(b) ||
229 edid_is_ascii_block(b) ||
230 edid_is_monitor_block(b) ||
231 edid_is_timing_block(b))) {
232 b[0] = 0x00;
233 b[1] = 0x00;
234 b[2] = 0x00;
235 b[3] = 0xfd;
236 b[4] = 0x00;
237 b[5] = 60; /* vfmin */
238 b[6] = 60; /* vfmax */
239 b[7] = 30; /* hfmin */
240 b[8] = 75; /* hfmax */
241 b[9] = 17; /* pixclock - 170 MHz*/
242 b[10] = 0; /* GTF */
243 break;
244 }
245
246 b += DETAILED_TIMING_DESCRIPTION_SIZE;
247 }
248
249 for (i = 0; i < EDID_LENGTH - 1; i++)
250 csum += edid[i];
251
252 edid[127] = 256 - csum;
253 break;
148 } 254 }
149} 255}
150 256
@@ -273,46 +379,6 @@ static void get_chroma(unsigned char *block, struct fb_monspecs *specs)
273 DPRINTK("WhiteY: 0.%03d\n", specs->chroma.whitey); 379 DPRINTK("WhiteY: 0.%03d\n", specs->chroma.whitey);
274} 380}
275 381
276static int edid_is_serial_block(unsigned char *block)
277{
278 if ((block[0] == 0x00) && (block[1] == 0x00) &&
279 (block[2] == 0x00) && (block[3] == 0xff) &&
280 (block[4] == 0x00))
281 return 1;
282 else
283 return 0;
284}
285
286static int edid_is_ascii_block(unsigned char *block)
287{
288 if ((block[0] == 0x00) && (block[1] == 0x00) &&
289 (block[2] == 0x00) && (block[3] == 0xfe) &&
290 (block[4] == 0x00))
291 return 1;
292 else
293 return 0;
294}
295
296static int edid_is_limits_block(unsigned char *block)
297{
298 if ((block[0] == 0x00) && (block[1] == 0x00) &&
299 (block[2] == 0x00) && (block[3] == 0xfd) &&
300 (block[4] == 0x00))
301 return 1;
302 else
303 return 0;
304}
305
306static int edid_is_monitor_block(unsigned char *block)
307{
308 if ((block[0] == 0x00) && (block[1] == 0x00) &&
309 (block[2] == 0x00) && (block[3] == 0xfc) &&
310 (block[4] == 0x00))
311 return 1;
312 else
313 return 0;
314}
315
316static void calc_mode_timings(int xres, int yres, int refresh, 382static void calc_mode_timings(int xres, int yres, int refresh,
317 struct fb_videomode *mode) 383 struct fb_videomode *mode)
318{ 384{
@@ -795,15 +861,6 @@ static void get_monspecs(unsigned char *edid, struct fb_monspecs *specs)
795 } 861 }
796} 862}
797 863
798static int edid_is_timing_block(unsigned char *block)
799{
800 if ((block[0] != 0x00) || (block[1] != 0x00) ||
801 (block[2] != 0x00) || (block[4] != 0x00))
802 return 1;
803 else
804 return 0;
805}
806
807int fb_parse_edid(unsigned char *edid, struct fb_var_screeninfo *var) 864int fb_parse_edid(unsigned char *edid, struct fb_var_screeninfo *var)
808{ 865{
809 int i; 866 int i;
diff --git a/drivers/video/fbsysfs.c b/drivers/video/fbsysfs.c
index 40c80c8190e2..d4a2c11d9809 100644
--- a/drivers/video/fbsysfs.c
+++ b/drivers/video/fbsysfs.c
@@ -376,7 +376,7 @@ static ssize_t show_pan(struct device *device,
376{ 376{
377 struct fb_info *fb_info = dev_get_drvdata(device); 377 struct fb_info *fb_info = dev_get_drvdata(device);
378 return snprintf(buf, PAGE_SIZE, "%d,%d\n", fb_info->var.xoffset, 378 return snprintf(buf, PAGE_SIZE, "%d,%d\n", fb_info->var.xoffset,
379 fb_info->var.xoffset); 379 fb_info->var.yoffset);
380} 380}
381 381
382static ssize_t show_name(struct device *device, 382static ssize_t show_name(struct device *device,
diff --git a/drivers/video/hecubafb.c b/drivers/video/hecubafb.c
new file mode 100644
index 000000000000..abfcb50364c8
--- /dev/null
+++ b/drivers/video/hecubafb.c
@@ -0,0 +1,471 @@
1/*
2 * linux/drivers/video/hecubafb.c -- FB driver for Hecuba controller
3 *
4 * Copyright (C) 2006, Jaya Kumar
5 * This work was sponsored by CIS(M) Sdn Bhd
6 *
7 * This file is subject to the terms and conditions of the GNU General Public
8 * License. See the file COPYING in the main directory of this archive for
9 * more details.
10 *
11 * Layout is based on skeletonfb.c by James Simmons and Geert Uytterhoeven.
12 * This work was possible because of apollo display code from E-Ink's website
13 * http://support.eink.com/community
14 * All information used to write this code is from public material made
15 * available by E-Ink on its support site. Some commands such as 0xA4
16 * were found by looping through cmd=0x00 thru 0xFF and supplying random
17 * values. There are other commands that the display is capable of,
18 * beyond the 5 used here but they are more complex.
19 *
20 * This driver is written to be used with the Hecuba display controller
21 * board, and tested with the EInk 800x600 display in 1 bit mode.
22 * The interface between Hecuba and the host is TTL based GPIO. The
23 * GPIO requirements are 8 writable data lines and 6 lines for control.
24 * Only 4 of the controls are actually used here but 6 for future use.
25 * The driver requires the IO addresses for data and control GPIO at
26 * load time. It is also possible to use this display with a standard
27 * PC parallel port.
28 *
29 * General notes:
30 * - User must set hecubafb_enable=1 to enable it
31 * - User must set dio_addr=0xIOADDR cio_addr=0xIOADDR c2io_addr=0xIOADDR
32 *
33 */
34
35#include <linux/module.h>
36#include <linux/kernel.h>
37#include <linux/errno.h>
38#include <linux/string.h>
39#include <linux/mm.h>
40#include <linux/slab.h>
41#include <linux/vmalloc.h>
42#include <linux/delay.h>
43#include <linux/interrupt.h>
44#include <linux/fb.h>
45#include <linux/init.h>
46#include <linux/platform_device.h>
47#include <linux/list.h>
48#include <asm/uaccess.h>
49
50/* Apollo controller specific defines */
51#define APOLLO_START_NEW_IMG 0xA0
52#define APOLLO_STOP_IMG_DATA 0xA1
53#define APOLLO_DISPLAY_IMG 0xA2
54#define APOLLO_ERASE_DISPLAY 0xA3
55#define APOLLO_INIT_DISPLAY 0xA4
56
57/* Hecuba interface specific defines */
58/* WUP is inverted, CD is inverted, DS is inverted */
59#define HCB_NWUP_BIT 0x01
60#define HCB_NDS_BIT 0x02
61#define HCB_RW_BIT 0x04
62#define HCB_NCD_BIT 0x08
63#define HCB_ACK_BIT 0x80
64
65/* Display specific information */
66#define DPY_W 600
67#define DPY_H 800
68
69struct hecubafb_par {
70 unsigned long dio_addr;
71 unsigned long cio_addr;
72 unsigned long c2io_addr;
73 unsigned char ctl;
74 struct fb_info *info;
75 unsigned int irq;
76};
77
78static struct fb_fix_screeninfo hecubafb_fix __devinitdata = {
79 .id = "hecubafb",
80 .type = FB_TYPE_PACKED_PIXELS,
81 .visual = FB_VISUAL_MONO01,
82 .xpanstep = 0,
83 .ypanstep = 0,
84 .ywrapstep = 0,
85 .accel = FB_ACCEL_NONE,
86};
87
88static struct fb_var_screeninfo hecubafb_var __devinitdata = {
89 .xres = DPY_W,
90 .yres = DPY_H,
91 .xres_virtual = DPY_W,
92 .yres_virtual = DPY_H,
93 .bits_per_pixel = 1,
94 .nonstd = 1,
95};
96
97static unsigned long dio_addr;
98static unsigned long cio_addr;
99static unsigned long c2io_addr;
100static unsigned long splashval;
101static unsigned int nosplash;
102static unsigned int hecubafb_enable;
103static unsigned int irq;
104
105static DECLARE_WAIT_QUEUE_HEAD(hecubafb_waitq);
106
107static void hcb_set_ctl(struct hecubafb_par *par)
108{
109 outb(par->ctl, par->cio_addr);
110}
111
112static unsigned char hcb_get_ctl(struct hecubafb_par *par)
113{
114 return inb(par->c2io_addr);
115}
116
117static void hcb_set_data(struct hecubafb_par *par, unsigned char value)
118{
119 outb(value, par->dio_addr);
120}
121
122static int __devinit apollo_init_control(struct hecubafb_par *par)
123{
124 unsigned char ctl;
125 /* for init, we want the following setup to be set:
126 WUP = lo
127 ACK = hi
128 DS = hi
129 RW = hi
130 CD = lo
131 */
132
133 /* write WUP to lo, DS to hi, RW to hi, CD to lo */
134 par->ctl = HCB_NWUP_BIT | HCB_RW_BIT | HCB_NCD_BIT ;
135 par->ctl &= ~HCB_NDS_BIT;
136 hcb_set_ctl(par);
137
138 /* check ACK is not lo */
139 ctl = hcb_get_ctl(par);
140 if ((ctl & HCB_ACK_BIT)) {
141 printk(KERN_ERR "Fail because ACK is already low\n");
142 return -ENXIO;
143 }
144
145 return 0;
146}
147
148static void hcb_wait_for_ack(struct hecubafb_par *par)
149{
150
151 int timeout;
152 unsigned char ctl;
153
154 timeout=500;
155 do {
156 ctl = hcb_get_ctl(par);
157 if ((ctl & HCB_ACK_BIT))
158 return;
159 udelay(1);
160 } while (timeout--);
161 printk(KERN_ERR "timed out waiting for ack\n");
162}
163
164static void hcb_wait_for_ack_clear(struct hecubafb_par *par)
165{
166
167 int timeout;
168 unsigned char ctl;
169
170 timeout=500;
171 do {
172 ctl = hcb_get_ctl(par);
173 if (!(ctl & HCB_ACK_BIT))
174 return;
175 udelay(1);
176 } while (timeout--);
177 printk(KERN_ERR "timed out waiting for clear\n");
178}
179
180static void apollo_send_data(struct hecubafb_par *par, unsigned char data)
181{
182 /* set data */
183 hcb_set_data(par, data);
184
185 /* set DS low */
186 par->ctl |= HCB_NDS_BIT;
187 hcb_set_ctl(par);
188
189 hcb_wait_for_ack(par);
190
191 /* set DS hi */
192 par->ctl &= ~(HCB_NDS_BIT);
193 hcb_set_ctl(par);
194
195 hcb_wait_for_ack_clear(par);
196}
197
198static void apollo_send_command(struct hecubafb_par *par, unsigned char data)
199{
200 /* command so set CD to high */
201 par->ctl &= ~(HCB_NCD_BIT);
202 hcb_set_ctl(par);
203
204 /* actually strobe with command */
205 apollo_send_data(par, data);
206
207 /* clear CD back to low */
208 par->ctl |= (HCB_NCD_BIT);
209 hcb_set_ctl(par);
210}
211
212/* main hecubafb functions */
213
214static void hecubafb_dpy_update(struct hecubafb_par *par)
215{
216 int i;
217 unsigned char *buf = (unsigned char __force *)par->info->screen_base;
218
219 apollo_send_command(par, 0xA0);
220
221 for (i=0; i < (DPY_W*DPY_H/8); i++) {
222 apollo_send_data(par, *(buf++));
223 }
224
225 apollo_send_command(par, 0xA1);
226 apollo_send_command(par, 0xA2);
227}
228
229/* this is called back from the deferred io workqueue */
230static void hecubafb_dpy_deferred_io(struct fb_info *info,
231 struct list_head *pagelist)
232{
233 hecubafb_dpy_update(info->par);
234}
235
236static void hecubafb_fillrect(struct fb_info *info,
237 const struct fb_fillrect *rect)
238{
239 struct hecubafb_par *par = info->par;
240
241 sys_fillrect(info, rect);
242
243 hecubafb_dpy_update(par);
244}
245
246static void hecubafb_copyarea(struct fb_info *info,
247 const struct fb_copyarea *area)
248{
249 struct hecubafb_par *par = info->par;
250
251 sys_copyarea(info, area);
252
253 hecubafb_dpy_update(par);
254}
255
256static void hecubafb_imageblit(struct fb_info *info,
257 const struct fb_image *image)
258{
259 struct hecubafb_par *par = info->par;
260
261 sys_imageblit(info, image);
262
263 hecubafb_dpy_update(par);
264}
265
266/*
267 * this is the slow path from userspace. they can seek and write to
268 * the fb. it's inefficient to do anything less than a full screen draw
269 */
270static ssize_t hecubafb_write(struct fb_info *info, const char __user *buf,
271 size_t count, loff_t *ppos)
272{
273 unsigned long p;
274 int err=-EINVAL;
275 struct hecubafb_par *par;
276 unsigned int xres;
277 unsigned int fbmemlength;
278
279 p = *ppos;
280 par = info->par;
281 xres = info->var.xres;
282 fbmemlength = (xres * info->var.yres)/8;
283
284 if (p > fbmemlength)
285 return -ENOSPC;
286
287 err = 0;
288 if ((count + p) > fbmemlength) {
289 count = fbmemlength - p;
290 err = -ENOSPC;
291 }
292
293 if (count) {
294 char *base_addr;
295
296 base_addr = (char __force *)info->screen_base;
297 count -= copy_from_user(base_addr + p, buf, count);
298 *ppos += count;
299 err = -EFAULT;
300 }
301
302 hecubafb_dpy_update(par);
303
304 if (count)
305 return count;
306
307 return err;
308}
309
310static struct fb_ops hecubafb_ops = {
311 .owner = THIS_MODULE,
312 .fb_read = fb_sys_read,
313 .fb_write = hecubafb_write,
314 .fb_fillrect = hecubafb_fillrect,
315 .fb_copyarea = hecubafb_copyarea,
316 .fb_imageblit = hecubafb_imageblit,
317};
318
319static struct fb_deferred_io hecubafb_defio = {
320 .delay = HZ,
321 .deferred_io = hecubafb_dpy_deferred_io,
322};
323
324static int __devinit hecubafb_probe(struct platform_device *dev)
325{
326 struct fb_info *info;
327 int retval = -ENOMEM;
328 int videomemorysize;
329 unsigned char *videomemory;
330 struct hecubafb_par *par;
331
332 videomemorysize = (DPY_W*DPY_H)/8;
333
334 if (!(videomemory = vmalloc(videomemorysize)))
335 return retval;
336
337 memset(videomemory, 0, videomemorysize);
338
339 info = framebuffer_alloc(sizeof(struct hecubafb_par), &dev->dev);
340 if (!info)
341 goto err;
342
343 info->screen_base = (char __iomem *) videomemory;
344 info->fbops = &hecubafb_ops;
345
346 info->var = hecubafb_var;
347 info->fix = hecubafb_fix;
348 info->fix.smem_len = videomemorysize;
349 par = info->par;
350 par->info = info;
351
352 if (!dio_addr || !cio_addr || !c2io_addr) {
353 printk(KERN_WARNING "no IO addresses supplied\n");
354 goto err1;
355 }
356 par->dio_addr = dio_addr;
357 par->cio_addr = cio_addr;
358 par->c2io_addr = c2io_addr;
359 info->flags = FBINFO_FLAG_DEFAULT;
360
361 info->fbdefio = &hecubafb_defio;
362 fb_deferred_io_init(info);
363
364 retval = register_framebuffer(info);
365 if (retval < 0)
366 goto err1;
367 platform_set_drvdata(dev, info);
368
369 printk(KERN_INFO
370 "fb%d: Hecuba frame buffer device, using %dK of video memory\n",
371 info->node, videomemorysize >> 10);
372
373 /* this inits the dpy */
374 apollo_init_control(par);
375
376 apollo_send_command(par, APOLLO_INIT_DISPLAY);
377 apollo_send_data(par, 0x81);
378
379 /* have to wait while display resets */
380 udelay(1000);
381
382 /* if we were told to splash the screen, we just clear it */
383 if (!nosplash) {
384 apollo_send_command(par, APOLLO_ERASE_DISPLAY);
385 apollo_send_data(par, splashval);
386 }
387
388 return 0;
389err1:
390 framebuffer_release(info);
391err:
392 vfree(videomemory);
393 return retval;
394}
395
396static int __devexit hecubafb_remove(struct platform_device *dev)
397{
398 struct fb_info *info = platform_get_drvdata(dev);
399
400 if (info) {
401 fb_deferred_io_cleanup(info);
402 unregister_framebuffer(info);
403 vfree((void __force *)info->screen_base);
404 framebuffer_release(info);
405 }
406 return 0;
407}
408
409static struct platform_driver hecubafb_driver = {
410 .probe = hecubafb_probe,
411 .remove = hecubafb_remove,
412 .driver = {
413 .name = "hecubafb",
414 },
415};
416
417static struct platform_device *hecubafb_device;
418
419static int __init hecubafb_init(void)
420{
421 int ret;
422
423 if (!hecubafb_enable) {
424 printk(KERN_ERR "Use hecubafb_enable to enable the device\n");
425 return -ENXIO;
426 }
427
428 ret = platform_driver_register(&hecubafb_driver);
429 if (!ret) {
430 hecubafb_device = platform_device_alloc("hecubafb", 0);
431 if (hecubafb_device)
432 ret = platform_device_add(hecubafb_device);
433 else
434 ret = -ENOMEM;
435
436 if (ret) {
437 platform_device_put(hecubafb_device);
438 platform_driver_unregister(&hecubafb_driver);
439 }
440 }
441 return ret;
442
443}
444
445static void __exit hecubafb_exit(void)
446{
447 platform_device_unregister(hecubafb_device);
448 platform_driver_unregister(&hecubafb_driver);
449}
450
451module_param(nosplash, uint, 0);
452MODULE_PARM_DESC(nosplash, "Disable doing the splash screen");
453module_param(hecubafb_enable, uint, 0);
454MODULE_PARM_DESC(hecubafb_enable, "Enable communication with Hecuba board");
455module_param(dio_addr, ulong, 0);
456MODULE_PARM_DESC(dio_addr, "IO address for data, eg: 0x480");
457module_param(cio_addr, ulong, 0);
458MODULE_PARM_DESC(cio_addr, "IO address for control, eg: 0x400");
459module_param(c2io_addr, ulong, 0);
460MODULE_PARM_DESC(c2io_addr, "IO address for secondary control, eg: 0x408");
461module_param(splashval, ulong, 0);
462MODULE_PARM_DESC(splashval, "Splash pattern: 0x00 is black, 0x01 is white");
463module_param(irq, uint, 0);
464MODULE_PARM_DESC(irq, "IRQ for the Hecuba board");
465
466module_init(hecubafb_init);
467module_exit(hecubafb_exit);
468
469MODULE_DESCRIPTION("fbdev driver for Hecuba board");
470MODULE_AUTHOR("Jaya Kumar");
471MODULE_LICENSE("GPL");
diff --git a/drivers/video/i810/i810.h b/drivers/video/i810/i810.h
index aa65ffce915b..889e4ea5edc1 100644
--- a/drivers/video/i810/i810.h
+++ b/drivers/video/i810/i810.h
@@ -133,7 +133,7 @@
133/* Masks (AND ops) and OR's */ 133/* Masks (AND ops) and OR's */
134#define FB_START_MASK (0x3f << (32 - 6)) 134#define FB_START_MASK (0x3f << (32 - 6))
135#define MMIO_ADDR_MASK (0x1FFF << (32 - 13)) 135#define MMIO_ADDR_MASK (0x1FFF << (32 - 13))
136#define FREQ_MASK 0x1EF 136#define FREQ_MASK (1 << 4)
137#define SCR_OFF 0x20 137#define SCR_OFF 0x20
138#define DRAM_ON 0x08 138#define DRAM_ON 0x08
139#define DRAM_OFF 0xE7 139#define DRAM_OFF 0xE7
diff --git a/drivers/video/intelfb/intelfbhw.c b/drivers/video/intelfb/intelfbhw.c
index c1eb18bf0883..16bc8d75e36e 100644
--- a/drivers/video/intelfb/intelfbhw.c
+++ b/drivers/video/intelfb/intelfbhw.c
@@ -1428,6 +1428,24 @@ static void refresh_ring(struct intelfb_info *dinfo);
1428static void reset_state(struct intelfb_info *dinfo); 1428static void reset_state(struct intelfb_info *dinfo);
1429static void do_flush(struct intelfb_info *dinfo); 1429static void do_flush(struct intelfb_info *dinfo);
1430 1430
1431static u32 get_ring_space(struct intelfb_info *dinfo)
1432{
1433 u32 ring_space;
1434
1435 if (dinfo->ring_tail >= dinfo->ring_head)
1436 ring_space = dinfo->ring.size -
1437 (dinfo->ring_tail - dinfo->ring_head);
1438 else
1439 ring_space = dinfo->ring_head - dinfo->ring_tail;
1440
1441 if (ring_space > RING_MIN_FREE)
1442 ring_space -= RING_MIN_FREE;
1443 else
1444 ring_space = 0;
1445
1446 return ring_space;
1447}
1448
1431static int 1449static int
1432wait_ring(struct intelfb_info *dinfo, int n) 1450wait_ring(struct intelfb_info *dinfo, int n)
1433{ 1451{
@@ -1442,13 +1460,8 @@ wait_ring(struct intelfb_info *dinfo, int n)
1442 end = jiffies + (HZ * 3); 1460 end = jiffies + (HZ * 3);
1443 while (dinfo->ring_space < n) { 1461 while (dinfo->ring_space < n) {
1444 dinfo->ring_head = INREG(PRI_RING_HEAD) & RING_HEAD_MASK; 1462 dinfo->ring_head = INREG(PRI_RING_HEAD) & RING_HEAD_MASK;
1445 if (dinfo->ring_tail + RING_MIN_FREE < dinfo->ring_head) 1463 dinfo->ring_space = get_ring_space(dinfo);
1446 dinfo->ring_space = dinfo->ring_head 1464
1447 - (dinfo->ring_tail + RING_MIN_FREE);
1448 else
1449 dinfo->ring_space = (dinfo->ring.size +
1450 dinfo->ring_head)
1451 - (dinfo->ring_tail + RING_MIN_FREE);
1452 if (dinfo->ring_head != last_head) { 1465 if (dinfo->ring_head != last_head) {
1453 end = jiffies + (HZ * 3); 1466 end = jiffies + (HZ * 3);
1454 last_head = dinfo->ring_head; 1467 last_head = dinfo->ring_head;
@@ -1513,12 +1526,7 @@ refresh_ring(struct intelfb_info *dinfo)
1513 1526
1514 dinfo->ring_head = INREG(PRI_RING_HEAD) & RING_HEAD_MASK; 1527 dinfo->ring_head = INREG(PRI_RING_HEAD) & RING_HEAD_MASK;
1515 dinfo->ring_tail = INREG(PRI_RING_TAIL) & RING_TAIL_MASK; 1528 dinfo->ring_tail = INREG(PRI_RING_TAIL) & RING_TAIL_MASK;
1516 if (dinfo->ring_tail + RING_MIN_FREE < dinfo->ring_head) 1529 dinfo->ring_space = get_ring_space(dinfo);
1517 dinfo->ring_space = dinfo->ring_head
1518 - (dinfo->ring_tail + RING_MIN_FREE);
1519 else
1520 dinfo->ring_space = (dinfo->ring.size + dinfo->ring_head)
1521 - (dinfo->ring_tail + RING_MIN_FREE);
1522} 1530}
1523 1531
1524static void 1532static void
diff --git a/drivers/video/logo/Kconfig b/drivers/video/logo/Kconfig
index f0e6512c87ff..9397bcef3018 100644
--- a/drivers/video/logo/Kconfig
+++ b/drivers/video/logo/Kconfig
@@ -2,73 +2,69 @@
2# Logo configuration 2# Logo configuration
3# 3#
4 4
5menu "Logo configuration" 5menuconfig LOGO
6
7config LOGO
8 bool "Bootup logo" 6 bool "Bootup logo"
9 depends on FB || SGI_NEWPORT_CONSOLE 7 depends on FB || SGI_NEWPORT_CONSOLE
10 help 8 help
11 Enable and select frame buffer bootup logos. 9 Enable and select frame buffer bootup logos.
12 10
11if LOGO
12
13config LOGO_LINUX_MONO 13config LOGO_LINUX_MONO
14 bool "Standard black and white Linux logo" 14 bool "Standard black and white Linux logo"
15 depends on LOGO
16 default y 15 default y
17 16
18config LOGO_LINUX_VGA16 17config LOGO_LINUX_VGA16
19 bool "Standard 16-color Linux logo" 18 bool "Standard 16-color Linux logo"
20 depends on LOGO
21 default y 19 default y
22 20
23config LOGO_LINUX_CLUT224 21config LOGO_LINUX_CLUT224
24 bool "Standard 224-color Linux logo" 22 bool "Standard 224-color Linux logo"
25 depends on LOGO
26 default y 23 default y
27 24
28config LOGO_DEC_CLUT224 25config LOGO_DEC_CLUT224
29 bool "224-color Digital Equipment Corporation Linux logo" 26 bool "224-color Digital Equipment Corporation Linux logo"
30 depends on LOGO && (MACH_DECSTATION || ALPHA) 27 depends on MACH_DECSTATION || ALPHA
31 default y 28 default y
32 29
33config LOGO_MAC_CLUT224 30config LOGO_MAC_CLUT224
34 bool "224-color Macintosh Linux logo" 31 bool "224-color Macintosh Linux logo"
35 depends on LOGO && MAC 32 depends on MAC
36 default y 33 default y
37 34
38config LOGO_PARISC_CLUT224 35config LOGO_PARISC_CLUT224
39 bool "224-color PA-RISC Linux logo" 36 bool "224-color PA-RISC Linux logo"
40 depends on LOGO && PARISC 37 depends on PARISC
41 default y 38 default y
42 39
43config LOGO_SGI_CLUT224 40config LOGO_SGI_CLUT224
44 bool "224-color SGI Linux logo" 41 bool "224-color SGI Linux logo"
45 depends on LOGO && (SGI_IP22 || SGI_IP27 || SGI_IP32 || X86_VISWS) 42 depends on SGI_IP22 || SGI_IP27 || SGI_IP32 || X86_VISWS
46 default y 43 default y
47 44
48config LOGO_SUN_CLUT224 45config LOGO_SUN_CLUT224
49 bool "224-color Sun Linux logo" 46 bool "224-color Sun Linux logo"
50 depends on LOGO && SPARC 47 depends on SPARC
51 default y 48 default y
52 49
53config LOGO_SUPERH_MONO 50config LOGO_SUPERH_MONO
54 bool "Black and white SuperH Linux logo" 51 bool "Black and white SuperH Linux logo"
55 depends on LOGO && SUPERH 52 depends on SUPERH
56 default y 53 default y
57 54
58config LOGO_SUPERH_VGA16 55config LOGO_SUPERH_VGA16
59 bool "16-color SuperH Linux logo" 56 bool "16-color SuperH Linux logo"
60 depends on LOGO && SUPERH 57 depends on SUPERH
61 default y 58 default y
62 59
63config LOGO_SUPERH_CLUT224 60config LOGO_SUPERH_CLUT224
64 bool "224-color SuperH Linux logo" 61 bool "224-color SuperH Linux logo"
65 depends on LOGO && SUPERH 62 depends on SUPERH
66 default y 63 default y
67 64
68config LOGO_M32R_CLUT224 65config LOGO_M32R_CLUT224
69 bool "224-color M32R Linux logo" 66 bool "224-color M32R Linux logo"
70 depends on LOGO && M32R 67 depends on M32R
71 default y 68 default y
72 69
73endmenu 70endif # LOGO
74
diff --git a/drivers/video/modedb.c b/drivers/video/modedb.c
index 3e517940c5a5..3741ad729401 100644
--- a/drivers/video/modedb.c
+++ b/drivers/video/modedb.c
@@ -395,7 +395,7 @@ static int my_atoi(const char *name)
395 395
396 for (;; name++) { 396 for (;; name++) {
397 switch (*name) { 397 switch (*name) {
398 case '0'...'9': 398 case '0' ... '9':
399 val = 10*val+(*name-'0'); 399 val = 10*val+(*name-'0');
400 break; 400 break;
401 default: 401 default:
@@ -548,7 +548,7 @@ int fb_find_mode(struct fb_var_screeninfo *var,
548 } else 548 } else
549 goto done; 549 goto done;
550 break; 550 break;
551 case '0'...'9': 551 case '0' ... '9':
552 break; 552 break;
553 case 'M': 553 case 'M':
554 if (!yres_specified) 554 if (!yres_specified)
diff --git a/drivers/video/neofb.c b/drivers/video/neofb.c
index 395ccedde9a6..bd30aba242d0 100644
--- a/drivers/video/neofb.c
+++ b/drivers/video/neofb.c
@@ -665,6 +665,7 @@ neofb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
665 var->red.msb_right = 0; 665 var->red.msb_right = 0;
666 var->green.msb_right = 0; 666 var->green.msb_right = 0;
667 var->blue.msb_right = 0; 667 var->blue.msb_right = 0;
668 var->transp.msb_right = 0;
668 669
669 switch (var->bits_per_pixel) { 670 switch (var->bits_per_pixel) {
670 case 8: /* PSEUDOCOLOUR, 256 */ 671 case 8: /* PSEUDOCOLOUR, 256 */
diff --git a/drivers/video/nvidia/nv_accel.c b/drivers/video/nvidia/nv_accel.c
index 9efb8a3854e2..fa4821c5572b 100644
--- a/drivers/video/nvidia/nv_accel.c
+++ b/drivers/video/nvidia/nv_accel.c
@@ -69,27 +69,38 @@ static const int NVCopyROP_PM[16] = {
69 0x5A, /* invert */ 69 0x5A, /* invert */
70}; 70};
71 71
72static inline void NVFlush(struct nvidia_par *par) 72static inline void nvidiafb_safe_mode(struct fb_info *info)
73{ 73{
74 struct nvidia_par *par = info->par;
75
76 touch_softlockup_watchdog();
77 info->pixmap.scan_align = 1;
78 par->lockup = 1;
79}
80
81static inline void NVFlush(struct fb_info *info)
82{
83 struct nvidia_par *par = info->par;
74 int count = 1000000000; 84 int count = 1000000000;
75 85
76 while (--count && READ_GET(par) != par->dmaPut) ; 86 while (--count && READ_GET(par) != par->dmaPut) ;
77 87
78 if (!count) { 88 if (!count) {
79 printk("nvidiafb: DMA Flush lockup\n"); 89 printk("nvidiafb: DMA Flush lockup\n");
80 par->lockup = 1; 90 nvidiafb_safe_mode(info);
81 } 91 }
82} 92}
83 93
84static inline void NVSync(struct nvidia_par *par) 94static inline void NVSync(struct fb_info *info)
85{ 95{
96 struct nvidia_par *par = info->par;
86 int count = 1000000000; 97 int count = 1000000000;
87 98
88 while (--count && NV_RD32(par->PGRAPH, 0x0700)) ; 99 while (--count && NV_RD32(par->PGRAPH, 0x0700)) ;
89 100
90 if (!count) { 101 if (!count) {
91 printk("nvidiafb: DMA Sync lockup\n"); 102 printk("nvidiafb: DMA Sync lockup\n");
92 par->lockup = 1; 103 nvidiafb_safe_mode(info);
93 } 104 }
94} 105}
95 106
@@ -101,8 +112,9 @@ static void NVDmaKickoff(struct nvidia_par *par)
101 } 112 }
102} 113}
103 114
104static void NVDmaWait(struct nvidia_par *par, int size) 115static void NVDmaWait(struct fb_info *info, int size)
105{ 116{
117 struct nvidia_par *par = info->par;
106 int dmaGet; 118 int dmaGet;
107 int count = 1000000000, cnt; 119 int count = 1000000000, cnt;
108 size++; 120 size++;
@@ -135,34 +147,38 @@ static void NVDmaWait(struct nvidia_par *par, int size)
135 } 147 }
136 148
137 if (!count) { 149 if (!count) {
138 printk("DMA Wait Lockup\n"); 150 printk("nvidiafb: DMA Wait Lockup\n");
139 par->lockup = 1; 151 nvidiafb_safe_mode(info);
140 } 152 }
141} 153}
142 154
143static void NVSetPattern(struct nvidia_par *par, u32 clr0, u32 clr1, 155static void NVSetPattern(struct fb_info *info, u32 clr0, u32 clr1,
144 u32 pat0, u32 pat1) 156 u32 pat0, u32 pat1)
145{ 157{
146 NVDmaStart(par, PATTERN_COLOR_0, 4); 158 struct nvidia_par *par = info->par;
159
160 NVDmaStart(info, par, PATTERN_COLOR_0, 4);
147 NVDmaNext(par, clr0); 161 NVDmaNext(par, clr0);
148 NVDmaNext(par, clr1); 162 NVDmaNext(par, clr1);
149 NVDmaNext(par, pat0); 163 NVDmaNext(par, pat0);
150 NVDmaNext(par, pat1); 164 NVDmaNext(par, pat1);
151} 165}
152 166
153static void NVSetRopSolid(struct nvidia_par *par, u32 rop, u32 planemask) 167static void NVSetRopSolid(struct fb_info *info, u32 rop, u32 planemask)
154{ 168{
169 struct nvidia_par *par = info->par;
170
155 if (planemask != ~0) { 171 if (planemask != ~0) {
156 NVSetPattern(par, 0, planemask, ~0, ~0); 172 NVSetPattern(info, 0, planemask, ~0, ~0);
157 if (par->currentRop != (rop + 32)) { 173 if (par->currentRop != (rop + 32)) {
158 NVDmaStart(par, ROP_SET, 1); 174 NVDmaStart(info, par, ROP_SET, 1);
159 NVDmaNext(par, NVCopyROP_PM[rop]); 175 NVDmaNext(par, NVCopyROP_PM[rop]);
160 par->currentRop = rop + 32; 176 par->currentRop = rop + 32;
161 } 177 }
162 } else if (par->currentRop != rop) { 178 } else if (par->currentRop != rop) {
163 if (par->currentRop >= 16) 179 if (par->currentRop >= 16)
164 NVSetPattern(par, ~0, ~0, ~0, ~0); 180 NVSetPattern(info, ~0, ~0, ~0, ~0);
165 NVDmaStart(par, ROP_SET, 1); 181 NVDmaStart(info, par, ROP_SET, 1);
166 NVDmaNext(par, NVCopyROP[rop]); 182 NVDmaNext(par, NVCopyROP[rop]);
167 par->currentRop = rop; 183 par->currentRop = rop;
168 } 184 }
@@ -175,7 +191,7 @@ static void NVSetClippingRectangle(struct fb_info *info, int x1, int y1,
175 int h = y2 - y1 + 1; 191 int h = y2 - y1 + 1;
176 int w = x2 - x1 + 1; 192 int w = x2 - x1 + 1;
177 193
178 NVDmaStart(par, CLIP_POINT, 2); 194 NVDmaStart(info, par, CLIP_POINT, 2);
179 NVDmaNext(par, (y1 << 16) | x1); 195 NVDmaNext(par, (y1 << 16) | x1);
180 NVDmaNext(par, (h << 16) | w); 196 NVDmaNext(par, (h << 16) | w);
181} 197}
@@ -237,23 +253,23 @@ void NVResetGraphics(struct fb_info *info)
237 break; 253 break;
238 } 254 }
239 255
240 NVDmaStart(par, SURFACE_FORMAT, 4); 256 NVDmaStart(info, par, SURFACE_FORMAT, 4);
241 NVDmaNext(par, surfaceFormat); 257 NVDmaNext(par, surfaceFormat);
242 NVDmaNext(par, pitch | (pitch << 16)); 258 NVDmaNext(par, pitch | (pitch << 16));
243 NVDmaNext(par, 0); 259 NVDmaNext(par, 0);
244 NVDmaNext(par, 0); 260 NVDmaNext(par, 0);
245 261
246 NVDmaStart(par, PATTERN_FORMAT, 1); 262 NVDmaStart(info, par, PATTERN_FORMAT, 1);
247 NVDmaNext(par, patternFormat); 263 NVDmaNext(par, patternFormat);
248 264
249 NVDmaStart(par, RECT_FORMAT, 1); 265 NVDmaStart(info, par, RECT_FORMAT, 1);
250 NVDmaNext(par, rectFormat); 266 NVDmaNext(par, rectFormat);
251 267
252 NVDmaStart(par, LINE_FORMAT, 1); 268 NVDmaStart(info, par, LINE_FORMAT, 1);
253 NVDmaNext(par, lineFormat); 269 NVDmaNext(par, lineFormat);
254 270
255 par->currentRop = ~0; /* set to something invalid */ 271 par->currentRop = ~0; /* set to something invalid */
256 NVSetRopSolid(par, ROP_COPY, ~0); 272 NVSetRopSolid(info, ROP_COPY, ~0);
257 273
258 NVSetClippingRectangle(info, 0, 0, info->var.xres_virtual, 274 NVSetClippingRectangle(info, 0, 0, info->var.xres_virtual,
259 info->var.yres_virtual); 275 info->var.yres_virtual);
@@ -269,10 +285,10 @@ int nvidiafb_sync(struct fb_info *info)
269 return 0; 285 return 0;
270 286
271 if (!par->lockup) 287 if (!par->lockup)
272 NVFlush(par); 288 NVFlush(info);
273 289
274 if (!par->lockup) 290 if (!par->lockup)
275 NVSync(par); 291 NVSync(info);
276 292
277 return 0; 293 return 0;
278} 294}
@@ -287,7 +303,7 @@ void nvidiafb_copyarea(struct fb_info *info, const struct fb_copyarea *region)
287 if (par->lockup) 303 if (par->lockup)
288 return cfb_copyarea(info, region); 304 return cfb_copyarea(info, region);
289 305
290 NVDmaStart(par, BLIT_POINT_SRC, 3); 306 NVDmaStart(info, par, BLIT_POINT_SRC, 3);
291 NVDmaNext(par, (region->sy << 16) | region->sx); 307 NVDmaNext(par, (region->sy << 16) | region->sx);
292 NVDmaNext(par, (region->dy << 16) | region->dx); 308 NVDmaNext(par, (region->dy << 16) | region->dx);
293 NVDmaNext(par, (region->height << 16) | region->width); 309 NVDmaNext(par, (region->height << 16) | region->width);
@@ -312,19 +328,19 @@ void nvidiafb_fillrect(struct fb_info *info, const struct fb_fillrect *rect)
312 color = ((u32 *) info->pseudo_palette)[rect->color]; 328 color = ((u32 *) info->pseudo_palette)[rect->color];
313 329
314 if (rect->rop != ROP_COPY) 330 if (rect->rop != ROP_COPY)
315 NVSetRopSolid(par, rect->rop, ~0); 331 NVSetRopSolid(info, rect->rop, ~0);
316 332
317 NVDmaStart(par, RECT_SOLID_COLOR, 1); 333 NVDmaStart(info, par, RECT_SOLID_COLOR, 1);
318 NVDmaNext(par, color); 334 NVDmaNext(par, color);
319 335
320 NVDmaStart(par, RECT_SOLID_RECTS(0), 2); 336 NVDmaStart(info, par, RECT_SOLID_RECTS(0), 2);
321 NVDmaNext(par, (rect->dx << 16) | rect->dy); 337 NVDmaNext(par, (rect->dx << 16) | rect->dy);
322 NVDmaNext(par, (rect->width << 16) | rect->height); 338 NVDmaNext(par, (rect->width << 16) | rect->height);
323 339
324 NVDmaKickoff(par); 340 NVDmaKickoff(par);
325 341
326 if (rect->rop != ROP_COPY) 342 if (rect->rop != ROP_COPY)
327 NVSetRopSolid(par, ROP_COPY, ~0); 343 NVSetRopSolid(info, ROP_COPY, ~0);
328} 344}
329 345
330static void nvidiafb_mono_color_expand(struct fb_info *info, 346static void nvidiafb_mono_color_expand(struct fb_info *info,
@@ -346,7 +362,7 @@ static void nvidiafb_mono_color_expand(struct fb_info *info,
346 bg = ((u32 *) info->pseudo_palette)[image->bg_color] | mask; 362 bg = ((u32 *) info->pseudo_palette)[image->bg_color] | mask;
347 } 363 }
348 364
349 NVDmaStart(par, RECT_EXPAND_TWO_COLOR_CLIP, 7); 365 NVDmaStart(info, par, RECT_EXPAND_TWO_COLOR_CLIP, 7);
350 NVDmaNext(par, (image->dy << 16) | (image->dx & 0xffff)); 366 NVDmaNext(par, (image->dy << 16) | (image->dx & 0xffff));
351 NVDmaNext(par, ((image->dy + image->height) << 16) | 367 NVDmaNext(par, ((image->dy + image->height) << 16) |
352 ((image->dx + image->width) & 0xffff)); 368 ((image->dx + image->width) & 0xffff));
@@ -357,7 +373,7 @@ static void nvidiafb_mono_color_expand(struct fb_info *info,
357 NVDmaNext(par, (image->dy << 16) | (image->dx & 0xffff)); 373 NVDmaNext(par, (image->dy << 16) | (image->dx & 0xffff));
358 374
359 while (dsize >= RECT_EXPAND_TWO_COLOR_DATA_MAX_DWORDS) { 375 while (dsize >= RECT_EXPAND_TWO_COLOR_DATA_MAX_DWORDS) {
360 NVDmaStart(par, RECT_EXPAND_TWO_COLOR_DATA(0), 376 NVDmaStart(info, par, RECT_EXPAND_TWO_COLOR_DATA(0),
361 RECT_EXPAND_TWO_COLOR_DATA_MAX_DWORDS); 377 RECT_EXPAND_TWO_COLOR_DATA_MAX_DWORDS);
362 378
363 for (j = RECT_EXPAND_TWO_COLOR_DATA_MAX_DWORDS; j--;) { 379 for (j = RECT_EXPAND_TWO_COLOR_DATA_MAX_DWORDS; j--;) {
@@ -370,7 +386,7 @@ static void nvidiafb_mono_color_expand(struct fb_info *info,
370 } 386 }
371 387
372 if (dsize) { 388 if (dsize) {
373 NVDmaStart(par, RECT_EXPAND_TWO_COLOR_DATA(0), dsize); 389 NVDmaStart(info, par, RECT_EXPAND_TWO_COLOR_DATA(0), dsize);
374 390
375 for (j = dsize; j--;) { 391 for (j = dsize; j--;) {
376 tmp = data[k++]; 392 tmp = data[k++];
diff --git a/drivers/video/nvidia/nv_hw.c b/drivers/video/nvidia/nv_hw.c
index ea426115c6f9..f297c7b14a41 100644
--- a/drivers/video/nvidia/nv_hw.c
+++ b/drivers/video/nvidia/nv_hw.c
@@ -686,7 +686,7 @@ static void nForceUpdateArbitrationSettings(unsigned VClk,
686 686
687 if ((par->Chipset & 0x0FF0) == 0x01A0) { 687 if ((par->Chipset & 0x0FF0) == 0x01A0) {
688 unsigned int uMClkPostDiv; 688 unsigned int uMClkPostDiv;
689 dev = pci_find_slot(0, 3); 689 dev = pci_get_bus_and_slot(0, 3);
690 pci_read_config_dword(dev, 0x6C, &uMClkPostDiv); 690 pci_read_config_dword(dev, 0x6C, &uMClkPostDiv);
691 uMClkPostDiv = (uMClkPostDiv >> 8) & 0xf; 691 uMClkPostDiv = (uMClkPostDiv >> 8) & 0xf;
692 692
@@ -694,11 +694,11 @@ static void nForceUpdateArbitrationSettings(unsigned VClk,
694 uMClkPostDiv = 4; 694 uMClkPostDiv = 4;
695 MClk = 400000 / uMClkPostDiv; 695 MClk = 400000 / uMClkPostDiv;
696 } else { 696 } else {
697 dev = pci_find_slot(0, 5); 697 dev = pci_get_bus_and_slot(0, 5);
698 pci_read_config_dword(dev, 0x4c, &MClk); 698 pci_read_config_dword(dev, 0x4c, &MClk);
699 MClk /= 1000; 699 MClk /= 1000;
700 } 700 }
701 701 pci_dev_put(dev);
702 pll = NV_RD32(par->PRAMDAC0, 0x0500); 702 pll = NV_RD32(par->PRAMDAC0, 0x0500);
703 M = (pll >> 0) & 0xFF; 703 M = (pll >> 0) & 0xFF;
704 N = (pll >> 8) & 0xFF; 704 N = (pll >> 8) & 0xFF;
@@ -707,19 +707,21 @@ static void nForceUpdateArbitrationSettings(unsigned VClk,
707 sim_data.pix_bpp = (char)pixelDepth; 707 sim_data.pix_bpp = (char)pixelDepth;
708 sim_data.enable_video = 0; 708 sim_data.enable_video = 0;
709 sim_data.enable_mp = 0; 709 sim_data.enable_mp = 0;
710 pci_find_slot(0, 1); 710 dev = pci_get_bus_and_slot(0, 1);
711 pci_read_config_dword(dev, 0x7C, &sim_data.memory_type); 711 pci_read_config_dword(dev, 0x7C, &sim_data.memory_type);
712 pci_dev_put(dev);
712 sim_data.memory_type = (sim_data.memory_type >> 12) & 1; 713 sim_data.memory_type = (sim_data.memory_type >> 12) & 1;
713 sim_data.memory_width = 64; 714 sim_data.memory_width = 64;
714 715
715 dev = pci_find_slot(0, 3); 716 dev = pci_get_bus_and_slot(0, 3);
716 pci_read_config_dword(dev, 0, &memctrl); 717 pci_read_config_dword(dev, 0, &memctrl);
718 pci_dev_put(dev);
717 memctrl >>= 16; 719 memctrl >>= 16;
718 720
719 if ((memctrl == 0x1A9) || (memctrl == 0x1AB) || (memctrl == 0x1ED)) { 721 if ((memctrl == 0x1A9) || (memctrl == 0x1AB) || (memctrl == 0x1ED)) {
720 int dimm[3]; 722 int dimm[3];
721 723
722 pci_find_slot(0, 2); 724 dev = pci_get_bus_and_slot(0, 2);
723 pci_read_config_dword(dev, 0x40, &dimm[0]); 725 pci_read_config_dword(dev, 0x40, &dimm[0]);
724 dimm[0] = (dimm[0] >> 8) & 0x4f; 726 dimm[0] = (dimm[0] >> 8) & 0x4f;
725 pci_read_config_dword(dev, 0x44, &dimm[1]); 727 pci_read_config_dword(dev, 0x44, &dimm[1]);
@@ -731,6 +733,7 @@ static void nForceUpdateArbitrationSettings(unsigned VClk,
731 printk("nvidiafb: your nForce DIMMs are not arranged " 733 printk("nvidiafb: your nForce DIMMs are not arranged "
732 "in optimal banks!\n"); 734 "in optimal banks!\n");
733 } 735 }
736 pci_dev_put(dev);
734 } 737 }
735 738
736 sim_data.mem_latency = 3; 739 sim_data.mem_latency = 3;
diff --git a/drivers/video/nvidia/nv_i2c.c b/drivers/video/nvidia/nv_i2c.c
index b8588973e400..afe4567e1ff4 100644
--- a/drivers/video/nvidia/nv_i2c.c
+++ b/drivers/video/nvidia/nv_i2c.c
@@ -30,16 +30,14 @@ static void nvidia_gpio_setscl(void *data, int state)
30 struct nvidia_par *par = chan->par; 30 struct nvidia_par *par = chan->par;
31 u32 val; 31 u32 val;
32 32
33 VGA_WR08(par->PCIO, 0x3d4, chan->ddc_base + 1); 33 val = NVReadCrtc(par, chan->ddc_base + 1) & 0xf0;
34 val = VGA_RD08(par->PCIO, 0x3d5) & 0xf0;
35 34
36 if (state) 35 if (state)
37 val |= 0x20; 36 val |= 0x20;
38 else 37 else
39 val &= ~0x20; 38 val &= ~0x20;
40 39
41 VGA_WR08(par->PCIO, 0x3d4, chan->ddc_base + 1); 40 NVWriteCrtc(par, chan->ddc_base + 1, val | 0x01);
42 VGA_WR08(par->PCIO, 0x3d5, val | 0x1);
43} 41}
44 42
45static void nvidia_gpio_setsda(void *data, int state) 43static void nvidia_gpio_setsda(void *data, int state)
@@ -48,16 +46,14 @@ static void nvidia_gpio_setsda(void *data, int state)
48 struct nvidia_par *par = chan->par; 46 struct nvidia_par *par = chan->par;
49 u32 val; 47 u32 val;
50 48
51 VGA_WR08(par->PCIO, 0x3d4, chan->ddc_base + 1); 49 val = NVReadCrtc(par, chan->ddc_base + 1) & 0xf0;
52 val = VGA_RD08(par->PCIO, 0x3d5) & 0xf0;
53 50
54 if (state) 51 if (state)
55 val |= 0x10; 52 val |= 0x10;
56 else 53 else
57 val &= ~0x10; 54 val &= ~0x10;
58 55
59 VGA_WR08(par->PCIO, 0x3d4, chan->ddc_base + 1); 56 NVWriteCrtc(par, chan->ddc_base + 1, val | 0x01);
60 VGA_WR08(par->PCIO, 0x3d5, val | 0x1);
61} 57}
62 58
63static int nvidia_gpio_getscl(void *data) 59static int nvidia_gpio_getscl(void *data)
@@ -66,12 +62,9 @@ static int nvidia_gpio_getscl(void *data)
66 struct nvidia_par *par = chan->par; 62 struct nvidia_par *par = chan->par;
67 u32 val = 0; 63 u32 val = 0;
68 64
69 VGA_WR08(par->PCIO, 0x3d4, chan->ddc_base); 65 if (NVReadCrtc(par, chan->ddc_base) & 0x04)
70 if (VGA_RD08(par->PCIO, 0x3d5) & 0x04)
71 val = 1; 66 val = 1;
72 67
73 val = VGA_RD08(par->PCIO, 0x3d5);
74
75 return val; 68 return val;
76} 69}
77 70
@@ -81,20 +74,21 @@ static int nvidia_gpio_getsda(void *data)
81 struct nvidia_par *par = chan->par; 74 struct nvidia_par *par = chan->par;
82 u32 val = 0; 75 u32 val = 0;
83 76
84 VGA_WR08(par->PCIO, 0x3d4, chan->ddc_base); 77 if (NVReadCrtc(par, chan->ddc_base) & 0x08)
85 if (VGA_RD08(par->PCIO, 0x3d5) & 0x08)
86 val = 1; 78 val = 1;
87 79
88 return val; 80 return val;
89} 81}
90 82
91static int nvidia_setup_i2c_bus(struct nvidia_i2c_chan *chan, const char *name) 83static int nvidia_setup_i2c_bus(struct nvidia_i2c_chan *chan, const char *name,
84 unsigned int i2c_class)
92{ 85{
93 int rc; 86 int rc;
94 87
95 strcpy(chan->adapter.name, name); 88 strcpy(chan->adapter.name, name);
96 chan->adapter.owner = THIS_MODULE; 89 chan->adapter.owner = THIS_MODULE;
97 chan->adapter.id = I2C_HW_B_NVIDIA; 90 chan->adapter.id = I2C_HW_B_NVIDIA;
91 chan->adapter.class = i2c_class;
98 chan->adapter.algo_data = &chan->algo; 92 chan->adapter.algo_data = &chan->algo;
99 chan->adapter.dev.parent = &chan->par->pci_dev->dev; 93 chan->adapter.dev.parent = &chan->par->pci_dev->dev;
100 chan->algo.setsda = nvidia_gpio_setsda; 94 chan->algo.setsda = nvidia_gpio_setsda;
@@ -127,83 +121,39 @@ static int nvidia_setup_i2c_bus(struct nvidia_i2c_chan *chan, const char *name)
127 121
128void nvidia_create_i2c_busses(struct nvidia_par *par) 122void nvidia_create_i2c_busses(struct nvidia_par *par)
129{ 123{
130 par->bus = 3;
131
132 par->chan[0].par = par; 124 par->chan[0].par = par;
133 par->chan[1].par = par; 125 par->chan[1].par = par;
134 par->chan[2].par = par; 126 par->chan[2].par = par;
135 127
136 par->chan[0].ddc_base = 0x3e; 128 par->chan[0].ddc_base = 0x36;
137 nvidia_setup_i2c_bus(&par->chan[0], "nvidia #0"); 129 nvidia_setup_i2c_bus(&par->chan[0], "nvidia #0", I2C_CLASS_HWMON);
138 130
139 par->chan[1].ddc_base = 0x36; 131 par->chan[1].ddc_base = 0x3e;
140 nvidia_setup_i2c_bus(&par->chan[1], "nvidia #1"); 132 nvidia_setup_i2c_bus(&par->chan[1], "nvidia #1", 0);
141 133
142 par->chan[2].ddc_base = 0x50; 134 par->chan[2].ddc_base = 0x50;
143 nvidia_setup_i2c_bus(&par->chan[2], "nvidia #2"); 135 nvidia_setup_i2c_bus(&par->chan[2], "nvidia #2", 0);
144} 136}
145 137
146void nvidia_delete_i2c_busses(struct nvidia_par *par) 138void nvidia_delete_i2c_busses(struct nvidia_par *par)
147{ 139{
148 if (par->chan[0].par) 140 int i;
149 i2c_del_adapter(&par->chan[0].adapter);
150 par->chan[0].par = NULL;
151
152 if (par->chan[1].par)
153 i2c_del_adapter(&par->chan[1].adapter);
154 par->chan[1].par = NULL;
155
156 if (par->chan[2].par)
157 i2c_del_adapter(&par->chan[2].adapter);
158 par->chan[2].par = NULL;
159
160}
161 141
162static u8 *nvidia_do_probe_i2c_edid(struct nvidia_i2c_chan *chan) 142 for (i = 0; i < 3; i++) {
163{ 143 if (!par->chan[i].par)
164 u8 start = 0x0; 144 continue;
165 struct i2c_msg msgs[] = { 145 i2c_del_adapter(&par->chan[i].adapter);
166 { 146 par->chan[i].par = NULL;
167 .addr = 0x50,
168 .len = 1,
169 .buf = &start,
170 }, {
171 .addr = 0x50,
172 .flags = I2C_M_RD,
173 .len = EDID_LENGTH,
174 },
175 };
176 u8 *buf;
177
178 if (!chan->par)
179 return NULL;
180
181 buf = kmalloc(EDID_LENGTH, GFP_KERNEL);
182 if (!buf) {
183 dev_warn(&chan->par->pci_dev->dev, "Out of memory!\n");
184 return NULL;
185 } 147 }
186 msgs[1].buf = buf;
187
188 if (i2c_transfer(&chan->adapter, msgs, 2) == 2)
189 return buf;
190 dev_dbg(&chan->par->pci_dev->dev, "Unable to read EDID block.\n");
191 kfree(buf);
192 return NULL;
193} 148}
194 149
195int nvidia_probe_i2c_connector(struct fb_info *info, int conn, u8 **out_edid) 150int nvidia_probe_i2c_connector(struct fb_info *info, int conn, u8 **out_edid)
196{ 151{
197 struct nvidia_par *par = info->par; 152 struct nvidia_par *par = info->par;
198 u8 *edid = NULL; 153 u8 *edid = NULL;
199 int i;
200 154
201 for (i = 0; i < 3; i++) { 155 if (par->chan[conn - 1].par)
202 /* Do the real work */ 156 edid = fb_ddc_read(&par->chan[conn - 1].adapter);
203 edid = nvidia_do_probe_i2c_edid(&par->chan[conn - 1]);
204 if (edid)
205 break;
206 }
207 157
208 if (!edid && conn == 1) { 158 if (!edid && conn == 1) {
209 /* try to get from firmware */ 159 /* try to get from firmware */
diff --git a/drivers/video/nvidia/nv_local.h b/drivers/video/nvidia/nv_local.h
index e009d242ea10..68e508daa417 100644
--- a/drivers/video/nvidia/nv_local.h
+++ b/drivers/video/nvidia/nv_local.h
@@ -73,9 +73,9 @@
73#define NVDmaNext(par, data) \ 73#define NVDmaNext(par, data) \
74 NV_WR32(&(par)->dmaBase[(par)->dmaCurrent++], 0, (data)) 74 NV_WR32(&(par)->dmaBase[(par)->dmaCurrent++], 0, (data))
75 75
76#define NVDmaStart(par, tag, size) { \ 76#define NVDmaStart(info, par, tag, size) { \
77 if((par)->dmaFree <= (size)) \ 77 if((par)->dmaFree <= (size)) \
78 NVDmaWait(par, size); \ 78 NVDmaWait(info, size); \
79 NVDmaNext(par, ((size) << 18) | (tag)); \ 79 NVDmaNext(par, ((size) << 18) | (tag)); \
80 (par)->dmaFree -= ((size) + 1); \ 80 (par)->dmaFree -= ((size) + 1); \
81} 81}
diff --git a/drivers/video/nvidia/nv_setup.c b/drivers/video/nvidia/nv_setup.c
index eab3e282a4de..707e2c8a13ed 100644
--- a/drivers/video/nvidia/nv_setup.c
+++ b/drivers/video/nvidia/nv_setup.c
@@ -261,7 +261,7 @@ static void nv10GetConfig(struct nvidia_par *par)
261 } 261 }
262#endif 262#endif
263 263
264 dev = pci_find_slot(0, 1); 264 dev = pci_get_bus_and_slot(0, 1);
265 if ((par->Chipset & 0xffff) == 0x01a0) { 265 if ((par->Chipset & 0xffff) == 0x01a0) {
266 int amt = 0; 266 int amt = 0;
267 267
@@ -276,6 +276,7 @@ static void nv10GetConfig(struct nvidia_par *par)
276 par->RamAmountKBytes = 276 par->RamAmountKBytes =
277 (NV_RD32(par->PFB, 0x020C) & 0xFFF00000) >> 10; 277 (NV_RD32(par->PFB, 0x020C) & 0xFFF00000) >> 10;
278 } 278 }
279 pci_dev_put(dev);
279 280
280 par->CrystalFreqKHz = (NV_RD32(par->PEXTDEV, 0x0000) & (1 << 6)) ? 281 par->CrystalFreqKHz = (NV_RD32(par->PEXTDEV, 0x0000) & (1 << 6)) ?
281 14318 : 13500; 282 14318 : 13500;
@@ -656,7 +657,7 @@ int NVCommonSetup(struct fb_info *info)
656 par->LVDS = 0; 657 par->LVDS = 0;
657 if (par->FlatPanel && par->twoHeads) { 658 if (par->FlatPanel && par->twoHeads) {
658 NV_WR32(par->PRAMDAC0, 0x08B0, 0x00010004); 659 NV_WR32(par->PRAMDAC0, 0x08B0, 0x00010004);
659 if (par->PRAMDAC0[0x08b4] & 1) 660 if (NV_RD32(par->PRAMDAC0, 0x08b4) & 1)
660 par->LVDS = 1; 661 par->LVDS = 1;
661 printk("nvidiafb: Panel is %s\n", par->LVDS ? "LVDS" : "TMDS"); 662 printk("nvidiafb: Panel is %s\n", par->LVDS ? "LVDS" : "TMDS");
662 } 663 }
diff --git a/drivers/video/nvidia/nv_type.h b/drivers/video/nvidia/nv_type.h
index 86e65dea60d3..38f7cc0a2331 100644
--- a/drivers/video/nvidia/nv_type.h
+++ b/drivers/video/nvidia/nv_type.h
@@ -4,8 +4,9 @@
4#include <linux/fb.h> 4#include <linux/fb.h>
5#include <linux/types.h> 5#include <linux/types.h>
6#include <linux/i2c.h> 6#include <linux/i2c.h>
7#include <linux/i2c-id.h>
8#include <linux/i2c-algo-bit.h> 7#include <linux/i2c-algo-bit.h>
8#include <linux/mutex.h>
9#include <video/vga.h>
9 10
10#define NV_ARCH_04 0x04 11#define NV_ARCH_04 0x04
11#define NV_ARCH_10 0x10 12#define NV_ARCH_10 0x10
@@ -94,13 +95,15 @@ struct riva_regs {
94struct nvidia_par { 95struct nvidia_par {
95 RIVA_HW_STATE SavedReg; 96 RIVA_HW_STATE SavedReg;
96 RIVA_HW_STATE ModeReg; 97 RIVA_HW_STATE ModeReg;
98 RIVA_HW_STATE initial_state;
97 RIVA_HW_STATE *CurrentState; 99 RIVA_HW_STATE *CurrentState;
100 struct vgastate vgastate;
101 struct mutex open_lock;
98 u32 pseudo_palette[16]; 102 u32 pseudo_palette[16];
99 struct pci_dev *pci_dev; 103 struct pci_dev *pci_dev;
100 u32 Architecture; 104 u32 Architecture;
101 u32 CursorStart; 105 u32 CursorStart;
102 int Chipset; 106 int Chipset;
103 int bus;
104 unsigned long FbAddress; 107 unsigned long FbAddress;
105 u8 __iomem *FbStart; 108 u8 __iomem *FbStart;
106 u32 FbMapSize; 109 u32 FbMapSize;
@@ -143,6 +146,7 @@ struct nvidia_par {
143 int BlendingPossible; 146 int BlendingPossible;
144 u32 paletteEnabled; 147 u32 paletteEnabled;
145 u32 forceCRTC; 148 u32 forceCRTC;
149 u32 open_count;
146 u8 DDCBase; 150 u8 DDCBase;
147#ifdef CONFIG_MTRR 151#ifdef CONFIG_MTRR
148 struct { 152 struct {
diff --git a/drivers/video/nvidia/nvidia.c b/drivers/video/nvidia/nvidia.c
index b97ec6901263..7c36b5fe582e 100644
--- a/drivers/video/nvidia/nvidia.c
+++ b/drivers/video/nvidia/nvidia.c
@@ -200,7 +200,7 @@ static int nvidia_panel_tweak(struct nvidia_par *par,
200 return tweak; 200 return tweak;
201} 201}
202 202
203static void nvidia_vga_protect(struct nvidia_par *par, int on) 203static void nvidia_screen_off(struct nvidia_par *par, int on)
204{ 204{
205 unsigned char tmp; 205 unsigned char tmp;
206 206
@@ -649,7 +649,7 @@ static int nvidiafb_set_par(struct fb_info *info)
649 NVLockUnlock(par, 0); 649 NVLockUnlock(par, 0);
650 } 650 }
651 651
652 nvidia_vga_protect(par, 1); 652 nvidia_screen_off(par, 1);
653 653
654 nvidia_write_regs(par, &par->ModeReg); 654 nvidia_write_regs(par, &par->ModeReg);
655 NVSetStartAddress(par, 0); 655 NVSetStartAddress(par, 0);
@@ -687,7 +687,7 @@ static int nvidiafb_set_par(struct fb_info *info)
687 687
688 par->cursor_reset = 1; 688 par->cursor_reset = 1;
689 689
690 nvidia_vga_protect(par, 0); 690 nvidia_screen_off(par, 0);
691 691
692#ifdef CONFIG_BOOTX_TEXT 692#ifdef CONFIG_BOOTX_TEXT
693 /* Update debug text engine */ 693 /* Update debug text engine */
@@ -696,6 +696,7 @@ static int nvidiafb_set_par(struct fb_info *info)
696 info->var.bits_per_pixel, info->fix.line_length); 696 info->var.bits_per_pixel, info->fix.line_length);
697#endif 697#endif
698 698
699 NVLockUnlock(par, 0);
699 NVTRACE_LEAVE(); 700 NVTRACE_LEAVE();
700 return 0; 701 return 0;
701} 702}
@@ -948,8 +949,80 @@ static int nvidiafb_blank(int blank, struct fb_info *info)
948 return 0; 949 return 0;
949} 950}
950 951
952/*
953 * Because the VGA registers are not mapped linearly in its MMIO space,
954 * restrict VGA register saving and restore to x86 only, where legacy VGA IO
955 * access is legal. Consequently, we must also check if the device is the
956 * primary display.
957 */
958#ifdef CONFIG_X86
959static void save_vga_x86(struct nvidia_par *par)
960{
961 struct resource *res= &par->pci_dev->resource[PCI_ROM_RESOURCE];
962
963 if (res && res->flags & IORESOURCE_ROM_SHADOW) {
964 memset(&par->vgastate, 0, sizeof(par->vgastate));
965 par->vgastate.flags = VGA_SAVE_MODE | VGA_SAVE_FONTS |
966 VGA_SAVE_CMAP;
967 save_vga(&par->vgastate);
968 }
969}
970
971static void restore_vga_x86(struct nvidia_par *par)
972{
973 struct resource *res= &par->pci_dev->resource[PCI_ROM_RESOURCE];
974
975 if (res && res->flags & IORESOURCE_ROM_SHADOW)
976 restore_vga(&par->vgastate);
977}
978#else
979#define save_vga_x86(x) do {} while (0)
980#define restore_vga_x86(x) do {} while (0)
981#endif /* X86 */
982
983static int nvidiafb_open(struct fb_info *info, int user)
984{
985 struct nvidia_par *par = info->par;
986
987 mutex_lock(&par->open_lock);
988
989 if (!par->open_count) {
990 save_vga_x86(par);
991 nvidia_save_vga(par, &par->initial_state);
992 }
993
994 par->open_count++;
995 mutex_unlock(&par->open_lock);
996 return 0;
997}
998
999static int nvidiafb_release(struct fb_info *info, int user)
1000{
1001 struct nvidia_par *par = info->par;
1002 int err = 0;
1003
1004 mutex_lock(&par->open_lock);
1005
1006 if (!par->open_count) {
1007 err = -EINVAL;
1008 goto done;
1009 }
1010
1011 if (par->open_count == 1) {
1012 nvidia_write_regs(par, &par->initial_state);
1013 restore_vga_x86(par);
1014 }
1015
1016 par->open_count--;
1017done:
1018 mutex_unlock(&par->open_lock);
1019 return err;
1020}
1021
951static struct fb_ops nvidia_fb_ops = { 1022static struct fb_ops nvidia_fb_ops = {
952 .owner = THIS_MODULE, 1023 .owner = THIS_MODULE,
1024 .fb_open = nvidiafb_open,
1025 .fb_release = nvidiafb_release,
953 .fb_check_var = nvidiafb_check_var, 1026 .fb_check_var = nvidiafb_check_var,
954 .fb_set_par = nvidiafb_set_par, 1027 .fb_set_par = nvidiafb_set_par,
955 .fb_setcolreg = nvidiafb_setcolreg, 1028 .fb_setcolreg = nvidiafb_setcolreg,
@@ -1207,7 +1280,7 @@ static int __devinit nvidiafb_probe(struct pci_dev *pd,
1207 1280
1208 par = info->par; 1281 par = info->par;
1209 par->pci_dev = pd; 1282 par->pci_dev = pd;
1210 1283 mutex_init(&par->open_lock);
1211 info->pixmap.addr = kzalloc(8 * 1024, GFP_KERNEL); 1284 info->pixmap.addr = kzalloc(8 * 1024, GFP_KERNEL);
1212 1285
1213 if (info->pixmap.addr == NULL) 1286 if (info->pixmap.addr == NULL)
diff --git a/drivers/video/pm2fb.c b/drivers/video/pm2fb.c
index a560a2223825..1ac5264bb2c1 100644
--- a/drivers/video/pm2fb.c
+++ b/drivers/video/pm2fb.c
@@ -81,8 +81,6 @@ static int lowvsync;
81struct pm2fb_par 81struct pm2fb_par
82{ 82{
83 pm2type_t type; /* Board type */ 83 pm2type_t type; /* Board type */
84 u32 fb_size; /* framebuffer memory size */
85 unsigned char __iomem *v_fb; /* virtual address of frame buffer */
86 unsigned char __iomem *v_regs;/* virtual address of p_regs */ 84 unsigned char __iomem *v_regs;/* virtual address of p_regs */
87 u32 memclock; /* memclock */ 85 u32 memclock; /* memclock */
88 u32 video; /* video flags before blanking */ 86 u32 video; /* video flags before blanking */
@@ -103,7 +101,7 @@ static struct fb_fix_screeninfo pm2fb_fix __devinitdata = {
103 .xpanstep = 1, 101 .xpanstep = 1,
104 .ypanstep = 1, 102 .ypanstep = 1,
105 .ywrapstep = 0, 103 .ywrapstep = 0,
106 .accel = FB_ACCEL_NONE, 104 .accel = FB_ACCEL_3DLABS_PERMEDIA2,
107}; 105};
108 106
109/* 107/*
@@ -206,6 +204,17 @@ static inline void WAIT_FIFO(struct pm2fb_par* p, u32 a)
206} 204}
207#endif 205#endif
208 206
207static void wait_pm2(struct pm2fb_par* par) {
208
209 WAIT_FIFO(par, 1);
210 pm2_WR(par, PM2R_SYNC, 0);
211 mb();
212 do {
213 while (pm2_RD(par, PM2R_OUT_FIFO_WORDS) == 0);
214 rmb();
215 } while (pm2_RD(par, PM2R_OUT_FIFO) != PM2TAG(PM2R_SYNC));
216}
217
209/* 218/*
210 * partial products for the supported horizontal resolutions. 219 * partial products for the supported horizontal resolutions.
211 */ 220 */
@@ -302,10 +311,10 @@ static void pm2v_mnp(u32 clk, unsigned char* mm, unsigned char* nn,
302 s32 delta = 1000; 311 s32 delta = 1000;
303 312
304 *mm = *nn = *pp = 0; 313 *mm = *nn = *pp = 0;
305 for (n = 1; n; n++) { 314 for ( m = 1; m < 128; m++) {
306 for ( m = 1; m; m++) { 315 for (n = 2 * m + 1; n; n++) {
307 for ( p = 0; p < 2; p++) { 316 for ( p = 0; p < 2; p++) {
308 f = PM2_REFERENCE_CLOCK * n / (m * (1 << (p + 1))); 317 f = ( PM2_REFERENCE_CLOCK >> ( p + 1 )) * n / m;
309 if ( clk > f - delta && clk < f + delta ) { 318 if ( clk > f - delta && clk < f + delta ) {
310 delta = ( clk > f ) ? clk - f : f - clk; 319 delta = ( clk > f ) ? clk - f : f - clk;
311 *mm=m; 320 *mm=m;
@@ -462,21 +471,43 @@ static void set_memclock(struct pm2fb_par* par, u32 clk)
462 int i; 471 int i;
463 unsigned char m, n, p; 472 unsigned char m, n, p;
464 473
465 pm2_mnp(clk, &m, &n, &p); 474 switch (par->type) {
466 WAIT_FIFO(par, 10); 475 case PM2_TYPE_PERMEDIA2V:
467 pm2_RDAC_WR(par, PM2I_RD_MEMORY_CLOCK_3, 6); 476 pm2v_mnp(clk/2, &m, &n, &p);
468 wmb(); 477 WAIT_FIFO(par, 8);
469 pm2_RDAC_WR(par, PM2I_RD_MEMORY_CLOCK_1, m); 478 pm2_WR(par, PM2VR_RD_INDEX_HIGH, PM2VI_RD_MCLK_CONTROL >> 8);
470 pm2_RDAC_WR(par, PM2I_RD_MEMORY_CLOCK_2, n); 479 pm2v_RDAC_WR(par, PM2VI_RD_MCLK_CONTROL, 0);
471 wmb(); 480 wmb();
472 pm2_RDAC_WR(par, PM2I_RD_MEMORY_CLOCK_3, 8|p); 481 pm2v_RDAC_WR(par, PM2VI_RD_MCLK_PRESCALE, m);
473 wmb(); 482 pm2v_RDAC_WR(par, PM2VI_RD_MCLK_FEEDBACK, n);
474 pm2_RDAC_RD(par, PM2I_RD_MEMORY_CLOCK_STATUS); 483 pm2v_RDAC_WR(par, PM2VI_RD_MCLK_POSTSCALE, p);
475 rmb(); 484 wmb();
476 for (i = 256; 485 pm2v_RDAC_WR(par, PM2VI_RD_MCLK_CONTROL, 1);
477 i && !(pm2_RD(par, PM2R_RD_INDEXED_DATA) & PM2F_PLL_LOCKED); 486 rmb();
478 i--) 487 for (i = 256;
479 ; 488 i && !(pm2_RDAC_RD(par, PM2VI_RD_MCLK_CONTROL) & 2);
489 i--)
490 ;
491 pm2_WR(par, PM2VR_RD_INDEX_HIGH, 0);
492 break;
493 case PM2_TYPE_PERMEDIA2:
494 pm2_mnp(clk, &m, &n, &p);
495 WAIT_FIFO(par, 10);
496 pm2_RDAC_WR(par, PM2I_RD_MEMORY_CLOCK_3, 6);
497 wmb();
498 pm2_RDAC_WR(par, PM2I_RD_MEMORY_CLOCK_1, m);
499 pm2_RDAC_WR(par, PM2I_RD_MEMORY_CLOCK_2, n);
500 wmb();
501 pm2_RDAC_WR(par, PM2I_RD_MEMORY_CLOCK_3, 8|p);
502 wmb();
503 pm2_RDAC_RD(par, PM2I_RD_MEMORY_CLOCK_STATUS);
504 rmb();
505 for (i = 256;
506 i && !(pm2_RD(par, PM2R_RD_INDEXED_DATA) & PM2F_PLL_LOCKED);
507 i--)
508 ;
509 break;
510 }
480} 511}
481 512
482static void set_pixclock(struct pm2fb_par* par, u32 clk) 513static void set_pixclock(struct pm2fb_par* par, u32 clk)
@@ -623,6 +654,8 @@ static int pm2fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
623 return -EINVAL; 654 return -EINVAL;
624 } 655 }
625 656
657 var->transp.offset = 0;
658 var->transp.length = 0;
626 switch(var->bits_per_pixel) { 659 switch(var->bits_per_pixel) {
627 case 8: 660 case 8:
628 var->red.length = var->green.length = var->blue.length = 8; 661 var->red.length = var->green.length = var->blue.length = 8;
@@ -1017,6 +1050,117 @@ static int pm2fb_blank(int blank_mode, struct fb_info *info)
1017 return 0; 1050 return 0;
1018} 1051}
1019 1052
1053/*
1054 * block operation. copy=0: rectangle fill, copy=1: rectangle copy.
1055 */
1056static void pm2fb_block_op(struct pm2fb_par* par, int copy,
1057 s32 xsrc, s32 ysrc,
1058 s32 x, s32 y, s32 w, s32 h,
1059 u32 color) {
1060
1061 if (!w || !h)
1062 return;
1063 WAIT_FIFO(par, 6);
1064 pm2_WR(par, PM2R_CONFIG, PM2F_CONFIG_FB_WRITE_ENABLE |
1065 PM2F_CONFIG_FB_READ_SOURCE_ENABLE);
1066 pm2_WR(par, PM2R_FB_PIXEL_OFFSET, 0);
1067 if (copy)
1068 pm2_WR(par, PM2R_FB_SOURCE_DELTA,
1069 ((ysrc-y) & 0xfff) << 16 | ((xsrc-x) & 0xfff));
1070 else
1071 pm2_WR(par, PM2R_FB_BLOCK_COLOR, color);
1072 pm2_WR(par, PM2R_RECTANGLE_ORIGIN, (y << 16) | x);
1073 pm2_WR(par, PM2R_RECTANGLE_SIZE, (h << 16) | w);
1074 wmb();
1075 pm2_WR(par, PM2R_RENDER,PM2F_RENDER_RECTANGLE |
1076 (x<xsrc ? PM2F_INCREASE_X : 0) |
1077 (y<ysrc ? PM2F_INCREASE_Y : 0) |
1078 (copy ? 0 : PM2F_RENDER_FASTFILL));
1079 wait_pm2(par);
1080}
1081
1082static void pm2fb_fillrect (struct fb_info *info,
1083 const struct fb_fillrect *region)
1084{
1085 struct pm2fb_par *par = info->par;
1086 struct fb_fillrect modded;
1087 int vxres, vyres;
1088 u32 color = (info->fix.visual == FB_VISUAL_TRUECOLOR) ?
1089 ((u32*)info->pseudo_palette)[region->color] : region->color;
1090
1091 if (info->state != FBINFO_STATE_RUNNING)
1092 return;
1093 if ((info->flags & FBINFO_HWACCEL_DISABLED) ||
1094 region->rop != ROP_COPY ) {
1095 cfb_fillrect(info, region);
1096 return;
1097 }
1098
1099 vxres = info->var.xres_virtual;
1100 vyres = info->var.yres_virtual;
1101
1102 memcpy(&modded, region, sizeof(struct fb_fillrect));
1103
1104 if(!modded.width || !modded.height ||
1105 modded.dx >= vxres || modded.dy >= vyres)
1106 return;
1107
1108 if(modded.dx + modded.width > vxres)
1109 modded.width = vxres - modded.dx;
1110 if(modded.dy + modded.height > vyres)
1111 modded.height = vyres - modded.dy;
1112
1113 if(info->var.bits_per_pixel == 8)
1114 color |= color << 8;
1115 if(info->var.bits_per_pixel <= 16)
1116 color |= color << 16;
1117
1118 if(info->var.bits_per_pixel != 24)
1119 pm2fb_block_op(par, 0, 0, 0,
1120 modded.dx, modded.dy,
1121 modded.width, modded.height, color);
1122 else
1123 cfb_fillrect(info, region);
1124}
1125
1126static void pm2fb_copyarea(struct fb_info *info,
1127 const struct fb_copyarea *area)
1128{
1129 struct pm2fb_par *par = info->par;
1130 struct fb_copyarea modded;
1131 u32 vxres, vyres;
1132
1133 if (info->state != FBINFO_STATE_RUNNING)
1134 return;
1135 if (info->flags & FBINFO_HWACCEL_DISABLED) {
1136 cfb_copyarea(info, area);
1137 return;
1138 }
1139
1140 memcpy(&modded, area, sizeof(struct fb_copyarea));
1141
1142 vxres = info->var.xres_virtual;
1143 vyres = info->var.yres_virtual;
1144
1145 if(!modded.width || !modded.height ||
1146 modded.sx >= vxres || modded.sy >= vyres ||
1147 modded.dx >= vxres || modded.dy >= vyres)
1148 return;
1149
1150 if(modded.sx + modded.width > vxres)
1151 modded.width = vxres - modded.sx;
1152 if(modded.dx + modded.width > vxres)
1153 modded.width = vxres - modded.dx;
1154 if(modded.sy + modded.height > vyres)
1155 modded.height = vyres - modded.sy;
1156 if(modded.dy + modded.height > vyres)
1157 modded.height = vyres - modded.dy;
1158
1159 pm2fb_block_op(par, 1, modded.sx, modded.sy,
1160 modded.dx, modded.dy,
1161 modded.width, modded.height, 0);
1162}
1163
1020/* ------------ Hardware Independent Functions ------------ */ 1164/* ------------ Hardware Independent Functions ------------ */
1021 1165
1022/* 1166/*
@@ -1030,8 +1174,8 @@ static struct fb_ops pm2fb_ops = {
1030 .fb_setcolreg = pm2fb_setcolreg, 1174 .fb_setcolreg = pm2fb_setcolreg,
1031 .fb_blank = pm2fb_blank, 1175 .fb_blank = pm2fb_blank,
1032 .fb_pan_display = pm2fb_pan_display, 1176 .fb_pan_display = pm2fb_pan_display,
1033 .fb_fillrect = cfb_fillrect, 1177 .fb_fillrect = pm2fb_fillrect,
1034 .fb_copyarea = cfb_copyarea, 1178 .fb_copyarea = pm2fb_copyarea,
1035 .fb_imageblit = cfb_imageblit, 1179 .fb_imageblit = cfb_imageblit,
1036}; 1180};
1037 1181
@@ -1119,38 +1263,47 @@ static int __devinit pm2fb_probe(struct pci_dev *pdev,
1119 1263
1120 if(default_par->mem_control == 0 && 1264 if(default_par->mem_control == 0 &&
1121 default_par->boot_address == 0x31 && 1265 default_par->boot_address == 0x31 &&
1122 default_par->mem_config == 0x259fffff && 1266 default_par->mem_config == 0x259fffff) {
1123 pdev->subsystem_vendor == 0x1048 && 1267 default_par->memclock = CVPPC_MEMCLOCK;
1124 pdev->subsystem_device == 0x0a31) {
1125 DPRINTK("subsystem_vendor: %04x, subsystem_device: %04x\n",
1126 pdev->subsystem_vendor, pdev->subsystem_device);
1127 DPRINTK("We have not been initialized by VGA BIOS "
1128 "and are running on an Elsa Winner 2000 Office\n");
1129 DPRINTK("Initializing card timings manually...\n");
1130 default_par->mem_control=0; 1268 default_par->mem_control=0;
1131 default_par->boot_address=0x20; 1269 default_par->boot_address=0x20;
1132 default_par->mem_config=0xe6002021; 1270 default_par->mem_config=0xe6002021;
1133 default_par->memclock=100000; 1271 if (pdev->subsystem_vendor == 0x1048 &&
1272 pdev->subsystem_device == 0x0a31) {
1273 DPRINTK("subsystem_vendor: %04x, subsystem_device: %04x\n",
1274 pdev->subsystem_vendor, pdev->subsystem_device);
1275 DPRINTK("We have not been initialized by VGA BIOS "
1276 "and are running on an Elsa Winner 2000 Office\n");
1277 DPRINTK("Initializing card timings manually...\n");
1278 default_par->memclock=70000;
1279 }
1280 if (pdev->subsystem_vendor == 0x3d3d &&
1281 pdev->subsystem_device == 0x0100) {
1282 DPRINTK("subsystem_vendor: %04x, subsystem_device: %04x\n",
1283 pdev->subsystem_vendor, pdev->subsystem_device);
1284 DPRINTK("We have not been initialized by VGA BIOS "
1285 "and are running on an 3dlabs reference board\n");
1286 DPRINTK("Initializing card timings manually...\n");
1287 default_par->memclock=74894;
1288 }
1134 } 1289 }
1135 1290
1136 /* Now work out how big lfb is going to be. */ 1291 /* Now work out how big lfb is going to be. */
1137 switch(default_par->mem_config & PM2F_MEM_CONFIG_RAM_MASK) { 1292 switch(default_par->mem_config & PM2F_MEM_CONFIG_RAM_MASK) {
1138 case PM2F_MEM_BANKS_1: 1293 case PM2F_MEM_BANKS_1:
1139 default_par->fb_size=0x200000; 1294 pm2fb_fix.smem_len=0x200000;
1140 break; 1295 break;
1141 case PM2F_MEM_BANKS_2: 1296 case PM2F_MEM_BANKS_2:
1142 default_par->fb_size=0x400000; 1297 pm2fb_fix.smem_len=0x400000;
1143 break; 1298 break;
1144 case PM2F_MEM_BANKS_3: 1299 case PM2F_MEM_BANKS_3:
1145 default_par->fb_size=0x600000; 1300 pm2fb_fix.smem_len=0x600000;
1146 break; 1301 break;
1147 case PM2F_MEM_BANKS_4: 1302 case PM2F_MEM_BANKS_4:
1148 default_par->fb_size=0x800000; 1303 pm2fb_fix.smem_len=0x800000;
1149 break; 1304 break;
1150 } 1305 }
1151 default_par->memclock = CVPPC_MEMCLOCK;
1152 pm2fb_fix.smem_start = pci_resource_start(pdev, 1); 1306 pm2fb_fix.smem_start = pci_resource_start(pdev, 1);
1153 pm2fb_fix.smem_len = default_par->fb_size;
1154 1307
1155 /* Linear frame buffer - request region and map it. */ 1308 /* Linear frame buffer - request region and map it. */
1156 if ( !request_mem_region(pm2fb_fix.smem_start, pm2fb_fix.smem_len, 1309 if ( !request_mem_region(pm2fb_fix.smem_start, pm2fb_fix.smem_len,
@@ -1158,9 +1311,9 @@ static int __devinit pm2fb_probe(struct pci_dev *pdev,
1158 printk(KERN_WARNING "pm2fb: Can't reserve smem.\n"); 1311 printk(KERN_WARNING "pm2fb: Can't reserve smem.\n");
1159 goto err_exit_mmio; 1312 goto err_exit_mmio;
1160 } 1313 }
1161 info->screen_base = default_par->v_fb = 1314 info->screen_base =
1162 ioremap_nocache(pm2fb_fix.smem_start, pm2fb_fix.smem_len); 1315 ioremap_nocache(pm2fb_fix.smem_start, pm2fb_fix.smem_len);
1163 if ( !default_par->v_fb ) { 1316 if ( !info->screen_base ) {
1164 printk(KERN_WARNING "pm2fb: Can't ioremap smem area.\n"); 1317 printk(KERN_WARNING "pm2fb: Can't ioremap smem area.\n");
1165 release_mem_region(pm2fb_fix.smem_start, pm2fb_fix.smem_len); 1318 release_mem_region(pm2fb_fix.smem_start, pm2fb_fix.smem_len);
1166 goto err_exit_mmio; 1319 goto err_exit_mmio;
@@ -1170,7 +1323,9 @@ static int __devinit pm2fb_probe(struct pci_dev *pdev,
1170 info->fix = pm2fb_fix; 1323 info->fix = pm2fb_fix;
1171 info->pseudo_palette = default_par->palette; 1324 info->pseudo_palette = default_par->palette;
1172 info->flags = FBINFO_DEFAULT | 1325 info->flags = FBINFO_DEFAULT |
1173 FBINFO_HWACCEL_YPAN; 1326 FBINFO_HWACCEL_YPAN |
1327 FBINFO_HWACCEL_COPYAREA |
1328 FBINFO_HWACCEL_FILLRECT;
1174 1329
1175 if (!mode) 1330 if (!mode)
1176 mode = "640x480@60"; 1331 mode = "640x480@60";
@@ -1180,13 +1335,13 @@ static int __devinit pm2fb_probe(struct pci_dev *pdev,
1180 info->var = pm2fb_var; 1335 info->var = pm2fb_var;
1181 1336
1182 if (fb_alloc_cmap(&info->cmap, 256, 0) < 0) 1337 if (fb_alloc_cmap(&info->cmap, 256, 0) < 0)
1183 goto err_exit_all; 1338 goto err_exit_both;
1184 1339
1185 if (register_framebuffer(info) < 0) 1340 if (register_framebuffer(info) < 0)
1186 goto err_exit_both; 1341 goto err_exit_all;
1187 1342
1188 printk(KERN_INFO "fb%d: %s frame buffer device, memory = %dK.\n", 1343 printk(KERN_INFO "fb%d: %s frame buffer device, memory = %dK.\n",
1189 info->node, info->fix.id, default_par->fb_size / 1024); 1344 info->node, info->fix.id, pm2fb_fix.smem_len / 1024);
1190 1345
1191 /* 1346 /*
1192 * Our driver data 1347 * Our driver data
@@ -1242,6 +1397,9 @@ static struct pci_device_id pm2fb_id_table[] = {
1242 { PCI_VENDOR_ID_3DLABS, PCI_DEVICE_ID_3DLABS_PERMEDIA2V, 1397 { PCI_VENDOR_ID_3DLABS, PCI_DEVICE_ID_3DLABS_PERMEDIA2V,
1243 PCI_ANY_ID, PCI_ANY_ID, PCI_BASE_CLASS_DISPLAY << 16, 1398 PCI_ANY_ID, PCI_ANY_ID, PCI_BASE_CLASS_DISPLAY << 16,
1244 0xff0000, 0 }, 1399 0xff0000, 0 },
1400 { PCI_VENDOR_ID_3DLABS, PCI_DEVICE_ID_3DLABS_PERMEDIA2V,
1401 PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_NOT_DEFINED_VGA << 8,
1402 0xff00, 0 },
1245 { 0, } 1403 { 0, }
1246}; 1404};
1247 1405
diff --git a/drivers/video/pvr2fb.c b/drivers/video/pvr2fb.c
index a93618bc9d27..df2909ae704c 100644
--- a/drivers/video/pvr2fb.c
+++ b/drivers/video/pvr2fb.c
@@ -214,7 +214,7 @@ static int pvr2_init_cable(void);
214static int pvr2_get_param(const struct pvr2_params *p, const char *s, 214static int pvr2_get_param(const struct pvr2_params *p, const char *s,
215 int val, int size); 215 int val, int size);
216#ifdef CONFIG_SH_DMA 216#ifdef CONFIG_SH_DMA
217static ssize_t pvr2fb_write(struct file *file, const char *buf, 217static ssize_t pvr2fb_write(struct fb_info *info, const char *buf,
218 size_t count, loff_t *ppos); 218 size_t count, loff_t *ppos);
219#endif 219#endif
220 220
@@ -674,7 +674,7 @@ static int pvr2_init_cable(void)
674} 674}
675 675
676#ifdef CONFIG_SH_DMA 676#ifdef CONFIG_SH_DMA
677static ssize_t pvr2fb_write(struct file *file, const char *buf, 677static ssize_t pvr2fb_write(struct fb_info *info, const char *buf,
678 size_t count, loff_t *ppos) 678 size_t count, loff_t *ppos)
679{ 679{
680 unsigned long dst, start, end, len; 680 unsigned long dst, start, end, len;
diff --git a/drivers/video/pxafb.c b/drivers/video/pxafb.c
index 0b195f33f84f..81e571d59b50 100644
--- a/drivers/video/pxafb.c
+++ b/drivers/video/pxafb.c
@@ -1203,7 +1203,7 @@ static int __init pxafb_parse_options(struct device *dev, char *options)
1203 } else 1203 } else
1204 goto done; 1204 goto done;
1205 break; 1205 break;
1206 case '0'...'9': 1206 case '0' ... '9':
1207 break; 1207 break;
1208 default: 1208 default:
1209 goto done; 1209 goto done;
diff --git a/drivers/video/riva/fbdev.c b/drivers/video/riva/fbdev.c
index 9c6bd0991852..0fe547842c64 100644
--- a/drivers/video/riva/fbdev.c
+++ b/drivers/video/riva/fbdev.c
@@ -317,15 +317,15 @@ static int riva_bl_update_status(struct backlight_device *bd)
317 else 317 else
318 level = bd->props.brightness; 318 level = bd->props.brightness;
319 319
320 tmp_pmc = par->riva.PMC[0x10F0/4] & 0x0000FFFF; 320 tmp_pmc = NV_RD32(par->riva.PMC, 0x10F0) & 0x0000FFFF;
321 tmp_pcrt = par->riva.PCRTC0[0x081C/4] & 0xFFFFFFFC; 321 tmp_pcrt = NV_RD32(par->riva.PCRTC0, 0x081C) & 0xFFFFFFFC;
322 if(level > 0) { 322 if(level > 0) {
323 tmp_pcrt |= 0x1; 323 tmp_pcrt |= 0x1;
324 tmp_pmc |= (1 << 31); /* backlight bit */ 324 tmp_pmc |= (1 << 31); /* backlight bit */
325 tmp_pmc |= riva_bl_get_level_brightness(par, level) << 16; /* level */ 325 tmp_pmc |= riva_bl_get_level_brightness(par, level) << 16; /* level */
326 } 326 }
327 par->riva.PCRTC0[0x081C/4] = tmp_pcrt; 327 NV_WR32(par->riva.PCRTC0, 0x081C, tmp_pcrt);
328 par->riva.PMC[0x10F0/4] = tmp_pmc; 328 NV_WR32(par->riva.PMC, 0x10F0, tmp_pmc);
329 329
330 return 0; 330 return 0;
331} 331}
@@ -1788,8 +1788,10 @@ static int __devinit riva_get_EDID_i2c(struct fb_info *info)
1788 1788
1789 NVTRACE_ENTER(); 1789 NVTRACE_ENTER();
1790 riva_create_i2c_busses(par); 1790 riva_create_i2c_busses(par);
1791 for (i = 0; i < par->bus; i++) { 1791 for (i = 0; i < 3; i++) {
1792 riva_probe_i2c_connector(par, i+1, &par->EDID); 1792 if (!par->chan[i].par)
1793 continue;
1794 riva_probe_i2c_connector(par, i, &par->EDID);
1793 if (par->EDID && !fb_parse_edid(par->EDID, &var)) { 1795 if (par->EDID && !fb_parse_edid(par->EDID, &var)) {
1794 printk(PFX "Found EDID Block from BUS %i\n", i); 1796 printk(PFX "Found EDID Block from BUS %i\n", i);
1795 break; 1797 break;
@@ -2104,7 +2106,7 @@ err_ret:
2104 return ret; 2106 return ret;
2105} 2107}
2106 2108
2107static void __exit rivafb_remove(struct pci_dev *pd) 2109static void __devexit rivafb_remove(struct pci_dev *pd)
2108{ 2110{
2109 struct fb_info *info = pci_get_drvdata(pd); 2111 struct fb_info *info = pci_get_drvdata(pd);
2110 struct riva_par *par = info->par; 2112 struct riva_par *par = info->par;
@@ -2185,7 +2187,7 @@ static struct pci_driver rivafb_driver = {
2185 .name = "rivafb", 2187 .name = "rivafb",
2186 .id_table = rivafb_pci_tbl, 2188 .id_table = rivafb_pci_tbl,
2187 .probe = rivafb_probe, 2189 .probe = rivafb_probe,
2188 .remove = __exit_p(rivafb_remove), 2190 .remove = __devexit_p(rivafb_remove),
2189}; 2191};
2190 2192
2191 2193
diff --git a/drivers/video/riva/nv4ref.h b/drivers/video/riva/nv4ref.h
deleted file mode 100644
index 3b5f9117c37d..000000000000
--- a/drivers/video/riva/nv4ref.h
+++ /dev/null
@@ -1,2445 +0,0 @@
1 /***************************************************************************\
2|* *|
3|* Copyright 1993-1998 NVIDIA, Corporation. All rights reserved. *|
4|* *|
5|* NOTICE TO USER: The source code is copyrighted under U.S. and *|
6|* international laws. Users and possessors of this source code are *|
7|* hereby granted a nonexclusive, royalty-free copyright license to *|
8|* use this code in individual and commercial software. *|
9|* *|
10|* Any use of this source code must include, in the user documenta- *|
11|* tion and internal comments to the code, notices to the end user *|
12|* as follows: *|
13|* *|
14|* Copyright 1993-1998 NVIDIA, Corporation. All rights reserved. *|
15|* *|
16|* NVIDIA, CORPORATION MAKES NO REPRESENTATION ABOUT THE SUITABILITY *|
17|* OF THIS SOURCE CODE FOR ANY PURPOSE. IT IS PROVIDED "AS IS" *|
18|* WITHOUT EXPRESS OR IMPLIED WARRANTY OF ANY KIND. NVIDIA, CORPOR- *|
19|* ATION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOURCE CODE, *|
20|* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGE- *|
21|* MENT, AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL *|
22|* NVIDIA, CORPORATION BE LIABLE FOR ANY SPECIAL, INDIRECT, INCI- *|
23|* DENTAL, OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RE- *|
24|* SULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION *|
25|* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF *|
26|* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOURCE CODE. *|
27|* *|
28|* U.S. Government End Users. This source code is a "commercial *|
29|* item," as that term is defined at 48 C.F.R. 2.101 (OCT 1995), *|
30|* consisting of "commercial computer software" and "commercial *|
31|* computer software documentation," as such terms are used in *|
32|* 48 C.F.R. 12.212 (SEPT 1995) and is provided to the U.S. Govern- *|
33|* ment only as a commercial end item. Consistent with 48 C.F.R. *|
34|* 12.212 and 48 C.F.R. 227.7202-1 through 227.7202-4 (JUNE 1995), *|
35|* all U.S. Government End Users acquire the source code with only *|
36|* those rights set forth herein. *|
37|* *|
38 \***************************************************************************/
39
40/*
41 * GPL licensing note -- nVidia is allowing a liberal interpretation of
42 * the documentation restriction above, to merely say that this nVidia's
43 * copyright and disclaimer should be included with all code derived
44 * from this source. -- Jeff Garzik <jgarzik@pobox.com>, 01/Nov/99
45 */
46
47 /***************************************************************************\
48|* Modified 1999 by Fredrik Reite (fredrik@reite.com) *|
49 \***************************************************************************/
50
51
52#ifndef __NV4REF_H__
53#define __NV4REF_H__
54
55/* Magic values to lock/unlock extended regs */
56#define NV_CIO_SR_LOCK_INDEX 0x0000001F /* */
57#define NV_CIO_SR_UNLOCK_RW_VALUE 0x00000057 /* */
58#define NV_CIO_SR_UNLOCK_RO_VALUE 0x00000075 /* */
59#define NV_CIO_SR_LOCK_VALUE 0x00000099 /* */
60
61#define UNLOCK_EXT_MAGIC 0x57
62#define LOCK_EXT_MAGIC 0x99 /* Any value other than 0x57 will do */
63
64#define LOCK_EXT_INDEX 0x6
65
66#define NV_PCRTC_HORIZ_TOTAL 0x00
67#define NV_PCRTC_HORIZ_DISPLAY_END 0x01
68#define NV_PCRTC_HORIZ_BLANK_START 0x02
69
70#define NV_PCRTC_HORIZ_BLANK_END 0x03
71#define NV_PCRTC_HORIZ_BLANK_END_EVRA 7:7
72#define NV_PCRTC_HORIZ_BLANK_END_DISPLAY_END_SKEW 6:5
73#define NV_PCRTC_HORIZ_BLANK_END_HORIZ_BLANK_END 4:0
74
75#define NV_PCRTC_HORIZ_RETRACE_START 0x04
76
77#define NV_PCRTC_HORIZ_RETRACE_END 0x05
78#define NV_PCRTC_HORIZ_RETRACE_END_HORIZ_BLANK_END_5 7:7
79#define NV_PCRTC_HORIZ_RETRACE_END_HORIZ_RETRACE_SKEW 6:5
80#define NV_PCRTC_HORIZ_RETRACE_END_HORIZ_RETRACE_END 4:0
81
82#define NV_PCRTC_VERT_TOTAL 0x06
83
84#define NV_PCRTC_OVERFLOW 0x07
85#define NV_PCRTC_OVERFLOW_VERT_RETRACE_START_9 7:7
86#define NV_PCRTC_OVERFLOW_VERT_DISPLAY_END_9 6:6
87#define NV_PCRTC_OVERFLOW_VERT_TOTAL_9 5:5
88#define NV_PCRTC_OVERFLOW_LINE_COMPARE_8 4:4
89#define NV_PCRTC_OVERFLOW_VERT_BLANK_START_8 3:3
90#define NV_PCRTC_OVERFLOW_VERT_RETRACE_START_8 2:2
91#define NV_PCRTC_OVERFLOW_VERT_DISPLAY_END_8 1:1
92#define NV_PCRTC_OVERFLOW_VERT_TOTAL_8 0:0
93
94#define NV_PCRTC_PRESET_ROW_SCAN 0x08
95
96#define NV_PCRTC_MAX_SCAN_LINE 0x09
97#define NV_PCRTC_MAX_SCAN_LINE_DOUBLE_SCAN 7:7
98#define NV_PCRTC_MAX_SCAN_LINE_LINE_COMPARE_9 6:6
99#define NV_PCRTC_MAX_SCAN_LINE_VERT_BLANK_START_9 5:5
100#define NV_PCRTC_MAX_SCAN_LINE_MAX_SCAN_LINE 4:0
101
102#define NV_PCRTC_CURSOR_START 0x0A
103#define NV_PCRTC_CURSOR_END 0x0B
104#define NV_PCRTC_START_ADDR_HIGH 0x0C
105#define NV_PCRTC_START_ADDR_LOW 0x0D
106#define NV_PCRTC_CURSOR_LOCATION_HIGH 0x0E
107#define NV_PCRTC_CURSOR_LOCATION_LOW 0x0F
108
109#define NV_PCRTC_VERT_RETRACE_START 0x10
110#define NV_PCRTC_VERT_RETRACE_END 0x11
111#define NV_PCRTC_VERT_DISPLAY_END 0x12
112#define NV_PCRTC_OFFSET 0x13
113#define NV_PCRTC_UNDERLINE_LOCATION 0x14
114#define NV_PCRTC_VERT_BLANK_START 0x15
115#define NV_PCRTC_VERT_BLANK_END 0x16
116#define NV_PCRTC_MODE_CONTROL 0x17
117#define NV_PCRTC_LINE_COMPARE 0x18
118
119/* Extended offset and start address */
120#define NV_PCRTC_REPAINT0 0x19
121#define NV_PCRTC_REPAINT0_OFFSET_10_8 7:5
122#define NV_PCRTC_REPAINT0_START_ADDR_20_16 4:0
123
124/* Horizonal extended bits */
125#define NV_PCRTC_HORIZ_EXTRA 0x2d
126#define NV_PCRTC_HORIZ_EXTRA_INTER_HALF_START_8 4:4
127#define NV_PCRTC_HORIZ_EXTRA_HORIZ_RETRACE_START_8 3:3
128#define NV_PCRTC_HORIZ_EXTRA_HORIZ_BLANK_START_8 2:2
129#define NV_PCRTC_HORIZ_EXTRA_DISPLAY_END_8 1:1
130#define NV_PCRTC_HORIZ_EXTRA_DISPLAY_TOTAL_8 0:0
131
132/* Assorted extra bits */
133#define NV_PCRTC_EXTRA 0x25
134#define NV_PCRTC_EXTRA_OFFSET_11 5:5
135#define NV_PCRTC_EXTRA_HORIZ_BLANK_END_6 4:4
136#define NV_PCRTC_EXTRA_VERT_BLANK_START_10 3:3
137#define NV_PCRTC_EXTRA_VERT_RETRACE_START_10 2:2
138#define NV_PCRTC_EXTRA_VERT_DISPLAY_END_10 1:1
139#define NV_PCRTC_EXTRA_VERT_TOTAL_10 0:0
140
141/* Controls how much data the refresh fifo requests */
142#define NV_PCRTC_FIFO_CONTROL 0x1b
143#define NV_PCRTC_FIFO_CONTROL_UNDERFLOW_WARN 7:7
144#define NV_PCRTC_FIFO_CONTROL_BURST_LENGTH 2:0
145#define NV_PCRTC_FIFO_CONTROL_BURST_LENGTH_8 0x0
146#define NV_PCRTC_FIFO_CONTROL_BURST_LENGTH_32 0x1
147#define NV_PCRTC_FIFO_CONTROL_BURST_LENGTH_64 0x2
148#define NV_PCRTC_FIFO_CONTROL_BURST_LENGTH_128 0x3
149#define NV_PCRTC_FIFO_CONTROL_BURST_LENGTH_256 0x4
150
151/* When the fifo occupancy falls below *twice* the watermark,
152 * the refresh fifo will start to be refilled. If this value is
153 * too low, you will get junk on the screen. Too high, and performance
154 * will suffer. Watermark in units of 8 bytes
155 */
156#define NV_PCRTC_FIFO 0x20
157#define NV_PCRTC_FIFO_RESET 7:7
158#define NV_PCRTC_FIFO_WATERMARK 5:0
159
160/* Various flags */
161#define NV_PCRTC_REPAINT1 0x1a
162#define NV_PCRTC_REPAINT1_HSYNC 7:7
163#define NV_PCRTC_REPAINT1_HYSNC_DISABLE 0x01
164#define NV_PCRTC_REPAINT1_HYSNC_ENABLE 0x00
165#define NV_PCRTC_REPAINT1_VSYNC 6:6
166#define NV_PCRTC_REPAINT1_VYSNC_DISABLE 0x01
167#define NV_PCRTC_REPAINT1_VYSNC_ENABLE 0x00
168#define NV_PCRTC_REPAINT1_COMPATIBLE_TEXT 4:4
169#define NV_PCRTC_REPAINT1_COMPATIBLE_TEXT_ENABLE 0x01
170#define NV_PCRTC_REPAINT1_COMPATIBLE_TEXT_DISABLE 0x00
171#define NV_PCRTC_REPAINT1_LARGE_SCREEN 2:2
172#define NV_PCRTC_REPAINT1_LARGE_SCREEN_DISABLE 0x01
173#define NV_PCRTC_REPAINT1_LARGE_SCREEN_ENABLE 0x00 /* >=1280 */
174#define NV_PCRTC_REPAINT1_PALETTE_WIDTH 1:1
175#define NV_PCRTC_REPAINT1_PALETTE_WIDTH_8BITS 0x00
176#define NV_PCRTC_REPAINT1_PALETTE_WIDTH_6BITS 0x01
177
178#define NV_PCRTC_GRCURSOR0 0x30
179#define NV_PCRTC_GRCURSOR0_START_ADDR_21_16 5:0
180
181#define NV_PCRTC_GRCURSOR1 0x31
182#define NV_PCRTC_GRCURSOR1_START_ADDR_15_11 7:3
183#define NV_PCRTC_GRCURSOR1_SCAN_DBL 1:1
184#define NV_PCRTC_GRCURSOR1_SCAN_DBL_DISABLE 0
185#define NV_PCRTC_GRCURSOR1_SCAN_DBL_ENABLE 1
186#define NV_PCRTC_GRCURSOR1_CURSOR 0:0
187#define NV_PCRTC_GRCURSOR1_CURSOR_DISABLE 0
188#define NV_PCRTC_GRCURSOR1_CURSOR_ENABLE 1
189
190/* Controls what the format of the framebuffer is */
191#define NV_PCRTC_PIXEL 0x28
192#define NV_PCRTC_PIXEL_MODE 7:7
193#define NV_PCRTC_PIXEL_MODE_TV 0x01
194#define NV_PCRTC_PIXEL_MODE_VGA 0x00
195#define NV_PCRTC_PIXEL_TV_MODE 6:6
196#define NV_PCRTC_PIXEL_TV_MODE_NTSC 0x00
197#define NV_PCRTC_PIXEL_TV_MODE_PAL 0x01
198#define NV_PCRTC_PIXEL_TV_HORIZ_ADJUST 5:3
199#define NV_PCRTC_PIXEL_FORMAT 1:0
200#define NV_PCRTC_PIXEL_FORMAT_VGA 0x00
201#define NV_PCRTC_PIXEL_FORMAT_8BPP 0x01
202#define NV_PCRTC_PIXEL_FORMAT_16BPP 0x02
203#define NV_PCRTC_PIXEL_FORMAT_32BPP 0x03
204
205/* RAMDAC registers and fields */
206#define NV_PRAMDAC 0x00680FFF:0x00680000 /* RW--D */
207#define NV_PRAMDAC_GRCURSOR_START_POS 0x00680300 /* RW-4R */
208#define NV_PRAMDAC_GRCURSOR_START_POS_X 11:0 /* RWXSF */
209#define NV_PRAMDAC_GRCURSOR_START_POS_Y 27:16 /* RWXSF */
210#define NV_PRAMDAC_NVPLL_COEFF 0x00680500 /* RW-4R */
211#define NV_PRAMDAC_NVPLL_COEFF_MDIV 7:0 /* RWIUF */
212#define NV_PRAMDAC_NVPLL_COEFF_NDIV 15:8 /* RWIUF */
213#define NV_PRAMDAC_NVPLL_COEFF_PDIV 18:16 /* RWIVF */
214#define NV_PRAMDAC_MPLL_COEFF 0x00680504 /* RW-4R */
215#define NV_PRAMDAC_MPLL_COEFF_MDIV 7:0 /* RWIUF */
216#define NV_PRAMDAC_MPLL_COEFF_NDIV 15:8 /* RWIUF */
217#define NV_PRAMDAC_MPLL_COEFF_PDIV 18:16 /* RWIVF */
218#define NV_PRAMDAC_VPLL_COEFF 0x00680508 /* RW-4R */
219#define NV_PRAMDAC_VPLL_COEFF_MDIV 7:0 /* RWIUF */
220#define NV_PRAMDAC_VPLL_COEFF_NDIV 15:8 /* RWIUF */
221#define NV_PRAMDAC_VPLL_COEFF_PDIV 18:16 /* RWIVF */
222#define NV_PRAMDAC_PLL_COEFF_SELECT 0x0068050C /* RW-4R */
223#define NV_PRAMDAC_PLL_COEFF_SELECT_DLL_BYPASS 4:4 /* RWIVF */
224#define NV_PRAMDAC_PLL_COEFF_SELECT_DLL_BYPASS_FALSE 0x00000000 /* RWI-V */
225#define NV_PRAMDAC_PLL_COEFF_SELECT_DLL_BYPASS_TRUE 0x00000001 /* RW--V */
226#define NV_PRAMDAC_PLL_COEFF_SELECT_MPLL_SOURCE 8:8 /* RWIVF */
227#define NV_PRAMDAC_PLL_COEFF_SELECT_MPLL_SOURCE_DEFAULT 0x00000000 /* RWI-V */
228#define NV_PRAMDAC_PLL_COEFF_SELECT_MPLL_SOURCE_PROG 0x00000001 /* RW--V */
229#define NV_PRAMDAC_PLL_COEFF_SELECT_MPLL_BYPASS 12:12 /* RWIVF */
230#define NV_PRAMDAC_PLL_COEFF_SELECT_MPLL_BYPASS_FALSE 0x00000000 /* RWI-V */
231#define NV_PRAMDAC_PLL_COEFF_SELECT_MPLL_BYPASS_TRUE 0x00000001 /* RW--V */
232#define NV_PRAMDAC_PLL_COEFF_SELECT_VPLL_SOURCE 16:16 /* RWIVF */
233#define NV_PRAMDAC_PLL_COEFF_SELECT_VPLL_SOURCE_DEFAULT 0x00000000 /* RWI-V */
234#define NV_PRAMDAC_PLL_COEFF_SELECT_VPLL_SOURCE_PROG 0x00000001 /* RW--V */
235#define NV_PRAMDAC_PLL_COEFF_SELECT_VPLL_BYPASS 20:20 /* RWIVF */
236#define NV_PRAMDAC_PLL_COEFF_SELECT_VPLL_BYPASS_FALSE 0x00000000 /* RWI-V */
237#define NV_PRAMDAC_PLL_COEFF_SELECT_VPLL_BYPASS_TRUE 0x00000001 /* RW--V */
238#define NV_PRAMDAC_PLL_COEFF_SELECT_PCLK_SOURCE 25:24 /* RWIVF */
239#define NV_PRAMDAC_PLL_COEFF_SELECT_PCLK_SOURCE_VPLL 0x00000000 /* RWI-V */
240#define NV_PRAMDAC_PLL_COEFF_SELECT_PCLK_SOURCE_VIP 0x00000001 /* RW--V */
241#define NV_PRAMDAC_PLL_COEFF_SELECT_PCLK_SOURCE_XTALOSC 0x00000002 /* RW--V */
242#define NV_PRAMDAC_PLL_COEFF_SELECT_VCLK_RATIO 28:28 /* RWIVF */
243#define NV_PRAMDAC_PLL_COEFF_SELECT_VCLK_RATIO_DB1 0x00000000 /* RWI-V */
244#define NV_PRAMDAC_PLL_COEFF_SELECT_VCLK_RATIO_DB2 0x00000001 /* RW--V */
245#define NV_PRAMDAC_GENERAL_CONTROL 0x00680600 /* RW-4R */
246#define NV_PRAMDAC_GENERAL_CONTROL_FF_COEFF 1:0 /* RWIVF */
247#define NV_PRAMDAC_GENERAL_CONTROL_FF_COEFF_DEF 0x00000000 /* RWI-V */
248#define NV_PRAMDAC_GENERAL_CONTROL_IDC_MODE 4:4 /* RWIVF */
249#define NV_PRAMDAC_GENERAL_CONTROL_IDC_MODE_GAMMA 0x00000000 /* RWI-V */
250#define NV_PRAMDAC_GENERAL_CONTROL_IDC_MODE_INDEX 0x00000001 /* RW--V */
251#define NV_PRAMDAC_GENERAL_CONTROL_VGA_STATE 8:8 /* RWIVF */
252#define NV_PRAMDAC_GENERAL_CONTROL_VGA_STATE_NOTSE 0x00000000 /* RWI-V */
253#define NV_PRAMDAC_GENERAL_CONTROL_VGA_STATE_SEL 0x00000001 /* RW--V */
254#define NV_PRAMDAC_GENERAL_CONTROL_565_MODE 12:12 /* RWIVF */
255#define NV_PRAMDAC_GENERAL_CONTROL_565_MODE_NOTSEL 0x00000000 /* RWI-V */
256#define NV_PRAMDAC_GENERAL_CONTROL_565_MODE_SEL 0x00000001 /* RW--V */
257#define NV_PRAMDAC_GENERAL_CONTROL_BLK_PEDSTL 16:16 /* RWIVF */
258#define NV_PRAMDAC_GENERAL_CONTROL_BLK_PEDSTL_OFF 0x00000000 /* RWI-V */
259#define NV_PRAMDAC_GENERAL_CONTROL_BLK_PEDSTL_ON 0x00000001 /* RW--V */
260#define NV_PRAMDAC_GENERAL_CONTROL_TERMINATION 17:17 /* RWIVF */
261#define NV_PRAMDAC_GENERAL_CONTROL_TERMINATION_37OHM 0x00000000 /* RWI-V */
262#define NV_PRAMDAC_GENERAL_CONTROL_TERMINATION_75OHM 0x00000001 /* RW--V */
263#define NV_PRAMDAC_GENERAL_CONTROL_BPC 20:20 /* RWIVF */
264#define NV_PRAMDAC_GENERAL_CONTROL_BPC_6BITS 0x00000000 /* RWI-V */
265#define NV_PRAMDAC_GENERAL_CONTROL_BPC_8BITS 0x00000001 /* RW--V */
266#define NV_PRAMDAC_GENERAL_CONTROL_DAC_SLEEP 24:24 /* RWIVF */
267#define NV_PRAMDAC_GENERAL_CONTROL_DAC_SLEEP_DIS 0x00000000 /* RWI-V */
268#define NV_PRAMDAC_GENERAL_CONTROL_DAC_SLEEP_EN 0x00000001 /* RW--V */
269#define NV_PRAMDAC_GENERAL_CONTROL_PALETTE_CLK 28:28 /* RWIVF */
270#define NV_PRAMDAC_GENERAL_CONTROL_PALETTE_CLK_EN 0x00000000 /* RWI-V */
271#define NV_PRAMDAC_GENERAL_CONTROL_PALETTE_CLK_DIS 0x00000001 /* RW--V */
272
273/* Master Control */
274#define NV_PMC 0x00000FFF:0x00000000 /* RW--D */
275#define NV_PMC_BOOT_0 0x00000000 /* R--4R */
276#define NV_PMC_BOOT_0_MINOR_REVISION 3:0 /* C--VF */
277#define NV_PMC_BOOT_0_MINOR_REVISION_0 0x00000000 /* C---V */
278#define NV_PMC_BOOT_0_MAJOR_REVISION 7:4 /* C--VF */
279#define NV_PMC_BOOT_0_MAJOR_REVISION_A 0x00000000 /* C---V */
280#define NV_PMC_BOOT_0_MAJOR_REVISION_B 0x00000001 /* ----V */
281#define NV_PMC_BOOT_0_IMPLEMENTATION 11:8 /* C--VF */
282#define NV_PMC_BOOT_0_IMPLEMENTATION_NV4_0 0x00000000 /* C---V */
283#define NV_PMC_BOOT_0_ARCHITECTURE 15:12 /* C--VF */
284#define NV_PMC_BOOT_0_ARCHITECTURE_NV0 0x00000000 /* ----V */
285#define NV_PMC_BOOT_0_ARCHITECTURE_NV1 0x00000001 /* ----V */
286#define NV_PMC_BOOT_0_ARCHITECTURE_NV2 0x00000002 /* ----V */
287#define NV_PMC_BOOT_0_ARCHITECTURE_NV3 0x00000003 /* ----V */
288#define NV_PMC_BOOT_0_ARCHITECTURE_NV4 0x00000004 /* C---V */
289#define NV_PMC_BOOT_0_FIB_REVISION 19:16 /* C--VF */
290#define NV_PMC_BOOT_0_FIB_REVISION_0 0x00000000 /* C---V */
291#define NV_PMC_BOOT_0_MASK_REVISION 23:20 /* C--VF */
292#define NV_PMC_BOOT_0_MASK_REVISION_A 0x00000000 /* C---V */
293#define NV_PMC_BOOT_0_MASK_REVISION_B 0x00000001 /* ----V */
294#define NV_PMC_BOOT_0_MANUFACTURER 27:24 /* C--UF */
295#define NV_PMC_BOOT_0_MANUFACTURER_NVIDIA 0x00000000 /* C---V */
296#define NV_PMC_BOOT_0_FOUNDRY 31:28 /* C--VF */
297#define NV_PMC_BOOT_0_FOUNDRY_SGS 0x00000000 /* ----V */
298#define NV_PMC_BOOT_0_FOUNDRY_HELIOS 0x00000001 /* ----V */
299#define NV_PMC_BOOT_0_FOUNDRY_TSMC 0x00000002 /* C---V */
300#define NV_PMC_INTR_0 0x00000100 /* RW-4R */
301#define NV_PMC_INTR_0_PMEDIA 4:4 /* R--VF */
302#define NV_PMC_INTR_0_PMEDIA_NOT_PENDING 0x00000000 /* R---V */
303#define NV_PMC_INTR_0_PMEDIA_PENDING 0x00000001 /* R---V */
304#define NV_PMC_INTR_0_PFIFO 8:8 /* R--VF */
305#define NV_PMC_INTR_0_PFIFO_NOT_PENDING 0x00000000 /* R---V */
306#define NV_PMC_INTR_0_PFIFO_PENDING 0x00000001 /* R---V */
307#define NV_PMC_INTR_0_PGRAPH 12:12 /* R--VF */
308#define NV_PMC_INTR_0_PGRAPH_NOT_PENDING 0x00000000 /* R---V */
309#define NV_PMC_INTR_0_PGRAPH_PENDING 0x00000001 /* R---V */
310#define NV_PMC_INTR_0_PVIDEO 16:16 /* R--VF */
311#define NV_PMC_INTR_0_PVIDEO_NOT_PENDING 0x00000000 /* R---V */
312#define NV_PMC_INTR_0_PVIDEO_PENDING 0x00000001 /* R---V */
313#define NV_PMC_INTR_0_PTIMER 20:20 /* R--VF */
314#define NV_PMC_INTR_0_PTIMER_NOT_PENDING 0x00000000 /* R---V */
315#define NV_PMC_INTR_0_PTIMER_PENDING 0x00000001 /* R---V */
316#define NV_PMC_INTR_0_PCRTC 24:24 /* R--VF */
317#define NV_PMC_INTR_0_PCRTC_NOT_PENDING 0x00000000 /* R---V */
318#define NV_PMC_INTR_0_PCRTC_PENDING 0x00000001 /* R---V */
319#define NV_PMC_INTR_0_PBUS 28:28 /* R--VF */
320#define NV_PMC_INTR_0_PBUS_NOT_PENDING 0x00000000 /* R---V */
321#define NV_PMC_INTR_0_PBUS_PENDING 0x00000001 /* R---V */
322#define NV_PMC_INTR_0_SOFTWARE 31:31 /* RWIVF */
323#define NV_PMC_INTR_0_SOFTWARE_NOT_PENDING 0x00000000 /* RWI-V */
324#define NV_PMC_INTR_0_SOFTWARE_PENDING 0x00000001 /* RW--V */
325#define NV_PMC_INTR_EN_0 0x00000140 /* RW-4R */
326#define NV_PMC_INTR_EN_0_INTA 1:0 /* RWIVF */
327#define NV_PMC_INTR_EN_0_INTA_DISABLED 0x00000000 /* RWI-V */
328#define NV_PMC_INTR_EN_0_INTA_HARDWARE 0x00000001 /* RW--V */
329#define NV_PMC_INTR_EN_0_INTA_SOFTWARE 0x00000002 /* RW--V */
330#define NV_PMC_INTR_READ_0 0x00000160 /* R--4R */
331#define NV_PMC_INTR_READ_0_INTA 0:0 /* R--VF */
332#define NV_PMC_INTR_READ_0_INTA_LOW 0x00000000 /* R---V */
333#define NV_PMC_INTR_READ_0_INTA_HIGH 0x00000001 /* R---V */
334#define NV_PMC_ENABLE 0x00000200 /* RW-4R */
335#define NV_PMC_ENABLE_PMEDIA 4:4 /* RWIVF */
336#define NV_PMC_ENABLE_PMEDIA_DISABLED 0x00000000 /* RWI-V */
337#define NV_PMC_ENABLE_PMEDIA_ENABLED 0x00000001 /* RW--V */
338#define NV_PMC_ENABLE_PFIFO 8:8 /* RWIVF */
339#define NV_PMC_ENABLE_PFIFO_DISABLED 0x00000000 /* RWI-V */
340#define NV_PMC_ENABLE_PFIFO_ENABLED 0x00000001 /* RW--V */
341#define NV_PMC_ENABLE_PGRAPH 12:12 /* RWIVF */
342#define NV_PMC_ENABLE_PGRAPH_DISABLED 0x00000000 /* RWI-V */
343#define NV_PMC_ENABLE_PGRAPH_ENABLED 0x00000001 /* RW--V */
344#define NV_PMC_ENABLE_PPMI 16:16 /* RWIVF */
345#define NV_PMC_ENABLE_PPMI_DISABLED 0x00000000 /* RWI-V */
346#define NV_PMC_ENABLE_PPMI_ENABLED 0x00000001 /* RW--V */
347#define NV_PMC_ENABLE_PFB 20:20 /* RWIVF */
348#define NV_PMC_ENABLE_PFB_DISABLED 0x00000000 /* RW--V */
349#define NV_PMC_ENABLE_PFB_ENABLED 0x00000001 /* RWI-V */
350#define NV_PMC_ENABLE_PCRTC 24:24 /* RWIVF */
351#define NV_PMC_ENABLE_PCRTC_DISABLED 0x00000000 /* RW--V */
352#define NV_PMC_ENABLE_PCRTC_ENABLED 0x00000001 /* RWI-V */
353#define NV_PMC_ENABLE_PVIDEO 28:28 /* RWIVF */
354#define NV_PMC_ENABLE_PVIDEO_DISABLED 0x00000000 /* RWI-V */
355#define NV_PMC_ENABLE_PVIDEO_ENABLED 0x00000001 /* RW--V */
356
357/* dev_timer.ref */
358#define NV_PTIMER 0x00009FFF:0x00009000 /* RW--D */
359#define NV_PTIMER_INTR_0 0x00009100 /* RW-4R */
360#define NV_PTIMER_INTR_0_ALARM 0:0 /* RWXVF */
361#define NV_PTIMER_INTR_0_ALARM_NOT_PENDING 0x00000000 /* R---V */
362#define NV_PTIMER_INTR_0_ALARM_PENDING 0x00000001 /* R---V */
363#define NV_PTIMER_INTR_0_ALARM_RESET 0x00000001 /* -W--V */
364#define NV_PTIMER_INTR_EN_0 0x00009140 /* RW-4R */
365#define NV_PTIMER_INTR_EN_0_ALARM 0:0 /* RWIVF */
366#define NV_PTIMER_INTR_EN_0_ALARM_DISABLED 0x00000000 /* RWI-V */
367#define NV_PTIMER_INTR_EN_0_ALARM_ENABLED 0x00000001 /* RW--V */
368#define NV_PTIMER_NUMERATOR 0x00009200 /* RW-4R */
369#define NV_PTIMER_NUMERATOR_VALUE 15:0 /* RWIUF */
370#define NV_PTIMER_NUMERATOR_VALUE_0 0x00000000 /* RWI-V */
371#define NV_PTIMER_DENOMINATOR 0x00009210 /* RW-4R */
372#define NV_PTIMER_DENOMINATOR_VALUE 15:0 /* RWIUF */
373#define NV_PTIMER_DENOMINATOR_VALUE_0 0x00000000 /* RWI-V */
374#define NV_PTIMER_TIME_0 0x00009400 /* RW-4R */
375#define NV_PTIMER_TIME_0_NSEC 31:5 /* RWXUF */
376#define NV_PTIMER_TIME_1 0x00009410 /* RW-4R */
377#define NV_PTIMER_TIME_1_NSEC 28:0 /* RWXUF */
378#define NV_PTIMER_ALARM_0 0x00009420 /* RW-4R */
379#define NV_PTIMER_ALARM_0_NSEC 31:5 /* RWXUF */
380
381/* dev_fifo.ref */
382#define NV_PFIFO 0x00003FFF:0x00002000 /* RW--D */
383#define NV_PFIFO_DELAY_0 0x00002040 /* RW-4R */
384#define NV_PFIFO_DELAY_0_WAIT_RETRY 9:0 /* RWIUF */
385#define NV_PFIFO_DELAY_0_WAIT_RETRY_0 0x00000000 /* RWI-V */
386#define NV_PFIFO_DMA_TIMESLICE 0x00002044 /* RW-4R */
387#define NV_PFIFO_DMA_TIMESLICE_SELECT 16:0 /* RWIUF */
388#define NV_PFIFO_DMA_TIMESLICE_SELECT_1 0x00000000 /* RWI-V */
389#define NV_PFIFO_DMA_TIMESLICE_SELECT_16K 0x00003fff /* RW--V */
390#define NV_PFIFO_DMA_TIMESLICE_SELECT_32K 0x00007fff /* RW--V */
391#define NV_PFIFO_DMA_TIMESLICE_SELECT_64K 0x0000ffff /* RW--V */
392#define NV_PFIFO_DMA_TIMESLICE_SELECT_128K 0x0001ffff /* RW--V */
393#define NV_PFIFO_DMA_TIMESLICE_TIMEOUT 24:24 /* RWIUF */
394#define NV_PFIFO_DMA_TIMESLICE_TIMEOUT_DISABLED 0x00000000 /* RW--V */
395#define NV_PFIFO_DMA_TIMESLICE_TIMEOUT_ENABLED 0x00000001 /* RWI-V */
396#define NV_PFIFO_PIO_TIMESLICE 0x00002048 /* RW-4R */
397#define NV_PFIFO_PIO_TIMESLICE_SELECT 16:0 /* RWIUF */
398#define NV_PFIFO_PIO_TIMESLICE_SELECT_1 0x00000000 /* RWI-V */
399#define NV_PFIFO_PIO_TIMESLICE_SELECT_16K 0x00003fff /* RW--V */
400#define NV_PFIFO_PIO_TIMESLICE_SELECT_32K 0x00007fff /* RW--V */
401#define NV_PFIFO_PIO_TIMESLICE_SELECT_64K 0x0000ffff /* RW--V */
402#define NV_PFIFO_PIO_TIMESLICE_SELECT_128K 0x0001ffff /* RW--V */
403#define NV_PFIFO_PIO_TIMESLICE_TIMEOUT 24:24 /* RWIUF */
404#define NV_PFIFO_PIO_TIMESLICE_TIMEOUT_DISABLED 0x00000000 /* RW--V */
405#define NV_PFIFO_PIO_TIMESLICE_TIMEOUT_ENABLED 0x00000001 /* RWI-V */
406#define NV_PFIFO_TIMESLICE 0x0000204C /* RW-4R */
407#define NV_PFIFO_TIMESLICE_TIMER 17:0 /* RWIUF */
408#define NV_PFIFO_TIMESLICE_TIMER_EXPIRED 0x0003FFFF /* RWI-V */
409#define NV_PFIFO_NEXT_CHANNEL 0x00002050 /* RW-4R */
410#define NV_PFIFO_NEXT_CHANNEL_CHID 3:0 /* RWXUF */
411#define NV_PFIFO_NEXT_CHANNEL_MODE 8:8 /* RWXVF */
412#define NV_PFIFO_NEXT_CHANNEL_MODE_PIO 0x00000000 /* RW--V */
413#define NV_PFIFO_NEXT_CHANNEL_MODE_DMA 0x00000001 /* RW--V */
414#define NV_PFIFO_NEXT_CHANNEL_SWITCH 12:12 /* RWIVF */
415#define NV_PFIFO_NEXT_CHANNEL_SWITCH_NOT_PENDING 0x00000000 /* RWI-V */
416#define NV_PFIFO_NEXT_CHANNEL_SWITCH_PENDING 0x00000001 /* RW--V */
417#define NV_PFIFO_DEBUG_0 0x00002080 /* R--4R */
418#define NV_PFIFO_DEBUG_0_CACHE_ERROR0 0:0 /* R-XVF */
419#define NV_PFIFO_DEBUG_0_CACHE_ERROR0_NOT_PENDING 0x00000000 /* R---V */
420#define NV_PFIFO_DEBUG_0_CACHE_ERROR0_PENDING 0x00000001 /* R---V */
421#define NV_PFIFO_DEBUG_0_CACHE_ERROR1 4:4 /* R-XVF */
422#define NV_PFIFO_DEBUG_0_CACHE_ERROR1_NOT_PENDING 0x00000000 /* R---V */
423#define NV_PFIFO_DEBUG_0_CACHE_ERROR1_PENDING 0x00000001 /* R---V */
424#define NV_PFIFO_INTR_0 0x00002100 /* RW-4R */
425#define NV_PFIFO_INTR_0_CACHE_ERROR 0:0 /* RWXVF */
426#define NV_PFIFO_INTR_0_CACHE_ERROR_NOT_PENDING 0x00000000 /* R---V */
427#define NV_PFIFO_INTR_0_CACHE_ERROR_PENDING 0x00000001 /* R---V */
428#define NV_PFIFO_INTR_0_CACHE_ERROR_RESET 0x00000001 /* -W--V */
429#define NV_PFIFO_INTR_0_RUNOUT 4:4 /* RWXVF */
430#define NV_PFIFO_INTR_0_RUNOUT_NOT_PENDING 0x00000000 /* R---V */
431#define NV_PFIFO_INTR_0_RUNOUT_PENDING 0x00000001 /* R---V */
432#define NV_PFIFO_INTR_0_RUNOUT_RESET 0x00000001 /* -W--V */
433#define NV_PFIFO_INTR_0_RUNOUT_OVERFLOW 8:8 /* RWXVF */
434#define NV_PFIFO_INTR_0_RUNOUT_OVERFLOW_NOT_PENDING 0x00000000 /* R---V */
435#define NV_PFIFO_INTR_0_RUNOUT_OVERFLOW_PENDING 0x00000001 /* R---V */
436#define NV_PFIFO_INTR_0_RUNOUT_OVERFLOW_RESET 0x00000001 /* -W--V */
437#define NV_PFIFO_INTR_0_DMA_PUSHER 12:12 /* RWXVF */
438#define NV_PFIFO_INTR_0_DMA_PUSHER_NOT_PENDING 0x00000000 /* R---V */
439#define NV_PFIFO_INTR_0_DMA_PUSHER_PENDING 0x00000001 /* R---V */
440#define NV_PFIFO_INTR_0_DMA_PUSHER_RESET 0x00000001 /* -W--V */
441#define NV_PFIFO_INTR_0_DMA_PT 16:16 /* RWXVF */
442#define NV_PFIFO_INTR_0_DMA_PT_NOT_PENDING 0x00000000 /* R---V */
443#define NV_PFIFO_INTR_0_DMA_PT_PENDING 0x00000001 /* R---V */
444#define NV_PFIFO_INTR_0_DMA_PT_RESET 0x00000001 /* -W--V */
445#define NV_PFIFO_INTR_EN_0 0x00002140 /* RW-4R */
446#define NV_PFIFO_INTR_EN_0_CACHE_ERROR 0:0 /* RWIVF */
447#define NV_PFIFO_INTR_EN_0_CACHE_ERROR_DISABLED 0x00000000 /* RWI-V */
448#define NV_PFIFO_INTR_EN_0_CACHE_ERROR_ENABLED 0x00000001 /* RW--V */
449#define NV_PFIFO_INTR_EN_0_RUNOUT 4:4 /* RWIVF */
450#define NV_PFIFO_INTR_EN_0_RUNOUT_DISABLED 0x00000000 /* RWI-V */
451#define NV_PFIFO_INTR_EN_0_RUNOUT_ENABLED 0x00000001 /* RW--V */
452#define NV_PFIFO_INTR_EN_0_RUNOUT_OVERFLOW 8:8 /* RWIVF */
453#define NV_PFIFO_INTR_EN_0_RUNOUT_OVERFLOW_DISABLED 0x00000000 /* RWI-V */
454#define NV_PFIFO_INTR_EN_0_RUNOUT_OVERFLOW_ENABLED 0x00000001 /* RW--V */
455#define NV_PFIFO_INTR_EN_0_DMA_PUSHER 12:12 /* RWIVF */
456#define NV_PFIFO_INTR_EN_0_DMA_PUSHER_DISABLED 0x00000000 /* RWI-V */
457#define NV_PFIFO_INTR_EN_0_DMA_PUSHER_ENABLED 0x00000001 /* RW--V */
458#define NV_PFIFO_INTR_EN_0_DMA_PT 16:16 /* RWIVF */
459#define NV_PFIFO_INTR_EN_0_DMA_PT_DISABLED 0x00000000 /* RWI-V */
460#define NV_PFIFO_INTR_EN_0_DMA_PT_ENABLED 0x00000001 /* RW--V */
461#define NV_PFIFO_RAMHT 0x00002210 /* RW-4R */
462#define NV_PFIFO_RAMHT_BASE_ADDRESS 8:4 /* RWIUF */
463#define NV_PFIFO_RAMHT_BASE_ADDRESS_10000 0x00000010 /* RWI-V */
464#define NV_PFIFO_RAMHT_SIZE 17:16 /* RWIUF */
465#define NV_PFIFO_RAMHT_SIZE_4K 0x00000000 /* RWI-V */
466#define NV_PFIFO_RAMHT_SIZE_8K 0x00000001 /* RW--V */
467#define NV_PFIFO_RAMHT_SIZE_16K 0x00000002 /* RW--V */
468#define NV_PFIFO_RAMHT_SIZE_32K 0x00000003 /* RW--V */
469#define NV_PFIFO_RAMHT_SEARCH 25:24 /* RWIUF */
470#define NV_PFIFO_RAMHT_SEARCH_16 0x00000000 /* RWI-V */
471#define NV_PFIFO_RAMHT_SEARCH_32 0x00000001 /* RW--V */
472#define NV_PFIFO_RAMHT_SEARCH_64 0x00000002 /* RW--V */
473#define NV_PFIFO_RAMHT_SEARCH_128 0x00000003 /* RW--V */
474#define NV_PFIFO_RAMFC 0x00002214 /* RW-4R */
475#define NV_PFIFO_RAMFC_BASE_ADDRESS 8:1 /* RWIUF */
476#define NV_PFIFO_RAMFC_BASE_ADDRESS_11000 0x00000088 /* RWI-V */
477#define NV_PFIFO_RAMRO 0x00002218 /* RW-4R */
478#define NV_PFIFO_RAMRO_BASE_ADDRESS 8:1 /* RWIUF */
479#define NV_PFIFO_RAMRO_BASE_ADDRESS_11200 0x00000089 /* RWI-V */
480#define NV_PFIFO_RAMRO_BASE_ADDRESS_12000 0x00000090 /* RW--V */
481#define NV_PFIFO_RAMRO_SIZE 16:16 /* RWIVF */
482#define NV_PFIFO_RAMRO_SIZE_512 0x00000000 /* RWI-V */
483#define NV_PFIFO_RAMRO_SIZE_8K 0x00000001 /* RW--V */
484#define NV_PFIFO_CACHES 0x00002500 /* RW-4R */
485#define NV_PFIFO_CACHES_REASSIGN 0:0 /* RWIVF */
486#define NV_PFIFO_CACHES_REASSIGN_DISABLED 0x00000000 /* RWI-V */
487#define NV_PFIFO_CACHES_REASSIGN_ENABLED 0x00000001 /* RW--V */
488#define NV_PFIFO_CACHES_DMA_SUSPEND 4:4 /* R--VF */
489#define NV_PFIFO_CACHES_DMA_SUSPEND_IDLE 0x00000000 /* R---V */
490#define NV_PFIFO_CACHES_DMA_SUSPEND_BUSY 0x00000001 /* R---V */
491#define NV_PFIFO_MODE 0x00002504 /* RW-4R */
492#define NV_PFIFO_MODE_CHANNEL_0 0:0 /* RWIVF */
493#define NV_PFIFO_MODE_CHANNEL_0_PIO 0x00000000 /* RWI-V */
494#define NV_PFIFO_MODE_CHANNEL_0_DMA 0x00000001 /* RW--V */
495#define NV_PFIFO_MODE_CHANNEL_1 1:1 /* RWIVF */
496#define NV_PFIFO_MODE_CHANNEL_1_PIO 0x00000000 /* RWI-V */
497#define NV_PFIFO_MODE_CHANNEL_1_DMA 0x00000001 /* RW--V */
498#define NV_PFIFO_MODE_CHANNEL_2 2:2 /* RWIVF */
499#define NV_PFIFO_MODE_CHANNEL_2_PIO 0x00000000 /* RWI-V */
500#define NV_PFIFO_MODE_CHANNEL_2_DMA 0x00000001 /* RW--V */
501#define NV_PFIFO_MODE_CHANNEL_3 3:3 /* RWIVF */
502#define NV_PFIFO_MODE_CHANNEL_3_PIO 0x00000000 /* RWI-V */
503#define NV_PFIFO_MODE_CHANNEL_3_DMA 0x00000001 /* RW--V */
504#define NV_PFIFO_MODE_CHANNEL_4 4:4 /* RWIVF */
505#define NV_PFIFO_MODE_CHANNEL_4_PIO 0x00000000 /* RWI-V */
506#define NV_PFIFO_MODE_CHANNEL_4_DMA 0x00000001 /* RW--V */
507#define NV_PFIFO_MODE_CHANNEL_5 5:5 /* RWIVF */
508#define NV_PFIFO_MODE_CHANNEL_5_PIO 0x00000000 /* RWI-V */
509#define NV_PFIFO_MODE_CHANNEL_5_DMA 0x00000001 /* RW--V */
510#define NV_PFIFO_MODE_CHANNEL_6 6:6 /* RWIVF */
511#define NV_PFIFO_MODE_CHANNEL_6_PIO 0x00000000 /* RWI-V */
512#define NV_PFIFO_MODE_CHANNEL_6_DMA 0x00000001 /* RW--V */
513#define NV_PFIFO_MODE_CHANNEL_7 7:7 /* RWIVF */
514#define NV_PFIFO_MODE_CHANNEL_7_PIO 0x00000000 /* RWI-V */
515#define NV_PFIFO_MODE_CHANNEL_7_DMA 0x00000001 /* RW--V */
516#define NV_PFIFO_MODE_CHANNEL_8 8:8 /* RWIVF */
517#define NV_PFIFO_MODE_CHANNEL_8_PIO 0x00000000 /* RWI-V */
518#define NV_PFIFO_MODE_CHANNEL_8_DMA 0x00000001 /* RW--V */
519#define NV_PFIFO_MODE_CHANNEL_9 9:9 /* RWIVF */
520#define NV_PFIFO_MODE_CHANNEL_9_PIO 0x00000000 /* RWI-V */
521#define NV_PFIFO_MODE_CHANNEL_9_DMA 0x00000001 /* RW--V */
522#define NV_PFIFO_MODE_CHANNEL_10 10:10 /* RWIVF */
523#define NV_PFIFO_MODE_CHANNEL_10_PIO 0x00000000 /* RWI-V */
524#define NV_PFIFO_MODE_CHANNEL_10_DMA 0x00000001 /* RW--V */
525#define NV_PFIFO_MODE_CHANNEL_11 11:11 /* RWIVF */
526#define NV_PFIFO_MODE_CHANNEL_11_PIO 0x00000000 /* RWI-V */
527#define NV_PFIFO_MODE_CHANNEL_11_DMA 0x00000001 /* RW--V */
528#define NV_PFIFO_MODE_CHANNEL_12 12:12 /* RWIVF */
529#define NV_PFIFO_MODE_CHANNEL_12_PIO 0x00000000 /* RWI-V */
530#define NV_PFIFO_MODE_CHANNEL_12_DMA 0x00000001 /* RW--V */
531#define NV_PFIFO_MODE_CHANNEL_13 13:13 /* RWIVF */
532#define NV_PFIFO_MODE_CHANNEL_13_PIO 0x00000000 /* RWI-V */
533#define NV_PFIFO_MODE_CHANNEL_13_DMA 0x00000001 /* RW--V */
534#define NV_PFIFO_MODE_CHANNEL_14 14:14 /* RWIVF */
535#define NV_PFIFO_MODE_CHANNEL_14_PIO 0x00000000 /* RWI-V */
536#define NV_PFIFO_MODE_CHANNEL_14_DMA 0x00000001 /* RW--V */
537#define NV_PFIFO_MODE_CHANNEL_15 15:15 /* RWIVF */
538#define NV_PFIFO_MODE_CHANNEL_15_PIO 0x00000000 /* RWI-V */
539#define NV_PFIFO_MODE_CHANNEL_15_DMA 0x00000001 /* RW--V */
540#define NV_PFIFO_DMA 0x00002508 /* RW-4R */
541#define NV_PFIFO_DMA_CHANNEL_0 0:0 /* RWIVF */
542#define NV_PFIFO_DMA_CHANNEL_0_NOT_PENDING 0x00000000 /* RWI-V */
543#define NV_PFIFO_DMA_CHANNEL_0_PENDING 0x00000001 /* RW--V */
544#define NV_PFIFO_DMA_CHANNEL_1 1:1 /* RWIVF */
545#define NV_PFIFO_DMA_CHANNEL_1_NOT_PENDING 0x00000000 /* RWI-V */
546#define NV_PFIFO_DMA_CHANNEL_1_PENDING 0x00000001 /* RW--V */
547#define NV_PFIFO_DMA_CHANNEL_2 2:2 /* RWIVF */
548#define NV_PFIFO_DMA_CHANNEL_2_NOT_PENDING 0x00000000 /* RWI-V */
549#define NV_PFIFO_DMA_CHANNEL_2_PENDING 0x00000001 /* RW--V */
550#define NV_PFIFO_DMA_CHANNEL_3 3:3 /* RWIVF */
551#define NV_PFIFO_DMA_CHANNEL_3_NOT_PENDING 0x00000000 /* RWI-V */
552#define NV_PFIFO_DMA_CHANNEL_3_PENDING 0x00000001 /* RW--V */
553#define NV_PFIFO_DMA_CHANNEL_4 4:4 /* RWIVF */
554#define NV_PFIFO_DMA_CHANNEL_4_NOT_PENDING 0x00000000 /* RWI-V */
555#define NV_PFIFO_DMA_CHANNEL_4_PENDING 0x00000001 /* RW--V */
556#define NV_PFIFO_DMA_CHANNEL_5 5:5 /* RWIVF */
557#define NV_PFIFO_DMA_CHANNEL_5_NOT_PENDING 0x00000000 /* RWI-V */
558#define NV_PFIFO_DMA_CHANNEL_5_PENDING 0x00000001 /* RW--V */
559#define NV_PFIFO_DMA_CHANNEL_6 6:6 /* RWIVF */
560#define NV_PFIFO_DMA_CHANNEL_6_NOT_PENDING 0x00000000 /* RWI-V */
561#define NV_PFIFO_DMA_CHANNEL_6_PENDING 0x00000001 /* RW--V */
562#define NV_PFIFO_DMA_CHANNEL_7 7:7 /* RWIVF */
563#define NV_PFIFO_DMA_CHANNEL_7_NOT_PENDING 0x00000000 /* RWI-V */
564#define NV_PFIFO_DMA_CHANNEL_7_PENDING 0x00000001 /* RW--V */
565#define NV_PFIFO_DMA_CHANNEL_8 8:8 /* RWIVF */
566#define NV_PFIFO_DMA_CHANNEL_8_NOT_PENDING 0x00000000 /* RWI-V */
567#define NV_PFIFO_DMA_CHANNEL_8_PENDING 0x00000001 /* RW--V */
568#define NV_PFIFO_DMA_CHANNEL_9 9:9 /* RWIVF */
569#define NV_PFIFO_DMA_CHANNEL_9_NOT_PENDING 0x00000000 /* RWI-V */
570#define NV_PFIFO_DMA_CHANNEL_9_PENDING 0x00000001 /* RW--V */
571#define NV_PFIFO_DMA_CHANNEL_10 10:10 /* RWIVF */
572#define NV_PFIFO_DMA_CHANNEL_10_NOT_PENDING 0x00000000 /* RWI-V */
573#define NV_PFIFO_DMA_CHANNEL_10_PENDING 0x00000001 /* RW--V */
574#define NV_PFIFO_DMA_CHANNEL_11 11:11 /* RWIVF */
575#define NV_PFIFO_DMA_CHANNEL_11_NOT_PENDING 0x00000000 /* RWI-V */
576#define NV_PFIFO_DMA_CHANNEL_11_PENDING 0x00000001 /* RW--V */
577#define NV_PFIFO_DMA_CHANNEL_12 12:12 /* RWIVF */
578#define NV_PFIFO_DMA_CHANNEL_12_NOT_PENDING 0x00000000 /* RWI-V */
579#define NV_PFIFO_DMA_CHANNEL_12_PENDING 0x00000001 /* RW--V */
580#define NV_PFIFO_DMA_CHANNEL_13 13:13 /* RWIVF */
581#define NV_PFIFO_DMA_CHANNEL_13_NOT_PENDING 0x00000000 /* RWI-V */
582#define NV_PFIFO_DMA_CHANNEL_13_PENDING 0x00000001 /* RW--V */
583#define NV_PFIFO_DMA_CHANNEL_14 14:14 /* RWIVF */
584#define NV_PFIFO_DMA_CHANNEL_14_NOT_PENDING 0x00000000 /* RWI-V */
585#define NV_PFIFO_DMA_CHANNEL_14_PENDING 0x00000001 /* RW--V */
586#define NV_PFIFO_DMA_CHANNEL_15 15:15 /* RWIVF */
587#define NV_PFIFO_DMA_CHANNEL_15_NOT_PENDING 0x00000000 /* RWI-V */
588#define NV_PFIFO_DMA_CHANNEL_15_PENDING 0x00000001 /* RW--V */
589#define NV_PFIFO_SIZE 0x0000250C /* RW-4R */
590#define NV_PFIFO_SIZE_CHANNEL_0 0:0 /* RWIVF */
591#define NV_PFIFO_SIZE_CHANNEL_0_124_BYTES 0x00000000 /* RWI-V */
592#define NV_PFIFO_SIZE_CHANNEL_0_512_BYTES 0x00000001 /* RW--V */
593#define NV_PFIFO_SIZE_CHANNEL_1 1:1 /* RWIVF */
594#define NV_PFIFO_SIZE_CHANNEL_1_124_BYTES 0x00000000 /* RWI-V */
595#define NV_PFIFO_SIZE_CHANNEL_1_512_BYTES 0x00000001 /* RW--V */
596#define NV_PFIFO_SIZE_CHANNEL_2 2:2 /* RWIVF */
597#define NV_PFIFO_SIZE_CHANNEL_2_124_BYTES 0x00000000 /* RWI-V */
598#define NV_PFIFO_SIZE_CHANNEL_2_512_BYTES 0x00000001 /* RW--V */
599#define NV_PFIFO_SIZE_CHANNEL_3 3:3 /* RWIVF */
600#define NV_PFIFO_SIZE_CHANNEL_3_124_BYTES 0x00000000 /* RWI-V */
601#define NV_PFIFO_SIZE_CHANNEL_3_512_BYTES 0x00000001 /* RW--V */
602#define NV_PFIFO_SIZE_CHANNEL_4 4:4 /* RWIVF */
603#define NV_PFIFO_SIZE_CHANNEL_4_124_BYTES 0x00000000 /* RWI-V */
604#define NV_PFIFO_SIZE_CHANNEL_4_512_BYTES 0x00000001 /* RW--V */
605#define NV_PFIFO_SIZE_CHANNEL_5 5:5 /* RWIVF */
606#define NV_PFIFO_SIZE_CHANNEL_5_124_BYTES 0x00000000 /* RWI-V */
607#define NV_PFIFO_SIZE_CHANNEL_5_512_BYTES 0x00000001 /* RW--V */
608#define NV_PFIFO_SIZE_CHANNEL_6 6:6 /* RWIVF */
609#define NV_PFIFO_SIZE_CHANNEL_6_124_BYTES 0x00000000 /* RWI-V */
610#define NV_PFIFO_SIZE_CHANNEL_6_512_BYTES 0x00000001 /* RW--V */
611#define NV_PFIFO_SIZE_CHANNEL_7 7:7 /* RWIVF */
612#define NV_PFIFO_SIZE_CHANNEL_7_124_BYTES 0x00000000 /* RWI-V */
613#define NV_PFIFO_SIZE_CHANNEL_7_512_BYTES 0x00000001 /* RW--V */
614#define NV_PFIFO_SIZE_CHANNEL_8 8:8 /* RWIVF */
615#define NV_PFIFO_SIZE_CHANNEL_8_124_BYTES 0x00000000 /* RWI-V */
616#define NV_PFIFO_SIZE_CHANNEL_8_512_BYTES 0x00000001 /* RW--V */
617#define NV_PFIFO_SIZE_CHANNEL_9 9:9 /* RWIVF */
618#define NV_PFIFO_SIZE_CHANNEL_9_124_BYTES 0x00000000 /* RWI-V */
619#define NV_PFIFO_SIZE_CHANNEL_9_512_BYTES 0x00000001 /* RW--V */
620#define NV_PFIFO_SIZE_CHANNEL_10 10:10 /* RWIVF */
621#define NV_PFIFO_SIZE_CHANNEL_10_124_BYTES 0x00000000 /* RWI-V */
622#define NV_PFIFO_SIZE_CHANNEL_10_512_BYTES 0x00000001 /* RW--V */
623#define NV_PFIFO_SIZE_CHANNEL_11 11:11 /* RWIVF */
624#define NV_PFIFO_SIZE_CHANNEL_11_124_BYTES 0x00000000 /* RWI-V */
625#define NV_PFIFO_SIZE_CHANNEL_11_512_BYTES 0x00000001 /* RW--V */
626#define NV_PFIFO_SIZE_CHANNEL_12 12:12 /* RWIVF */
627#define NV_PFIFO_SIZE_CHANNEL_12_124_BYTES 0x00000000 /* RWI-V */
628#define NV_PFIFO_SIZE_CHANNEL_12_512_BYTES 0x00000001 /* RW--V */
629#define NV_PFIFO_SIZE_CHANNEL_13 13:13 /* RWIVF */
630#define NV_PFIFO_SIZE_CHANNEL_13_124_BYTES 0x00000000 /* RWI-V */
631#define NV_PFIFO_SIZE_CHANNEL_13_512_BYTES 0x00000001 /* RW--V */
632#define NV_PFIFO_SIZE_CHANNEL_14 14:14 /* RWIVF */
633#define NV_PFIFO_SIZE_CHANNEL_14_124_BYTES 0x00000000 /* RWI-V */
634#define NV_PFIFO_SIZE_CHANNEL_14_512_BYTES 0x00000001 /* RW--V */
635#define NV_PFIFO_SIZE_CHANNEL_15 15:15 /* RWIVF */
636#define NV_PFIFO_SIZE_CHANNEL_15_124_BYTES 0x00000000 /* RWI-V */
637#define NV_PFIFO_SIZE_CHANNEL_15_512_BYTES 0x00000001 /* RW--V */
638#define NV_PFIFO_CACHE0_PUSH0 0x00003000 /* RW-4R */
639#define NV_PFIFO_CACHE0_PUSH0_ACCESS 0:0 /* RWIVF */
640#define NV_PFIFO_CACHE0_PUSH0_ACCESS_DISABLED 0x00000000 /* RWI-V */
641#define NV_PFIFO_CACHE0_PUSH0_ACCESS_ENABLED 0x00000001 /* RW--V */
642#define NV_PFIFO_CACHE1_PUSH0 0x00003200 /* RW-4R */
643#define NV_PFIFO_CACHE1_PUSH0_ACCESS 0:0 /* RWIVF */
644#define NV_PFIFO_CACHE1_PUSH0_ACCESS_DISABLED 0x00000000 /* RWI-V */
645#define NV_PFIFO_CACHE1_PUSH0_ACCESS_ENABLED 0x00000001 /* RW--V */
646#define NV_PFIFO_CACHE0_PUSH1 0x00003004 /* RW-4R */
647#define NV_PFIFO_CACHE0_PUSH1_CHID 3:0 /* RWXUF */
648#define NV_PFIFO_CACHE1_PUSH1 0x00003204 /* RW-4R */
649#define NV_PFIFO_CACHE1_PUSH1_CHID 3:0 /* RWXUF */
650#define NV_PFIFO_CACHE1_PUSH1_MODE 8:8 /* RWIVF */
651#define NV_PFIFO_CACHE1_PUSH1_MODE_PIO 0x00000000 /* RWI-V */
652#define NV_PFIFO_CACHE1_PUSH1_MODE_DMA 0x00000001 /* RW--V */
653#define NV_PFIFO_CACHE1_DMA_PUSH 0x00003220 /* RW-4R */
654#define NV_PFIFO_CACHE1_DMA_PUSH_ACCESS 0:0 /* RWIVF */
655#define NV_PFIFO_CACHE1_DMA_PUSH_ACCESS_DISABLED 0x00000000 /* RWI-V */
656#define NV_PFIFO_CACHE1_DMA_PUSH_ACCESS_ENABLED 0x00000001 /* RW--V */
657#define NV_PFIFO_CACHE1_DMA_PUSH_STATE 4:4 /* R--VF */
658#define NV_PFIFO_CACHE1_DMA_PUSH_STATE_IDLE 0x00000000 /* R---V */
659#define NV_PFIFO_CACHE1_DMA_PUSH_STATE_BUSY 0x00000001 /* R---V */
660#define NV_PFIFO_CACHE1_DMA_PUSH_BUFFER 8:8 /* R--VF */
661#define NV_PFIFO_CACHE1_DMA_PUSH_BUFFER_NOT_EMPTY 0x00000000 /* R---V */
662#define NV_PFIFO_CACHE1_DMA_PUSH_BUFFER_EMPTY 0x00000001 /* R---V */
663#define NV_PFIFO_CACHE1_DMA_PUSH_STATUS 12:12 /* RWIVF */
664#define NV_PFIFO_CACHE1_DMA_PUSH_STATUS_RUNNING 0x00000000 /* RWI-V */
665#define NV_PFIFO_CACHE1_DMA_PUSH_STATUS_SUSPENDED 0x00000001 /* RW--V */
666#define NV_PFIFO_CACHE1_DMA_FETCH 0x00003224 /* RW-4R */
667#define NV_PFIFO_CACHE1_DMA_FETCH_TRIG 7:3 /* RWIUF */
668#define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_8_BYTES 0x00000000 /* RW--V */
669#define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_16_BYTES 0x00000001 /* RW--V */
670#define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_24_BYTES 0x00000002 /* RW--V */
671#define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_32_BYTES 0x00000003 /* RW--V */
672#define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_40_BYTES 0x00000004 /* RW--V */
673#define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_48_BYTES 0x00000005 /* RW--V */
674#define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_56_BYTES 0x00000006 /* RW--V */
675#define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_64_BYTES 0x00000007 /* RW--V */
676#define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_72_BYTES 0x00000008 /* RW--V */
677#define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_80_BYTES 0x00000009 /* RW--V */
678#define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_88_BYTES 0x0000000A /* RW--V */
679#define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_96_BYTES 0x0000000B /* RW--V */
680#define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_104_BYTES 0x0000000C /* RW--V */
681#define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_112_BYTES 0x0000000D /* RW--V */
682#define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_120_BYTES 0x0000000E /* RW--V */
683#define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_128_BYTES 0x0000000F /* RWI-V */
684#define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_136_BYTES 0x00000010 /* RW--V */
685#define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_144_BYTES 0x00000011 /* RW--V */
686#define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_152_BYTES 0x00000012 /* RW--V */
687#define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_160_BYTES 0x00000013 /* RW--V */
688#define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_168_BYTES 0x00000014 /* RW--V */
689#define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_176_BYTES 0x00000015 /* RW--V */
690#define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_184_BYTES 0x00000016 /* RW--V */
691#define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_192_BYTES 0x00000017 /* RW--V */
692#define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_200_BYTES 0x00000018 /* RW--V */
693#define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_208_BYTES 0x00000019 /* RW--V */
694#define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_216_BYTES 0x0000001A /* RW--V */
695#define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_224_BYTES 0x0000001B /* RW--V */
696#define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_232_BYTES 0x0000001C /* RW--V */
697#define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_240_BYTES 0x0000001D /* RW--V */
698#define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_248_BYTES 0x0000001E /* RW--V */
699#define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_256_BYTES 0x0000001F /* RW--V */
700#define NV_PFIFO_CACHE1_DMA_FETCH_SIZE 15:13 /* RWIUF */
701#define NV_PFIFO_CACHE1_DMA_FETCH_SIZE_32_BYTES 0x00000000 /* RW--V */
702#define NV_PFIFO_CACHE1_DMA_FETCH_SIZE_64_BYTES 0x00000001 /* RW--V */
703#define NV_PFIFO_CACHE1_DMA_FETCH_SIZE_96_BYTES 0x00000002 /* RW--V */
704#define NV_PFIFO_CACHE1_DMA_FETCH_SIZE_128_BYTES 0x00000003 /* RWI-V */
705#define NV_PFIFO_CACHE1_DMA_FETCH_SIZE_160_BYTES 0x00000004 /* RW--V */
706#define NV_PFIFO_CACHE1_DMA_FETCH_SIZE_192_BYTES 0x00000005 /* RW--V */
707#define NV_PFIFO_CACHE1_DMA_FETCH_SIZE_224_BYTES 0x00000006 /* RW--V */
708#define NV_PFIFO_CACHE1_DMA_FETCH_SIZE_256_BYTES 0x00000007 /* RW--V */
709#define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS 19:16 /* RWIUF */
710#define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_0 0x00000000 /* RWI-V */
711#define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_1 0x00000001 /* RW--V */
712#define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_2 0x00000002 /* RW--V */
713#define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_3 0x00000003 /* RW--V */
714#define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_4 0x00000004 /* RW--V */
715#define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_5 0x00000005 /* RW--V */
716#define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_6 0x00000006 /* RW--V */
717#define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_7 0x00000007 /* RW--V */
718#define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_8 0x00000008 /* RW--V */
719#define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_9 0x00000009 /* RW--V */
720#define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_10 0x0000000A /* RW--V */
721#define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_11 0x0000000B /* RW--V */
722#define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_12 0x0000000C /* RW--V */
723#define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_13 0x0000000D /* RW--V */
724#define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_14 0x0000000E /* RW--V */
725#define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_15 0x0000000F /* RW--V */
726#define NV_PFIFO_CACHE1_DMA_PUT 0x00003240 /* RW-4R */
727#define NV_PFIFO_CACHE1_DMA_PUT_OFFSET 28:2 /* RWXUF */
728#define NV_PFIFO_CACHE1_DMA_GET 0x00003244 /* RW-4R */
729#define NV_PFIFO_CACHE1_DMA_GET_OFFSET 28:2 /* RWXUF */
730#define NV_PFIFO_CACHE1_DMA_STATE 0x00003228 /* RW-4R */
731#define NV_PFIFO_CACHE1_DMA_STATE_METHOD 12:2 /* RWXUF */
732#define NV_PFIFO_CACHE1_DMA_STATE_SUBCHANNEL 15:13 /* RWXUF */
733#define NV_PFIFO_CACHE1_DMA_STATE_METHOD_COUNT 28:18 /* RWIUF */
734#define NV_PFIFO_CACHE1_DMA_STATE_METHOD_COUNT_0 0x00000000 /* RWI-V */
735#define NV_PFIFO_CACHE1_DMA_STATE_ERROR 31:30 /* RWXUF */
736#define NV_PFIFO_CACHE1_DMA_STATE_ERROR_NONE 0x00000000 /* RW--V */
737#define NV_PFIFO_CACHE1_DMA_STATE_ERROR_NON_CACHE 0x00000001 /* RW--V */
738#define NV_PFIFO_CACHE1_DMA_STATE_ERROR_RESERVED_CMD 0x00000002 /* RW--V */
739#define NV_PFIFO_CACHE1_DMA_STATE_ERROR_PROTECTION 0x00000003 /* RW--V */
740#define NV_PFIFO_CACHE1_DMA_INSTANCE 0x0000322C /* RW-4R */
741#define NV_PFIFO_CACHE1_DMA_INSTANCE_ADDRESS 15:0 /* RWXUF */
742#define NV_PFIFO_CACHE1_DMA_CTL 0x00003230 /* RW-4R */
743#define NV_PFIFO_CACHE1_DMA_CTL_ADJUST 11:2 /* RWXUF */
744#define NV_PFIFO_CACHE1_DMA_CTL_PAGE_TABLE 12:12 /* RWXUF */
745#define NV_PFIFO_CACHE1_DMA_CTL_PAGE_TABLE_NOT_PRESENT 0x00000000 /* RW--V */
746#define NV_PFIFO_CACHE1_DMA_CTL_PAGE_TABLE_PRESENT 0x00000001 /* RW--V */
747#define NV_PFIFO_CACHE1_DMA_CTL_PAGE_ENTRY 13:13 /* RWXUF */
748#define NV_PFIFO_CACHE1_DMA_CTL_PAGE_ENTRY_NOT_LINEAR 0x00000000 /* RW--V */
749#define NV_PFIFO_CACHE1_DMA_CTL_PAGE_ENTRY_LINEAR 0x00000001 /* RW--V */
750#define NV_PFIFO_CACHE1_DMA_CTL_TARGET_NODE 17:16 /* RWXUF */
751#define NV_PFIFO_CACHE1_DMA_CTL_TARGET_NODE_PCI 0x00000002 /* RW--V */
752#define NV_PFIFO_CACHE1_DMA_CTL_TARGET_NODE_AGP 0x00000003 /* RW--V */
753#define NV_PFIFO_CACHE1_DMA_CTL_AT_INFO 31:31 /* RWIUF */
754#define NV_PFIFO_CACHE1_DMA_CTL_AT_INFO_INVALID 0x00000000 /* RW--V */
755#define NV_PFIFO_CACHE1_DMA_CTL_AT_INFO_VALID 0x00000001 /* RWI-V */
756#define NV_PFIFO_CACHE1_DMA_LIMIT 0x00003234 /* RW-4R */
757#define NV_PFIFO_CACHE1_DMA_LIMIT_OFFSET 28:2 /* RWXUF */
758#define NV_PFIFO_CACHE1_DMA_TLB_TAG 0x00003238 /* RW-4R */
759#define NV_PFIFO_CACHE1_DMA_TLB_TAG_ADDRESS 28:12 /* RWXUF */
760#define NV_PFIFO_CACHE1_DMA_TLB_TAG_STATE 0:0 /* RWIUF */
761#define NV_PFIFO_CACHE1_DMA_TLB_TAG_STATE_INVALID 0x00000000 /* RWI-V */
762#define NV_PFIFO_CACHE1_DMA_TLB_TAG_STATE_VALID 0x00000001 /* RW--V */
763#define NV_PFIFO_CACHE1_DMA_TLB_PTE 0x0000323C /* RW-4R */
764#define NV_PFIFO_CACHE1_DMA_TLB_PTE_FRAME_ADDRESS 31:12 /* RWXUF */
765#define NV_PFIFO_CACHE0_PULL0 0x00003050 /* RW-4R */
766#define NV_PFIFO_CACHE0_PULL0_ACCESS 0:0 /* RWIVF */
767#define NV_PFIFO_CACHE0_PULL0_ACCESS_DISABLED 0x00000000 /* RWI-V */
768#define NV_PFIFO_CACHE0_PULL0_ACCESS_ENABLED 0x00000001 /* RW--V */
769#define NV_PFIFO_CACHE0_PULL0_HASH 4:4 /* R-XVF */
770#define NV_PFIFO_CACHE0_PULL0_HASH_SUCCEEDED 0x00000000 /* R---V */
771#define NV_PFIFO_CACHE0_PULL0_HASH_FAILED 0x00000001 /* R---V */
772#define NV_PFIFO_CACHE0_PULL0_DEVICE 8:8 /* R-XVF */
773#define NV_PFIFO_CACHE0_PULL0_DEVICE_HARDWARE 0x00000000 /* R---V */
774#define NV_PFIFO_CACHE0_PULL0_DEVICE_SOFTWARE 0x00000001 /* R---V */
775#define NV_PFIFO_CACHE0_PULL0_HASH_STATE 12:12 /* R-XVF */
776#define NV_PFIFO_CACHE0_PULL0_HASH_STATE_IDLE 0x00000000 /* R---V */
777#define NV_PFIFO_CACHE0_PULL0_HASH_STATE_BUSY 0x00000001 /* R---V */
778#define NV_PFIFO_CACHE1_PULL0 0x00003250 /* RW-4R */
779#define NV_PFIFO_CACHE1_PULL0_ACCESS 0:0 /* RWIVF */
780#define NV_PFIFO_CACHE1_PULL0_ACCESS_DISABLED 0x00000000 /* RWI-V */
781#define NV_PFIFO_CACHE1_PULL0_ACCESS_ENABLED 0x00000001 /* RW--V */
782#define NV_PFIFO_CACHE1_PULL0_HASH 4:4 /* R-XVF */
783#define NV_PFIFO_CACHE1_PULL0_HASH_SUCCEEDED 0x00000000 /* R---V */
784#define NV_PFIFO_CACHE1_PULL0_HASH_FAILED 0x00000001 /* R---V */
785#define NV_PFIFO_CACHE1_PULL0_DEVICE 8:8 /* R-XVF */
786#define NV_PFIFO_CACHE1_PULL0_DEVICE_HARDWARE 0x00000000 /* R---V */
787#define NV_PFIFO_CACHE1_PULL0_DEVICE_SOFTWARE 0x00000001 /* R---V */
788#define NV_PFIFO_CACHE1_PULL0_HASH_STATE 12:12 /* R-XVF */
789#define NV_PFIFO_CACHE1_PULL0_HASH_STATE_IDLE 0x00000000 /* R---V */
790#define NV_PFIFO_CACHE1_PULL0_HASH_STATE_BUSY 0x00000001 /* R---V */
791#define NV_PFIFO_CACHE0_PULL1 0x00003054 /* RW-4R */
792#define NV_PFIFO_CACHE0_PULL1_ENGINE 1:0 /* RWXUF */
793#define NV_PFIFO_CACHE0_PULL1_ENGINE_SW 0x00000000 /* RW--V */
794#define NV_PFIFO_CACHE0_PULL1_ENGINE_GRAPHICS 0x00000001 /* RW--V */
795#define NV_PFIFO_CACHE0_PULL1_ENGINE_DVD 0x00000002 /* RW--V */
796#define NV_PFIFO_CACHE1_PULL1 0x00003254 /* RW-4R */
797#define NV_PFIFO_CACHE1_PULL1_ENGINE 1:0 /* RWXUF */
798#define NV_PFIFO_CACHE1_PULL1_ENGINE_SW 0x00000000 /* RW--V */
799#define NV_PFIFO_CACHE1_PULL1_ENGINE_GRAPHICS 0x00000001 /* RW--V */
800#define NV_PFIFO_CACHE1_PULL1_ENGINE_DVD 0x00000002 /* RW--V */
801#define NV_PFIFO_CACHE0_HASH 0x00003058 /* RW-4R */
802#define NV_PFIFO_CACHE0_HASH_INSTANCE 15:0 /* RWXUF */
803#define NV_PFIFO_CACHE0_HASH_VALID 16:16 /* RWXVF */
804#define NV_PFIFO_CACHE1_HASH 0x00003258 /* RW-4R */
805#define NV_PFIFO_CACHE1_HASH_INSTANCE 15:0 /* RWXUF */
806#define NV_PFIFO_CACHE1_HASH_VALID 16:16 /* RWXVF */
807#define NV_PFIFO_CACHE0_STATUS 0x00003014 /* R--4R */
808#define NV_PFIFO_CACHE0_STATUS_LOW_MARK 4:4 /* R--VF */
809#define NV_PFIFO_CACHE0_STATUS_LOW_MARK_NOT_EMPTY 0x00000000 /* R---V */
810#define NV_PFIFO_CACHE0_STATUS_LOW_MARK_EMPTY 0x00000001 /* R---V */
811#define NV_PFIFO_CACHE0_STATUS_HIGH_MARK 8:8 /* R--VF */
812#define NV_PFIFO_CACHE0_STATUS_HIGH_MARK_NOT_FULL 0x00000000 /* R---V */
813#define NV_PFIFO_CACHE0_STATUS_HIGH_MARK_FULL 0x00000001 /* R---V */
814#define NV_PFIFO_CACHE1_STATUS 0x00003214 /* R--4R */
815#define NV_PFIFO_CACHE1_STATUS_LOW_MARK 4:4 /* R--VF */
816#define NV_PFIFO_CACHE1_STATUS_LOW_MARK_NOT_EMPTY 0x00000000 /* R---V */
817#define NV_PFIFO_CACHE1_STATUS_LOW_MARK_EMPTY 0x00000001 /* R---V */
818#define NV_PFIFO_CACHE1_STATUS_HIGH_MARK 8:8 /* R--VF */
819#define NV_PFIFO_CACHE1_STATUS_HIGH_MARK_NOT_FULL 0x00000000 /* R---V */
820#define NV_PFIFO_CACHE1_STATUS_HIGH_MARK_FULL 0x00000001 /* R---V */
821#define NV_PFIFO_CACHE1_STATUS1 0x00003218 /* R--4R */
822#define NV_PFIFO_CACHE1_STATUS1_RANOUT 0:0 /* R-XVF */
823#define NV_PFIFO_CACHE1_STATUS1_RANOUT_FALSE 0x00000000 /* R---V */
824#define NV_PFIFO_CACHE1_STATUS1_RANOUT_TRUE 0x00000001 /* R---V */
825#define NV_PFIFO_CACHE0_PUT 0x00003010 /* RW-4R */
826#define NV_PFIFO_CACHE0_PUT_ADDRESS 2:2 /* RWXUF */
827#define NV_PFIFO_CACHE1_PUT 0x00003210 /* RW-4R */
828#define NV_PFIFO_CACHE1_PUT_ADDRESS 9:2 /* RWXUF */
829#define NV_PFIFO_CACHE0_GET 0x00003070 /* RW-4R */
830#define NV_PFIFO_CACHE0_GET_ADDRESS 2:2 /* RWXUF */
831#define NV_PFIFO_CACHE1_GET 0x00003270 /* RW-4R */
832#define NV_PFIFO_CACHE1_GET_ADDRESS 9:2 /* RWXUF */
833#define NV_PFIFO_CACHE0_ENGINE 0x00003080 /* RW-4R */
834#define NV_PFIFO_CACHE0_ENGINE_0 1:0 /* RWXUF */
835#define NV_PFIFO_CACHE0_ENGINE_0_SW 0x00000000 /* RW--V */
836#define NV_PFIFO_CACHE0_ENGINE_0_GRAPHICS 0x00000001 /* RW--V */
837#define NV_PFIFO_CACHE0_ENGINE_0_DVD 0x00000002 /* RW--V */
838#define NV_PFIFO_CACHE0_ENGINE_1 5:4 /* RWXUF */
839#define NV_PFIFO_CACHE0_ENGINE_1_SW 0x00000000 /* RW--V */
840#define NV_PFIFO_CACHE0_ENGINE_1_GRAPHICS 0x00000001 /* RW--V */
841#define NV_PFIFO_CACHE0_ENGINE_1_DVD 0x00000002 /* RW--V */
842#define NV_PFIFO_CACHE0_ENGINE_2 9:8 /* RWXUF */
843#define NV_PFIFO_CACHE0_ENGINE_2_SW 0x00000000 /* RW--V */
844#define NV_PFIFO_CACHE0_ENGINE_2_GRAPHICS 0x00000001 /* RW--V */
845#define NV_PFIFO_CACHE0_ENGINE_2_DVD 0x00000002 /* RW--V */
846#define NV_PFIFO_CACHE0_ENGINE_3 13:12 /* RWXUF */
847#define NV_PFIFO_CACHE0_ENGINE_3_SW 0x00000000 /* RW--V */
848#define NV_PFIFO_CACHE0_ENGINE_3_GRAPHICS 0x00000001 /* RW--V */
849#define NV_PFIFO_CACHE0_ENGINE_3_DVD 0x00000002 /* RW--V */
850#define NV_PFIFO_CACHE0_ENGINE_4 17:16 /* RWXUF */
851#define NV_PFIFO_CACHE0_ENGINE_4_SW 0x00000000 /* RW--V */
852#define NV_PFIFO_CACHE0_ENGINE_4_GRAPHICS 0x00000001 /* RW--V */
853#define NV_PFIFO_CACHE0_ENGINE_4_DVD 0x00000002 /* RW--V */
854#define NV_PFIFO_CACHE0_ENGINE_5 21:20 /* RWXUF */
855#define NV_PFIFO_CACHE0_ENGINE_5_SW 0x00000000 /* RW--V */
856#define NV_PFIFO_CACHE0_ENGINE_5_GRAPHICS 0x00000001 /* RW--V */
857#define NV_PFIFO_CACHE0_ENGINE_5_DVD 0x00000002 /* RW--V */
858#define NV_PFIFO_CACHE0_ENGINE_6 25:24 /* RWXUF */
859#define NV_PFIFO_CACHE0_ENGINE_6_SW 0x00000000 /* RW--V */
860#define NV_PFIFO_CACHE0_ENGINE_6_GRAPHICS 0x00000001 /* RW--V */
861#define NV_PFIFO_CACHE0_ENGINE_6_DVD 0x00000002 /* RW--V */
862#define NV_PFIFO_CACHE0_ENGINE_7 29:28 /* RWXUF */
863#define NV_PFIFO_CACHE0_ENGINE_7_SW 0x00000000 /* RW--V */
864#define NV_PFIFO_CACHE0_ENGINE_7_GRAPHICS 0x00000001 /* RW--V */
865#define NV_PFIFO_CACHE0_ENGINE_7_DVD 0x00000002 /* RW--V */
866#define NV_PFIFO_CACHE1_ENGINE 0x00003280 /* RW-4R */
867#define NV_PFIFO_CACHE1_ENGINE_0 1:0 /* RWXUF */
868#define NV_PFIFO_CACHE1_ENGINE_0_SW 0x00000000 /* RW--V */
869#define NV_PFIFO_CACHE1_ENGINE_0_GRAPHICS 0x00000001 /* RW--V */
870#define NV_PFIFO_CACHE1_ENGINE_0_DVD 0x00000002 /* RW--V */
871#define NV_PFIFO_CACHE1_ENGINE_1 5:4 /* RWXUF */
872#define NV_PFIFO_CACHE1_ENGINE_1_SW 0x00000000 /* RW--V */
873#define NV_PFIFO_CACHE1_ENGINE_1_GRAPHICS 0x00000001 /* RW--V */
874#define NV_PFIFO_CACHE1_ENGINE_1_DVD 0x00000002 /* RW--V */
875#define NV_PFIFO_CACHE1_ENGINE_2 9:8 /* RWXUF */
876#define NV_PFIFO_CACHE1_ENGINE_2_SW 0x00000000 /* RW--V */
877#define NV_PFIFO_CACHE1_ENGINE_2_GRAPHICS 0x00000001 /* RW--V */
878#define NV_PFIFO_CACHE1_ENGINE_2_DVD 0x00000002 /* RW--V */
879#define NV_PFIFO_CACHE1_ENGINE_3 13:12 /* RWXUF */
880#define NV_PFIFO_CACHE1_ENGINE_3_SW 0x00000000 /* RW--V */
881#define NV_PFIFO_CACHE1_ENGINE_3_GRAPHICS 0x00000001 /* RW--V */
882#define NV_PFIFO_CACHE1_ENGINE_3_DVD 0x00000002 /* RW--V */
883#define NV_PFIFO_CACHE1_ENGINE_4 17:16 /* RWXUF */
884#define NV_PFIFO_CACHE1_ENGINE_4_SW 0x00000000 /* RW--V */
885#define NV_PFIFO_CACHE1_ENGINE_4_GRAPHICS 0x00000001 /* RW--V */
886#define NV_PFIFO_CACHE1_ENGINE_4_DVD 0x00000002 /* RW--V */
887#define NV_PFIFO_CACHE1_ENGINE_5 21:20 /* RWXUF */
888#define NV_PFIFO_CACHE1_ENGINE_5_SW 0x00000000 /* RW--V */
889#define NV_PFIFO_CACHE1_ENGINE_5_GRAPHICS 0x00000001 /* RW--V */
890#define NV_PFIFO_CACHE1_ENGINE_5_DVD 0x00000002 /* RW--V */
891#define NV_PFIFO_CACHE1_ENGINE_6 25:24 /* RWXUF */
892#define NV_PFIFO_CACHE1_ENGINE_6_SW 0x00000000 /* RW--V */
893#define NV_PFIFO_CACHE1_ENGINE_6_GRAPHICS 0x00000001 /* RW--V */
894#define NV_PFIFO_CACHE1_ENGINE_6_DVD 0x00000002 /* RW--V */
895#define NV_PFIFO_CACHE1_ENGINE_7 29:28 /* RWXUF */
896#define NV_PFIFO_CACHE1_ENGINE_7_SW 0x00000000 /* RW--V */
897#define NV_PFIFO_CACHE1_ENGINE_7_GRAPHICS 0x00000001 /* RW--V */
898#define NV_PFIFO_CACHE1_ENGINE_7_DVD 0x00000002 /* RW--V */
899#define NV_PFIFO_CACHE0_METHOD(i) (0x00003100+(i)*8) /* RW-4A */
900#define NV_PFIFO_CACHE0_METHOD__SIZE_1 1 /* */
901#define NV_PFIFO_CACHE0_METHOD_ADDRESS 12:2 /* RWXUF */
902#define NV_PFIFO_CACHE0_METHOD_SUBCHANNEL 15:13 /* RWXUF */
903#define NV_PFIFO_CACHE1_METHOD(i) (0x00003800+(i)*8) /* RW-4A */
904#define NV_PFIFO_CACHE1_METHOD__SIZE_1 128 /* */
905#define NV_PFIFO_CACHE1_METHOD_ADDRESS 12:2 /* RWXUF */
906#define NV_PFIFO_CACHE1_METHOD_SUBCHANNEL 15:13 /* RWXUF */
907#define NV_PFIFO_CACHE1_METHOD_ALIAS(i) (0x00003C00+(i)*8) /* RW-4A */
908#define NV_PFIFO_CACHE1_METHOD_ALIAS__SIZE_1 128 /* */
909#define NV_PFIFO_CACHE0_DATA(i) (0x00003104+(i)*8) /* RW-4A */
910#define NV_PFIFO_CACHE0_DATA__SIZE_1 1 /* */
911#define NV_PFIFO_CACHE0_DATA_VALUE 31:0 /* RWXVF */
912#define NV_PFIFO_CACHE1_DATA(i) (0x00003804+(i)*8) /* RW-4A */
913#define NV_PFIFO_CACHE1_DATA__SIZE_1 128 /* */
914#define NV_PFIFO_CACHE1_DATA_VALUE 31:0 /* RWXVF */
915#define NV_PFIFO_CACHE1_DATA_ALIAS(i) (0x00003C04+(i)*8) /* RW-4A */
916#define NV_PFIFO_CACHE1_DATA_ALIAS__SIZE_1 128 /* */
917#define NV_PFIFO_DEVICE(i) (0x00002800+(i)*4) /* R--4A */
918#define NV_PFIFO_DEVICE__SIZE_1 128 /* */
919#define NV_PFIFO_DEVICE_CHID 3:0 /* R--UF */
920#define NV_PFIFO_DEVICE_SWITCH 24:24 /* R--VF */
921#define NV_PFIFO_DEVICE_SWITCH_UNAVAILABLE 0x00000000 /* R---V */
922#define NV_PFIFO_DEVICE_SWITCH_AVAILABLE 0x00000001 /* R---V */
923#define NV_PFIFO_RUNOUT_STATUS 0x00002400 /* R--4R */
924#define NV_PFIFO_RUNOUT_STATUS_RANOUT 0:0 /* R--VF */
925#define NV_PFIFO_RUNOUT_STATUS_RANOUT_FALSE 0x00000000 /* R---V */
926#define NV_PFIFO_RUNOUT_STATUS_RANOUT_TRUE 0x00000001 /* R---V */
927#define NV_PFIFO_RUNOUT_STATUS_LOW_MARK 4:4 /* R--VF */
928#define NV_PFIFO_RUNOUT_STATUS_LOW_MARK_NOT_EMPTY 0x00000000 /* R---V */
929#define NV_PFIFO_RUNOUT_STATUS_LOW_MARK_EMPTY 0x00000001 /* R---V */
930#define NV_PFIFO_RUNOUT_STATUS_HIGH_MARK 8:8 /* R--VF */
931#define NV_PFIFO_RUNOUT_STATUS_HIGH_MARK_NOT_FULL 0x00000000 /* R---V */
932#define NV_PFIFO_RUNOUT_STATUS_HIGH_MARK_FULL 0x00000001 /* R---V */
933#define NV_PFIFO_RUNOUT_PUT 0x00002410 /* RW-4R */
934#define NV_PFIFO_RUNOUT_PUT_ADDRESS 12:3 /* RWXUF */
935#define NV_PFIFO_RUNOUT_PUT_ADDRESS__SIZE_0 8:3 /* RWXUF */
936#define NV_PFIFO_RUNOUT_PUT_ADDRESS__SIZE_1 12:3 /* RWXUF */
937#define NV_PFIFO_RUNOUT_GET 0x00002420 /* RW-4R */
938#define NV_PFIFO_RUNOUT_GET_ADDRESS 13:3 /* RWXUF */
939/* dev_graphics.ref */
940#define NV_PGRAPH 0x00401FFF:0x00400000 /* RW--D */
941#define NV_PGRAPH_DEBUG_0 0x00400080 /* RW-4R */
942#define NV_PGRAPH_DEBUG_1 0x00400084 /* RW-4R */
943#define NV_PGRAPH_DEBUG_2 0x00400088 /* RW-4R */
944#define NV_PGRAPH_DEBUG_3 0x0040008C /* RW-4R */
945#define NV_PGRAPH_INTR 0x00400100 /* RW-4R */
946#define NV_PGRAPH_INTR_NOTIFY 0:0 /* RWIVF */
947#define NV_PGRAPH_INTR_NOTIFY_NOT_PENDING 0x00000000 /* R-I-V */
948#define NV_PGRAPH_INTR_NOTIFY_PENDING 0x00000001 /* R---V */
949#define NV_PGRAPH_INTR_NOTIFY_RESET 0x00000001 /* -W--C */
950#define NV_PGRAPH_INTR_MISSING_HW 4:4 /* RWIVF */
951#define NV_PGRAPH_INTR_MISSING_HW_NOT_PENDING 0x00000000 /* R-I-V */
952#define NV_PGRAPH_INTR_MISSING_HW_PENDING 0x00000001 /* R---V */
953#define NV_PGRAPH_INTR_MISSING_HW_RESET 0x00000001 /* -W--C */
954#define NV_PGRAPH_INTR_TLB_PRESENT_A 8:8 /* RWIVF */
955#define NV_PGRAPH_INTR_TLB_PRESENT_A_NOT_PENDING 0x00000000 /* R-I-V */
956#define NV_PGRAPH_INTR_TLB_PRESENT_A_PENDING 0x00000001 /* R---V */
957#define NV_PGRAPH_INTR_TLB_PRESENT_A_RESET 0x00000001 /* -W--C */
958#define NV_PGRAPH_INTR_TLB_PRESENT_B 9:9 /* RWIVF */
959#define NV_PGRAPH_INTR_TLB_PRESENT_B_NOT_PENDING 0x00000000 /* R-I-V */
960#define NV_PGRAPH_INTR_TLB_PRESENT_B_PENDING 0x00000001 /* R---V */
961#define NV_PGRAPH_INTR_TLB_PRESENT_B_RESET 0x00000001 /* -W--C */
962#define NV_PGRAPH_INTR_CONTEXT_SWITCH 12:12 /* RWIVF */
963#define NV_PGRAPH_INTR_CONTEXT_SWITCH_NOT_PENDING 0x00000000 /* R-I-V */
964#define NV_PGRAPH_INTR_CONTEXT_SWITCH_PENDING 0x00000001 /* R---V */
965#define NV_PGRAPH_INTR_CONTEXT_SWITCH_RESET 0x00000001 /* -W--C */
966#define NV_PGRAPH_INTR_BUFFER_NOTIFY 16:16 /* RWIVF */
967#define NV_PGRAPH_INTR_BUFFER_NOTIFY_NOT_PENDING 0x00000000 /* R-I-V */
968#define NV_PGRAPH_INTR_BUFFER_NOTIFY_PENDING 0x00000001 /* R---V */
969#define NV_PGRAPH_INTR_BUFFER_NOTIFY_RESET 0x00000001 /* -W--C */
970#define NV_PGRAPH_NSTATUS 0x00400104 /* RW-4R */
971#define NV_PGRAPH_NSTATUS_STATE_IN_USE 11:11 /* RWIVF */
972#define NV_PGRAPH_NSTATUS_STATE_IN_USE_NOT_PENDING 0x00000000 /* RWI-V */
973#define NV_PGRAPH_NSTATUS_STATE_IN_USE_PENDING 0x00000001 /* RW--V */
974#define NV_PGRAPH_NSTATUS_INVALID_STATE 12:12 /* RWIVF */
975#define NV_PGRAPH_NSTATUS_INVALID_STATE_NOT_PENDING 0x00000000 /* RWI-V */
976#define NV_PGRAPH_NSTATUS_INVALID_STATE_PENDING 0x00000001 /* RW--V */
977#define NV_PGRAPH_NSTATUS_BAD_ARGUMENT 13:13 /* RWIVF */
978#define NV_PGRAPH_NSTATUS_BAD_ARGUMENT_NOT_PENDING 0x00000000 /* RWI-V */
979#define NV_PGRAPH_NSTATUS_BAD_ARGUMENT_PENDING 0x00000001 /* RW--V */
980#define NV_PGRAPH_NSTATUS_PROTECTION_FAULT 14:14 /* RWIVF */
981#define NV_PGRAPH_NSTATUS_PROTECTION_FAULT_NOT_PENDING 0x00000000 /* RWI-V */
982#define NV_PGRAPH_NSTATUS_PROTECTION_FAULT_PENDING 0x00000001 /* RW--V */
983#define NV_PGRAPH_NSOURCE 0x00400108 /* R--4R */
984#define NV_PGRAPH_NSOURCE_NOTIFICATION 0:0 /* R-IVF */
985#define NV_PGRAPH_NSOURCE_NOTIFICATION_NOT_PENDING 0x00000000 /* R-I-V */
986#define NV_PGRAPH_NSOURCE_NOTIFICATION_PENDING 0x00000001 /* R---V */
987#define NV_PGRAPH_NSOURCE_DATA_ERROR 1:1 /* R-IVF */
988#define NV_PGRAPH_NSOURCE_DATA_ERROR_NOT_PENDING 0x00000000 /* R-I-V */
989#define NV_PGRAPH_NSOURCE_DATA_ERROR_PENDING 0x00000001 /* R---V */
990#define NV_PGRAPH_NSOURCE_PROTECTION_ERROR 2:2 /* R-IVF */
991#define NV_PGRAPH_NSOURCE_PROTECTION_ERROR_NOT_PENDING 0x00000000 /* R-I-V */
992#define NV_PGRAPH_NSOURCE_PROTECTION_ERROR_PENDING 0x00000001 /* R---V */
993#define NV_PGRAPH_NSOURCE_RANGE_EXCEPTION 3:3 /* R-IVF */
994#define NV_PGRAPH_NSOURCE_RANGE_EXCEPTION_NOT_PENDING 0x00000000 /* R-I-V */
995#define NV_PGRAPH_NSOURCE_RANGE_EXCEPTION_PENDING 0x00000001 /* R---V */
996#define NV_PGRAPH_NSOURCE_LIMIT_COLOR 4:4 /* R-IVF */
997#define NV_PGRAPH_NSOURCE_LIMIT_COLOR_NOT_PENDING 0x00000000 /* R-I-V */
998#define NV_PGRAPH_NSOURCE_LIMIT_COLOR_PENDING 0x00000001 /* R---V */
999#define NV_PGRAPH_NSOURCE_LIMIT_ZETA_ 5:5 /* R-IVF */
1000#define NV_PGRAPH_NSOURCE_LIMIT_ZETA_NOT_PENDING 0x00000000 /* R-I-V */
1001#define NV_PGRAPH_NSOURCE_LIMIT_ZETA_PENDING 0x00000001 /* R---V */
1002#define NV_PGRAPH_NSOURCE_ILLEGAL_MTHD 6:6 /* R-IVF */
1003#define NV_PGRAPH_NSOURCE_ILLEGAL_MTHD_NOT_PENDING 0x00000000 /* R-I-V */
1004#define NV_PGRAPH_NSOURCE_ILLEGAL_MTHD_PENDING 0x00000001 /* R---V */
1005#define NV_PGRAPH_NSOURCE_DMA_R_PROTECTION 7:7 /* R-IVF */
1006#define NV_PGRAPH_NSOURCE_DMA_R_PROTECTION_NOT_PENDING 0x00000000 /* R-I-V */
1007#define NV_PGRAPH_NSOURCE_DMA_R_PROTECTION_PENDING 0x00000001 /* R---V */
1008#define NV_PGRAPH_NSOURCE_DMA_W_PROTECTION 8:8 /* R-IVF */
1009#define NV_PGRAPH_NSOURCE_DMA_W_PROTECTION_NOT_PENDING 0x00000000 /* R-I-V */
1010#define NV_PGRAPH_NSOURCE_DMA_W_PROTECTION_PENDING 0x00000001 /* R---V */
1011#define NV_PGRAPH_NSOURCE_FORMAT_EXCEPTION 9:9 /* R-IVF */
1012#define NV_PGRAPH_NSOURCE_FORMAT_EXCEPTION_NOT_PENDING 0x00000000 /* R-I-V */
1013#define NV_PGRAPH_NSOURCE_FORMAT_EXCEPTION_PENDING 0x00000001 /* R---V */
1014#define NV_PGRAPH_NSOURCE_PATCH_EXCEPTION 10:10 /* R-IVF */
1015#define NV_PGRAPH_NSOURCE_PATCH_EXCEPTION_NOT_PENDING 0x00000000 /* R-I-V */
1016#define NV_PGRAPH_NSOURCE_PATCH_EXCEPTION_PENDING 0x00000001 /* R---V */
1017#define NV_PGRAPH_NSOURCE_STATE_INVALID 11:11 /* R-IVF */
1018#define NV_PGRAPH_NSOURCE_STATE_INVALID_NOT_PENDING 0x00000000 /* R-I-V */
1019#define NV_PGRAPH_NSOURCE_STATE_INVALID_PENDING 0x00000001 /* R---V */
1020#define NV_PGRAPH_NSOURCE_DOUBLE_NOTIFY 12:12 /* R-IVF */
1021#define NV_PGRAPH_NSOURCE_DOUBLE_NOTIFY_NOT_PENDING 0x00000000 /* R-I-V */
1022#define NV_PGRAPH_NSOURCE_DOUBLE_NOTIFY_PENDING 0x00000001 /* R---V */
1023#define NV_PGRAPH_NSOURCE_NOTIFY_IN_USE 13:13 /* R-IVF */
1024#define NV_PGRAPH_NSOURCE_NOTIFY_IN_USE_NOT_PENDING 0x00000000 /* R-I-V */
1025#define NV_PGRAPH_NSOURCE_NOTIFY_IN_USE_PENDING 0x00000001 /* R---V */
1026#define NV_PGRAPH_NSOURCE_METHOD_CNT 14:14 /* R-IVF */
1027#define NV_PGRAPH_NSOURCE_METHOD_CNT_NOT_PENDING 0x00000000 /* R-I-V */
1028#define NV_PGRAPH_NSOURCE_METHOD_CNT_PENDING 0x00000001 /* R---V */
1029#define NV_PGRAPH_NSOURCE_BFR_NOTIFICATION 15:15 /* R-IVF */
1030#define NV_PGRAPH_NSOURCE_BFR_NOTIFICATION_NOT_PENDING 0x00000000 /* R-I-V */
1031#define NV_PGRAPH_NSOURCE_BFR_NOTIFICATION_PENDING 0x00000001 /* R---V */
1032#define NV_PGRAPH_INTR_EN 0x00400140 /* RW-4R */
1033#define NV_PGRAPH_INTR_EN_NOTIFY 0:0 /* RWIVF */
1034#define NV_PGRAPH_INTR_EN_NOTIFY_DISABLED 0x00000000 /* RWI-V */
1035#define NV_PGRAPH_INTR_EN_NOTIFY_ENABLED 0x00000001 /* RW--V */
1036#define NV_PGRAPH_INTR_EN_MISSING_HW 4:4 /* RWIVF */
1037#define NV_PGRAPH_INTR_EN_MISSING_HW_DISABLED 0x00000000 /* RWI-V */
1038#define NV_PGRAPH_INTR_EN_MISSING_HW_ENABLED 0x00000001 /* RW--V */
1039#define NV_PGRAPH_INTR_EN_TLB_PRESENT_A 8:8 /* RWIVF */
1040#define NV_PGRAPH_INTR_EN_TLB_PRESENT_A_DISABLED 0x00000000 /* RWI-V */
1041#define NV_PGRAPH_INTR_EN_TLB_PRESENT_A_ENABLED 0x00000001 /* RW--V */
1042#define NV_PGRAPH_INTR_EN_TLB_PRESENT_B 9:9 /* RWIVF */
1043#define NV_PGRAPH_INTR_EN_TLB_PRESENT_B_DISABLED 0x00000000 /* RWI-V */
1044#define NV_PGRAPH_INTR_EN_TLB_PRESENT_B_ENABLED 0x00000001 /* RW--V */
1045#define NV_PGRAPH_INTR_EN_CONTEXT_SWITCH 12:12 /* RWIVF */
1046#define NV_PGRAPH_INTR_EN_CONTEXT_SWITCH_DISABLED 0x00000000 /* RWI-V */
1047#define NV_PGRAPH_INTR_EN_CONTEXT_SWITCH_ENABLED 0x00000001 /* RW--V */
1048#define NV_PGRAPH_INTR_EN_BUFFER_NOTIFY 16:16 /* RWIVF */
1049#define NV_PGRAPH_INTR_EN_BUFFER_NOTIFY_DISABLED 0x00000000 /* RWI-V */
1050#define NV_PGRAPH_INTR_EN_BUFFER_NOTIFY_ENABLED 0x00000001 /* RW--V */
1051#define NV_PGRAPH_CTX_SWITCH1 0x00400160 /* RW-4R */
1052#define NV_PGRAPH_CTX_SWITCH1_GRCLASS 7:0 /* RWXVF */
1053#define NV_PGRAPH_CTX_SWITCH1_CHROMA_KEY 12:12 /* RWXUF */
1054#define NV_PGRAPH_CTX_SWITCH1_CHROMA_KEY_DISABLE 0x00000000 /* RW--V */
1055#define NV_PGRAPH_CTX_SWITCH1_CHROMA_KEY_ENABLE 0x00000001 /* RW--V */
1056#define NV_PGRAPH_CTX_SWITCH1_USER_CLIP 13:13 /* RWXUF */
1057#define NV_PGRAPH_CTX_SWITCH1_USER_CLIP_DISABLE 0x00000000 /* RW--V */
1058#define NV_PGRAPH_CTX_SWITCH1_USER_CLIP_ENABLE 0x00000001 /* RW--V */
1059#define NV_PGRAPH_CTX_SWITCH1_SWIZZLE 14:14 /* RWXUF */
1060#define NV_PGRAPH_CTX_SWITCH1_SWIZZLE_DISABLE 0x00000000 /* RW--V */
1061#define NV_PGRAPH_CTX_SWITCH1_SWIZZLE_ENABLE 0x00000001 /* RW--V */
1062#define NV_PGRAPH_CTX_SWITCH1_PATCH_CONFIG 17:15 /* RWXUF */
1063#define NV_PGRAPH_CTX_SWITCH1_PATCH_CONFIG_SRCCOPY_AND 0x00000000 /* RW--V */
1064#define NV_PGRAPH_CTX_SWITCH1_PATCH_CONFIG_ROP_AND 0x00000001 /* RW--V */
1065#define NV_PGRAPH_CTX_SWITCH1_PATCH_CONFIG_BLEND_AND 0x00000002 /* RW--V */
1066#define NV_PGRAPH_CTX_SWITCH1_PATCH_CONFIG_SRCCOPY 0x00000003 /* RW--V */
1067#define NV_PGRAPH_CTX_SWITCH1_PATCH_CONFIG_SRCCOPY_PRE 0x00000004 /* RW--V */
1068#define NV_PGRAPH_CTX_SWITCH1_PATCH_CONFIG_BLEND_PRE 0x00000005 /* RW--V */
1069#define NV_PGRAPH_CTX_SWITCH1_PATCH_STATUS 24:24 /* RWXUF */
1070#define NV_PGRAPH_CTX_SWITCH1_PATCH_STATUS_INVALID 0x00000000 /* RW--V */
1071#define NV_PGRAPH_CTX_SWITCH1_PATCH_STATUS_VALID 0x00000001 /* RW--V */
1072#define NV_PGRAPH_CTX_SWITCH1_CONTEXT_SURFACE 25:25 /* RWXUF */
1073#define NV_PGRAPH_CTX_SWITCH1_CONTEXT_SURFACE_INVALID 0x00000000 /* RW--V */
1074#define NV_PGRAPH_CTX_SWITCH1_CONTEXT_SURFACE_VALID 0x00000001 /* RW--V */
1075#define NV_PGRAPH_CTX_SWITCH1_VOLATILE_RESET 31:31 /* CWIVF */
1076#define NV_PGRAPH_CTX_SWITCH1_VOLATILE_RESET_IGNORE 0x00000000 /* CWI-V */
1077#define NV_PGRAPH_CTX_SWITCH1_VOLATILE_RESET_ENABLED 0x00000001 /* -W--T */
1078#define NV_PGRAPH_CTX_SWITCH2 0x00400164 /* RW-4R */
1079#define NV_PGRAPH_CTX_SWITCH2_MONO_FORMAT 1:0 /* RWXUF */
1080#define NV_PGRAPH_CTX_SWITCH2_MONO_FORMAT_INVALID 0x00 /* RW--V */
1081#define NV_PGRAPH_CTX_SWITCH2_MONO_FORMAT_CGA6_M1 0x01 /* RW--V */
1082#define NV_PGRAPH_CTX_SWITCH2_MONO_FORMAT_LE_M1 0x02 /* RW--V */
1083#define NV_PGRAPH_CTX_SWITCH2_COLOR_FORMAT 13:8 /* RWXUF */
1084#define NV_PGRAPH_CTX_SWITCH2_COLOR_FORMAT_INVALID 0x00 /* RW--V */
1085#define NV_PGRAPH_CTX_SWITCH2_COLOR_FORMAT_LE_Y8 0x01 /* RW--V */
1086#define NV_PGRAPH_CTX_SWITCH2_COLOR_FORMAT_LE_X16A8Y8 0x02 /* RW--V */
1087#define NV_PGRAPH_CTX_SWITCH2_COLOR_FORMAT_LE_X24Y8 0x03 /* RW--V */
1088#define NV_PGRAPH_CTX_SWITCH2_COLOR_FORMAT_LE_A1R5G5B5 0x06 /* RW--V */
1089#define NV_PGRAPH_CTX_SWITCH2_COLOR_FORMAT_LE_X1R5G5B5 0x07 /* RW--V */
1090#define NV_PGRAPH_CTX_SWITCH2_COLOR_FORMAT_LE_X16A1R5G5B5 0x08 /* RW--V */
1091#define NV_PGRAPH_CTX_SWITCH2_COLOR_FORMAT_LE_X17R5G5B5 0x09 /* RW--V */
1092#define NV_PGRAPH_CTX_SWITCH2_COLOR_FORMAT_LE_R5G6B5 0x0A /* RW--V */
1093#define NV_PGRAPH_CTX_SWITCH2_COLOR_FORMAT_LE_A16R5G6B5 0x0B /* RW--V */
1094#define NV_PGRAPH_CTX_SWITCH2_COLOR_FORMAT_LE_X16R5G6B5 0x0C /* RW--V */
1095#define NV_PGRAPH_CTX_SWITCH2_COLOR_FORMAT_LE_A8R8G8B8 0x0D /* RW--V */
1096#define NV_PGRAPH_CTX_SWITCH2_COLOR_FORMAT_LE_X8R8G8B8 0x0E /* RW--V */
1097#define NV_PGRAPH_CTX_SWITCH2_COLOR_FORMAT_LE_Y16 0x0F /* RW--V */
1098#define NV_PGRAPH_CTX_SWITCH2_COLOR_FORMAT_LE_A16Y16 0x10 /* RW--V */
1099#define NV_PGRAPH_CTX_SWITCH2_COLOR_FORMAT_LE_X16Y16 0x11 /* RW--V */
1100#define NV_PGRAPH_CTX_SWITCH2_COLOR_FORMAT_LE_V8YB8U8YA8 0x12 /* RW--V */
1101#define NV_PGRAPH_CTX_SWITCH2_COLOR_FORMAT_LE_YB8V8YA8U8 0x13 /* RW--V */
1102#define NV_PGRAPH_CTX_SWITCH2_COLOR_FORMAT_LE_Y32 0x14 /* RW--V */
1103#define NV_PGRAPH_CTX_SWITCH2_NOTIFY_INSTANCE 31:16 /* RWXUF */
1104#define NV_PGRAPH_CTX_SWITCH2_NOTIFY_INSTANCE_INVALID 0x0000 /* RW--V */
1105#define NV_PGRAPH_CTX_SWITCH3 0x00400168 /* RW-4R */
1106#define NV_PGRAPH_CTX_SWITCH3_DMA_INSTANCE_0 15:0 /* RWXUF */
1107#define NV_PGRAPH_CTX_SWITCH3_DMA_INSTANCE_0_INVALID 0x0000 /* RW--V */
1108#define NV_PGRAPH_CTX_SWITCH3_DMA_INSTANCE_1 31:16 /* RWXUF */
1109#define NV_PGRAPH_CTX_SWITCH3_DMA_INSTANCE_1_INVALID 0x0000 /* RW--V */
1110#define NV_PGRAPH_CTX_SWITCH4 0x0040016C /* RW-4R */
1111#define NV_PGRAPH_CTX_SWITCH4_USER_INSTANCE 15:0 /* RWXUF */
1112#define NV_PGRAPH_CTX_SWITCH4_USER_INSTANCE_INVALID 0x0000 /* RW--V */
1113#define NV_PGRAPH_CTX_CACHE1(i) (0x00400180+(i)*4) /* RW-4A */
1114#define NV_PGRAPH_CTX_CACHE1__SIZE_1 8 /* */
1115#define NV_PGRAPH_CTX_CACHE1_GRCLASS 7:0 /* RWXVF */
1116#define NV_PGRAPH_CTX_CACHE1_CHROMA_KEY 12:12 /* RWXVF */
1117#define NV_PGRAPH_CTX_CACHE1_USER_CLIP 13:13 /* RWXVF */
1118#define NV_PGRAPH_CTX_CACHE1_SWIZZLE 14:14 /* RWXVF */
1119#define NV_PGRAPH_CTX_CACHE1_PATCH_CONFIG 19:15 /* RWXVF */
1120#define NV_PGRAPH_CTX_CACHE1_SPARE1 20:20 /* RWXVF */
1121#define NV_PGRAPH_CTX_CACHE1_PATCH_STATUS 24:24 /* RWXVF */
1122#define NV_PGRAPH_CTX_CACHE1_CONTEXT_SURFACE 25:25 /* RWXVF */
1123#define NV_PGRAPH_CTX_CACHE2(i) (0x004001a0+(i)*4) /* RW-4A */
1124#define NV_PGRAPH_CTX_CACHE2__SIZE_1 8 /* */
1125#define NV_PGRAPH_CTX_CACHE2_MONO_FORMAT 1:0 /* RWXVF */
1126#define NV_PGRAPH_CTX_CACHE2_COLOR_FORMAT 13:8 /* RWXVF */
1127#define NV_PGRAPH_CTX_CACHE2_NOTIFY_INSTANCE 31:16 /* RWXVF */
1128#define NV_PGRAPH_CTX_CACHE3(i) (0x004001c0+(i)*4) /* RW-4A */
1129#define NV_PGRAPH_CTX_CACHE3__SIZE_1 8 /* */
1130#define NV_PGRAPH_CTX_CACHE3_DMA_INSTANCE_0 15:0 /* RWXVF */
1131#define NV_PGRAPH_CTX_CACHE3_DMA_INSTANCE_1 31:16 /* RWXVF */
1132#define NV_PGRAPH_CTX_CACHE4(i) (0x004001e0+(i)*4) /* RW-4A */
1133#define NV_PGRAPH_CTX_CACHE4__SIZE_1 8 /* */
1134#define NV_PGRAPH_CTX_CACHE4_USER_INSTANCE 15:0 /* RWXVF */
1135#define NV_PGRAPH_CTX_CONTROL 0x00400170 /* RW-4R */
1136#define NV_PGRAPH_CTX_CONTROL_MINIMUM_TIME 1:0 /* RWIVF */
1137#define NV_PGRAPH_CTX_CONTROL_MINIMUM_TIME_33US 0x00000000 /* RWI-V */
1138#define NV_PGRAPH_CTX_CONTROL_MINIMUM_TIME_262US 0x00000001 /* RW--V */
1139#define NV_PGRAPH_CTX_CONTROL_MINIMUM_TIME_2MS 0x00000002 /* RW--V */
1140#define NV_PGRAPH_CTX_CONTROL_MINIMUM_TIME_17MS 0x00000003 /* RW--V */
1141#define NV_PGRAPH_CTX_CONTROL_TIME 8:8 /* RWIVF */
1142#define NV_PGRAPH_CTX_CONTROL_TIME_EXPIRED 0x00000000 /* RWI-V */
1143#define NV_PGRAPH_CTX_CONTROL_TIME_NOT_EXPIRED 0x00000001 /* RW--V */
1144#define NV_PGRAPH_CTX_CONTROL_CHID 16:16 /* RWIVF */
1145#define NV_PGRAPH_CTX_CONTROL_CHID_INVALID 0x00000000 /* RWI-V */
1146#define NV_PGRAPH_CTX_CONTROL_CHID_VALID 0x00000001 /* RW--V */
1147#define NV_PGRAPH_CTX_CONTROL_CHANGE 20:20 /* R--VF */
1148#define NV_PGRAPH_CTX_CONTROL_CHANGE_UNAVAILABLE 0x00000000 /* R---V */
1149#define NV_PGRAPH_CTX_CONTROL_CHANGE_AVAILABLE 0x00000001 /* R---V */
1150#define NV_PGRAPH_CTX_CONTROL_SWITCHING 24:24 /* RWIVF */
1151#define NV_PGRAPH_CTX_CONTROL_SWITCHING_IDLE 0x00000000 /* RWI-V */
1152#define NV_PGRAPH_CTX_CONTROL_SWITCHING_BUSY 0x00000001 /* RW--V */
1153#define NV_PGRAPH_CTX_CONTROL_DEVICE 28:28 /* RWIVF */
1154#define NV_PGRAPH_CTX_CONTROL_DEVICE_DISABLED 0x00000000 /* RWI-V */
1155#define NV_PGRAPH_CTX_CONTROL_DEVICE_ENABLED 0x00000001 /* RW--V */
1156#define NV_PGRAPH_CTX_USER 0x00400174 /* RW-4R */
1157#define NV_PGRAPH_CTX_USER_SUBCH 15:13 /* RWIVF */
1158#define NV_PGRAPH_CTX_USER_SUBCH_0 0x00000000 /* RWI-V */
1159#define NV_PGRAPH_CTX_USER_CHID 27:24 /* RWIVF */
1160#define NV_PGRAPH_CTX_USER_CHID_0 0x00000000 /* RWI-V */
1161#define NV_PGRAPH_FIFO 0x00400720 /* RW-4R */
1162#define NV_PGRAPH_FIFO_ACCESS 0:0 /* RWIVF */
1163#define NV_PGRAPH_FIFO_ACCESS_DISABLED 0x00000000 /* RW--V */
1164#define NV_PGRAPH_FIFO_ACCESS_ENABLED 0x00000001 /* RWI-V */
1165#define NV_PGRAPH_FFINTFC_FIFO_0(i) (0x00400730+(i)*4) /* RW-4A */
1166#define NV_PGRAPH_FFINTFC_FIFO_0__SIZE_1 4 /* */
1167#define NV_PGRAPH_FFINTFC_FIFO_0_TAG 0:0 /* RWXVF */
1168#define NV_PGRAPH_FFINTFC_FIFO_0_TAG_MTHD 0x00000000 /* RW--V */
1169#define NV_PGRAPH_FFINTFC_FIFO_0_TAG_CHSW 0x00000001 /* RW--V */
1170#define NV_PGRAPH_FFINTFC_FIFO_0_SUBCH 3:1 /* RWXVF */
1171#define NV_PGRAPH_FFINTFC_FIFO_0_SUBCH_0 0x00000000 /* RW--V */
1172#define NV_PGRAPH_FFINTFC_FIFO_0_SUBCH_1 0x00000001 /* RW--V */
1173#define NV_PGRAPH_FFINTFC_FIFO_0_SUBCH_2 0x00000002 /* RW--V */
1174#define NV_PGRAPH_FFINTFC_FIFO_0_SUBCH_3 0x00000003 /* RW--V */
1175#define NV_PGRAPH_FFINTFC_FIFO_0_SUBCH_4 0x00000004 /* RW--V */
1176#define NV_PGRAPH_FFINTFC_FIFO_0_SUBCH_5 0x00000005 /* RW--V */
1177#define NV_PGRAPH_FFINTFC_FIFO_0_SUBCH_6 0x00000006 /* RW--V */
1178#define NV_PGRAPH_FFINTFC_FIFO_0_SUBCH_7 0x00000007 /* RW--V */
1179#define NV_PGRAPH_FFINTFC_FIFO_0_MTHD 14:4 /* RWXVF */
1180#define NV_PGRAPH_FFINTFC_FIFO_0_MTHD_CTX_SWITCH 0x00000000 /* RW--V */
1181#define NV_PGRAPH_FFINTFC_FIFO_1(i) (0x00400740+(i)*4) /* RW-4A */
1182#define NV_PGRAPH_FFINTFC_FIFO_1__SIZE_1 4 /* */
1183#define NV_PGRAPH_FFINTFC_FIFO_1_ARGUMENT 31:0 /* RWXVF */
1184#define NV_PGRAPH_FFINTFC_FIFO_PTR 0x00400750 /* RW-4R */
1185#define NV_PGRAPH_FFINTFC_FIFO_PTR_WRITE 2:0 /* RWIVF */
1186#define NV_PGRAPH_FFINTFC_FIFO_PTR_WRITE_0 0x00000000 /* RWI-V */
1187#define NV_PGRAPH_FFINTFC_FIFO_PTR_READ 6:4 /* RWIVF */
1188#define NV_PGRAPH_FFINTFC_FIFO_PTR_READ_0 0x00000000 /* RWI-V */
1189#define NV_PGRAPH_FFINTFC_ST2 0x00400754 /* RW-4R */
1190#define NV_PGRAPH_FFINTFC_ST2_STATUS 0:0 /* RWIVF */
1191#define NV_PGRAPH_FFINTFC_ST2_STATUS_INVALID 0x00000000 /* RWI-V */
1192#define NV_PGRAPH_FFINTFC_ST2_STATUS_VALID 0x00000001 /* RW--V */
1193#define NV_PGRAPH_FFINTFC_ST2_MTHD 11:1 /* RWIVF */
1194#define NV_PGRAPH_FFINTFC_ST2_MTHD_CTX_SWITCH 0x00000000 /* RWI-V */
1195#define NV_PGRAPH_FFINTFC_ST2_SUBCH 14:12 /* RWIVF */
1196#define NV_PGRAPH_FFINTFC_ST2_SUBCH_0 0x00000000 /* RWI-V */
1197#define NV_PGRAPH_FFINTFC_ST2_SUBCH_1 0x00000001 /* RW--V */
1198#define NV_PGRAPH_FFINTFC_ST2_SUBCH_2 0x00000002 /* RW--V */
1199#define NV_PGRAPH_FFINTFC_ST2_SUBCH_3 0x00000003 /* RW--V */
1200#define NV_PGRAPH_FFINTFC_ST2_SUBCH_4 0x00000004 /* RW--V */
1201#define NV_PGRAPH_FFINTFC_ST2_SUBCH_5 0x00000005 /* RW--V */
1202#define NV_PGRAPH_FFINTFC_ST2_SUBCH_6 0x00000006 /* RW--V */
1203#define NV_PGRAPH_FFINTFC_ST2_SUBCH_7 0x00000007 /* RW--V */
1204#define NV_PGRAPH_FFINTFC_ST2_CHID 18:15 /* RWIVF */
1205#define NV_PGRAPH_FFINTFC_ST2_CHID_0 0x00000000 /* RWI-V */
1206#define NV_PGRAPH_FFINTFC_ST2_CHID_1 0x00000001 /* RW--V */
1207#define NV_PGRAPH_FFINTFC_ST2_CHID_2 0x00000002 /* RW--V */
1208#define NV_PGRAPH_FFINTFC_ST2_CHID_3 0x00000003 /* RW--V */
1209#define NV_PGRAPH_FFINTFC_ST2_CHID_4 0x00000004 /* RW--V */
1210#define NV_PGRAPH_FFINTFC_ST2_CHID_5 0x00000005 /* RW--V */
1211#define NV_PGRAPH_FFINTFC_ST2_CHID_6 0x00000006 /* RW--V */
1212#define NV_PGRAPH_FFINTFC_ST2_CHID_7 0x00000007 /* RW--V */
1213#define NV_PGRAPH_FFINTFC_ST2_CHID_8 0x00000008 /* RW--V */
1214#define NV_PGRAPH_FFINTFC_ST2_CHID_9 0x00000009 /* RW--V */
1215#define NV_PGRAPH_FFINTFC_ST2_CHID_10 0x0000000A /* RW--V */
1216#define NV_PGRAPH_FFINTFC_ST2_CHID_11 0x0000000B /* RW--V */
1217#define NV_PGRAPH_FFINTFC_ST2_CHID_12 0x0000000C /* RW--V */
1218#define NV_PGRAPH_FFINTFC_ST2_CHID_13 0x0000000D /* RW--V */
1219#define NV_PGRAPH_FFINTFC_ST2_CHID_14 0x0000000E /* RW--V */
1220#define NV_PGRAPH_FFINTFC_ST2_CHID_15 0x0000000F /* RW--V */
1221#define NV_PGRAPH_FFINTFC_ST2_CHID_STATUS 19:19 /* RWIVF */
1222#define NV_PGRAPH_FFINTFC_ST2_CHID_STATUS_INVALID 0x00000000 /* RWI-V */
1223#define NV_PGRAPH_FFINTFC_ST2_CHID_STATUS_VALID 0x00000001 /* RW--V */
1224#define NV_PGRAPH_FFINTFC_ST2_D 0x00400758 /* RW-4R */
1225#define NV_PGRAPH_FFINTFC_ST2_D_ARGUMENT 31:0 /* RWIVF */
1226#define NV_PGRAPH_FFINTFC_ST2_D_ARGUMENT_0 0x00000000 /* RWI-V */
1227#define NV_PGRAPH_STATUS 0x00400700 /* R--4R */
1228#define NV_PGRAPH_STATUS_STATE 0:0 /* R-IVF */
1229#define NV_PGRAPH_STATUS_STATE_IDLE 0x00000000 /* R-I-V */
1230#define NV_PGRAPH_STATUS_STATE_BUSY 0x00000001 /* R---V */
1231#define NV_PGRAPH_STATUS_XY_LOGIC 4:4 /* R-IVF */
1232#define NV_PGRAPH_STATUS_XY_LOGIC_IDLE 0x00000000 /* R-I-V */
1233#define NV_PGRAPH_STATUS_XY_LOGIC_BUSY 0x00000001 /* R---V */
1234#define NV_PGRAPH_STATUS_FE 5:5 /* R-IVF */
1235#define NV_PGRAPH_STATUS_FE_IDLE 0x00000000 /* R-I-V */
1236#define NV_PGRAPH_STATUS_FE_BUSY 0x00000001 /* R---V */
1237#define NV_PGRAPH_STATUS_RASTERIZER 6:6 /* R-IVF */
1238#define NV_PGRAPH_STATUS_RASTERIZER_IDLE 0x00000000 /* R-I-V */
1239#define NV_PGRAPH_STATUS_RASTERIZER_BUSY 0x00000001 /* R---V */
1240#define NV_PGRAPH_STATUS_PORT_NOTIFY 8:8 /* R-IVF */
1241#define NV_PGRAPH_STATUS_PORT_NOTIFY_IDLE 0x00000000 /* R-I-V */
1242#define NV_PGRAPH_STATUS_PORT_NOTIFY_BUSY 0x00000001 /* R---V */
1243#define NV_PGRAPH_STATUS_PORT_REGISTER 12:12 /* R-IVF */
1244#define NV_PGRAPH_STATUS_PORT_REGISTER_IDLE 0x00000000 /* R-I-V */
1245#define NV_PGRAPH_STATUS_PORT_REGISTER_BUSY 0x00000001 /* R---V */
1246#define NV_PGRAPH_STATUS_PORT_DMA 16:16 /* R-IVF */
1247#define NV_PGRAPH_STATUS_PORT_DMA_IDLE 0x00000000 /* R-I-V */
1248#define NV_PGRAPH_STATUS_PORT_DMA_BUSY 0x00000001 /* R---V */
1249#define NV_PGRAPH_STATUS_DMA_ENGINE 17:17 /* R-IVF */
1250#define NV_PGRAPH_STATUS_DMA_ENGINE_IDLE 0x00000000 /* R-I-V */
1251#define NV_PGRAPH_STATUS_DMA_ENGINE_BUSY 0x00000001 /* R---V */
1252#define NV_PGRAPH_STATUS_DMA_NOTIFY 20:20 /* R-IVF */
1253#define NV_PGRAPH_STATUS_DMA_NOTIFY_IDLE 0x00000000 /* R-I-V */
1254#define NV_PGRAPH_STATUS_DMA_NOTIFY_BUSY 0x00000001 /* R---V */
1255#define NV_PGRAPH_STATUS_DMA_BUFFER_NOTIFY 21:21 /* R-IVF */
1256#define NV_PGRAPH_STATUS_DMA_BUFFER_NOTIFY_IDLE 0x00000000 /* R-I-V */
1257#define NV_PGRAPH_STATUS_DMA_BUFFER_NOTIFY_BUSY 0x00000001 /* R---V */
1258#define NV_PGRAPH_STATUS_D3D 24:24 /* R-IVF */
1259#define NV_PGRAPH_STATUS_D3D_IDLE 0x00000000 /* R-I-V */
1260#define NV_PGRAPH_STATUS_D3D_BUSY 0x00000001 /* R---V */
1261#define NV_PGRAPH_STATUS_CACHE 25:25 /* R-IVF */
1262#define NV_PGRAPH_STATUS_CACHE_IDLE 0x00000000 /* R-I-V */
1263#define NV_PGRAPH_STATUS_CACHE_BUSY 0x00000001 /* R---V */
1264#define NV_PGRAPH_STATUS_LIGHTING 26:26 /* R-IVF */
1265#define NV_PGRAPH_STATUS_LIGHTING_IDLE 0x00000000 /* R-I-V */
1266#define NV_PGRAPH_STATUS_LIGHTING_BUSY 0x00000001 /* R---V */
1267#define NV_PGRAPH_STATUS_PREROP 27:27 /* R-IVF */
1268#define NV_PGRAPH_STATUS_PREROP_IDLE 0x00000000 /* R-I-V */
1269#define NV_PGRAPH_STATUS_PREROP_BUSY 0x00000001 /* R---V */
1270#define NV_PGRAPH_STATUS_ROP 28:28 /* R-IVF */
1271#define NV_PGRAPH_STATUS_ROP_IDLE 0x00000000 /* R-I-V */
1272#define NV_PGRAPH_STATUS_ROP_BUSY 0x00000001 /* R---V */
1273#define NV_PGRAPH_STATUS_PORT_USER 29:29 /* R-IVF */
1274#define NV_PGRAPH_STATUS_PORT_USER_IDLE 0x00000000 /* R-I-V */
1275#define NV_PGRAPH_STATUS_PORT_USER_BUSY 0x00000001 /* R---V */
1276#define NV_PGRAPH_TRAPPED_ADDR 0x00400704 /* R--4R */
1277#define NV_PGRAPH_TRAPPED_ADDR_MTHD 12:2 /* R-XUF */
1278#define NV_PGRAPH_TRAPPED_ADDR_SUBCH 15:13 /* R-XUF */
1279#define NV_PGRAPH_TRAPPED_ADDR_CHID 27:24 /* R-XUF */
1280#define NV_PGRAPH_TRAPPED_DATA 0x00400708 /* R--4R */
1281#define NV_PGRAPH_TRAPPED_DATA_VALUE 31:0 /* R-XVF */
1282#define NV_PGRAPH_SURFACE 0x0040070C /* RW-4R */
1283#define NV_PGRAPH_SURFACE_TYPE 1:0 /* RWIVF */
1284#define NV_PGRAPH_SURFACE_TYPE_INVALID 0x00000000 /* RWI-V */
1285#define NV_PGRAPH_SURFACE_TYPE_NON_SWIZZLE 0x00000001 /* RW--V */
1286#define NV_PGRAPH_SURFACE_TYPE_SWIZZLE 0x00000002 /* RW--V */
1287#define NV_PGRAPH_NOTIFY 0x00400714 /* RW-4R */
1288#define NV_PGRAPH_NOTIFY_BUFFER_REQ 0:0 /* RWIVF */
1289#define NV_PGRAPH_NOTIFY_BUFFER_REQ_NOT_PENDING 0x00000000 /* RWI-V */
1290#define NV_PGRAPH_NOTIFY_BUFFER_REQ_PENDING 0x00000001 /* RW--V */
1291#define NV_PGRAPH_NOTIFY_BUFFER_STYLE 8:8 /* RWIVF */
1292#define NV_PGRAPH_NOTIFY_BUFFER_STYLE_WRITE_ONLY 0x00000000 /* RWI-V */
1293#define NV_PGRAPH_NOTIFY_BUFFER_STYLE_WRITE_THEN_AWAKEN 0x00000001 /* RW--V */
1294#define NV_PGRAPH_NOTIFY_REQ 16:16 /* RWIVF */
1295#define NV_PGRAPH_NOTIFY_REQ_NOT_PENDING 0x00000000 /* RWI-V */
1296#define NV_PGRAPH_NOTIFY_REQ_PENDING 0x00000001 /* RW--V */
1297#define NV_PGRAPH_NOTIFY_STYLE 20:20 /* RWIVF */
1298#define NV_PGRAPH_NOTIFY_STYLE_WRITE_ONLY 0x00000000 /* RWI-V */
1299#define NV_PGRAPH_NOTIFY_STYLE_WRITE_THEN_AWAKEN 0x00000001 /* RW--V */
1300#define NV_PGRAPH_BOFFSET(i) (0x00400640+(i)*4) /* RW-4A */
1301#define NV_PGRAPH_BOFFSET__SIZE_1 6 /* */
1302#define NV_PGRAPH_BOFFSET_LINADRS 23:0 /* RWIUF */
1303#define NV_PGRAPH_BOFFSET_LINADRS_0 0x00000000 /* RWI-V */
1304#define NV_PGRAPH_BOFFSET0 0x00400640 /* RW-4R */
1305#define NV_PGRAPH_BOFFSET0__ALIAS_1 NV_PGRAPH_BOFFSET(0) /* */
1306#define NV_PGRAPH_BOFFSET0_LINADRS 23:0 /* RWIUF */
1307#define NV_PGRAPH_BOFFSET0_LINADRS_0 0x00000000 /* RWI-V */
1308#define NV_PGRAPH_BOFFSET1 0x00400644 /* RW-4R */
1309#define NV_PGRAPH_BOFFSET1__ALIAS_1 NV_PGRAPH_BOFFSET(1) /* */
1310#define NV_PGRAPH_BOFFSET1_LINADRS 23:0 /* RWIUF */
1311#define NV_PGRAPH_BOFFSET1_LINADRS_0 0x00000000 /* RWI-V */
1312#define NV_PGRAPH_BOFFSET2 0x00400648 /* RW-4R */
1313#define NV_PGRAPH_BOFFSET2__ALIAS_1 NV_PGRAPH_BOFFSET(2) /* */
1314#define NV_PGRAPH_BOFFSET2_LINADRS 23:0 /* RWIUF */
1315#define NV_PGRAPH_BOFFSET2_LINADRS_0 0x00000000 /* RWI-V */
1316#define NV_PGRAPH_BOFFSET3 0x0040064C /* RW-4R */
1317#define NV_PGRAPH_BOFFSET3__ALIAS_1 NV_PGRAPH_BOFFSET(3) /* */
1318#define NV_PGRAPH_BOFFSET3_LINADRS 23:0 /* RWIUF */
1319#define NV_PGRAPH_BOFFSET3_LINADRS_0 0x00000000 /* RWI-V */
1320#define NV_PGRAPH_BOFFSET4 0x00400650 /* RW-4R */
1321#define NV_PGRAPH_BOFFSET4__ALIAS_1 NV_PGRAPH_BOFFSET(4) /* */
1322#define NV_PGRAPH_BOFFSET4_LINADRS 23:0 /* RWIUF */
1323#define NV_PGRAPH_BOFFSET4_LINADRS_0 0x00000000 /* RWI-V */
1324#define NV_PGRAPH_BOFFSET5 0x00400654 /* RW-4R */
1325#define NV_PGRAPH_BOFFSET5__ALIAS_1 NV_PGRAPH_BOFFSET(5) /* */
1326#define NV_PGRAPH_BOFFSET5_LINADRS 23:0 /* RWIUF */
1327#define NV_PGRAPH_BOFFSET5_LINADRS_0 0x00000000 /* RWI-V */
1328#define NV_PGRAPH_BBASE(i) (0x00400658+(i)*4) /* RW-4A */
1329#define NV_PGRAPH_BBASE__SIZE_1 6 /* */
1330#define NV_PGRAPH_BBASE_LINADRS 23:0 /* RWIUF */
1331#define NV_PGRAPH_BBASE_LINADRS_0 0x00000000 /* RWI-V */
1332#define NV_PGRAPH_BBASE0 0x00400658 /* RW-4R */
1333#define NV_PGRAPH_BBASE0__ALIAS_1 NV_PGRAPH_BBASE(0) /* */
1334#define NV_PGRAPH_BBASE0_LINADRS 23:0 /* RWIUF */
1335#define NV_PGRAPH_BBASE0_LINADRS_0 0x00000000 /* RWI-V */
1336#define NV_PGRAPH_BBASE1 0x0040065c /* RW-4R */
1337#define NV_PGRAPH_BBASE1__ALIAS_1 NV_PGRAPH_BBASE(1) /* */
1338#define NV_PGRAPH_BBASE1_LINADRS 23:0 /* RWIUF */
1339#define NV_PGRAPH_BBASE1_LINADRS_0 0x00000000 /* RWI-V */
1340#define NV_PGRAPH_BBASE2 0x00400660 /* RW-4R */
1341#define NV_PGRAPH_BBASE2__ALIAS_1 NV_PGRAPH_BBASE(2) /* */
1342#define NV_PGRAPH_BBASE2_LINADRS 23:0 /* RWIUF */
1343#define NV_PGRAPH_BBASE2_LINADRS_0 0x00000000 /* RWI-V */
1344#define NV_PGRAPH_BBASE3 0x00400664 /* RW-4R */
1345#define NV_PGRAPH_BBASE3__ALIAS_1 NV_PGRAPH_BBASE(3) /* */
1346#define NV_PGRAPH_BBASE3_LINADRS 23:0 /* RWIUF */
1347#define NV_PGRAPH_BBASE3_LINADRS_0 0x00000000 /* RWI-V */
1348#define NV_PGRAPH_BBASE4 0x00400668 /* RW-4R */
1349#define NV_PGRAPH_BBASE4__ALIAS_1 NV_PGRAPH_BBASE(4) /* */
1350#define NV_PGRAPH_BBASE4_LINADRS 23:0 /* RWIUF */
1351#define NV_PGRAPH_BBASE4_LINADRS_0 0x00000000 /* RWI-V */
1352#define NV_PGRAPH_BBASE5 0x0040066C /* RW-4R */
1353#define NV_PGRAPH_BBASE5__ALIAS_1 NV_PGRAPH_BBASE(5) /* */
1354#define NV_PGRAPH_BBASE5_LINADRS 23:0 /* RWIUF */
1355#define NV_PGRAPH_BBASE5_LINADRS_0 0x00000000 /* RWI-V */
1356#define NV_PGRAPH_BPITCH(i) (0x00400670+(i)*4) /* RW-4A */
1357#define NV_PGRAPH_BPITCH__SIZE_1 5 /* */
1358#define NV_PGRAPH_BPITCH_VALUE 12:0 /* RWIUF */
1359#define NV_PGRAPH_BPITCH_VALUE_0 0x00000000 /* RWI-V */
1360#define NV_PGRAPH_BPITCH0 0x00400670 /* RW-4R */
1361#define NV_PGRAPH_BPITCH0__ALIAS_1 NV_PGRAPH_BPITCH(0) /* */
1362#define NV_PGRAPH_BPITCH0_VALUE 12:0 /* RWIUF */
1363#define NV_PGRAPH_BPITCH0_VALUE_0 0x00000000 /* RWI-V */
1364#define NV_PGRAPH_BPITCH1 0x00400674 /* RW-4R */
1365#define NV_PGRAPH_BPITCH1__ALIAS_1 NV_PGRAPH_BPITCH(1) /* */
1366#define NV_PGRAPH_BPITCH1_VALUE 12:0 /* RWIUF */
1367#define NV_PGRAPH_BPITCH1_VALUE_0 0x00000000 /* RWI-V */
1368#define NV_PGRAPH_BPITCH2 0x00400678 /* RW-4R */
1369#define NV_PGRAPH_BPITCH2__ALIAS_1 NV_PGRAPH_BPITCH(2) /* */
1370#define NV_PGRAPH_BPITCH2_VALUE 12:0 /* RWIUF */
1371#define NV_PGRAPH_BPITCH2_VALUE_0 0x00000000 /* RWI-V */
1372#define NV_PGRAPH_BPITCH3 0x0040067C /* RW-4R */
1373#define NV_PGRAPH_BPITCH3__ALIAS_1 NV_PGRAPH_BPITCH(3) /* */
1374#define NV_PGRAPH_BPITCH3_VALUE 12:0 /* RWIUF */
1375#define NV_PGRAPH_BPITCH3_VALUE_0 0x00000000 /* RWI-V */
1376#define NV_PGRAPH_BPITCH4 0x00400680 /* RW-4R */
1377#define NV_PGRAPH_BPITCH4__ALIAS_1 NV_PGRAPH_BPITCH(4) /* */
1378#define NV_PGRAPH_BPITCH4_VALUE 12:0 /* RWIUF */
1379#define NV_PGRAPH_BPITCH4_VALUE_0 0x00000000 /* RWI-V */
1380#define NV_PGRAPH_BLIMIT(i) (0x00400684+(i)*4) /* RW-4A */
1381#define NV_PGRAPH_BLIMIT__SIZE_1 6 /* */
1382#define NV_PGRAPH_BLIMIT_VALUE 23:0 /* RWXUF */
1383#define NV_PGRAPH_BLIMIT_TYPE 31:31 /* RWIVF */
1384#define NV_PGRAPH_BLIMIT_TYPE_IN_MEMORY 0x00000000 /* RW--V */
1385#define NV_PGRAPH_BLIMIT_TYPE_NULL 0x00000001 /* RWI-V */
1386#define NV_PGRAPH_BLIMIT0 0x00400684 /* RW-4R */
1387#define NV_PGRAPH_BLIMIT0__ALIAS_1 NV_PGRAPH_BLIMIT(0) /* */
1388#define NV_PGRAPH_BLIMIT0_VALUE 23:0 /* RWXUF */
1389#define NV_PGRAPH_BLIMIT0_TYPE 31:31 /* RWIVF */
1390#define NV_PGRAPH_BLIMIT0_TYPE_IN_MEMORY 0x00000000 /* RW--V */
1391#define NV_PGRAPH_BLIMIT0_TYPE_NULL 0x00000001 /* RWI-V */
1392#define NV_PGRAPH_BLIMIT1 0x00400688 /* RW-4R */
1393#define NV_PGRAPH_BLIMIT1__ALIAS_1 NV_PGRAPH_BLIMIT(1) /* */
1394#define NV_PGRAPH_BLIMIT1_VALUE 23:0 /* RWXUF */
1395#define NV_PGRAPH_BLIMIT1_TYPE 31:31 /* RWIVF */
1396#define NV_PGRAPH_BLIMIT1_TYPE_IN_MEMORY 0x00000000 /* RW--V */
1397#define NV_PGRAPH_BLIMIT1_TYPE_NULL 0x00000001 /* RWI-V */
1398#define NV_PGRAPH_BLIMIT2 0x0040068c /* RW-4R */
1399#define NV_PGRAPH_BLIMIT2__ALIAS_1 NV_PGRAPH_BLIMIT(2) /* */
1400#define NV_PGRAPH_BLIMIT2_VALUE 23:0 /* RWXUF */
1401#define NV_PGRAPH_BLIMIT2_TYPE 31:31 /* RWIVF */
1402#define NV_PGRAPH_BLIMIT2_TYPE_IN_MEMORY 0x00000000 /* RW--V */
1403#define NV_PGRAPH_BLIMIT2_TYPE_NULL 0x00000001 /* RWI-V */
1404#define NV_PGRAPH_BLIMIT3 0x00400690 /* RW-4R */
1405#define NV_PGRAPH_BLIMIT3__ALIAS_1 NV_PGRAPH_BLIMIT(3) /* */
1406#define NV_PGRAPH_BLIMIT3_VALUE 23:0 /* RWXUF */
1407#define NV_PGRAPH_BLIMIT3_TYPE 31:31 /* RWIVF */
1408#define NV_PGRAPH_BLIMIT3_TYPE_IN_MEMORY 0x00000000 /* RW--V */
1409#define NV_PGRAPH_BLIMIT3_TYPE_NULL 0x00000001 /* RWI-V */
1410#define NV_PGRAPH_BLIMIT4 0x00400694 /* RW-4R */
1411#define NV_PGRAPH_BLIMIT4__ALIAS_1 NV_PGRAPH_BLIMIT(4) /* */
1412#define NV_PGRAPH_BLIMIT4_VALUE 23:0 /* RWXUF */
1413#define NV_PGRAPH_BLIMIT4_TYPE 31:31 /* RWIVF */
1414#define NV_PGRAPH_BLIMIT4_TYPE_IN_MEMORY 0x00000000 /* RW--V */
1415#define NV_PGRAPH_BLIMIT4_TYPE_NULL 0x00000001 /* RWI-V */
1416#define NV_PGRAPH_BLIMIT5 0x00400698 /* RW-4R */
1417#define NV_PGRAPH_BLIMIT5__ALIAS_1 NV_PGRAPH_BLIMIT(5) /* */
1418#define NV_PGRAPH_BLIMIT5_VALUE 23:0 /* RWXUF */
1419#define NV_PGRAPH_BLIMIT5_TYPE 31:31 /* RWIVF */
1420#define NV_PGRAPH_BLIMIT5_TYPE_IN_MEMORY 0x00000000 /* RW--V */
1421#define NV_PGRAPH_BLIMIT5_TYPE_NULL 0x00000001 /* RWI-V */
1422#define NV_PGRAPH_BSWIZZLE2 0x0040069c /* RW-4R */
1423#define NV_PGRAPH_BSWIZZLE2_WIDTH 19:16 /* RWIUF */
1424#define NV_PGRAPH_BSWIZZLE2_WIDTH_0 0x00000000 /* RWI-V */
1425#define NV_PGRAPH_BSWIZZLE2_HEIGHT 27:24 /* RWIUF */
1426#define NV_PGRAPH_BSWIZZLE2_HEIGHT_0 0x00000000 /* RWI-V */
1427#define NV_PGRAPH_BSWIZZLE5 0x004006a0 /* RW-4R */
1428#define NV_PGRAPH_BSWIZZLE5_WIDTH 19:16 /* RWIUF */
1429#define NV_PGRAPH_BSWIZZLE5_WIDTH_0 0x00000000 /* RWI-V */
1430#define NV_PGRAPH_BSWIZZLE5_HEIGHT 27:24 /* RWIUF */
1431#define NV_PGRAPH_BSWIZZLE5_HEIGHT_0 0x00000000 /* RWI-V */
1432#define NV_PGRAPH_BPIXEL 0x00400724 /* RW-4R */
1433#define NV_PGRAPH_BPIXEL_DEPTH0 3:0 /* RWIVF */
1434#define NV_PGRAPH_BPIXEL_DEPTH0_INVALID 0x00000000 /* RWI-V */
1435#define NV_PGRAPH_BPIXEL_DEPTH0_Y8 0x00000001 /* RW--V */
1436#define NV_PGRAPH_BPIXEL_DEPTH0_X1R5G5B5_Z1R5G5B5 0x00000002 /* RW--V */
1437#define NV_PGRAPH_BPIXEL_DEPTH0_X1R5G5B5_O1R5G5B5 0x00000003 /* RW--V */
1438#define NV_PGRAPH_BPIXEL_DEPTH0_A1R5G5B5 0x00000004 /* RW--V */
1439#define NV_PGRAPH_BPIXEL_DEPTH0_R5G6B5 0x00000005 /* RW--V */
1440#define NV_PGRAPH_BPIXEL_DEPTH0_Y16 0x00000006 /* RW--V */
1441#define NV_PGRAPH_BPIXEL_DEPTH0_X8R8G8B8_Z8R8G8B8 0x00000007 /* RW--V */
1442#define NV_PGRAPH_BPIXEL_DEPTH0_X8R8G8B8_O1Z7R8G8B8 0x00000008 /* RW--V */
1443#define NV_PGRAPH_BPIXEL_DEPTH0_X1A7R8G8B8_Z1A7R8G8B8 0x00000009 /* RW--V */
1444#define NV_PGRAPH_BPIXEL_DEPTH0_X1A7R8G8B8_O1A7R8G8B8 0x0000000a /* RW--V */
1445#define NV_PGRAPH_BPIXEL_DEPTH0_X8R8G8B8_O8R8G8B8 0x0000000b /* RW--V */
1446#define NV_PGRAPH_BPIXEL_DEPTH0_A8R8G8B8 0x0000000c /* RW--V */
1447#define NV_PGRAPH_BPIXEL_DEPTH0_Y32 0x0000000d /* RW--V */
1448#define NV_PGRAPH_BPIXEL_DEPTH0_V8YB8U8YA8 0x0000000e /* RW--V */
1449#define NV_PGRAPH_BPIXEL_DEPTH0_YB8V8YA8U8 0x0000000f /* RW--V */
1450#define NV_PGRAPH_BPIXEL_DEPTH1 7:4 /* RWIVF */
1451#define NV_PGRAPH_BPIXEL_DEPTH1_INVALID 0x00000000 /* RWI-V */
1452#define NV_PGRAPH_BPIXEL_DEPTH1_Y8 0x00000001 /* RW--V */
1453#define NV_PGRAPH_BPIXEL_DEPTH1_X1R5G5B5_Z1R5G5B5 0x00000002 /* RW--V */
1454#define NV_PGRAPH_BPIXEL_DEPTH1_X1R5G5B5_O1R5G5B5 0x00000003 /* RW--V */
1455#define NV_PGRAPH_BPIXEL_DEPTH1_A1R5G5B5 0x00000004 /* RW--V */
1456#define NV_PGRAPH_BPIXEL_DEPTH1_R5G6B5 0x00000005 /* RW--V */
1457#define NV_PGRAPH_BPIXEL_DEPTH1_Y16 0x00000006 /* RW--V */
1458#define NV_PGRAPH_BPIXEL_DEPTH1_X8R8G8B8_Z8R8G8B8 0x00000007 /* RW--V */
1459#define NV_PGRAPH_BPIXEL_DEPTH1_X8R8G8B8_O1Z7R8G8B8 0x00000008 /* RW--V */
1460#define NV_PGRAPH_BPIXEL_DEPTH1_X1A7R8G8B8_Z1A7R8G8B8 0x00000009 /* RW--V */
1461#define NV_PGRAPH_BPIXEL_DEPTH1_X1A7R8G8B8_O1A7R8G8B8 0x0000000a /* RW--V */
1462#define NV_PGRAPH_BPIXEL_DEPTH1_X8R8G8B8_O8R8G8B8 0x0000000b /* RW--V */
1463#define NV_PGRAPH_BPIXEL_DEPTH1_A8R8G8B8 0x0000000c /* RW--V */
1464#define NV_PGRAPH_BPIXEL_DEPTH1_Y32 0x0000000d /* RW--V */
1465#define NV_PGRAPH_BPIXEL_DEPTH1_V8YB8U8YA8 0x0000000e /* RW--V */
1466#define NV_PGRAPH_BPIXEL_DEPTH1_YB8V8YA8U8 0x0000000f /* RW--V */
1467#define NV_PGRAPH_BPIXEL_DEPTH2 11:8 /* RWIVF */
1468#define NV_PGRAPH_BPIXEL_DEPTH2_INVALID 0x00000000 /* RWI-V */
1469#define NV_PGRAPH_BPIXEL_DEPTH2_Y8 0x00000001 /* RW--V */
1470#define NV_PGRAPH_BPIXEL_DEPTH2_X1R5G5B5_Z1R5G5B5 0x00000002 /* RW--V */
1471#define NV_PGRAPH_BPIXEL_DEPTH2_X1R5G5B5_O1R5G5B5 0x00000003 /* RW--V */
1472#define NV_PGRAPH_BPIXEL_DEPTH2_A1R5G5B5 0x00000004 /* RW--V */
1473#define NV_PGRAPH_BPIXEL_DEPTH2_R5G6B5 0x00000005 /* RW--V */
1474#define NV_PGRAPH_BPIXEL_DEPTH2_Y16 0x00000006 /* RW--V */
1475#define NV_PGRAPH_BPIXEL_DEPTH2_X8R8G8B8_Z8R8G8B8 0x00000007 /* RW--V */
1476#define NV_PGRAPH_BPIXEL_DEPTH2_X8R8G8B8_O1Z7R8G8B8 0x00000008 /* RW--V */
1477#define NV_PGRAPH_BPIXEL_DEPTH2_X1A7R8G8B8_Z1A7R8G8B8 0x00000009 /* RW--V */
1478#define NV_PGRAPH_BPIXEL_DEPTH2_X1A7R8G8B8_O1A7R8G8B8 0x0000000a /* RW--V */
1479#define NV_PGRAPH_BPIXEL_DEPTH2_X8R8G8B8_O8R8G8B8 0x0000000b /* RW--V */
1480#define NV_PGRAPH_BPIXEL_DEPTH2_A8R8G8B8 0x0000000c /* RW--V */
1481#define NV_PGRAPH_BPIXEL_DEPTH2_Y32 0x0000000d /* RW--V */
1482#define NV_PGRAPH_BPIXEL_DEPTH2_V8YB8U8YA8 0x0000000e /* RW--V */
1483#define NV_PGRAPH_BPIXEL_DEPTH2_YB8V8YA8U8 0x0000000f /* RW--V */
1484#define NV_PGRAPH_BPIXEL_DEPTH3 15:12 /* RWIVF */
1485#define NV_PGRAPH_BPIXEL_DEPTH3_INVALID 0x00000000 /* RWI-V */
1486#define NV_PGRAPH_BPIXEL_DEPTH3_Y8 0x00000001 /* RW--V */
1487#define NV_PGRAPH_BPIXEL_DEPTH3_X1R5G5B5_Z1R5G5B5 0x00000002 /* RW--V */
1488#define NV_PGRAPH_BPIXEL_DEPTH3_X1R5G5B5_O1R5G5B5 0x00000003 /* RW--V */
1489#define NV_PGRAPH_BPIXEL_DEPTH3_A1R5G5B5 0x00000004 /* RW--V */
1490#define NV_PGRAPH_BPIXEL_DEPTH3_R5G6B5 0x00000005 /* RW--V */
1491#define NV_PGRAPH_BPIXEL_DEPTH3_Y16 0x00000006 /* RW--V */
1492#define NV_PGRAPH_BPIXEL_DEPTH3_X8R8G8B8_Z8R8G8B8 0x00000007 /* RW--V */
1493#define NV_PGRAPH_BPIXEL_DEPTH3_X8R8G8B8_O1Z7R8G8B8 0x00000008 /* RW--V */
1494#define NV_PGRAPH_BPIXEL_DEPTH3_X1A7R8G8B8_Z1A7R8G8B8 0x00000009 /* RW--V */
1495#define NV_PGRAPH_BPIXEL_DEPTH3_X1A7R8G8B8_O1A7R8G8B8 0x0000000a /* RW--V */
1496#define NV_PGRAPH_BPIXEL_DEPTH3_X8R8G8B8_O8R8G8B8 0x0000000b /* RW--V */
1497#define NV_PGRAPH_BPIXEL_DEPTH3_A8R8G8B8 0x0000000c /* RW--V */
1498#define NV_PGRAPH_BPIXEL_DEPTH3_Y32 0x0000000d /* RW--V */
1499#define NV_PGRAPH_BPIXEL_DEPTH3_V8YB8U8YA8 0x0000000e /* RW--V */
1500#define NV_PGRAPH_BPIXEL_DEPTH3_YB8V8YA8U8 0x0000000f /* RW--V */
1501#define NV_PGRAPH_BPIXEL_DEPTH4 19:16 /* RWIVF */
1502#define NV_PGRAPH_BPIXEL_DEPTH4_INVALID 0x00000000 /* RWI-V */
1503#define NV_PGRAPH_BPIXEL_DEPTH4_Y8 0x00000001 /* RW--V */
1504#define NV_PGRAPH_BPIXEL_DEPTH4_X1R5G5B5_Z1R5G5B5 0x00000002 /* RW--V */
1505#define NV_PGRAPH_BPIXEL_DEPTH4_X1R5G5B5_O1R5G5B5 0x00000003 /* RW--V */
1506#define NV_PGRAPH_BPIXEL_DEPTH4_A1R5G5B5 0x00000004 /* RW--V */
1507#define NV_PGRAPH_BPIXEL_DEPTH4_R5G6B5 0x00000005 /* RW--V */
1508#define NV_PGRAPH_BPIXEL_DEPTH4_Y16 0x00000006 /* RW--V */
1509#define NV_PGRAPH_BPIXEL_DEPTH4_X8R8G8B8_Z8R8G8B8 0x00000007 /* RW--V */
1510#define NV_PGRAPH_BPIXEL_DEPTH4_X8R8G8B8_O1Z7R8G8B8 0x00000008 /* RW--V */
1511#define NV_PGRAPH_BPIXEL_DEPTH4_X1A7R8G8B8_Z1A7R8G8B8 0x00000009 /* RW--V */
1512#define NV_PGRAPH_BPIXEL_DEPTH4_X1A7R8G8B8_O1A7R8G8B8 0x0000000a /* RW--V */
1513#define NV_PGRAPH_BPIXEL_DEPTH4_X8R8G8B8_O8R8G8B8 0x0000000b /* RW--V */
1514#define NV_PGRAPH_BPIXEL_DEPTH4_A8R8G8B8 0x0000000c /* RW--V */
1515#define NV_PGRAPH_BPIXEL_DEPTH4_Y32 0x0000000d /* RW--V */
1516#define NV_PGRAPH_BPIXEL_DEPTH4_V8YB8U8YA8 0x0000000e /* RW--V */
1517#define NV_PGRAPH_BPIXEL_DEPTH4_YB8V8YA8U8 0x0000000f /* RW--V */
1518#define NV_PGRAPH_BPIXEL_DEPTH5 23:20 /* RWIVF */
1519#define NV_PGRAPH_BPIXEL_DEPTH5_INVALID 0x00000000 /* RWI-V */
1520#define NV_PGRAPH_BPIXEL_DEPTH5_Y8 0x00000001 /* RW--V */
1521#define NV_PGRAPH_BPIXEL_DEPTH5_X1R5G5B5_Z1R5G5B5 0x00000002 /* RW--V */
1522#define NV_PGRAPH_BPIXEL_DEPTH5_X1R5G5B5_O1R5G5B5 0x00000003 /* RW--V */
1523#define NV_PGRAPH_BPIXEL_DEPTH5_A1R5G5B5 0x00000004 /* RW--V */
1524#define NV_PGRAPH_BPIXEL_DEPTH5_R5G6B5 0x00000005 /* RW--V */
1525#define NV_PGRAPH_BPIXEL_DEPTH5_Y16 0x00000006 /* RW--V */
1526#define NV_PGRAPH_BPIXEL_DEPTH5_X8R8G8B8_Z8R8G8B8 0x00000007 /* RW--V */
1527#define NV_PGRAPH_BPIXEL_DEPTH5_X8R8G8B8_O1Z7R8G8B8 0x00000008 /* RW--V */
1528#define NV_PGRAPH_BPIXEL_DEPTH5_X1A7R8G8B8_Z1A7R8G8B8 0x00000009 /* RW--V */
1529#define NV_PGRAPH_BPIXEL_DEPTH5_X1A7R8G8B8_O1A7R8G8B8 0x0000000a /* RW--V */
1530#define NV_PGRAPH_BPIXEL_DEPTH5_X8R8G8B8_O8R8G8B8 0x0000000b /* RW--V */
1531#define NV_PGRAPH_BPIXEL_DEPTH5_A8R8G8B8 0x0000000c /* RW--V */
1532#define NV_PGRAPH_BPIXEL_DEPTH5_Y32 0x0000000d /* RW--V */
1533#define NV_PGRAPH_BPIXEL_DEPTH5_V8YB8U8YA8 0x0000000e /* RW--V */
1534#define NV_PGRAPH_BPIXEL_DEPTH5_YB8V8YA8U8 0x0000000f /* RW--V */
1535#define NV_PGRAPH_LIMIT_VIOL_PIX 0x00400610 /* RW-4R */
1536#define NV_PGRAPH_LIMIT_VIOL_PIX_ADRS 23:0 /* RWIVF */
1537#define NV_PGRAPH_LIMIT_VIOL_PIX_ADRS_0 0x00000000 /* RWI-V */
1538#define NV_PGRAPH_LIMIT_VIOL_PIX_BLIT 29:29 /* RWIVF */
1539#define NV_PGRAPH_LIMIT_VIOL_PIX_BLIT_NO_VIOL 0x00000000 /* RWI-V */
1540#define NV_PGRAPH_LIMIT_VIOL_PIX_BLIT_VIOL 0x00000001 /* RW--V */
1541#define NV_PGRAPH_LIMIT_VIOL_PIX_LIMIT 30:30 /* RWIVF */
1542#define NV_PGRAPH_LIMIT_VIOL_PIX_LIMIT_NO_VIOL 0x00000000 /* RWI-V */
1543#define NV_PGRAPH_LIMIT_VIOL_PIX_LIMIT_VIOL 0x00000001 /* RW--V */
1544#define NV_PGRAPH_LIMIT_VIOL_PIX_OVRFLW 31:31 /* RWIVF */
1545#define NV_PGRAPH_LIMIT_VIOL_PIX_OVRFLW_NO_VIOL 0x00000000 /* RWI-V */
1546#define NV_PGRAPH_LIMIT_VIOL_PIX_OVRFLW_VIOL 0x00000001 /* RW--V */
1547#define NV_PGRAPH_LIMIT_VIOL_Z 0x00400614 /* RW-4R */
1548#define NV_PGRAPH_LIMIT_VIOL_Z_ADRS 23:0 /* RWIVF */
1549#define NV_PGRAPH_LIMIT_VIOL_Z_ADRS_0 0x00000000 /* RWI-V */
1550#define NV_PGRAPH_LIMIT_VIOL_Z_LIMIT 30:30 /* RWIVF */
1551#define NV_PGRAPH_LIMIT_VIOL_Z_LIMIT_NO_VIOL 0x00000000 /* RWI-V */
1552#define NV_PGRAPH_LIMIT_VIOL_Z_LIMIT_VIOL 0x00000001 /* RW--V */
1553#define NV_PGRAPH_LIMIT_VIOL_Z_OVRFLW 31:31 /* RWIVF */
1554#define NV_PGRAPH_LIMIT_VIOL_Z_OVRFLW_NO_VIOL 0x00000000 /* RWI-V */
1555#define NV_PGRAPH_LIMIT_VIOL_Z_OVRFLW_VIOL 0x00000001 /* RW--V */
1556#define NV_PGRAPH_STATE 0x00400710 /* RW-4R */
1557#define NV_PGRAPH_STATE_BUFFER_0 0:0 /* RWIVF */
1558#define NV_PGRAPH_STATE_BUFFER_0_INVALID 0x00000000 /* RWI-V */
1559#define NV_PGRAPH_STATE_BUFFER_0_VALID 0x00000001 /* RW--V */
1560#define NV_PGRAPH_STATE_BUFFER_1 1:1 /* RWIVF */
1561#define NV_PGRAPH_STATE_BUFFER_1_INVALID 0x00000000 /* RWI-V */
1562#define NV_PGRAPH_STATE_BUFFER_1_VALID 0x00000001 /* RW--V */
1563#define NV_PGRAPH_STATE_BUFFER_2 2:2 /* RWIVF */
1564#define NV_PGRAPH_STATE_BUFFER_2_INVALID 0x00000000 /* RWI-V */
1565#define NV_PGRAPH_STATE_BUFFER_2_VALID 0x00000001 /* RW--V */
1566#define NV_PGRAPH_STATE_BUFFER_3 3:3 /* RWIVF */
1567#define NV_PGRAPH_STATE_BUFFER_3_INVALID 0x00000000 /* RWI-V */
1568#define NV_PGRAPH_STATE_BUFFER_3_VALID 0x00000001 /* RW--V */
1569#define NV_PGRAPH_STATE_BUFFER_4 4:4 /* RWIVF */
1570#define NV_PGRAPH_STATE_BUFFER_4_INVALID 0x00000000 /* RWI-V */
1571#define NV_PGRAPH_STATE_BUFFER_4_VALID 0x00000001 /* RW--V */
1572#define NV_PGRAPH_STATE_BUFFER_5 5:5 /* RWIVF */
1573#define NV_PGRAPH_STATE_BUFFER_5_INVALID 0x00000000 /* RWI-V */
1574#define NV_PGRAPH_STATE_BUFFER_5_VALID 0x00000001 /* RW--V */
1575#define NV_PGRAPH_STATE_PITCH_0 8:8 /* RWIVF */
1576#define NV_PGRAPH_STATE_PITCH_0_INVALID 0x00000000 /* RWI-V */
1577#define NV_PGRAPH_STATE_PITCH_0_VALID 0x00000001 /* RW--V */
1578#define NV_PGRAPH_STATE_PITCH_1 9:9 /* RWIVF */
1579#define NV_PGRAPH_STATE_PITCH_1_INVALID 0x00000000 /* RWI-V */
1580#define NV_PGRAPH_STATE_PITCH_1_VALID 0x00000001 /* RW--V */
1581#define NV_PGRAPH_STATE_PITCH_2 10:10 /* RWIVF */
1582#define NV_PGRAPH_STATE_PITCH_2_INVALID 0x00000000 /* RWI-V */
1583#define NV_PGRAPH_STATE_PITCH_2_VALID 0x00000001 /* RW--V */
1584#define NV_PGRAPH_STATE_PITCH_3 11:11 /* RWIVF */
1585#define NV_PGRAPH_STATE_PITCH_3_INVALID 0x00000000 /* RWI-V */
1586#define NV_PGRAPH_STATE_PITCH_3_VALID 0x00000001 /* RW--V */
1587#define NV_PGRAPH_STATE_PITCH_4 12:12 /* RWIVF */
1588#define NV_PGRAPH_STATE_PITCH_4_INVALID 0x00000000 /* RWI-V */
1589#define NV_PGRAPH_STATE_PITCH_4_VALID 0x00000001 /* RW--V */
1590#define NV_PGRAPH_STATE_CHROMA_COLOR 16:16 /* RWIVF */
1591#define NV_PGRAPH_STATE_CHROMA_COLOR_INVALID 0x00000000 /* RWI-V */
1592#define NV_PGRAPH_STATE_CHROMA_COLOR_VALID 0x00000001 /* RW--V */
1593#define NV_PGRAPH_STATE_CHROMA_COLORFMT 17:17 /* RWIVF */
1594#define NV_PGRAPH_STATE_CHROMA_COLORFMT_INVALID 0x00000000 /* RWI-V */
1595#define NV_PGRAPH_STATE_CHROMA_COLORFMT_VALID 0x00000001 /* RW--V */
1596#define NV_PGRAPH_STATE_CPATTERN_COLORFMT 20:20 /* RWIVF */
1597#define NV_PGRAPH_STATE_CPATTERN_COLORFMT_INVALID 0x00000000 /* RWI-V */
1598#define NV_PGRAPH_STATE_CPATTERN_COLORFMT_VALID 0x00000001 /* RW--V */
1599#define NV_PGRAPH_STATE_CPATTERN_MONOFMT 21:21 /* RWIVF */
1600#define NV_PGRAPH_STATE_CPATTERN_MONOFMT_INVALID 0x00000000 /* RWI-V */
1601#define NV_PGRAPH_STATE_CPATTERN_MONOFMT_VALID 0x00000001 /* RW--V */
1602#define NV_PGRAPH_STATE_CPATTERN_SELECT 22:22 /* RWIVF */
1603#define NV_PGRAPH_STATE_CPATTERN_SELECT_INVALID 0x00000000 /* RWI-V */
1604#define NV_PGRAPH_STATE_CPATTERN_SELECT_VALID 0x00000001 /* RW--V */
1605#define NV_PGRAPH_STATE_PATTERN_COLOR0 24:24 /* RWIVF */
1606#define NV_PGRAPH_STATE_PATTERN_COLOR0_INVALID 0x00000000 /* RWI-V */
1607#define NV_PGRAPH_STATE_PATTERN_COLOR0_VALID 0x00000001 /* RW--V */
1608#define NV_PGRAPH_STATE_PATTERN_COLOR1 25:25 /* RWIVF */
1609#define NV_PGRAPH_STATE_PATTERN_COLOR1_INVALID 0x00000000 /* RWI-V */
1610#define NV_PGRAPH_STATE_PATTERN_COLOR1_VALID 0x00000001 /* RW--V */
1611#define NV_PGRAPH_STATE_PATTERN_PATT0 26:26 /* RWIVF */
1612#define NV_PGRAPH_STATE_PATTERN_PATT0_INVALID 0x00000000 /* RWI-V */
1613#define NV_PGRAPH_STATE_PATTERN_PATT0_VALID 0x00000001 /* RW--V */
1614#define NV_PGRAPH_STATE_PATTERN_PATT1 27:27 /* RWIVF */
1615#define NV_PGRAPH_STATE_PATTERN_PATT1_INVALID 0x00000000 /* RWI-V */
1616#define NV_PGRAPH_STATE_PATTERN_PATT1_VALID 0x00000001 /* RW--V */
1617#define NV_PGRAPH_CACHE_INDEX 0x00400728 /* RW-4R */
1618#define NV_PGRAPH_CACHE_INDEX_BANK 2:2 /* RWXVF */
1619#define NV_PGRAPH_CACHE_INDEX_BANK_10 0x00000000 /* RW--V */
1620#define NV_PGRAPH_CACHE_INDEX_BANK_32 0x00000001 /* RW--V */
1621#define NV_PGRAPH_CACHE_INDEX_ADRS 12:3 /* RWXVF */
1622#define NV_PGRAPH_CACHE_INDEX_ADRS_0 0x00000000 /* RW--V */
1623#define NV_PGRAPH_CACHE_INDEX_ADRS_1024 0x00000400 /* RW--V */
1624#define NV_PGRAPH_CACHE_INDEX_OP 14:13 /* RWXVF */
1625#define NV_PGRAPH_CACHE_INDEX_OP_WR_CACHE 0x00000000 /* RW--V */
1626#define NV_PGRAPH_CACHE_INDEX_OP_RD_CACHE 0x00000001 /* RW--V */
1627#define NV_PGRAPH_CACHE_INDEX_OP_RD_INDEX 0x00000002 /* RW--V */
1628#define NV_PGRAPH_CACHE_RAM 0x0040072c /* RW-4R */
1629#define NV_PGRAPH_CACHE_RAM_VALUE 31:0 /* RWXVF */
1630#define NV_PGRAPH_DMA_PITCH 0x00400760 /* RW-4R */
1631#define NV_PGRAPH_DMA_PITCH_S0 15:0 /* RWXSF */
1632#define NV_PGRAPH_DMA_PITCH_S1 31:16 /* RWXSF */
1633#define NV_PGRAPH_DVD_COLORFMT 0x00400764 /* RW-4R */
1634#define NV_PGRAPH_DVD_COLORFMT_IMAGE 5:0 /* RWNVF */
1635#define NV_PGRAPH_DVD_COLORFMT_IMAGE_FORMAT_INVALID 0x00 /* RWN-V */
1636#define NV_PGRAPH_DVD_COLORFMT_IMAGE_FORMAT_LE_V8YB8U8YA8 0x12 /* RW--V */
1637#define NV_PGRAPH_DVD_COLORFMT_IMAGE_FORMAT_LE_YB8V8YA8U8 0x13 /* RW--V */
1638#define NV_PGRAPH_DVD_COLORFMT_OVLY 9:8 /* RWNVF */
1639#define NV_PGRAPH_DVD_COLORFMT_OVLY_FORMAT_INVALID 0x00 /* RWN-V */
1640#define NV_PGRAPH_DVD_COLORFMT_OVLY_FORMAT_LE_A8Y8U8V8 0x01 /* RW--V */
1641#define NV_PGRAPH_DVD_COLORFMT_OVLY_FORMAT_LE_A4V6YB6A4U6YA6 0x02 /* RW--V */
1642#define NV_PGRAPH_DVD_COLORFMT_OVLY_FORMAT_TRANSPARENT 0x03 /* RW--V */
1643#define NV_PGRAPH_SCALED_FORMAT 0x00400768 /* RW-4R */
1644#define NV_PGRAPH_SCALED_FORMAT_ORIGIN 17:16 /* RWIVF */
1645#define NV_PGRAPH_SCALED_FORMAT_ORIGIN_INVALID 0x00000000 /* RWI-V */
1646#define NV_PGRAPH_SCALED_FORMAT_ORIGIN_CENTER 0x00000001 /* RW--V */
1647#define NV_PGRAPH_SCALED_FORMAT_ORIGIN_CORNER 0x00000002 /* RW--V */
1648#define NV_PGRAPH_SCALED_FORMAT_INTERPOLATOR 24:24 /* RWIVF */
1649#define NV_PGRAPH_SCALED_FORMAT_INTERPOLATOR_ZOH 0x00000000 /* RWI-V */
1650#define NV_PGRAPH_SCALED_FORMAT_INTERPOLATOR_FOH 0x00000001 /* RW--V */
1651#define NV_PGRAPH_PATT_COLOR0 0x00400800 /* RW-4R */
1652#define NV_PGRAPH_PATT_COLOR0_VALUE 31:0 /* RWXUF */
1653#define NV_PGRAPH_PATT_COLOR1 0x00400804 /* RW-4R */
1654#define NV_PGRAPH_PATT_COLOR1_VALUE 31:0 /* RWXUF */
1655#define NV_PGRAPH_PATT_COLORRAM(i) (0x00400900+(i)*4) /* R--4A */
1656#define NV_PGRAPH_PATT_COLORRAM__SIZE_1 64 /* */
1657#define NV_PGRAPH_PATT_COLORRAM_VALUE 23:0 /* R--UF */
1658#define NV_PGRAPH_PATTERN(i) (0x00400808+(i)*4) /* RW-4A */
1659#define NV_PGRAPH_PATTERN__SIZE_1 2 /* */
1660#define NV_PGRAPH_PATTERN_BITMAP 31:0 /* RWXVF */
1661#define NV_PGRAPH_PATTERN_SHAPE 0x00400810 /* RW-4R */
1662#define NV_PGRAPH_PATTERN_SHAPE_VALUE 1:0 /* RWXVF */
1663#define NV_PGRAPH_PATTERN_SHAPE_VALUE_8X_8Y 0x00000000 /* RW--V */
1664#define NV_PGRAPH_PATTERN_SHAPE_VALUE_64X_1Y 0x00000001 /* RW--V */
1665#define NV_PGRAPH_PATTERN_SHAPE_VALUE_1X_64Y 0x00000002 /* RW--V */
1666#define NV_PGRAPH_PATTERN_SHAPE_SELECT 4:4 /* RWXVF */
1667#define NV_PGRAPH_PATTERN_SHAPE_SELECT_2COLOR 0x00000000 /* RW--V */
1668#define NV_PGRAPH_PATTERN_SHAPE_SELECT_FULLCOLOR 0x00000001 /* RW--V */
1669#define NV_PGRAPH_MONO_COLOR0 0x00400600 /* RW-4R */
1670#define NV_PGRAPH_MONO_COLOR0_VALUE 31:0 /* RWXUF */
1671#define NV_PGRAPH_ROP3 0x00400604 /* RW-4R */
1672#define NV_PGRAPH_ROP3_VALUE 7:0 /* RWXVF */
1673#define NV_PGRAPH_CHROMA 0x00400814 /* RW-4R */
1674#define NV_PGRAPH_CHROMA_VALUE 31:0 /* RWXUF */
1675#define NV_PGRAPH_BETA_AND 0x00400608 /* RW-4R */
1676#define NV_PGRAPH_BETA_AND_VALUE_FRACTION 30:23 /* RWXUF */
1677#define NV_PGRAPH_BETA_PREMULT 0x0040060c /* RW-4R */
1678#define NV_PGRAPH_BETA_PREMULT_VALUE 31:0 /* RWXUF */
1679#define NV_PGRAPH_CONTROL0 0x00400818 /* RW-4R */
1680#define NV_PGRAPH_CONTROL1 0x0040081c /* RW-4R */
1681#define NV_PGRAPH_CONTROL2 0x00400820 /* RW-4R */
1682#define NV_PGRAPH_BLEND 0x00400824 /* RW-4R */
1683#define NV_PGRAPH_DPRAM_INDEX 0x00400828 /* RW-4R */
1684#define NV_PGRAPH_DPRAM_INDEX_ADRS 6:0 /* RWIVF */
1685#define NV_PGRAPH_DPRAM_INDEX_ADRS_0 0x00000000 /* RWI-V */
1686#define NV_PGRAPH_DPRAM_INDEX_SELECT 10:8 /* RWIVF */
1687#define NV_PGRAPH_DPRAM_INDEX_SELECT_ADRS_0 0x00000000 /* RWI-V */
1688#define NV_PGRAPH_DPRAM_INDEX_SELECT_ADRS_1 0x00000001 /* RW--V */
1689#define NV_PGRAPH_DPRAM_INDEX_SELECT_DATA_0 0x00000002 /* RW--V */
1690#define NV_PGRAPH_DPRAM_INDEX_SELECT_DATA_1 0x00000003 /* RW--V */
1691#define NV_PGRAPH_DPRAM_INDEX_SELECT_WE_0 0x00000004 /* RW--V */
1692#define NV_PGRAPH_DPRAM_INDEX_SELECT_WE_1 0x00000005 /* RW--V */
1693#define NV_PGRAPH_DPRAM_INDEX_SELECT_ALPHA_0 0x00000006 /* RW--V */
1694#define NV_PGRAPH_DPRAM_INDEX_SELECT_ALPHA_1 0x00000007 /* RW--V */
1695#define NV_PGRAPH_DPRAM_DATA 0x0040082c /* RW-4R */
1696#define NV_PGRAPH_DPRAM_DATA_VALUE 31:0 /* RWXVF */
1697#define NV_PGRAPH_DPRAM_ADRS_0 0x0040082c /* RW-4R */
1698#define NV_PGRAPH_DPRAM_ADRS_0__ALIAS_1 NV_PGRAPH_DPRAM_DATA /* */
1699#define NV_PGRAPH_DPRAM_ADRS_0_VALUE 19:0 /* RWXVF */
1700#define NV_PGRAPH_DPRAM_ADRS_1 0x0040082c /* RW-4R */
1701#define NV_PGRAPH_DPRAM_ADRS_1__ALIAS_1 NV_PGRAPH_DPRAM_DATA /* */
1702#define NV_PGRAPH_DPRAM_ADRS_1_VALUE 19:0 /* RWXVF */
1703#define NV_PGRAPH_DPRAM_DATA_0 0x0040082c /* RW-4R */
1704#define NV_PGRAPH_DPRAM_DATA_0__ALIAS_1 NV_PGRAPH_DPRAM_DATA /* */
1705#define NV_PGRAPH_DPRAM_DATA_0_VALUE 31:0 /* RWXVF */
1706#define NV_PGRAPH_DPRAM_DATA_1 0x0040082c /* RW-4R */
1707#define NV_PGRAPH_DPRAM_DATA_1__ALIAS_1 NV_PGRAPH_DPRAM_DATA /* */
1708#define NV_PGRAPH_DPRAM_DATA_1_VALUE 31:0 /* RWXVF */
1709#define NV_PGRAPH_DPRAM_WE_0 0x0040082c /* RW-4R */
1710#define NV_PGRAPH_DPRAM_WE_0__ALIAS_1 NV_PGRAPH_DPRAM_DATA /* */
1711#define NV_PGRAPH_DPRAM_WE_0_VALUE 23:0 /* RWXVF */
1712#define NV_PGRAPH_DPRAM_WE_1 0x0040082c /* RW-4R */
1713#define NV_PGRAPH_DPRAM_WE_1__ALIAS_1 NV_PGRAPH_DPRAM_DATA /* */
1714#define NV_PGRAPH_DPRAM_WE_1_VALUE 23:0 /* RWXVF */
1715#define NV_PGRAPH_DPRAM_ALPHA_0 0x0040082c /* RW-4R */
1716#define NV_PGRAPH_DPRAM_ALPHA_0__ALIAS_1 NV_PGRAPH_DPRAM_DATA /* */
1717#define NV_PGRAPH_DPRAM_ALPHA_0_VALUE 31:0 /* RWXVF */
1718#define NV_PGRAPH_DPRAM_ALPHA_1 0x0040082c /* RW-4R */
1719#define NV_PGRAPH_DPRAM_ALPHA_1__ALIAS_1 NV_PGRAPH_DPRAM_DATA /* */
1720#define NV_PGRAPH_DPRAM_ALPHA_1_VALUE 31:0 /* RWXVF */
1721#define NV_PGRAPH_STORED_FMT 0x00400830 /* RW-4R */
1722#define NV_PGRAPH_STORED_FMT_MONO0 5:0 /* RWXVF */
1723#define NV_PGRAPH_STORED_FMT_PATT0 13:8 /* RWXVF */
1724#define NV_PGRAPH_STORED_FMT_PATT1 21:16 /* RWXVF */
1725#define NV_PGRAPH_STORED_FMT_CHROMA 29:24 /* RWXVF */
1726#define NV_PGRAPH_FORMATS 0x00400618 /* RW-4R */
1727#define NV_PGRAPH_FORMATS_ROP 2:0 /* R-XVF */
1728#define NV_PGRAPH_FORMATS_ROP_Y8 0x00000000 /* -W--V */
1729#define NV_PGRAPH_FORMATS_ROP_RGB15 0x00000001 /* -W--V */
1730#define NV_PGRAPH_FORMATS_ROP_RGB16 0x00000002 /* -W--V */
1731#define NV_PGRAPH_FORMATS_ROP_Y16 0x00000003 /* -W--V */
1732#define NV_PGRAPH_FORMATS_ROP_INVALID 0x00000004 /* -W--V */
1733#define NV_PGRAPH_FORMATS_ROP_RGB24 0x00000005 /* -W--V */
1734#define NV_PGRAPH_FORMATS_ROP_RGB30 0x00000006 /* -W--V */
1735#define NV_PGRAPH_FORMATS_ROP_Y32 0x00000007 /* -W--V */
1736#define NV_PGRAPH_FORMATS_SRC 9:4 /* R-XVF */
1737#define NV_PGRAPH_FORMATS_SRC_INVALID 0x00000000 /* RW--V */
1738#define NV_PGRAPH_FORMATS_SRC_LE_Y8 0x00000001 /* RW--V */
1739#define NV_PGRAPH_FORMATS_SRC_LE_X16A8Y8 0x00000002 /* RW--V */
1740#define NV_PGRAPH_FORMATS_SRC_LE_X24Y8 0x00000003 /* RW--V */
1741#define NV_PGRAPH_FORMATS_SRC_LE_A1R5G5B5 0x00000006 /* RW--V */
1742#define NV_PGRAPH_FORMATS_SRC_LE_X1R5G5B5 0x00000007 /* RW--V */
1743#define NV_PGRAPH_FORMATS_SRC_LE_X16A1R5G5B5 0x00000008 /* RW--V */
1744#define NV_PGRAPH_FORMATS_SRC_LE_X17R5G5B5 0x00000009 /* RW--V */
1745#define NV_PGRAPH_FORMATS_SRC_LE_R5G6B5 0x0000000A /* RW--V */
1746#define NV_PGRAPH_FORMATS_SRC_LE_A16R5G6B5 0x0000000B /* RW--V */
1747#define NV_PGRAPH_FORMATS_SRC_LE_X16R5G6B5 0x0000000C /* RW--V */
1748#define NV_PGRAPH_FORMATS_SRC_LE_A8R8G8B8 0x0000000D /* RW--V */
1749#define NV_PGRAPH_FORMATS_SRC_LE_X8R8G8B8 0x0000000E /* RW--V */
1750#define NV_PGRAPH_FORMATS_SRC_LE_Y16 0x0000000F /* RW--V */
1751#define NV_PGRAPH_FORMATS_SRC_LE_A16Y16 0x00000010 /* RW--V */
1752#define NV_PGRAPH_FORMATS_SRC_LE_X16Y16 0x00000011 /* RW--V */
1753#define NV_PGRAPH_FORMATS_SRC_LE_V8YB8U8YA8 0x00000012 /* RW--V */
1754#define NV_PGRAPH_FORMATS_SRC_LE_YB8V8YA8U8 0x00000013 /* RW--V */
1755#define NV_PGRAPH_FORMATS_SRC_LE_Y32 0x00000014 /* RW--V */
1756#define NV_PGRAPH_FORMATS_FB 15:12 /* R-XVF */
1757#define NV_PGRAPH_FORMATS_FB_INVALID 0x00000000 /* RWI-V */
1758#define NV_PGRAPH_FORMATS_FB_Y8 0x00000001 /* RW--V */
1759#define NV_PGRAPH_FORMATS_FB_X1R5G5B5_Z1R5G5B5 0x00000002 /* RW--V */
1760#define NV_PGRAPH_FORMATS_FB_X1R5G5B5_O1R5G5B5 0x00000003 /* RW--V */
1761#define NV_PGRAPH_FORMATS_FB_A1R5G5B5 0x00000004 /* RW--V */
1762#define NV_PGRAPH_FORMATS_FB_R5G6B5 0x00000005 /* RW--V */
1763#define NV_PGRAPH_FORMATS_FB_Y16 0x00000006 /* RW--V */
1764#define NV_PGRAPH_FORMATS_FB_X8R8G8B8_Z8R8G8B8 0x00000007 /* RW--V */
1765#define NV_PGRAPH_FORMATS_FB_X8R8G8B8_O1Z7R8G8B8 0x00000008 /* RW--V */
1766#define NV_PGRAPH_FORMATS_FB_X1A7R8G8B8_Z1A7R8G8B8 0x00000009 /* RW--V */
1767#define NV_PGRAPH_FORMATS_FB_X1A7R8G8B8_O1A7R8G8B8 0x0000000a /* RW--V */
1768#define NV_PGRAPH_FORMATS_FB_X8R8G8B8_O8R8G8B8 0x0000000b /* RW--V */
1769#define NV_PGRAPH_FORMATS_FB_A8R8G8B8 0x0000000c /* RW--V */
1770#define NV_PGRAPH_FORMATS_FB_Y32 0x0000000d /* RW--V */
1771#define NV_PGRAPH_FORMATS_FB_V8YB8U8YA8 0x0000000e /* RW--V */
1772#define NV_PGRAPH_FORMATS_FB_YB8V8YA8U8 0x0000000f /* RW--V */
1773#define NV_PGRAPH_ABS_X_RAM(i) (0x00400400+(i)*4) /* RW-4A */
1774#define NV_PGRAPH_ABS_X_RAM__SIZE_1 32 /* */
1775#define NV_PGRAPH_ABS_X_RAM_VALUE 31:0 /* RWXUF */
1776#define NV_PGRAPH_X_RAM_BPORT(i) (0x00400c00+(i)*4) /* R--4A */
1777#define NV_PGRAPH_X_RAM_BPORT__SIZE_1 32 /* */
1778#define NV_PGRAPH_X_RAM_BPORT_VALUE 31:0 /* R--UF */
1779#define NV_PGRAPH_ABS_Y_RAM(i) (0x00400480+(i)*4) /* RW-4A */
1780#define NV_PGRAPH_ABS_Y_RAM__SIZE_1 32 /* */
1781#define NV_PGRAPH_ABS_Y_RAM_VALUE 31:0 /* RWXUF */
1782#define NV_PGRAPH_Y_RAM_BPORT(i) (0x00400c80+(i)*4) /* R--4A */
1783#define NV_PGRAPH_Y_RAM_BPORT__SIZE_1 32 /* */
1784#define NV_PGRAPH_Y_RAM_BPORT_VALUE 31:0 /* R--UF */
1785#define NV_PGRAPH_XY_LOGIC_MISC0 0x00400514 /* RW-4R */
1786#define NV_PGRAPH_XY_LOGIC_MISC0_COUNTER 17:0 /* RWBUF */
1787#define NV_PGRAPH_XY_LOGIC_MISC0_COUNTER_0 0x00000000 /* RWB-V */
1788#define NV_PGRAPH_XY_LOGIC_MISC0_DIMENSION 20:20 /* RWVVF */
1789#define NV_PGRAPH_XY_LOGIC_MISC0_DIMENSION_NONZERO 0x00000000 /* RWV-V */
1790#define NV_PGRAPH_XY_LOGIC_MISC0_DIMENSION_ZERO 0x00000001 /* RW--V */
1791#define NV_PGRAPH_XY_LOGIC_MISC0_INDEX 31:28 /* RWBUF */
1792#define NV_PGRAPH_XY_LOGIC_MISC0_INDEX_0 0x00000000 /* RWB-V */
1793#define NV_PGRAPH_XY_LOGIC_MISC1 0x00400518 /* RW-4R */
1794#define NV_PGRAPH_XY_LOGIC_MISC1_INITIAL 0:0 /* RWNVF */
1795#define NV_PGRAPH_XY_LOGIC_MISC1_INITIAL_NEEDED 0x00000000 /* RWN-V */
1796#define NV_PGRAPH_XY_LOGIC_MISC1_INITIAL_DONE 0x00000001 /* RW--V */
1797#define NV_PGRAPH_XY_LOGIC_MISC1_XTRACLIPX 4:4 /* RWIVF */
1798#define NV_PGRAPH_XY_LOGIC_MISC1_XTRACLIPX_NOTNULL 0x00000000 /* RWI-V */
1799#define NV_PGRAPH_XY_LOGIC_MISC1_XTRACLIPX_NULL 0x00000001 /* RW--V */
1800#define NV_PGRAPH_XY_LOGIC_MISC1_XTRACLIPY 5:5 /* RWIVF */
1801#define NV_PGRAPH_XY_LOGIC_MISC1_XTRACLIPY_NOTNULL 0x00000000 /* RWI-V */
1802#define NV_PGRAPH_XY_LOGIC_MISC1_XTRACLIPY_NULL 0x00000001 /* RW--V */
1803#define NV_PGRAPH_XY_LOGIC_MISC1_SEL_XIMAX 12:12 /* RWIVF */
1804#define NV_PGRAPH_XY_LOGIC_MISC1_SEL_XIMAX_UUMAX 0x00000000 /* RWI-V */
1805#define NV_PGRAPH_XY_LOGIC_MISC1_SEL_XIMAX_IMAGEMAX 0x00000001 /* RW--V */
1806#define NV_PGRAPH_XY_LOGIC_MISC1_SEL_YIMAX 16:16 /* RWIVF */
1807#define NV_PGRAPH_XY_LOGIC_MISC1_SEL_YIMAX_UUMAX 0x00000000 /* RWI-V */
1808#define NV_PGRAPH_XY_LOGIC_MISC1_SEL_YIMAX_IMAGEMAX 0x00000001 /* RW--V */
1809#define NV_PGRAPH_XY_LOGIC_MISC1_SEL_XXTRA 20:20 /* RWIVF */
1810#define NV_PGRAPH_XY_LOGIC_MISC1_SEL_XXTRA_CLIPMAX 0x00000000 /* RWI-V */
1811#define NV_PGRAPH_XY_LOGIC_MISC1_SEL_XXTRA_IMAGEMAX 0x00000001 /* RW--V */
1812#define NV_PGRAPH_XY_LOGIC_MISC2 0x0040051C /* RW-4R */
1813#define NV_PGRAPH_XY_LOGIC_MISC2_HANDOFF 0:0 /* RWIVF */
1814#define NV_PGRAPH_XY_LOGIC_MISC2_HANDOFF_DISABLE 0x00000000 /* RWI-V */
1815#define NV_PGRAPH_XY_LOGIC_MISC2_HANDOFF_ENABLE 0x00000001 /* RW--V */
1816#define NV_PGRAPH_XY_LOGIC_MISC2_XTRACLIPX 4:4 /* RWIVF */
1817#define NV_PGRAPH_XY_LOGIC_MISC2_XTRACLIPX_NOTNULL 0x00000000 /* RWI-V */
1818#define NV_PGRAPH_XY_LOGIC_MISC2_XTRACLIPX_NULL 0x00000001 /* RW--V */
1819#define NV_PGRAPH_XY_LOGIC_MISC2_XTRACLIPY 5:5 /* RWIVF */
1820#define NV_PGRAPH_XY_LOGIC_MISC2_XTRACLIPY_NOTNULL 0x00000000 /* RWI-V */
1821#define NV_PGRAPH_XY_LOGIC_MISC2_XTRACLIPY_NULL 0x00000001 /* RW--V */
1822#define NV_PGRAPH_XY_LOGIC_MISC2_SEL_XIMAX 12:12 /* RWIVF */
1823#define NV_PGRAPH_XY_LOGIC_MISC2_SEL_XIMAX_UCMAX 0x00000000 /* RWI-V */
1824#define NV_PGRAPH_XY_LOGIC_MISC2_SEL_XIMAX_IMAGEMAX 0x00000001 /* RW--V */
1825#define NV_PGRAPH_XY_LOGIC_MISC2_SEL_YIMAX 16:16 /* RWIVF */
1826#define NV_PGRAPH_XY_LOGIC_MISC2_SEL_YIMAX_UCMAX 0x00000000 /* RWI-V */
1827#define NV_PGRAPH_XY_LOGIC_MISC2_SEL_YIMAX_IMAGEMAX 0x00000001 /* RW--V */
1828#define NV_PGRAPH_XY_LOGIC_MISC2_SEL_XXTRA 20:20 /* RWIVF */
1829#define NV_PGRAPH_XY_LOGIC_MISC2_SEL_XXTRA_CLIPMAX 0x00000000 /* RWI-V */
1830#define NV_PGRAPH_XY_LOGIC_MISC2_SEL_XXTRA_IMAGEMAX 0x00000001 /* RW--V */
1831#define NV_PGRAPH_XY_LOGIC_MISC3 0x00400520 /* RW-4R */
1832#define NV_PGRAPH_XY_LOGIC_MISC3_WDIMY_EQ_0 0:0 /* RWXVF */
1833#define NV_PGRAPH_XY_LOGIC_MISC3_WDIMY_EQ_0_NULL 0x00000000 /* RW--V */
1834#define NV_PGRAPH_XY_LOGIC_MISC3_WDIMY_EQ_0_TRUE 0x00000001 /* RW--V */
1835#define NV_PGRAPH_XY_LOGIC_MISC3_RELOAD_WDIMY 4:4 /* RWXVF */
1836#define NV_PGRAPH_XY_LOGIC_MISC3_RELOAD_WDIMY_NULL 0x00000000 /* RW--V */
1837#define NV_PGRAPH_XY_LOGIC_MISC3_RELOAD_WDIMY_TRUE 0x00000001 /* RW--V */
1838#define NV_PGRAPH_XY_LOGIC_MISC3_RELOAD_WX 8:8 /* RWIVF */
1839#define NV_PGRAPH_XY_LOGIC_MISC3_RELOAD_WX_NULL 0x00000000 /* RWI-V */
1840#define NV_PGRAPH_XY_LOGIC_MISC3_RELOAD_WX_TRUE 0x00000001 /* RW--V */
1841#define NV_PGRAPH_XY_LOGIC_MISC3_TEXT_ALG 12:12 /* RWIVF */
1842#define NV_PGRAPH_XY_LOGIC_MISC3_TEXT_ALG_NULL 0x00000000 /* RWI-V */
1843#define NV_PGRAPH_XY_LOGIC_MISC3_TEXT_ALG_TRUE 0x00000001 /* RW--V */
1844#define NV_PGRAPH_XY_LOGIC_MISC3_TEXT_DIMX 22:16 /* RWXUF */
1845#define NV_PGRAPH_XY_LOGIC_MISC3_TEXT_DIMX_0 0x00000000 /* RW--V */
1846#define NV_PGRAPH_XY_LOGIC_MISC3_TEXT_WDIMX 30:24 /* RWXUF */
1847#define NV_PGRAPH_XY_LOGIC_MISC3_TEXT_WDIMX_0 0x00000000 /* RW--V */
1848#define NV_PGRAPH_X_MISC 0x00400500 /* RW-4R */
1849#define NV_PGRAPH_X_MISC_BIT33_0 0:0 /* RWNVF */
1850#define NV_PGRAPH_X_MISC_BIT33_0_0 0x00000000 /* RWN-V */
1851#define NV_PGRAPH_X_MISC_BIT33_1 1:1 /* RWNVF */
1852#define NV_PGRAPH_X_MISC_BIT33_1_0 0x00000000 /* RWN-V */
1853#define NV_PGRAPH_X_MISC_BIT33_2 2:2 /* RWNVF */
1854#define NV_PGRAPH_X_MISC_BIT33_2_0 0x00000000 /* RWN-V */
1855#define NV_PGRAPH_X_MISC_BIT33_3 3:3 /* RWNVF */
1856#define NV_PGRAPH_X_MISC_BIT33_3_0 0x00000000 /* RWN-V */
1857#define NV_PGRAPH_X_MISC_RANGE_0 4:4 /* RWNVF */
1858#define NV_PGRAPH_X_MISC_RANGE_0_0 0x00000000 /* RWN-V */
1859#define NV_PGRAPH_X_MISC_RANGE_1 5:5 /* RWNVF */
1860#define NV_PGRAPH_X_MISC_RANGE_1_0 0x00000000 /* RWN-V */
1861#define NV_PGRAPH_X_MISC_RANGE_2 6:6 /* RWNVF */
1862#define NV_PGRAPH_X_MISC_RANGE_2_0 0x00000000 /* RWN-V */
1863#define NV_PGRAPH_X_MISC_RANGE_3 7:7 /* RWNVF */
1864#define NV_PGRAPH_X_MISC_RANGE_3_0 0x00000000 /* RWN-V */
1865#define NV_PGRAPH_X_MISC_ADDER_OUTPUT 29:28 /* RWXVF */
1866#define NV_PGRAPH_X_MISC_ADDER_OUTPUT_EQ_0 0x00000000 /* RW--V */
1867#define NV_PGRAPH_X_MISC_ADDER_OUTPUT_LT_0 0x00000001 /* RW--V */
1868#define NV_PGRAPH_X_MISC_ADDER_OUTPUT_GT_0 0x00000002 /* RW--V */
1869#define NV_PGRAPH_Y_MISC 0x00400504 /* RW-4R */
1870#define NV_PGRAPH_Y_MISC_BIT33_0 0:0 /* RWNVF */
1871#define NV_PGRAPH_Y_MISC_BIT33_0_0 0x00000000 /* RWN-V */
1872#define NV_PGRAPH_Y_MISC_BIT33_1 1:1 /* RWNVF */
1873#define NV_PGRAPH_Y_MISC_BIT33_1_0 0x00000000 /* RWN-V */
1874#define NV_PGRAPH_Y_MISC_BIT33_2 2:2 /* RWNVF */
1875#define NV_PGRAPH_Y_MISC_BIT33_2_0 0x00000000 /* RWN-V */
1876#define NV_PGRAPH_Y_MISC_BIT33_3 3:3 /* RWNVF */
1877#define NV_PGRAPH_Y_MISC_BIT33_3_0 0x00000000 /* RWN-V */
1878#define NV_PGRAPH_Y_MISC_RANGE_0 4:4 /* RWNVF */
1879#define NV_PGRAPH_Y_MISC_RANGE_0_0 0x00000000 /* RWN-V */
1880#define NV_PGRAPH_Y_MISC_RANGE_1 5:5 /* RWNVF */
1881#define NV_PGRAPH_Y_MISC_RANGE_1_0 0x00000000 /* RWN-V */
1882#define NV_PGRAPH_Y_MISC_RANGE_2 6:6 /* RWNVF */
1883#define NV_PGRAPH_Y_MISC_RANGE_2_0 0x00000000 /* RWN-V */
1884#define NV_PGRAPH_Y_MISC_RANGE_3 7:7 /* RWNVF */
1885#define NV_PGRAPH_Y_MISC_RANGE_3_0 0x00000000 /* RWN-V */
1886#define NV_PGRAPH_Y_MISC_ADDER_OUTPUT 29:28 /* RWXVF */
1887#define NV_PGRAPH_Y_MISC_ADDER_OUTPUT_EQ_0 0x00000000 /* RW--V */
1888#define NV_PGRAPH_Y_MISC_ADDER_OUTPUT_LT_0 0x00000001 /* RW--V */
1889#define NV_PGRAPH_Y_MISC_ADDER_OUTPUT_GT_0 0x00000002 /* RW--V */
1890#define NV_PGRAPH_ABS_UCLIP_XMIN 0x0040053C /* RW-4R */
1891#define NV_PGRAPH_ABS_UCLIP_XMIN_VALUE 15:0 /* RWXSF */
1892#define NV_PGRAPH_ABS_UCLIP_XMAX 0x00400544 /* RW-4R */
1893#define NV_PGRAPH_ABS_UCLIP_XMAX_VALUE 17:0 /* RWXSF */
1894#define NV_PGRAPH_ABS_UCLIP_YMIN 0x00400540 /* RW-4R */
1895#define NV_PGRAPH_ABS_UCLIP_YMIN_VALUE 15:0 /* RWXSF */
1896#define NV_PGRAPH_ABS_UCLIP_YMAX 0x00400548 /* RW-4R */
1897#define NV_PGRAPH_ABS_UCLIP_YMAX_VALUE 17:0 /* RWXSF */
1898#define NV_PGRAPH_ABS_UCLIPA_XMIN 0x00400560 /* RW-4R */
1899#define NV_PGRAPH_ABS_UCLIPA_XMIN_VALUE 15:0 /* RWXSF */
1900#define NV_PGRAPH_ABS_UCLIPA_XMAX 0x00400568 /* RW-4R */
1901#define NV_PGRAPH_ABS_UCLIPA_XMAX_VALUE 17:0 /* RWXSF */
1902#define NV_PGRAPH_ABS_UCLIPA_YMIN 0x00400564 /* RW-4R */
1903#define NV_PGRAPH_ABS_UCLIPA_YMIN_VALUE 15:0 /* RWXSF */
1904#define NV_PGRAPH_ABS_UCLIPA_YMAX 0x0040056C /* RW-4R */
1905#define NV_PGRAPH_ABS_UCLIPA_YMAX_VALUE 17:0 /* RWXSF */
1906#define NV_PGRAPH_SOURCE_COLOR 0x0040050C /* RW-4R */
1907#define NV_PGRAPH_SOURCE_COLOR_VALUE 31:0 /* RWNVF */
1908#define NV_PGRAPH_SOURCE_COLOR_VALUE_0 0x00000000 /* RWN-V */
1909#define NV_PGRAPH_VALID1 0x00400508 /* RW-4R */
1910#define NV_PGRAPH_VALID1_VLD 22:0 /* RWNVF */
1911#define NV_PGRAPH_VALID1_VLD_0 0x00000000 /* RWN-V */
1912#define NV_PGRAPH_VALID1_CLIP_MIN 28:28 /* RWIVF */
1913#define NV_PGRAPH_VALID1_CLIP_MIN_NO_ERROR 0x00000000 /* RWI-V */
1914#define NV_PGRAPH_VALID1_CLIP_MIN_ONLY 0x00000001 /* RW--V */
1915#define NV_PGRAPH_VALID1_CLIPA_MIN 29:29 /* RWIVF */
1916#define NV_PGRAPH_VALID1_CLIPA_MIN_NO_ERROR 0x00000000 /* RWI-V */
1917#define NV_PGRAPH_VALID1_CLIPA_MIN_ONLY 0x00000001 /* RW--V */
1918#define NV_PGRAPH_VALID1_CLIP_MAX 30:30 /* RWIVF */
1919#define NV_PGRAPH_VALID1_CLIP_MAX_NO_ERROR 0x00000000 /* RWI-V */
1920#define NV_PGRAPH_VALID1_CLIP_MAX_ONLY 0x00000001 /* RW--V */
1921#define NV_PGRAPH_VALID1_CLIPA_MAX 31:31 /* RWIVF */
1922#define NV_PGRAPH_VALID1_CLIPA_MAX_NO_ERROR 0x00000000 /* RWI-V */
1923#define NV_PGRAPH_VALID1_CLIPA_MAX_ONLY 0x00000001 /* RW--V */
1924#define NV_PGRAPH_VALID2 0x00400578 /* RW-4R */
1925#define NV_PGRAPH_VALID2_VLD2 28:0 /* RWNVF */
1926#define NV_PGRAPH_VALID2_VLD2_0 0x00000000 /* RWN-V */
1927#define NV_PGRAPH_ABS_ICLIP_XMAX 0x00400534 /* RW-4R */
1928#define NV_PGRAPH_ABS_ICLIP_XMAX_VALUE 17:0 /* RWXSF */
1929#define NV_PGRAPH_ABS_ICLIP_YMAX 0x00400538 /* RW-4R */
1930#define NV_PGRAPH_ABS_ICLIP_YMAX_VALUE 17:0 /* RWXSF */
1931#define NV_PGRAPH_CLIPX_0 0x00400524 /* RW-4R */
1932#define NV_PGRAPH_CLIPX_0_CLIP0_MIN 1:0 /* RWNVF */
1933#define NV_PGRAPH_CLIPX_0_CLIP0_MIN_GT 0x00000000 /* RW--V */
1934#define NV_PGRAPH_CLIPX_0_CLIP0_MIN_LT 0x00000001 /* RWN-V */
1935#define NV_PGRAPH_CLIPX_0_CLIP0_MIN_EQ 0x00000002 /* RW--V */
1936#define NV_PGRAPH_CLIPX_0_CLIP0_MAX 3:2 /* RWNVF */
1937#define NV_PGRAPH_CLIPX_0_CLIP0_MAX_LT 0x00000000 /* RW--V */
1938#define NV_PGRAPH_CLIPX_0_CLIP0_MAX_GT 0x00000001 /* RWN-V */
1939#define NV_PGRAPH_CLIPX_0_CLIP0_MAX_EQ 0x00000002 /* RW--V */
1940#define NV_PGRAPH_CLIPX_0_CLIP1_MIN 5:4 /* RWNVF */
1941#define NV_PGRAPH_CLIPX_0_CLIP1_MIN_GT 0x00000000 /* RW--V */
1942#define NV_PGRAPH_CLIPX_0_CLIP1_MIN_LT 0x00000001 /* RWN-V */
1943#define NV_PGRAPH_CLIPX_0_CLIP1_MIN_EQ 0x00000002 /* RW--V */
1944#define NV_PGRAPH_CLIPX_0_CLIP1_MAX 7:6 /* RWNVF */
1945#define NV_PGRAPH_CLIPX_0_CLIP1_MAX_LT 0x00000000 /* RW--V */
1946#define NV_PGRAPH_CLIPX_0_CLIP1_MAX_GT 0x00000001 /* RWN-V */
1947#define NV_PGRAPH_CLIPX_0_CLIP1_MAX_EQ 0x00000002 /* RW--V */
1948#define NV_PGRAPH_CLIPX_0_CLIP2_MIN 9:8 /* RWNVF */
1949#define NV_PGRAPH_CLIPX_0_CLIP2_MIN_GT 0x00000000 /* RW--V */
1950#define NV_PGRAPH_CLIPX_0_CLIP2_MIN_LT 0x00000001 /* RWN-V */
1951#define NV_PGRAPH_CLIPX_0_CLIP2_MIN_EQ 0x00000002 /* RW--V */
1952#define NV_PGRAPH_CLIPX_0_CLIP2_MAX 11:10 /* RWNVF */
1953#define NV_PGRAPH_CLIPX_0_CLIP2_MAX_LT 0x00000000 /* RW--V */
1954#define NV_PGRAPH_CLIPX_0_CLIP2_MAX_GT 0x00000001 /* RWN-V */
1955#define NV_PGRAPH_CLIPX_0_CLIP2_MAX_EQ 0x00000002 /* RW--V */
1956#define NV_PGRAPH_CLIPX_0_CLIP3_MIN 13:12 /* RWNVF */
1957#define NV_PGRAPH_CLIPX_0_CLIP3_MIN_GT 0x00000000 /* RW--V */
1958#define NV_PGRAPH_CLIPX_0_CLIP3_MIN_LT 0x00000001 /* RWN-V */
1959#define NV_PGRAPH_CLIPX_0_CLIP3_MIN_EQ 0x00000002 /* RW--V */
1960#define NV_PGRAPH_CLIPX_0_CLIP3_MAX 15:14 /* RWNVF */
1961#define NV_PGRAPH_CLIPX_0_CLIP3_MAX_LT 0x00000000 /* RW--V */
1962#define NV_PGRAPH_CLIPX_0_CLIP3_MAX_GT 0x00000001 /* RWN-V */
1963#define NV_PGRAPH_CLIPX_0_CLIP3_MAX_EQ 0x00000002 /* RW--V */
1964#define NV_PGRAPH_CLIPX_0_CLIP4_MIN 17:16 /* RWNVF */
1965#define NV_PGRAPH_CLIPX_0_CLIP4_MIN_GT 0x00000000 /* RW--V */
1966#define NV_PGRAPH_CLIPX_0_CLIP4_MIN_LT 0x00000001 /* RWN-V */
1967#define NV_PGRAPH_CLIPX_0_CLIP4_MIN_EQ 0x00000002 /* RW--V */
1968#define NV_PGRAPH_CLIPX_0_CLIP4_MAX 19:18 /* RWNVF */
1969#define NV_PGRAPH_CLIPX_0_CLIP4_MAX_LT 0x00000000 /* RW--V */
1970#define NV_PGRAPH_CLIPX_0_CLIP4_MAX_GT 0x00000001 /* RWN-V */
1971#define NV_PGRAPH_CLIPX_0_CLIP4_MAX_EQ 0x00000002 /* RW--V */
1972#define NV_PGRAPH_CLIPX_0_CLIP5_MIN 21:20 /* RWNVF */
1973#define NV_PGRAPH_CLIPX_0_CLIP5_MIN_GT 0x00000000 /* RW--V */
1974#define NV_PGRAPH_CLIPX_0_CLIP5_MIN_LT 0x00000001 /* RWN-V */
1975#define NV_PGRAPH_CLIPX_0_CLIP5_MIN_EQ 0x00000002 /* RW--V */
1976#define NV_PGRAPH_CLIPX_0_CLIP5_MAX 23:22 /* RWNVF */
1977#define NV_PGRAPH_CLIPX_0_CLIP5_MAX_LT 0x00000000 /* RW--V */
1978#define NV_PGRAPH_CLIPX_0_CLIP5_MAX_GT 0x00000001 /* RWN-V */
1979#define NV_PGRAPH_CLIPX_0_CLIP5_MAX_EQ 0x00000002 /* RW--V */
1980#define NV_PGRAPH_CLIPX_0_CLIP6_MIN 25:24 /* RWNVF */
1981#define NV_PGRAPH_CLIPX_0_CLIP6_MIN_GT 0x00000000 /* RW--V */
1982#define NV_PGRAPH_CLIPX_0_CLIP6_MIN_LT 0x00000001 /* RWN-V */
1983#define NV_PGRAPH_CLIPX_0_CLIP6_MIN_EQ 0x00000002 /* RW--V */
1984#define NV_PGRAPH_CLIPX_0_CLIP6_MAX 27:26 /* RWNVF */
1985#define NV_PGRAPH_CLIPX_0_CLIP6_MAX_LT 0x00000000 /* RW--V */
1986#define NV_PGRAPH_CLIPX_0_CLIP6_MAX_GT 0x00000001 /* RWN-V */
1987#define NV_PGRAPH_CLIPX_0_CLIP6_MAX_EQ 0x00000002 /* RW--V */
1988#define NV_PGRAPH_CLIPX_0_CLIP7_MIN 29:28 /* RWNVF */
1989#define NV_PGRAPH_CLIPX_0_CLIP7_MIN_GT 0x00000000 /* RW--V */
1990#define NV_PGRAPH_CLIPX_0_CLIP7_MIN_LT 0x00000001 /* RWN-V */
1991#define NV_PGRAPH_CLIPX_0_CLIP7_MIN_EQ 0x00000002 /* RW--V */
1992#define NV_PGRAPH_CLIPX_0_CLIP7_MAX 31:30 /* RWNVF */
1993#define NV_PGRAPH_CLIPX_0_CLIP7_MAX_LT 0x00000000 /* RW--V */
1994#define NV_PGRAPH_CLIPX_0_CLIP7_MAX_GT 0x00000001 /* RWN-V */
1995#define NV_PGRAPH_CLIPX_0_CLIP7_MAX_EQ 0x00000002 /* RW--V */
1996#define NV_PGRAPH_CLIPX_1 0x00400528 /* RW-4R */
1997#define NV_PGRAPH_CLIPX_1_CLIP8_MIN 1:0 /* RWNVF */
1998#define NV_PGRAPH_CLIPX_1_CLIP8_MIN_GT 0x00000000 /* RW--V */
1999#define NV_PGRAPH_CLIPX_1_CLIP8_MIN_LT 0x00000001 /* RWN-V */
2000#define NV_PGRAPH_CLIPX_1_CLIP8_MIN_EQ 0x00000002 /* RW--V */
2001#define NV_PGRAPH_CLIPX_1_CLIP8_MAX 3:2 /* RWNVF */
2002#define NV_PGRAPH_CLIPX_1_CLIP8_MAX_LT 0x00000000 /* RW--V */
2003#define NV_PGRAPH_CLIPX_1_CLIP8_MAX_GT 0x00000001 /* RWN-V */
2004#define NV_PGRAPH_CLIPX_1_CLIP8_MAX_EQ 0x00000002 /* RW--V */
2005#define NV_PGRAPH_CLIPX_1_CLIP9_MIN 5:4 /* RWNVF */
2006#define NV_PGRAPH_CLIPX_1_CLIP9_MIN_GT 0x00000000 /* RW--V */
2007#define NV_PGRAPH_CLIPX_1_CLIP9_MIN_LT 0x00000001 /* RWN-V */
2008#define NV_PGRAPH_CLIPX_1_CLIP9_MIN_EQ 0x00000002 /* RW--V */
2009#define NV_PGRAPH_CLIPX_1_CLIP9_MAX 7:6 /* RWNVF */
2010#define NV_PGRAPH_CLIPX_1_CLIP9_MAX_LT 0x00000000 /* RW--V */
2011#define NV_PGRAPH_CLIPX_1_CLIP9_MAX_GT 0x00000001 /* RWN-V */
2012#define NV_PGRAPH_CLIPX_1_CLIP9_MAX_EQ 0x00000002 /* RW--V */
2013#define NV_PGRAPH_CLIPX_1_CLIP10_MIN 9:8 /* RWNVF */
2014#define NV_PGRAPH_CLIPX_1_CLIP10_MIN_GT 0x00000000 /* RW--V */
2015#define NV_PGRAPH_CLIPX_1_CLIP10_MIN_LT 0x00000001 /* RWN-V */
2016#define NV_PGRAPH_CLIPX_1_CLIP10_MIN_EQ 0x00000002 /* RW--V */
2017#define NV_PGRAPH_CLIPX_1_CLIP10_MAX 11:10 /* RWNVF */
2018#define NV_PGRAPH_CLIPX_1_CLIP10_MAX_LT 0x00000000 /* RW--V */
2019#define NV_PGRAPH_CLIPX_1_CLIP10_MAX_GT 0x00000001 /* RWN-V */
2020#define NV_PGRAPH_CLIPX_1_CLIP10_MAX_EQ 0x00000002 /* RW--V */
2021#define NV_PGRAPH_CLIPX_1_CLIP11_MIN 13:12 /* RWNVF */
2022#define NV_PGRAPH_CLIPX_1_CLIP11_MIN_GT 0x00000000 /* RW--V */
2023#define NV_PGRAPH_CLIPX_1_CLIP11_MIN_LT 0x00000001 /* RWN-V */
2024#define NV_PGRAPH_CLIPX_1_CLIP11MIN_EQ 0x00000002 /* RW--V */
2025#define NV_PGRAPH_CLIPX_1_CLIP11_MAX 15:14 /* RWNVF */
2026#define NV_PGRAPH_CLIPX_1_CLIP11_MAX_LT 0x00000000 /* RW--V */
2027#define NV_PGRAPH_CLIPX_1_CLIP11_MAX_GT 0x00000001 /* RWN-V */
2028#define NV_PGRAPH_CLIPX_1_CLIP11_MAX_EQ 0x00000002 /* RW--V */
2029#define NV_PGRAPH_CLIPX_1_CLIP12_MIN 17:16 /* RWNVF */
2030#define NV_PGRAPH_CLIPX_1_CLIP12_MIN_GT 0x00000000 /* RW--V */
2031#define NV_PGRAPH_CLIPX_1_CLIP12_MIN_LT 0x00000001 /* RWN-V */
2032#define NV_PGRAPH_CLIPX_1_CLIP12_MIN_EQ 0x00000002 /* RW--V */
2033#define NV_PGRAPH_CLIPX_1_CLIP12_MAX 19:18 /* RWNVF */
2034#define NV_PGRAPH_CLIPX_1_CLIP12_MAX_LT 0x00000000 /* RW--V */
2035#define NV_PGRAPH_CLIPX_1_CLIP12_MAX_GT 0x00000001 /* RWN-V */
2036#define NV_PGRAPH_CLIPX_1_CLIP12_MAX_EQ 0x00000002 /* RW--V */
2037#define NV_PGRAPH_CLIPX_1_CLIP13_MIN 21:20 /* RWNVF */
2038#define NV_PGRAPH_CLIPX_1_CLIP13_MIN_GT 0x00000000 /* RW--V */
2039#define NV_PGRAPH_CLIPX_1_CLIP13_MIN_LT 0x00000001 /* RWN-V */
2040#define NV_PGRAPH_CLIPX_1_CLIP13_MIN_EQ 0x00000002 /* RW--V */
2041#define NV_PGRAPH_CLIPX_1_CLIP13_MAX 23:22 /* RWNVF */
2042#define NV_PGRAPH_CLIPX_1_CLIP13_MAX_LT 0x00000000 /* RW--V */
2043#define NV_PGRAPH_CLIPX_1_CLIP13_MAX_GT 0x00000001 /* RWN-V */
2044#define NV_PGRAPH_CLIPX_1_CLIP13_MAX_EQ 0x00000002 /* RW--V */
2045#define NV_PGRAPH_CLIPX_1_CLIP14_MIN 25:24 /* RWNVF */
2046#define NV_PGRAPH_CLIPX_1_CLIP14_MIN_GT 0x00000000 /* RW--V */
2047#define NV_PGRAPH_CLIPX_1_CLIP14_MIN_LT 0x00000001 /* RWN-V */
2048#define NV_PGRAPH_CLIPX_1_CLIP14_MIN_EQ 0x00000002 /* RW--V */
2049#define NV_PGRAPH_CLIPX_1_CLIP14_MAX 27:26 /* RWNVF */
2050#define NV_PGRAPH_CLIPX_1_CLIP14_MAX_LT 0x00000000 /* RW--V */
2051#define NV_PGRAPH_CLIPX_1_CLIP14_MAX_GT 0x00000001 /* RWN-V */
2052#define NV_PGRAPH_CLIPX_1_CLIP14_MAX_EQ 0x00000002 /* RW--V */
2053#define NV_PGRAPH_CLIPX_1_CLIP15_MIN 29:28 /* RWNVF */
2054#define NV_PGRAPH_CLIPX_1_CLIP15_MIN_GT 0x00000000 /* RW--V */
2055#define NV_PGRAPH_CLIPX_1_CLIP15_MIN_LT 0x00000001 /* RWN-V */
2056#define NV_PGRAPH_CLIPX_1_CLIP15_MIN_EQ 0x00000002 /* RW--V */
2057#define NV_PGRAPH_CLIPX_1_CLIP15_MAX 31:30 /* RWNVF */
2058#define NV_PGRAPH_CLIPX_1_CLIP15_MAX_LT 0x00000000 /* RW--V */
2059#define NV_PGRAPH_CLIPX_1_CLIP15_MAX_GT 0x00000001 /* RWN-V */
2060#define NV_PGRAPH_CLIPX_1_CLIP15_MAX_EQ 0x00000002 /* RW--V */
2061#define NV_PGRAPH_CLIPY_0 0x0040052c /* RW-4R */
2062#define NV_PGRAPH_CLIPY_0_CLIP0_MIN 1:0 /* RWNVF */
2063#define NV_PGRAPH_CLIPY_0_CLIP0_MIN_GT 0x00000000 /* RW--V */
2064#define NV_PGRAPH_CLIPY_0_CLIP0_MIN_LT 0x00000001 /* RWN-V */
2065#define NV_PGRAPH_CLIPY_0_CLIP0_MIN_EQ 0x00000002 /* RW--V */
2066#define NV_PGRAPH_CLIPY_0_CLIP0_MAX 3:2 /* RWNVF */
2067#define NV_PGRAPH_CLIPY_0_CLIP0_MAX_LT 0x00000000 /* RW--V */
2068#define NV_PGRAPH_CLIPY_0_CLIP0_MAX_GT 0x00000001 /* RWN-V */
2069#define NV_PGRAPH_CLIPY_0_CLIP0_MAX_EQ 0x00000002 /* RW--V */
2070#define NV_PGRAPH_CLIPY_0_CLIP1_MIN 5:4 /* RWNVF */
2071#define NV_PGRAPH_CLIPY_0_CLIP1_MIN_GT 0x00000000 /* RW--V */
2072#define NV_PGRAPH_CLIPY_0_CLIP1_MIN_LT 0x00000001 /* RWN-V */
2073#define NV_PGRAPH_CLIPY_0_CLIP1_MIN_EQ 0x00000002 /* RW--V */
2074#define NV_PGRAPH_CLIPY_0_CLIP1_MAX 7:6 /* RWNVF */
2075#define NV_PGRAPH_CLIPY_0_CLIP1_MAX_LT 0x00000000 /* RW--V */
2076#define NV_PGRAPH_CLIPY_0_CLIP1_MAX_GT 0x00000001 /* RWN-V */
2077#define NV_PGRAPH_CLIPY_0_CLIP1_MAX_EQ 0x00000002 /* RW--V */
2078#define NV_PGRAPH_CLIPY_0_CLIP2_MIN 9:8 /* RWNVF */
2079#define NV_PGRAPH_CLIPY_0_CLIP2_MIN_GT 0x00000000 /* RW--V */
2080#define NV_PGRAPH_CLIPY_0_CLIP2_MIN_LT 0x00000001 /* RWN-V */
2081#define NV_PGRAPH_CLIPY_0_CLIP2_MIN_EQ 0x00000002 /* RW--V */
2082#define NV_PGRAPH_CLIPY_0_CLIP2_MAX 11:10 /* RWNVF */
2083#define NV_PGRAPH_CLIPY_0_CLIP2_MAX_LT 0x00000000 /* RW--V */
2084#define NV_PGRAPH_CLIPY_0_CLIP2_MAX_GT 0x00000001 /* RWN-V */
2085#define NV_PGRAPH_CLIPY_0_CLIP2_MAX_EQ 0x00000002 /* RW--V */
2086#define NV_PGRAPH_CLIPY_0_CLIP3_MIN 13:12 /* RWNVF */
2087#define NV_PGRAPH_CLIPY_0_CLIP3_MIN_GT 0x00000000 /* RW--V */
2088#define NV_PGRAPH_CLIPY_0_CLIP3_MIN_LT 0x00000001 /* RWN-V */
2089#define NV_PGRAPH_CLIPY_0_CLIP3_MIN_EQ 0x00000002 /* RW--V */
2090#define NV_PGRAPH_CLIPY_0_CLIP3_MAX 15:14 /* RWNVF */
2091#define NV_PGRAPH_CLIPY_0_CLIP3_MAX_LT 0x00000000 /* RW--V */
2092#define NV_PGRAPH_CLIPY_0_CLIP3_MAX_GT 0x00000001 /* RWN-V */
2093#define NV_PGRAPH_CLIPY_0_CLIP3_MAX_EQ 0x00000002 /* RW--V */
2094#define NV_PGRAPH_CLIPY_0_CLIP4_MIN 17:16 /* RWNVF */
2095#define NV_PGRAPH_CLIPY_0_CLIP4_MIN_GT 0x00000000 /* RW--V */
2096#define NV_PGRAPH_CLIPY_0_CLIP4_MIN_LT 0x00000001 /* RWN-V */
2097#define NV_PGRAPH_CLIPY_0_CLIP4_MIN_EQ 0x00000002 /* RW--V */
2098#define NV_PGRAPH_CLIPY_0_CLIP4_MAX 19:18 /* RWNVF */
2099#define NV_PGRAPH_CLIPY_0_CLIP4_MAX_LT 0x00000000 /* RW--V */
2100#define NV_PGRAPH_CLIPY_0_CLIP4_MAX_GT 0x00000001 /* RWN-V */
2101#define NV_PGRAPH_CLIPY_0_CLIP4_MAX_EQ 0x00000002 /* RW--V */
2102#define NV_PGRAPH_CLIPY_0_CLIP5_MIN 21:20 /* RWNVF */
2103#define NV_PGRAPH_CLIPY_0_CLIP5_MIN_GT 0x00000000 /* RW--V */
2104#define NV_PGRAPH_CLIPY_0_CLIP5_MIN_LT 0x00000001 /* RWN-V */
2105#define NV_PGRAPH_CLIPY_0_CLIP5_MIN_EQ 0x00000002 /* RW--V */
2106#define NV_PGRAPH_CLIPY_0_CLIP5_MAX 23:22 /* RWNVF */
2107#define NV_PGRAPH_CLIPY_0_CLIP5_MAX_LT 0x00000000 /* RW--V */
2108#define NV_PGRAPH_CLIPY_0_CLIP5_MAX_GT 0x00000001 /* RWN-V */
2109#define NV_PGRAPH_CLIPY_0_CLIP5_MAX_EQ 0x00000002 /* RW--V */
2110#define NV_PGRAPH_CLIPY_0_CLIP6_MIN 25:24 /* RWNVF */
2111#define NV_PGRAPH_CLIPY_0_CLIP6_MIN_GT 0x00000000 /* RW--V */
2112#define NV_PGRAPH_CLIPY_0_CLIP6_MIN_LT 0x00000001 /* RWN-V */
2113#define NV_PGRAPH_CLIPY_0_CLIP6_MIN_EQ 0x00000002 /* RW--V */
2114#define NV_PGRAPH_CLIPY_0_CLIP6_MAX 27:26 /* RWNVF */
2115#define NV_PGRAPH_CLIPY_0_CLIP6_MAX_LT 0x00000000 /* RW--V */
2116#define NV_PGRAPH_CLIPY_0_CLIP6_MAX_GT 0x00000001 /* RWN-V */
2117#define NV_PGRAPH_CLIPY_0_CLIP6_MAX_EQ 0x00000002 /* RW--V */
2118#define NV_PGRAPH_CLIPY_0_CLIP7_MIN 29:28 /* RWNVF */
2119#define NV_PGRAPH_CLIPY_0_CLIP7_MIN_GT 0x00000000 /* RW--V */
2120#define NV_PGRAPH_CLIPY_0_CLIP7_MIN_LT 0x00000001 /* RWN-V */
2121#define NV_PGRAPH_CLIPY_0_CLIP7_MIN_EQ 0x00000002 /* RW--V */
2122#define NV_PGRAPH_CLIPY_0_CLIP7_MAX 31:30 /* RWNVF */
2123#define NV_PGRAPH_CLIPY_0_CLIP7_MAX_LT 0x00000000 /* RW--V */
2124#define NV_PGRAPH_CLIPY_0_CLIP7_MAX_GT 0x00000001 /* RWN-V */
2125#define NV_PGRAPH_CLIPY_0_CLIP7_MAX_EQ 0x00000002 /* RW--V */
2126#define NV_PGRAPH_CLIPY_1 0x00400530 /* RW-4R */
2127#define NV_PGRAPH_CLIPY_1_CLIP8_MIN 1:0 /* RWNVF */
2128#define NV_PGRAPH_CLIPY_1_CLIP8_MIN_GT 0x00000000 /* RW--V */
2129#define NV_PGRAPH_CLIPY_1_CLIP8_MIN_LT 0x00000001 /* RWN-V */
2130#define NV_PGRAPH_CLIPY_1_CLIP8_MIN_EQ 0x00000002 /* RW--V */
2131#define NV_PGRAPH_CLIPY_1_CLIP8_MAX 3:2 /* RWNVF */
2132#define NV_PGRAPH_CLIPY_1_CLIP8_MAX_LT 0x00000000 /* RW--V */
2133#define NV_PGRAPH_CLIPY_1_CLIP8_MAX_GT 0x00000001 /* RWN-V */
2134#define NV_PGRAPH_CLIPY_1_CLIP8_MAX_EQ 0x00000002 /* RW--V */
2135#define NV_PGRAPH_CLIPY_1_CLIP9_MIN 5:4 /* RWNVF */
2136#define NV_PGRAPH_CLIPY_1_CLIP9_MIN_GT 0x00000000 /* RW--V */
2137#define NV_PGRAPH_CLIPY_1_CLIP9_MIN_LT 0x00000001 /* RWN-V */
2138#define NV_PGRAPH_CLIPY_1_CLIP9_MIN_EQ 0x00000002 /* RW--V */
2139#define NV_PGRAPH_CLIPY_1_CLIP9_MAX 7:6 /* RWNVF */
2140#define NV_PGRAPH_CLIPY_1_CLIP9_MAX_LT 0x00000000 /* RW--V */
2141#define NV_PGRAPH_CLIPY_1_CLIP9_MAX_GT 0x00000001 /* RWN-V */
2142#define NV_PGRAPH_CLIPY_1_CLIP9_MAX_EQ 0x00000002 /* RW--V */
2143#define NV_PGRAPH_CLIPY_1_CLIP10_MIN 9:8 /* RWNVF */
2144#define NV_PGRAPH_CLIPY_1_CLIP10_MIN_GT 0x00000000 /* RW--V */
2145#define NV_PGRAPH_CLIPY_1_CLIP10_MIN_LT 0x00000001 /* RWN-V */
2146#define NV_PGRAPH_CLIPY_1_CLIP10_MIN_EQ 0x00000002 /* RW--V */
2147#define NV_PGRAPH_CLIPY_1_CLIP10_MAX 11:10 /* RWNVF */
2148#define NV_PGRAPH_CLIPY_1_CLIP10_MAX_LT 0x00000000 /* RW--V */
2149#define NV_PGRAPH_CLIPY_1_CLIP10_MAX_GT 0x00000001 /* RWN-V */
2150#define NV_PGRAPH_CLIPY_1_CLIP10_MAX_EQ 0x00000002 /* RW--V */
2151#define NV_PGRAPH_CLIPY_1_CLIP11_MIN 13:12 /* RWNVF */
2152#define NV_PGRAPH_CLIPY_1_CLIP11_MIN_GT 0x00000000 /* RW--V */
2153#define NV_PGRAPH_CLIPY_1_CLIP11_MIN_LT 0x00000001 /* RWN-V */
2154#define NV_PGRAPH_CLIPY_1_CLIP11MIN_EQ 0x00000002 /* RW--V */
2155#define NV_PGRAPH_CLIPY_1_CLIP11_MAX 15:14 /* RWNVF */
2156#define NV_PGRAPH_CLIPY_1_CLIP11_MAX_LT 0x00000000 /* RW--V */
2157#define NV_PGRAPH_CLIPY_1_CLIP11_MAX_GT 0x00000001 /* RWN-V */
2158#define NV_PGRAPH_CLIPY_1_CLIP11_MAX_EQ 0x00000002 /* RW--V */
2159#define NV_PGRAPH_CLIPY_1_CLIP12_MIN 17:16 /* RWNVF */
2160#define NV_PGRAPH_CLIPY_1_CLIP12_MIN_GT 0x00000000 /* RW--V */
2161#define NV_PGRAPH_CLIPY_1_CLIP12_MIN_LT 0x00000001 /* RWN-V */
2162#define NV_PGRAPH_CLIPY_1_CLIP12_MIN_EQ 0x00000002 /* RW--V */
2163#define NV_PGRAPH_CLIPY_1_CLIP12_MAX 19:18 /* RWNVF */
2164#define NV_PGRAPH_CLIPY_1_CLIP12_MAX_LT 0x00000000 /* RW--V */
2165#define NV_PGRAPH_CLIPY_1_CLIP12_MAX_GT 0x00000001 /* RWN-V */
2166#define NV_PGRAPH_CLIPY_1_CLIP12_MAX_EQ 0x00000002 /* RW--V */
2167#define NV_PGRAPH_CLIPY_1_CLIP13_MIN 21:20 /* RWNVF */
2168#define NV_PGRAPH_CLIPY_1_CLIP13_MIN_GT 0x00000000 /* RW--V */
2169#define NV_PGRAPH_CLIPY_1_CLIP13_MIN_LT 0x00000001 /* RWN-V */
2170#define NV_PGRAPH_CLIPY_1_CLIP13_MIN_EQ 0x00000002 /* RW--V */
2171#define NV_PGRAPH_CLIPY_1_CLIP13_MAX 23:22 /* RWNVF */
2172#define NV_PGRAPH_CLIPY_1_CLIP13_MAX_LT 0x00000000 /* RW--V */
2173#define NV_PGRAPH_CLIPY_1_CLIP13_MAX_GT 0x00000001 /* RWN-V */
2174#define NV_PGRAPH_CLIPY_1_CLIP13_MAX_EQ 0x00000002 /* RW--V */
2175#define NV_PGRAPH_CLIPY_1_CLIP14_MIN 25:24 /* RWNVF */
2176#define NV_PGRAPH_CLIPY_1_CLIP14_MIN_GT 0x00000000 /* RW--V */
2177#define NV_PGRAPH_CLIPY_1_CLIP14_MIN_LT 0x00000001 /* RWN-V */
2178#define NV_PGRAPH_CLIPY_1_CLIP14_MIN_EQ 0x00000002 /* RW--V */
2179#define NV_PGRAPH_CLIPY_1_CLIP14_MAX 27:26 /* RWNVF */
2180#define NV_PGRAPH_CLIPY_1_CLIP14_MAX_LT 0x00000000 /* RW--V */
2181#define NV_PGRAPH_CLIPY_1_CLIP14_MAX_GT 0x00000001 /* RWN-V */
2182#define NV_PGRAPH_CLIPY_1_CLIP14_MAX_EQ 0x00000002 /* RW--V */
2183#define NV_PGRAPH_CLIPY_1_CLIP15_MIN 29:28 /* RWNVF */
2184#define NV_PGRAPH_CLIPY_1_CLIP15_MIN_GT 0x00000000 /* RW--V */
2185#define NV_PGRAPH_CLIPY_1_CLIP15_MIN_LT 0x00000001 /* RWN-V */
2186#define NV_PGRAPH_CLIPY_1_CLIP15_MIN_EQ 0x00000002 /* RW--V */
2187#define NV_PGRAPH_CLIPY_1_CLIP15_MAX 31:30 /* RWNVF */
2188#define NV_PGRAPH_CLIPY_1_CLIP15_MAX_LT 0x00000000 /* RW--V */
2189#define NV_PGRAPH_CLIPY_1_CLIP15_MAX_GT 0x00000001 /* RWN-V */
2190#define NV_PGRAPH_CLIPY_1_CLIP15_MAX_EQ 0x00000002 /* RW--V */
2191#define NV_PGRAPH_MISC24_0 0x00400510 /* RW-4R */
2192#define NV_PGRAPH_MISC24_0_VALUE 23:0 /* RWXUF */
2193#define NV_PGRAPH_MISC24_1 0x00400570 /* RW-4R */
2194#define NV_PGRAPH_MISC24_1_VALUE 23:0 /* RWXUF */
2195#define NV_PGRAPH_MISC24_2 0x00400574 /* RW-4R */
2196#define NV_PGRAPH_MISC24_2_VALUE 23:0 /* RWXUF */
2197#define NV_PGRAPH_PASSTHRU_0 0x0040057C /* RW-4R */
2198#define NV_PGRAPH_PASSTHRU_0_VALUE 31:0 /* RWXUF */
2199#define NV_PGRAPH_PASSTHRU_1 0x00400580 /* RW-4R */
2200#define NV_PGRAPH_PASSTHRU_1_VALUE 31:0 /* RWXUF */
2201#define NV_PGRAPH_PASSTHRU_2 0x00400584 /* RW-4R */
2202#define NV_PGRAPH_PASSTHRU_2_VALUE 31:0 /* RWXUF */
2203#define NV_PGRAPH_U_RAM(i) (0x00400d00+(i)*4) /* RW-4A */
2204#define NV_PGRAPH_U_RAM__SIZE_1 16 /* */
2205#define NV_PGRAPH_U_RAM_VALUE 31:6 /* RWXFF */
2206#define NV_PGRAPH_V_RAM(i) (0x00400d40+(i)*4) /* RW-4A */
2207#define NV_PGRAPH_V_RAM__SIZE_1 16 /* */
2208#define NV_PGRAPH_V_RAM_VALUE 31:6 /* RWXFF */
2209#define NV_PGRAPH_M_RAM(i) (0x00400d80+(i)*4) /* RW-4A */
2210#define NV_PGRAPH_M_RAM__SIZE_1 16 /* */
2211#define NV_PGRAPH_M_RAM_VALUE 31:6 /* RWXFF */
2212#define NV_PGRAPH_DMA_START_0 0x00401000 /* RW-4R */
2213#define NV_PGRAPH_DMA_START_0_VALUE 31:0 /* RWXUF */
2214#define NV_PGRAPH_DMA_START_1 0x00401004 /* RW-4R */
2215#define NV_PGRAPH_DMA_START_1_VALUE 31:0 /* RWXUF */
2216#define NV_PGRAPH_DMA_LENGTH 0x00401008 /* RW-4R */
2217#define NV_PGRAPH_DMA_LENGTH_VALUE 21:0 /* RWXUF */
2218#define NV_PGRAPH_DMA_MISC 0x0040100C /* RW-4R */
2219#define NV_PGRAPH_DMA_MISC_COUNT 15:0 /* RWXUF */
2220#define NV_PGRAPH_DMA_MISC_FMT_SRC 18:16 /* RWXVF */
2221#define NV_PGRAPH_DMA_MISC_FMT_DST 22:20 /* RWXVF */
2222#define NV_PGRAPH_DMA_DATA_0 0x00401020 /* RW-4R */
2223#define NV_PGRAPH_DMA_DATA_0_VALUE 31:0 /* RWXUF */
2224#define NV_PGRAPH_DMA_DATA_1 0x00401024 /* RW-4R */
2225#define NV_PGRAPH_DMA_DATA_1_VALUE 31:0 /* RWXUF */
2226#define NV_PGRAPH_DMA_RM 0x00401030 /* RW-4R */
2227#define NV_PGRAPH_DMA_RM_ASSIST_A 0:0 /* RWIVF */
2228#define NV_PGRAPH_DMA_RM_ASSIST_A_NOT_PENDING 0x00000000 /* R-I-V */
2229#define NV_PGRAPH_DMA_RM_ASSIST_A_PENDING 0x00000001 /* R---V */
2230#define NV_PGRAPH_DMA_RM_ASSIST_A_RESET 0x00000001 /* -W--C */
2231#define NV_PGRAPH_DMA_RM_ASSIST_B 1:1 /* RWIVF */
2232#define NV_PGRAPH_DMA_RM_ASSIST_B_NOT_PENDING 0x00000000 /* R-I-V */
2233#define NV_PGRAPH_DMA_RM_ASSIST_B_PENDING 0x00000001 /* R---V */
2234#define NV_PGRAPH_DMA_RM_ASSIST_B_RESET 0x00000001 /* -W--C */
2235#define NV_PGRAPH_DMA_RM_WRITE_REQ 4:4 /* CWIVF */
2236#define NV_PGRAPH_DMA_RM_WRITE_REQ_NOT_PENDING 0x00000000 /* CWI-V */
2237#define NV_PGRAPH_DMA_RM_WRITE_REQ_PENDING 0x00000001 /* -W--T */
2238#define NV_PGRAPH_DMA_A_XLATE_INST 0x00401040 /* RW-4R */
2239#define NV_PGRAPH_DMA_A_XLATE_INST_VALUE 15:0 /* RWXUF */
2240#define NV_PGRAPH_DMA_A_CONTROL 0x00401044 /* RW-4R */
2241#define NV_PGRAPH_DMA_A_CONTROL_PAGE_TABLE 12:12 /* RWIVF */
2242#define NV_PGRAPH_DMA_A_CONTROL_PAGE_TABLE_NOT_PRESENT 0x00000000 /* RWI-V */
2243#define NV_PGRAPH_DMA_A_CONTROL_PAGE_TABLE_PRESENT 0x00000001 /* RW--V */
2244#define NV_PGRAPH_DMA_A_CONTROL_PAGE_ENTRY 13:13 /* RWXVF */
2245#define NV_PGRAPH_DMA_A_CONTROL_PAGE_ENTRY_NOT_LINEAR 0x00000000 /* RW--V */
2246#define NV_PGRAPH_DMA_A_CONTROL_PAGE_ENTRY_LINEAR 0x00000001 /* RW--V */
2247#define NV_PGRAPH_DMA_A_CONTROL_TARGET_NODE 17:16 /* RWXUF */
2248#define NV_PGRAPH_DMA_A_CONTROL_TARGET_NODE_NVM 0x00000000 /* RW--V */
2249#define NV_PGRAPH_DMA_A_CONTROL_TARGET_NODE_PCI 0x00000002 /* RW--V */
2250#define NV_PGRAPH_DMA_A_CONTROL_TARGET_NODE_AGP 0x00000003 /* RW--V */
2251#define NV_PGRAPH_DMA_A_CONTROL_ADJUST 31:20 /* RWXUF */
2252#define NV_PGRAPH_DMA_A_LIMIT 0x00401048 /* RW-4R */
2253#define NV_PGRAPH_DMA_A_LIMIT_OFFSET 31:0 /* RWXUF */
2254#define NV_PGRAPH_DMA_A_TLB_PTE 0x0040104C /* RW-4R */
2255#define NV_PGRAPH_DMA_A_TLB_PTE_ACCESS 1:1 /* RWXVF */
2256#define NV_PGRAPH_DMA_A_TLB_PTE_ACCESS_READ_ONLY 0x00000000 /* RW--V */
2257#define NV_PGRAPH_DMA_A_TLB_PTE_ACCESS_READ_WRITE 0x00000001 /* RW--V */
2258#define NV_PGRAPH_DMA_A_TLB_PTE_FRAME_ADDRESS 31:12 /* RWXUF */
2259#define NV_PGRAPH_DMA_A_TLB_TAG 0x00401050 /* RW-4R */
2260#define NV_PGRAPH_DMA_A_TLB_TAG_ADDRESS 31:12 /* RWXUF */
2261#define NV_PGRAPH_DMA_A_ADJ_OFFSET 0x00401054 /* RW-4R */
2262#define NV_PGRAPH_DMA_A_ADJ_OFFSET_VALUE 31:0 /* RWXUF */
2263#define NV_PGRAPH_DMA_A_OFFSET 0x00401058 /* RW-4R */
2264#define NV_PGRAPH_DMA_A_OFFSET_VALUE 31:0 /* RWXUF */
2265#define NV_PGRAPH_DMA_A_SIZE 0x0040105C /* RW-4R */
2266#define NV_PGRAPH_DMA_A_SIZE_VALUE 24:0 /* RWXUF */
2267#define NV_PGRAPH_DMA_A_Y_SIZE 0x00401060 /* RW-4R */
2268#define NV_PGRAPH_DMA_A_Y_SIZE_VALUE 10:0 /* RWXUF */
2269#define NV_PGRAPH_DMA_B_XLATE_INST 0x00401080 /* RW-4R */
2270#define NV_PGRAPH_DMA_B_XLATE_INST_VALUE 15:0 /* RWXUF */
2271#define NV_PGRAPH_DMA_B_CONTROL 0x00401084 /* RW-4R */
2272#define NV_PGRAPH_DMA_B_CONTROL_PAGE_TABLE 12:12 /* RWIVF */
2273#define NV_PGRAPH_DMA_B_CONTROL_PAGE_TABLE_NOT_PRESENT 0x00000000 /* RWI-V */
2274#define NV_PGRAPH_DMA_B_CONTROL_PAGE_TABLE_PRESENT 0x00000001 /* RW--V */
2275#define NV_PGRAPH_DMA_B_CONTROL_PAGE_ENTRY 13:13 /* RWXVF */
2276#define NV_PGRAPH_DMA_B_CONTROL_PAGE_ENTRY_NOT_LINEAR 0x00000000 /* RW--V */
2277#define NV_PGRAPH_DMA_B_CONTROL_PAGE_ENTRY_LINEAR 0x00000001 /* RW--V */
2278#define NV_PGRAPH_DMA_B_CONTROL_TARGET_NODE 17:16 /* RWXUF */
2279#define NV_PGRAPH_DMA_B_CONTROL_TARGET_NODE_NVM 0x00000000 /* RW--V */
2280#define NV_PGRAPH_DMA_B_CONTROL_TARGET_NODE_PCI 0x00000002 /* RW--V */
2281#define NV_PGRAPH_DMA_B_CONTROL_TARGET_NODE_AGP 0x00000003 /* RW--V */
2282#define NV_PGRAPH_DMA_B_CONTROL_ADJUST 31:20 /* RWXUF */
2283#define NV_PGRAPH_DMA_B_LIMIT 0x00401088 /* RW-4R */
2284#define NV_PGRAPH_DMA_B_LIMIT_OFFSET 31:0 /* RWXUF */
2285#define NV_PGRAPH_DMA_B_TLB_PTE 0x0040108C /* RW-4R */
2286#define NV_PGRAPH_DMA_B_TLB_PTE_ACCESS 1:1 /* RWXVF */
2287#define NV_PGRAPH_DMA_B_TLB_PTE_ACCESS_READ_ONLY 0x00000000 /* RW--V */
2288#define NV_PGRAPH_DMA_B_TLB_PTE_ACCESS_READ_WRITE 0x00000001 /* RW--V */
2289#define NV_PGRAPH_DMA_B_TLB_PTE_FRAME_ADDRESS 31:12 /* RWXUF */
2290#define NV_PGRAPH_DMA_B_TLB_TAG 0x00401090 /* RW-4R */
2291#define NV_PGRAPH_DMA_B_TLB_TAG_ADDRESS 31:12 /* RWXUF */
2292#define NV_PGRAPH_DMA_B_ADJ_OFFSET 0x00401094 /* RW-4R */
2293#define NV_PGRAPH_DMA_B_ADJ_OFFSET_VALUE 31:0 /* RWXUF */
2294#define NV_PGRAPH_DMA_B_OFFSET 0x00401098 /* RW-4R */
2295#define NV_PGRAPH_DMA_B_OFFSET_VALUE 31:0 /* RWXUF */
2296#define NV_PGRAPH_DMA_B_SIZE 0x0040109C /* RW-4R */
2297#define NV_PGRAPH_DMA_B_SIZE_VALUE 24:0 /* RWXUF */
2298#define NV_PGRAPH_DMA_B_Y_SIZE 0x004010A0 /* RW-4R */
2299#define NV_PGRAPH_DMA_B_Y_SIZE_VALUE 10:0 /* RWXUF */
2300
2301/* Framebuffer registers */
2302#define NV_PFB 0x00100FFF:0x00100000 /* RW--D */
2303#define NV_PFB_BOOT_0 0x00100000 /* RW-4R */
2304#define NV_PFB_BOOT_0_RAM_AMOUNT 1:0 /* RW-VF */
2305#define NV_PFB_BOOT_0_RAM_AMOUNT_32MB 0x00000000 /* RW--V */
2306#define NV_PFB_BOOT_0_RAM_AMOUNT_4MB 0x00000001 /* RW--V */
2307#define NV_PFB_BOOT_0_RAM_AMOUNT_8MB 0x00000002 /* RW--V */
2308#define NV_PFB_BOOT_0_RAM_AMOUNT_16MB 0x00000003 /* RW--V */
2309#define NV_PFB_BOOT_0_RAM_WIDTH_128 2:2 /* RW-VF */
2310#define NV_PFB_BOOT_0_RAM_WIDTH_128_OFF 0x00000000 /* RW--V */
2311#define NV_PFB_BOOT_0_RAM_WIDTH_128_ON 0x00000001 /* RW--V */
2312#define NV_PFB_BOOT_0_RAM_TYPE 4:3 /* RW-VF */
2313#define NV_PFB_BOOT_0_RAM_TYPE_256K 0x00000000 /* RW--V */
2314#define NV_PFB_BOOT_0_RAM_TYPE_512K_2BANK 0x00000001 /* RW--V */
2315#define NV_PFB_BOOT_0_RAM_TYPE_512K_4BANK 0x00000002 /* RW--V */
2316#define NV_PFB_BOOT_0_RAM_TYPE_1024K_2BANK 0x00000003 /* RW--V */
2317#define NV_PFB_CONFIG_0 0x00100200 /* RW-4R */
2318#define NV_PFB_CONFIG_0_TYPE 14:0 /* RWIVF */
2319#define NV_PFB_CONFIG_0_TYPE_OLD1024_FIXED_8BPP 0x00000120 /* RW--V */
2320#define NV_PFB_CONFIG_0_TYPE_OLD1024_FIXED_16BPP 0x00000220 /* RW--V */
2321#define NV_PFB_CONFIG_0_TYPE_OLD1024_FIXED_32BPP 0x00000320 /* RW--V */
2322#define NV_PFB_CONFIG_0_TYPE_OLD1024_VAR_8BPP 0x00004120 /* RW--V */
2323#define NV_PFB_CONFIG_0_TYPE_OLD1024_VAR_16BPP 0x00004220 /* RW--V */
2324#define NV_PFB_CONFIG_0_TYPE_OLD1024_VAR_32BPP 0x00004320 /* RW--V */
2325#define NV_PFB_CONFIG_0_TYPE_TETRIS 0x00002000 /* RW--V */
2326#define NV_PFB_CONFIG_0_TYPE_NOTILING 0x00001114 /* RWI-V */
2327#define NV_PFB_CONFIG_0_TETRIS_MODE 17:15 /* RWI-F */
2328#define NV_PFB_CONFIG_0_TETRIS_MODE_PASS 0x00000000 /* RWI-V */
2329#define NV_PFB_CONFIG_0_TETRIS_MODE_1 0x00000001 /* RW--V */
2330#define NV_PFB_CONFIG_0_TETRIS_MODE_2 0x00000002 /* RW--V */
2331#define NV_PFB_CONFIG_0_TETRIS_MODE_3 0x00000003 /* RW--V */
2332#define NV_PFB_CONFIG_0_TETRIS_MODE_4 0x00000004 /* RW--V */
2333#define NV_PFB_CONFIG_0_TETRIS_MODE_5 0x00000005 /* RW--V */
2334#define NV_PFB_CONFIG_0_TETRIS_MODE_6 0x00000006 /* RW--V */
2335#define NV_PFB_CONFIG_0_TETRIS_MODE_7 0x00000007 /* RW--V */
2336#define NV_PFB_CONFIG_0_TETRIS_SHIFT 19:18 /* RWI-F */
2337#define NV_PFB_CONFIG_0_TETRIS_SHIFT_0 0x00000000 /* RWI-V */
2338#define NV_PFB_CONFIG_0_TETRIS_SHIFT_1 0x00000001 /* RW--V */
2339#define NV_PFB_CONFIG_0_TETRIS_SHIFT_2 0x00000002 /* RW--V */
2340#define NV_PFB_CONFIG_0_BANK_SWAP 22:20 /* RWI-F */
2341#define NV_PFB_CONFIG_0_BANK_SWAP_OFF 0x00000000 /* RWI-V */
2342#define NV_PFB_CONFIG_0_BANK_SWAP_1M 0x00000001 /* RW--V */
2343#define NV_PFB_CONFIG_0_BANK_SWAP_2M 0x00000005 /* RW--V */
2344#define NV_PFB_CONFIG_0_BANK_SWAP_4M 0x00000007 /* RW--V */
2345#define NV_PFB_CONFIG_0_UNUSED 23:23 /* RW-VF */
2346#define NV_PFB_CONFIG_0_SCRAMBLE_EN 29:29 /* RWIVF */
2347#define NV_PFB_CONFIG_0_SCRAMBLE_EN_INIT 0x00000000 /* RW--V */
2348#define NV_PFB_CONFIG_0_SCRAMBLE_ACTIVE 0x00000001 /* RW--V */
2349#define NV_PFB_CONFIG_0_PRAMIN_WR 28:28 /* RWIVF */
2350#define NV_PFB_CONFIG_0_PRAMIN_WR_INIT 0x00000000 /* RW--V */
2351#define NV_PFB_CONFIG_0_PRAMIN_WR_DISABLED 0x00000001 /* RW--V */
2352#define NV_PFB_CONFIG_0_PRAMIN_WR_MASK 27:24 /* RWIVF */
2353#define NV_PFB_CONFIG_0_PRAMIN_WR_MASK_INIT 0x00000000 /* RWI-V */
2354#define NV_PFB_CONFIG_0_PRAMIN_WR_MASK_CLEAR 0x0000000f /* RWI-V */
2355#define NV_PFB_CONFIG_1 0x00100204 /* RW-4R */
2356#define NV_PFB_RTL 0x00100300 /* RW-4R */
2357#define NV_PFB_RTL_H 0:0 /* RWIUF */
2358#define NV_PFB_RTL_H_DEFAULT 0x00000000 /* RWI-V */
2359#define NV_PFB_RTL_MC 1:1 /* RWIUF */
2360#define NV_PFB_RTL_MC_DEFAULT 0x00000000 /* RWI-V */
2361#define NV_PFB_RTL_V 2:2 /* RWIUF */
2362#define NV_PFB_RTL_V_DEFAULT 0x00000000 /* RWI-V */
2363#define NV_PFB_RTL_G 3:3 /* RWIUF */
2364#define NV_PFB_RTL_G_DEFAULT 0x00000000 /* RWI-V */
2365#define NV_PFB_RTL_GB 4:4 /* RWIUF */
2366#define NV_PFB_RTL_GB_DEFAULT 0x00000000 /* RWI-V */
2367#define NV_PFB_CONFIG_0_RESOLUTION 5:0 /* RWIVF */
2368#define NV_PFB_CONFIG_0_RESOLUTION_320_PIXELS 0x0000000a /* RW--V */
2369#define NV_PFB_CONFIG_0_RESOLUTION_400_PIXELS 0x0000000d /* RW--V */
2370#define NV_PFB_CONFIG_0_RESOLUTION_480_PIXELS 0x0000000f /* RW--V */
2371#define NV_PFB_CONFIG_0_RESOLUTION_512_PIXELS 0x00000010 /* RW--V */
2372#define NV_PFB_CONFIG_0_RESOLUTION_640_PIXELS 0x00000014 /* RW--V */
2373#define NV_PFB_CONFIG_0_RESOLUTION_800_PIXELS 0x00000019 /* RW--V */
2374#define NV_PFB_CONFIG_0_RESOLUTION_960_PIXELS 0x0000001e /* RW--V */
2375#define NV_PFB_CONFIG_0_RESOLUTION_1024_PIXELS 0x00000020 /* RW--V */
2376#define NV_PFB_CONFIG_0_RESOLUTION_1152_PIXELS 0x00000024 /* RW--V */
2377#define NV_PFB_CONFIG_0_RESOLUTION_1280_PIXELS 0x00000028 /* RW--V */
2378#define NV_PFB_CONFIG_0_RESOLUTION_1600_PIXELS 0x00000032 /* RW--V */
2379#define NV_PFB_CONFIG_0_RESOLUTION_DEFAULT 0x00000014 /* RWI-V */
2380#define NV_PFB_CONFIG_0_PIXEL_DEPTH 9:8 /* RWIVF */
2381#define NV_PFB_CONFIG_0_PIXEL_DEPTH_8_BITS 0x00000001 /* RW--V */
2382#define NV_PFB_CONFIG_0_PIXEL_DEPTH_16_BITS 0x00000002 /* RW--V */
2383#define NV_PFB_CONFIG_0_PIXEL_DEPTH_32_BITS 0x00000003 /* RW--V */
2384#define NV_PFB_CONFIG_0_PIXEL_DEPTH_DEFAULT 0x00000001 /* RWI-V */
2385#define NV_PFB_CONFIG_0_TILING 12:12 /* RWIVF */
2386#define NV_PFB_CONFIG_0_TILING_ENABLED 0x00000000 /* RW--V */
2387#define NV_PFB_CONFIG_0_TILING_DISABLED 0x00000001 /* RWI-V */
2388#define NV_PFB_CONFIG_1_SGRAM100 3:3 /* RWIVF */
2389#define NV_PFB_CONFIG_1_SGRAM100_ENABLED 0x00000000 /* RWI-V */
2390#define NV_PFB_CONFIG_1_SGRAM100_DISABLED 0x00000001 /* RW--V */
2391#define NV_PFB_DEBUG_0_CKE_ALWAYSON 29:29 /* RWIVF */
2392#define NV_PFB_DEBUG_0_CKE_ALWAYSON_OFF 0x00000000 /* RW--V */
2393#define NV_PFB_DEBUG_0_CKE_ALWAYSON_ON 0x00000001 /* RWI-V */
2394
2395#define NV_PEXTDEV 0x00101FFF:0x00101000 /* RW--D */
2396#define NV_PEXTDEV_BOOT_0 0x00101000 /* R--4R */
2397#define NV_PEXTDEV_BOOT_0_STRAP_BUS_SPEED 0:0 /* R-XVF */
2398#define NV_PEXTDEV_BOOT_0_STRAP_BUS_SPEED_33MHZ 0x00000000 /* R---V */
2399#define NV_PEXTDEV_BOOT_0_STRAP_BUS_SPEED_66MHZ 0x00000001 /* R---V */
2400#define NV_PEXTDEV_BOOT_0_STRAP_SUB_VENDOR 1:1 /* R-XVF */
2401#define NV_PEXTDEV_BOOT_0_STRAP_SUB_VENDOR_NO_BIOS 0x00000000 /* R---V */
2402#define NV_PEXTDEV_BOOT_0_STRAP_SUB_VENDOR_BIOS 0x00000001 /* R---V */
2403#define NV_PEXTDEV_BOOT_0_STRAP_RAM_TYPE 3:2 /* R-XVF */
2404#define NV_PEXTDEV_BOOT_0_STRAP_RAM_TYPE_SGRAM_256K 0x00000000 /* R---V */
2405#define NV_PEXTDEV_BOOT_0_STRAP_RAM_TYPE_SGRAM_512K_2BANK 0x00000001 /* R---V */
2406#define NV_PEXTDEV_BOOT_0_STRAP_RAM_TYPE_SGRAM_512K_4BANK 0x00000002 /* R---V */
2407#define NV_PEXTDEV_BOOT_0_STRAP_RAM_TYPE_1024K_2BANK 0x00000003 /* R---V */
2408#define NV_PEXTDEV_BOOT_0_STRAP_RAM_WIDTH 4:4 /* R-XVF */
2409#define NV_PEXTDEV_BOOT_0_STRAP_RAM_WIDTH_64 0x00000000 /* R---V */
2410#define NV_PEXTDEV_BOOT_0_STRAP_RAM_WIDTH_128 0x00000001 /* R---V */
2411#define NV_PEXTDEV_BOOT_0_STRAP_BUS_TYPE 5:5 /* R-XVF */
2412#define NV_PEXTDEV_BOOT_0_STRAP_BUS_TYPE_PCI 0x00000000 /* R---V */
2413#define NV_PEXTDEV_BOOT_0_STRAP_BUS_TYPE_AGP 0x00000001 /* R---V */
2414#define NV_PEXTDEV_BOOT_0_STRAP_CRYSTAL 6:6 /* R-XVF */
2415#define NV_PEXTDEV_BOOT_0_STRAP_CRYSTAL_13500K 0x00000000 /* R---V */
2416#define NV_PEXTDEV_BOOT_0_STRAP_CRYSTAL_14318180 0x00000001 /* R---V */
2417#define NV_PEXTDEV_BOOT_0_STRAP_TVMODE 8:7 /* R-XVF */
2418#define NV_PEXTDEV_BOOT_0_STRAP_TVMODE_SECAM 0x00000000 /* R---V */
2419#define NV_PEXTDEV_BOOT_0_STRAP_TVMODE_NTSC 0x00000001 /* R---V */
2420#define NV_PEXTDEV_BOOT_0_STRAP_TVMODE_PAL 0x00000002 /* R---V */
2421#define NV_PEXTDEV_BOOT_0_STRAP_TVMODE_DISABLED 0x00000003 /* R---V */
2422#define NV_PEXTDEV_BOOT_0_STRAP_OVERWRITE 11:11 /* RWIVF */
2423#define NV_PEXTDEV_BOOT_0_STRAP_OVERWRITE_DISABLED 0x00000000 /* RWI-V */
2424#define NV_PEXTDEV_BOOT_0_STRAP_OVERWRITE_ENABLED 0x00000001 /* RW--V */
2425
2426/* Extras */
2427#define NV_PRAMIN 0x007FFFFF:0x00700000 /* RW--M */
2428/*#define NV_PRAMIN 0x00FFFFFF:0x00C00000*/
2429#define NV_PNVM 0x01FFFFFF:0x01000000 /* RW--M */
2430/*#define NV_PNVM 0x00BFFFFF:0x00800000*/
2431#define NV_CHAN0 0x0080ffff:0x00800000
2432
2433/* FIFO subchannels */
2434#define NV_UROP 0x43
2435#define NV_UCHROMA 0x57
2436#define NV_UCLIP 0x19
2437#define NV_UPATT 0x18
2438#define NV_ULIN 0x5C
2439#define NV_UTRI 0x5D
2440#define NV_URECT 0x5E
2441#define NV_UBLIT 0x5F
2442#define NV_UGLYPH 0x4B
2443
2444#endif /*__NV4REF_H__*/
2445
diff --git a/drivers/video/riva/nv_driver.c b/drivers/video/riva/nv_driver.c
index be630a0ccfd4..a11026812d1b 100644
--- a/drivers/video/riva/nv_driver.c
+++ b/drivers/video/riva/nv_driver.c
@@ -231,12 +231,14 @@ unsigned long riva_get_memlen(struct riva_par *par)
231 case NV_ARCH_30: 231 case NV_ARCH_30:
232 if(chipset == NV_CHIP_IGEFORCE2) { 232 if(chipset == NV_CHIP_IGEFORCE2) {
233 233
234 dev = pci_find_slot(0, 1); 234 dev = pci_get_bus_and_slot(0, 1);
235 pci_read_config_dword(dev, 0x7C, &amt); 235 pci_read_config_dword(dev, 0x7C, &amt);
236 pci_dev_put(dev);
236 memlen = (((amt >> 6) & 31) + 1) * 1024; 237 memlen = (((amt >> 6) & 31) + 1) * 1024;
237 } else if (chipset == NV_CHIP_0x01F0) { 238 } else if (chipset == NV_CHIP_0x01F0) {
238 dev = pci_find_slot(0, 1); 239 dev = pci_get_bus_and_slot(0, 1);
239 pci_read_config_dword(dev, 0x84, &amt); 240 pci_read_config_dword(dev, 0x84, &amt);
241 pci_dev_put(dev);
240 memlen = (((amt >> 4) & 127) + 1) * 1024; 242 memlen = (((amt >> 4) & 127) + 1) * 1024;
241 } else { 243 } else {
242 switch ((NV_RD32(chip->PFB, 0x0000020C) >> 20) & 244 switch ((NV_RD32(chip->PFB, 0x0000020C) >> 20) &
diff --git a/drivers/video/riva/riva_hw.c b/drivers/video/riva/riva_hw.c
index e0b8c521cc9c..70bfd78eca81 100644
--- a/drivers/video/riva/riva_hw.c
+++ b/drivers/video/riva/riva_hw.c
@@ -1118,8 +1118,9 @@ static void nForceUpdateArbitrationSettings
1118 unsigned int uMClkPostDiv; 1118 unsigned int uMClkPostDiv;
1119 struct pci_dev *dev; 1119 struct pci_dev *dev;
1120 1120
1121 dev = pci_find_slot(0, 3); 1121 dev = pci_get_bus_and_slot(0, 3);
1122 pci_read_config_dword(dev, 0x6C, &uMClkPostDiv); 1122 pci_read_config_dword(dev, 0x6C, &uMClkPostDiv);
1123 pci_dev_put(dev);
1123 uMClkPostDiv = (uMClkPostDiv >> 8) & 0xf; 1124 uMClkPostDiv = (uMClkPostDiv >> 8) & 0xf;
1124 1125
1125 if(!uMClkPostDiv) uMClkPostDiv = 4; 1126 if(!uMClkPostDiv) uMClkPostDiv = 4;
@@ -1132,8 +1133,9 @@ static void nForceUpdateArbitrationSettings
1132 sim_data.enable_video = 0; 1133 sim_data.enable_video = 0;
1133 sim_data.enable_mp = 0; 1134 sim_data.enable_mp = 0;
1134 1135
1135 dev = pci_find_slot(0, 1); 1136 dev = pci_get_bus_and_slot(0, 1);
1136 pci_read_config_dword(dev, 0x7C, &sim_data.memory_type); 1137 pci_read_config_dword(dev, 0x7C, &sim_data.memory_type);
1138 pci_dev_put(dev);
1137 sim_data.memory_type = (sim_data.memory_type >> 12) & 1; 1139 sim_data.memory_type = (sim_data.memory_type >> 12) & 1;
1138 1140
1139 sim_data.memory_width = 64; 1141 sim_data.memory_width = 64;
@@ -2112,12 +2114,14 @@ static void nv10GetConfig
2112 * Fill in chip configuration. 2114 * Fill in chip configuration.
2113 */ 2115 */
2114 if(chipset == NV_CHIP_IGEFORCE2) { 2116 if(chipset == NV_CHIP_IGEFORCE2) {
2115 dev = pci_find_slot(0, 1); 2117 dev = pci_get_bus_and_slot(0, 1);
2116 pci_read_config_dword(dev, 0x7C, &amt); 2118 pci_read_config_dword(dev, 0x7C, &amt);
2119 pci_dev_put(dev);
2117 chip->RamAmountKBytes = (((amt >> 6) & 31) + 1) * 1024; 2120 chip->RamAmountKBytes = (((amt >> 6) & 31) + 1) * 1024;
2118 } else if(chipset == NV_CHIP_0x01F0) { 2121 } else if(chipset == NV_CHIP_0x01F0) {
2119 dev = pci_find_slot(0, 1); 2122 dev = pci_get_bus_and_slot(0, 1);
2120 pci_read_config_dword(dev, 0x84, &amt); 2123 pci_read_config_dword(dev, 0x84, &amt);
2124 pci_dev_put(dev);
2121 chip->RamAmountKBytes = (((amt >> 4) & 127) + 1) * 1024; 2125 chip->RamAmountKBytes = (((amt >> 4) & 127) + 1) * 1024;
2122 } else { 2126 } else {
2123 switch ((NV_RD32(chip->PFB, 0x0000020C) >> 20) & 0x000000FF) 2127 switch ((NV_RD32(chip->PFB, 0x0000020C) >> 20) & 0x000000FF)
diff --git a/drivers/video/riva/rivafb-i2c.c b/drivers/video/riva/rivafb-i2c.c
index 0405e839ff93..76e6ce353c8e 100644
--- a/drivers/video/riva/rivafb-i2c.c
+++ b/drivers/video/riva/rivafb-i2c.c
@@ -88,13 +88,16 @@ static int riva_gpio_getsda(void* data)
88 return val; 88 return val;
89} 89}
90 90
91static int riva_setup_i2c_bus(struct riva_i2c_chan *chan, const char *name) 91static int __devinit riva_setup_i2c_bus(struct riva_i2c_chan *chan,
92 const char *name,
93 unsigned int i2c_class)
92{ 94{
93 int rc; 95 int rc;
94 96
95 strcpy(chan->adapter.name, name); 97 strcpy(chan->adapter.name, name);
96 chan->adapter.owner = THIS_MODULE; 98 chan->adapter.owner = THIS_MODULE;
97 chan->adapter.id = I2C_HW_B_RIVA; 99 chan->adapter.id = I2C_HW_B_RIVA;
100 chan->adapter.class = i2c_class;
98 chan->adapter.algo_data = &chan->algo; 101 chan->adapter.algo_data = &chan->algo;
99 chan->adapter.dev.parent = &chan->par->pdev->dev; 102 chan->adapter.dev.parent = &chan->par->pdev->dev;
100 chan->algo.setsda = riva_gpio_setsda; 103 chan->algo.setsda = riva_gpio_setsda;
@@ -124,42 +127,38 @@ static int riva_setup_i2c_bus(struct riva_i2c_chan *chan, const char *name)
124 return rc; 127 return rc;
125} 128}
126 129
127void riva_create_i2c_busses(struct riva_par *par) 130void __devinit riva_create_i2c_busses(struct riva_par *par)
128{ 131{
129 par->bus = 3;
130
131 par->chan[0].par = par; 132 par->chan[0].par = par;
132 par->chan[1].par = par; 133 par->chan[1].par = par;
133 par->chan[2].par = par; 134 par->chan[2].par = par;
134 135
135 par->chan[0].ddc_base = 0x3e; 136 par->chan[0].ddc_base = 0x36;
136 par->chan[1].ddc_base = 0x36; 137 par->chan[1].ddc_base = 0x3e;
137 par->chan[2].ddc_base = 0x50; 138 par->chan[2].ddc_base = 0x50;
138 riva_setup_i2c_bus(&par->chan[0], "BUS1"); 139 riva_setup_i2c_bus(&par->chan[0], "BUS1", I2C_CLASS_HWMON);
139 riva_setup_i2c_bus(&par->chan[1], "BUS2"); 140 riva_setup_i2c_bus(&par->chan[1], "BUS2", 0);
140 riva_setup_i2c_bus(&par->chan[2], "BUS3"); 141 riva_setup_i2c_bus(&par->chan[2], "BUS3", 0);
141} 142}
142 143
143void riva_delete_i2c_busses(struct riva_par *par) 144void riva_delete_i2c_busses(struct riva_par *par)
144{ 145{
145 if (par->chan[0].par) 146 int i;
146 i2c_del_adapter(&par->chan[0].adapter);
147 par->chan[0].par = NULL;
148
149 if (par->chan[1].par)
150 i2c_del_adapter(&par->chan[1].adapter);
151 par->chan[1].par = NULL;
152 147
153 if (par->chan[2].par) 148 for (i = 0; i < 3; i++) {
154 i2c_del_adapter(&par->chan[2].adapter); 149 if (!par->chan[i].par)
155 par->chan[2].par = NULL; 150 continue;
151 i2c_del_adapter(&par->chan[i].adapter);
152 par->chan[i].par = NULL;
153 }
156} 154}
157 155
158int riva_probe_i2c_connector(struct riva_par *par, int conn, u8 **out_edid) 156int __devinit riva_probe_i2c_connector(struct riva_par *par, int conn, u8 **out_edid)
159{ 157{
160 u8 *edid = NULL; 158 u8 *edid = NULL;
161 159
162 edid = fb_ddc_read(&par->chan[conn-1].adapter); 160 if (par->chan[conn].par)
161 edid = fb_ddc_read(&par->chan[conn].adapter);
163 162
164 if (out_edid) 163 if (out_edid)
165 *out_edid = edid; 164 *out_edid = edid;
diff --git a/drivers/video/riva/rivafb.h b/drivers/video/riva/rivafb.h
index 48ead6d72f24..d9f107b704c6 100644
--- a/drivers/video/riva/rivafb.h
+++ b/drivers/video/riva/rivafb.h
@@ -4,7 +4,6 @@
4#include <linux/fb.h> 4#include <linux/fb.h>
5#include <video/vga.h> 5#include <video/vga.h>
6#include <linux/i2c.h> 6#include <linux/i2c.h>
7#include <linux/i2c-id.h>
8#include <linux/i2c-algo-bit.h> 7#include <linux/i2c-algo-bit.h>
9 8
10#include "riva_hw.h" 9#include "riva_hw.h"
@@ -61,7 +60,6 @@ struct riva_par {
61 Bool SecondCRTC; 60 Bool SecondCRTC;
62 int FlatPanel; 61 int FlatPanel;
63 struct pci_dev *pdev; 62 struct pci_dev *pdev;
64 int bus;
65 int cursor_reset; 63 int cursor_reset;
66#ifdef CONFIG_MTRR 64#ifdef CONFIG_MTRR
67 struct { int vram; int vram_valid; } mtrr; 65 struct { int vram; int vram_valid; } mtrr;
diff --git a/drivers/video/s3fb.c b/drivers/video/s3fb.c
index 3091b20124b4..756fafb41d78 100644
--- a/drivers/video/s3fb.c
+++ b/drivers/video/s3fb.c
@@ -65,7 +65,7 @@ static const struct svga_fb_format s3fb_formats[] = {
65 65
66 66
67static const struct svga_pll s3_pll = {3, 129, 3, 33, 0, 3, 67static const struct svga_pll s3_pll = {3, 129, 3, 33, 0, 3,
68 60000, 240000, 14318}; 68 35000, 240000, 14318};
69 69
70static const int s3_memsizes[] = {4096, 0, 3072, 8192, 2048, 6144, 1024, 512}; 70static const int s3_memsizes[] = {4096, 0, 3072, 8192, 2048, 6144, 1024, 512};
71 71
@@ -164,7 +164,7 @@ MODULE_PARM_DESC(fasttext, "Enable S3 fast text mode (1=enable, 0=disable, defau
164static void s3fb_settile_fast(struct fb_info *info, struct fb_tilemap *map) 164static void s3fb_settile_fast(struct fb_info *info, struct fb_tilemap *map)
165{ 165{
166 const u8 *font = map->data; 166 const u8 *font = map->data;
167 u8* fb = (u8 *) info->screen_base; 167 u8 __iomem *fb = (u8 __iomem *) info->screen_base;
168 int i, c; 168 int i, c;
169 169
170 if ((map->width != 8) || (map->height != 16) || 170 if ((map->width != 8) || (map->height != 16) ||
@@ -177,20 +177,19 @@ static void s3fb_settile_fast(struct fb_info *info, struct fb_tilemap *map)
177 fb += 2; 177 fb += 2;
178 for (i = 0; i < map->height; i++) { 178 for (i = 0; i < map->height; i++) {
179 for (c = 0; c < map->length; c++) { 179 for (c = 0; c < map->length; c++) {
180 fb[c * 4] = font[c * map->height + i]; 180 fb_writeb(font[c * map->height + i], fb + c * 4);
181 } 181 }
182 fb += 1024; 182 fb += 1024;
183 } 183 }
184} 184}
185 185
186
187
188static struct fb_tile_ops s3fb_tile_ops = { 186static struct fb_tile_ops s3fb_tile_ops = {
189 .fb_settile = svga_settile, 187 .fb_settile = svga_settile,
190 .fb_tilecopy = svga_tilecopy, 188 .fb_tilecopy = svga_tilecopy,
191 .fb_tilefill = svga_tilefill, 189 .fb_tilefill = svga_tilefill,
192 .fb_tileblit = svga_tileblit, 190 .fb_tileblit = svga_tileblit,
193 .fb_tilecursor = svga_tilecursor, 191 .fb_tilecursor = svga_tilecursor,
192 .fb_get_tilemax = svga_get_tilemax,
194}; 193};
195 194
196static struct fb_tile_ops s3fb_fast_tile_ops = { 195static struct fb_tile_ops s3fb_fast_tile_ops = {
@@ -199,6 +198,7 @@ static struct fb_tile_ops s3fb_fast_tile_ops = {
199 .fb_tilefill = svga_tilefill, 198 .fb_tilefill = svga_tilefill,
200 .fb_tileblit = svga_tileblit, 199 .fb_tileblit = svga_tileblit,
201 .fb_tilecursor = svga_tilecursor, 200 .fb_tilecursor = svga_tilecursor,
201 .fb_get_tilemax = svga_get_tilemax,
202}; 202};
203 203
204 204
@@ -326,8 +326,13 @@ static void s3_set_pixclock(struct fb_info *info, u32 pixclock)
326{ 326{
327 u16 m, n, r; 327 u16 m, n, r;
328 u8 regval; 328 u8 regval;
329 int rv;
329 330
330 svga_compute_pll(&s3_pll, 1000000000 / pixclock, &m, &n, &r, info->node); 331 rv = svga_compute_pll(&s3_pll, 1000000000 / pixclock, &m, &n, &r, info->node);
332 if (rv < 0) {
333 printk(KERN_ERR "fb%d: cannot set requested pixclock, keeping old value\n", info->node);
334 return;
335 }
331 336
332 /* Set VGA misc register */ 337 /* Set VGA misc register */
333 regval = vga_r(NULL, VGA_MIS_R); 338 regval = vga_r(NULL, VGA_MIS_R);
@@ -449,6 +454,10 @@ static int s3fb_set_par(struct fb_info *info)
449 info->flags &= ~FBINFO_MISC_TILEBLITTING; 454 info->flags &= ~FBINFO_MISC_TILEBLITTING;
450 info->tileops = NULL; 455 info->tileops = NULL;
451 456
457 /* in 4bpp supports 8p wide tiles only, any tiles otherwise */
458 info->pixmap.blit_x = (bpp == 4) ? (1 << (8 - 1)) : (~(u32)0);
459 info->pixmap.blit_y = ~(u32)0;
460
452 offset_value = (info->var.xres_virtual * bpp) / 64; 461 offset_value = (info->var.xres_virtual * bpp) / 64;
453 screen_size = info->var.yres_virtual * info->fix.line_length; 462 screen_size = info->var.yres_virtual * info->fix.line_length;
454 } else { 463 } else {
@@ -458,6 +467,10 @@ static int s3fb_set_par(struct fb_info *info)
458 info->flags |= FBINFO_MISC_TILEBLITTING; 467 info->flags |= FBINFO_MISC_TILEBLITTING;
459 info->tileops = fasttext ? &s3fb_fast_tile_ops : &s3fb_tile_ops; 468 info->tileops = fasttext ? &s3fb_fast_tile_ops : &s3fb_tile_ops;
460 469
470 /* supports 8x16 tiles only */
471 info->pixmap.blit_x = 1 << (8 - 1);
472 info->pixmap.blit_y = 1 << (16 - 1);
473
461 offset_value = info->var.xres_virtual / 16; 474 offset_value = info->var.xres_virtual / 16;
462 screen_size = (info->var.xres_virtual * info->var.yres_virtual) / 64; 475 screen_size = (info->var.xres_virtual * info->var.yres_virtual) / 64;
463 } 476 }
@@ -656,7 +669,7 @@ static int s3fb_set_par(struct fb_info *info)
656 value = ((value * hmul) / 8) - 5; 669 value = ((value * hmul) / 8) - 5;
657 vga_wcrt(NULL, 0x3C, (value + 1) / 2); 670 vga_wcrt(NULL, 0x3C, (value + 1) / 2);
658 671
659 memset((u8*)info->screen_base, 0x00, screen_size); 672 memset_io(info->screen_base, 0x00, screen_size);
660 /* Device and screen back on */ 673 /* Device and screen back on */
661 svga_wcrt_mask(0x17, 0x80, 0x80); 674 svga_wcrt_mask(0x17, 0x80, 0x80);
662 svga_wseq_mask(0x01, 0x00, 0x20); 675 svga_wseq_mask(0x01, 0x00, 0x20);
@@ -699,7 +712,7 @@ static int s3fb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
699 break; 712 break;
700 case 16: 713 case 16:
701 if (regno >= 16) 714 if (regno >= 16)
702 return -EINVAL; 715 return 0;
703 716
704 if (fb->var.green.length == 5) 717 if (fb->var.green.length == 5)
705 ((u32*)fb->pseudo_palette)[regno] = ((red & 0xF800) >> 1) | 718 ((u32*)fb->pseudo_palette)[regno] = ((red & 0xF800) >> 1) |
@@ -712,9 +725,9 @@ static int s3fb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
712 case 24: 725 case 24:
713 case 32: 726 case 32:
714 if (regno >= 16) 727 if (regno >= 16)
715 return -EINVAL; 728 return 0;
716 729
717 ((u32*)fb->pseudo_palette)[regno] = ((transp & 0xFF00) << 16) | ((red & 0xFF00) << 8) | 730 ((u32*)fb->pseudo_palette)[regno] = ((red & 0xFF00) << 8) |
718 (green & 0xFF00) | ((blue & 0xFF00) >> 8); 731 (green & 0xFF00) | ((blue & 0xFF00) >> 8);
719 break; 732 break;
720 default: 733 default:
@@ -767,12 +780,6 @@ static int s3fb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info)
767 780
768 unsigned int offset; 781 unsigned int offset;
769 782
770 /* Validate the offsets */
771 if ((var->xoffset + var->xres) > var->xres_virtual)
772 return -EINVAL;
773 if ((var->yoffset + var->yres) > var->yres_virtual)
774 return -EINVAL;
775
776 /* Calculate the offset */ 783 /* Calculate the offset */
777 if (var->bits_per_pixel == 0) { 784 if (var->bits_per_pixel == 0) {
778 offset = (var->yoffset / 16) * (var->xres_virtual / 2) + (var->xoffset / 2); 785 offset = (var->yoffset / 16) * (var->xres_virtual / 2) + (var->xoffset / 2);
@@ -789,6 +796,23 @@ static int s3fb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info)
789 return 0; 796 return 0;
790} 797}
791 798
799/* Get capabilities of accelerator based on the mode */
800
801static void s3fb_get_caps(struct fb_info *info, struct fb_blit_caps *caps,
802 struct fb_var_screeninfo *var)
803{
804 if (var->bits_per_pixel == 0) {
805 /* can only support 256 8x16 bitmap */
806 caps->x = 1 << (8 - 1);
807 caps->y = 1 << (16 - 1);
808 caps->len = 256;
809 } else {
810 caps->x = ~(u32)0;
811 caps->y = ~(u32)0;
812 caps->len = ~(u32)0;
813 }
814}
815
792/* ------------------------------------------------------------------------- */ 816/* ------------------------------------------------------------------------- */
793 817
794/* Frame buffer operations */ 818/* Frame buffer operations */
@@ -805,6 +829,7 @@ static struct fb_ops s3fb_ops = {
805 .fb_fillrect = s3fb_fillrect, 829 .fb_fillrect = s3fb_fillrect,
806 .fb_copyarea = cfb_copyarea, 830 .fb_copyarea = cfb_copyarea,
807 .fb_imageblit = s3fb_imageblit, 831 .fb_imageblit = s3fb_imageblit,
832 .fb_get_caps = s3fb_get_caps,
808}; 833};
809 834
810/* ------------------------------------------------------------------------- */ 835/* ------------------------------------------------------------------------- */
@@ -1061,6 +1086,7 @@ static int s3_pci_resume(struct pci_dev* dev)
1061{ 1086{
1062 struct fb_info *info = pci_get_drvdata(dev); 1087 struct fb_info *info = pci_get_drvdata(dev);
1063 struct s3fb_info *par = info->par; 1088 struct s3fb_info *par = info->par;
1089 int err;
1064 1090
1065 dev_info(&(dev->dev), "resume\n"); 1091 dev_info(&(dev->dev), "resume\n");
1066 1092
@@ -1075,7 +1101,13 @@ static int s3_pci_resume(struct pci_dev* dev)
1075 1101
1076 pci_set_power_state(dev, PCI_D0); 1102 pci_set_power_state(dev, PCI_D0);
1077 pci_restore_state(dev); 1103 pci_restore_state(dev);
1078 pci_enable_device(dev); 1104 err = pci_enable_device(dev);
1105 if (err) {
1106 mutex_unlock(&(par->open_lock));
1107 release_console_sem();
1108 dev_err(&(dev->dev), "error %d enabling device for resume\n", err);
1109 return err;
1110 }
1079 pci_set_master(dev); 1111 pci_set_master(dev);
1080 1112
1081 s3fb_set_par(info); 1113 s3fb_set_par(info);
diff --git a/drivers/video/savage/savagefb-i2c.c b/drivers/video/savage/savagefb-i2c.c
index 8db066ccca6b..35c1ce62b216 100644
--- a/drivers/video/savage/savagefb-i2c.c
+++ b/drivers/video/savage/savagefb-i2c.c
@@ -41,10 +41,6 @@
41#define SAVAGE4_I2C_SCL_IN 0x00000008 41#define SAVAGE4_I2C_SCL_IN 0x00000008
42#define SAVAGE4_I2C_SDA_IN 0x00000010 42#define SAVAGE4_I2C_SDA_IN 0x00000010
43 43
44#define SET_CR_IX(base, val) writeb((val), base + 0x8000 + VGA_CR_IX)
45#define SET_CR_DATA(base, val) writeb((val), base + 0x8000 + VGA_CR_DATA)
46#define GET_CR_DATA(base) readb(base + 0x8000 + VGA_CR_DATA)
47
48static void savage4_gpio_setscl(void *data, int val) 44static void savage4_gpio_setscl(void *data, int val)
49{ 45{
50 struct savagefb_i2c_chan *chan = data; 46 struct savagefb_i2c_chan *chan = data;
@@ -92,15 +88,15 @@ static void prosavage_gpio_setscl(void* data, int val)
92 struct savagefb_i2c_chan *chan = data; 88 struct savagefb_i2c_chan *chan = data;
93 u32 r; 89 u32 r;
94 90
95 SET_CR_IX(chan->ioaddr, chan->reg); 91 r = VGArCR(chan->reg, chan->par);
96 r = GET_CR_DATA(chan->ioaddr);
97 r |= PROSAVAGE_I2C_ENAB; 92 r |= PROSAVAGE_I2C_ENAB;
98 if (val) { 93 if (val) {
99 r |= PROSAVAGE_I2C_SCL_OUT; 94 r |= PROSAVAGE_I2C_SCL_OUT;
100 } else { 95 } else {
101 r &= ~PROSAVAGE_I2C_SCL_OUT; 96 r &= ~PROSAVAGE_I2C_SCL_OUT;
102 } 97 }
103 SET_CR_DATA(chan->ioaddr, r); 98
99 VGAwCR(chan->reg, r, chan->par);
104} 100}
105 101
106static void prosavage_gpio_setsda(void* data, int val) 102static void prosavage_gpio_setsda(void* data, int val)
@@ -108,31 +104,29 @@ static void prosavage_gpio_setsda(void* data, int val)
108 struct savagefb_i2c_chan *chan = data; 104 struct savagefb_i2c_chan *chan = data;
109 unsigned int r; 105 unsigned int r;
110 106
111 SET_CR_IX(chan->ioaddr, chan->reg); 107 r = VGArCR(chan->reg, chan->par);
112 r = GET_CR_DATA(chan->ioaddr);
113 r |= PROSAVAGE_I2C_ENAB; 108 r |= PROSAVAGE_I2C_ENAB;
114 if (val) { 109 if (val) {
115 r |= PROSAVAGE_I2C_SDA_OUT; 110 r |= PROSAVAGE_I2C_SDA_OUT;
116 } else { 111 } else {
117 r &= ~PROSAVAGE_I2C_SDA_OUT; 112 r &= ~PROSAVAGE_I2C_SDA_OUT;
118 } 113 }
119 SET_CR_DATA(chan->ioaddr, r); 114
115 VGAwCR(chan->reg, r, chan->par);
120} 116}
121 117
122static int prosavage_gpio_getscl(void* data) 118static int prosavage_gpio_getscl(void* data)
123{ 119{
124 struct savagefb_i2c_chan *chan = data; 120 struct savagefb_i2c_chan *chan = data;
125 121
126 SET_CR_IX(chan->ioaddr, chan->reg); 122 return (VGArCR(chan->reg, chan->par) & PROSAVAGE_I2C_SCL_IN) ? 1 : 0;
127 return (0 != (GET_CR_DATA(chan->ioaddr) & PROSAVAGE_I2C_SCL_IN));
128} 123}
129 124
130static int prosavage_gpio_getsda(void* data) 125static int prosavage_gpio_getsda(void* data)
131{ 126{
132 struct savagefb_i2c_chan *chan = data; 127 struct savagefb_i2c_chan *chan = data;
133 128
134 SET_CR_IX(chan->ioaddr, chan->reg); 129 return (VGArCR(chan->reg, chan->par) & PROSAVAGE_I2C_SDA_IN) ? 1 : 0;
135 return (0 != (GET_CR_DATA(chan->ioaddr) & PROSAVAGE_I2C_SDA_IN));
136} 130}
137 131
138static int savage_setup_i2c_bus(struct savagefb_i2c_chan *chan, 132static int savage_setup_i2c_bus(struct savagefb_i2c_chan *chan,
diff --git a/drivers/video/savage/savagefb.h b/drivers/video/savage/savagefb.h
index e648a6c0f6d9..8bfdfc3c5234 100644
--- a/drivers/video/savage/savagefb.h
+++ b/drivers/video/savage/savagefb.h
@@ -15,6 +15,8 @@
15#include <linux/i2c.h> 15#include <linux/i2c.h>
16#include <linux/i2c-id.h> 16#include <linux/i2c-id.h>
17#include <linux/i2c-algo-bit.h> 17#include <linux/i2c-algo-bit.h>
18#include <linux/mutex.h>
19#include <video/vga.h>
18#include "../edid.h" 20#include "../edid.h"
19 21
20#ifdef SAVAGEFB_DEBUG 22#ifdef SAVAGEFB_DEBUG
@@ -189,8 +191,12 @@ struct savagefb_par {
189 struct savagefb_i2c_chan chan; 191 struct savagefb_i2c_chan chan;
190 struct savage_reg state; 192 struct savage_reg state;
191 struct savage_reg save; 193 struct savage_reg save;
194 struct savage_reg initial;
195 struct vgastate vgastate;
196 struct mutex open_lock;
192 unsigned char *edid; 197 unsigned char *edid;
193 u32 pseudo_palette[16]; 198 u32 pseudo_palette[16];
199 u32 open_count;
194 int paletteEnabled; 200 int paletteEnabled;
195 int pm_state; 201 int pm_state;
196 int display_type; 202 int display_type;
@@ -203,7 +209,7 @@ struct savagefb_par {
203 int clock[4]; 209 int clock[4];
204 int MCLK, REFCLK, LCDclk; 210 int MCLK, REFCLK, LCDclk;
205 struct { 211 struct {
206 u8 __iomem *vbase; 212 void __iomem *vbase;
207 u32 pbase; 213 u32 pbase;
208 u32 len; 214 u32 len;
209#ifdef CONFIG_MTRR 215#ifdef CONFIG_MTRR
@@ -212,7 +218,7 @@ struct savagefb_par {
212 } video; 218 } video;
213 219
214 struct { 220 struct {
215 volatile u8 __iomem *vbase; 221 void __iomem *vbase;
216 u32 pbase; 222 u32 pbase;
217 u32 len; 223 u32 len;
218 } mmio; 224 } mmio;
diff --git a/drivers/video/savage/savagefb_driver.c b/drivers/video/savage/savagefb_driver.c
index 0166ec2ccf32..3d7507ad55f6 100644
--- a/drivers/video/savage/savagefb_driver.c
+++ b/drivers/video/savage/savagefb_driver.c
@@ -1623,8 +1623,46 @@ static void savagefb_restore_state(struct fb_info *info)
1623 savagefb_blank(FB_BLANK_UNBLANK, info); 1623 savagefb_blank(FB_BLANK_UNBLANK, info);
1624} 1624}
1625 1625
1626static int savagefb_open(struct fb_info *info, int user)
1627{
1628 struct savagefb_par *par = info->par;
1629
1630 mutex_lock(&par->open_lock);
1631
1632 if (!par->open_count) {
1633 memset(&par->vgastate, 0, sizeof(par->vgastate));
1634 par->vgastate.flags = VGA_SAVE_CMAP | VGA_SAVE_FONTS |
1635 VGA_SAVE_MODE;
1636 par->vgastate.vgabase = par->mmio.vbase + 0x8000;
1637 save_vga(&par->vgastate);
1638 savage_get_default_par(par, &par->initial);
1639 }
1640
1641 par->open_count++;
1642 mutex_unlock(&par->open_lock);
1643 return 0;
1644}
1645
1646static int savagefb_release(struct fb_info *info, int user)
1647{
1648 struct savagefb_par *par = info->par;
1649
1650 mutex_lock(&par->open_lock);
1651
1652 if (par->open_count == 1) {
1653 savage_set_default_par(par, &par->initial);
1654 restore_vga(&par->vgastate);
1655 }
1656
1657 par->open_count--;
1658 mutex_unlock(&par->open_lock);
1659 return 0;
1660}
1661
1626static struct fb_ops savagefb_ops = { 1662static struct fb_ops savagefb_ops = {
1627 .owner = THIS_MODULE, 1663 .owner = THIS_MODULE,
1664 .fb_open = savagefb_open,
1665 .fb_release = savagefb_release,
1628 .fb_check_var = savagefb_check_var, 1666 .fb_check_var = savagefb_check_var,
1629 .fb_set_par = savagefb_set_par, 1667 .fb_set_par = savagefb_set_par,
1630 .fb_setcolreg = savagefb_setcolreg, 1668 .fb_setcolreg = savagefb_setcolreg,
@@ -2173,6 +2211,7 @@ static int __devinit savagefb_probe(struct pci_dev* dev,
2173 if (!info) 2211 if (!info)
2174 return -ENOMEM; 2212 return -ENOMEM;
2175 par = info->par; 2213 par = info->par;
2214 mutex_init(&par->open_lock);
2176 err = pci_enable_device(dev); 2215 err = pci_enable_device(dev);
2177 if (err) 2216 if (err)
2178 goto failed_enable; 2217 goto failed_enable;
diff --git a/drivers/video/sis/osdef.h b/drivers/video/sis/osdef.h
index d048bd39961b..c1492782cb18 100644
--- a/drivers/video/sis/osdef.h
+++ b/drivers/video/sis/osdef.h
@@ -58,9 +58,6 @@
58#define SIS_LINUX_KERNEL /* Linux kernel framebuffer */ 58#define SIS_LINUX_KERNEL /* Linux kernel framebuffer */
59#undef SIS_XORG_XF86 /* XFree86/X.org */ 59#undef SIS_XORG_XF86 /* XFree86/X.org */
60 60
61#undef SIS_LINUX_KERNEL_24
62#undef SIS_LINUX_KERNEL_26
63
64#ifdef OutPortByte 61#ifdef OutPortByte
65#undef OutPortByte 62#undef OutPortByte
66#endif 63#endif
@@ -100,8 +97,6 @@
100#define SIS315H 97#define SIS315H
101#endif 98#endif
102 99
103#define SIS_LINUX_KERNEL_26
104
105#if !defined(SIS300) && !defined(SIS315H) 100#if !defined(SIS300) && !defined(SIS315H)
106#warning Neither CONFIG_FB_SIS_300 nor CONFIG_FB_SIS_315 is set 101#warning Neither CONFIG_FB_SIS_300 nor CONFIG_FB_SIS_315 is set
107#warning sisfb will not work! 102#warning sisfb will not work!
diff --git a/drivers/video/sis/sis.h b/drivers/video/sis/sis.h
index 7d5ee2145e21..d5e2d9c27847 100644
--- a/drivers/video/sis/sis.h
+++ b/drivers/video/sis/sis.h
@@ -27,11 +27,7 @@
27#include <linux/version.h> 27#include <linux/version.h>
28 28
29#include "osdef.h" 29#include "osdef.h"
30#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
31#include <video/sisfb.h> 30#include <video/sisfb.h>
32#else
33#include <linux/sisfb.h>
34#endif
35 31
36#include "vgatypes.h" 32#include "vgatypes.h"
37#include "vstruct.h" 33#include "vstruct.h"
@@ -40,33 +36,17 @@
40#define VER_MINOR 8 36#define VER_MINOR 8
41#define VER_LEVEL 9 37#define VER_LEVEL 9
42 38
43#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
44#include <linux/spinlock.h> 39#include <linux/spinlock.h>
45#define SIS_PCI_GET_CLASS(a, b) pci_get_class(a, b) 40
46#define SIS_PCI_GET_DEVICE(a,b,c) pci_get_device(a,b,c)
47#define SIS_PCI_GET_SLOT(a,b) pci_get_slot(a,b)
48#define SIS_PCI_PUT_DEVICE(a) pci_dev_put(a)
49#ifdef CONFIG_COMPAT 41#ifdef CONFIG_COMPAT
50#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,10) 42#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,10)
51#include <linux/ioctl32.h> 43#include <linux/ioctl32.h>
52#define SIS_OLD_CONFIG_COMPAT 44#define SIS_OLD_CONFIG_COMPAT
53#else 45#else
54#include <linux/smp_lock.h>
55#define SIS_NEW_CONFIG_COMPAT 46#define SIS_NEW_CONFIG_COMPAT
56#endif 47#endif
57#endif /* CONFIG_COMPAT */ 48#endif /* CONFIG_COMPAT */
58#else /* 2.4 */ 49
59#define SIS_PCI_GET_CLASS(a, b) pci_find_class(a, b)
60#define SIS_PCI_GET_DEVICE(a,b,c) pci_find_device(a,b,c)
61#define SIS_PCI_GET_SLOT(a,b) pci_find_slot(a,b)
62#define SIS_PCI_PUT_DEVICE(a)
63#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,19)
64#ifdef __x86_64__ /* Shouldn't we check for CONFIG_IA32_EMULATION here? */
65#include <asm/ioctl32.h>
66#define SIS_OLD_CONFIG_COMPAT
67#endif
68#endif
69#endif /* 2.4 */
70#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,8) 50#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,8)
71#define SIS_IOTYPE1 void __iomem 51#define SIS_IOTYPE1 void __iomem
72#define SIS_IOTYPE2 __iomem 52#define SIS_IOTYPE2 __iomem
@@ -498,26 +478,8 @@ struct sis_video_info {
498 478
499 struct fb_var_screeninfo default_var; 479 struct fb_var_screeninfo default_var;
500 480
501#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
502 struct fb_fix_screeninfo sisfb_fix; 481 struct fb_fix_screeninfo sisfb_fix;
503 u32 pseudo_palette[17]; 482 u32 pseudo_palette[17];
504#endif
505
506#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
507 struct display sis_disp;
508 struct display_switch sisfb_sw;
509 struct {
510 u16 red, green, blue, pad;
511 } sis_palette[256];
512 union {
513#ifdef FBCON_HAS_CFB16
514 u16 cfb16[16];
515#endif
516#ifdef FBCON_HAS_CFB32
517 u32 cfb32[16];
518#endif
519 } sis_fbcon_cmap;
520#endif
521 483
522 struct sisfb_monitor { 484 struct sisfb_monitor {
523 u16 hmin; 485 u16 hmin;
@@ -538,10 +500,6 @@ struct sis_video_info {
538 500
539 int mni; /* Mode number index */ 501 int mni; /* Mode number index */
540 502
541#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
542 int currcon;
543#endif
544
545 unsigned long video_size; 503 unsigned long video_size;
546 unsigned long video_base; 504 unsigned long video_base;
547 unsigned long mmio_size; 505 unsigned long mmio_size;
@@ -578,9 +536,6 @@ struct sis_video_info {
578 int sisfb_tvplug; 536 int sisfb_tvplug;
579 int sisfb_tvstd; 537 int sisfb_tvstd;
580 int sisfb_nocrt2rate; 538 int sisfb_nocrt2rate;
581#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
582 int sisfb_inverse;
583#endif
584 539
585 u32 heapstart; /* offset */ 540 u32 heapstart; /* offset */
586 SIS_IOTYPE1 *sisfb_heap_start; /* address */ 541 SIS_IOTYPE1 *sisfb_heap_start; /* address */
@@ -646,9 +601,7 @@ struct sis_video_info {
646 int modechanged; 601 int modechanged;
647 unsigned char modeprechange; 602 unsigned char modeprechange;
648 603
649#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
650 u8 sisfb_lastrates[128]; 604 u8 sisfb_lastrates[128];
651#endif
652 605
653 int newrom; 606 int newrom;
654 int haveXGIROM; 607 int haveXGIROM;
diff --git a/drivers/video/sis/sis_main.c b/drivers/video/sis/sis_main.c
index 01197d740217..a30e1e13d8be 100644
--- a/drivers/video/sis/sis_main.c
+++ b/drivers/video/sis/sis_main.c
@@ -37,7 +37,6 @@
37#include <linux/module.h> 37#include <linux/module.h>
38#include <linux/moduleparam.h> 38#include <linux/moduleparam.h>
39#include <linux/kernel.h> 39#include <linux/kernel.h>
40#include <linux/smp_lock.h>
41#include <linux/spinlock.h> 40#include <linux/spinlock.h>
42#include <linux/errno.h> 41#include <linux/errno.h>
43#include <linux/string.h> 42#include <linux/string.h>
@@ -1948,7 +1947,7 @@ sisfb_get_northbridge(int basechipid)
1948 default: return NULL; 1947 default: return NULL;
1949 } 1948 }
1950 for(i = 0; i < nbridgenum; i++) { 1949 for(i = 0; i < nbridgenum; i++) {
1951 if((pdev = SIS_PCI_GET_DEVICE(PCI_VENDOR_ID_SI, 1950 if((pdev = pci_get_device(PCI_VENDOR_ID_SI,
1952 nbridgeids[nbridgeidx+i], NULL))) 1951 nbridgeids[nbridgeidx+i], NULL)))
1953 break; 1952 break;
1954 } 1953 }
@@ -4613,9 +4612,9 @@ sisfb_find_host_bridge(struct sis_video_info *ivideo, struct pci_dev *mypdev,
4613 unsigned short temp; 4612 unsigned short temp;
4614 int ret = 0; 4613 int ret = 0;
4615 4614
4616 while((pdev = SIS_PCI_GET_CLASS(PCI_CLASS_BRIDGE_HOST, pdev))) { 4615 while((pdev = pci_get_class(PCI_CLASS_BRIDGE_HOST, pdev))) {
4617 temp = pdev->vendor; 4616 temp = pdev->vendor;
4618 SIS_PCI_PUT_DEVICE(pdev); 4617 pci_dev_put(pdev);
4619 if(temp == pcivendor) { 4618 if(temp == pcivendor) {
4620 ret = 1; 4619 ret = 1;
4621 break; 4620 break;
@@ -5154,24 +5153,24 @@ sisfb_post_xgi(struct pci_dev *pdev)
5154 if(reg & 0x80) v2 |= 0x80; 5153 if(reg & 0x80) v2 |= 0x80;
5155 v2 |= 0x01; 5154 v2 |= 0x01;
5156 5155
5157 if((mypdev = SIS_PCI_GET_DEVICE(PCI_VENDOR_ID_SI, 0x0730, NULL))) { 5156 if((mypdev = pci_get_device(PCI_VENDOR_ID_SI, 0x0730, NULL))) {
5158 SIS_PCI_PUT_DEVICE(mypdev); 5157 pci_dev_put(mypdev);
5159 if(((v2 & 0x06) == 2) || ((v2 & 0x06) == 4)) 5158 if(((v2 & 0x06) == 2) || ((v2 & 0x06) == 4))
5160 v2 &= 0xf9; 5159 v2 &= 0xf9;
5161 v2 |= 0x08; 5160 v2 |= 0x08;
5162 v1 &= 0xfe; 5161 v1 &= 0xfe;
5163 } else { 5162 } else {
5164 mypdev = SIS_PCI_GET_DEVICE(PCI_VENDOR_ID_SI, 0x0735, NULL); 5163 mypdev = pci_get_device(PCI_VENDOR_ID_SI, 0x0735, NULL);
5165 if(!mypdev) 5164 if(!mypdev)
5166 mypdev = SIS_PCI_GET_DEVICE(PCI_VENDOR_ID_SI, 0x0645, NULL); 5165 mypdev = pci_get_device(PCI_VENDOR_ID_SI, 0x0645, NULL);
5167 if(!mypdev) 5166 if(!mypdev)
5168 mypdev = SIS_PCI_GET_DEVICE(PCI_VENDOR_ID_SI, 0x0650, NULL); 5167 mypdev = pci_get_device(PCI_VENDOR_ID_SI, 0x0650, NULL);
5169 if(mypdev) { 5168 if(mypdev) {
5170 pci_read_config_dword(mypdev, 0x94, &regd); 5169 pci_read_config_dword(mypdev, 0x94, &regd);
5171 regd &= 0xfffffeff; 5170 regd &= 0xfffffeff;
5172 pci_write_config_dword(mypdev, 0x94, regd); 5171 pci_write_config_dword(mypdev, 0x94, regd);
5173 v1 &= 0xfe; 5172 v1 &= 0xfe;
5174 SIS_PCI_PUT_DEVICE(mypdev); 5173 pci_dev_put(mypdev);
5175 } else if(sisfb_find_host_bridge(ivideo, pdev, PCI_VENDOR_ID_SI)) { 5174 } else if(sisfb_find_host_bridge(ivideo, pdev, PCI_VENDOR_ID_SI)) {
5176 v1 &= 0xfe; 5175 v1 &= 0xfe;
5177 } else if(sisfb_find_host_bridge(ivideo, pdev, 0x1106) || 5176 } else if(sisfb_find_host_bridge(ivideo, pdev, 0x1106) ||
@@ -5194,13 +5193,13 @@ sisfb_post_xgi(struct pci_dev *pdev)
5194 if( (!(v1 & 0x02)) && (v2 & 0x30) && (regd < 0xcf) ) 5193 if( (!(v1 & 0x02)) && (v2 & 0x30) && (regd < 0xcf) )
5195 setSISIDXREG(SISCR, 0x5f, 0xf1, 0x01); 5194 setSISIDXREG(SISCR, 0x5f, 0xf1, 0x01);
5196 5195
5197 if((mypdev = SIS_PCI_GET_DEVICE(0x10de, 0x01e0, NULL))) { 5196 if((mypdev = pci_get_device(0x10de, 0x01e0, NULL))) {
5198 /* TODO: set CR5f &0xf1 | 0x01 for version 6570 5197 /* TODO: set CR5f &0xf1 | 0x01 for version 6570
5199 * of nforce 2 ROM 5198 * of nforce 2 ROM
5200 */ 5199 */
5201 if(0) 5200 if(0)
5202 setSISIDXREG(SISCR, 0x5f, 0xf1, 0x01); 5201 setSISIDXREG(SISCR, 0x5f, 0xf1, 0x01);
5203 SIS_PCI_PUT_DEVICE(mypdev); 5202 pci_dev_put(mypdev);
5204 } 5203 }
5205 } 5204 }
5206 5205
@@ -5236,9 +5235,9 @@ sisfb_post_xgi(struct pci_dev *pdev)
5236 setSISIDXREG(SISCR, 0x75, 0xe0, bios[0x4ff] & 0x1f); 5235 setSISIDXREG(SISCR, 0x75, 0xe0, bios[0x4ff] & 0x1f);
5237 setSISIDXREG(SISCR, 0x76, 0xe0, bios[0x500] & 0x1f); 5236 setSISIDXREG(SISCR, 0x76, 0xe0, bios[0x500] & 0x1f);
5238 v1 = bios[0x501]; 5237 v1 = bios[0x501];
5239 if((mypdev = SIS_PCI_GET_DEVICE(0x8086, 0x2530, NULL))) { 5238 if((mypdev = pci_get_device(0x8086, 0x2530, NULL))) {
5240 v1 = 0xf0; 5239 v1 = 0xf0;
5241 SIS_PCI_PUT_DEVICE(mypdev); 5240 pci_dev_put(mypdev);
5242 } 5241 }
5243 outSISIDXREG(SISCR, 0x77, v1); 5242 outSISIDXREG(SISCR, 0x77, v1);
5244 } 5243 }
@@ -5947,7 +5946,7 @@ sisfb_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
5947 5946
5948 if(!ivideo->sisvga_enabled) { 5947 if(!ivideo->sisvga_enabled) {
5949 if(pci_enable_device(pdev)) { 5948 if(pci_enable_device(pdev)) {
5950 if(ivideo->nbridge) SIS_PCI_PUT_DEVICE(ivideo->nbridge); 5949 if(ivideo->nbridge) pci_dev_put(ivideo->nbridge);
5951 pci_set_drvdata(pdev, NULL); 5950 pci_set_drvdata(pdev, NULL);
5952 kfree(sis_fb_info); 5951 kfree(sis_fb_info);
5953 return -EIO; 5952 return -EIO;
@@ -5974,7 +5973,7 @@ sisfb_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
5974 "requiring Chrontel/GPIO setup\n", 5973 "requiring Chrontel/GPIO setup\n",
5975 mychswtable[i].vendorName, 5974 mychswtable[i].vendorName,
5976 mychswtable[i].cardName); 5975 mychswtable[i].cardName);
5977 ivideo->lpcdev = SIS_PCI_GET_DEVICE(PCI_VENDOR_ID_SI, 0x0008, NULL); 5976 ivideo->lpcdev = pci_get_device(PCI_VENDOR_ID_SI, 0x0008, NULL);
5978 break; 5977 break;
5979 } 5978 }
5980 i++; 5979 i++;
@@ -5984,7 +5983,7 @@ sisfb_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
5984 5983
5985#ifdef CONFIG_FB_SIS_315 5984#ifdef CONFIG_FB_SIS_315
5986 if((ivideo->chip == SIS_760) && (ivideo->nbridge)) { 5985 if((ivideo->chip == SIS_760) && (ivideo->nbridge)) {
5987 ivideo->lpcdev = SIS_PCI_GET_SLOT(ivideo->nbridge->bus, (2 << 3)); 5986 ivideo->lpcdev = pci_get_slot(ivideo->nbridge->bus, (2 << 3));
5988 } 5987 }
5989#endif 5988#endif
5990 5989
@@ -6149,9 +6148,9 @@ error_1: release_mem_region(ivideo->video_base, ivideo->video_size);
6149error_2: release_mem_region(ivideo->mmio_base, ivideo->mmio_size); 6148error_2: release_mem_region(ivideo->mmio_base, ivideo->mmio_size);
6150error_3: vfree(ivideo->bios_abase); 6149error_3: vfree(ivideo->bios_abase);
6151 if(ivideo->lpcdev) 6150 if(ivideo->lpcdev)
6152 SIS_PCI_PUT_DEVICE(ivideo->lpcdev); 6151 pci_dev_put(ivideo->lpcdev);
6153 if(ivideo->nbridge) 6152 if(ivideo->nbridge)
6154 SIS_PCI_PUT_DEVICE(ivideo->nbridge); 6153 pci_dev_put(ivideo->nbridge);
6155 pci_set_drvdata(pdev, NULL); 6154 pci_set_drvdata(pdev, NULL);
6156 if(!ivideo->sisvga_enabled) 6155 if(!ivideo->sisvga_enabled)
6157 pci_disable_device(pdev); 6156 pci_disable_device(pdev);
@@ -6331,70 +6330,6 @@ error_3: vfree(ivideo->bios_abase);
6331 6330
6332 sisfb_set_vparms(ivideo); 6331 sisfb_set_vparms(ivideo);
6333 6332
6334#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
6335
6336 /* ---------------- For 2.4: Now switch the mode ------------------ */
6337
6338 printk(KERN_INFO "sisfb: Setting mode %dx%dx%d (%dHz)\n",
6339 ivideo->video_width, ivideo->video_height, ivideo->video_bpp,
6340 ivideo->refresh_rate);
6341
6342 /* Determine whether or not acceleration is to be
6343 * used. Need to know before pre/post_set_mode()
6344 */
6345 ivideo->accel = 0;
6346 ivideo->default_var.accel_flags &= ~FB_ACCELF_TEXT;
6347 if(ivideo->sisfb_accel) {
6348 ivideo->accel = -1;
6349 ivideo->default_var.accel_flags |= FB_ACCELF_TEXT;
6350 }
6351
6352 /* Now switch the mode */
6353 sisfb_pre_setmode(ivideo);
6354
6355 if(SiSSetMode(&ivideo->SiS_Pr, ivideo->mode_no) == 0) {
6356 printk(KERN_ERR "sisfb: Fatal error: Setting mode[0x%x] failed\n",
6357 ivideo->mode_no);
6358 ret = -EINVAL;
6359 iounmap(ivideo->mmio_vbase);
6360 goto error_0;
6361 }
6362
6363 outSISIDXREG(SISSR, IND_SIS_PASSWORD, SIS_PASSWORD);
6364
6365 sisfb_post_setmode(ivideo);
6366
6367 /* Maximize regardless of sisfb_max at startup */
6368 ivideo->default_var.yres_virtual = 32767;
6369
6370 /* Force reset of x virtual in crtc_to_var */
6371 ivideo->default_var.xres_virtual = 0;
6372
6373 /* Copy mode timing to var */
6374 sisfb_crtc_to_var(ivideo, &ivideo->default_var);
6375
6376 /* Find out about screen pitch */
6377 sisfb_calc_pitch(ivideo, &ivideo->default_var);
6378 sisfb_set_pitch(ivideo);
6379
6380 /* Init the accelerator (does nothing currently) */
6381 sisfb_initaccel(ivideo);
6382
6383 /* Init some fbinfo entries */
6384 sis_fb_info->node = -1;
6385 sis_fb_info->flags = FBINFO_FLAG_DEFAULT;
6386 sis_fb_info->fbops = &sisfb_ops;
6387 sis_fb_info->disp = &ivideo->sis_disp;
6388 sis_fb_info->blank = &sisfb_blank;
6389 sis_fb_info->switch_con = &sisfb_switch;
6390 sis_fb_info->updatevar = &sisfb_update_var;
6391 sis_fb_info->changevar = NULL;
6392 strcpy(sis_fb_info->fontname, sisfb_fontname);
6393
6394 sisfb_set_disp(-1, &ivideo->default_var, sis_fb_info);
6395
6396#else /* --------- For 2.6: Setup a somewhat sane default var ------------ */
6397
6398 printk(KERN_INFO "sisfb: Default mode is %dx%dx%d (%dHz)\n", 6333 printk(KERN_INFO "sisfb: Default mode is %dx%dx%d (%dHz)\n",
6399 ivideo->video_width, ivideo->video_height, ivideo->video_bpp, 6334 ivideo->video_width, ivideo->video_height, ivideo->video_bpp,
6400 ivideo->refresh_rate); 6335 ivideo->refresh_rate);
@@ -6454,7 +6389,6 @@ error_3: vfree(ivideo->bios_abase);
6454 sis_fb_info->pseudo_palette = ivideo->pseudo_palette; 6389 sis_fb_info->pseudo_palette = ivideo->pseudo_palette;
6455 6390
6456 fb_alloc_cmap(&sis_fb_info->cmap, 256 , 0); 6391 fb_alloc_cmap(&sis_fb_info->cmap, 256 , 0);
6457#endif /* 2.6 */
6458 6392
6459 printk(KERN_DEBUG "sisfb: Initial vbflags 0x%x\n", (int)ivideo->vbflags); 6393 printk(KERN_DEBUG "sisfb: Initial vbflags 0x%x\n", (int)ivideo->vbflags);
6460 6394
@@ -6564,10 +6498,10 @@ static void __devexit sisfb_remove(struct pci_dev *pdev)
6564 vfree(ivideo->bios_abase); 6498 vfree(ivideo->bios_abase);
6565 6499
6566 if(ivideo->lpcdev) 6500 if(ivideo->lpcdev)
6567 SIS_PCI_PUT_DEVICE(ivideo->lpcdev); 6501 pci_dev_put(ivideo->lpcdev);
6568 6502
6569 if(ivideo->nbridge) 6503 if(ivideo->nbridge)
6570 SIS_PCI_PUT_DEVICE(ivideo->nbridge); 6504 pci_dev_put(ivideo->nbridge);
6571 6505
6572#ifdef CONFIG_MTRR 6506#ifdef CONFIG_MTRR
6573 /* Release MTRR region */ 6507 /* Release MTRR region */
diff --git a/drivers/video/skeletonfb.c b/drivers/video/skeletonfb.c
index bb96cb65fdaa..842b5cd054c6 100644
--- a/drivers/video/skeletonfb.c
+++ b/drivers/video/skeletonfb.c
@@ -51,6 +51,7 @@
51#include <linux/delay.h> 51#include <linux/delay.h>
52#include <linux/fb.h> 52#include <linux/fb.h>
53#include <linux/init.h> 53#include <linux/init.h>
54#include <linux/pci.h>
54 55
55 /* 56 /*
56 * This is just simple sample code. 57 * This is just simple sample code.
@@ -60,6 +61,11 @@
60 */ 61 */
61 62
62/* 63/*
64 * Driver data
65 */
66static char *mode_option __devinitdata;
67
68/*
63 * If your driver supports multiple boards, you should make the 69 * If your driver supports multiple boards, you should make the
64 * below data types arrays, or allocate them dynamically (using kmalloc()). 70 * below data types arrays, or allocate them dynamically (using kmalloc()).
65 */ 71 */
@@ -78,7 +84,7 @@ struct xxx_par;
78 * if we don't use modedb. If we do use modedb see xxxfb_init how to use it 84 * if we don't use modedb. If we do use modedb see xxxfb_init how to use it
79 * to get a fb_var_screeninfo. Otherwise define a default var as well. 85 * to get a fb_var_screeninfo. Otherwise define a default var as well.
80 */ 86 */
81static struct fb_fix_screeninfo xxxfb_fix __initdata = { 87static struct fb_fix_screeninfo xxxfb_fix __devinitdata = {
82 .id = "FB's name", 88 .id = "FB's name",
83 .type = FB_TYPE_PACKED_PIXELS, 89 .type = FB_TYPE_PACKED_PIXELS,
84 .visual = FB_VISUAL_PSEUDOCOLOR, 90 .visual = FB_VISUAL_PSEUDOCOLOR,
@@ -142,7 +148,7 @@ int xxxfb_setup(char*);
142 * 148 *
143 * Returns negative errno on error, or zero on success. 149 * Returns negative errno on error, or zero on success.
144 */ 150 */
145static int xxxfb_open(const struct fb_info *info, int user) 151static int xxxfb_open(struct fb_info *info, int user)
146{ 152{
147 return 0; 153 return 0;
148} 154}
@@ -161,7 +167,7 @@ static int xxxfb_open(const struct fb_info *info, int user)
161 * 167 *
162 * Returns negative errno on error, or zero on success. 168 * Returns negative errno on error, or zero on success.
163 */ 169 */
164static int xxxfb_release(const struct fb_info *info, int user) 170static int xxxfb_release(struct fb_info *info, int user)
165{ 171{
166 return 0; 172 return 0;
167} 173}
@@ -278,7 +284,7 @@ static int xxxfb_set_par(struct fb_info *info)
278 */ 284 */
279static int xxxfb_setcolreg(unsigned regno, unsigned red, unsigned green, 285static int xxxfb_setcolreg(unsigned regno, unsigned red, unsigned green,
280 unsigned blue, unsigned transp, 286 unsigned blue, unsigned transp,
281 const struct fb_info *info) 287 struct fb_info *info)
282{ 288{
283 if (regno >= 256) /* no. of hw registers */ 289 if (regno >= 256) /* no. of hw registers */
284 return -EINVAL; 290 return -EINVAL;
@@ -416,7 +422,7 @@ static int xxxfb_setcolreg(unsigned regno, unsigned red, unsigned green,
416 * Returns negative errno on error, or zero on success. 422 * Returns negative errno on error, or zero on success.
417 */ 423 */
418static int xxxfb_pan_display(struct fb_var_screeninfo *var, 424static int xxxfb_pan_display(struct fb_var_screeninfo *var,
419 const struct fb_info *info) 425 struct fb_info *info)
420{ 426{
421 /* 427 /*
422 * If your hardware does not support panning, _do_ _not_ implement this 428 * If your hardware does not support panning, _do_ _not_ implement this
@@ -454,7 +460,7 @@ static int xxxfb_pan_display(struct fb_var_screeninfo *var,
454 * Return !0 for any modes that are unimplemented. 460 * Return !0 for any modes that are unimplemented.
455 * 461 *
456 */ 462 */
457static int xxxfb_blank(int blank_mode, const struct fb_info *info) 463static int xxxfb_blank(int blank_mode, struct fb_info *info)
458{ 464{
459 /* ... */ 465 /* ... */
460 return 0; 466 return 0;
@@ -483,7 +489,7 @@ static int xxxfb_blank(int blank_mode, const struct fb_info *info)
483 * depending on the rastering operation with the value of color which 489 * depending on the rastering operation with the value of color which
484 * is in the current color depth format. 490 * is in the current color depth format.
485 */ 491 */
486void xxfb_fillrect(struct fb_info *p, const struct fb_fillrect *region) 492void xxxfb_fillrect(struct fb_info *p, const struct fb_fillrect *region)
487{ 493{
488/* Meaning of struct fb_fillrect 494/* Meaning of struct fb_fillrect
489 * 495 *
@@ -623,19 +629,6 @@ void xxxfb_rotate(struct fb_info *info, int angle)
623} 629}
624 630
625/** 631/**
626 * xxxfb_poll - NOT a required function. The purpose of this
627 * function is to provide a way for some process
628 * to wait until a specific hardware event occurs
629 * for the framebuffer device.
630 *
631 * @info: frame buffer structure that represents a single frame buffer
632 * @wait: poll table where we store process that await a event.
633 */
634void xxxfb_poll(struct fb_info *info, poll_table *wait)
635{
636}
637
638/**
639 * xxxfb_sync - NOT a required function. Normally the accel engine 632 * xxxfb_sync - NOT a required function. Normally the accel engine
640 * for a graphics card take a specific amount of time. 633 * for a graphics card take a specific amount of time.
641 * Often we have to wait for the accelerator to finish 634 * Often we have to wait for the accelerator to finish
@@ -647,21 +640,49 @@ void xxxfb_poll(struct fb_info *info, poll_table *wait)
647 * If the driver has implemented its own hardware-based drawing function, 640 * If the driver has implemented its own hardware-based drawing function,
648 * implementing this function is highly recommended. 641 * implementing this function is highly recommended.
649 */ 642 */
650void xxxfb_sync(struct fb_info *info) 643int xxxfb_sync(struct fb_info *info)
651{ 644{
645 return 0;
652} 646}
653 647
654 /* 648 /*
649 * Frame buffer operations
650 */
651
652static struct fb_ops xxxfb_ops = {
653 .owner = THIS_MODULE,
654 .fb_open = xxxfb_open,
655 .fb_read = xxxfb_read,
656 .fb_write = xxxfb_write,
657 .fb_release = xxxfb_release,
658 .fb_check_var = xxxfb_check_var,
659 .fb_set_par = xxxfb_set_par,
660 .fb_setcolreg = xxxfb_setcolreg,
661 .fb_blank = xxxfb_blank,
662 .fb_pan_display = xxxfb_pan_display,
663 .fb_fillrect = xxxfb_fillrect, /* Needed !!! */
664 .fb_copyarea = xxxfb_copyarea, /* Needed !!! */
665 .fb_imageblit = xxxfb_imageblit, /* Needed !!! */
666 .fb_cursor = xxxfb_cursor, /* Optional !!! */
667 .fb_rotate = xxxfb_rotate,
668 .fb_sync = xxxfb_sync,
669 .fb_ioctl = xxxfb_ioctl,
670 .fb_mmap = xxxfb_mmap,
671};
672
673/* ------------------------------------------------------------------------- */
674
675 /*
655 * Initialization 676 * Initialization
656 */ 677 */
657 678
658/* static int __init xxfb_probe (struct device *device) -- for platform devs */ 679/* static int __init xxfb_probe (struct device *device) -- for platform devs */
659static int __init xxxfb_probe(struct pci_dev *dev, 680static int __devinit xxxfb_probe(struct pci_dev *dev,
660 const_struct pci_device_id *ent) 681 const struct pci_device_id *ent)
661{ 682{
662 struct fb_info *info; 683 struct fb_info *info;
663 struct xxx_par *par; 684 struct xxx_par *par;
664 struct device = &dev->dev; /* for pci drivers */ 685 struct device* device = &dev->dev; /* for pci drivers */
665 int cmap_len, retval; 686 int cmap_len, retval;
666 687
667 /* 688 /*
@@ -684,7 +705,7 @@ static int __init xxxfb_probe(struct pci_dev *dev,
684 info->screen_base = framebuffer_virtual_memory; 705 info->screen_base = framebuffer_virtual_memory;
685 info->fbops = &xxxfb_ops; 706 info->fbops = &xxxfb_ops;
686 info->fix = xxxfb_fix; /* this will be the only time xxxfb_fix will be 707 info->fix = xxxfb_fix; /* this will be the only time xxxfb_fix will be
687 * used, so mark it as __initdata 708 * used, so mark it as __devinitdata
688 */ 709 */
689 info->pseudo_palette = pseudo_palette; /* The pseudopalette is an 710 info->pseudo_palette = pseudo_palette; /* The pseudopalette is an
690 * 16-member array 711 * 16-member array
@@ -760,7 +781,7 @@ static int __init xxxfb_probe(struct pci_dev *dev,
760 * 781 *
761 * NOTE: This field is currently unused. 782 * NOTE: This field is currently unused.
762 */ 783 */
763 info->pixmap.scan_align = 32 784 info->pixmap.scan_align = 32;
764/***************************** End optional stage ***************************/ 785/***************************** End optional stage ***************************/
765 786
766 /* 787 /*
@@ -770,13 +791,13 @@ static int __init xxxfb_probe(struct pci_dev *dev,
770 if (!mode_option) 791 if (!mode_option)
771 mode_option = "640x480@60"; 792 mode_option = "640x480@60";
772 793
773 retval = fb_find_mode(info->var, info, mode_option, NULL, 0, NULL, 8); 794 retval = fb_find_mode(&info->var, info, mode_option, NULL, 0, NULL, 8);
774 795
775 if (!retval || retval == 4) 796 if (!retval || retval == 4)
776 return -EINVAL; 797 return -EINVAL;
777 798
778 /* This has to been done !!! */ 799 /* This has to been done !!! */
779 fb_alloc_cmap(info->cmap, cmap_len, 0); 800 fb_alloc_cmap(&info->cmap, cmap_len, 0);
780 801
781 /* 802 /*
782 * The following is done in the case of having hardware with a static 803 * The following is done in the case of having hardware with a static
@@ -811,34 +832,77 @@ static int __init xxxfb_probe(struct pci_dev *dev,
811 /* 832 /*
812 * Cleanup 833 * Cleanup
813 */ 834 */
814/* static void __exit xxxfb_remove(struct device *device) */ 835/* static void __devexit xxxfb_remove(struct device *device) */
815static void __exit xxxfb_remove(struct pci_dev *dev) 836static void __devexit xxxfb_remove(struct pci_dev *dev)
816{ 837{
817 struct fb_info *info = pci_get_drv_data(dev); 838 struct fb_info *info = pci_get_drvdata(dev);
818 /* or dev_get_drv_data(device); */ 839 /* or dev_get_drvdata(device); */
819 840
820 if (info) { 841 if (info) {
821 unregister_framebuffer(info); 842 unregister_framebuffer(info);
822 fb_dealloc_cmap(&info.cmap); 843 fb_dealloc_cmap(&info->cmap);
823 /* ... */ 844 /* ... */
824 framebuffer_release(info); 845 framebuffer_release(info);
825 } 846 }
847}
848
849#ifdef CONFIG_PCI
850#ifdef CONFIG_PM
851/**
852 * xxxfb_suspend - Optional but recommended function. Suspend the device.
853 * @dev: PCI device
854 * @msg: the suspend event code.
855 *
856 * See Documentation/power/devices.txt for more information
857 */
858static int xxxfb_suspend(struct pci_dev *dev, pm_message_t msg)
859{
860 struct fb_info *info = pci_get_drvdata(dev);
861 struct xxxfb_par *par = info->par;
862
863 /* suspend here */
864 return 0;
865}
866
867/**
868 * xxxfb_resume - Optional but recommended function. Resume the device.
869 * @dev: PCI device
870 *
871 * See Documentation/power/devices.txt for more information
872 */
873static int xxxfb_resume(struct pci_dev *dev)
874{
875 struct fb_info *info = pci_get_drvdata(dev);
876 struct xxxfb_par *par = info->par;
826 877
878 /* resume here */
827 return 0; 879 return 0;
828} 880}
881#else
882#define xxxfb_suspend NULL
883#define xxxfb_resume NULL
884#endif /* CONFIG_PM */
885
886static struct pci_device_id xxxfb_id_table[] = {
887 { PCI_VENDOR_ID_XXX, PCI_DEVICE_ID_XXX,
888 PCI_ANY_ID, PCI_ANY_ID, PCI_BASE_CLASS_DISPLAY << 16,
889 PCI_CLASS_MASK, 0 },
890 { 0, }
891};
829 892
830#if CONFIG_PCI
831/* For PCI drivers */ 893/* For PCI drivers */
832static struct pci_driver xxxfb_driver = { 894static struct pci_driver xxxfb_driver = {
833 .name = "xxxfb", 895 .name = "xxxfb",
834 .id_table = xxxfb_devices, 896 .id_table = xxxfb_id_table,
835 .probe = xxxfb_probe, 897 .probe = xxxfb_probe,
836 .remove = __devexit_p(xxxfb_remove), 898 .remove = __devexit_p(xxxfb_remove),
837 .suspend = xxxfb_suspend, /* optional */ 899 .suspend = xxxfb_suspend, /* optional but recommended */
838 .resume = xxxfb_resume, /* optional */ 900 .resume = xxxfb_resume, /* optional but recommended */
839}; 901};
840 902
841static int __init xxxfb_init(void) 903MODULE_DEVICE_TABLE(pci, xxxfb_id_table);
904
905int __init xxxfb_init(void)
842{ 906{
843 /* 907 /*
844 * For kernel boot options (in 'video=xxxfb:<options>' format) 908 * For kernel boot options (in 'video=xxxfb:<options>' format)
@@ -858,16 +922,53 @@ static void __exit xxxfb_exit(void)
858{ 922{
859 pci_unregister_driver(&xxxfb_driver); 923 pci_unregister_driver(&xxxfb_driver);
860} 924}
861#else 925#else /* non PCI, platform drivers */
862#include <linux/platform_device.h> 926#include <linux/platform_device.h>
863/* for platform devices */ 927/* for platform devices */
928
929#ifdef CONFIG_PM
930/**
931 * xxxfb_suspend - Optional but recommended function. Suspend the device.
932 * @dev: platform device
933 * @msg: the suspend event code.
934 *
935 * See Documentation/power/devices.txt for more information
936 */
937static int xxxfb_suspend(struct platform_device *dev, pm_message_t msg)
938{
939 struct fb_info *info = platform_get_drvdata(dev);
940 struct xxxfb_par *par = info->par;
941
942 /* suspend here */
943 return 0;
944}
945
946/**
947 * xxxfb_resume - Optional but recommended function. Resume the device.
948 * @dev: platform device
949 *
950 * See Documentation/power/devices.txt for more information
951 */
952static int xxxfb_resume(struct platform_dev *dev)
953{
954 struct fb_info *info = platform_get_drvdata(dev);
955 struct xxxfb_par *par = info->par;
956
957 /* resume here */
958 return 0;
959}
960#else
961#define xxxfb_suspend NULL
962#define xxxfb_resume NULL
963#endif /* CONFIG_PM */
964
864static struct device_driver xxxfb_driver = { 965static struct device_driver xxxfb_driver = {
865 .name = "xxxfb", 966 .name = "xxxfb",
866 .bus = &platform_bus_type, 967 .bus = &platform_bus_type,
867 .probe = xxxfb_probe, 968 .probe = xxxfb_probe,
868 .remove = xxxfb_remove, 969 .remove = xxxfb_remove,
869 .suspend = xxxfb_suspend, /* optional */ 970 .suspend = xxxfb_suspend, /* optional but recommended */
870 .resume = xxxfb_resume, /* optional */ 971 .resume = xxxfb_resume, /* optional but recommended */
871}; 972};
872 973
873static struct platform_device xxxfb_device = { 974static struct platform_device xxxfb_device = {
@@ -903,8 +1004,9 @@ static void __exit xxxfb_exit(void)
903 platform_device_unregister(&xxxfb_device); 1004 platform_device_unregister(&xxxfb_device);
904 driver_unregister(&xxxfb_driver); 1005 driver_unregister(&xxxfb_driver);
905} 1006}
906#endif 1007#endif /* CONFIG_PCI */
907 1008
1009#ifdef MODULE
908 /* 1010 /*
909 * Setup 1011 * Setup
910 */ 1012 */
@@ -917,34 +1019,7 @@ int __init xxxfb_setup(char *options)
917{ 1019{
918 /* Parse user speficied options (`video=xxxfb:') */ 1020 /* Parse user speficied options (`video=xxxfb:') */
919} 1021}
920 1022#endif /* MODULE */
921/* ------------------------------------------------------------------------- */
922
923 /*
924 * Frame buffer operations
925 */
926
927static struct fb_ops xxxfb_ops = {
928 .owner = THIS_MODULE,
929 .fb_open = xxxfb_open,
930 .fb_read = xxxfb_read,
931 .fb_write = xxxfb_write,
932 .fb_release = xxxfb_release,
933 .fb_check_var = xxxfb_check_var,
934 .fb_set_par = xxxfb_set_par,
935 .fb_setcolreg = xxxfb_setcolreg,
936 .fb_blank = xxxfb_blank,
937 .fb_pan_display = xxxfb_pan_display,
938 .fb_fillrect = xxxfb_fillrect, /* Needed !!! */
939 .fb_copyarea = xxxfb_copyarea, /* Needed !!! */
940 .fb_imageblit = xxxfb_imageblit, /* Needed !!! */
941 .fb_cursor = xxxfb_cursor, /* Optional !!! */
942 .fb_rotate = xxxfb_rotate,
943 .fb_poll = xxxfb_poll,
944 .fb_sync = xxxfb_sync,
945 .fb_ioctl = xxxfb_ioctl,
946 .fb_mmap = xxxfb_mmap,
947};
948 1023
949/* ------------------------------------------------------------------------- */ 1024/* ------------------------------------------------------------------------- */
950 1025
@@ -954,6 +1029,6 @@ static struct fb_ops xxxfb_ops = {
954 */ 1029 */
955 1030
956module_init(xxxfb_init); 1031module_init(xxxfb_init);
957module_exit(xxxfb_cleanup); 1032module_exit(xxxfb_remove);
958 1033
959MODULE_LICENSE("GPL"); 1034MODULE_LICENSE("GPL");
diff --git a/drivers/video/sm501fb.c b/drivers/video/sm501fb.c
index 0a44c44672c8..c86df126f93a 100644
--- a/drivers/video/sm501fb.c
+++ b/drivers/video/sm501fb.c
@@ -989,7 +989,7 @@ static int sm501fb_cursor(struct fb_info *info, struct fb_cursor *cursor)
989 ((info->cmap.green[fg_col] & 0xFC) << 3) | 989 ((info->cmap.green[fg_col] & 0xFC) << 3) |
990 ((info->cmap.blue[fg_col] & 0xF8) >> 3); 990 ((info->cmap.blue[fg_col] & 0xF8) >> 3);
991 991
992 dev_dbg(fbi->dev, "fgcol %08x, bgcol %08x\n", fg, bg); 992 dev_dbg(fbi->dev, "fgcol %08lx, bgcol %08lx\n", fg, bg);
993 993
994 writel(bg, base + SM501_OFF_HWC_COLOR_1_2); 994 writel(bg, base + SM501_OFF_HWC_COLOR_1_2);
995 writel(fg, base + SM501_OFF_HWC_COLOR_3); 995 writel(fg, base + SM501_OFF_HWC_COLOR_3);
diff --git a/drivers/video/svgalib.c b/drivers/video/svgalib.c
index 68b30d9eac58..079cdc911e48 100644
--- a/drivers/video/svgalib.c
+++ b/drivers/video/svgalib.c
@@ -194,7 +194,7 @@ void svga_dump_var(struct fb_var_screeninfo *var, int node)
194void svga_settile(struct fb_info *info, struct fb_tilemap *map) 194void svga_settile(struct fb_info *info, struct fb_tilemap *map)
195{ 195{
196 const u8 *font = map->data; 196 const u8 *font = map->data;
197 u8* fb = (u8 *) info->screen_base; 197 u8 __iomem *fb = (u8 __iomem *)info->screen_base;
198 int i, c; 198 int i, c;
199 199
200 if ((map->width != 8) || (map->height != 16) || 200 if ((map->width != 8) || (map->height != 16) ||
@@ -207,7 +207,8 @@ void svga_settile(struct fb_info *info, struct fb_tilemap *map)
207 fb += 2; 207 fb += 2;
208 for (c = 0; c < map->length; c++) { 208 for (c = 0; c < map->length; c++) {
209 for (i = 0; i < map->height; i++) { 209 for (i = 0; i < map->height; i++) {
210 fb[i * 4] = font[i]; 210 fb_writeb(font[i], fb + i * 4);
211// fb[i * 4] = font[i];
211 } 212 }
212 fb += 128; 213 fb += 128;
213 font += map->height; 214 font += map->height;
@@ -221,8 +222,8 @@ void svga_tilecopy(struct fb_info *info, struct fb_tilearea *area)
221 /* colstride is halved in this function because u16 are used */ 222 /* colstride is halved in this function because u16 are used */
222 int colstride = 1 << (info->fix.type_aux & FB_AUX_TEXT_SVGA_MASK); 223 int colstride = 1 << (info->fix.type_aux & FB_AUX_TEXT_SVGA_MASK);
223 int rowstride = colstride * (info->var.xres_virtual / 8); 224 int rowstride = colstride * (info->var.xres_virtual / 8);
224 u16 *fb = (u16 *) info->screen_base; 225 u16 __iomem *fb = (u16 __iomem *) info->screen_base;
225 u16 *src, *dst; 226 u16 __iomem *src, *dst;
226 227
227 if ((area->sy > area->dy) || 228 if ((area->sy > area->dy) ||
228 ((area->sy == area->dy) && (area->sx > area->dx))) { 229 ((area->sy == area->dy) && (area->sx > area->dx))) {
@@ -239,10 +240,11 @@ void svga_tilecopy(struct fb_info *info, struct fb_tilearea *area)
239 } 240 }
240 241
241 for (dy = 0; dy < area->height; dy++) { 242 for (dy = 0; dy < area->height; dy++) {
242 u16* src2 = src; 243 u16 __iomem *src2 = src;
243 u16* dst2 = dst; 244 u16 __iomem *dst2 = dst;
244 for (dx = 0; dx < area->width; dx++) { 245 for (dx = 0; dx < area->width; dx++) {
245 *dst2 = *src2; 246 fb_writew(fb_readw(src2), dst2);
247// *dst2 = *src2;
246 src2 += colstride; 248 src2 += colstride;
247 dst2 += colstride; 249 dst2 += colstride;
248 } 250 }
@@ -258,14 +260,14 @@ void svga_tilefill(struct fb_info *info, struct fb_tilerect *rect)
258 int colstride = 2 << (info->fix.type_aux & FB_AUX_TEXT_SVGA_MASK); 260 int colstride = 2 << (info->fix.type_aux & FB_AUX_TEXT_SVGA_MASK);
259 int rowstride = colstride * (info->var.xres_virtual / 8); 261 int rowstride = colstride * (info->var.xres_virtual / 8);
260 int attr = (0x0F & rect->bg) << 4 | (0x0F & rect->fg); 262 int attr = (0x0F & rect->bg) << 4 | (0x0F & rect->fg);
261 u8 *fb = (u8 *) info->screen_base; 263 u8 __iomem *fb = (u8 __iomem *)info->screen_base;
262 fb += rect->sx * colstride + rect->sy * rowstride; 264 fb += rect->sx * colstride + rect->sy * rowstride;
263 265
264 for (dy = 0; dy < rect->height; dy++) { 266 for (dy = 0; dy < rect->height; dy++) {
265 u8* fb2 = fb; 267 u8 __iomem *fb2 = fb;
266 for (dx = 0; dx < rect->width; dx++) { 268 for (dx = 0; dx < rect->width; dx++) {
267 fb2[0] = rect->index; 269 fb_writeb(rect->index, fb2);
268 fb2[1] = attr; 270 fb_writeb(attr, fb2 + 1);
269 fb2 += colstride; 271 fb2 += colstride;
270 } 272 }
271 fb += rowstride; 273 fb += rowstride;
@@ -279,15 +281,15 @@ void svga_tileblit(struct fb_info *info, struct fb_tileblit *blit)
279 int colstride = 2 << (info->fix.type_aux & FB_AUX_TEXT_SVGA_MASK); 281 int colstride = 2 << (info->fix.type_aux & FB_AUX_TEXT_SVGA_MASK);
280 int rowstride = colstride * (info->var.xres_virtual / 8); 282 int rowstride = colstride * (info->var.xres_virtual / 8);
281 int attr = (0x0F & blit->bg) << 4 | (0x0F & blit->fg); 283 int attr = (0x0F & blit->bg) << 4 | (0x0F & blit->fg);
282 u8* fb = (u8 *) info->screen_base; 284 u8 __iomem *fb = (u8 __iomem *)info->screen_base;
283 fb += blit->sx * colstride + blit->sy * rowstride; 285 fb += blit->sx * colstride + blit->sy * rowstride;
284 286
285 i=0; 287 i=0;
286 for (dy=0; dy < blit->height; dy ++) { 288 for (dy=0; dy < blit->height; dy ++) {
287 u8* fb2 = fb; 289 u8 __iomem *fb2 = fb;
288 for (dx = 0; dx < blit->width; dx ++) { 290 for (dx = 0; dx < blit->width; dx ++) {
289 fb2[0] = blit->indices[i]; 291 fb_writeb(blit->indices[i], fb2);
290 fb2[1] = attr; 292 fb_writeb(attr, fb2 + 1);
291 fb2 += colstride; 293 fb2 += colstride;
292 i ++; 294 i ++;
293 if (i == blit->length) return; 295 if (i == blit->length) return;
@@ -340,6 +342,11 @@ void svga_tilecursor(struct fb_info *info, struct fb_tilecursor *cursor)
340 vga_wcrt(NULL, 0x0A, cs); /* set cursor start and enable it */ 342 vga_wcrt(NULL, 0x0A, cs); /* set cursor start and enable it */
341} 343}
342 344
345int svga_get_tilemax(struct fb_info *info)
346{
347 return 256;
348}
349
343 350
344/* ------------------------------------------------------------------------- */ 351/* ------------------------------------------------------------------------- */
345 352
@@ -621,6 +628,7 @@ EXPORT_SYMBOL(svga_tilecopy);
621EXPORT_SYMBOL(svga_tilefill); 628EXPORT_SYMBOL(svga_tilefill);
622EXPORT_SYMBOL(svga_tileblit); 629EXPORT_SYMBOL(svga_tileblit);
623EXPORT_SYMBOL(svga_tilecursor); 630EXPORT_SYMBOL(svga_tilecursor);
631EXPORT_SYMBOL(svga_get_tilemax);
624 632
625EXPORT_SYMBOL(svga_compute_pll); 633EXPORT_SYMBOL(svga_compute_pll);
626EXPORT_SYMBOL(svga_check_timings); 634EXPORT_SYMBOL(svga_check_timings);
diff --git a/drivers/video/syscopyarea.c b/drivers/video/syscopyarea.c
new file mode 100644
index 000000000000..37af10ab8f52
--- /dev/null
+++ b/drivers/video/syscopyarea.c
@@ -0,0 +1,378 @@
1/*
2 * Generic Bit Block Transfer for frame buffers located in system RAM with
3 * packed pixels of any depth.
4 *
5 * Based almost entirely from cfbcopyarea.c (which is based almost entirely
6 * on Geert Uytterhoeven's copyarea routine)
7 *
8 * Copyright (C) 2007 Antonino Daplas <adaplas@pol.net>
9 *
10 * This file is subject to the terms and conditions of the GNU General Public
11 * License. See the file COPYING in the main directory of this archive for
12 * more details.
13 *
14 */
15#include <linux/module.h>
16#include <linux/kernel.h>
17#include <linux/string.h>
18#include <linux/fb.h>
19#include <linux/slab.h>
20#include <asm/types.h>
21#include <asm/io.h>
22#include "fb_draw.h"
23
24 /*
25 * Generic bitwise copy algorithm
26 */
27
28static void
29bitcpy(unsigned long *dst, int dst_idx, const unsigned long *src,
30 int src_idx, int bits, unsigned n)
31{
32 unsigned long first, last;
33 int const shift = dst_idx-src_idx;
34 int left, right;
35
36 first = FB_SHIFT_HIGH(~0UL, dst_idx);
37 last = ~(FB_SHIFT_HIGH(~0UL, (dst_idx+n) % bits));
38
39 if (!shift) {
40 /* Same alignment for source and dest */
41 if (dst_idx+n <= bits) {
42 /* Single word */
43 if (last)
44 first &= last;
45 *dst = comp(*src, *dst, first);
46 } else {
47 /* Multiple destination words */
48 /* Leading bits */
49 if (first != ~0UL) {
50 *dst = comp(*src, *dst, first);
51 dst++;
52 src++;
53 n -= bits - dst_idx;
54 }
55
56 /* Main chunk */
57 n /= bits;
58 while (n >= 8) {
59 *dst++ = *src++;
60 *dst++ = *src++;
61 *dst++ = *src++;
62 *dst++ = *src++;
63 *dst++ = *src++;
64 *dst++ = *src++;
65 *dst++ = *src++;
66 *dst++ = *src++;
67 n -= 8;
68 }
69 while (n--)
70 *dst++ = *src++;
71
72 /* Trailing bits */
73 if (last)
74 *dst = comp(*src, *dst, last);
75 }
76 } else {
77 unsigned long d0, d1;
78 int m;
79
80 /* Different alignment for source and dest */
81 right = shift & (bits - 1);
82 left = -shift & (bits - 1);
83
84 if (dst_idx+n <= bits) {
85 /* Single destination word */
86 if (last)
87 first &= last;
88 if (shift > 0) {
89 /* Single source word */
90 *dst = comp(*src >> right, *dst, first);
91 } else if (src_idx+n <= bits) {
92 /* Single source word */
93 *dst = comp(*src << left, *dst, first);
94 } else {
95 /* 2 source words */
96 d0 = *src++;
97 d1 = *src;
98 *dst = comp(d0 << left | d1 >> right, *dst,
99 first);
100 }
101 } else {
102 /* Multiple destination words */
103 /** We must always remember the last value read,
104 because in case SRC and DST overlap bitwise (e.g.
105 when moving just one pixel in 1bpp), we always
106 collect one full long for DST and that might
107 overlap with the current long from SRC. We store
108 this value in 'd0'. */
109 d0 = *src++;
110 /* Leading bits */
111 if (shift > 0) {
112 /* Single source word */
113 *dst = comp(d0 >> right, *dst, first);
114 dst++;
115 n -= bits - dst_idx;
116 } else {
117 /* 2 source words */
118 d1 = *src++;
119 *dst = comp(d0 << left | *dst >> right, *dst, first);
120 d0 = d1;
121 dst++;
122 n -= bits - dst_idx;
123 }
124
125 /* Main chunk */
126 m = n % bits;
127 n /= bits;
128 while (n >= 4) {
129 d1 = *src++;
130 *dst++ = d0 << left | d1 >> right;
131 d0 = d1;
132 d1 = *src++;
133 *dst++ = d0 << left | d1 >> right;
134 d0 = d1;
135 d1 = *src++;
136 *dst++ = d0 << left | d1 >> right;
137 d0 = d1;
138 d1 = *src++;
139 *dst++ = d0 << left | d1 >> right;
140 d0 = d1;
141 n -= 4;
142 }
143 while (n--) {
144 d1 = *src++;
145 *dst++ = d0 << left | d1 >> right;
146 d0 = d1;
147 }
148
149 /* Trailing bits */
150 if (last) {
151 if (m <= right) {
152 /* Single source word */
153 *dst = comp(d0 << left, *dst, last);
154 } else {
155 /* 2 source words */
156 d1 = *src;
157 *dst = comp(d0 << left | d1 >> right,
158 *dst, last);
159 }
160 }
161 }
162 }
163}
164
165 /*
166 * Generic bitwise copy algorithm, operating backward
167 */
168
169static void
170bitcpy_rev(unsigned long *dst, int dst_idx, const unsigned long *src,
171 int src_idx, int bits, unsigned n)
172{
173 unsigned long first, last;
174 int shift;
175
176 dst += (n-1)/bits;
177 src += (n-1)/bits;
178 if ((n-1) % bits) {
179 dst_idx += (n-1) % bits;
180 dst += dst_idx >> (ffs(bits) - 1);
181 dst_idx &= bits - 1;
182 src_idx += (n-1) % bits;
183 src += src_idx >> (ffs(bits) - 1);
184 src_idx &= bits - 1;
185 }
186
187 shift = dst_idx-src_idx;
188
189 first = FB_SHIFT_LOW(~0UL, bits - 1 - dst_idx);
190 last = ~(FB_SHIFT_LOW(~0UL, bits - 1 - ((dst_idx-n) % bits)));
191
192 if (!shift) {
193 /* Same alignment for source and dest */
194 if ((unsigned long)dst_idx+1 >= n) {
195 /* Single word */
196 if (last)
197 first &= last;
198 *dst = comp(*src, *dst, first);
199 } else {
200 /* Multiple destination words */
201
202 /* Leading bits */
203 if (first != ~0UL) {
204 *dst = comp(*src, *dst, first);
205 dst--;
206 src--;
207 n -= dst_idx+1;
208 }
209
210 /* Main chunk */
211 n /= bits;
212 while (n >= 8) {
213 *dst-- = *src--;
214 *dst-- = *src--;
215 *dst-- = *src--;
216 *dst-- = *src--;
217 *dst-- = *src--;
218 *dst-- = *src--;
219 *dst-- = *src--;
220 *dst-- = *src--;
221 n -= 8;
222 }
223 while (n--)
224 *dst-- = *src--;
225 /* Trailing bits */
226 if (last)
227 *dst = comp(*src, *dst, last);
228 }
229 } else {
230 /* Different alignment for source and dest */
231
232 int const left = -shift & (bits-1);
233 int const right = shift & (bits-1);
234
235 if ((unsigned long)dst_idx+1 >= n) {
236 /* Single destination word */
237 if (last)
238 first &= last;
239 if (shift < 0) {
240 /* Single source word */
241 *dst = comp(*src << left, *dst, first);
242 } else if (1+(unsigned long)src_idx >= n) {
243 /* Single source word */
244 *dst = comp(*src >> right, *dst, first);
245 } else {
246 /* 2 source words */
247 *dst = comp(*src >> right | *(src-1) << left,
248 *dst, first);
249 }
250 } else {
251 /* Multiple destination words */
252 /** We must always remember the last value read,
253 because in case SRC and DST overlap bitwise (e.g.
254 when moving just one pixel in 1bpp), we always
255 collect one full long for DST and that might
256 overlap with the current long from SRC. We store
257 this value in 'd0'. */
258 unsigned long d0, d1;
259 int m;
260
261 d0 = *src--;
262 /* Leading bits */
263 if (shift < 0) {
264 /* Single source word */
265 *dst = comp(d0 << left, *dst, first);
266 } else {
267 /* 2 source words */
268 d1 = *src--;
269 *dst = comp(d0 >> right | d1 << left, *dst,
270 first);
271 d0 = d1;
272 }
273 dst--;
274 n -= dst_idx+1;
275
276 /* Main chunk */
277 m = n % bits;
278 n /= bits;
279 while (n >= 4) {
280 d1 = *src--;
281 *dst-- = d0 >> right | d1 << left;
282 d0 = d1;
283 d1 = *src--;
284 *dst-- = d0 >> right | d1 << left;
285 d0 = d1;
286 d1 = *src--;
287 *dst-- = d0 >> right | d1 << left;
288 d0 = d1;
289 d1 = *src--;
290 *dst-- = d0 >> right | d1 << left;
291 d0 = d1;
292 n -= 4;
293 }
294 while (n--) {
295 d1 = *src--;
296 *dst-- = d0 >> right | d1 << left;
297 d0 = d1;
298 }
299
300 /* Trailing bits */
301 if (last) {
302 if (m <= left) {
303 /* Single source word */
304 *dst = comp(d0 >> right, *dst, last);
305 } else {
306 /* 2 source words */
307 d1 = *src;
308 *dst = comp(d0 >> right | d1 << left,
309 *dst, last);
310 }
311 }
312 }
313 }
314}
315
316void sys_copyarea(struct fb_info *p, const struct fb_copyarea *area)
317{
318 u32 dx = area->dx, dy = area->dy, sx = area->sx, sy = area->sy;
319 u32 height = area->height, width = area->width;
320 unsigned long const bits_per_line = p->fix.line_length*8u;
321 unsigned long *dst = NULL, *src = NULL;
322 int bits = BITS_PER_LONG, bytes = bits >> 3;
323 int dst_idx = 0, src_idx = 0, rev_copy = 0;
324
325 if (p->state != FBINFO_STATE_RUNNING)
326 return;
327
328 /* if the beginning of the target area might overlap with the end of
329 the source area, be have to copy the area reverse. */
330 if ((dy == sy && dx > sx) || (dy > sy)) {
331 dy += height;
332 sy += height;
333 rev_copy = 1;
334 }
335
336 /* split the base of the framebuffer into a long-aligned address and
337 the index of the first bit */
338 dst = src = (unsigned long *)((unsigned long)p->screen_base &
339 ~(bytes-1));
340 dst_idx = src_idx = 8*((unsigned long)p->screen_base & (bytes-1));
341 /* add offset of source and target area */
342 dst_idx += dy*bits_per_line + dx*p->var.bits_per_pixel;
343 src_idx += sy*bits_per_line + sx*p->var.bits_per_pixel;
344
345 if (p->fbops->fb_sync)
346 p->fbops->fb_sync(p);
347
348 if (rev_copy) {
349 while (height--) {
350 dst_idx -= bits_per_line;
351 src_idx -= bits_per_line;
352 dst += dst_idx >> (ffs(bits) - 1);
353 dst_idx &= (bytes - 1);
354 src += src_idx >> (ffs(bits) - 1);
355 src_idx &= (bytes - 1);
356 bitcpy_rev(dst, dst_idx, src, src_idx, bits,
357 width*p->var.bits_per_pixel);
358 }
359 } else {
360 while (height--) {
361 dst += dst_idx >> (ffs(bits) - 1);
362 dst_idx &= (bytes - 1);
363 src += src_idx >> (ffs(bits) - 1);
364 src_idx &= (bytes - 1);
365 bitcpy(dst, dst_idx, src, src_idx, bits,
366 width*p->var.bits_per_pixel);
367 dst_idx += bits_per_line;
368 src_idx += bits_per_line;
369 }
370 }
371}
372
373EXPORT_SYMBOL(sys_copyarea);
374
375MODULE_AUTHOR("Antonino Daplas <adaplas@pol.net>");
376MODULE_DESCRIPTION("Generic copyarea (sys-to-sys)");
377MODULE_LICENSE("GPL");
378
diff --git a/drivers/video/sysfillrect.c b/drivers/video/sysfillrect.c
new file mode 100644
index 000000000000..a261e9e6a675
--- /dev/null
+++ b/drivers/video/sysfillrect.c
@@ -0,0 +1,334 @@
1/*
2 * Generic fillrect for frame buffers in system RAM with packed pixels of
3 * any depth.
4 *
5 * Based almost entirely from cfbfillrect.c (which is based almost entirely
6 * on Geert Uytterhoeven's fillrect routine)
7 *
8 * Copyright (C) 2007 Antonino Daplas <adaplas@pol.net>
9 *
10 * This file is subject to the terms and conditions of the GNU General Public
11 * License. See the file COPYING in the main directory of this archive for
12 * more details.
13 */
14#include <linux/module.h>
15#include <linux/string.h>
16#include <linux/fb.h>
17#include <asm/types.h>
18#include "fb_draw.h"
19
20 /*
21 * Aligned pattern fill using 32/64-bit memory accesses
22 */
23
24static void
25bitfill_aligned(unsigned long *dst, int dst_idx, unsigned long pat,
26 unsigned n, int bits)
27{
28 unsigned long first, last;
29
30 if (!n)
31 return;
32
33 first = FB_SHIFT_HIGH(~0UL, dst_idx);
34 last = ~(FB_SHIFT_HIGH(~0UL, (dst_idx+n) % bits));
35
36 if (dst_idx+n <= bits) {
37 /* Single word */
38 if (last)
39 first &= last;
40 *dst = comp(pat, *dst, first);
41 } else {
42 /* Multiple destination words */
43
44 /* Leading bits */
45 if (first!= ~0UL) {
46 *dst = comp(pat, *dst, first);
47 dst++;
48 n -= bits - dst_idx;
49 }
50
51 /* Main chunk */
52 n /= bits;
53 while (n >= 8) {
54 *dst++ = pat;
55 *dst++ = pat;
56 *dst++ = pat;
57 *dst++ = pat;
58 *dst++ = pat;
59 *dst++ = pat;
60 *dst++ = pat;
61 *dst++ = pat;
62 n -= 8;
63 }
64 while (n--)
65 *dst++ = pat;
66 /* Trailing bits */
67 if (last)
68 *dst = comp(pat, *dst, last);
69 }
70}
71
72
73 /*
74 * Unaligned generic pattern fill using 32/64-bit memory accesses
75 * The pattern must have been expanded to a full 32/64-bit value
76 * Left/right are the appropriate shifts to convert to the pattern to be
77 * used for the next 32/64-bit word
78 */
79
80static void
81bitfill_unaligned(unsigned long *dst, int dst_idx, unsigned long pat,
82 int left, int right, unsigned n, int bits)
83{
84 unsigned long first, last;
85
86 if (!n)
87 return;
88
89 first = FB_SHIFT_HIGH(~0UL, dst_idx);
90 last = ~(FB_SHIFT_HIGH(~0UL, (dst_idx+n) % bits));
91
92 if (dst_idx+n <= bits) {
93 /* Single word */
94 if (last)
95 first &= last;
96 *dst = comp(pat, *dst, first);
97 } else {
98 /* Multiple destination words */
99 /* Leading bits */
100 if (first) {
101 *dst = comp(pat, *dst, first);
102 dst++;
103 pat = pat << left | pat >> right;
104 n -= bits - dst_idx;
105 }
106
107 /* Main chunk */
108 n /= bits;
109 while (n >= 4) {
110 *dst++ = pat;
111 pat = pat << left | pat >> right;
112 *dst++ = pat;
113 pat = pat << left | pat >> right;
114 *dst++ = pat;
115 pat = pat << left | pat >> right;
116 *dst++ = pat;
117 pat = pat << left | pat >> right;
118 n -= 4;
119 }
120 while (n--) {
121 *dst++ = pat;
122 pat = pat << left | pat >> right;
123 }
124
125 /* Trailing bits */
126 if (last)
127 *dst = comp(pat, *dst, first);
128 }
129}
130
131 /*
132 * Aligned pattern invert using 32/64-bit memory accesses
133 */
134static void
135bitfill_aligned_rev(unsigned long *dst, int dst_idx, unsigned long pat,
136 unsigned n, int bits)
137{
138 unsigned long val = pat;
139 unsigned long first, last;
140
141 if (!n)
142 return;
143
144 first = FB_SHIFT_HIGH(~0UL, dst_idx);
145 last = ~(FB_SHIFT_HIGH(~0UL, (dst_idx+n) % bits));
146
147 if (dst_idx+n <= bits) {
148 /* Single word */
149 if (last)
150 first &= last;
151 *dst = comp(*dst ^ val, *dst, first);
152 } else {
153 /* Multiple destination words */
154 /* Leading bits */
155 if (first!=0UL) {
156 *dst = comp(*dst ^ val, *dst, first);
157 dst++;
158 n -= bits - dst_idx;
159 }
160
161 /* Main chunk */
162 n /= bits;
163 while (n >= 8) {
164 *dst++ ^= val;
165 *dst++ ^= val;
166 *dst++ ^= val;
167 *dst++ ^= val;
168 *dst++ ^= val;
169 *dst++ ^= val;
170 *dst++ ^= val;
171 *dst++ ^= val;
172 n -= 8;
173 }
174 while (n--)
175 *dst++ ^= val;
176 /* Trailing bits */
177 if (last)
178 *dst = comp(*dst ^ val, *dst, last);
179 }
180}
181
182
183 /*
184 * Unaligned generic pattern invert using 32/64-bit memory accesses
185 * The pattern must have been expanded to a full 32/64-bit value
186 * Left/right are the appropriate shifts to convert to the pattern to be
187 * used for the next 32/64-bit word
188 */
189
190static void
191bitfill_unaligned_rev(unsigned long *dst, int dst_idx, unsigned long pat,
192 int left, int right, unsigned n, int bits)
193{
194 unsigned long first, last;
195
196 if (!n)
197 return;
198
199 first = FB_SHIFT_HIGH(~0UL, dst_idx);
200 last = ~(FB_SHIFT_HIGH(~0UL, (dst_idx+n) % bits));
201
202 if (dst_idx+n <= bits) {
203 /* Single word */
204 if (last)
205 first &= last;
206 *dst = comp(*dst ^ pat, *dst, first);
207 } else {
208 /* Multiple destination words */
209
210 /* Leading bits */
211 if (first != 0UL) {
212 *dst = comp(*dst ^ pat, *dst, first);
213 dst++;
214 pat = pat << left | pat >> right;
215 n -= bits - dst_idx;
216 }
217
218 /* Main chunk */
219 n /= bits;
220 while (n >= 4) {
221 *dst++ ^= pat;
222 pat = pat << left | pat >> right;
223 *dst++ ^= pat;
224 pat = pat << left | pat >> right;
225 *dst++ ^= pat;
226 pat = pat << left | pat >> right;
227 *dst++ ^= pat;
228 pat = pat << left | pat >> right;
229 n -= 4;
230 }
231 while (n--) {
232 *dst ^= pat;
233 pat = pat << left | pat >> right;
234 }
235
236 /* Trailing bits */
237 if (last)
238 *dst = comp(*dst ^ pat, *dst, last);
239 }
240}
241
242void sys_fillrect(struct fb_info *p, const struct fb_fillrect *rect)
243{
244 unsigned long pat, fg;
245 unsigned long width = rect->width, height = rect->height;
246 int bits = BITS_PER_LONG, bytes = bits >> 3;
247 u32 bpp = p->var.bits_per_pixel;
248 unsigned long *dst;
249 int dst_idx, left;
250
251 if (p->state != FBINFO_STATE_RUNNING)
252 return;
253
254 if (p->fix.visual == FB_VISUAL_TRUECOLOR ||
255 p->fix.visual == FB_VISUAL_DIRECTCOLOR )
256 fg = ((u32 *) (p->pseudo_palette))[rect->color];
257 else
258 fg = rect->color;
259
260 pat = pixel_to_pat( bpp, fg);
261
262 dst = (unsigned long *)((unsigned long)p->screen_base & ~(bytes-1));
263 dst_idx = ((unsigned long)p->screen_base & (bytes - 1))*8;
264 dst_idx += rect->dy*p->fix.line_length*8+rect->dx*bpp;
265 /* FIXME For now we support 1-32 bpp only */
266 left = bits % bpp;
267 if (p->fbops->fb_sync)
268 p->fbops->fb_sync(p);
269 if (!left) {
270 void (*fill_op32)(unsigned long *dst, int dst_idx,
271 unsigned long pat, unsigned n, int bits) =
272 NULL;
273
274 switch (rect->rop) {
275 case ROP_XOR:
276 fill_op32 = bitfill_aligned_rev;
277 break;
278 case ROP_COPY:
279 fill_op32 = bitfill_aligned;
280 break;
281 default:
282 printk( KERN_ERR "cfb_fillrect(): unknown rop, "
283 "defaulting to ROP_COPY\n");
284 fill_op32 = bitfill_aligned;
285 break;
286 }
287 while (height--) {
288 dst += dst_idx >> (ffs(bits) - 1);
289 dst_idx &= (bits - 1);
290 fill_op32(dst, dst_idx, pat, width*bpp, bits);
291 dst_idx += p->fix.line_length*8;
292 }
293 } else {
294 int right;
295 int r;
296 int rot = (left-dst_idx) % bpp;
297 void (*fill_op)(unsigned long *dst, int dst_idx,
298 unsigned long pat, int left, int right,
299 unsigned n, int bits) = NULL;
300
301 /* rotate pattern to correct start position */
302 pat = pat << rot | pat >> (bpp-rot);
303
304 right = bpp-left;
305 switch (rect->rop) {
306 case ROP_XOR:
307 fill_op = bitfill_unaligned_rev;
308 break;
309 case ROP_COPY:
310 fill_op = bitfill_unaligned;
311 break;
312 default:
313 printk(KERN_ERR "cfb_fillrect(): unknown rop, "
314 "defaulting to ROP_COPY\n");
315 fill_op = bitfill_unaligned;
316 break;
317 }
318 while (height--) {
319 dst += dst_idx >> (ffs(bits) - 1);
320 dst_idx &= (bits - 1);
321 fill_op(dst, dst_idx, pat, left, right,
322 width*bpp, bits);
323 r = (p->fix.line_length*8) % bpp;
324 pat = pat << (bpp-r) | pat >> r;
325 dst_idx += p->fix.line_length*8;
326 }
327 }
328}
329
330EXPORT_SYMBOL(sys_fillrect);
331
332MODULE_AUTHOR("Antonino Daplas <adaplas@pol.net>");
333MODULE_DESCRIPTION("Generic fill rectangle (sys-to-sys)");
334MODULE_LICENSE("GPL");
diff --git a/drivers/video/sysimgblt.c b/drivers/video/sysimgblt.c
new file mode 100644
index 000000000000..bd7e7e9d155f
--- /dev/null
+++ b/drivers/video/sysimgblt.c
@@ -0,0 +1,291 @@
1/*
2 * Generic 1-bit or 8-bit source to 1-32 bit destination expansion
3 * for frame buffer located in system RAM with packed pixels of any depth.
4 *
5 * Based almost entirely on cfbimgblt.c
6 *
7 * Copyright (C) April 2007 Antonino Daplas <adaplas@pol.net>
8 *
9 * This file is subject to the terms and conditions of the GNU General Public
10 * License. See the file COPYING in the main directory of this archive for
11 * more details.
12 */
13#include <linux/module.h>
14#include <linux/string.h>
15#include <linux/fb.h>
16#include <asm/types.h>
17
18#define DEBUG
19
20#ifdef DEBUG
21#define DPRINTK(fmt, args...) printk(KERN_DEBUG "%s: " fmt,__FUNCTION__,## args)
22#else
23#define DPRINTK(fmt, args...)
24#endif
25
26static const u32 cfb_tab8[] = {
27#if defined(__BIG_ENDIAN)
28 0x00000000,0x000000ff,0x0000ff00,0x0000ffff,
29 0x00ff0000,0x00ff00ff,0x00ffff00,0x00ffffff,
30 0xff000000,0xff0000ff,0xff00ff00,0xff00ffff,
31 0xffff0000,0xffff00ff,0xffffff00,0xffffffff
32#elif defined(__LITTLE_ENDIAN)
33 0x00000000,0xff000000,0x00ff0000,0xffff0000,
34 0x0000ff00,0xff00ff00,0x00ffff00,0xffffff00,
35 0x000000ff,0xff0000ff,0x00ff00ff,0xffff00ff,
36 0x0000ffff,0xff00ffff,0x00ffffff,0xffffffff
37#else
38#error FIXME: No endianness??
39#endif
40};
41
42static const u32 cfb_tab16[] = {
43#if defined(__BIG_ENDIAN)
44 0x00000000, 0x0000ffff, 0xffff0000, 0xffffffff
45#elif defined(__LITTLE_ENDIAN)
46 0x00000000, 0xffff0000, 0x0000ffff, 0xffffffff
47#else
48#error FIXME: No endianness??
49#endif
50};
51
52static const u32 cfb_tab32[] = {
53 0x00000000, 0xffffffff
54};
55
56static void color_imageblit(const struct fb_image *image, struct fb_info *p,
57 void *dst1, u32 start_index, u32 pitch_index)
58{
59 /* Draw the penguin */
60 u32 *dst, *dst2;
61 u32 color = 0, val, shift;
62 int i, n, bpp = p->var.bits_per_pixel;
63 u32 null_bits = 32 - bpp;
64 u32 *palette = (u32 *) p->pseudo_palette;
65 const u8 *src = image->data;
66
67 dst2 = dst1;
68 for (i = image->height; i--; ) {
69 n = image->width;
70 dst = dst1;
71 shift = 0;
72 val = 0;
73
74 if (start_index) {
75 u32 start_mask = ~(FB_SHIFT_HIGH(~(u32)0,
76 start_index));
77 val = *dst & start_mask;
78 shift = start_index;
79 }
80 while (n--) {
81 if (p->fix.visual == FB_VISUAL_TRUECOLOR ||
82 p->fix.visual == FB_VISUAL_DIRECTCOLOR )
83 color = palette[*src];
84 else
85 color = *src;
86 color <<= FB_LEFT_POS(bpp);
87 val |= FB_SHIFT_HIGH(color, shift);
88 if (shift >= null_bits) {
89 *dst++ = val;
90
91 val = (shift == null_bits) ? 0 :
92 FB_SHIFT_LOW(color, 32 - shift);
93 }
94 shift += bpp;
95 shift &= (32 - 1);
96 src++;
97 }
98 if (shift) {
99 u32 end_mask = FB_SHIFT_HIGH(~(u32)0, shift);
100
101 *dst &= end_mask;
102 *dst |= val;
103 }
104 dst1 += p->fix.line_length;
105 if (pitch_index) {
106 dst2 += p->fix.line_length;
107 dst1 = (u8 *)((long)dst2 & ~(sizeof(u32) - 1));
108
109 start_index += pitch_index;
110 start_index &= 32 - 1;
111 }
112 }
113}
114
115static void slow_imageblit(const struct fb_image *image, struct fb_info *p,
116 void *dst1, u32 fgcolor, u32 bgcolor,
117 u32 start_index, u32 pitch_index)
118{
119 u32 shift, color = 0, bpp = p->var.bits_per_pixel;
120 u32 *dst, *dst2;
121 u32 val, pitch = p->fix.line_length;
122 u32 null_bits = 32 - bpp;
123 u32 spitch = (image->width+7)/8;
124 const u8 *src = image->data, *s;
125 u32 i, j, l;
126
127 dst2 = dst1;
128 fgcolor <<= FB_LEFT_POS(bpp);
129 bgcolor <<= FB_LEFT_POS(bpp);
130
131 for (i = image->height; i--; ) {
132 shift = val = 0;
133 l = 8;
134 j = image->width;
135 dst = dst1;
136 s = src;
137
138 /* write leading bits */
139 if (start_index) {
140 u32 start_mask = ~(FB_SHIFT_HIGH(~(u32)0,start_index));
141 val = *dst & start_mask;
142 shift = start_index;
143 }
144
145 while (j--) {
146 l--;
147 color = (*s & (1 << l)) ? fgcolor : bgcolor;
148 val |= FB_SHIFT_HIGH(color, shift);
149
150 /* Did the bitshift spill bits to the next long? */
151 if (shift >= null_bits) {
152 *dst++ = val;
153 val = (shift == null_bits) ? 0 :
154 FB_SHIFT_LOW(color,32 - shift);
155 }
156 shift += bpp;
157 shift &= (32 - 1);
158 if (!l) { l = 8; s++; };
159 }
160
161 /* write trailing bits */
162 if (shift) {
163 u32 end_mask = FB_SHIFT_HIGH(~(u32)0, shift);
164
165 *dst &= end_mask;
166 *dst |= val;
167 }
168
169 dst1 += pitch;
170 src += spitch;
171 if (pitch_index) {
172 dst2 += pitch;
173 dst1 = (u8 *)((long)dst2 & ~(sizeof(u32) - 1));
174 start_index += pitch_index;
175 start_index &= 32 - 1;
176 }
177
178 }
179}
180
181/*
182 * fast_imageblit - optimized monochrome color expansion
183 *
184 * Only if: bits_per_pixel == 8, 16, or 32
185 * image->width is divisible by pixel/dword (ppw);
186 * fix->line_legth is divisible by 4;
187 * beginning and end of a scanline is dword aligned
188 */
189static void fast_imageblit(const struct fb_image *image, struct fb_info *p,
190 void *dst1, u32 fgcolor, u32 bgcolor)
191{
192 u32 fgx = fgcolor, bgx = bgcolor, bpp = p->var.bits_per_pixel;
193 u32 ppw = 32/bpp, spitch = (image->width + 7)/8;
194 u32 bit_mask, end_mask, eorx, shift;
195 const char *s = image->data, *src;
196 u32 *dst;
197 const u32 *tab = NULL;
198 int i, j, k;
199
200 switch (bpp) {
201 case 8:
202 tab = cfb_tab8;
203 break;
204 case 16:
205 tab = cfb_tab16;
206 break;
207 case 32:
208 default:
209 tab = cfb_tab32;
210 break;
211 }
212
213 for (i = ppw-1; i--; ) {
214 fgx <<= bpp;
215 bgx <<= bpp;
216 fgx |= fgcolor;
217 bgx |= bgcolor;
218 }
219
220 bit_mask = (1 << ppw) - 1;
221 eorx = fgx ^ bgx;
222 k = image->width/ppw;
223
224 for (i = image->height; i--; ) {
225 dst = dst1;
226 shift = 8;
227 src = s;
228
229 for (j = k; j--; ) {
230 shift -= ppw;
231 end_mask = tab[(*src >> shift) & bit_mask];
232 *dst++ = (end_mask & eorx) ^ bgx;
233 if (!shift) {
234 shift = 8;
235 src++;
236 }
237 }
238 dst1 += p->fix.line_length;
239 s += spitch;
240 }
241}
242
243void sys_imageblit(struct fb_info *p, const struct fb_image *image)
244{
245 u32 fgcolor, bgcolor, start_index, bitstart, pitch_index = 0;
246 u32 bpl = sizeof(u32), bpp = p->var.bits_per_pixel;
247 u32 width = image->width;
248 u32 dx = image->dx, dy = image->dy;
249 void *dst1;
250
251 if (p->state != FBINFO_STATE_RUNNING)
252 return;
253
254 bitstart = (dy * p->fix.line_length * 8) + (dx * bpp);
255 start_index = bitstart & (32 - 1);
256 pitch_index = (p->fix.line_length & (bpl - 1)) * 8;
257
258 bitstart /= 8;
259 bitstart &= ~(bpl - 1);
260 dst1 = (void __force *)p->screen_base + bitstart;
261
262 if (p->fbops->fb_sync)
263 p->fbops->fb_sync(p);
264
265 if (image->depth == 1) {
266 if (p->fix.visual == FB_VISUAL_TRUECOLOR ||
267 p->fix.visual == FB_VISUAL_DIRECTCOLOR) {
268 fgcolor = ((u32*)(p->pseudo_palette))[image->fg_color];
269 bgcolor = ((u32*)(p->pseudo_palette))[image->bg_color];
270 } else {
271 fgcolor = image->fg_color;
272 bgcolor = image->bg_color;
273 }
274
275 if (32 % bpp == 0 && !start_index && !pitch_index &&
276 ((width & (32/bpp-1)) == 0) &&
277 bpp >= 8 && bpp <= 32)
278 fast_imageblit(image, p, dst1, fgcolor, bgcolor);
279 else
280 slow_imageblit(image, p, dst1, fgcolor, bgcolor,
281 start_index, pitch_index);
282 } else
283 color_imageblit(image, p, dst1, start_index, pitch_index);
284}
285
286EXPORT_SYMBOL(sys_imageblit);
287
288MODULE_AUTHOR("Antonino Daplas <adaplas@pol.net>");
289MODULE_DESCRIPTION("1-bit/8-bit to 1-32 bit color expansion (sys-to-sys)");
290MODULE_LICENSE("GPL");
291
diff --git a/drivers/video/tgafb.c b/drivers/video/tgafb.c
index 7478d0e3e211..f0fde6ea7c36 100644
--- a/drivers/video/tgafb.c
+++ b/drivers/video/tgafb.c
@@ -5,27 +5,45 @@
5 * Copyright (C) 1997 Geert Uytterhoeven 5 * Copyright (C) 1997 Geert Uytterhoeven
6 * Copyright (C) 1999,2000 Martin Lucina, Tom Zerucha 6 * Copyright (C) 1999,2000 Martin Lucina, Tom Zerucha
7 * Copyright (C) 2002 Richard Henderson 7 * Copyright (C) 2002 Richard Henderson
8 * Copyright (C) 2006 Maciej W. Rozycki
8 * 9 *
9 * This file is subject to the terms and conditions of the GNU General Public 10 * This file is subject to the terms and conditions of the GNU General Public
10 * License. See the file COPYING in the main directory of this archive for 11 * License. See the file COPYING in the main directory of this archive for
11 * more details. 12 * more details.
12 */ 13 */
13 14
14#include <linux/module.h> 15#include <linux/bitrev.h>
15#include <linux/kernel.h>
16#include <linux/errno.h>
17#include <linux/string.h>
18#include <linux/mm.h>
19#include <linux/slab.h>
20#include <linux/delay.h> 16#include <linux/delay.h>
21#include <linux/init.h> 17#include <linux/device.h>
18#include <linux/errno.h>
22#include <linux/fb.h> 19#include <linux/fb.h>
20#include <linux/init.h>
21#include <linux/ioport.h>
22#include <linux/kernel.h>
23#include <linux/mm.h>
24#include <linux/module.h>
23#include <linux/pci.h> 25#include <linux/pci.h>
24#include <linux/selection.h> 26#include <linux/selection.h>
25#include <linux/bitrev.h> 27#include <linux/slab.h>
28#include <linux/string.h>
29#include <linux/tc.h>
30
26#include <asm/io.h> 31#include <asm/io.h>
32
27#include <video/tgafb.h> 33#include <video/tgafb.h>
28 34
35#ifdef CONFIG_PCI
36#define TGA_BUS_PCI(dev) (dev->bus == &pci_bus_type)
37#else
38#define TGA_BUS_PCI(dev) 0
39#endif
40
41#ifdef CONFIG_TC
42#define TGA_BUS_TC(dev) (dev->bus == &tc_bus_type)
43#else
44#define TGA_BUS_TC(dev) 0
45#endif
46
29/* 47/*
30 * Local functions. 48 * Local functions.
31 */ 49 */
@@ -41,14 +59,19 @@ static void tgafb_init_fix(struct fb_info *);
41static void tgafb_imageblit(struct fb_info *, const struct fb_image *); 59static void tgafb_imageblit(struct fb_info *, const struct fb_image *);
42static void tgafb_fillrect(struct fb_info *, const struct fb_fillrect *); 60static void tgafb_fillrect(struct fb_info *, const struct fb_fillrect *);
43static void tgafb_copyarea(struct fb_info *, const struct fb_copyarea *); 61static void tgafb_copyarea(struct fb_info *, const struct fb_copyarea *);
62static int tgafb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info);
44 63
45static int __devinit tgafb_pci_register(struct pci_dev *, 64static int __devinit tgafb_register(struct device *dev);
46 const struct pci_device_id *); 65static void __devexit tgafb_unregister(struct device *dev);
47static void __devexit tgafb_pci_unregister(struct pci_dev *);
48 66
49static const char *mode_option = "640x480@60"; 67static const char *mode_option;
68static const char *mode_option_pci = "640x480@60";
69static const char *mode_option_tc = "1280x1024@72";
50 70
51 71
72static struct pci_driver tgafb_pci_driver;
73static struct tc_driver tgafb_tc_driver;
74
52/* 75/*
53 * Frame buffer operations 76 * Frame buffer operations
54 */ 77 */
@@ -59,15 +82,20 @@ static struct fb_ops tgafb_ops = {
59 .fb_set_par = tgafb_set_par, 82 .fb_set_par = tgafb_set_par,
60 .fb_setcolreg = tgafb_setcolreg, 83 .fb_setcolreg = tgafb_setcolreg,
61 .fb_blank = tgafb_blank, 84 .fb_blank = tgafb_blank,
85 .fb_pan_display = tgafb_pan_display,
62 .fb_fillrect = tgafb_fillrect, 86 .fb_fillrect = tgafb_fillrect,
63 .fb_copyarea = tgafb_copyarea, 87 .fb_copyarea = tgafb_copyarea,
64 .fb_imageblit = tgafb_imageblit, 88 .fb_imageblit = tgafb_imageblit,
65}; 89};
66 90
67 91
92#ifdef CONFIG_PCI
68/* 93/*
69 * PCI registration operations 94 * PCI registration operations
70 */ 95 */
96static int __devinit tgafb_pci_register(struct pci_dev *,
97 const struct pci_device_id *);
98static void __devexit tgafb_pci_unregister(struct pci_dev *);
71 99
72static struct pci_device_id const tgafb_pci_table[] = { 100static struct pci_device_id const tgafb_pci_table[] = {
73 { PCI_DEVICE(PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_TGA) }, 101 { PCI_DEVICE(PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_TGA) },
@@ -75,13 +103,68 @@ static struct pci_device_id const tgafb_pci_table[] = {
75}; 103};
76MODULE_DEVICE_TABLE(pci, tgafb_pci_table); 104MODULE_DEVICE_TABLE(pci, tgafb_pci_table);
77 105
78static struct pci_driver tgafb_driver = { 106static struct pci_driver tgafb_pci_driver = {
79 .name = "tgafb", 107 .name = "tgafb",
80 .id_table = tgafb_pci_table, 108 .id_table = tgafb_pci_table,
81 .probe = tgafb_pci_register, 109 .probe = tgafb_pci_register,
82 .remove = __devexit_p(tgafb_pci_unregister), 110 .remove = __devexit_p(tgafb_pci_unregister),
83}; 111};
84 112
113static int __devinit
114tgafb_pci_register(struct pci_dev *pdev, const struct pci_device_id *ent)
115{
116 return tgafb_register(&pdev->dev);
117}
118
119static void __devexit
120tgafb_pci_unregister(struct pci_dev *pdev)
121{
122 tgafb_unregister(&pdev->dev);
123}
124#endif /* CONFIG_PCI */
125
126#ifdef CONFIG_TC
127/*
128 * TC registration operations
129 */
130static int __devinit tgafb_tc_register(struct device *);
131static int __devexit tgafb_tc_unregister(struct device *);
132
133static struct tc_device_id const tgafb_tc_table[] = {
134 { "DEC ", "PMAGD-AA" },
135 { "DEC ", "PMAGD " },
136 { }
137};
138MODULE_DEVICE_TABLE(tc, tgafb_tc_table);
139
140static struct tc_driver tgafb_tc_driver = {
141 .id_table = tgafb_tc_table,
142 .driver = {
143 .name = "tgafb",
144 .bus = &tc_bus_type,
145 .probe = tgafb_tc_register,
146 .remove = __devexit_p(tgafb_tc_unregister),
147 },
148};
149
150static int __devinit
151tgafb_tc_register(struct device *dev)
152{
153 int status = tgafb_register(dev);
154 if (!status)
155 get_device(dev);
156 return status;
157}
158
159static int __devexit
160tgafb_tc_unregister(struct device *dev)
161{
162 put_device(dev);
163 tgafb_unregister(dev);
164 return 0;
165}
166#endif /* CONFIG_TC */
167
85 168
86/** 169/**
87 * tgafb_check_var - Optional function. Validates a var passed in. 170 * tgafb_check_var - Optional function. Validates a var passed in.
@@ -132,10 +215,10 @@ static int
132tgafb_set_par(struct fb_info *info) 215tgafb_set_par(struct fb_info *info)
133{ 216{
134 static unsigned int const deep_presets[4] = { 217 static unsigned int const deep_presets[4] = {
135 0x00014000, 218 0x00004000,
136 0x0001440d, 219 0x0000440d,
137 0xffffffff, 220 0xffffffff,
138 0x0001441d 221 0x0000441d
139 }; 222 };
140 static unsigned int const rasterop_presets[4] = { 223 static unsigned int const rasterop_presets[4] = {
141 0x00000003, 224 0x00000003,
@@ -157,6 +240,8 @@ tgafb_set_par(struct fb_info *info)
157 }; 240 };
158 241
159 struct tga_par *par = (struct tga_par *) info->par; 242 struct tga_par *par = (struct tga_par *) info->par;
243 int tga_bus_pci = TGA_BUS_PCI(par->dev);
244 int tga_bus_tc = TGA_BUS_TC(par->dev);
160 u32 htimings, vtimings, pll_freq; 245 u32 htimings, vtimings, pll_freq;
161 u8 tga_type; 246 u8 tga_type;
162 int i; 247 int i;
@@ -221,7 +306,7 @@ tgafb_set_par(struct fb_info *info)
221 TGA_WRITE_REG(par, vtimings, TGA_VERT_REG); 306 TGA_WRITE_REG(par, vtimings, TGA_VERT_REG);
222 307
223 /* Initalise RAMDAC. */ 308 /* Initalise RAMDAC. */
224 if (tga_type == TGA_TYPE_8PLANE) { 309 if (tga_type == TGA_TYPE_8PLANE && tga_bus_pci) {
225 310
226 /* Init BT485 RAMDAC registers. */ 311 /* Init BT485 RAMDAC registers. */
227 BT485_WRITE(par, 0xa2 | (par->sync_on_green ? 0x8 : 0x0), 312 BT485_WRITE(par, 0xa2 | (par->sync_on_green ? 0x8 : 0x0),
@@ -236,21 +321,7 @@ tgafb_set_par(struct fb_info *info)
236 BT485_WRITE(par, 0x00, BT485_ADDR_PAL_WRITE); 321 BT485_WRITE(par, 0x00, BT485_ADDR_PAL_WRITE);
237 TGA_WRITE_REG(par, BT485_DATA_PAL, TGA_RAMDAC_SETUP_REG); 322 TGA_WRITE_REG(par, BT485_DATA_PAL, TGA_RAMDAC_SETUP_REG);
238 323
239#ifdef CONFIG_HW_CONSOLE
240 for (i = 0; i < 16; i++) {
241 int j = color_table[i];
242
243 TGA_WRITE_REG(par, default_red[j]|(BT485_DATA_PAL<<8),
244 TGA_RAMDAC_REG);
245 TGA_WRITE_REG(par, default_grn[j]|(BT485_DATA_PAL<<8),
246 TGA_RAMDAC_REG);
247 TGA_WRITE_REG(par, default_blu[j]|(BT485_DATA_PAL<<8),
248 TGA_RAMDAC_REG);
249 }
250 for (i = 0; i < 240 * 3; i += 4) {
251#else
252 for (i = 0; i < 256 * 3; i += 4) { 324 for (i = 0; i < 256 * 3; i += 4) {
253#endif
254 TGA_WRITE_REG(par, 0x55 | (BT485_DATA_PAL << 8), 325 TGA_WRITE_REG(par, 0x55 | (BT485_DATA_PAL << 8),
255 TGA_RAMDAC_REG); 326 TGA_RAMDAC_REG);
256 TGA_WRITE_REG(par, 0x00 | (BT485_DATA_PAL << 8), 327 TGA_WRITE_REG(par, 0x00 | (BT485_DATA_PAL << 8),
@@ -261,6 +332,27 @@ tgafb_set_par(struct fb_info *info)
261 TGA_RAMDAC_REG); 332 TGA_RAMDAC_REG);
262 } 333 }
263 334
335 } else if (tga_type == TGA_TYPE_8PLANE && tga_bus_tc) {
336
337 /* Init BT459 RAMDAC registers. */
338 BT459_WRITE(par, BT459_REG_ACC, BT459_CMD_REG_0, 0x40);
339 BT459_WRITE(par, BT459_REG_ACC, BT459_CMD_REG_1, 0x00);
340 BT459_WRITE(par, BT459_REG_ACC, BT459_CMD_REG_2,
341 (par->sync_on_green ? 0xc0 : 0x40));
342
343 BT459_WRITE(par, BT459_REG_ACC, BT459_CUR_CMD_REG, 0x00);
344
345 /* Fill the palette. */
346 BT459_LOAD_ADDR(par, 0x0000);
347 TGA_WRITE_REG(par, BT459_PALETTE << 2, TGA_RAMDAC_SETUP_REG);
348
349 for (i = 0; i < 256 * 3; i += 4) {
350 TGA_WRITE_REG(par, 0x55, TGA_RAMDAC_REG);
351 TGA_WRITE_REG(par, 0x00, TGA_RAMDAC_REG);
352 TGA_WRITE_REG(par, 0x00, TGA_RAMDAC_REG);
353 TGA_WRITE_REG(par, 0x00, TGA_RAMDAC_REG);
354 }
355
264 } else { /* 24-plane or 24plusZ */ 356 } else { /* 24-plane or 24plusZ */
265 357
266 /* Init BT463 RAMDAC registers. */ 358 /* Init BT463 RAMDAC registers. */
@@ -431,6 +523,8 @@ tgafb_setcolreg(unsigned regno, unsigned red, unsigned green, unsigned blue,
431 unsigned transp, struct fb_info *info) 523 unsigned transp, struct fb_info *info)
432{ 524{
433 struct tga_par *par = (struct tga_par *) info->par; 525 struct tga_par *par = (struct tga_par *) info->par;
526 int tga_bus_pci = TGA_BUS_PCI(par->dev);
527 int tga_bus_tc = TGA_BUS_TC(par->dev);
434 528
435 if (regno > 255) 529 if (regno > 255)
436 return 1; 530 return 1;
@@ -438,12 +532,18 @@ tgafb_setcolreg(unsigned regno, unsigned red, unsigned green, unsigned blue,
438 green >>= 8; 532 green >>= 8;
439 blue >>= 8; 533 blue >>= 8;
440 534
441 if (par->tga_type == TGA_TYPE_8PLANE) { 535 if (par->tga_type == TGA_TYPE_8PLANE && tga_bus_pci) {
442 BT485_WRITE(par, regno, BT485_ADDR_PAL_WRITE); 536 BT485_WRITE(par, regno, BT485_ADDR_PAL_WRITE);
443 TGA_WRITE_REG(par, BT485_DATA_PAL, TGA_RAMDAC_SETUP_REG); 537 TGA_WRITE_REG(par, BT485_DATA_PAL, TGA_RAMDAC_SETUP_REG);
444 TGA_WRITE_REG(par, red|(BT485_DATA_PAL<<8),TGA_RAMDAC_REG); 538 TGA_WRITE_REG(par, red|(BT485_DATA_PAL<<8),TGA_RAMDAC_REG);
445 TGA_WRITE_REG(par, green|(BT485_DATA_PAL<<8),TGA_RAMDAC_REG); 539 TGA_WRITE_REG(par, green|(BT485_DATA_PAL<<8),TGA_RAMDAC_REG);
446 TGA_WRITE_REG(par, blue|(BT485_DATA_PAL<<8),TGA_RAMDAC_REG); 540 TGA_WRITE_REG(par, blue|(BT485_DATA_PAL<<8),TGA_RAMDAC_REG);
541 } else if (par->tga_type == TGA_TYPE_8PLANE && tga_bus_tc) {
542 BT459_LOAD_ADDR(par, regno);
543 TGA_WRITE_REG(par, BT459_PALETTE << 2, TGA_RAMDAC_SETUP_REG);
544 TGA_WRITE_REG(par, red, TGA_RAMDAC_REG);
545 TGA_WRITE_REG(par, green, TGA_RAMDAC_REG);
546 TGA_WRITE_REG(par, blue, TGA_RAMDAC_REG);
447 } else { 547 } else {
448 if (regno < 16) { 548 if (regno < 16) {
449 u32 value = (regno << 16) | (regno << 8) | regno; 549 u32 value = (regno << 16) | (regno << 8) | regno;
@@ -523,16 +623,8 @@ tgafb_blank(int blank, struct fb_info *info)
523 * Acceleration. 623 * Acceleration.
524 */ 624 */
525 625
526/**
527 * tgafb_imageblit - REQUIRED function. Can use generic routines if
528 * non acclerated hardware and packed pixel based.
529 * Copies a image from system memory to the screen.
530 *
531 * @info: frame buffer structure that represents a single frame buffer
532 * @image: structure defining the image.
533 */
534static void 626static void
535tgafb_imageblit(struct fb_info *info, const struct fb_image *image) 627tgafb_mono_imageblit(struct fb_info *info, const struct fb_image *image)
536{ 628{
537 struct tga_par *par = (struct tga_par *) info->par; 629 struct tga_par *par = (struct tga_par *) info->par;
538 u32 fgcolor, bgcolor, dx, dy, width, height, vxres, vyres, pixelmask; 630 u32 fgcolor, bgcolor, dx, dy, width, height, vxres, vyres, pixelmask;
@@ -542,6 +634,17 @@ tgafb_imageblit(struct fb_info *info, const struct fb_image *image)
542 void __iomem *regs_base; 634 void __iomem *regs_base;
543 void __iomem *fb_base; 635 void __iomem *fb_base;
544 636
637 is8bpp = info->var.bits_per_pixel == 8;
638
639 /* For copies that aren't pixel expansion, there's little we
640 can do better than the generic code. */
641 /* ??? There is a DMA write mode; I wonder if that could be
642 made to pull the data from the image buffer... */
643 if (image->depth > 1) {
644 cfb_imageblit(info, image);
645 return;
646 }
647
545 dx = image->dx; 648 dx = image->dx;
546 dy = image->dy; 649 dy = image->dy;
547 width = image->width; 650 width = image->width;
@@ -559,18 +662,8 @@ tgafb_imageblit(struct fb_info *info, const struct fb_image *image)
559 if (dy + height > vyres) 662 if (dy + height > vyres)
560 height = vyres - dy; 663 height = vyres - dy;
561 664
562 /* For copies that aren't pixel expansion, there's little we
563 can do better than the generic code. */
564 /* ??? There is a DMA write mode; I wonder if that could be
565 made to pull the data from the image buffer... */
566 if (image->depth > 1) {
567 cfb_imageblit(info, image);
568 return;
569 }
570
571 regs_base = par->tga_regs_base; 665 regs_base = par->tga_regs_base;
572 fb_base = par->tga_fb_base; 666 fb_base = par->tga_fb_base;
573 is8bpp = info->var.bits_per_pixel == 8;
574 667
575 /* Expand the color values to fill 32-bits. */ 668 /* Expand the color values to fill 32-bits. */
576 /* ??? Would be nice to notice colour changes elsewhere, so 669 /* ??? Would be nice to notice colour changes elsewhere, so
@@ -748,6 +841,85 @@ tgafb_imageblit(struct fb_info *info, const struct fb_image *image)
748 regs_base + TGA_MODE_REG); 841 regs_base + TGA_MODE_REG);
749} 842}
750 843
844static void
845tgafb_clut_imageblit(struct fb_info *info, const struct fb_image *image)
846{
847 struct tga_par *par = (struct tga_par *) info->par;
848 u32 color, dx, dy, width, height, vxres, vyres;
849 u32 *palette = ((u32 *)info->pseudo_palette);
850 unsigned long pos, line_length, i, j;
851 const unsigned char *data;
852 void *regs_base, *fb_base;
853
854 dx = image->dx;
855 dy = image->dy;
856 width = image->width;
857 height = image->height;
858 vxres = info->var.xres_virtual;
859 vyres = info->var.yres_virtual;
860 line_length = info->fix.line_length;
861
862 /* Crop the image to the screen. */
863 if (dx > vxres || dy > vyres)
864 return;
865 if (dx + width > vxres)
866 width = vxres - dx;
867 if (dy + height > vyres)
868 height = vyres - dy;
869
870 regs_base = par->tga_regs_base;
871 fb_base = par->tga_fb_base;
872
873 pos = dy * line_length + (dx * 4);
874 data = image->data;
875
876 /* Now copy the image, color_expanding via the palette. */
877 for (i = 0; i < height; i++) {
878 for (j = 0; j < width; j++) {
879 color = palette[*data++];
880 __raw_writel(color, fb_base + pos + j*4);
881 }
882 pos += line_length;
883 }
884}
885
886/**
887 * tgafb_imageblit - REQUIRED function. Can use generic routines if
888 * non acclerated hardware and packed pixel based.
889 * Copies a image from system memory to the screen.
890 *
891 * @info: frame buffer structure that represents a single frame buffer
892 * @image: structure defining the image.
893 */
894static void
895tgafb_imageblit(struct fb_info *info, const struct fb_image *image)
896{
897 unsigned int is8bpp = info->var.bits_per_pixel == 8;
898
899 /* If a mono image, regardless of FB depth, go do it. */
900 if (image->depth == 1) {
901 tgafb_mono_imageblit(info, image);
902 return;
903 }
904
905 /* For copies that aren't pixel expansion, there's little we
906 can do better than the generic code. */
907 /* ??? There is a DMA write mode; I wonder if that could be
908 made to pull the data from the image buffer... */
909 if (image->depth == info->var.bits_per_pixel) {
910 cfb_imageblit(info, image);
911 return;
912 }
913
914 /* If 24-plane FB and the image is 8-plane with CLUT, we can do it. */
915 if (!is8bpp && image->depth == 8) {
916 tgafb_clut_imageblit(info, image);
917 return;
918 }
919
920 /* Silently return... */
921}
922
751/** 923/**
752 * tgafb_fillrect - REQUIRED function. Can use generic routines if 924 * tgafb_fillrect - REQUIRED function. Can use generic routines if
753 * non acclerated hardware and packed pixel based. 925 * non acclerated hardware and packed pixel based.
@@ -1309,18 +1481,29 @@ static void
1309tgafb_init_fix(struct fb_info *info) 1481tgafb_init_fix(struct fb_info *info)
1310{ 1482{
1311 struct tga_par *par = (struct tga_par *)info->par; 1483 struct tga_par *par = (struct tga_par *)info->par;
1484 int tga_bus_pci = TGA_BUS_PCI(par->dev);
1485 int tga_bus_tc = TGA_BUS_TC(par->dev);
1312 u8 tga_type = par->tga_type; 1486 u8 tga_type = par->tga_type;
1313 const char *tga_type_name; 1487 const char *tga_type_name = NULL;
1314 1488
1315 switch (tga_type) { 1489 switch (tga_type) {
1316 case TGA_TYPE_8PLANE: 1490 case TGA_TYPE_8PLANE:
1317 tga_type_name = "Digital ZLXp-E1"; 1491 if (tga_bus_pci)
1492 tga_type_name = "Digital ZLXp-E1";
1493 if (tga_bus_tc)
1494 tga_type_name = "Digital ZLX-E1";
1318 break; 1495 break;
1319 case TGA_TYPE_24PLANE: 1496 case TGA_TYPE_24PLANE:
1320 tga_type_name = "Digital ZLXp-E2"; 1497 if (tga_bus_pci)
1498 tga_type_name = "Digital ZLXp-E2";
1499 if (tga_bus_tc)
1500 tga_type_name = "Digital ZLX-E2";
1321 break; 1501 break;
1322 case TGA_TYPE_24PLUSZ: 1502 case TGA_TYPE_24PLUSZ:
1323 tga_type_name = "Digital ZLXp-E3"; 1503 if (tga_bus_pci)
1504 tga_type_name = "Digital ZLXp-E3";
1505 if (tga_bus_tc)
1506 tga_type_name = "Digital ZLX-E3";
1324 break; 1507 break;
1325 default: 1508 default:
1326 tga_type_name = "Unknown"; 1509 tga_type_name = "Unknown";
@@ -1346,11 +1529,37 @@ tgafb_init_fix(struct fb_info *info)
1346 info->fix.ywrapstep = 0; 1529 info->fix.ywrapstep = 0;
1347 1530
1348 info->fix.accel = FB_ACCEL_DEC_TGA; 1531 info->fix.accel = FB_ACCEL_DEC_TGA;
1532
1533 /*
1534 * These are needed by fb_set_logo_truepalette(), so we
1535 * set them here for 24-plane cards.
1536 */
1537 if (tga_type != TGA_TYPE_8PLANE) {
1538 info->var.red.length = 8;
1539 info->var.green.length = 8;
1540 info->var.blue.length = 8;
1541 info->var.red.offset = 16;
1542 info->var.green.offset = 8;
1543 info->var.blue.offset = 0;
1544 }
1349} 1545}
1350 1546
1351static __devinit int 1547static int tgafb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info)
1352tgafb_pci_register(struct pci_dev *pdev, const struct pci_device_id *ent) 1548{
1549 /* We just use this to catch switches out of graphics mode. */
1550 tgafb_set_par(info); /* A bit of overkill for BASE_ADDR reset. */
1551 return 0;
1552}
1553
1554static int __devinit
1555tgafb_register(struct device *dev)
1353{ 1556{
1557 static const struct fb_videomode modedb_tc = {
1558 /* 1280x1024 @ 72 Hz, 76.8 kHz hsync */
1559 "1280x1024@72", 0, 1280, 1024, 7645, 224, 28, 33, 3, 160, 3,
1560 FB_SYNC_ON_GREEN, FB_VMODE_NONINTERLACED
1561 };
1562
1354 static unsigned int const fb_offset_presets[4] = { 1563 static unsigned int const fb_offset_presets[4] = {
1355 TGA_8PLANE_FB_OFFSET, 1564 TGA_8PLANE_FB_OFFSET,
1356 TGA_24PLANE_FB_OFFSET, 1565 TGA_24PLANE_FB_OFFSET,
@@ -1358,40 +1567,51 @@ tgafb_pci_register(struct pci_dev *pdev, const struct pci_device_id *ent)
1358 TGA_24PLUSZ_FB_OFFSET 1567 TGA_24PLUSZ_FB_OFFSET
1359 }; 1568 };
1360 1569
1570 const struct fb_videomode *modedb_tga = NULL;
1571 resource_size_t bar0_start = 0, bar0_len = 0;
1572 const char *mode_option_tga = NULL;
1573 int tga_bus_pci = TGA_BUS_PCI(dev);
1574 int tga_bus_tc = TGA_BUS_TC(dev);
1575 unsigned int modedbsize_tga = 0;
1361 void __iomem *mem_base; 1576 void __iomem *mem_base;
1362 unsigned long bar0_start, bar0_len;
1363 struct fb_info *info; 1577 struct fb_info *info;
1364 struct tga_par *par; 1578 struct tga_par *par;
1365 u8 tga_type; 1579 u8 tga_type;
1366 int ret; 1580 int ret = 0;
1367 1581
1368 /* Enable device in PCI config. */ 1582 /* Enable device in PCI config. */
1369 if (pci_enable_device(pdev)) { 1583 if (tga_bus_pci && pci_enable_device(to_pci_dev(dev))) {
1370 printk(KERN_ERR "tgafb: Cannot enable PCI device\n"); 1584 printk(KERN_ERR "tgafb: Cannot enable PCI device\n");
1371 return -ENODEV; 1585 return -ENODEV;
1372 } 1586 }
1373 1587
1374 /* Allocate the fb and par structures. */ 1588 /* Allocate the fb and par structures. */
1375 info = framebuffer_alloc(sizeof(struct tga_par), &pdev->dev); 1589 info = framebuffer_alloc(sizeof(struct tga_par), dev);
1376 if (!info) { 1590 if (!info) {
1377 printk(KERN_ERR "tgafb: Cannot allocate memory\n"); 1591 printk(KERN_ERR "tgafb: Cannot allocate memory\n");
1378 return -ENOMEM; 1592 return -ENOMEM;
1379 } 1593 }
1380 1594
1381 par = info->par; 1595 par = info->par;
1382 pci_set_drvdata(pdev, info); 1596 dev_set_drvdata(dev, info);
1383 1597
1384 /* Request the mem regions. */ 1598 /* Request the mem regions. */
1385 bar0_start = pci_resource_start(pdev, 0);
1386 bar0_len = pci_resource_len(pdev, 0);
1387 ret = -ENODEV; 1599 ret = -ENODEV;
1600 if (tga_bus_pci) {
1601 bar0_start = pci_resource_start(to_pci_dev(dev), 0);
1602 bar0_len = pci_resource_len(to_pci_dev(dev), 0);
1603 }
1604 if (tga_bus_tc) {
1605 bar0_start = to_tc_dev(dev)->resource.start;
1606 bar0_len = to_tc_dev(dev)->resource.end - bar0_start + 1;
1607 }
1388 if (!request_mem_region (bar0_start, bar0_len, "tgafb")) { 1608 if (!request_mem_region (bar0_start, bar0_len, "tgafb")) {
1389 printk(KERN_ERR "tgafb: cannot reserve FB region\n"); 1609 printk(KERN_ERR "tgafb: cannot reserve FB region\n");
1390 goto err0; 1610 goto err0;
1391 } 1611 }
1392 1612
1393 /* Map the framebuffer. */ 1613 /* Map the framebuffer. */
1394 mem_base = ioremap(bar0_start, bar0_len); 1614 mem_base = ioremap_nocache(bar0_start, bar0_len);
1395 if (!mem_base) { 1615 if (!mem_base) {
1396 printk(KERN_ERR "tgafb: Cannot map MMIO\n"); 1616 printk(KERN_ERR "tgafb: Cannot map MMIO\n");
1397 goto err1; 1617 goto err1;
@@ -1399,12 +1619,16 @@ tgafb_pci_register(struct pci_dev *pdev, const struct pci_device_id *ent)
1399 1619
1400 /* Grab info about the card. */ 1620 /* Grab info about the card. */
1401 tga_type = (readl(mem_base) >> 12) & 0x0f; 1621 tga_type = (readl(mem_base) >> 12) & 0x0f;
1402 par->pdev = pdev; 1622 par->dev = dev;
1403 par->tga_mem_base = mem_base; 1623 par->tga_mem_base = mem_base;
1404 par->tga_fb_base = mem_base + fb_offset_presets[tga_type]; 1624 par->tga_fb_base = mem_base + fb_offset_presets[tga_type];
1405 par->tga_regs_base = mem_base + TGA_REGS_OFFSET; 1625 par->tga_regs_base = mem_base + TGA_REGS_OFFSET;
1406 par->tga_type = tga_type; 1626 par->tga_type = tga_type;
1407 pci_read_config_byte(pdev, PCI_REVISION_ID, &par->tga_chip_rev); 1627 if (tga_bus_pci)
1628 pci_read_config_byte(to_pci_dev(dev), PCI_REVISION_ID,
1629 &par->tga_chip_rev);
1630 if (tga_bus_tc)
1631 par->tga_chip_rev = TGA_READ_REG(par, TGA_START_REG) & 0xff;
1408 1632
1409 /* Setup framebuffer. */ 1633 /* Setup framebuffer. */
1410 info->flags = FBINFO_DEFAULT | FBINFO_HWACCEL_COPYAREA | 1634 info->flags = FBINFO_DEFAULT | FBINFO_HWACCEL_COPYAREA |
@@ -1414,8 +1638,17 @@ tgafb_pci_register(struct pci_dev *pdev, const struct pci_device_id *ent)
1414 info->pseudo_palette = (void *)(par + 1); 1638 info->pseudo_palette = (void *)(par + 1);
1415 1639
1416 /* This should give a reasonable default video mode. */ 1640 /* This should give a reasonable default video mode. */
1417 1641 if (tga_bus_pci) {
1418 ret = fb_find_mode(&info->var, info, mode_option, NULL, 0, NULL, 1642 mode_option_tga = mode_option_pci;
1643 }
1644 if (tga_bus_tc) {
1645 mode_option_tga = mode_option_tc;
1646 modedb_tga = &modedb_tc;
1647 modedbsize_tga = 1;
1648 }
1649 ret = fb_find_mode(&info->var, info,
1650 mode_option ? mode_option : mode_option_tga,
1651 modedb_tga, modedbsize_tga, NULL,
1419 tga_type == TGA_TYPE_8PLANE ? 8 : 32); 1652 tga_type == TGA_TYPE_8PLANE ? 8 : 32);
1420 if (ret == 0 || ret == 4) { 1653 if (ret == 0 || ret == 4) {
1421 printk(KERN_ERR "tgafb: Could not find valid video mode\n"); 1654 printk(KERN_ERR "tgafb: Could not find valid video mode\n");
@@ -1438,13 +1671,19 @@ tgafb_pci_register(struct pci_dev *pdev, const struct pci_device_id *ent)
1438 goto err1; 1671 goto err1;
1439 } 1672 }
1440 1673
1441 printk(KERN_INFO "tgafb: DC21030 [TGA] detected, rev=0x%02x\n", 1674 if (tga_bus_pci) {
1442 par->tga_chip_rev); 1675 pr_info("tgafb: DC21030 [TGA] detected, rev=0x%02x\n",
1443 printk(KERN_INFO "tgafb: at PCI bus %d, device %d, function %d\n", 1676 par->tga_chip_rev);
1444 pdev->bus->number, PCI_SLOT(pdev->devfn), 1677 pr_info("tgafb: at PCI bus %d, device %d, function %d\n",
1445 PCI_FUNC(pdev->devfn)); 1678 to_pci_dev(dev)->bus->number,
1446 printk(KERN_INFO "fb%d: %s frame buffer device at 0x%lx\n", 1679 PCI_SLOT(to_pci_dev(dev)->devfn),
1447 info->node, info->fix.id, bar0_start); 1680 PCI_FUNC(to_pci_dev(dev)->devfn));
1681 }
1682 if (tga_bus_tc)
1683 pr_info("tgafb: SFB+ detected, rev=0x%02x\n",
1684 par->tga_chip_rev);
1685 pr_info("fb%d: %s frame buffer device at 0x%lx\n",
1686 info->node, info->fix.id, (long)bar0_start);
1448 1687
1449 return 0; 1688 return 0;
1450 1689
@@ -1458,25 +1697,39 @@ tgafb_pci_register(struct pci_dev *pdev, const struct pci_device_id *ent)
1458} 1697}
1459 1698
1460static void __devexit 1699static void __devexit
1461tgafb_pci_unregister(struct pci_dev *pdev) 1700tgafb_unregister(struct device *dev)
1462{ 1701{
1463 struct fb_info *info = pci_get_drvdata(pdev); 1702 resource_size_t bar0_start = 0, bar0_len = 0;
1464 struct tga_par *par = info->par; 1703 int tga_bus_pci = TGA_BUS_PCI(dev);
1704 int tga_bus_tc = TGA_BUS_TC(dev);
1705 struct fb_info *info = NULL;
1706 struct tga_par *par;
1465 1707
1708 info = dev_get_drvdata(dev);
1466 if (!info) 1709 if (!info)
1467 return; 1710 return;
1711
1712 par = info->par;
1468 unregister_framebuffer(info); 1713 unregister_framebuffer(info);
1469 fb_dealloc_cmap(&info->cmap); 1714 fb_dealloc_cmap(&info->cmap);
1470 iounmap(par->tga_mem_base); 1715 iounmap(par->tga_mem_base);
1471 release_mem_region(pci_resource_start(pdev, 0), 1716 if (tga_bus_pci) {
1472 pci_resource_len(pdev, 0)); 1717 bar0_start = pci_resource_start(to_pci_dev(dev), 0);
1718 bar0_len = pci_resource_len(to_pci_dev(dev), 0);
1719 }
1720 if (tga_bus_tc) {
1721 bar0_start = to_tc_dev(dev)->resource.start;
1722 bar0_len = to_tc_dev(dev)->resource.end - bar0_start + 1;
1723 }
1724 release_mem_region(bar0_start, bar0_len);
1473 framebuffer_release(info); 1725 framebuffer_release(info);
1474} 1726}
1475 1727
1476static void __devexit 1728static void __devexit
1477tgafb_exit(void) 1729tgafb_exit(void)
1478{ 1730{
1479 pci_unregister_driver(&tgafb_driver); 1731 tc_unregister_driver(&tgafb_tc_driver);
1732 pci_unregister_driver(&tgafb_pci_driver);
1480} 1733}
1481 1734
1482#ifndef MODULE 1735#ifndef MODULE
@@ -1505,6 +1758,7 @@ tgafb_setup(char *arg)
1505static int __devinit 1758static int __devinit
1506tgafb_init(void) 1759tgafb_init(void)
1507{ 1760{
1761 int status;
1508#ifndef MODULE 1762#ifndef MODULE
1509 char *option = NULL; 1763 char *option = NULL;
1510 1764
@@ -1512,7 +1766,10 @@ tgafb_init(void)
1512 return -ENODEV; 1766 return -ENODEV;
1513 tgafb_setup(option); 1767 tgafb_setup(option);
1514#endif 1768#endif
1515 return pci_register_driver(&tgafb_driver); 1769 status = pci_register_driver(&tgafb_pci_driver);
1770 if (!status)
1771 status = tc_register_driver(&tgafb_tc_driver);
1772 return status;
1516} 1773}
1517 1774
1518/* 1775/*
@@ -1522,5 +1779,5 @@ tgafb_init(void)
1522module_init(tgafb_init); 1779module_init(tgafb_init);
1523module_exit(tgafb_exit); 1780module_exit(tgafb_exit);
1524 1781
1525MODULE_DESCRIPTION("framebuffer driver for TGA chipset"); 1782MODULE_DESCRIPTION("Framebuffer driver for TGA/SFB+ chipset");
1526MODULE_LICENSE("GPL"); 1783MODULE_LICENSE("GPL");
diff --git a/drivers/video/vermilion/Makefile b/drivers/video/vermilion/Makefile
new file mode 100644
index 000000000000..cc21a656153d
--- /dev/null
+++ b/drivers/video/vermilion/Makefile
@@ -0,0 +1,5 @@
1obj-$(CONFIG_FB_LE80578) += vmlfb.o
2obj-$(CONFIG_FB_CARILLO_RANCH) += crvml.o
3
4vmlfb-objs := vermilion.o
5crvml-objs := cr_pll.o
diff --git a/drivers/video/vermilion/cr_pll.c b/drivers/video/vermilion/cr_pll.c
new file mode 100644
index 000000000000..ebc6e6e0dd0f
--- /dev/null
+++ b/drivers/video/vermilion/cr_pll.c
@@ -0,0 +1,208 @@
1/*
2 * Copyright (c) Intel Corp. 2007.
3 * All Rights Reserved.
4 *
5 * Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to
6 * develop this driver.
7 *
8 * This file is part of the Carillo Ranch video subsystem driver.
9 * The Carillo Ranch video subsystem driver is free software;
10 * you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * The Carillo Ranch video subsystem driver is distributed
16 * in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this driver; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
24 *
25 * Authors:
26 * Thomas Hellstrom <thomas-at-tungstengraphics-dot-com>
27 * Alan Hourihane <alanh-at-tungstengraphics-dot-com>
28 */
29
30#include <linux/module.h>
31#include <linux/kernel.h>
32#include <linux/pci.h>
33#include <linux/errno.h>
34#include <linux/fb.h>
35#include "vermilion.h"
36
37/* The PLL Clock register sits on Host bridge */
38#define CRVML_DEVICE_MCH 0x5001
39#define CRVML_REG_MCHBAR 0x44
40#define CRVML_REG_MCHEN 0x54
41#define CRVML_MCHEN_BIT (1 << 28)
42#define CRVML_MCHMAP_SIZE 4096
43#define CRVML_REG_CLOCK 0xc3c
44#define CRVML_CLOCK_SHIFT 8
45#define CRVML_CLOCK_MASK 0x00000f00
46
47static struct pci_dev *mch_dev;
48static u32 mch_bar;
49static void __iomem *mch_regs_base;
50static u32 saved_clock;
51
52static const unsigned crvml_clocks[] = {
53 6750,
54 13500,
55 27000,
56 29700,
57 37125,
58 54000,
59 59400,
60 74250,
61 120000
62 /*
63 * There are more clocks, but they are disabled on the CR board.
64 */
65};
66
67static const u32 crvml_clock_bits[] = {
68 0x0a,
69 0x09,
70 0x08,
71 0x07,
72 0x06,
73 0x05,
74 0x04,
75 0x03,
76 0x0b
77};
78
79static const unsigned crvml_num_clocks = ARRAY_SIZE(crvml_clocks);
80
81static int crvml_sys_restore(struct vml_sys *sys)
82{
83 void __iomem *clock_reg = mch_regs_base + CRVML_REG_CLOCK;
84
85 iowrite32(saved_clock, clock_reg);
86 ioread32(clock_reg);
87
88 return 0;
89}
90
91static int crvml_sys_save(struct vml_sys *sys)
92{
93 void __iomem *clock_reg = mch_regs_base + CRVML_REG_CLOCK;
94
95 saved_clock = ioread32(clock_reg);
96
97 return 0;
98}
99
100static int crvml_nearest_index(const struct vml_sys *sys, int clock)
101{
102 int i;
103 int cur_index = 0;
104 int cur_diff;
105 int diff;
106
107 cur_diff = clock - crvml_clocks[0];
108 cur_diff = (cur_diff < 0) ? -cur_diff : cur_diff;
109 for (i = 1; i < crvml_num_clocks; ++i) {
110 diff = clock - crvml_clocks[i];
111 diff = (diff < 0) ? -diff : diff;
112 if (diff < cur_diff) {
113 cur_index = i;
114 cur_diff = diff;
115 }
116 }
117 return cur_index;
118}
119
120static int crvml_nearest_clock(const struct vml_sys *sys, int clock)
121{
122 return crvml_clocks[crvml_nearest_index(sys, clock)];
123}
124
125static int crvml_set_clock(struct vml_sys *sys, int clock)
126{
127 void __iomem *clock_reg = mch_regs_base + CRVML_REG_CLOCK;
128 int index;
129 u32 clock_val;
130
131 index = crvml_nearest_index(sys, clock);
132
133 if (crvml_clocks[index] != clock)
134 return -EINVAL;
135
136 clock_val = ioread32(clock_reg) & ~CRVML_CLOCK_MASK;
137 clock_val = crvml_clock_bits[index] << CRVML_CLOCK_SHIFT;
138 iowrite32(clock_val, clock_reg);
139 ioread32(clock_reg);
140
141 return 0;
142}
143
144static struct vml_sys cr_pll_ops = {
145 .name = "Carillo Ranch",
146 .save = crvml_sys_save,
147 .restore = crvml_sys_restore,
148 .set_clock = crvml_set_clock,
149 .nearest_clock = crvml_nearest_clock,
150};
151
152static int __init cr_pll_init(void)
153{
154 int err;
155 u32 dev_en;
156
157 mch_dev = pci_get_device(PCI_VENDOR_ID_INTEL,
158 CRVML_DEVICE_MCH, NULL);
159 if (!mch_dev) {
160 printk(KERN_ERR
161 "Could not find Carillo Ranch MCH device.\n");
162 return -ENODEV;
163 }
164
165 pci_read_config_dword(mch_dev, CRVML_REG_MCHEN, &dev_en);
166 if (!(dev_en & CRVML_MCHEN_BIT)) {
167 printk(KERN_ERR
168 "Carillo Ranch MCH device was not enabled.\n");
169 pci_dev_put(mch_dev);
170 return -ENODEV;
171 }
172
173 pci_read_config_dword(mch_dev, CRVML_REG_MCHBAR,
174 &mch_bar);
175 mch_regs_base =
176 ioremap_nocache(mch_bar, CRVML_MCHMAP_SIZE);
177 if (!mch_regs_base) {
178 printk(KERN_ERR
179 "Carillo Ranch MCH device was not enabled.\n");
180 pci_dev_put(mch_dev);
181 return -ENODEV;
182 }
183
184 err = vmlfb_register_subsys(&cr_pll_ops);
185 if (err) {
186 printk(KERN_ERR
187 "Carillo Ranch failed to initialize vml_sys.\n");
188 pci_dev_put(mch_dev);
189 return err;
190 }
191
192 return 0;
193}
194
195static void __exit cr_pll_exit(void)
196{
197 vmlfb_unregister_subsys(&cr_pll_ops);
198
199 iounmap(mch_regs_base);
200 pci_dev_put(mch_dev);
201}
202
203module_init(cr_pll_init);
204module_exit(cr_pll_exit);
205
206MODULE_AUTHOR("Tungsten Graphics Inc.");
207MODULE_DESCRIPTION("Carillo Ranch PLL Driver");
208MODULE_LICENSE("GPL");
diff --git a/drivers/video/vermilion/vermilion.c b/drivers/video/vermilion/vermilion.c
new file mode 100644
index 000000000000..de531c907718
--- /dev/null
+++ b/drivers/video/vermilion/vermilion.c
@@ -0,0 +1,1195 @@
1/*
2 * Copyright (c) Intel Corp. 2007.
3 * All Rights Reserved.
4 *
5 * Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to
6 * develop this driver.
7 *
8 * This file is part of the Vermilion Range fb driver.
9 * The Vermilion Range fb driver is free software;
10 * you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * The Vermilion Range fb driver is distributed
16 * in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this driver; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
24 *
25 * Authors:
26 * Thomas Hellström <thomas-at-tungstengraphics-dot-com>
27 * Michel Dänzer <michel-at-tungstengraphics-dot-com>
28 * Alan Hourihane <alanh-at-tungstengraphics-dot-com>
29 */
30
31#include <linux/module.h>
32#include <linux/kernel.h>
33#include <linux/errno.h>
34#include <linux/string.h>
35#include <linux/delay.h>
36#include <linux/mm.h>
37#include <linux/fb.h>
38#include <linux/pci.h>
39#include <asm/cacheflush.h>
40#include <asm/tlbflush.h>
41#include <linux/mmzone.h>
42#include <asm/uaccess.h>
43
44/* #define VERMILION_DEBUG */
45
46#include "vermilion.h"
47
48#define MODULE_NAME "vmlfb"
49
50#define VML_TOHW(_val, _width) ((((_val) << (_width)) + 0x7FFF - (_val)) >> 16)
51
52static struct mutex vml_mutex;
53static struct list_head global_no_mode;
54static struct list_head global_has_mode;
55static struct fb_ops vmlfb_ops;
56static struct vml_sys *subsys = NULL;
57static char *vml_default_mode = "1024x768@60";
58static struct fb_videomode defaultmode = {
59 NULL, 60, 1024, 768, 12896, 144, 24, 29, 3, 136, 6,
60 0, FB_VMODE_NONINTERLACED
61};
62
63static u32 vml_mem_requested = (10 * 1024 * 1024);
64static u32 vml_mem_contig = (4 * 1024 * 1024);
65static u32 vml_mem_min = (4 * 1024 * 1024);
66
67static u32 vml_clocks[] = {
68 6750,
69 13500,
70 27000,
71 29700,
72 37125,
73 54000,
74 59400,
75 74250,
76 120000,
77 148500
78};
79
80static u32 vml_num_clocks = ARRAY_SIZE(vml_clocks);
81
82/*
83 * Allocate a contiguous vram area and make its linear kernel map
84 * uncached.
85 */
86
87static int vmlfb_alloc_vram_area(struct vram_area *va, unsigned max_order,
88 unsigned min_order)
89{
90 gfp_t flags;
91 unsigned long i;
92 pgprot_t wc_pageprot;
93
94 wc_pageprot = PAGE_KERNEL_NOCACHE;
95 max_order++;
96 do {
97 /*
98 * Really try hard to get the needed memory.
99 * We need memory below the first 32MB, so we
100 * add the __GFP_DMA flag that guarantees that we are
101 * below the first 16MB.
102 */
103
104 flags = __GFP_DMA | __GFP_HIGH;
105 va->logical =
106 __get_free_pages(flags, --max_order);
107 } while (va->logical == 0 && max_order > min_order);
108
109 if (!va->logical)
110 return -ENOMEM;
111
112 va->phys = virt_to_phys((void *)va->logical);
113 va->size = PAGE_SIZE << max_order;
114 va->order = max_order;
115
116 /*
117 * It seems like __get_free_pages only ups the usage count
118 * of the first page. This doesn't work with nopage mapping, so
119 * up the usage count once more.
120 */
121
122 memset((void *)va->logical, 0x00, va->size);
123 for (i = va->logical; i < va->logical + va->size; i += PAGE_SIZE) {
124 get_page(virt_to_page(i));
125 }
126
127 /*
128 * Change caching policy of the linear kernel map to avoid
129 * mapping type conflicts with user-space mappings.
130 * The first global_flush_tlb() is really only there to do a global
131 * wbinvd().
132 */
133
134 global_flush_tlb();
135 change_page_attr(virt_to_page(va->logical), va->size >> PAGE_SHIFT,
136 wc_pageprot);
137 global_flush_tlb();
138
139 printk(KERN_DEBUG MODULE_NAME
140 ": Allocated %ld bytes vram area at 0x%08lx\n",
141 va->size, va->phys);
142
143 return 0;
144}
145
146/*
147 * Free a contiguous vram area and reset its linear kernel map
148 * mapping type.
149 */
150
151static void vmlfb_free_vram_area(struct vram_area *va)
152{
153 unsigned long j;
154
155 if (va->logical) {
156
157 /*
158 * Reset the linear kernel map caching policy.
159 */
160
161 change_page_attr(virt_to_page(va->logical),
162 va->size >> PAGE_SHIFT, PAGE_KERNEL);
163 global_flush_tlb();
164
165 /*
166 * Decrease the usage count on the pages we've used
167 * to compensate for upping when allocating.
168 */
169
170 for (j = va->logical; j < va->logical + va->size;
171 j += PAGE_SIZE) {
172 (void)put_page_testzero(virt_to_page(j));
173 }
174
175 printk(KERN_DEBUG MODULE_NAME
176 ": Freeing %ld bytes vram area at 0x%08lx\n",
177 va->size, va->phys);
178 free_pages(va->logical, va->order);
179
180 va->logical = 0;
181 }
182}
183
184/*
185 * Free allocated vram.
186 */
187
188static void vmlfb_free_vram(struct vml_info *vinfo)
189{
190 int i;
191
192 for (i = 0; i < vinfo->num_areas; ++i) {
193 vmlfb_free_vram_area(&vinfo->vram[i]);
194 }
195 vinfo->num_areas = 0;
196}
197
198/*
199 * Allocate vram. Currently we try to allocate contiguous areas from the
200 * __GFP_DMA zone and puzzle them together. A better approach would be to
201 * allocate one contiguous area for scanout and use one-page allocations for
202 * offscreen areas. This requires user-space and GPU virtual mappings.
203 */
204
205static int vmlfb_alloc_vram(struct vml_info *vinfo,
206 size_t requested,
207 size_t min_total, size_t min_contig)
208{
209 int i, j;
210 int order;
211 int contiguous;
212 int err;
213 struct vram_area *va;
214 struct vram_area *va2;
215
216 vinfo->num_areas = 0;
217 for (i = 0; i < VML_VRAM_AREAS; ++i) {
218 va = &vinfo->vram[i];
219 order = 0;
220
221 while (requested > (PAGE_SIZE << order) && order < MAX_ORDER)
222 order++;
223
224 err = vmlfb_alloc_vram_area(va, order, 0);
225
226 if (err)
227 break;
228
229 if (i == 0) {
230 vinfo->vram_start = va->phys;
231 vinfo->vram_logical = (void __iomem *) va->logical;
232 vinfo->vram_contig_size = va->size;
233 vinfo->num_areas = 1;
234 } else {
235 contiguous = 0;
236
237 for (j = 0; j < i; ++j) {
238 va2 = &vinfo->vram[j];
239 if (va->phys + va->size == va2->phys ||
240 va2->phys + va2->size == va->phys) {
241 contiguous = 1;
242 break;
243 }
244 }
245
246 if (contiguous) {
247 vinfo->num_areas++;
248 if (va->phys < vinfo->vram_start) {
249 vinfo->vram_start = va->phys;
250 vinfo->vram_logical =
251 (void __iomem *)va->logical;
252 }
253 vinfo->vram_contig_size += va->size;
254 } else {
255 vmlfb_free_vram_area(va);
256 break;
257 }
258 }
259
260 if (requested < va->size)
261 break;
262 else
263 requested -= va->size;
264 }
265
266 if (vinfo->vram_contig_size > min_total &&
267 vinfo->vram_contig_size > min_contig) {
268
269 printk(KERN_DEBUG MODULE_NAME
270 ": Contiguous vram: %ld bytes at physical 0x%08lx.\n",
271 (unsigned long)vinfo->vram_contig_size,
272 (unsigned long)vinfo->vram_start);
273
274 return 0;
275 }
276
277 printk(KERN_ERR MODULE_NAME
278 ": Could not allocate requested minimal amount of vram.\n");
279
280 vmlfb_free_vram(vinfo);
281
282 return -ENOMEM;
283}
284
285/*
286 * Find the GPU to use with our display controller.
287 */
288
289static int vmlfb_get_gpu(struct vml_par *par)
290{
291 mutex_lock(&vml_mutex);
292
293 par->gpu = pci_get_device(PCI_VENDOR_ID_INTEL, VML_DEVICE_GPU, NULL);
294
295 if (!par->gpu) {
296 mutex_unlock(&vml_mutex);
297 return -ENODEV;
298 }
299
300 mutex_unlock(&vml_mutex);
301
302 if (pci_enable_device(par->gpu) < 0)
303 return -ENODEV;
304
305 return 0;
306}
307
308/*
309 * Find a contiguous vram area that contains a given offset from vram start.
310 */
311static int vmlfb_vram_offset(struct vml_info *vinfo, unsigned long offset)
312{
313 unsigned long aoffset;
314 unsigned i;
315
316 for (i = 0; i < vinfo->num_areas; ++i) {
317 aoffset = offset - (vinfo->vram[i].phys - vinfo->vram_start);
318
319 if (aoffset < vinfo->vram[i].size) {
320 return 0;
321 }
322 }
323
324 return -EINVAL;
325}
326
327/*
328 * Remap the MMIO register spaces of the VDC and the GPU.
329 */
330
331static int vmlfb_enable_mmio(struct vml_par *par)
332{
333 int err;
334
335 par->vdc_mem_base = pci_resource_start(par->vdc, 0);
336 par->vdc_mem_size = pci_resource_len(par->vdc, 0);
337 if (!request_mem_region(par->vdc_mem_base, par->vdc_mem_size, "vmlfb")) {
338 printk(KERN_ERR MODULE_NAME
339 ": Could not claim display controller MMIO.\n");
340 return -EBUSY;
341 }
342 par->vdc_mem = ioremap_nocache(par->vdc_mem_base, par->vdc_mem_size);
343 if (par->vdc_mem == NULL) {
344 printk(KERN_ERR MODULE_NAME
345 ": Could not map display controller MMIO.\n");
346 err = -ENOMEM;
347 goto out_err_0;
348 }
349
350 par->gpu_mem_base = pci_resource_start(par->gpu, 0);
351 par->gpu_mem_size = pci_resource_len(par->gpu, 0);
352 if (!request_mem_region(par->gpu_mem_base, par->gpu_mem_size, "vmlfb")) {
353 printk(KERN_ERR MODULE_NAME ": Could not claim GPU MMIO.\n");
354 err = -EBUSY;
355 goto out_err_1;
356 }
357 par->gpu_mem = ioremap_nocache(par->gpu_mem_base, par->gpu_mem_size);
358 if (par->gpu_mem == NULL) {
359 printk(KERN_ERR MODULE_NAME ": Could not map GPU MMIO.\n");
360 err = -ENOMEM;
361 goto out_err_2;
362 }
363
364 return 0;
365
366out_err_2:
367 release_mem_region(par->gpu_mem_base, par->gpu_mem_size);
368out_err_1:
369 iounmap(par->vdc_mem);
370out_err_0:
371 release_mem_region(par->vdc_mem_base, par->vdc_mem_size);
372 return err;
373}
374
375/*
376 * Unmap the VDC and GPU register spaces.
377 */
378
379static void vmlfb_disable_mmio(struct vml_par *par)
380{
381 iounmap(par->gpu_mem);
382 release_mem_region(par->gpu_mem_base, par->gpu_mem_size);
383 iounmap(par->vdc_mem);
384 release_mem_region(par->vdc_mem_base, par->vdc_mem_size);
385}
386
387/*
388 * Release and uninit the VDC and GPU.
389 */
390
391static void vmlfb_release_devices(struct vml_par *par)
392{
393 if (atomic_dec_and_test(&par->refcount)) {
394 pci_set_drvdata(par->vdc, NULL);
395 pci_disable_device(par->gpu);
396 pci_disable_device(par->vdc);
397 }
398}
399
400/*
401 * Free up allocated resources for a device.
402 */
403
404static void __devexit vml_pci_remove(struct pci_dev *dev)
405{
406 struct fb_info *info;
407 struct vml_info *vinfo;
408 struct vml_par *par;
409
410 info = pci_get_drvdata(dev);
411 if (info) {
412 vinfo = container_of(info, struct vml_info, info);
413 par = vinfo->par;
414 mutex_lock(&vml_mutex);
415 unregister_framebuffer(info);
416 fb_dealloc_cmap(&info->cmap);
417 vmlfb_free_vram(vinfo);
418 vmlfb_disable_mmio(par);
419 vmlfb_release_devices(par);
420 kfree(vinfo);
421 kfree(par);
422 mutex_unlock(&vml_mutex);
423 }
424}
425
426static void vmlfb_set_pref_pixel_format(struct fb_var_screeninfo *var)
427{
428 switch (var->bits_per_pixel) {
429 case 16:
430 var->blue.offset = 0;
431 var->blue.length = 5;
432 var->green.offset = 5;
433 var->green.length = 5;
434 var->red.offset = 10;
435 var->red.length = 5;
436 var->transp.offset = 15;
437 var->transp.length = 1;
438 break;
439 case 32:
440 var->blue.offset = 0;
441 var->blue.length = 8;
442 var->green.offset = 8;
443 var->green.length = 8;
444 var->red.offset = 16;
445 var->red.length = 8;
446 var->transp.offset = 24;
447 var->transp.length = 0;
448 break;
449 default:
450 break;
451 }
452
453 var->blue.msb_right = var->green.msb_right =
454 var->red.msb_right = var->transp.msb_right = 0;
455}
456
457/*
458 * Device initialization.
459 * We initialize one vml_par struct per device and one vml_info
460 * struct per pipe. Currently we have only one pipe.
461 */
462
463static int __devinit vml_pci_probe(struct pci_dev *dev,
464 const struct pci_device_id *id)
465{
466 struct vml_info *vinfo;
467 struct fb_info *info;
468 struct vml_par *par;
469 int err = 0;
470
471 par = kzalloc(sizeof(*par), GFP_KERNEL);
472 if (par == NULL)
473 return -ENOMEM;
474
475 vinfo = kzalloc(sizeof(*vinfo), GFP_KERNEL);
476 if (vinfo == NULL) {
477 err = -ENOMEM;
478 goto out_err_0;
479 }
480
481 vinfo->par = par;
482 par->vdc = dev;
483 atomic_set(&par->refcount, 1);
484
485 switch (id->device) {
486 case VML_DEVICE_VDC:
487 if ((err = vmlfb_get_gpu(par)))
488 goto out_err_1;
489 pci_set_drvdata(dev, &vinfo->info);
490 break;
491 default:
492 err = -ENODEV;
493 goto out_err_1;
494 break;
495 }
496
497 info = &vinfo->info;
498 info->flags = FBINFO_DEFAULT | FBINFO_PARTIAL_PAN_OK;
499
500 err = vmlfb_enable_mmio(par);
501 if (err)
502 goto out_err_2;
503
504 err = vmlfb_alloc_vram(vinfo, vml_mem_requested,
505 vml_mem_contig, vml_mem_min);
506 if (err)
507 goto out_err_3;
508
509 strcpy(info->fix.id, "Vermilion Range");
510 info->fix.mmio_start = 0;
511 info->fix.mmio_len = 0;
512 info->fix.smem_start = vinfo->vram_start;
513 info->fix.smem_len = vinfo->vram_contig_size;
514 info->fix.type = FB_TYPE_PACKED_PIXELS;
515 info->fix.visual = FB_VISUAL_TRUECOLOR;
516 info->fix.ypanstep = 1;
517 info->fix.xpanstep = 1;
518 info->fix.ywrapstep = 0;
519 info->fix.accel = FB_ACCEL_NONE;
520 info->screen_base = vinfo->vram_logical;
521 info->pseudo_palette = vinfo->pseudo_palette;
522 info->par = par;
523 info->fbops = &vmlfb_ops;
524 info->device = &dev->dev;
525
526 INIT_LIST_HEAD(&vinfo->head);
527 vinfo->pipe_disabled = 1;
528 vinfo->cur_blank_mode = FB_BLANK_UNBLANK;
529
530 info->var.grayscale = 0;
531 info->var.bits_per_pixel = 16;
532 vmlfb_set_pref_pixel_format(&info->var);
533
534 if (!fb_find_mode
535 (&info->var, info, vml_default_mode, NULL, 0, &defaultmode, 16)) {
536 printk(KERN_ERR MODULE_NAME ": Could not find initial mode\n");
537 }
538
539 if (fb_alloc_cmap(&info->cmap, 256, 1) < 0) {
540 err = -ENOMEM;
541 goto out_err_4;
542 }
543
544 err = register_framebuffer(info);
545 if (err) {
546 printk(KERN_ERR MODULE_NAME ": Register framebuffer error.\n");
547 goto out_err_5;
548 }
549
550 printk("Initialized vmlfb\n");
551
552 return 0;
553
554out_err_5:
555 fb_dealloc_cmap(&info->cmap);
556out_err_4:
557 vmlfb_free_vram(vinfo);
558out_err_3:
559 vmlfb_disable_mmio(par);
560out_err_2:
561 vmlfb_release_devices(par);
562out_err_1:
563 kfree(vinfo);
564out_err_0:
565 kfree(par);
566 return err;
567}
568
569static int vmlfb_open(struct fb_info *info, int user)
570{
571 /*
572 * Save registers here?
573 */
574 return 0;
575}
576
577static int vmlfb_release(struct fb_info *info, int user)
578{
579 /*
580 * Restore registers here.
581 */
582
583 return 0;
584}
585
586static int vml_nearest_clock(int clock)
587{
588
589 int i;
590 int cur_index;
591 int cur_diff;
592 int diff;
593
594 cur_index = 0;
595 cur_diff = clock - vml_clocks[0];
596 cur_diff = (cur_diff < 0) ? -cur_diff : cur_diff;
597 for (i = 1; i < vml_num_clocks; ++i) {
598 diff = clock - vml_clocks[i];
599 diff = (diff < 0) ? -diff : diff;
600 if (diff < cur_diff) {
601 cur_index = i;
602 cur_diff = diff;
603 }
604 }
605 return vml_clocks[cur_index];
606}
607
608static int vmlfb_check_var_locked(struct fb_var_screeninfo *var,
609 struct vml_info *vinfo)
610{
611 u32 pitch;
612 u64 mem;
613 int nearest_clock;
614 int clock;
615 int clock_diff;
616 struct fb_var_screeninfo v;
617
618 v = *var;
619 clock = PICOS2KHZ(var->pixclock);
620
621 if (subsys && subsys->nearest_clock) {
622 nearest_clock = subsys->nearest_clock(subsys, clock);
623 } else {
624 nearest_clock = vml_nearest_clock(clock);
625 }
626
627 /*
628 * Accept a 20% diff.
629 */
630
631 clock_diff = nearest_clock - clock;
632 clock_diff = (clock_diff < 0) ? -clock_diff : clock_diff;
633 if (clock_diff > clock / 5) {
634#if 0
635 printk(KERN_DEBUG MODULE_NAME ": Diff failure. %d %d\n",clock_diff,clock);
636#endif
637 return -EINVAL;
638 }
639
640 v.pixclock = KHZ2PICOS(nearest_clock);
641
642 if (var->xres > VML_MAX_XRES || var->yres > VML_MAX_YRES) {
643 printk(KERN_DEBUG MODULE_NAME ": Resolution failure.\n");
644 return -EINVAL;
645 }
646 if (var->xres_virtual > VML_MAX_XRES_VIRTUAL) {
647 printk(KERN_DEBUG MODULE_NAME
648 ": Virtual resolution failure.\n");
649 return -EINVAL;
650 }
651 switch (v.bits_per_pixel) {
652 case 0 ... 16:
653 v.bits_per_pixel = 16;
654 break;
655 case 17 ... 32:
656 v.bits_per_pixel = 32;
657 break;
658 default:
659 printk(KERN_DEBUG MODULE_NAME ": Invalid bpp: %d.\n",
660 var->bits_per_pixel);
661 return -EINVAL;
662 }
663
664 pitch = __ALIGN_MASK((var->xres * var->bits_per_pixel) >> 3, 0x3F);
665 mem = pitch * var->yres_virtual;
666 if (mem > vinfo->vram_contig_size) {
667 return -ENOMEM;
668 }
669
670 switch (v.bits_per_pixel) {
671 case 16:
672 if (var->blue.offset != 0 ||
673 var->blue.length != 5 ||
674 var->green.offset != 5 ||
675 var->green.length != 5 ||
676 var->red.offset != 10 ||
677 var->red.length != 5 ||
678 var->transp.offset != 15 || var->transp.length != 1) {
679 vmlfb_set_pref_pixel_format(&v);
680 }
681 break;
682 case 32:
683 if (var->blue.offset != 0 ||
684 var->blue.length != 8 ||
685 var->green.offset != 8 ||
686 var->green.length != 8 ||
687 var->red.offset != 16 ||
688 var->red.length != 8 ||
689 (var->transp.length != 0 && var->transp.length != 8) ||
690 (var->transp.length == 8 && var->transp.offset != 24)) {
691 vmlfb_set_pref_pixel_format(&v);
692 }
693 break;
694 default:
695 return -EINVAL;
696 }
697
698 *var = v;
699
700 return 0;
701}
702
703static int vmlfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
704{
705 struct vml_info *vinfo = container_of(info, struct vml_info, info);
706 int ret;
707
708 mutex_lock(&vml_mutex);
709 ret = vmlfb_check_var_locked(var, vinfo);
710 mutex_unlock(&vml_mutex);
711
712 return ret;
713}
714
715static void vml_wait_vblank(struct vml_info *vinfo)
716{
717 /* Wait for vblank. For now, just wait for a 50Hz cycle (20ms)) */
718 mdelay(20);
719}
720
721static void vmlfb_disable_pipe(struct vml_info *vinfo)
722{
723 struct vml_par *par = vinfo->par;
724
725 /* Disable the MDVO pad */
726 VML_WRITE32(par, VML_RCOMPSTAT, 0);
727 while (!(VML_READ32(par, VML_RCOMPSTAT) & VML_MDVO_VDC_I_RCOMP)) ;
728
729 /* Disable display planes */
730 VML_WRITE32(par, VML_DSPCCNTR,
731 VML_READ32(par, VML_DSPCCNTR) & ~VML_GFX_ENABLE);
732 (void)VML_READ32(par, VML_DSPCCNTR);
733 /* Wait for vblank for the disable to take effect */
734 vml_wait_vblank(vinfo);
735
736 /* Next, disable display pipes */
737 VML_WRITE32(par, VML_PIPEACONF, 0);
738 (void)VML_READ32(par, VML_PIPEACONF);
739
740 vinfo->pipe_disabled = 1;
741}
742
743#ifdef VERMILION_DEBUG
744static void vml_dump_regs(struct vml_info *vinfo)
745{
746 struct vml_par *par = vinfo->par;
747
748 printk(KERN_DEBUG MODULE_NAME ": Modesetting register dump:\n");
749 printk(KERN_DEBUG MODULE_NAME ": \tHTOTAL_A : 0x%08x\n",
750 (unsigned)VML_READ32(par, VML_HTOTAL_A));
751 printk(KERN_DEBUG MODULE_NAME ": \tHBLANK_A : 0x%08x\n",
752 (unsigned)VML_READ32(par, VML_HBLANK_A));
753 printk(KERN_DEBUG MODULE_NAME ": \tHSYNC_A : 0x%08x\n",
754 (unsigned)VML_READ32(par, VML_HSYNC_A));
755 printk(KERN_DEBUG MODULE_NAME ": \tVTOTAL_A : 0x%08x\n",
756 (unsigned)VML_READ32(par, VML_VTOTAL_A));
757 printk(KERN_DEBUG MODULE_NAME ": \tVBLANK_A : 0x%08x\n",
758 (unsigned)VML_READ32(par, VML_VBLANK_A));
759 printk(KERN_DEBUG MODULE_NAME ": \tVSYNC_A : 0x%08x\n",
760 (unsigned)VML_READ32(par, VML_VSYNC_A));
761 printk(KERN_DEBUG MODULE_NAME ": \tDSPCSTRIDE : 0x%08x\n",
762 (unsigned)VML_READ32(par, VML_DSPCSTRIDE));
763 printk(KERN_DEBUG MODULE_NAME ": \tDSPCSIZE : 0x%08x\n",
764 (unsigned)VML_READ32(par, VML_DSPCSIZE));
765 printk(KERN_DEBUG MODULE_NAME ": \tDSPCPOS : 0x%08x\n",
766 (unsigned)VML_READ32(par, VML_DSPCPOS));
767 printk(KERN_DEBUG MODULE_NAME ": \tDSPARB : 0x%08x\n",
768 (unsigned)VML_READ32(par, VML_DSPARB));
769 printk(KERN_DEBUG MODULE_NAME ": \tDSPCADDR : 0x%08x\n",
770 (unsigned)VML_READ32(par, VML_DSPCADDR));
771 printk(KERN_DEBUG MODULE_NAME ": \tBCLRPAT_A : 0x%08x\n",
772 (unsigned)VML_READ32(par, VML_BCLRPAT_A));
773 printk(KERN_DEBUG MODULE_NAME ": \tCANVSCLR_A : 0x%08x\n",
774 (unsigned)VML_READ32(par, VML_CANVSCLR_A));
775 printk(KERN_DEBUG MODULE_NAME ": \tPIPEASRC : 0x%08x\n",
776 (unsigned)VML_READ32(par, VML_PIPEASRC));
777 printk(KERN_DEBUG MODULE_NAME ": \tPIPEACONF : 0x%08x\n",
778 (unsigned)VML_READ32(par, VML_PIPEACONF));
779 printk(KERN_DEBUG MODULE_NAME ": \tDSPCCNTR : 0x%08x\n",
780 (unsigned)VML_READ32(par, VML_DSPCCNTR));
781 printk(KERN_DEBUG MODULE_NAME ": \tRCOMPSTAT : 0x%08x\n",
782 (unsigned)VML_READ32(par, VML_RCOMPSTAT));
783 printk(KERN_DEBUG MODULE_NAME ": End of modesetting register dump.\n");
784}
785#endif
786
787static int vmlfb_set_par_locked(struct vml_info *vinfo)
788{
789 struct vml_par *par = vinfo->par;
790 struct fb_info *info = &vinfo->info;
791 struct fb_var_screeninfo *var = &info->var;
792 u32 htotal, hactive, hblank_start, hblank_end, hsync_start, hsync_end;
793 u32 vtotal, vactive, vblank_start, vblank_end, vsync_start, vsync_end;
794 u32 dspcntr;
795 int clock;
796
797 vinfo->bytes_per_pixel = var->bits_per_pixel >> 3;
798 vinfo->stride =
799 __ALIGN_MASK(var->xres_virtual * vinfo->bytes_per_pixel, 0x3F);
800 info->fix.line_length = vinfo->stride;
801
802 if (!subsys)
803 return 0;
804
805 htotal =
806 var->xres + var->right_margin + var->hsync_len + var->left_margin;
807 hactive = var->xres;
808 hblank_start = var->xres;
809 hblank_end = htotal;
810 hsync_start = hactive + var->right_margin;
811 hsync_end = hsync_start + var->hsync_len;
812
813 vtotal =
814 var->yres + var->lower_margin + var->vsync_len + var->upper_margin;
815 vactive = var->yres;
816 vblank_start = var->yres;
817 vblank_end = vtotal;
818 vsync_start = vactive + var->lower_margin;
819 vsync_end = vsync_start + var->vsync_len;
820
821 dspcntr = VML_GFX_ENABLE | VML_GFX_GAMMABYPASS;
822 clock = PICOS2KHZ(var->pixclock);
823
824 if (subsys->nearest_clock) {
825 clock = subsys->nearest_clock(subsys, clock);
826 } else {
827 clock = vml_nearest_clock(clock);
828 }
829 printk(KERN_DEBUG MODULE_NAME
830 ": Set mode Hfreq : %d kHz, Vfreq : %d Hz.\n", clock / htotal,
831 ((clock / htotal) * 1000) / vtotal);
832
833 switch (var->bits_per_pixel) {
834 case 16:
835 dspcntr |= VML_GFX_ARGB1555;
836 break;
837 case 32:
838 if (var->transp.length == 8)
839 dspcntr |= VML_GFX_ARGB8888 | VML_GFX_ALPHAMULT;
840 else
841 dspcntr |= VML_GFX_RGB0888;
842 break;
843 default:
844 return -EINVAL;
845 }
846
847 vmlfb_disable_pipe(vinfo);
848 mb();
849
850 if (subsys->set_clock)
851 subsys->set_clock(subsys, clock);
852 else
853 return -EINVAL;
854
855 VML_WRITE32(par, VML_HTOTAL_A, ((htotal - 1) << 16) | (hactive - 1));
856 VML_WRITE32(par, VML_HBLANK_A,
857 ((hblank_end - 1) << 16) | (hblank_start - 1));
858 VML_WRITE32(par, VML_HSYNC_A,
859 ((hsync_end - 1) << 16) | (hsync_start - 1));
860 VML_WRITE32(par, VML_VTOTAL_A, ((vtotal - 1) << 16) | (vactive - 1));
861 VML_WRITE32(par, VML_VBLANK_A,
862 ((vblank_end - 1) << 16) | (vblank_start - 1));
863 VML_WRITE32(par, VML_VSYNC_A,
864 ((vsync_end - 1) << 16) | (vsync_start - 1));
865 VML_WRITE32(par, VML_DSPCSTRIDE, vinfo->stride);
866 VML_WRITE32(par, VML_DSPCSIZE,
867 ((var->yres - 1) << 16) | (var->xres - 1));
868 VML_WRITE32(par, VML_DSPCPOS, 0x00000000);
869 VML_WRITE32(par, VML_DSPARB, VML_FIFO_DEFAULT);
870 VML_WRITE32(par, VML_BCLRPAT_A, 0x00000000);
871 VML_WRITE32(par, VML_CANVSCLR_A, 0x00000000);
872 VML_WRITE32(par, VML_PIPEASRC,
873 ((var->xres - 1) << 16) | (var->yres - 1));
874
875 wmb();
876 VML_WRITE32(par, VML_PIPEACONF, VML_PIPE_ENABLE);
877 wmb();
878 VML_WRITE32(par, VML_DSPCCNTR, dspcntr);
879 wmb();
880 VML_WRITE32(par, VML_DSPCADDR, (u32) vinfo->vram_start +
881 var->yoffset * vinfo->stride +
882 var->xoffset * vinfo->bytes_per_pixel);
883
884 VML_WRITE32(par, VML_RCOMPSTAT, VML_MDVO_PAD_ENABLE);
885
886 while (!(VML_READ32(par, VML_RCOMPSTAT) &
887 (VML_MDVO_VDC_I_RCOMP | VML_MDVO_PAD_ENABLE))) ;
888
889 vinfo->pipe_disabled = 0;
890#ifdef VERMILION_DEBUG
891 vml_dump_regs(vinfo);
892#endif
893
894 return 0;
895}
896
897static int vmlfb_set_par(struct fb_info *info)
898{
899 struct vml_info *vinfo = container_of(info, struct vml_info, info);
900 int ret;
901
902 mutex_lock(&vml_mutex);
903 list_del(&vinfo->head);
904 list_add(&vinfo->head, (subsys) ? &global_has_mode : &global_no_mode);
905 ret = vmlfb_set_par_locked(vinfo);
906
907 mutex_unlock(&vml_mutex);
908 return ret;
909}
910
911static int vmlfb_blank_locked(struct vml_info *vinfo)
912{
913 struct vml_par *par = vinfo->par;
914 u32 cur = VML_READ32(par, VML_PIPEACONF);
915
916 switch (vinfo->cur_blank_mode) {
917 case FB_BLANK_UNBLANK:
918 if (vinfo->pipe_disabled) {
919 vmlfb_set_par_locked(vinfo);
920 }
921 VML_WRITE32(par, VML_PIPEACONF, cur & ~VML_PIPE_FORCE_BORDER);
922 (void)VML_READ32(par, VML_PIPEACONF);
923 break;
924 case FB_BLANK_NORMAL:
925 if (vinfo->pipe_disabled) {
926 vmlfb_set_par_locked(vinfo);
927 }
928 VML_WRITE32(par, VML_PIPEACONF, cur | VML_PIPE_FORCE_BORDER);
929 (void)VML_READ32(par, VML_PIPEACONF);
930 break;
931 case FB_BLANK_VSYNC_SUSPEND:
932 case FB_BLANK_HSYNC_SUSPEND:
933 if (!vinfo->pipe_disabled) {
934 vmlfb_disable_pipe(vinfo);
935 }
936 break;
937 case FB_BLANK_POWERDOWN:
938 if (!vinfo->pipe_disabled) {
939 vmlfb_disable_pipe(vinfo);
940 }
941 break;
942 default:
943 return -EINVAL;
944 }
945
946 return 0;
947}
948
949static int vmlfb_blank(int blank_mode, struct fb_info *info)
950{
951 struct vml_info *vinfo = container_of(info, struct vml_info, info);
952 int ret;
953
954 mutex_lock(&vml_mutex);
955 vinfo->cur_blank_mode = blank_mode;
956 ret = vmlfb_blank_locked(vinfo);
957 mutex_unlock(&vml_mutex);
958 return ret;
959}
960
961static int vmlfb_pan_display(struct fb_var_screeninfo *var,
962 struct fb_info *info)
963{
964 struct vml_info *vinfo = container_of(info, struct vml_info, info);
965 struct vml_par *par = vinfo->par;
966
967 mutex_lock(&vml_mutex);
968 VML_WRITE32(par, VML_DSPCADDR, (u32) vinfo->vram_start +
969 var->yoffset * vinfo->stride +
970 var->xoffset * vinfo->bytes_per_pixel);
971 (void)VML_READ32(par, VML_DSPCADDR);
972 mutex_unlock(&vml_mutex);
973
974 return 0;
975}
976
977static int vmlfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
978 u_int transp, struct fb_info *info)
979{
980 u32 v;
981
982 if (regno >= 16)
983 return -EINVAL;
984
985 if (info->var.grayscale) {
986 red = green = blue = (red * 77 + green * 151 + blue * 28) >> 8;
987 }
988
989 if (info->fix.visual != FB_VISUAL_TRUECOLOR)
990 return -EINVAL;
991
992 red = VML_TOHW(red, info->var.red.length);
993 blue = VML_TOHW(blue, info->var.blue.length);
994 green = VML_TOHW(green, info->var.green.length);
995 transp = VML_TOHW(transp, info->var.transp.length);
996
997 v = (red << info->var.red.offset) |
998 (green << info->var.green.offset) |
999 (blue << info->var.blue.offset) |
1000 (transp << info->var.transp.offset);
1001
1002 switch (info->var.bits_per_pixel) {
1003 case 16:
1004 ((u32 *) info->pseudo_palette)[regno] = v;
1005 break;
1006 case 24:
1007 case 32:
1008 ((u32 *) info->pseudo_palette)[regno] = v;
1009 break;
1010 }
1011 return 0;
1012}
1013
1014static int vmlfb_mmap(struct fb_info *info, struct vm_area_struct *vma)
1015{
1016 struct vml_info *vinfo = container_of(info, struct vml_info, info);
1017 unsigned long size = vma->vm_end - vma->vm_start;
1018 unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
1019 int ret;
1020
1021 if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT))
1022 return -EINVAL;
1023 if (offset + size > vinfo->vram_contig_size)
1024 return -EINVAL;
1025 ret = vmlfb_vram_offset(vinfo, offset);
1026 if (ret)
1027 return -EINVAL;
1028 offset += vinfo->vram_start;
1029 pgprot_val(vma->vm_page_prot) |= _PAGE_PCD;
1030 pgprot_val(vma->vm_page_prot) &= ~_PAGE_PWT;
1031 vma->vm_flags |= VM_RESERVED | VM_IO;
1032 if (remap_pfn_range(vma, vma->vm_start, offset >> PAGE_SHIFT,
1033 size, vma->vm_page_prot))
1034 return -EAGAIN;
1035 return 0;
1036}
1037
1038static int vmlfb_sync(struct fb_info *info)
1039{
1040 return 0;
1041}
1042
1043static int vmlfb_cursor(struct fb_info *info, struct fb_cursor *cursor)
1044{
1045 return -EINVAL; /* just to force soft_cursor() call */
1046}
1047
1048static struct fb_ops vmlfb_ops = {
1049 .owner = THIS_MODULE,
1050 .fb_open = vmlfb_open,
1051 .fb_release = vmlfb_release,
1052 .fb_check_var = vmlfb_check_var,
1053 .fb_set_par = vmlfb_set_par,
1054 .fb_blank = vmlfb_blank,
1055 .fb_pan_display = vmlfb_pan_display,
1056 .fb_fillrect = cfb_fillrect,
1057 .fb_copyarea = cfb_copyarea,
1058 .fb_imageblit = cfb_imageblit,
1059 .fb_cursor = vmlfb_cursor,
1060 .fb_sync = vmlfb_sync,
1061 .fb_mmap = vmlfb_mmap,
1062 .fb_setcolreg = vmlfb_setcolreg
1063};
1064
1065static struct pci_device_id vml_ids[] = {
1066 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, VML_DEVICE_VDC)},
1067 {0}
1068};
1069
1070static struct pci_driver vmlfb_pci_driver = {
1071 .name = "vmlfb",
1072 .id_table = vml_ids,
1073 .probe = vml_pci_probe,
1074 .remove = __devexit_p(vml_pci_remove)
1075};
1076
1077static void __exit vmlfb_cleanup(void)
1078{
1079 pci_unregister_driver(&vmlfb_pci_driver);
1080}
1081
1082static int __init vmlfb_init(void)
1083{
1084
1085#ifndef MODULE
1086 char *option = NULL;
1087
1088 if (fb_get_options(MODULE_NAME, &option))
1089 return -ENODEV;
1090#endif
1091
1092 printk(KERN_DEBUG MODULE_NAME ": initializing\n");
1093 mutex_init(&vml_mutex);
1094 INIT_LIST_HEAD(&global_no_mode);
1095 INIT_LIST_HEAD(&global_has_mode);
1096
1097 return pci_register_driver(&vmlfb_pci_driver);
1098}
1099
1100int vmlfb_register_subsys(struct vml_sys *sys)
1101{
1102 struct vml_info *entry;
1103 struct list_head *list;
1104 u32 save_activate;
1105
1106 mutex_lock(&vml_mutex);
1107 if (subsys != NULL) {
1108 subsys->restore(subsys);
1109 }
1110 subsys = sys;
1111 subsys->save(subsys);
1112
1113 /*
1114 * We need to restart list traversal for each item, since we
1115 * release the list mutex in the loop.
1116 */
1117
1118 list = global_no_mode.next;
1119 while (list != &global_no_mode) {
1120 list_del_init(list);
1121 entry = list_entry(list, struct vml_info, head);
1122
1123 /*
1124 * First, try the current mode which might not be
1125 * completely validated with respect to the pixel clock.
1126 */
1127
1128 if (!vmlfb_check_var_locked(&entry->info.var, entry)) {
1129 vmlfb_set_par_locked(entry);
1130 list_add_tail(list, &global_has_mode);
1131 } else {
1132
1133 /*
1134 * Didn't work. Try to find another mode,
1135 * that matches this subsys.
1136 */
1137
1138 mutex_unlock(&vml_mutex);
1139 save_activate = entry->info.var.activate;
1140 entry->info.var.bits_per_pixel = 16;
1141 vmlfb_set_pref_pixel_format(&entry->info.var);
1142 if (fb_find_mode(&entry->info.var,
1143 &entry->info,
1144 vml_default_mode, NULL, 0, NULL, 16)) {
1145 entry->info.var.activate |=
1146 FB_ACTIVATE_FORCE | FB_ACTIVATE_NOW;
1147 fb_set_var(&entry->info, &entry->info.var);
1148 } else {
1149 printk(KERN_ERR MODULE_NAME
1150 ": Sorry. no mode found for this subsys.\n");
1151 }
1152 entry->info.var.activate = save_activate;
1153 mutex_lock(&vml_mutex);
1154 }
1155 vmlfb_blank_locked(entry);
1156 list = global_no_mode.next;
1157 }
1158 mutex_unlock(&vml_mutex);
1159
1160 printk(KERN_DEBUG MODULE_NAME ": Registered %s subsystem.\n",
1161 subsys->name ? subsys->name : "unknown");
1162 return 0;
1163}
1164
1165EXPORT_SYMBOL_GPL(vmlfb_register_subsys);
1166
1167void vmlfb_unregister_subsys(struct vml_sys *sys)
1168{
1169 struct vml_info *entry, *next;
1170
1171 mutex_lock(&vml_mutex);
1172 if (subsys != sys) {
1173 mutex_unlock(&vml_mutex);
1174 return;
1175 }
1176 subsys->restore(subsys);
1177 subsys = NULL;
1178 list_for_each_entry_safe(entry, next, &global_has_mode, head) {
1179 printk(KERN_DEBUG MODULE_NAME ": subsys disable pipe\n");
1180 vmlfb_disable_pipe(entry);
1181 list_del(&entry->head);
1182 list_add_tail(&entry->head, &global_no_mode);
1183 }
1184 mutex_unlock(&vml_mutex);
1185}
1186
1187EXPORT_SYMBOL_GPL(vmlfb_unregister_subsys);
1188
1189module_init(vmlfb_init);
1190module_exit(vmlfb_cleanup);
1191
1192MODULE_AUTHOR("Tungsten Graphics");
1193MODULE_DESCRIPTION("Initialization of the Vermilion display devices");
1194MODULE_VERSION("1.0.0");
1195MODULE_LICENSE("GPL");
diff --git a/drivers/video/vermilion/vermilion.h b/drivers/video/vermilion/vermilion.h
new file mode 100644
index 000000000000..1fc6695a49d2
--- /dev/null
+++ b/drivers/video/vermilion/vermilion.h
@@ -0,0 +1,260 @@
1/*
2 * Copyright (c) Intel Corp. 2007.
3 * All Rights Reserved.
4 *
5 * Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to
6 * develop this driver.
7 *
8 * This file is part of the Vermilion Range fb driver.
9 * The Vermilion Range fb driver is free software;
10 * you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * The Vermilion Range fb driver is distributed
16 * in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this driver; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
24 *
25 * Authors:
26 * Thomas Hellström <thomas-at-tungstengraphics-dot-com>
27 */
28
29#ifndef _VERMILION_H_
30#define _VERMILION_H_
31
32#include <linux/kernel.h>
33#include <linux/version.h>
34#include <linux/pci.h>
35#include <asm/atomic.h>
36#include <linux/mutex.h>
37
38#define VML_DEVICE_GPU 0x5002
39#define VML_DEVICE_VDC 0x5009
40
41#define VML_VRAM_AREAS 3
42#define VML_MAX_XRES 1024
43#define VML_MAX_YRES 768
44#define VML_MAX_XRES_VIRTUAL 1040
45
46/*
47 * Display controller registers:
48 */
49
50/* Display controller 10-bit color representation */
51
52#define VML_R_MASK 0x3FF00000
53#define VML_R_SHIFT 20
54#define VML_G_MASK 0x000FFC00
55#define VML_G_SHIFT 10
56#define VML_B_MASK 0x000003FF
57#define VML_B_SHIFT 0
58
59/* Graphics plane control */
60#define VML_DSPCCNTR 0x00072180
61#define VML_GFX_ENABLE 0x80000000
62#define VML_GFX_GAMMABYPASS 0x40000000
63#define VML_GFX_ARGB1555 0x0C000000
64#define VML_GFX_RGB0888 0x18000000
65#define VML_GFX_ARGB8888 0x1C000000
66#define VML_GFX_ALPHACONST 0x02000000
67#define VML_GFX_ALPHAMULT 0x01000000
68#define VML_GFX_CONST_ALPHA 0x000000FF
69
70/* Graphics plane start address. Pixel aligned. */
71#define VML_DSPCADDR 0x00072184
72
73/* Graphics plane stride register. */
74#define VML_DSPCSTRIDE 0x00072188
75
76/* Graphics plane position register. */
77#define VML_DSPCPOS 0x0007218C
78#define VML_POS_YMASK 0x0FFF0000
79#define VML_POS_YSHIFT 16
80#define VML_POS_XMASK 0x00000FFF
81#define VML_POS_XSHIFT 0
82
83/* Graphics plane height and width */
84#define VML_DSPCSIZE 0x00072190
85#define VML_SIZE_HMASK 0x0FFF0000
86#define VML_SIZE_HSHIFT 16
87#define VML_SISE_WMASK 0x00000FFF
88#define VML_SIZE_WSHIFT 0
89
90/* Graphics plane gamma correction lookup table registers (129 * 32 bits) */
91#define VML_DSPCGAMLUT 0x00072200
92
93/* Pixel video output configuration register */
94#define VML_PVOCONFIG 0x00061140
95#define VML_CONFIG_BASE 0x80000000
96#define VML_CONFIG_PIXEL_SWAP 0x04000000
97#define VML_CONFIG_DE_INV 0x01000000
98#define VML_CONFIG_HREF_INV 0x00400000
99#define VML_CONFIG_VREF_INV 0x00100000
100#define VML_CONFIG_CLK_INV 0x00040000
101#define VML_CONFIG_CLK_DIV2 0x00010000
102#define VML_CONFIG_ESTRB_INV 0x00008000
103
104/* Pipe A Horizontal total register */
105#define VML_HTOTAL_A 0x00060000
106#define VML_HTOTAL_MASK 0x1FFF0000
107#define VML_HTOTAL_SHIFT 16
108#define VML_HTOTAL_VAL 8192
109#define VML_HACTIVE_MASK 0x000007FF
110#define VML_HACTIVE_SHIFT 0
111#define VML_HACTIVE_VAL 4096
112
113/* Pipe A Horizontal Blank register */
114#define VML_HBLANK_A 0x00060004
115#define VML_HBLANK_END_MASK 0x1FFF0000
116#define VML_HBLANK_END_SHIFT 16
117#define VML_HBLANK_END_VAL 8192
118#define VML_HBLANK_START_MASK 0x00001FFF
119#define VML_HBLANK_START_SHIFT 0
120#define VML_HBLANK_START_VAL 8192
121
122/* Pipe A Horizontal Sync register */
123#define VML_HSYNC_A 0x00060008
124#define VML_HSYNC_END_MASK 0x1FFF0000
125#define VML_HSYNC_END_SHIFT 16
126#define VML_HSYNC_END_VAL 8192
127#define VML_HSYNC_START_MASK 0x00001FFF
128#define VML_HSYNC_START_SHIFT 0
129#define VML_HSYNC_START_VAL 8192
130
131/* Pipe A Vertical total register */
132#define VML_VTOTAL_A 0x0006000C
133#define VML_VTOTAL_MASK 0x1FFF0000
134#define VML_VTOTAL_SHIFT 16
135#define VML_VTOTAL_VAL 8192
136#define VML_VACTIVE_MASK 0x000007FF
137#define VML_VACTIVE_SHIFT 0
138#define VML_VACTIVE_VAL 4096
139
140/* Pipe A Vertical Blank register */
141#define VML_VBLANK_A 0x00060010
142#define VML_VBLANK_END_MASK 0x1FFF0000
143#define VML_VBLANK_END_SHIFT 16
144#define VML_VBLANK_END_VAL 8192
145#define VML_VBLANK_START_MASK 0x00001FFF
146#define VML_VBLANK_START_SHIFT 0
147#define VML_VBLANK_START_VAL 8192
148
149/* Pipe A Vertical Sync register */
150#define VML_VSYNC_A 0x00060014
151#define VML_VSYNC_END_MASK 0x1FFF0000
152#define VML_VSYNC_END_SHIFT 16
153#define VML_VSYNC_END_VAL 8192
154#define VML_VSYNC_START_MASK 0x00001FFF
155#define VML_VSYNC_START_SHIFT 0
156#define VML_VSYNC_START_VAL 8192
157
158/* Pipe A Source Image size (minus one - equal to active size)
159 * Programmable while pipe is enabled.
160 */
161#define VML_PIPEASRC 0x0006001C
162#define VML_PIPEASRC_HMASK 0x0FFF0000
163#define VML_PIPEASRC_HSHIFT 16
164#define VML_PIPEASRC_VMASK 0x00000FFF
165#define VML_PIPEASRC_VSHIFT 0
166
167/* Pipe A Border Color Pattern register (10 bit color) */
168#define VML_BCLRPAT_A 0x00060020
169
170/* Pipe A Canvas Color register (10 bit color) */
171#define VML_CANVSCLR_A 0x00060024
172
173/* Pipe A Configuration register */
174#define VML_PIPEACONF 0x00070008
175#define VML_PIPE_BASE 0x00000000
176#define VML_PIPE_ENABLE 0x80000000
177#define VML_PIPE_FORCE_BORDER 0x02000000
178#define VML_PIPE_PLANES_OFF 0x00080000
179#define VML_PIPE_ARGB_OUTPUT_MODE 0x00040000
180
181/* Pipe A FIFO setting */
182#define VML_DSPARB 0x00070030
183#define VML_FIFO_DEFAULT 0x00001D9C
184
185/* MDVO rcomp status & pads control register */
186#define VML_RCOMPSTAT 0x00070048
187#define VML_MDVO_VDC_I_RCOMP 0x80000000
188#define VML_MDVO_POWERSAVE_OFF 0x00000008
189#define VML_MDVO_PAD_ENABLE 0x00000004
190#define VML_MDVO_PULLDOWN_ENABLE 0x00000001
191
192struct vml_par {
193 struct pci_dev *vdc;
194 u64 vdc_mem_base;
195 u64 vdc_mem_size;
196 char __iomem *vdc_mem;
197
198 struct pci_dev *gpu;
199 u64 gpu_mem_base;
200 u64 gpu_mem_size;
201 char __iomem *gpu_mem;
202
203 atomic_t refcount;
204};
205
206struct vram_area {
207 unsigned long logical;
208 unsigned long phys;
209 unsigned long size;
210 unsigned order;
211};
212
213struct vml_info {
214 struct fb_info info;
215 struct vml_par *par;
216 struct list_head head;
217 struct vram_area vram[VML_VRAM_AREAS];
218 u64 vram_start;
219 u64 vram_contig_size;
220 u32 num_areas;
221 void __iomem *vram_logical;
222 u32 pseudo_palette[16];
223 u32 stride;
224 u32 bytes_per_pixel;
225 atomic_t vmas;
226 int cur_blank_mode;
227 int pipe_disabled;
228};
229
230/*
231 * Subsystem
232 */
233
234struct vml_sys {
235 char *name;
236
237 /*
238 * Save / Restore;
239 */
240
241 int (*save) (struct vml_sys * sys);
242 int (*restore) (struct vml_sys * sys);
243
244 /*
245 * PLL programming;
246 */
247
248 int (*set_clock) (struct vml_sys * sys, int clock);
249 int (*nearest_clock) (const struct vml_sys * sys, int clock);
250};
251
252extern int vmlfb_register_subsys(struct vml_sys *sys);
253extern void vmlfb_unregister_subsys(struct vml_sys *sys);
254
255#define VML_READ32(_par, _offset) \
256 (ioread32((_par)->vdc_mem + (_offset)))
257#define VML_WRITE32(_par, _offset, _value) \
258 iowrite32(_value, (_par)->vdc_mem + (_offset))
259
260#endif
diff --git a/drivers/video/vfb.c b/drivers/video/vfb.c
index a9b99b01bd8e..64ee78c3c12b 100644
--- a/drivers/video/vfb.c
+++ b/drivers/video/vfb.c
@@ -84,13 +84,15 @@ static int vfb_mmap(struct fb_info *info,
84 struct vm_area_struct *vma); 84 struct vm_area_struct *vma);
85 85
86static struct fb_ops vfb_ops = { 86static struct fb_ops vfb_ops = {
87 .fb_read = fb_sys_read,
88 .fb_write = fb_sys_write,
87 .fb_check_var = vfb_check_var, 89 .fb_check_var = vfb_check_var,
88 .fb_set_par = vfb_set_par, 90 .fb_set_par = vfb_set_par,
89 .fb_setcolreg = vfb_setcolreg, 91 .fb_setcolreg = vfb_setcolreg,
90 .fb_pan_display = vfb_pan_display, 92 .fb_pan_display = vfb_pan_display,
91 .fb_fillrect = cfb_fillrect, 93 .fb_fillrect = sys_fillrect,
92 .fb_copyarea = cfb_copyarea, 94 .fb_copyarea = sys_copyarea,
93 .fb_imageblit = cfb_imageblit, 95 .fb_imageblit = sys_imageblit,
94 .fb_mmap = vfb_mmap, 96 .fb_mmap = vfb_mmap,
95}; 97};
96 98
diff --git a/drivers/video/vga16fb.c b/drivers/video/vga16fb.c
index ec4c7dc54a66..2a14d28c4163 100644
--- a/drivers/video/vga16fb.c
+++ b/drivers/video/vga16fb.c
@@ -1378,6 +1378,8 @@ static int __init vga16fb_probe(struct platform_device *dev)
1378 info->fbops = &vga16fb_ops; 1378 info->fbops = &vga16fb_ops;
1379 info->var = vga16fb_defined; 1379 info->var = vga16fb_defined;
1380 info->fix = vga16fb_fix; 1380 info->fix = vga16fb_fix;
1381 /* supports rectangles with widths of multiples of 8 */
1382 info->pixmap.blit_x = 1 << 7 | 1 << 15 | 1 << 23 | 1 << 31;
1381 info->flags = FBINFO_FLAG_DEFAULT | 1383 info->flags = FBINFO_FLAG_DEFAULT |
1382 FBINFO_HWACCEL_YPAN; 1384 FBINFO_HWACCEL_YPAN;
1383 1385
diff --git a/drivers/video/vgastate.c b/drivers/video/vgastate.c
index d94efafc77b5..b91c466225b9 100644
--- a/drivers/video/vgastate.c
+++ b/drivers/video/vgastate.c
@@ -50,23 +50,28 @@ static void save_vga_text(struct vgastate *state, void __iomem *fbbase)
50 struct regstate *saved = (struct regstate *) state->vidstate; 50 struct regstate *saved = (struct regstate *) state->vidstate;
51 int i; 51 int i;
52 u8 misc, attr10, gr4, gr5, gr6, seq1, seq2, seq4; 52 u8 misc, attr10, gr4, gr5, gr6, seq1, seq2, seq4;
53 unsigned short iobase;
53 54
54 /* if in graphics mode, no need to save */ 55 /* if in graphics mode, no need to save */
56 misc = vga_r(state->vgabase, VGA_MIS_R);
57 iobase = (misc & 1) ? 0x3d0 : 0x3b0;
58
59 vga_r(state->vgabase, iobase + 0xa);
60 vga_w(state->vgabase, VGA_ATT_W, 0x00);
55 attr10 = vga_rattr(state->vgabase, 0x10); 61 attr10 = vga_rattr(state->vgabase, 0x10);
62 vga_r(state->vgabase, iobase + 0xa);
63 vga_w(state->vgabase, VGA_ATT_W, 0x20);
64
56 if (attr10 & 1) 65 if (attr10 & 1)
57 return; 66 return;
58 67
59 /* save regs */ 68 /* save regs */
60 misc = vga_r(state->vgabase, VGA_MIS_R);
61 gr4 = vga_rgfx(state->vgabase, VGA_GFX_PLANE_READ); 69 gr4 = vga_rgfx(state->vgabase, VGA_GFX_PLANE_READ);
62 gr5 = vga_rgfx(state->vgabase, VGA_GFX_MODE); 70 gr5 = vga_rgfx(state->vgabase, VGA_GFX_MODE);
63 gr6 = vga_rgfx(state->vgabase, VGA_GFX_MISC); 71 gr6 = vga_rgfx(state->vgabase, VGA_GFX_MISC);
64 seq2 = vga_rseq(state->vgabase, VGA_SEQ_PLANE_WRITE); 72 seq2 = vga_rseq(state->vgabase, VGA_SEQ_PLANE_WRITE);
65 seq4 = vga_rseq(state->vgabase, VGA_SEQ_MEMORY_MODE); 73 seq4 = vga_rseq(state->vgabase, VGA_SEQ_MEMORY_MODE);
66 74
67 /* force graphics mode */
68 vga_w(state->vgabase, VGA_MIS_W, misc | 1);
69
70 /* blank screen */ 75 /* blank screen */
71 seq1 = vga_rseq(state->vgabase, VGA_SEQ_CLOCK_MODE); 76 seq1 = vga_rseq(state->vgabase, VGA_SEQ_CLOCK_MODE);
72 vga_wseq(state->vgabase, VGA_SEQ_RESET, 0x1); 77 vga_wseq(state->vgabase, VGA_SEQ_RESET, 0x1);
@@ -115,15 +120,12 @@ static void save_vga_text(struct vgastate *state, void __iomem *fbbase)
115 } 120 }
116 121
117 /* restore regs */ 122 /* restore regs */
118 vga_wattr(state->vgabase, 0x10, attr10);
119
120 vga_wseq(state->vgabase, VGA_SEQ_PLANE_WRITE, seq2); 123 vga_wseq(state->vgabase, VGA_SEQ_PLANE_WRITE, seq2);
121 vga_wseq(state->vgabase, VGA_SEQ_MEMORY_MODE, seq4); 124 vga_wseq(state->vgabase, VGA_SEQ_MEMORY_MODE, seq4);
122 125
123 vga_wgfx(state->vgabase, VGA_GFX_PLANE_READ, gr4); 126 vga_wgfx(state->vgabase, VGA_GFX_PLANE_READ, gr4);
124 vga_wgfx(state->vgabase, VGA_GFX_MODE, gr5); 127 vga_wgfx(state->vgabase, VGA_GFX_MODE, gr5);
125 vga_wgfx(state->vgabase, VGA_GFX_MISC, gr6); 128 vga_wgfx(state->vgabase, VGA_GFX_MISC, gr6);
126 vga_w(state->vgabase, VGA_MIS_W, misc);
127 129
128 /* unblank screen */ 130 /* unblank screen */
129 vga_wseq(state->vgabase, VGA_SEQ_RESET, 0x1); 131 vga_wseq(state->vgabase, VGA_SEQ_RESET, 0x1);
@@ -137,11 +139,10 @@ static void restore_vga_text(struct vgastate *state, void __iomem *fbbase)
137{ 139{
138 struct regstate *saved = (struct regstate *) state->vidstate; 140 struct regstate *saved = (struct regstate *) state->vidstate;
139 int i; 141 int i;
140 u8 misc, gr1, gr3, gr4, gr5, gr6, gr8; 142 u8 gr1, gr3, gr4, gr5, gr6, gr8;
141 u8 seq1, seq2, seq4; 143 u8 seq1, seq2, seq4;
142 144
143 /* save regs */ 145 /* save regs */
144 misc = vga_r(state->vgabase, VGA_MIS_R);
145 gr1 = vga_rgfx(state->vgabase, VGA_GFX_SR_ENABLE); 146 gr1 = vga_rgfx(state->vgabase, VGA_GFX_SR_ENABLE);
146 gr3 = vga_rgfx(state->vgabase, VGA_GFX_DATA_ROTATE); 147 gr3 = vga_rgfx(state->vgabase, VGA_GFX_DATA_ROTATE);
147 gr4 = vga_rgfx(state->vgabase, VGA_GFX_PLANE_READ); 148 gr4 = vga_rgfx(state->vgabase, VGA_GFX_PLANE_READ);
@@ -151,9 +152,6 @@ static void restore_vga_text(struct vgastate *state, void __iomem *fbbase)
151 seq2 = vga_rseq(state->vgabase, VGA_SEQ_PLANE_WRITE); 152 seq2 = vga_rseq(state->vgabase, VGA_SEQ_PLANE_WRITE);
152 seq4 = vga_rseq(state->vgabase, VGA_SEQ_MEMORY_MODE); 153 seq4 = vga_rseq(state->vgabase, VGA_SEQ_MEMORY_MODE);
153 154
154 /* force graphics mode */
155 vga_w(state->vgabase, VGA_MIS_W, misc | 1);
156
157 /* blank screen */ 155 /* blank screen */
158 seq1 = vga_rseq(state->vgabase, VGA_SEQ_CLOCK_MODE); 156 seq1 = vga_rseq(state->vgabase, VGA_SEQ_CLOCK_MODE);
159 vga_wseq(state->vgabase, VGA_SEQ_RESET, 0x1); 157 vga_wseq(state->vgabase, VGA_SEQ_RESET, 0x1);
@@ -213,8 +211,6 @@ static void restore_vga_text(struct vgastate *state, void __iomem *fbbase)
213 vga_wseq(state->vgabase, VGA_SEQ_RESET, 0x3); 211 vga_wseq(state->vgabase, VGA_SEQ_RESET, 0x3);
214 212
215 /* restore regs */ 213 /* restore regs */
216 vga_w(state->vgabase, VGA_MIS_W, misc);
217
218 vga_wgfx(state->vgabase, VGA_GFX_SR_ENABLE, gr1); 214 vga_wgfx(state->vgabase, VGA_GFX_SR_ENABLE, gr1);
219 vga_wgfx(state->vgabase, VGA_GFX_DATA_ROTATE, gr3); 215 vga_wgfx(state->vgabase, VGA_GFX_DATA_ROTATE, gr3);
220 vga_wgfx(state->vgabase, VGA_GFX_PLANE_READ, gr4); 216 vga_wgfx(state->vgabase, VGA_GFX_PLANE_READ, gr4);
diff --git a/drivers/video/xilinxfb.c b/drivers/video/xilinxfb.c
new file mode 100644
index 000000000000..1d29a89a86b4
--- /dev/null
+++ b/drivers/video/xilinxfb.c
@@ -0,0 +1,381 @@
1/*
2 * xilinxfb.c
3 *
4 * Xilinx TFT LCD frame buffer driver
5 *
6 * Author: MontaVista Software, Inc.
7 * source@mvista.com
8 *
9 * 2002-2007 (c) MontaVista Software, Inc. This file is licensed under the
10 * terms of the GNU General Public License version 2. This program is licensed
11 * "as is" without any warranty of any kind, whether express or implied.
12 */
13
14/*
15 * This driver was based on au1100fb.c by MontaVista rewritten for 2.6
16 * by Embedded Alley Solutions <source@embeddedalley.com>, which in turn
17 * was based on skeletonfb.c, Skeleton for a frame buffer device by
18 * Geert Uytterhoeven.
19 */
20
21#include <linux/module.h>
22#include <linux/kernel.h>
23#include <linux/version.h>
24#include <linux/errno.h>
25#include <linux/string.h>
26#include <linux/mm.h>
27#include <linux/fb.h>
28#include <linux/init.h>
29#include <linux/dma-mapping.h>
30#include <linux/platform_device.h>
31
32#include <asm/io.h>
33#include <syslib/virtex_devices.h>
34
35#define DRIVER_NAME "xilinxfb"
36#define DRIVER_DESCRIPTION "Xilinx TFT LCD frame buffer driver"
37
38/*
39 * Xilinx calls it "PLB TFT LCD Controller" though it can also be used for
40 * the VGA port on the Xilinx ML40x board. This is a hardware display controller
41 * for a 640x480 resolution TFT or VGA screen.
42 *
43 * The interface to the framebuffer is nice and simple. There are two
44 * control registers. The first tells the LCD interface where in memory
45 * the frame buffer is (only the 11 most significant bits are used, so
46 * don't start thinking about scrolling). The second allows the LCD to
47 * be turned on or off as well as rotated 180 degrees.
48 */
49#define NUM_REGS 2
50#define REG_FB_ADDR 0
51#define REG_CTRL 1
52#define REG_CTRL_ENABLE 0x0001
53#define REG_CTRL_ROTATE 0x0002
54
55/*
56 * The hardware only handles a single mode: 640x480 24 bit true
57 * color. Each pixel gets a word (32 bits) of memory. Within each word,
58 * the 8 most significant bits are ignored, the next 8 bits are the red
59 * level, the next 8 bits are the green level and the 8 least
60 * significant bits are the blue level. Each row of the LCD uses 1024
61 * words, but only the first 640 pixels are displayed with the other 384
62 * words being ignored. There are 480 rows.
63 */
64#define BYTES_PER_PIXEL 4
65#define BITS_PER_PIXEL (BYTES_PER_PIXEL * 8)
66#define XRES 640
67#define YRES 480
68#define XRES_VIRTUAL 1024
69#define YRES_VIRTUAL YRES
70#define LINE_LENGTH (XRES_VIRTUAL * BYTES_PER_PIXEL)
71#define FB_SIZE (YRES_VIRTUAL * LINE_LENGTH)
72
73#define RED_SHIFT 16
74#define GREEN_SHIFT 8
75#define BLUE_SHIFT 0
76
77#define PALETTE_ENTRIES_NO 16 /* passed to fb_alloc_cmap() */
78
79/*
80 * Here are the default fb_fix_screeninfo and fb_var_screeninfo structures
81 */
82static struct fb_fix_screeninfo xilinx_fb_fix __initdata = {
83 .id = "Xilinx",
84 .type = FB_TYPE_PACKED_PIXELS,
85 .visual = FB_VISUAL_TRUECOLOR,
86 .smem_len = FB_SIZE,
87 .line_length = LINE_LENGTH,
88 .accel = FB_ACCEL_NONE
89};
90
91static struct fb_var_screeninfo xilinx_fb_var __initdata = {
92 .xres = XRES,
93 .yres = YRES,
94 .xres_virtual = XRES_VIRTUAL,
95 .yres_virtual = YRES_VIRTUAL,
96
97 .bits_per_pixel = BITS_PER_PIXEL,
98
99 .red = { RED_SHIFT, 8, 0 },
100 .green = { GREEN_SHIFT, 8, 0 },
101 .blue = { BLUE_SHIFT, 8, 0 },
102 .transp = { 0, 0, 0 },
103
104 .activate = FB_ACTIVATE_NOW
105};
106
107struct xilinxfb_drvdata {
108
109 struct fb_info info; /* FB driver info record */
110
111 u32 regs_phys; /* phys. address of the control registers */
112 u32 __iomem *regs; /* virt. address of the control registers */
113
114 unsigned char __iomem *fb_virt; /* virt. address of the frame buffer */
115 dma_addr_t fb_phys; /* phys. address of the frame buffer */
116
117 u32 reg_ctrl_default;
118
119 u32 pseudo_palette[PALETTE_ENTRIES_NO];
120 /* Fake palette of 16 colors */
121};
122
123#define to_xilinxfb_drvdata(_info) \
124 container_of(_info, struct xilinxfb_drvdata, info)
125
126/*
127 * The LCD controller has DCR interface to its registers, but all
128 * the boards and configurations the driver has been tested with
129 * use opb2dcr bridge. So the registers are seen as memory mapped.
130 * This macro is to make it simple to add the direct DCR access
131 * when it's needed.
132 */
133#define xilinx_fb_out_be32(driverdata, offset, val) \
134 out_be32(driverdata->regs + offset, val)
135
136static int
137xilinx_fb_setcolreg(unsigned regno, unsigned red, unsigned green, unsigned blue,
138 unsigned transp, struct fb_info *fbi)
139{
140 u32 *palette = fbi->pseudo_palette;
141
142 if (regno >= PALETTE_ENTRIES_NO)
143 return -EINVAL;
144
145 if (fbi->var.grayscale) {
146 /* Convert color to grayscale.
147 * grayscale = 0.30*R + 0.59*G + 0.11*B */
148 red = green = blue =
149 (red * 77 + green * 151 + blue * 28 + 127) >> 8;
150 }
151
152 /* fbi->fix.visual is always FB_VISUAL_TRUECOLOR */
153
154 /* We only handle 8 bits of each color. */
155 red >>= 8;
156 green >>= 8;
157 blue >>= 8;
158 palette[regno] = (red << RED_SHIFT) | (green << GREEN_SHIFT) |
159 (blue << BLUE_SHIFT);
160
161 return 0;
162}
163
164static int
165xilinx_fb_blank(int blank_mode, struct fb_info *fbi)
166{
167 struct xilinxfb_drvdata *drvdata = to_xilinxfb_drvdata(fbi);
168
169 switch (blank_mode) {
170 case FB_BLANK_UNBLANK:
171 /* turn on panel */
172 xilinx_fb_out_be32(drvdata, REG_CTRL, drvdata->reg_ctrl_default);
173 break;
174
175 case FB_BLANK_NORMAL:
176 case FB_BLANK_VSYNC_SUSPEND:
177 case FB_BLANK_HSYNC_SUSPEND:
178 case FB_BLANK_POWERDOWN:
179 /* turn off panel */
180 xilinx_fb_out_be32(drvdata, REG_CTRL, 0);
181 default:
182 break;
183
184 }
185 return 0; /* success */
186}
187
188static struct fb_ops xilinxfb_ops =
189{
190 .owner = THIS_MODULE,
191 .fb_setcolreg = xilinx_fb_setcolreg,
192 .fb_blank = xilinx_fb_blank,
193 .fb_fillrect = cfb_fillrect,
194 .fb_copyarea = cfb_copyarea,
195 .fb_imageblit = cfb_imageblit,
196};
197
198/* === The device driver === */
199
200static int
201xilinxfb_drv_probe(struct device *dev)
202{
203 struct platform_device *pdev;
204 struct xilinxfb_platform_data *pdata;
205 struct xilinxfb_drvdata *drvdata;
206 struct resource *regs_res;
207 int retval;
208
209 if (!dev)
210 return -EINVAL;
211
212 pdev = to_platform_device(dev);
213 pdata = pdev->dev.platform_data;
214
215 if (pdata == NULL) {
216 printk(KERN_ERR "Couldn't find platform data.\n");
217 return -EFAULT;
218 }
219
220 drvdata = kzalloc(sizeof(*drvdata), GFP_KERNEL);
221 if (!drvdata) {
222 printk(KERN_ERR "Couldn't allocate device private record\n");
223 return -ENOMEM;
224 }
225 dev_set_drvdata(dev, drvdata);
226
227 /* Map the control registers in */
228 regs_res = platform_get_resource(pdev, IORESOURCE_IO, 0);
229 if (!regs_res || (regs_res->end - regs_res->start + 1 < 8)) {
230 printk(KERN_ERR "Couldn't get registers resource\n");
231 retval = -EFAULT;
232 goto failed1;
233 }
234
235 if (!request_mem_region(regs_res->start, 8, DRIVER_NAME)) {
236 printk(KERN_ERR
237 "Couldn't lock memory region at 0x%08X\n",
238 regs_res->start);
239 retval = -EBUSY;
240 goto failed1;
241 }
242 drvdata->regs = (u32 __iomem*) ioremap(regs_res->start, 8);
243 drvdata->regs_phys = regs_res->start;
244
245 /* Allocate the framebuffer memory */
246 drvdata->fb_virt = dma_alloc_coherent(dev, PAGE_ALIGN(FB_SIZE),
247 &drvdata->fb_phys, GFP_KERNEL);
248 if (!drvdata->fb_virt) {
249 printk(KERN_ERR "Could not allocate frame buffer memory\n");
250 retval = -ENOMEM;
251 goto failed2;
252 }
253
254 /* Clear (turn to black) the framebuffer */
255 memset_io((void *) drvdata->fb_virt, 0, FB_SIZE);
256
257 /* Tell the hardware where the frame buffer is */
258 xilinx_fb_out_be32(drvdata, REG_FB_ADDR, drvdata->fb_phys);
259
260 /* Turn on the display */
261 if (pdata->rotate_screen) {
262 drvdata->reg_ctrl_default = REG_CTRL_ENABLE | REG_CTRL_ROTATE;
263 } else {
264 drvdata->reg_ctrl_default = REG_CTRL_ENABLE;
265 }
266 xilinx_fb_out_be32(drvdata, REG_CTRL, drvdata->reg_ctrl_default);
267
268 /* Fill struct fb_info */
269 drvdata->info.device = dev;
270 drvdata->info.screen_base = drvdata->fb_virt;
271 drvdata->info.fbops = &xilinxfb_ops;
272 drvdata->info.fix = xilinx_fb_fix;
273 drvdata->info.fix.smem_start = drvdata->fb_phys;
274 drvdata->info.pseudo_palette = drvdata->pseudo_palette;
275
276 if (fb_alloc_cmap(&drvdata->info.cmap, PALETTE_ENTRIES_NO, 0) < 0) {
277 printk(KERN_ERR "Fail to allocate colormap (%d entries)\n",
278 PALETTE_ENTRIES_NO);
279 retval = -EFAULT;
280 goto failed3;
281 }
282
283 drvdata->info.flags = FBINFO_DEFAULT;
284 xilinx_fb_var.height = pdata->screen_height_mm;
285 xilinx_fb_var.width = pdata->screen_width_mm;
286 drvdata->info.var = xilinx_fb_var;
287
288 /* Register new frame buffer */
289 if (register_framebuffer(&drvdata->info) < 0) {
290 printk(KERN_ERR "Could not register frame buffer\n");
291 retval = -EINVAL;
292 goto failed4;
293 }
294
295 return 0; /* success */
296
297failed4:
298 fb_dealloc_cmap(&drvdata->info.cmap);
299
300failed3:
301 dma_free_coherent(dev, PAGE_ALIGN(FB_SIZE), drvdata->fb_virt,
302 drvdata->fb_phys);
303
304 /* Turn off the display */
305 xilinx_fb_out_be32(drvdata, REG_CTRL, 0);
306 iounmap(drvdata->regs);
307
308failed2:
309 release_mem_region(regs_res->start, 8);
310
311failed1:
312 kfree(drvdata);
313 dev_set_drvdata(dev, NULL);
314
315 return retval;
316}
317
318static int
319xilinxfb_drv_remove(struct device *dev)
320{
321 struct xilinxfb_drvdata *drvdata;
322
323 if (!dev)
324 return -ENODEV;
325
326 drvdata = (struct xilinxfb_drvdata *) dev_get_drvdata(dev);
327
328#if !defined(CONFIG_FRAMEBUFFER_CONSOLE) && defined(CONFIG_LOGO)
329 xilinx_fb_blank(VESA_POWERDOWN, &drvdata->info);
330#endif
331
332 unregister_framebuffer(&drvdata->info);
333
334 fb_dealloc_cmap(&drvdata->info.cmap);
335
336 dma_free_coherent(dev, PAGE_ALIGN(FB_SIZE), drvdata->fb_virt,
337 drvdata->fb_phys);
338
339 /* Turn off the display */
340 xilinx_fb_out_be32(drvdata, REG_CTRL, 0);
341 iounmap(drvdata->regs);
342
343 release_mem_region(drvdata->regs_phys, 8);
344
345 kfree(drvdata);
346 dev_set_drvdata(dev, NULL);
347
348 return 0;
349}
350
351
352static struct device_driver xilinxfb_driver = {
353 .name = DRIVER_NAME,
354 .bus = &platform_bus_type,
355
356 .probe = xilinxfb_drv_probe,
357 .remove = xilinxfb_drv_remove
358};
359
360static int __init
361xilinxfb_init(void)
362{
363 /*
364 * No kernel boot options used,
365 * so we just need to register the driver
366 */
367 return driver_register(&xilinxfb_driver);
368}
369
370static void __exit
371xilinxfb_cleanup(void)
372{
373 driver_unregister(&xilinxfb_driver);
374}
375
376module_init(xilinxfb_init);
377module_exit(xilinxfb_cleanup);
378
379MODULE_AUTHOR("MontaVista Software, Inc. <source@mvista.com>");
380MODULE_DESCRIPTION(DRIVER_DESCRIPTION);
381MODULE_LICENSE("GPL");
diff --git a/drivers/w1/masters/Kconfig b/drivers/w1/masters/Kconfig
index 2fb425536eae..8f779338f744 100644
--- a/drivers/w1/masters/Kconfig
+++ b/drivers/w1/masters/Kconfig
@@ -35,5 +35,13 @@ config W1_MASTER_DS2482
35 This driver can also be built as a module. If so, the module 35 This driver can also be built as a module. If so, the module
36 will be called ds2482. 36 will be called ds2482.
37 37
38config W1_MASTER_DS1WM
39 tristate "Maxim DS1WM 1-wire busmaster"
40 depends on W1 && ARM
41 help
42 Say Y here to enable the DS1WM 1-wire driver, such as that
43 in HP iPAQ devices like h5xxx, h2200, and ASIC3-based like
44 hx4700.
45
38endmenu 46endmenu
39 47
diff --git a/drivers/w1/masters/Makefile b/drivers/w1/masters/Makefile
index 4cee256a8134..11551b328186 100644
--- a/drivers/w1/masters/Makefile
+++ b/drivers/w1/masters/Makefile
@@ -5,4 +5,4 @@
5obj-$(CONFIG_W1_MASTER_MATROX) += matrox_w1.o 5obj-$(CONFIG_W1_MASTER_MATROX) += matrox_w1.o
6obj-$(CONFIG_W1_MASTER_DS2490) += ds2490.o 6obj-$(CONFIG_W1_MASTER_DS2490) += ds2490.o
7obj-$(CONFIG_W1_MASTER_DS2482) += ds2482.o 7obj-$(CONFIG_W1_MASTER_DS2482) += ds2482.o
8 8obj-$(CONFIG_W1_MASTER_DS1WM) += ds1wm.o
diff --git a/drivers/w1/masters/ds1wm.c b/drivers/w1/masters/ds1wm.c
new file mode 100644
index 000000000000..763bc73e5070
--- /dev/null
+++ b/drivers/w1/masters/ds1wm.c
@@ -0,0 +1,468 @@
1/*
2 * 1-wire busmaster driver for DS1WM and ASICs with embedded DS1WMs
3 * such as HP iPAQs (including h5xxx, h2200, and devices with ASIC3
4 * like hx4700).
5 *
6 * Copyright (c) 2004-2005, Szabolcs Gyurko <szabolcs.gyurko@tlt.hu>
7 * Copyright (c) 2004-2007, Matt Reimer <mreimer@vpop.net>
8 *
9 * Use consistent with the GNU GPL is permitted,
10 * provided that this copyright notice is
11 * preserved in its entirety in all copies and derived works.
12 */
13
14#include <linux/module.h>
15#include <linux/interrupt.h>
16#include <linux/irq.h>
17#include <linux/pm.h>
18#include <linux/platform_device.h>
19#include <linux/clk.h>
20#include <linux/delay.h>
21#include <linux/ds1wm.h>
22
23#include <asm/io.h>
24
25#include "../w1.h"
26#include "../w1_int.h"
27
28
29#define DS1WM_CMD 0x00 /* R/W 4 bits command */
30#define DS1WM_DATA 0x01 /* R/W 8 bits, transmit/receive buffer */
31#define DS1WM_INT 0x02 /* R/W interrupt status */
32#define DS1WM_INT_EN 0x03 /* R/W interrupt enable */
33#define DS1WM_CLKDIV 0x04 /* R/W 5 bits of divisor and pre-scale */
34
35#define DS1WM_CMD_1W_RESET (1 << 0) /* force reset on 1-wire bus */
36#define DS1WM_CMD_SRA (1 << 1) /* enable Search ROM accelerator mode */
37#define DS1WM_CMD_DQ_OUTPUT (1 << 2) /* write only - forces bus low */
38#define DS1WM_CMD_DQ_INPUT (1 << 3) /* read only - reflects state of bus */
39#define DS1WM_CMD_RST (1 << 5) /* software reset */
40#define DS1WM_CMD_OD (1 << 7) /* overdrive */
41
42#define DS1WM_INT_PD (1 << 0) /* presence detect */
43#define DS1WM_INT_PDR (1 << 1) /* presence detect result */
44#define DS1WM_INT_TBE (1 << 2) /* tx buffer empty */
45#define DS1WM_INT_TSRE (1 << 3) /* tx shift register empty */
46#define DS1WM_INT_RBF (1 << 4) /* rx buffer full */
47#define DS1WM_INT_RSRF (1 << 5) /* rx shift register full */
48
49#define DS1WM_INTEN_EPD (1 << 0) /* enable presence detect int */
50#define DS1WM_INTEN_IAS (1 << 1) /* INTR active state */
51#define DS1WM_INTEN_ETBE (1 << 2) /* enable tx buffer empty int */
52#define DS1WM_INTEN_ETMT (1 << 3) /* enable tx shift register empty int */
53#define DS1WM_INTEN_ERBF (1 << 4) /* enable rx buffer full int */
54#define DS1WM_INTEN_ERSRF (1 << 5) /* enable rx shift register full int */
55#define DS1WM_INTEN_DQO (1 << 6) /* enable direct bus driving ops */
56
57
58#define DS1WM_TIMEOUT (HZ * 5)
59
60static struct {
61 unsigned long freq;
62 unsigned long divisor;
63} freq[] = {
64 { 4000000, 0x8 },
65 { 5000000, 0x2 },
66 { 6000000, 0x5 },
67 { 7000000, 0x3 },
68 { 8000000, 0xc },
69 { 10000000, 0x6 },
70 { 12000000, 0x9 },
71 { 14000000, 0x7 },
72 { 16000000, 0x10 },
73 { 20000000, 0xa },
74 { 24000000, 0xd },
75 { 28000000, 0xb },
76 { 32000000, 0x14 },
77 { 40000000, 0xe },
78 { 48000000, 0x11 },
79 { 56000000, 0xf },
80 { 64000000, 0x18 },
81 { 80000000, 0x12 },
82 { 96000000, 0x15 },
83 { 112000000, 0x13 },
84 { 128000000, 0x1c },
85};
86
87struct ds1wm_data {
88 void *map;
89 int bus_shift; /* # of shifts to calc register offsets */
90 struct platform_device *pdev;
91 struct ds1wm_platform_data *pdata;
92 int irq;
93 int active_high;
94 struct clk *clk;
95 int slave_present;
96 void *reset_complete;
97 void *read_complete;
98 void *write_complete;
99 u8 read_byte; /* last byte received */
100};
101
102static inline void ds1wm_write_register(struct ds1wm_data *ds1wm_data, u32 reg,
103 u8 val)
104{
105 __raw_writeb(val, ds1wm_data->map + (reg << ds1wm_data->bus_shift));
106}
107
108static inline u8 ds1wm_read_register(struct ds1wm_data *ds1wm_data, u32 reg)
109{
110 return __raw_readb(ds1wm_data->map + (reg << ds1wm_data->bus_shift));
111}
112
113
114static irqreturn_t ds1wm_isr(int isr, void *data)
115{
116 struct ds1wm_data *ds1wm_data = data;
117 u8 intr = ds1wm_read_register(ds1wm_data, DS1WM_INT);
118
119 ds1wm_data->slave_present = (intr & DS1WM_INT_PDR) ? 0 : 1;
120
121 if ((intr & DS1WM_INT_PD) && ds1wm_data->reset_complete)
122 complete(ds1wm_data->reset_complete);
123
124 if ((intr & DS1WM_INT_TSRE) && ds1wm_data->write_complete)
125 complete(ds1wm_data->write_complete);
126
127 if (intr & DS1WM_INT_RBF) {
128 ds1wm_data->read_byte = ds1wm_read_register(ds1wm_data,
129 DS1WM_DATA);
130 if (ds1wm_data->read_complete)
131 complete(ds1wm_data->read_complete);
132 }
133
134 return IRQ_HANDLED;
135}
136
137static int ds1wm_reset(struct ds1wm_data *ds1wm_data)
138{
139 unsigned long timeleft;
140 DECLARE_COMPLETION_ONSTACK(reset_done);
141
142 ds1wm_data->reset_complete = &reset_done;
143
144 ds1wm_write_register(ds1wm_data, DS1WM_INT_EN, DS1WM_INTEN_EPD |
145 (ds1wm_data->active_high ? DS1WM_INTEN_IAS : 0));
146
147 ds1wm_write_register(ds1wm_data, DS1WM_CMD, DS1WM_CMD_1W_RESET);
148
149 timeleft = wait_for_completion_timeout(&reset_done, DS1WM_TIMEOUT);
150 ds1wm_data->reset_complete = NULL;
151 if (!timeleft) {
152 dev_dbg(&ds1wm_data->pdev->dev, "reset failed\n");
153 return 1;
154 }
155
156 /* Wait for the end of the reset. According to the specs, the time
157 * from when the interrupt is asserted to the end of the reset is:
158 * tRSTH - tPDH - tPDL - tPDI
159 * 625 us - 60 us - 240 us - 100 ns = 324.9 us
160 *
161 * We'll wait a bit longer just to be sure.
162 */
163 udelay(500);
164
165 ds1wm_write_register(ds1wm_data, DS1WM_INT_EN,
166 DS1WM_INTEN_ERBF | DS1WM_INTEN_ETMT | DS1WM_INTEN_EPD |
167 (ds1wm_data->active_high ? DS1WM_INTEN_IAS : 0));
168
169 if (!ds1wm_data->slave_present) {
170 dev_dbg(&ds1wm_data->pdev->dev, "reset: no devices found\n");
171 return 1;
172 }
173
174 return 0;
175}
176
177static int ds1wm_write(struct ds1wm_data *ds1wm_data, u8 data)
178{
179 DECLARE_COMPLETION_ONSTACK(write_done);
180 ds1wm_data->write_complete = &write_done;
181
182 ds1wm_write_register(ds1wm_data, DS1WM_DATA, data);
183
184 wait_for_completion_timeout(&write_done, DS1WM_TIMEOUT);
185 ds1wm_data->write_complete = NULL;
186
187 return 0;
188}
189
190static int ds1wm_read(struct ds1wm_data *ds1wm_data, unsigned char write_data)
191{
192 DECLARE_COMPLETION_ONSTACK(read_done);
193 ds1wm_data->read_complete = &read_done;
194
195 ds1wm_write(ds1wm_data, write_data);
196 wait_for_completion_timeout(&read_done, DS1WM_TIMEOUT);
197 ds1wm_data->read_complete = NULL;
198
199 return ds1wm_data->read_byte;
200}
201
202static int ds1wm_find_divisor(int gclk)
203{
204 int i;
205
206 for (i = 0; i < ARRAY_SIZE(freq); i++)
207 if (gclk <= freq[i].freq)
208 return freq[i].divisor;
209
210 return 0;
211}
212
213static void ds1wm_up(struct ds1wm_data *ds1wm_data)
214{
215 int gclk, divisor;
216
217 if (ds1wm_data->pdata->enable)
218 ds1wm_data->pdata->enable(ds1wm_data->pdev);
219
220 gclk = clk_get_rate(ds1wm_data->clk);
221 clk_enable(ds1wm_data->clk);
222 divisor = ds1wm_find_divisor(gclk);
223 if (divisor == 0) {
224 dev_err(&ds1wm_data->pdev->dev,
225 "no suitable divisor for %dHz clock\n", gclk);
226 return;
227 }
228 ds1wm_write_register(ds1wm_data, DS1WM_CLKDIV, divisor);
229
230 /* Let the w1 clock stabilize. */
231 msleep(1);
232
233 ds1wm_reset(ds1wm_data);
234}
235
236static void ds1wm_down(struct ds1wm_data *ds1wm_data)
237{
238 ds1wm_reset(ds1wm_data);
239
240 /* Disable interrupts. */
241 ds1wm_write_register(ds1wm_data, DS1WM_INT_EN,
242 ds1wm_data->active_high ? DS1WM_INTEN_IAS : 0);
243
244 if (ds1wm_data->pdata->disable)
245 ds1wm_data->pdata->disable(ds1wm_data->pdev);
246
247 clk_disable(ds1wm_data->clk);
248}
249
250/* --------------------------------------------------------------------- */
251/* w1 methods */
252
253static u8 ds1wm_read_byte(void *data)
254{
255 struct ds1wm_data *ds1wm_data = data;
256
257 return ds1wm_read(ds1wm_data, 0xff);
258}
259
260static void ds1wm_write_byte(void *data, u8 byte)
261{
262 struct ds1wm_data *ds1wm_data = data;
263
264 ds1wm_write(ds1wm_data, byte);
265}
266
267static u8 ds1wm_reset_bus(void *data)
268{
269 struct ds1wm_data *ds1wm_data = data;
270
271 ds1wm_reset(ds1wm_data);
272
273 return 0;
274}
275
276static void ds1wm_search(void *data, u8 search_type,
277 w1_slave_found_callback slave_found)
278{
279 struct ds1wm_data *ds1wm_data = data;
280 int i;
281 unsigned long long rom_id;
282
283 /* XXX We need to iterate for multiple devices per the DS1WM docs.
284 * See http://www.maxim-ic.com/appnotes.cfm/appnote_number/120. */
285 if (ds1wm_reset(ds1wm_data))
286 return;
287
288 ds1wm_write(ds1wm_data, search_type);
289 ds1wm_write_register(ds1wm_data, DS1WM_CMD, DS1WM_CMD_SRA);
290
291 for (rom_id = 0, i = 0; i < 16; i++) {
292
293 unsigned char resp, r, d;
294
295 resp = ds1wm_read(ds1wm_data, 0x00);
296
297 r = ((resp & 0x02) >> 1) |
298 ((resp & 0x08) >> 2) |
299 ((resp & 0x20) >> 3) |
300 ((resp & 0x80) >> 4);
301
302 d = ((resp & 0x01) >> 0) |
303 ((resp & 0x04) >> 1) |
304 ((resp & 0x10) >> 2) |
305 ((resp & 0x40) >> 3);
306
307 rom_id |= (unsigned long long) r << (i * 4);
308
309 }
310 dev_dbg(&ds1wm_data->pdev->dev, "found 0x%08llX", rom_id);
311
312 ds1wm_write_register(ds1wm_data, DS1WM_CMD, ~DS1WM_CMD_SRA);
313 ds1wm_reset(ds1wm_data);
314
315 slave_found(ds1wm_data, rom_id);
316}
317
318/* --------------------------------------------------------------------- */
319
320static struct w1_bus_master ds1wm_master = {
321 .read_byte = ds1wm_read_byte,
322 .write_byte = ds1wm_write_byte,
323 .reset_bus = ds1wm_reset_bus,
324 .search = ds1wm_search,
325};
326
327static int ds1wm_probe(struct platform_device *pdev)
328{
329 struct ds1wm_data *ds1wm_data;
330 struct ds1wm_platform_data *plat;
331 struct resource *res;
332 int ret;
333
334 if (!pdev)
335 return -ENODEV;
336
337 ds1wm_data = kzalloc(sizeof (*ds1wm_data), GFP_KERNEL);
338 if (!ds1wm_data)
339 return -ENOMEM;
340
341 platform_set_drvdata(pdev, ds1wm_data);
342
343 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
344 if (!res) {
345 ret = -ENXIO;
346 goto err0;
347 }
348 ds1wm_data->map = ioremap(res->start, res->end - res->start + 1);
349 if (!ds1wm_data->map) {
350 ret = -ENOMEM;
351 goto err0;
352 }
353 plat = pdev->dev.platform_data;
354 ds1wm_data->bus_shift = plat->bus_shift;
355 ds1wm_data->pdev = pdev;
356 ds1wm_data->pdata = plat;
357
358 res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
359 if (!res) {
360 ret = -ENXIO;
361 goto err1;
362 }
363 ds1wm_data->irq = res->start;
364 ds1wm_data->active_high = (res->flags & IORESOURCE_IRQ_HIGHEDGE) ?
365 1 : 0;
366
367 set_irq_type(ds1wm_data->irq, ds1wm_data->active_high ?
368 IRQ_TYPE_EDGE_RISING : IRQ_TYPE_EDGE_FALLING);
369
370 ret = request_irq(ds1wm_data->irq, ds1wm_isr, IRQF_DISABLED,
371 "ds1wm", ds1wm_data);
372 if (ret)
373 goto err1;
374
375 ds1wm_data->clk = clk_get(&pdev->dev, "ds1wm");
376 if (!ds1wm_data->clk) {
377 ret = -ENOENT;
378 goto err2;
379 }
380
381 ds1wm_up(ds1wm_data);
382
383 ds1wm_master.data = (void *)ds1wm_data;
384
385 ret = w1_add_master_device(&ds1wm_master);
386 if (ret)
387 goto err3;
388
389 return 0;
390
391err3:
392 ds1wm_down(ds1wm_data);
393 clk_put(ds1wm_data->clk);
394err2:
395 free_irq(ds1wm_data->irq, ds1wm_data);
396err1:
397 iounmap(ds1wm_data->map);
398err0:
399 kfree(ds1wm_data);
400
401 return ret;
402}
403
404#ifdef CONFIG_PM
405static int ds1wm_suspend(struct platform_device *pdev, pm_message_t state)
406{
407 struct ds1wm_data *ds1wm_data = platform_get_drvdata(pdev);
408
409 ds1wm_down(ds1wm_data);
410
411 return 0;
412}
413
414static int ds1wm_resume(struct platform_device *pdev)
415{
416 struct ds1wm_data *ds1wm_data = platform_get_drvdata(pdev);
417
418 ds1wm_up(ds1wm_data);
419
420 return 0;
421}
422#else
423#define ds1wm_suspend NULL
424#define ds1wm_resume NULL
425#endif
426
427static int ds1wm_remove(struct platform_device *pdev)
428{
429 struct ds1wm_data *ds1wm_data = platform_get_drvdata(pdev);
430
431 w1_remove_master_device(&ds1wm_master);
432 ds1wm_down(ds1wm_data);
433 clk_put(ds1wm_data->clk);
434 free_irq(ds1wm_data->irq, ds1wm_data);
435 iounmap(ds1wm_data->map);
436 kfree(ds1wm_data);
437
438 return 0;
439}
440
441static struct platform_driver ds1wm_driver = {
442 .driver = {
443 .name = "ds1wm",
444 },
445 .probe = ds1wm_probe,
446 .remove = ds1wm_remove,
447 .suspend = ds1wm_suspend,
448 .resume = ds1wm_resume
449};
450
451static int __init ds1wm_init(void)
452{
453 printk("DS1WM w1 busmaster driver - (c) 2004 Szabolcs Gyurko\n");
454 return platform_driver_register(&ds1wm_driver);
455}
456
457static void __exit ds1wm_exit(void)
458{
459 platform_driver_unregister(&ds1wm_driver);
460}
461
462module_init(ds1wm_init);
463module_exit(ds1wm_exit);
464
465MODULE_LICENSE("GPL");
466MODULE_AUTHOR("Szabolcs Gyurko <szabolcs.gyurko@tlt.hu>, "
467 "Matt Reimer <mreimer@vpop.net>");
468MODULE_DESCRIPTION("DS1WM w1 busmaster driver");
diff --git a/drivers/w1/w1.c b/drivers/w1/w1.c
index 63c07243993c..7d6876dbcc96 100644
--- a/drivers/w1/w1.c
+++ b/drivers/w1/w1.c
@@ -459,7 +459,7 @@ static int __w1_attach_slave_device(struct w1_slave *sl)
459 (unsigned long long) sl->reg_num.id); 459 (unsigned long long) sl->reg_num.id);
460 460
461 dev_dbg(&sl->dev, "%s: registering %s as %p.\n", __func__, 461 dev_dbg(&sl->dev, "%s: registering %s as %p.\n", __func__,
462 &sl->dev.bus_id[0]); 462 &sl->dev.bus_id[0], sl);
463 463
464 err = device_register(&sl->dev); 464 err = device_register(&sl->dev);
465 if (err < 0) { 465 if (err < 0) {
diff --git a/drivers/w1/w1_int.c b/drivers/w1/w1_int.c
index 357a2e0f637a..258defdb2efd 100644
--- a/drivers/w1/w1_int.c
+++ b/drivers/w1/w1_int.c
@@ -100,7 +100,8 @@ int w1_add_master_device(struct w1_bus_master *master)
100 100
101 /* validate minimum functionality */ 101 /* validate minimum functionality */
102 if (!(master->touch_bit && master->reset_bus) && 102 if (!(master->touch_bit && master->reset_bus) &&
103 !(master->write_bit && master->read_bit)) { 103 !(master->write_bit && master->read_bit) &&
104 !(master->write_byte && master->read_byte && master->reset_bus)) {
104 printk(KERN_ERR "w1_add_master_device: invalid function set\n"); 105 printk(KERN_ERR "w1_add_master_device: invalid function set\n");
105 return(-EINVAL); 106 return(-EINVAL);
106 } 107 }