diff options
Diffstat (limited to 'drivers/macintosh')
-rw-r--r-- | drivers/macintosh/adb.c | 26 | ||||
-rw-r--r-- | drivers/macintosh/adbhid.c | 63 | ||||
-rw-r--r-- | drivers/macintosh/ans-lcd.c | 2 | ||||
-rw-r--r-- | drivers/macintosh/macio_sysfs.c | 12 | ||||
-rw-r--r-- | drivers/macintosh/mediabay.c | 34 | ||||
-rw-r--r-- | drivers/macintosh/smu.c | 38 | ||||
-rw-r--r-- | drivers/macintosh/therm_adt746x.c | 15 | ||||
-rw-r--r-- | drivers/macintosh/therm_pm72.c | 4 | ||||
-rw-r--r-- | drivers/macintosh/therm_windtunnel.c | 18 | ||||
-rw-r--r-- | drivers/macintosh/via-pmu.c | 3 | ||||
-rw-r--r-- | drivers/macintosh/via-pmu68k.c | 5 |
11 files changed, 151 insertions, 69 deletions
diff --git a/drivers/macintosh/adb.c b/drivers/macintosh/adb.c index dbaad39020a..cae52485208 100644 --- a/drivers/macintosh/adb.c +++ b/drivers/macintosh/adb.c @@ -46,7 +46,6 @@ #endif -EXPORT_SYMBOL(adb_controller); EXPORT_SYMBOL(adb_client_list); extern struct adb_driver via_macii_driver; @@ -80,7 +79,7 @@ static struct adb_driver *adb_driver_list[] = { static struct class *adb_dev_class; -struct adb_driver *adb_controller; +static struct adb_driver *adb_controller; BLOCKING_NOTIFIER_HEAD(adb_client_list); static int adb_got_sleep; static int adb_inited; @@ -290,7 +289,7 @@ static int adb_resume(struct platform_device *dev) } #endif /* CONFIG_PM */ -int __init adb_init(void) +static int __init adb_init(void) { struct adb_driver *driver; int i; @@ -644,12 +643,18 @@ do_adb_query(struct adb_request *req) static int adb_open(struct inode *inode, struct file *file) { struct adbdev_state *state; + int ret = 0; - if (iminor(inode) > 0 || adb_controller == NULL) - return -ENXIO; + lock_kernel(); + if (iminor(inode) > 0 || adb_controller == NULL) { + ret = -ENXIO; + goto out; + } state = kmalloc(sizeof(struct adbdev_state), GFP_KERNEL); - if (state == 0) - return -ENOMEM; + if (state == 0) { + ret = -ENOMEM; + goto out; + } file->private_data = state; spin_lock_init(&state->lock); atomic_set(&state->n_pending, 0); @@ -657,7 +662,9 @@ static int adb_open(struct inode *inode, struct file *file) init_waitqueue_head(&state->wait_queue); state->inuse = 1; - return 0; +out: + unlock_kernel(); + return ret; } static int adb_release(struct inode *inode, struct file *file) @@ -855,7 +862,8 @@ adbdev_init(void) adb_dev_class = class_create(THIS_MODULE, "adb"); if (IS_ERR(adb_dev_class)) return; - device_create(adb_dev_class, NULL, MKDEV(ADB_MAJOR, 0), "adb"); + device_create_drvdata(adb_dev_class, NULL, MKDEV(ADB_MAJOR, 0), NULL, + "adb"); platform_device_register(&adb_pfdev); platform_driver_probe(&adb_pfdrv, adb_dummy_probe); diff --git a/drivers/macintosh/adbhid.c b/drivers/macintosh/adbhid.c index ef4c117ea35..5396c67ba0a 100644 --- a/drivers/macintosh/adbhid.c +++ b/drivers/macintosh/adbhid.c @@ -75,7 +75,7 @@ static struct notifier_block adbhid_adb_notifier = { #define ADB_KEY_POWER_OLD 0x7e #define ADB_KEY_POWER 0x7f -u16 adb_to_linux_keycodes[128] = { +static const u16 adb_to_linux_keycodes[128] = { /* 0x00 */ KEY_A, /* 30 */ /* 0x01 */ KEY_S, /* 31 */ /* 0x02 */ KEY_D, /* 32 */ @@ -219,11 +219,13 @@ struct adbhid { int flags; }; -#define FLAG_FN_KEY_PRESSED 0x00000001 -#define FLAG_POWER_FROM_FN 0x00000002 -#define FLAG_EMU_FWDEL_DOWN 0x00000004 -#define FLAG_CAPSLOCK_TRANSLATE 0x00000008 -#define FLAG_CAPSLOCK_DOWN 0x00000010 +#define FLAG_FN_KEY_PRESSED 0x00000001 +#define FLAG_POWER_FROM_FN 0x00000002 +#define FLAG_EMU_FWDEL_DOWN 0x00000004 +#define FLAG_CAPSLOCK_TRANSLATE 0x00000008 +#define FLAG_CAPSLOCK_DOWN 0x00000010 +#define FLAG_CAPSLOCK_IGNORE_NEXT 0x00000020 +#define FLAG_POWER_KEY_PRESSED 0x00000040 static struct adbhid *adbhid[16]; @@ -291,11 +293,20 @@ adbhid_input_keycode(int id, int scancode, int repeat) if (keycode == ADB_KEY_CAPSLOCK && !up_flag) { /* Key pressed, turning on the CapsLock LED. * The next 0xff will be interpreted as a release. */ - ahid->flags |= FLAG_CAPSLOCK_TRANSLATE + if (ahid->flags & FLAG_CAPSLOCK_IGNORE_NEXT) { + /* Throw away this key event if it happens + * just after resume. */ + ahid->flags &= ~FLAG_CAPSLOCK_IGNORE_NEXT; + return; + } else { + ahid->flags |= FLAG_CAPSLOCK_TRANSLATE | FLAG_CAPSLOCK_DOWN; - } else if (scancode == 0xff) { + } + } else if (scancode == 0xff && + !(ahid->flags & FLAG_POWER_KEY_PRESSED)) { /* Scancode 0xff usually signifies that the capslock - * key was either pressed or released. */ + * key was either pressed or released, or that the + * power button was released. */ if (ahid->flags & FLAG_CAPSLOCK_TRANSLATE) { keycode = ADB_KEY_CAPSLOCK; if (ahid->flags & FLAG_CAPSLOCK_DOWN) { @@ -309,7 +320,7 @@ adbhid_input_keycode(int id, int scancode, int repeat) } } else { printk(KERN_INFO "Spurious caps lock event " - "(scancode 0xff)."); + "(scancode 0xff).\n"); } } } @@ -336,6 +347,12 @@ adbhid_input_keycode(int id, int scancode, int repeat) } break; case ADB_KEY_POWER: + /* Keep track of the power key state */ + if (up_flag) + ahid->flags &= ~FLAG_POWER_KEY_PRESSED; + else + ahid->flags |= FLAG_POWER_KEY_PRESSED; + /* Fn + Command will produce a bogus "power" keycode */ if (ahid->flags & FLAG_FN_KEY_PRESSED) { keycode = ADB_KEY_CMD; @@ -681,6 +698,21 @@ static int adbhid_kbd_event(struct input_dev *dev, unsigned int type, unsigned i return -1; } +static void +adbhid_kbd_capslock_remember(void) +{ + struct adbhid *ahid; + int i; + + for (i = 1; i < 16; i++) { + ahid = adbhid[i]; + + if (ahid && ahid->id == ADB_KEYBOARD) + if (ahid->flags & FLAG_CAPSLOCK_TRANSLATE) + ahid->flags |= FLAG_CAPSLOCK_IGNORE_NEXT; + } +} + static int adb_message_handler(struct notifier_block *this, unsigned long code, void *x) { @@ -697,8 +729,17 @@ adb_message_handler(struct notifier_block *this, unsigned long code, void *x) } /* Stop pending led requests */ - while(leds_req_pending) + while (leds_req_pending) adb_poll(); + + /* After resume, and if the capslock LED is on, the PMU will + * send a "capslock down" key event. This confuses the + * restore_capslock_events logic. Remember if the capslock + * LED was on before suspend so the unwanted key event can + * be ignored after resume. */ + if (restore_capslock_events) + adbhid_kbd_capslock_remember(); + break; case ADB_MSG_POST_RESET: diff --git a/drivers/macintosh/ans-lcd.c b/drivers/macintosh/ans-lcd.c index 73c50bc0209..6a822189325 100644 --- a/drivers/macintosh/ans-lcd.c +++ b/drivers/macintosh/ans-lcd.c @@ -3,6 +3,7 @@ */ #include <linux/types.h> +#include <linux/smp_lock.h> #include <linux/errno.h> #include <linux/kernel.h> #include <linux/miscdevice.h> @@ -119,6 +120,7 @@ anslcd_ioctl( struct inode * inode, struct file * file, static int anslcd_open( struct inode * inode, struct file * file ) { + cycle_kernel_lock(); return 0; } diff --git a/drivers/macintosh/macio_sysfs.c b/drivers/macintosh/macio_sysfs.c index 112e5ef728f..9e9453b5842 100644 --- a/drivers/macintosh/macio_sysfs.c +++ b/drivers/macintosh/macio_sysfs.c @@ -44,7 +44,7 @@ static ssize_t modalias_show (struct device *dev, struct device_attribute *attr, struct of_device *ofdev = to_of_device(dev); int len; - len = of_device_get_modalias(ofdev, buf, PAGE_SIZE); + len = of_device_get_modalias(ofdev, buf, PAGE_SIZE - 2); buf[len] = '\n'; buf[len+1] = 0; @@ -52,6 +52,15 @@ static ssize_t modalias_show (struct device *dev, struct device_attribute *attr, return len+1; } +static ssize_t devspec_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct of_device *ofdev; + + ofdev = to_of_device(dev); + return sprintf(buf, "%s\n", ofdev->node->full_name); +} + macio_config_of_attr (name, "%s\n"); macio_config_of_attr (type, "%s\n"); @@ -60,5 +69,6 @@ struct device_attribute macio_dev_attrs[] = { __ATTR_RO(type), __ATTR_RO(compatible), __ATTR_RO(modalias), + __ATTR_RO(devspec), __ATTR_NULL }; diff --git a/drivers/macintosh/mediabay.c b/drivers/macintosh/mediabay.c index 82add26cc66..b1e5b470525 100644 --- a/drivers/macintosh/mediabay.c +++ b/drivers/macintosh/mediabay.c @@ -21,6 +21,7 @@ #include <linux/init.h> #include <linux/ide.h> #include <linux/kthread.h> +#include <linux/mutex.h> #include <asm/prom.h> #include <asm/pgtable.h> #include <asm/io.h> @@ -77,14 +78,14 @@ struct media_bay_info { int index; int cached_gpio; int sleeping; - struct semaphore lock; + struct mutex lock; #ifdef CONFIG_BLK_DEV_IDE_PMAC ide_hwif_t *cd_port; void __iomem *cd_base; int cd_irq; int cd_retry; #endif -#if defined(CONFIG_BLK_DEV_IDE_PMAC) || defined(CONFIG_MAC_FLOPPY) +#if defined(CONFIG_BLK_DEV_IDE_PMAC) int cd_index; #endif }; @@ -417,6 +418,7 @@ static void poll_media_bay(struct media_bay_info* bay) } } +#ifdef CONFIG_BLK_DEV_IDE_PMAC int check_media_bay(struct device_node *which_bay, int what) { int i; @@ -432,7 +434,6 @@ int check_media_bay(struct device_node *which_bay, int what) } EXPORT_SYMBOL(check_media_bay); -#ifdef CONFIG_BLK_DEV_IDE_PMAC int check_media_bay_by_base(unsigned long base, int what) { int i; @@ -459,27 +460,27 @@ int media_bay_set_ide_infos(struct device_node* which_bay, unsigned long base, if (bay->mdev && which_bay == bay->mdev->ofdev.node) { int timeout = 5000, index = hwif->index; - down(&bay->lock); + mutex_lock(&bay->lock); bay->cd_port = hwif; bay->cd_base = (void __iomem *) base; bay->cd_irq = irq; if ((MB_CD != bay->content_id) || bay->state != mb_up) { - up(&bay->lock); + mutex_unlock(&bay->lock); return 0; } printk(KERN_DEBUG "Registered ide%d for media bay %d\n", index, i); do { if (MB_IDE_READY(i)) { bay->cd_index = index; - up(&bay->lock); + mutex_unlock(&bay->lock); return 0; } mdelay(1); } while(--timeout); printk(KERN_DEBUG "Timeount waiting IDE in bay %d\n", i); - up(&bay->lock); + mutex_unlock(&bay->lock); return -ENODEV; } } @@ -556,7 +557,8 @@ static void media_bay_step(int i) printk("mediabay %d, registering IDE...\n", i); pmu_suspend(); ide_port_scan(bay->cd_port); - bay->cd_index = bay->cd_port->index; + if (bay->cd_port->present) + bay->cd_index = bay->cd_port->index; pmu_resume(); } if (bay->cd_index == -1) { @@ -616,10 +618,10 @@ static int media_bay_task(void *x) while (!kthread_should_stop()) { for (i = 0; i < media_bay_count; ++i) { - down(&media_bays[i].lock); + mutex_lock(&media_bays[i].lock); if (!media_bays[i].sleeping) media_bay_step(i); - up(&media_bays[i].lock); + mutex_unlock(&media_bays[i].lock); } msleep_interruptible(MB_POLL_DELAY); @@ -659,7 +661,7 @@ static int __devinit media_bay_attach(struct macio_dev *mdev, const struct of_de bay->index = i; bay->ops = match->data; bay->sleeping = 0; - init_MUTEX(&bay->lock); + mutex_init(&bay->lock); /* Init HW probing */ if (bay->ops->init) @@ -697,10 +699,10 @@ static int media_bay_suspend(struct macio_dev *mdev, pm_message_t state) if (state.event != mdev->ofdev.dev.power.power_state.event && (state.event & PM_EVENT_SLEEP)) { - down(&bay->lock); + mutex_lock(&bay->lock); bay->sleeping = 1; set_mb_power(bay, 0); - up(&bay->lock); + mutex_unlock(&bay->lock); msleep(MB_POLL_DELAY); mdev->ofdev.dev.power.power_state = state; } @@ -719,12 +721,12 @@ static int media_bay_resume(struct macio_dev *mdev) they seem to help the 3400 get it right. */ /* Force MB power to 0 */ - down(&bay->lock); + mutex_lock(&bay->lock); set_mb_power(bay, 0); msleep(MB_POWER_DELAY); if (bay->ops->content(bay) != bay->content_id) { printk("mediabay%d: content changed during sleep...\n", bay->index); - up(&bay->lock); + mutex_unlock(&bay->lock); return 0; } set_mb_power(bay, 1); @@ -740,7 +742,7 @@ static int media_bay_resume(struct macio_dev *mdev) } while((bay->state != mb_empty) && (bay->state != mb_up)); bay->sleeping = 0; - up(&bay->lock); + mutex_unlock(&bay->lock); } return 0; } diff --git a/drivers/macintosh/smu.c b/drivers/macintosh/smu.c index 77ad192962c..96faa799b82 100644 --- a/drivers/macintosh/smu.c +++ b/drivers/macintosh/smu.c @@ -19,6 +19,7 @@ * the userland interface */ +#include <linux/smp_lock.h> #include <linux/types.h> #include <linux/kernel.h> #include <linux/device.h> @@ -35,6 +36,8 @@ #include <linux/sysdev.h> #include <linux/poll.h> #include <linux/mutex.h> +#include <linux/of_device.h> +#include <linux/of_platform.h> #include <asm/byteorder.h> #include <asm/io.h> @@ -45,8 +48,6 @@ #include <asm/sections.h> #include <asm/abs_addr.h> #include <asm/uaccess.h> -#include <asm/of_device.h> -#include <asm/of_platform.h> #define VERSION "0.7" #define AUTHOR "(c) 2005 Benjamin Herrenschmidt, IBM Corp." @@ -474,6 +475,7 @@ int __init smu_init (void) { struct device_node *np; const u32 *data; + int ret = 0; np = of_find_node_by_type(NULL, "smu"); if (np == NULL) @@ -483,13 +485,11 @@ int __init smu_init (void) if (smu_cmdbuf_abs == 0) { printk(KERN_ERR "SMU: Command buffer not allocated !\n"); - return -EINVAL; + ret = -EINVAL; + goto fail_np; } smu = alloc_bootmem(sizeof(struct smu_device)); - if (smu == NULL) - return -ENOMEM; - memset(smu, 0, sizeof(*smu)); spin_lock_init(&smu->lock); INIT_LIST_HEAD(&smu->cmd_list); @@ -507,14 +507,14 @@ int __init smu_init (void) smu->db_node = of_find_node_by_name(NULL, "smu-doorbell"); if (smu->db_node == NULL) { printk(KERN_ERR "SMU: Can't find doorbell GPIO !\n"); - goto fail; + ret = -ENXIO; + goto fail_bootmem; } data = of_get_property(smu->db_node, "reg", NULL); if (data == NULL) { - of_node_put(smu->db_node); - smu->db_node = NULL; printk(KERN_ERR "SMU: Can't find doorbell GPIO address !\n"); - goto fail; + ret = -ENXIO; + goto fail_db_node; } /* Current setup has one doorbell GPIO that does both doorbell @@ -548,7 +548,8 @@ int __init smu_init (void) smu->db_buf = ioremap(0x8000860c, 0x1000); if (smu->db_buf == NULL) { printk(KERN_ERR "SMU: Can't map doorbell buffer pointer !\n"); - goto fail; + ret = -ENXIO; + goto fail_msg_node; } /* U3 has an issue with NAP mode when issuing SMU commands */ @@ -559,10 +560,17 @@ int __init smu_init (void) sys_ctrler = SYS_CTRLER_SMU; return 0; - fail: +fail_msg_node: + if (smu->msg_node) + of_node_put(smu->msg_node); +fail_db_node: + of_node_put(smu->db_node); +fail_bootmem: + free_bootmem((unsigned long)smu, sizeof(struct smu_device)); smu = NULL; - return -ENXIO; - +fail_np: + of_node_put(np); + return ret; } @@ -1083,10 +1091,12 @@ static int smu_open(struct inode *inode, struct file *file) pp->mode = smu_file_commands; init_waitqueue_head(&pp->wait); + lock_kernel(); spin_lock_irqsave(&smu_clist_lock, flags); list_add(&pp->list, &smu_clist); spin_unlock_irqrestore(&smu_clist_lock, flags); file->private_data = pp; + unlock_kernel(); return 0; } diff --git a/drivers/macintosh/therm_adt746x.c b/drivers/macintosh/therm_adt746x.c index 54f4942a296..22bf981d393 100644 --- a/drivers/macintosh/therm_adt746x.c +++ b/drivers/macintosh/therm_adt746x.c @@ -24,13 +24,13 @@ #include <linux/kthread.h> #include <linux/moduleparam.h> #include <linux/freezer.h> +#include <linux/of_platform.h> #include <asm/prom.h> #include <asm/machdep.h> #include <asm/io.h> #include <asm/system.h> #include <asm/sections.h> -#include <asm/of_platform.h> #undef DEBUG @@ -562,18 +562,24 @@ thermostat_init(void) therm_type = ADT7460; else if (of_device_is_compatible(np, "adt7467")) therm_type = ADT7467; - else + else { + of_node_put(np); return -ENODEV; + } prop = of_get_property(np, "hwsensor-params-version", NULL); printk(KERN_INFO "adt746x: version %d (%ssupported)\n", *prop, (*prop == 1)?"":"un"); - if (*prop != 1) + if (*prop != 1) { + of_node_put(np); return -ENODEV; + } prop = of_get_property(np, "reg", NULL); - if (!prop) + if (!prop) { + of_node_put(np); return -ENODEV; + } /* look for bus either by path or using "reg" */ if (strstr(np->full_name, "/i2c-bus@") != NULL) { @@ -610,6 +616,7 @@ thermostat_init(void) if (of_dev == NULL) { printk(KERN_ERR "Can't register temperatures device !\n"); + of_node_put(np); return -ENODEV; } diff --git a/drivers/macintosh/therm_pm72.c b/drivers/macintosh/therm_pm72.c index ddfb426a9ab..817607e2af6 100644 --- a/drivers/macintosh/therm_pm72.c +++ b/drivers/macintosh/therm_pm72.c @@ -123,14 +123,14 @@ #include <linux/i2c.h> #include <linux/kthread.h> #include <linux/mutex.h> +#include <linux/of_device.h> +#include <linux/of_platform.h> #include <asm/prom.h> #include <asm/machdep.h> #include <asm/io.h> #include <asm/system.h> #include <asm/sections.h> -#include <asm/of_device.h> #include <asm/macio.h> -#include <asm/of_platform.h> #include "therm_pm72.h" diff --git a/drivers/macintosh/therm_windtunnel.c b/drivers/macintosh/therm_windtunnel.c index d11821af3b8..3da0a02efd7 100644 --- a/drivers/macintosh/therm_windtunnel.c +++ b/drivers/macintosh/therm_windtunnel.c @@ -37,13 +37,13 @@ #include <linux/slab.h> #include <linux/init.h> #include <linux/kthread.h> +#include <linux/of_platform.h> #include <asm/prom.h> #include <asm/machdep.h> #include <asm/io.h> #include <asm/system.h> #include <asm/sections.h> -#include <asm/of_platform.h> #include <asm/macio.h> #define LOG_TEMP 0 /* continously log temperature */ @@ -62,7 +62,7 @@ static struct { volatile int running; struct task_struct *poll_task; - struct semaphore lock; + struct mutex lock; struct of_device *of_dev; struct i2c_client *thermostat; @@ -286,23 +286,23 @@ restore_regs( void ) static int control_loop(void *dummy) { - down(&x.lock); + mutex_lock(&x.lock); setup_hardware(); - up(&x.lock); + mutex_unlock(&x.lock); for (;;) { msleep_interruptible(8000); if (kthread_should_stop()) break; - down(&x.lock); + mutex_lock(&x.lock); poll_temp(); - up(&x.lock); + mutex_unlock(&x.lock); } - down(&x.lock); + mutex_lock(&x.lock); restore_regs(); - up(&x.lock); + mutex_unlock(&x.lock); return 0; } @@ -489,7 +489,7 @@ g4fan_init( void ) const struct apple_thermal_info *info; struct device_node *np; - init_MUTEX( &x.lock ); + mutex_init(&x.lock); if( !(np=of_find_node_by_name(NULL, "power-mgt")) ) return -ENODEV; diff --git a/drivers/macintosh/via-pmu.c b/drivers/macintosh/via-pmu.c index d6365a9f063..d524dc245a2 100644 --- a/drivers/macintosh/via-pmu.c +++ b/drivers/macintosh/via-pmu.c @@ -18,6 +18,7 @@ * */ #include <stdarg.h> +#include <linux/smp_lock.h> #include <linux/types.h> #include <linux/errno.h> #include <linux/kernel.h> @@ -2047,6 +2048,7 @@ pmu_open(struct inode *inode, struct file *file) pp->rb_get = pp->rb_put = 0; spin_lock_init(&pp->lock); init_waitqueue_head(&pp->wait); + lock_kernel(); spin_lock_irqsave(&all_pvt_lock, flags); #if defined(CONFIG_INPUT_ADBHID) && defined(CONFIG_PMAC_BACKLIGHT) pp->backlight_locker = 0; @@ -2054,6 +2056,7 @@ pmu_open(struct inode *inode, struct file *file) list_add(&pp->list, &all_pmu_pvt); spin_unlock_irqrestore(&all_pvt_lock, flags); file->private_data = pp; + unlock_kernel(); return 0; } diff --git a/drivers/macintosh/via-pmu68k.c b/drivers/macintosh/via-pmu68k.c index e2f84da09e7..b64741c95ac 100644 --- a/drivers/macintosh/via-pmu68k.c +++ b/drivers/macintosh/via-pmu68k.c @@ -101,7 +101,6 @@ static int pmu_kind = PMU_UNKNOWN; static int pmu_fully_inited; int asleep; -BLOCKING_NOTIFIER_HEAD(sleep_notifier_list); static int pmu_probe(void); static int pmu_init(void); @@ -741,8 +740,8 @@ pmu_handle_data(unsigned char *data, int len) } } -int backlight_level = -1; -int backlight_enabled = 0; +static int backlight_level = -1; +static int backlight_enabled = 0; #define LEVEL_TO_BRIGHT(lev) ((lev) < 1? 0x7f: 0x4a - ((lev) << 1)) |