diff options
author | Anton Altaparmakov <aia21@cantab.net> | 2005-06-23 11:26:22 +0100 |
---|---|---|
committer | Anton Altaparmakov <aia21@cantab.net> | 2005-06-23 11:26:22 +0100 |
commit | 3357d4c75f1fb67e7304998c4ad4e9a9fed66fa4 (patch) | |
tree | ceba46966a5a1112a05d257d8ecb25ae5eee95e0 /drivers/char | |
parent | 364f6c717deef4a3ac4982e670fa9846b43cd060 (diff) | |
parent | ee98689be1b054897ff17655008c3048fe88be94 (diff) | |
download | talos-op-linux-3357d4c75f1fb67e7304998c4ad4e9a9fed66fa4.tar.gz talos-op-linux-3357d4c75f1fb67e7304998c4ad4e9a9fed66fa4.zip |
Automatic merge with /usr/src/ntfs-2.6.git.
Diffstat (limited to 'drivers/char')
28 files changed, 895 insertions, 142 deletions
diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig index 5ed6515ae01f..7ccf871d3c9d 100644 --- a/drivers/char/Kconfig +++ b/drivers/char/Kconfig @@ -929,6 +929,10 @@ config SCx200_GPIO If compiled as a module, it will be called scx200_gpio. +config GPIO_VR41XX + tristate "NEC VR4100 series General-purpose I/O Unit support" + depends on CPU_VR41XX + config RAW_DRIVER tristate "RAW driver (/dev/raw/rawN) (OBSOLETE)" help diff --git a/drivers/char/Makefile b/drivers/char/Makefile index e3f5c32aac55..1aff819f3832 100644 --- a/drivers/char/Makefile +++ b/drivers/char/Makefile @@ -80,6 +80,7 @@ obj-$(CONFIG_PPDEV) += ppdev.o obj-$(CONFIG_NWBUTTON) += nwbutton.o obj-$(CONFIG_NWFLASH) += nwflash.o obj-$(CONFIG_SCx200_GPIO) += scx200_gpio.o +obj-$(CONFIG_GPIO_VR41XX) += vr41xx_giu.o obj-$(CONFIG_TANBAC_TB0219) += tb0219.o obj-$(CONFIG_WATCHDOG) += watchdog/ diff --git a/drivers/char/drm/drm_pciids.h b/drivers/char/drm/drm_pciids.h index 54a2914e3a32..11c6950158b3 100644 --- a/drivers/char/drm/drm_pciids.h +++ b/drivers/char/drm/drm_pciids.h @@ -220,5 +220,6 @@ {0x8086, 0x2572, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ {0x8086, 0x2582, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ {0x8086, 0x2592, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ + {0x8086, 0x2772, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ {0, 0, 0} diff --git a/drivers/char/drm/radeon_irq.c b/drivers/char/drm/radeon_irq.c index 5b18bee6492e..cd25f28e26a3 100644 --- a/drivers/char/drm/radeon_irq.c +++ b/drivers/char/drm/radeon_irq.c @@ -123,11 +123,6 @@ static int radeon_wait_irq(drm_device_t *dev, int swi_nr) dev_priv->stats.boxes |= RADEON_BOX_WAIT_IDLE; - /* This is a hack to work around mysterious freezes on certain - * systems: - */ - radeon_acknowledge_irqs( dev_priv ); - DRM_WAIT_ON( ret, dev_priv->swi_queue, 3 * DRM_HZ, RADEON_READ( RADEON_LAST_SWI_REG ) >= swi_nr ); diff --git a/drivers/char/dsp56k.c b/drivers/char/dsp56k.c index 37d6649011ad..26271e3ca823 100644 --- a/drivers/char/dsp56k.c +++ b/drivers/char/dsp56k.c @@ -144,7 +144,7 @@ static struct dsp56k_device { int tx_wsize, rx_wsize; } dsp56k; -static struct class_simple *dsp56k_class; +static struct class *dsp56k_class; static int dsp56k_reset(void) { @@ -510,12 +510,12 @@ static int __init dsp56k_init_driver(void) printk("DSP56k driver: Unable to register driver\n"); return -ENODEV; } - dsp56k_class = class_simple_create(THIS_MODULE, "dsp56k"); + dsp56k_class = class_create(THIS_MODULE, "dsp56k"); if (IS_ERR(dsp56k_class)) { err = PTR_ERR(dsp56k_class); goto out_chrdev; } - class_simple_device_add(dsp56k_class, MKDEV(DSP56K_MAJOR, 0), NULL, "dsp56k"); + class_device_create(dsp56k_class, MKDEV(DSP56K_MAJOR, 0), NULL, "dsp56k"); err = devfs_mk_cdev(MKDEV(DSP56K_MAJOR, 0), S_IFCHR | S_IRUSR | S_IWUSR, "dsp56k"); @@ -526,8 +526,8 @@ static int __init dsp56k_init_driver(void) goto out; out_class: - class_simple_device_remove(MKDEV(DSP56K_MAJOR, 0)); - class_simple_destroy(dsp56k_class); + class_device_destroy(dsp56k_class, MKDEV(DSP56K_MAJOR, 0)); + class_destroy(dsp56k_class); out_chrdev: unregister_chrdev(DSP56K_MAJOR, "dsp56k"); out: @@ -537,8 +537,8 @@ module_init(dsp56k_init_driver); static void __exit dsp56k_cleanup_driver(void) { - class_simple_device_remove(MKDEV(DSP56K_MAJOR, 0)); - class_simple_destroy(dsp56k_class); + class_device_destroy(dsp56k_class, MKDEV(DSP56K_MAJOR, 0)); + class_destroy(dsp56k_class); unregister_chrdev(DSP56K_MAJOR, "dsp56k"); devfs_remove("dsp56k"); } diff --git a/drivers/char/ftape/zftape/zftape-init.c b/drivers/char/ftape/zftape/zftape-init.c index dbac7e54e8e0..5745b74044ec 100644 --- a/drivers/char/ftape/zftape/zftape-init.c +++ b/drivers/char/ftape/zftape/zftape-init.c @@ -99,7 +99,7 @@ static struct file_operations zft_cdev = .release = zft_close, }; -static struct class_simple *zft_class; +static struct class *zft_class; /* Open floppy tape device */ @@ -329,29 +329,29 @@ KERN_INFO "installing zftape VFS interface for ftape driver ..."); TRACE_CATCH(register_chrdev(QIC117_TAPE_MAJOR, "zft", &zft_cdev),); - zft_class = class_simple_create(THIS_MODULE, "zft"); + zft_class = class_create(THIS_MODULE, "zft"); for (i = 0; i < 4; i++) { - class_simple_device_add(zft_class, MKDEV(QIC117_TAPE_MAJOR, i), NULL, "qft%i", i); + class_device_create(zft_class, MKDEV(QIC117_TAPE_MAJOR, i), NULL, "qft%i", i); devfs_mk_cdev(MKDEV(QIC117_TAPE_MAJOR, i), S_IFCHR | S_IRUSR | S_IWUSR, "qft%i", i); - class_simple_device_add(zft_class, MKDEV(QIC117_TAPE_MAJOR, i + 4), NULL, "nqft%i", i); + class_device_create(zft_class, MKDEV(QIC117_TAPE_MAJOR, i + 4), NULL, "nqft%i", i); devfs_mk_cdev(MKDEV(QIC117_TAPE_MAJOR, i + 4), S_IFCHR | S_IRUSR | S_IWUSR, "nqft%i", i); - class_simple_device_add(zft_class, MKDEV(QIC117_TAPE_MAJOR, i + 16), NULL, "zqft%i", i); + class_device_create(zft_class, MKDEV(QIC117_TAPE_MAJOR, i + 16), NULL, "zqft%i", i); devfs_mk_cdev(MKDEV(QIC117_TAPE_MAJOR, i + 16), S_IFCHR | S_IRUSR | S_IWUSR, "zqft%i", i); - class_simple_device_add(zft_class, MKDEV(QIC117_TAPE_MAJOR, i + 20), NULL, "nzqft%i", i); + class_device_create(zft_class, MKDEV(QIC117_TAPE_MAJOR, i + 20), NULL, "nzqft%i", i); devfs_mk_cdev(MKDEV(QIC117_TAPE_MAJOR, i + 20), S_IFCHR | S_IRUSR | S_IWUSR, "nzqft%i", i); - class_simple_device_add(zft_class, MKDEV(QIC117_TAPE_MAJOR, i + 32), NULL, "rawqft%i", i); + class_device_create(zft_class, MKDEV(QIC117_TAPE_MAJOR, i + 32), NULL, "rawqft%i", i); devfs_mk_cdev(MKDEV(QIC117_TAPE_MAJOR, i + 32), S_IFCHR | S_IRUSR | S_IWUSR, "rawqft%i", i); - class_simple_device_add(zft_class, MKDEV(QIC117_TAPE_MAJOR, i + 36), NULL, "nrawrawqft%i", i); + class_device_create(zft_class, MKDEV(QIC117_TAPE_MAJOR, i + 36), NULL, "nrawrawqft%i", i); devfs_mk_cdev(MKDEV(QIC117_TAPE_MAJOR, i + 36), S_IFCHR | S_IRUSR | S_IWUSR, "nrawqft%i", i); @@ -381,19 +381,19 @@ static void zft_exit(void) } for (i = 0; i < 4; i++) { devfs_remove("qft%i", i); - class_simple_device_remove(MKDEV(QIC117_TAPE_MAJOR, i)); + class_device_destroy(zft_class, MKDEV(QIC117_TAPE_MAJOR, i)); devfs_remove("nqft%i", i); - class_simple_device_remove(MKDEV(QIC117_TAPE_MAJOR, i + 4)); + class_device_destroy(zft_class, MKDEV(QIC117_TAPE_MAJOR, i + 4)); devfs_remove("zqft%i", i); - class_simple_device_remove(MKDEV(QIC117_TAPE_MAJOR, i + 16)); + class_device_destroy(zft_class, MKDEV(QIC117_TAPE_MAJOR, i + 16)); devfs_remove("nzqft%i", i); - class_simple_device_remove(MKDEV(QIC117_TAPE_MAJOR, i + 20)); + class_device_destroy(zft_class, MKDEV(QIC117_TAPE_MAJOR, i + 20)); devfs_remove("rawqft%i", i); - class_simple_device_remove(MKDEV(QIC117_TAPE_MAJOR, i + 32)); + class_device_destroy(zft_class, MKDEV(QIC117_TAPE_MAJOR, i + 32)); devfs_remove("nrawqft%i", i); - class_simple_device_remove(MKDEV(QIC117_TAPE_MAJOR, i + 36)); + class_device_destroy(zft_class, MKDEV(QIC117_TAPE_MAJOR, i + 36)); } - class_simple_destroy(zft_class); + class_destroy(zft_class); zft_uninit_mem(); /* release remaining memory, if any */ printk(KERN_INFO "zftape successfully unloaded.\n"); TRACE_EXIT; diff --git a/drivers/char/hvcs.c b/drivers/char/hvcs.c index abfbdcfd4e72..3236d2404905 100644 --- a/drivers/char/hvcs.c +++ b/drivers/char/hvcs.c @@ -1466,7 +1466,7 @@ static inline struct hvcs_struct *from_vio_dev(struct vio_dev *viod) } /* The sysfs interface for the driver and devices */ -static ssize_t hvcs_partner_vtys_show(struct device *dev, char *buf) +static ssize_t hvcs_partner_vtys_show(struct device *dev, struct device_attribute *attr, char *buf) { struct vio_dev *viod = to_vio_dev(dev); struct hvcs_struct *hvcsd = from_vio_dev(viod); @@ -1480,7 +1480,7 @@ static ssize_t hvcs_partner_vtys_show(struct device *dev, char *buf) } static DEVICE_ATTR(partner_vtys, S_IRUGO, hvcs_partner_vtys_show, NULL); -static ssize_t hvcs_partner_clcs_show(struct device *dev, char *buf) +static ssize_t hvcs_partner_clcs_show(struct device *dev, struct device_attribute *attr, char *buf) { struct vio_dev *viod = to_vio_dev(dev); struct hvcs_struct *hvcsd = from_vio_dev(viod); @@ -1494,7 +1494,7 @@ static ssize_t hvcs_partner_clcs_show(struct device *dev, char *buf) } static DEVICE_ATTR(partner_clcs, S_IRUGO, hvcs_partner_clcs_show, NULL); -static ssize_t hvcs_current_vty_store(struct device *dev, const char * buf, +static ssize_t hvcs_current_vty_store(struct device *dev, struct device_attribute *attr, const char * buf, size_t count) { /* @@ -1505,7 +1505,7 @@ static ssize_t hvcs_current_vty_store(struct device *dev, const char * buf, return -EPERM; } -static ssize_t hvcs_current_vty_show(struct device *dev, char *buf) +static ssize_t hvcs_current_vty_show(struct device *dev, struct device_attribute *attr, char *buf) { struct vio_dev *viod = to_vio_dev(dev); struct hvcs_struct *hvcsd = from_vio_dev(viod); @@ -1521,7 +1521,7 @@ static ssize_t hvcs_current_vty_show(struct device *dev, char *buf) static DEVICE_ATTR(current_vty, S_IRUGO | S_IWUSR, hvcs_current_vty_show, hvcs_current_vty_store); -static ssize_t hvcs_vterm_state_store(struct device *dev, const char *buf, +static ssize_t hvcs_vterm_state_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct vio_dev *viod = to_vio_dev(dev); @@ -1559,7 +1559,7 @@ static ssize_t hvcs_vterm_state_store(struct device *dev, const char *buf, return count; } -static ssize_t hvcs_vterm_state_show(struct device *dev, char *buf) +static ssize_t hvcs_vterm_state_show(struct device *dev, struct device_attribute *attr, char *buf) { struct vio_dev *viod = to_vio_dev(dev); struct hvcs_struct *hvcsd = from_vio_dev(viod); @@ -1574,7 +1574,7 @@ static ssize_t hvcs_vterm_state_show(struct device *dev, char *buf) static DEVICE_ATTR(vterm_state, S_IRUGO | S_IWUSR, hvcs_vterm_state_show, hvcs_vterm_state_store); -static ssize_t hvcs_index_show(struct device *dev, char *buf) +static ssize_t hvcs_index_show(struct device *dev, struct device_attribute *attr, char *buf) { struct vio_dev *viod = to_vio_dev(dev); struct hvcs_struct *hvcsd = from_vio_dev(viod); diff --git a/drivers/char/ip2main.c b/drivers/char/ip2main.c index fca9a978fb73..3b8314b4249a 100644 --- a/drivers/char/ip2main.c +++ b/drivers/char/ip2main.c @@ -302,7 +302,7 @@ static char rirqs[IP2_MAX_BOARDS]; static int Valid_Irqs[] = { 3, 4, 5, 7, 10, 11, 12, 15, 0}; /* for sysfs class support */ -static struct class_simple *ip2_class; +static struct class *ip2_class; // Some functions to keep track of what irq's we have @@ -414,9 +414,9 @@ cleanup_module(void) iiResetDelay( i2BoardPtrTable[i] ); /* free io addresses and Tibet */ release_region( ip2config.addr[i], 8 ); - class_simple_device_remove(MKDEV(IP2_IPL_MAJOR, 4 * i)); + class_device_destroy(ip2_class, MKDEV(IP2_IPL_MAJOR, 4 * i)); devfs_remove("ip2/ipl%d", i); - class_simple_device_remove(MKDEV(IP2_IPL_MAJOR, 4 * i + 1)); + class_device_destroy(ip2_class, MKDEV(IP2_IPL_MAJOR, 4 * i + 1)); devfs_remove("ip2/stat%d", i); } /* Disable and remove interrupt handler. */ @@ -425,7 +425,7 @@ cleanup_module(void) clear_requested_irq( ip2config.irq[i]); } } - class_simple_destroy(ip2_class); + class_destroy(ip2_class); devfs_remove("ip2"); if ( ( err = tty_unregister_driver ( ip2_tty_driver ) ) ) { printk(KERN_ERR "IP2: failed to unregister tty driver (%d)\n", err); @@ -700,7 +700,7 @@ ip2_loadmain(int *iop, int *irqp, unsigned char *firmware, int firmsize) printk(KERN_ERR "IP2: failed to register IPL device (%d)\n", err ); } else { /* create the sysfs class */ - ip2_class = class_simple_create(THIS_MODULE, "ip2"); + ip2_class = class_create(THIS_MODULE, "ip2"); if (IS_ERR(ip2_class)) { err = PTR_ERR(ip2_class); goto out_chrdev; @@ -722,25 +722,25 @@ ip2_loadmain(int *iop, int *irqp, unsigned char *firmware, int firmsize) } if ( NULL != ( pB = i2BoardPtrTable[i] ) ) { - class_simple_device_add(ip2_class, MKDEV(IP2_IPL_MAJOR, + class_device_create(ip2_class, MKDEV(IP2_IPL_MAJOR, 4 * i), NULL, "ipl%d", i); err = devfs_mk_cdev(MKDEV(IP2_IPL_MAJOR, 4 * i), S_IRUSR | S_IWUSR | S_IRGRP | S_IFCHR, "ip2/ipl%d", i); if (err) { - class_simple_device_remove(MKDEV(IP2_IPL_MAJOR, - 4 * i)); + class_device_destroy(ip2_class, + MKDEV(IP2_IPL_MAJOR, 4 * i)); goto out_class; } - class_simple_device_add(ip2_class, MKDEV(IP2_IPL_MAJOR, + class_device_create(ip2_class, MKDEV(IP2_IPL_MAJOR, 4 * i + 1), NULL, "stat%d", i); err = devfs_mk_cdev(MKDEV(IP2_IPL_MAJOR, 4 * i + 1), S_IRUSR | S_IWUSR | S_IRGRP | S_IFCHR, "ip2/stat%d", i); if (err) { - class_simple_device_remove(MKDEV(IP2_IPL_MAJOR, - 4 * i + 1)); + class_device_destroy(ip2_class, + MKDEV(IP2_IPL_MAJOR, 4 * i + 1)); goto out_class; } @@ -798,7 +798,7 @@ retry: goto out; out_class: - class_simple_destroy(ip2_class); + class_destroy(ip2_class); out_chrdev: unregister_chrdev(IP2_IPL_MAJOR, "ip2"); out: diff --git a/drivers/char/ipmi/ipmi_devintf.c b/drivers/char/ipmi/ipmi_devintf.c index 6dc765dc5413..88d1ad656e99 100644 --- a/drivers/char/ipmi/ipmi_devintf.c +++ b/drivers/char/ipmi/ipmi_devintf.c @@ -520,7 +520,7 @@ MODULE_PARM_DESC(ipmi_major, "Sets the major number of the IPMI device. By" " interface. Other values will set the major device number" " to that value."); -static struct class_simple *ipmi_class; +static struct class *ipmi_class; static void ipmi_new_smi(int if_num) { @@ -529,12 +529,12 @@ static void ipmi_new_smi(int if_num) devfs_mk_cdev(dev, S_IFCHR | S_IRUSR | S_IWUSR, "ipmidev/%d", if_num); - class_simple_device_add(ipmi_class, dev, NULL, "ipmi%d", if_num); + class_device_create(ipmi_class, dev, NULL, "ipmi%d", if_num); } static void ipmi_smi_gone(int if_num) { - class_simple_device_remove(MKDEV(ipmi_major, if_num)); + class_device_destroy(ipmi_class, MKDEV(ipmi_major, if_num)); devfs_remove("ipmidev/%d", if_num); } @@ -555,7 +555,7 @@ static __init int init_ipmi_devintf(void) printk(KERN_INFO "ipmi device interface version " IPMI_DEVINTF_VERSION "\n"); - ipmi_class = class_simple_create(THIS_MODULE, "ipmi"); + ipmi_class = class_create(THIS_MODULE, "ipmi"); if (IS_ERR(ipmi_class)) { printk(KERN_ERR "ipmi: can't register device class\n"); return PTR_ERR(ipmi_class); @@ -563,7 +563,7 @@ static __init int init_ipmi_devintf(void) rv = register_chrdev(ipmi_major, DEVICE_NAME, &ipmi_fops); if (rv < 0) { - class_simple_destroy(ipmi_class); + class_destroy(ipmi_class); printk(KERN_ERR "ipmi: can't get major %d\n", ipmi_major); return rv; } @@ -577,7 +577,7 @@ static __init int init_ipmi_devintf(void) rv = ipmi_smi_watcher_register(&smi_watcher); if (rv) { unregister_chrdev(ipmi_major, DEVICE_NAME); - class_simple_destroy(ipmi_class); + class_destroy(ipmi_class); printk(KERN_WARNING "ipmi: can't register smi watcher\n"); return rv; } @@ -588,7 +588,7 @@ module_init(init_ipmi_devintf); static __exit void cleanup_ipmi(void) { - class_simple_destroy(ipmi_class); + class_destroy(ipmi_class); ipmi_smi_watcher_unregister(&smi_watcher); devfs_remove(DEVICE_NAME); unregister_chrdev(ipmi_major, DEVICE_NAME); diff --git a/drivers/char/ipmi/ipmi_msghandler.c b/drivers/char/ipmi/ipmi_msghandler.c index d7fb452af7f9..0c81652eaba6 100644 --- a/drivers/char/ipmi/ipmi_msghandler.c +++ b/drivers/char/ipmi/ipmi_msghandler.c @@ -641,7 +641,7 @@ int ipmi_create_user(unsigned int if_num, return -ENOMEM; down_read(&interfaces_sem); - if ((if_num > MAX_IPMI_INTERFACES) || ipmi_interfaces[if_num] == NULL) + if ((if_num >= MAX_IPMI_INTERFACES) || ipmi_interfaces[if_num] == NULL) { rv = -EINVAL; goto out_unlock; diff --git a/drivers/char/istallion.c b/drivers/char/istallion.c index 21aed0e8779d..c02a21dbad5d 100644 --- a/drivers/char/istallion.c +++ b/drivers/char/istallion.c @@ -792,7 +792,7 @@ static int stli_timeron; /*****************************************************************************/ -static struct class_simple *istallion_class; +static struct class *istallion_class; #ifdef MODULE @@ -854,10 +854,10 @@ static void __exit istallion_module_exit(void) put_tty_driver(stli_serial); for (i = 0; i < 4; i++) { devfs_remove("staliomem/%d", i); - class_simple_device_remove(MKDEV(STL_SIOMEMMAJOR, i)); + class_device_destroy(istallion_class, MKDEV(STL_SIOMEMMAJOR, i)); } devfs_remove("staliomem"); - class_simple_destroy(istallion_class); + class_destroy(istallion_class); if ((i = unregister_chrdev(STL_SIOMEMMAJOR, "staliomem"))) printk("STALLION: failed to un-register serial memory device, " "errno=%d\n", -i); @@ -5242,12 +5242,12 @@ int __init stli_init(void) "device\n"); devfs_mk_dir("staliomem"); - istallion_class = class_simple_create(THIS_MODULE, "staliomem"); + istallion_class = class_create(THIS_MODULE, "staliomem"); for (i = 0; i < 4; i++) { devfs_mk_cdev(MKDEV(STL_SIOMEMMAJOR, i), S_IFCHR | S_IRUSR | S_IWUSR, "staliomem/%d", i); - class_simple_device_add(istallion_class, MKDEV(STL_SIOMEMMAJOR, i), + class_device_create(istallion_class, MKDEV(STL_SIOMEMMAJOR, i), NULL, "staliomem%d", i); } diff --git a/drivers/char/lp.c b/drivers/char/lp.c index 4dee945031d4..59eebe5a035f 100644 --- a/drivers/char/lp.c +++ b/drivers/char/lp.c @@ -146,7 +146,7 @@ static struct lp_struct lp_table[LP_NO]; static unsigned int lp_count = 0; -static struct class_simple *lp_class; +static struct class *lp_class; #ifdef CONFIG_LP_CONSOLE static struct parport *console_registered; // initially NULL @@ -804,7 +804,7 @@ static int lp_register(int nr, struct parport *port) if (reset) lp_reset(nr); - class_simple_device_add(lp_class, MKDEV(LP_MAJOR, nr), NULL, + class_device_create(lp_class, MKDEV(LP_MAJOR, nr), NULL, "lp%d", nr); devfs_mk_cdev(MKDEV(LP_MAJOR, nr), S_IFCHR | S_IRUGO | S_IWUGO, "printers/%d", nr); @@ -907,7 +907,7 @@ static int __init lp_init (void) } devfs_mk_dir("printers"); - lp_class = class_simple_create(THIS_MODULE, "printer"); + lp_class = class_create(THIS_MODULE, "printer"); if (IS_ERR(lp_class)) { err = PTR_ERR(lp_class); goto out_devfs; @@ -930,7 +930,7 @@ static int __init lp_init (void) return 0; out_class: - class_simple_destroy(lp_class); + class_destroy(lp_class); out_devfs: devfs_remove("printers"); unregister_chrdev(LP_MAJOR, "lp"); @@ -981,10 +981,10 @@ static void lp_cleanup_module (void) continue; parport_unregister_device(lp_table[offset].dev); devfs_remove("printers/%d", offset); - class_simple_device_remove(MKDEV(LP_MAJOR, offset)); + class_device_destroy(lp_class, MKDEV(LP_MAJOR, offset)); } devfs_remove("printers"); - class_simple_destroy(lp_class); + class_destroy(lp_class); } __setup("lp=", lp_setup); diff --git a/drivers/char/mbcs.c b/drivers/char/mbcs.c index ac9cfa9701ea..115dbb35334b 100644 --- a/drivers/char/mbcs.c +++ b/drivers/char/mbcs.c @@ -699,7 +699,7 @@ static inline int mbcs_hw_init(struct mbcs_soft *soft) return 0; } -static ssize_t show_algo(struct device *dev, char *buf) +static ssize_t show_algo(struct device *dev, struct device_attribute *attr, char *buf) { struct cx_dev *cx_dev = to_cx_dev(dev); struct mbcs_soft *soft = cx_dev->soft; @@ -715,7 +715,7 @@ static ssize_t show_algo(struct device *dev, char *buf) (debug0 >> 32), (debug0 & 0xffffffff)); } -static ssize_t store_algo(struct device *dev, const char *buf, size_t count) +static ssize_t store_algo(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { int n; struct cx_dev *cx_dev = to_cx_dev(dev); diff --git a/drivers/char/mem.c b/drivers/char/mem.c index 947cb3cef816..e3085b22a365 100644 --- a/drivers/char/mem.c +++ b/drivers/char/mem.c @@ -484,7 +484,7 @@ static ssize_t write_kmem(struct file * file, const char __user * buf, return virtr + wrote; } -#if defined(CONFIG_ISA) || !defined(__mc68000__) +#if (defined(CONFIG_ISA) || !defined(__mc68000__)) && (!defined(CONFIG_PPC_ISERIES) || defined(CONFIG_PCI)) static ssize_t read_port(struct file * file, char __user * buf, size_t count, loff_t *ppos) { @@ -744,7 +744,7 @@ static struct file_operations null_fops = { .write = write_null, }; -#if defined(CONFIG_ISA) || !defined(__mc68000__) +#if (defined(CONFIG_ISA) || !defined(__mc68000__)) && (!defined(CONFIG_PPC_ISERIES) || defined(CONFIG_PCI)) static struct file_operations port_fops = { .llseek = memory_lseek, .read = read_port, @@ -804,7 +804,7 @@ static int memory_open(struct inode * inode, struct file * filp) case 3: filp->f_op = &null_fops; break; -#if defined(CONFIG_ISA) || !defined(__mc68000__) +#if (defined(CONFIG_ISA) || !defined(__mc68000__)) && (!defined(CONFIG_PPC_ISERIES) || defined(CONFIG_PCI)) case 4: filp->f_op = &port_fops; break; @@ -846,7 +846,7 @@ static const struct { {1, "mem", S_IRUSR | S_IWUSR | S_IRGRP, &mem_fops}, {2, "kmem", S_IRUSR | S_IWUSR | S_IRGRP, &kmem_fops}, {3, "null", S_IRUGO | S_IWUGO, &null_fops}, -#if defined(CONFIG_ISA) || !defined(__mc68000__) +#if (defined(CONFIG_ISA) || !defined(__mc68000__)) && (!defined(CONFIG_PPC_ISERIES) || defined(CONFIG_PCI)) {4, "port", S_IRUSR | S_IWUSR | S_IRGRP, &port_fops}, #endif {5, "zero", S_IRUGO | S_IWUGO, &zero_fops}, @@ -856,7 +856,7 @@ static const struct { {11,"kmsg", S_IRUGO | S_IWUSR, &kmsg_fops}, }; -static struct class_simple *mem_class; +static struct class *mem_class; static int __init chr_dev_init(void) { @@ -865,10 +865,9 @@ static int __init chr_dev_init(void) if (register_chrdev(MEM_MAJOR,"mem",&memory_fops)) printk("unable to get major %d for memory devs\n", MEM_MAJOR); - mem_class = class_simple_create(THIS_MODULE, "mem"); + mem_class = class_create(THIS_MODULE, "mem"); for (i = 0; i < ARRAY_SIZE(devlist); i++) { - class_simple_device_add(mem_class, - MKDEV(MEM_MAJOR, devlist[i].minor), + class_device_create(mem_class, MKDEV(MEM_MAJOR, devlist[i].minor), NULL, devlist[i].name); devfs_mk_cdev(MKDEV(MEM_MAJOR, devlist[i].minor), S_IFCHR | devlist[i].mode, devlist[i].name); diff --git a/drivers/char/misc.c b/drivers/char/misc.c index 0937544762da..3115d318b997 100644 --- a/drivers/char/misc.c +++ b/drivers/char/misc.c @@ -177,10 +177,10 @@ fail: /* * TODO for 2.7: - * - add a struct class_device to struct miscdevice and make all usages of + * - add a struct kref to struct miscdevice and make all usages of * them dynamic. */ -static struct class_simple *misc_class; +static struct class *misc_class; static struct file_operations misc_fops = { .owner = THIS_MODULE, @@ -238,8 +238,8 @@ int misc_register(struct miscdevice * misc) } dev = MKDEV(MISC_MAJOR, misc->minor); - misc->class = class_simple_device_add(misc_class, dev, - misc->dev, misc->name); + misc->class = class_device_create(misc_class, dev, misc->dev, + "%s", misc->name); if (IS_ERR(misc->class)) { err = PTR_ERR(misc->class); goto out; @@ -248,7 +248,7 @@ int misc_register(struct miscdevice * misc) err = devfs_mk_cdev(dev, S_IFCHR|S_IRUSR|S_IWUSR|S_IRGRP, misc->devfs_name); if (err) { - class_simple_device_remove(dev); + class_device_destroy(misc_class, dev); goto out; } @@ -281,7 +281,7 @@ int misc_deregister(struct miscdevice * misc) down(&misc_sem); list_del(&misc->list); - class_simple_device_remove(MKDEV(MISC_MAJOR, misc->minor)); + class_device_destroy(misc_class, MKDEV(MISC_MAJOR, misc->minor)); devfs_remove(misc->devfs_name); if (i < DYNAMIC_MINORS && i>0) { misc_minors[i>>3] &= ~(1 << (misc->minor & 7)); @@ -302,7 +302,7 @@ static int __init misc_init(void) if (ent) ent->proc_fops = &misc_proc_fops; #endif - misc_class = class_simple_create(THIS_MODULE, "misc"); + misc_class = class_create(THIS_MODULE, "misc"); if (IS_ERR(misc_class)) return PTR_ERR(misc_class); #ifdef CONFIG_MVME16x @@ -323,7 +323,7 @@ static int __init misc_init(void) if (register_chrdev(MISC_MAJOR,"misc",&misc_fops)) { printk("unable to get major %d for misc devices\n", MISC_MAJOR); - class_simple_destroy(misc_class); + class_destroy(misc_class); return -EIO; } return 0; diff --git a/drivers/char/mwave/mwavedd.c b/drivers/char/mwave/mwavedd.c index d37625d47746..d568991ac6b3 100644 --- a/drivers/char/mwave/mwavedd.c +++ b/drivers/char/mwave/mwavedd.c @@ -472,7 +472,7 @@ struct device mwave_device; /* Prevent code redundancy, create a macro for mwave_show_* functions. */ #define mwave_show_function(attr_name, format_string, field) \ -static ssize_t mwave_show_##attr_name(struct device *dev, char *buf) \ +static ssize_t mwave_show_##attr_name(struct device *dev, struct device_attribute *attr, char *buf) \ { \ DSP_3780I_CONFIG_SETTINGS *pSettings = \ &mwave_s_mdd.rBDData.rDspSettings; \ diff --git a/drivers/char/ppdev.c b/drivers/char/ppdev.c index 5eda075c62bd..0e22880432bc 100644 --- a/drivers/char/ppdev.c +++ b/drivers/char/ppdev.c @@ -737,7 +737,7 @@ static unsigned int pp_poll (struct file * file, poll_table * wait) return mask; } -static struct class_simple *ppdev_class; +static struct class *ppdev_class; static struct file_operations pp_fops = { .owner = THIS_MODULE, @@ -752,13 +752,13 @@ static struct file_operations pp_fops = { static void pp_attach(struct parport *port) { - class_simple_device_add(ppdev_class, MKDEV(PP_MAJOR, port->number), + class_device_create(ppdev_class, MKDEV(PP_MAJOR, port->number), NULL, "parport%d", port->number); } static void pp_detach(struct parport *port) { - class_simple_device_remove(MKDEV(PP_MAJOR, port->number)); + class_device_destroy(ppdev_class, MKDEV(PP_MAJOR, port->number)); } static struct parport_driver pp_driver = { @@ -776,7 +776,7 @@ static int __init ppdev_init (void) PP_MAJOR); return -EIO; } - ppdev_class = class_simple_create(THIS_MODULE, CHRDEV); + ppdev_class = class_create(THIS_MODULE, CHRDEV); if (IS_ERR(ppdev_class)) { err = PTR_ERR(ppdev_class); goto out_chrdev; @@ -798,7 +798,7 @@ out_class: for (i = 0; i < PARPORT_MAX; i++) devfs_remove("parports/%d", i); devfs_remove("parports"); - class_simple_destroy(ppdev_class); + class_destroy(ppdev_class); out_chrdev: unregister_chrdev(PP_MAJOR, CHRDEV); out: @@ -813,7 +813,7 @@ static void __exit ppdev_cleanup (void) devfs_remove("parports/%d", i); parport_unregister_driver(&pp_driver); devfs_remove("parports"); - class_simple_destroy(ppdev_class); + class_destroy(ppdev_class); unregister_chrdev (PP_MAJOR, CHRDEV); } diff --git a/drivers/char/raw.c b/drivers/char/raw.c index ca5f42bcaad9..f13e5de02207 100644 --- a/drivers/char/raw.c +++ b/drivers/char/raw.c @@ -27,7 +27,7 @@ struct raw_device_data { int inuse; }; -static struct class_simple *raw_class; +static struct class *raw_class; static struct raw_device_data raw_devices[MAX_RAW_MINORS]; static DECLARE_MUTEX(raw_mutex); static struct file_operations raw_ctl_fops; /* forward declaration */ @@ -127,8 +127,8 @@ raw_ioctl(struct inode *inode, struct file *filp, static void bind_device(struct raw_config_request *rq) { - class_simple_device_remove(MKDEV(RAW_MAJOR, rq->raw_minor)); - class_simple_device_add(raw_class, MKDEV(RAW_MAJOR, rq->raw_minor), + class_device_destroy(raw_class, MKDEV(RAW_MAJOR, rq->raw_minor)); + class_device_create(raw_class, MKDEV(RAW_MAJOR, rq->raw_minor), NULL, "raw%d", rq->raw_minor); } @@ -200,8 +200,8 @@ static int raw_ctl_ioctl(struct inode *inode, struct file *filp, if (rq.block_major == 0 && rq.block_minor == 0) { /* unbind */ rawdev->binding = NULL; - class_simple_device_remove(MKDEV(RAW_MAJOR, - rq.raw_minor)); + class_device_destroy(raw_class, + MKDEV(RAW_MAJOR, rq.raw_minor)); } else { rawdev->binding = bdget(dev); if (rawdev->binding == NULL) @@ -300,14 +300,14 @@ static int __init raw_init(void) goto error; } - raw_class = class_simple_create(THIS_MODULE, "raw"); + raw_class = class_create(THIS_MODULE, "raw"); if (IS_ERR(raw_class)) { printk(KERN_ERR "Error creating raw class.\n"); cdev_del(&raw_cdev); unregister_chrdev_region(dev, MAX_RAW_MINORS); goto error; } - class_simple_device_add(raw_class, MKDEV(RAW_MAJOR, 0), NULL, "rawctl"); + class_device_create(raw_class, MKDEV(RAW_MAJOR, 0), NULL, "rawctl"); devfs_mk_cdev(MKDEV(RAW_MAJOR, 0), S_IFCHR | S_IRUGO | S_IWUGO, @@ -331,8 +331,8 @@ static void __exit raw_exit(void) devfs_remove("raw/raw%d", i); devfs_remove("raw/rawctl"); devfs_remove("raw"); - class_simple_device_remove(MKDEV(RAW_MAJOR, 0)); - class_simple_destroy(raw_class); + class_device_destroy(raw_class, MKDEV(RAW_MAJOR, 0)); + class_destroy(raw_class); cdev_del(&raw_cdev); unregister_chrdev_region(MKDEV(RAW_MAJOR, 0), MAX_RAW_MINORS); } diff --git a/drivers/char/snsc.c b/drivers/char/snsc.c index e3c0b52d943f..261a41bf6d02 100644 --- a/drivers/char/snsc.c +++ b/drivers/char/snsc.c @@ -357,6 +357,8 @@ static struct file_operations scdrv_fops = { .release = scdrv_release, }; +static struct class *snsc_class; + /* * scdrv_init * @@ -372,7 +374,6 @@ scdrv_init(void) char *devnamep; struct sysctl_data_s *scd; void *salbuf; - struct class_simple *snsc_class; dev_t first_dev, dev; nasid_t event_nasid = ia64_sn_get_console_nasid(); @@ -382,7 +383,7 @@ scdrv_init(void) __FUNCTION__); return -ENODEV; } - snsc_class = class_simple_create(THIS_MODULE, SYSCTL_BASENAME); + snsc_class = class_create(THIS_MODULE, SYSCTL_BASENAME); for (cnode = 0; cnode < numionodes; cnode++) { geoid = cnodeid_get_geoid(cnode); @@ -436,7 +437,7 @@ scdrv_init(void) continue; } - class_simple_device_add(snsc_class, dev, NULL, + class_device_create(snsc_class, dev, NULL, "%s", devname); ia64_sn_irtr_intr_enable(scd->scd_nasid, diff --git a/drivers/char/stallion.c b/drivers/char/stallion.c index b8899f560b5e..951545a6ef2d 100644 --- a/drivers/char/stallion.c +++ b/drivers/char/stallion.c @@ -719,7 +719,7 @@ static struct file_operations stl_fsiomem = { /*****************************************************************************/ -static struct class_simple *stallion_class; +static struct class *stallion_class; /* * Loadable module initialization stuff. @@ -777,13 +777,13 @@ static void __exit stallion_module_exit(void) } for (i = 0; i < 4; i++) { devfs_remove("staliomem/%d", i); - class_simple_device_remove(MKDEV(STL_SIOMEMMAJOR, i)); + class_device_destroy(stallion_class, MKDEV(STL_SIOMEMMAJOR, i)); } devfs_remove("staliomem"); if ((i = unregister_chrdev(STL_SIOMEMMAJOR, "staliomem"))) printk("STALLION: failed to un-register serial memory device, " "errno=%d\n", -i); - class_simple_destroy(stallion_class); + class_destroy(stallion_class); if (stl_tmpwritebuf != (char *) NULL) kfree(stl_tmpwritebuf); @@ -3090,12 +3090,12 @@ static int __init stl_init(void) printk("STALLION: failed to register serial board device\n"); devfs_mk_dir("staliomem"); - stallion_class = class_simple_create(THIS_MODULE, "staliomem"); + stallion_class = class_create(THIS_MODULE, "staliomem"); for (i = 0; i < 4; i++) { devfs_mk_cdev(MKDEV(STL_SIOMEMMAJOR, i), S_IFCHR|S_IRUSR|S_IWUSR, "staliomem/%d", i); - class_simple_device_add(stallion_class, MKDEV(STL_SIOMEMMAJOR, i), NULL, "staliomem%d", i); + class_device_create(stallion_class, MKDEV(STL_SIOMEMMAJOR, i), NULL, "staliomem%d", i); } stl_serial->owner = THIS_MODULE; diff --git a/drivers/char/tipar.c b/drivers/char/tipar.c index 0c5ba9dc9063..659335d80ee7 100644 --- a/drivers/char/tipar.c +++ b/drivers/char/tipar.c @@ -90,7 +90,7 @@ static int timeout = TIMAXTIME; /* timeout in tenth of seconds */ static unsigned int tp_count; /* tipar count */ static unsigned long opened; /* opened devices */ -static struct class_simple *tipar_class; +static struct class *tipar_class; /* --- macros for parport access -------------------------------------- */ @@ -436,7 +436,7 @@ tipar_register(int nr, struct parport *port) goto out; } - class_simple_device_add(tipar_class, MKDEV(TIPAR_MAJOR, + class_device_create(tipar_class, MKDEV(TIPAR_MAJOR, TIPAR_MINOR + nr), NULL, "par%d", nr); /* Use devfs, tree: /dev/ticables/par/[0..2] */ err = devfs_mk_cdev(MKDEV(TIPAR_MAJOR, TIPAR_MINOR + nr), @@ -458,8 +458,8 @@ tipar_register(int nr, struct parport *port) goto out; out_class: - class_simple_device_remove(MKDEV(TIPAR_MAJOR, TIPAR_MINOR + nr)); - class_simple_destroy(tipar_class); + class_device_destroy(tipar_class, MKDEV(TIPAR_MAJOR, TIPAR_MINOR + nr)); + class_destroy(tipar_class); out: return err; } @@ -505,7 +505,7 @@ tipar_init_module(void) /* Use devfs with tree: /dev/ticables/par/[0..2] */ devfs_mk_dir("ticables/par"); - tipar_class = class_simple_create(THIS_MODULE, "ticables"); + tipar_class = class_create(THIS_MODULE, "ticables"); if (IS_ERR(tipar_class)) { err = PTR_ERR(tipar_class); goto out_chrdev; @@ -539,10 +539,10 @@ tipar_cleanup_module(void) if (table[i].dev == NULL) continue; parport_unregister_device(table[i].dev); - class_simple_device_remove(MKDEV(TIPAR_MAJOR, i)); + class_device_destroy(tipar_class, MKDEV(TIPAR_MAJOR, i)); devfs_remove("ticables/par/%d", i); } - class_simple_destroy(tipar_class); + class_destroy(tipar_class); devfs_remove("ticables/par"); pr_info("tipar: module unloaded\n"); diff --git a/drivers/char/tpm/tpm.c b/drivers/char/tpm/tpm.c index 87235330fdbe..8ce508b29865 100644 --- a/drivers/char/tpm/tpm.c +++ b/drivers/char/tpm/tpm.c @@ -212,7 +212,7 @@ static u8 pcrread[] = { 0, 0, 0, 0 /* PCR index */ }; -static ssize_t show_pcrs(struct device *dev, char *buf) +static ssize_t show_pcrs(struct device *dev, struct device_attribute *attr, char *buf) { u8 data[READ_PCR_RESULT_SIZE]; ssize_t len; @@ -255,7 +255,7 @@ static u8 readpubek[] = { 0, 0, 0, 124, /* TPM_ORD_ReadPubek */ }; -static ssize_t show_pubek(struct device *dev, char *buf) +static ssize_t show_pubek(struct device *dev, struct device_attribute *attr, char *buf) { u8 data[READ_PUBEK_RESULT_SIZE]; ssize_t len; @@ -330,7 +330,7 @@ static u8 cap_manufacturer[] = { 0, 0, 1, 3 }; -static ssize_t show_caps(struct device *dev, char *buf) +static ssize_t show_caps(struct device *dev, struct device_attribute *attr, char *buf) { u8 data[READ_PUBEK_RESULT_SIZE]; ssize_t len; diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c index 26e5e19ed854..31831030f73f 100644 --- a/drivers/char/tty_io.c +++ b/drivers/char/tty_io.c @@ -2654,7 +2654,7 @@ static void tty_default_put_char(struct tty_struct *tty, unsigned char ch) tty->driver->write(tty, &ch, 1); } -static struct class_simple *tty_class; +static struct class *tty_class; /** * tty_register_device - register a tty device @@ -2687,7 +2687,7 @@ void tty_register_device(struct tty_driver *driver, unsigned index, pty_line_name(driver, index, name); else tty_line_name(driver, index, name); - class_simple_device_add(tty_class, dev, device, name); + class_device_create(tty_class, dev, device, name); } /** @@ -2701,7 +2701,7 @@ void tty_register_device(struct tty_driver *driver, unsigned index, void tty_unregister_device(struct tty_driver *driver, unsigned index) { devfs_remove("%s%d", driver->devfs_name, index + driver->name_base); - class_simple_device_remove(MKDEV(driver->major, driver->minor_start) + index); + class_device_destroy(tty_class, MKDEV(driver->major, driver->minor_start) + index); } EXPORT_SYMBOL(tty_register_device); @@ -2918,7 +2918,7 @@ extern int vty_init(void); static int __init tty_class_init(void) { - tty_class = class_simple_create(THIS_MODULE, "tty"); + tty_class = class_create(THIS_MODULE, "tty"); if (IS_ERR(tty_class)) return PTR_ERR(tty_class); return 0; @@ -2947,14 +2947,14 @@ static int __init tty_init(void) register_chrdev_region(MKDEV(TTYAUX_MAJOR, 0), 1, "/dev/tty") < 0) panic("Couldn't register /dev/tty driver\n"); devfs_mk_cdev(MKDEV(TTYAUX_MAJOR, 0), S_IFCHR|S_IRUGO|S_IWUGO, "tty"); - class_simple_device_add(tty_class, MKDEV(TTYAUX_MAJOR, 0), NULL, "tty"); + class_device_create(tty_class, MKDEV(TTYAUX_MAJOR, 0), NULL, "tty"); cdev_init(&console_cdev, &console_fops); if (cdev_add(&console_cdev, MKDEV(TTYAUX_MAJOR, 1), 1) || register_chrdev_region(MKDEV(TTYAUX_MAJOR, 1), 1, "/dev/console") < 0) panic("Couldn't register /dev/console driver\n"); devfs_mk_cdev(MKDEV(TTYAUX_MAJOR, 1), S_IFCHR|S_IRUSR|S_IWUSR, "console"); - class_simple_device_add(tty_class, MKDEV(TTYAUX_MAJOR, 1), NULL, "console"); + class_device_create(tty_class, MKDEV(TTYAUX_MAJOR, 1), NULL, "console"); #ifdef CONFIG_UNIX98_PTYS cdev_init(&ptmx_cdev, &ptmx_fops); @@ -2962,7 +2962,7 @@ static int __init tty_init(void) register_chrdev_region(MKDEV(TTYAUX_MAJOR, 2), 1, "/dev/ptmx") < 0) panic("Couldn't register /dev/ptmx driver\n"); devfs_mk_cdev(MKDEV(TTYAUX_MAJOR, 2), S_IFCHR|S_IRUGO|S_IWUGO, "ptmx"); - class_simple_device_add(tty_class, MKDEV(TTYAUX_MAJOR, 2), NULL, "ptmx"); + class_device_create(tty_class, MKDEV(TTYAUX_MAJOR, 2), NULL, "ptmx"); #endif #ifdef CONFIG_VT @@ -2971,7 +2971,7 @@ static int __init tty_init(void) register_chrdev_region(MKDEV(TTY_MAJOR, 0), 1, "/dev/vc/0") < 0) panic("Couldn't register /dev/tty0 driver\n"); devfs_mk_cdev(MKDEV(TTY_MAJOR, 0), S_IFCHR|S_IRUSR|S_IWUSR, "vc/0"); - class_simple_device_add(tty_class, MKDEV(TTY_MAJOR, 0), NULL, "tty0"); + class_device_create(tty_class, MKDEV(TTY_MAJOR, 0), NULL, "tty0"); vty_init(); #endif diff --git a/drivers/char/vc_screen.c b/drivers/char/vc_screen.c index 7abe405b8657..79c2928a8817 100644 --- a/drivers/char/vc_screen.c +++ b/drivers/char/vc_screen.c @@ -474,7 +474,7 @@ static struct file_operations vcs_fops = { .open = vcs_open, }; -static struct class_simple *vc_class; +static struct class *vc_class; void vcs_make_devfs(struct tty_struct *tty) { @@ -484,26 +484,26 @@ void vcs_make_devfs(struct tty_struct *tty) devfs_mk_cdev(MKDEV(VCS_MAJOR, tty->index + 129), S_IFCHR|S_IRUSR|S_IWUSR, "vcc/a%u", tty->index + 1); - class_simple_device_add(vc_class, MKDEV(VCS_MAJOR, tty->index + 1), NULL, "vcs%u", tty->index + 1); - class_simple_device_add(vc_class, MKDEV(VCS_MAJOR, tty->index + 129), NULL, "vcsa%u", tty->index + 1); + class_device_create(vc_class, MKDEV(VCS_MAJOR, tty->index + 1), NULL, "vcs%u", tty->index + 1); + class_device_create(vc_class, MKDEV(VCS_MAJOR, tty->index + 129), NULL, "vcsa%u", tty->index + 1); } void vcs_remove_devfs(struct tty_struct *tty) { devfs_remove("vcc/%u", tty->index + 1); devfs_remove("vcc/a%u", tty->index + 1); - class_simple_device_remove(MKDEV(VCS_MAJOR, tty->index + 1)); - class_simple_device_remove(MKDEV(VCS_MAJOR, tty->index + 129)); + class_device_destroy(vc_class, MKDEV(VCS_MAJOR, tty->index + 1)); + class_device_destroy(vc_class, MKDEV(VCS_MAJOR, tty->index + 129)); } int __init vcs_init(void) { if (register_chrdev(VCS_MAJOR, "vcs", &vcs_fops)) panic("unable to get major %d for vcs device", VCS_MAJOR); - vc_class = class_simple_create(THIS_MODULE, "vc"); + vc_class = class_create(THIS_MODULE, "vc"); devfs_mk_cdev(MKDEV(VCS_MAJOR, 0), S_IFCHR|S_IRUSR|S_IWUSR, "vcc/0"); devfs_mk_cdev(MKDEV(VCS_MAJOR, 128), S_IFCHR|S_IRUSR|S_IWUSR, "vcc/a0"); - class_simple_device_add(vc_class, MKDEV(VCS_MAJOR, 0), NULL, "vcs"); - class_simple_device_add(vc_class, MKDEV(VCS_MAJOR, 128), NULL, "vcsa"); + class_device_create(vc_class, MKDEV(VCS_MAJOR, 0), NULL, "vcs"); + class_device_create(vc_class, MKDEV(VCS_MAJOR, 128), NULL, "vcsa"); return 0; } diff --git a/drivers/char/viotape.c b/drivers/char/viotape.c index aea3cbf5219d..4764b4f9555d 100644 --- a/drivers/char/viotape.c +++ b/drivers/char/viotape.c @@ -237,7 +237,7 @@ static dma_addr_t viotape_unitinfo_token; static struct mtget viomtget[VIOTAPE_MAX_TAPE]; -static struct class_simple *tape_class; +static struct class *tape_class; static struct device *tape_device[VIOTAPE_MAX_TAPE]; @@ -956,9 +956,9 @@ static int viotape_probe(struct vio_dev *vdev, const struct vio_device_id *id) state[i].cur_part = 0; for (j = 0; j < MAX_PARTITIONS; ++j) state[i].part_stat_rwi[j] = VIOT_IDLE; - class_simple_device_add(tape_class, MKDEV(VIOTAPE_MAJOR, i), NULL, + class_device_create(tape_class, MKDEV(VIOTAPE_MAJOR, i), NULL, "iseries!vt%d", i); - class_simple_device_add(tape_class, MKDEV(VIOTAPE_MAJOR, i | 0x80), + class_device_create(tape_class, MKDEV(VIOTAPE_MAJOR, i | 0x80), NULL, "iseries!nvt%d", i); devfs_mk_cdev(MKDEV(VIOTAPE_MAJOR, i), S_IFCHR | S_IRUSR | S_IWUSR, "iseries/vt%d", i); @@ -980,8 +980,8 @@ static int viotape_remove(struct vio_dev *vdev) devfs_remove("iseries/nvt%d", i); devfs_remove("iseries/vt%d", i); devfs_unregister_tape(state[i].dev_handle); - class_simple_device_remove(MKDEV(VIOTAPE_MAJOR, i | 0x80)); - class_simple_device_remove(MKDEV(VIOTAPE_MAJOR, i)); + class_device_destroy(tape_class, MKDEV(VIOTAPE_MAJOR, i | 0x80)); + class_device_destroy(tape_class, MKDEV(VIOTAPE_MAJOR, i)); return 0; } @@ -1045,7 +1045,7 @@ int __init viotap_init(void) goto clear_handler; } - tape_class = class_simple_create(THIS_MODULE, "tape"); + tape_class = class_create(THIS_MODULE, "tape"); if (IS_ERR(tape_class)) { printk(VIOTAPE_KERN_WARN "Unable to allocat class\n"); ret = PTR_ERR(tape_class); @@ -1070,7 +1070,7 @@ int __init viotap_init(void) return 0; unreg_class: - class_simple_destroy(tape_class); + class_destroy(tape_class); unreg_chrdev: unregister_chrdev(VIOTAPE_MAJOR, "viotape"); clear_handler: @@ -1110,7 +1110,7 @@ static void __exit viotap_exit(void) remove_proc_entry("iSeries/viotape", NULL); vio_unregister_driver(&viotape_driver); - class_simple_destroy(tape_class); + class_destroy(tape_class); ret = unregister_chrdev(VIOTAPE_MAJOR, "viotape"); if (ret < 0) printk(VIOTAPE_KERN_WARN "Error unregistering device: %d\n", diff --git a/drivers/char/vr41xx_giu.c b/drivers/char/vr41xx_giu.c new file mode 100644 index 000000000000..683278bc5241 --- /dev/null +++ b/drivers/char/vr41xx_giu.c @@ -0,0 +1,743 @@ +/* + * Driver for NEC VR4100 series General-purpose I/O Unit. + * + * Copyright (C) 2002 MontaVista Software Inc. + * Author: Yoichi Yuasa <yyuasa@mvista.com or source@mvista.com> + * Copyright (C) 2003-2005 Yoichi Yuasa <yuasa@hh.iij4u.or.jp> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#include <linux/device.h> +#include <linux/errno.h> +#include <linux/fs.h> +#include <linux/init.h> +#include <linux/irq.h> +#include <linux/interrupt.h> +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/spinlock.h> +#include <linux/types.h> + +#include <asm/cpu.h> +#include <asm/io.h> +#include <asm/vr41xx/giu.h> +#include <asm/vr41xx/vr41xx.h> + +MODULE_AUTHOR("Yoichi Yuasa <yuasa@hh.iij4u.or.jp>"); +MODULE_DESCRIPTION("NEC VR4100 series General-purpose I/O Unit driver"); +MODULE_LICENSE("GPL"); + +static int major; /* default is dynamic major device number */ +module_param(major, int, 0); +MODULE_PARM_DESC(major, "Major device number"); + +#define GIU_TYPE1_START 0x0b000100UL +#define GIU_TYPE1_SIZE 0x20UL + +#define GIU_TYPE2_START 0x0f000140UL +#define GIU_TYPE2_SIZE 0x20UL + +#define GIU_TYPE3_START 0x0f000140UL +#define GIU_TYPE3_SIZE 0x28UL + +#define GIU_PULLUPDOWN_START 0x0b0002e0UL +#define GIU_PULLUPDOWN_SIZE 0x04UL + +#define GIUIOSELL 0x00 +#define GIUIOSELH 0x02 +#define GIUPIODL 0x04 +#define GIUPIODH 0x06 +#define GIUINTSTATL 0x08 +#define GIUINTSTATH 0x0a +#define GIUINTENL 0x0c +#define GIUINTENH 0x0e +#define GIUINTTYPL 0x10 +#define GIUINTTYPH 0x12 +#define GIUINTALSELL 0x14 +#define GIUINTALSELH 0x16 +#define GIUINTHTSELL 0x18 +#define GIUINTHTSELH 0x1a +#define GIUPODATL 0x1c +#define GIUPODATEN 0x1c +#define GIUPODATH 0x1e + #define PIOEN0 0x0100 + #define PIOEN1 0x0200 +#define GIUPODAT 0x1e +#define GIUFEDGEINHL 0x20 +#define GIUFEDGEINHH 0x22 +#define GIUREDGEINHL 0x24 +#define GIUREDGEINHH 0x26 + +#define GIUUSEUPDN 0x1e0 +#define GIUTERMUPDN 0x1e2 + +#define GPIO_HAS_PULLUPDOWN_IO 0x0001 +#define GPIO_HAS_OUTPUT_ENABLE 0x0002 +#define GPIO_HAS_INTERRUPT_EDGE_SELECT 0x0100 + +static spinlock_t giu_lock; +static struct resource *giu_resource1; +static struct resource *giu_resource2; +static unsigned long giu_flags; +static unsigned int giu_nr_pins; + +static void __iomem *giu_base; + +#define giu_read(offset) readw(giu_base + (offset)) +#define giu_write(offset, value) writew((value), giu_base + (offset)) + +#define GPIO_PIN_OF_IRQ(irq) ((irq) - GIU_IRQ_BASE) +#define GIUINT_HIGH_OFFSET 16 +#define GIUINT_HIGH_MAX 32 + +static inline uint16_t giu_set(uint16_t offset, uint16_t set) +{ + uint16_t data; + + data = giu_read(offset); + data |= set; + giu_write(offset, data); + + return data; +} + +static inline uint16_t giu_clear(uint16_t offset, uint16_t clear) +{ + uint16_t data; + + data = giu_read(offset); + data &= ~clear; + giu_write(offset, data); + + return data; +} + +static unsigned int startup_giuint_low_irq(unsigned int irq) +{ + unsigned int pin; + + pin = GPIO_PIN_OF_IRQ(irq); + giu_write(GIUINTSTATL, 1 << pin); + giu_set(GIUINTENL, 1 << pin); + + return 0; +} + +static void shutdown_giuint_low_irq(unsigned int irq) +{ + giu_clear(GIUINTENL, 1 << GPIO_PIN_OF_IRQ(irq)); +} + +static void enable_giuint_low_irq(unsigned int irq) +{ + giu_set(GIUINTENL, 1 << GPIO_PIN_OF_IRQ(irq)); +} + +#define disable_giuint_low_irq shutdown_giuint_low_irq + +static void ack_giuint_low_irq(unsigned int irq) +{ + unsigned int pin; + + pin = GPIO_PIN_OF_IRQ(irq); + giu_clear(GIUINTENL, 1 << pin); + giu_write(GIUINTSTATL, 1 << pin); +} + +static void end_giuint_low_irq(unsigned int irq) +{ + if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) + giu_set(GIUINTENL, 1 << GPIO_PIN_OF_IRQ(irq)); +} + +static struct hw_interrupt_type giuint_low_irq_type = { + .typename = "GIUINTL", + .startup = startup_giuint_low_irq, + .shutdown = shutdown_giuint_low_irq, + .enable = enable_giuint_low_irq, + .disable = disable_giuint_low_irq, + .ack = ack_giuint_low_irq, + .end = end_giuint_low_irq, +}; + +static unsigned int startup_giuint_high_irq(unsigned int irq) +{ + unsigned int pin; + + pin = GPIO_PIN_OF_IRQ(irq) - GIUINT_HIGH_OFFSET; + giu_write(GIUINTSTATH, 1 << pin); + giu_set(GIUINTENH, 1 << pin); + + return 0; +} + +static void shutdown_giuint_high_irq(unsigned int irq) +{ + giu_clear(GIUINTENH, 1 << (GPIO_PIN_OF_IRQ(irq) - GIUINT_HIGH_OFFSET)); +} + +static void enable_giuint_high_irq(unsigned int irq) +{ + giu_set(GIUINTENH, 1 << (GPIO_PIN_OF_IRQ(irq) - GIUINT_HIGH_OFFSET)); +} + +#define disable_giuint_high_irq shutdown_giuint_high_irq + +static void ack_giuint_high_irq(unsigned int irq) +{ + unsigned int pin; + + pin = GPIO_PIN_OF_IRQ(irq) - GIUINT_HIGH_OFFSET; + giu_clear(GIUINTENH, 1 << pin); + giu_write(GIUINTSTATH, 1 << pin); +} + +static void end_giuint_high_irq(unsigned int irq) +{ + if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) + giu_set(GIUINTENH, 1 << (GPIO_PIN_OF_IRQ(irq) - GIUINT_HIGH_OFFSET)); +} + +static struct hw_interrupt_type giuint_high_irq_type = { + .typename = "GIUINTH", + .startup = startup_giuint_high_irq, + .shutdown = shutdown_giuint_high_irq, + .enable = enable_giuint_high_irq, + .disable = disable_giuint_high_irq, + .ack = ack_giuint_high_irq, + .end = end_giuint_high_irq, +}; + +static int giu_get_irq(unsigned int irq, struct pt_regs *regs) +{ + uint16_t pendl, pendh, maskl, maskh; + int i; + + pendl = giu_read(GIUINTSTATL); + pendh = giu_read(GIUINTSTATH); + maskl = giu_read(GIUINTENL); + maskh = giu_read(GIUINTENH); + + maskl &= pendl; + maskh &= pendh; + + if (maskl) { + for (i = 0; i < 16; i++) { + if (maskl & (1 << i)) + return GIU_IRQ(i); + } + } else if (maskh) { + for (i = 0; i < 16; i++) { + if (maskh & (1 << i)) + return GIU_IRQ(i + GIUINT_HIGH_OFFSET); + } + } + + printk(KERN_ERR "spurious GIU interrupt: %04x(%04x),%04x(%04x)\n", + maskl, pendl, maskh, pendh); + + atomic_inc(&irq_err_count); + + return -EINVAL; +} + +void vr41xx_set_irq_trigger(unsigned int pin, irq_trigger_t trigger, irq_signal_t signal) +{ + uint16_t mask; + + if (pin < GIUINT_HIGH_OFFSET) { + mask = 1 << pin; + if (trigger != IRQ_TRIGGER_LEVEL) { + giu_set(GIUINTTYPL, mask); + if (signal == IRQ_SIGNAL_HOLD) + giu_set(GIUINTHTSELL, mask); + else + giu_clear(GIUINTHTSELL, mask); + if (current_cpu_data.cputype == CPU_VR4133) { + switch (trigger) { + case IRQ_TRIGGER_EDGE_FALLING: + giu_set(GIUFEDGEINHL, mask); + giu_clear(GIUREDGEINHL, mask); + break; + case IRQ_TRIGGER_EDGE_RISING: + giu_clear(GIUFEDGEINHL, mask); + giu_set(GIUREDGEINHL, mask); + break; + default: + giu_set(GIUFEDGEINHL, mask); + giu_set(GIUREDGEINHL, mask); + break; + } + } + } else { + giu_clear(GIUINTTYPL, mask); + giu_clear(GIUINTHTSELL, mask); + } + giu_write(GIUINTSTATL, mask); + } else if (pin < GIUINT_HIGH_MAX) { + mask = 1 << (pin - GIUINT_HIGH_OFFSET); + if (trigger != IRQ_TRIGGER_LEVEL) { + giu_set(GIUINTTYPH, mask); + if (signal == IRQ_SIGNAL_HOLD) + giu_set(GIUINTHTSELH, mask); + else + giu_clear(GIUINTHTSELH, mask); + if (current_cpu_data.cputype == CPU_VR4133) { + switch (trigger) { + case IRQ_TRIGGER_EDGE_FALLING: + giu_set(GIUFEDGEINHH, mask); + giu_clear(GIUREDGEINHH, mask); + break; + case IRQ_TRIGGER_EDGE_RISING: + giu_clear(GIUFEDGEINHH, mask); + giu_set(GIUREDGEINHH, mask); + break; + default: + giu_set(GIUFEDGEINHH, mask); + giu_set(GIUREDGEINHH, mask); + break; + } + } + } else { + giu_clear(GIUINTTYPH, mask); + giu_clear(GIUINTHTSELH, mask); + } + giu_write(GIUINTSTATH, mask); + } +} + +EXPORT_SYMBOL_GPL(vr41xx_set_irq_trigger); + +void vr41xx_set_irq_level(unsigned int pin, irq_level_t level) +{ + uint16_t mask; + + if (pin < GIUINT_HIGH_OFFSET) { + mask = 1 << pin; + if (level == IRQ_LEVEL_HIGH) + giu_set(GIUINTALSELL, mask); + else + giu_clear(GIUINTALSELL, mask); + giu_write(GIUINTSTATL, mask); + } else if (pin < GIUINT_HIGH_MAX) { + mask = 1 << (pin - GIUINT_HIGH_OFFSET); + if (level == IRQ_LEVEL_HIGH) + giu_set(GIUINTALSELH, mask); + else + giu_clear(GIUINTALSELH, mask); + giu_write(GIUINTSTATH, mask); + } +} + +EXPORT_SYMBOL_GPL(vr41xx_set_irq_level); + +gpio_data_t vr41xx_gpio_get_pin(unsigned int pin) +{ + uint16_t reg, mask; + + if (pin >= giu_nr_pins) + return GPIO_DATA_INVAL; + + if (pin < 16) { + reg = giu_read(GIUPIODL); + mask = (uint16_t)1 << pin; + } else if (pin < 32) { + reg = giu_read(GIUPIODH); + mask = (uint16_t)1 << (pin - 16); + } else if (pin < 48) { + reg = giu_read(GIUPODATL); + mask = (uint16_t)1 << (pin - 32); + } else { + reg = giu_read(GIUPODATH); + mask = (uint16_t)1 << (pin - 48); + } + + if (reg & mask) + return GPIO_DATA_HIGH; + + return GPIO_DATA_LOW; +} + +EXPORT_SYMBOL_GPL(vr41xx_gpio_get_pin); + +int vr41xx_gpio_set_pin(unsigned int pin, gpio_data_t data) +{ + uint16_t offset, mask, reg; + unsigned long flags; + + if (pin >= giu_nr_pins) + return -EINVAL; + + if (pin < 16) { + offset = GIUPIODL; + mask = (uint16_t)1 << pin; + } else if (pin < 32) { + offset = GIUPIODH; + mask = (uint16_t)1 << (pin - 16); + } else if (pin < 48) { + offset = GIUPODATL; + mask = (uint16_t)1 << (pin - 32); + } else { + offset = GIUPODATH; + mask = (uint16_t)1 << (pin - 48); + } + + spin_lock_irqsave(&giu_lock, flags); + + reg = giu_read(offset); + if (data == GPIO_DATA_HIGH) + reg |= mask; + else + reg &= ~mask; + giu_write(offset, reg); + + spin_unlock_irqrestore(&giu_lock, flags); + + return 0; +} + +EXPORT_SYMBOL_GPL(vr41xx_gpio_set_pin); + +int vr41xx_gpio_set_direction(unsigned int pin, gpio_direction_t dir) +{ + uint16_t offset, mask, reg; + unsigned long flags; + + if (pin >= giu_nr_pins) + return -EINVAL; + + if (pin < 16) { + offset = GIUIOSELL; + mask = (uint16_t)1 << pin; + } else if (pin < 32) { + offset = GIUIOSELH; + mask = (uint16_t)1 << (pin - 16); + } else { + if (giu_flags & GPIO_HAS_OUTPUT_ENABLE) { + offset = GIUPODATEN; + mask = (uint16_t)1 << (pin - 32); + } else { + switch (pin) { + case 48: + offset = GIUPODATH; + mask = PIOEN0; + break; + case 49: + offset = GIUPODATH; + mask = PIOEN1; + break; + default: + return -EINVAL; + } + } + } + + spin_lock_irqsave(&giu_lock, flags); + + reg = giu_read(offset); + if (dir == GPIO_OUTPUT) + reg |= mask; + else + reg &= ~mask; + giu_write(offset, reg); + + spin_unlock_irqrestore(&giu_lock, flags); + + return 0; +} + +EXPORT_SYMBOL_GPL(vr41xx_gpio_set_direction); + +int vr41xx_gpio_pullupdown(unsigned int pin, gpio_pull_t pull) +{ + uint16_t reg, mask; + unsigned long flags; + + if ((giu_flags & GPIO_HAS_PULLUPDOWN_IO) != GPIO_HAS_PULLUPDOWN_IO) + return -EPERM; + + if (pin >= 15) + return -EINVAL; + + mask = (uint16_t)1 << pin; + + spin_lock_irqsave(&giu_lock, flags); + + if (pull == GPIO_PULL_UP || pull == GPIO_PULL_DOWN) { + reg = giu_read(GIUTERMUPDN); + if (pull == GPIO_PULL_UP) + reg |= mask; + else + reg &= ~mask; + giu_write(GIUTERMUPDN, reg); + + reg = giu_read(GIUUSEUPDN); + reg |= mask; + giu_write(GIUUSEUPDN, reg); + } else { + reg = giu_read(GIUUSEUPDN); + reg &= ~mask; + giu_write(GIUUSEUPDN, reg); + } + + spin_unlock_irqrestore(&giu_lock, flags); + + return 0; +} + +EXPORT_SYMBOL_GPL(vr41xx_gpio_pullupdown); + +static ssize_t gpio_read(struct file *file, char __user *buf, size_t len, + loff_t *ppos) +{ + unsigned int pin; + char value = '0'; + + pin = iminor(file->f_dentry->d_inode); + if (pin >= giu_nr_pins) + return -EBADF; + + if (vr41xx_gpio_get_pin(pin) == GPIO_DATA_HIGH) + value = '1'; + + if (len <= 0) + return -EFAULT; + + if (put_user(value, buf)) + return -EFAULT; + + return 1; +} + +static ssize_t gpio_write(struct file *file, const char __user *data, + size_t len, loff_t *ppos) +{ + unsigned int pin; + size_t i; + char c; + int retval = 0; + + pin = iminor(file->f_dentry->d_inode); + if (pin >= giu_nr_pins) + return -EBADF; + + for (i = 0; i < len; i++) { + if (get_user(c, data + i)) + return -EFAULT; + + switch (c) { + case '0': + retval = vr41xx_gpio_set_pin(pin, GPIO_DATA_LOW); + break; + case '1': + retval = vr41xx_gpio_set_pin(pin, GPIO_DATA_HIGH); + break; + case 'D': + printk(KERN_INFO "GPIO%d: pull down\n", pin); + retval = vr41xx_gpio_pullupdown(pin, GPIO_PULL_DOWN); + break; + case 'd': + printk(KERN_INFO "GPIO%d: pull up/down disable\n", pin); + retval = vr41xx_gpio_pullupdown(pin, GPIO_PULL_DISABLE); + break; + case 'I': + printk(KERN_INFO "GPIO%d: input\n", pin); + retval = vr41xx_gpio_set_direction(pin, GPIO_INPUT); + break; + case 'O': + printk(KERN_INFO "GPIO%d: output\n", pin); + retval = vr41xx_gpio_set_direction(pin, GPIO_OUTPUT); + break; + case 'o': + printk(KERN_INFO "GPIO%d: output disable\n", pin); + retval = vr41xx_gpio_set_direction(pin, GPIO_OUTPUT_DISABLE); + break; + case 'P': + printk(KERN_INFO "GPIO%d: pull up\n", pin); + retval = vr41xx_gpio_pullupdown(pin, GPIO_PULL_UP); + break; + case 'p': + printk(KERN_INFO "GPIO%d: pull up/down disable\n", pin); + retval = vr41xx_gpio_pullupdown(pin, GPIO_PULL_DISABLE); + break; + default: + break; + } + + if (retval < 0) + break; + } + + return i; +} + +static int gpio_open(struct inode *inode, struct file *file) +{ + unsigned int pin; + + pin = iminor(inode); + if (pin >= giu_nr_pins) + return -EBADF; + + return nonseekable_open(inode, file); +} + +static int gpio_release(struct inode *inode, struct file *file) +{ + unsigned int pin; + + pin = iminor(inode); + if (pin >= giu_nr_pins) + return -EBADF; + + return 0; +} + +static struct file_operations gpio_fops = { + .owner = THIS_MODULE, + .read = gpio_read, + .write = gpio_write, + .open = gpio_open, + .release = gpio_release, +}; + +static int giu_probe(struct device *dev) +{ + unsigned long start, size, flags = 0; + unsigned int nr_pins = 0; + struct resource *res1, *res2 = NULL; + void *base; + int retval, i; + + switch (current_cpu_data.cputype) { + case CPU_VR4111: + case CPU_VR4121: + start = GIU_TYPE1_START; + size = GIU_TYPE1_SIZE; + flags = GPIO_HAS_PULLUPDOWN_IO; + nr_pins = 50; + break; + case CPU_VR4122: + case CPU_VR4131: + start = GIU_TYPE2_START; + size = GIU_TYPE2_SIZE; + nr_pins = 36; + break; + case CPU_VR4133: + start = GIU_TYPE3_START; + size = GIU_TYPE3_SIZE; + flags = GPIO_HAS_INTERRUPT_EDGE_SELECT; + nr_pins = 48; + break; + default: + return -ENODEV; + } + + res1 = request_mem_region(start, size, "GIU"); + if (res1 == NULL) + return -EBUSY; + + base = ioremap(start, size); + if (base == NULL) { + release_resource(res1); + return -ENOMEM; + } + + if (flags & GPIO_HAS_PULLUPDOWN_IO) { + res2 = request_mem_region(GIU_PULLUPDOWN_START, GIU_PULLUPDOWN_SIZE, "GIU"); + if (res2 == NULL) { + iounmap(base); + release_resource(res1); + return -EBUSY; + } + } + + retval = register_chrdev(major, "GIU", &gpio_fops); + if (retval < 0) { + iounmap(base); + release_resource(res1); + release_resource(res2); + return retval; + } + + if (major == 0) { + major = retval; + printk(KERN_INFO "GIU: major number %d\n", major); + } + + spin_lock_init(&giu_lock); + giu_base = base; + giu_resource1 = res1; + giu_resource2 = res2; + giu_flags = flags; + giu_nr_pins = nr_pins; + + giu_write(GIUINTENL, 0); + giu_write(GIUINTENH, 0); + + for (i = GIU_IRQ_BASE; i <= GIU_IRQ_LAST; i++) { + if (i < GIU_IRQ(GIUINT_HIGH_OFFSET)) + irq_desc[i].handler = &giuint_low_irq_type; + else + irq_desc[i].handler = &giuint_high_irq_type; + } + + return cascade_irq(GIUINT_IRQ, giu_get_irq); +} + +static int giu_remove(struct device *dev) +{ + iounmap(giu_base); + + release_resource(giu_resource1); + if (giu_flags & GPIO_HAS_PULLUPDOWN_IO) + release_resource(giu_resource2); + + return 0; +} + +static struct platform_device *giu_platform_device; + +static struct device_driver giu_device_driver = { + .name = "GIU", + .bus = &platform_bus_type, + .probe = giu_probe, + .remove = giu_remove, +}; + +static int __devinit vr41xx_giu_init(void) +{ + int retval; + + giu_platform_device = platform_device_register_simple("GIU", -1, NULL, 0); + if (IS_ERR(giu_platform_device)) + return PTR_ERR(giu_platform_device); + + retval = driver_register(&giu_device_driver); + if (retval < 0) + platform_device_unregister(giu_platform_device); + + return retval; +} + +static void __devexit vr41xx_giu_exit(void) +{ + driver_unregister(&giu_device_driver); + + platform_device_unregister(giu_platform_device); +} + +module_init(vr41xx_giu_init); +module_exit(vr41xx_giu_exit); diff --git a/drivers/char/vt.c b/drivers/char/vt.c index e5ef1dfc5482..d7aa7a29f67e 100644 --- a/drivers/char/vt.c +++ b/drivers/char/vt.c @@ -2867,6 +2867,10 @@ void unblank_screen(void) */ static void blank_screen_t(unsigned long dummy) { + if (unlikely(!keventd_up())) { + mod_timer(&console_timer, jiffies + blankinterval); + return; + } blank_timer_expired = 1; schedule_work(&console_work); } diff --git a/drivers/char/watchdog/ixp2000_wdt.c b/drivers/char/watchdog/ixp2000_wdt.c index ab659d37b4d2..4e98c215e5b1 100644 --- a/drivers/char/watchdog/ixp2000_wdt.c +++ b/drivers/char/watchdog/ixp2000_wdt.c @@ -192,7 +192,12 @@ static struct miscdevice ixp2000_wdt_miscdev = static int __init ixp2000_wdt_init(void) { - wdt_tick_rate = (*IXP2000_T1_CLD * HZ)/ 256;; + if ((*IXP2000_PRODUCT_ID & 0x001ffef0) == 0x00000000) { + printk(KERN_INFO "Unable to use IXP2000 watchdog due to IXP2800 erratum #25.\n"); + return -EIO; + } + + wdt_tick_rate = (*IXP2000_T1_CLD * HZ) / 256; return misc_register(&ixp2000_wdt_miscdev); } |