diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2009-12-12 14:27:24 -0800 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-12-12 14:27:24 -0800 |
commit | 09cea96caa59fabab3030c53bd698b9b568d959a (patch) | |
tree | a991cdc0c887fdcda37f4b751ee98d3db9559f4e /drivers/macintosh | |
parent | 6eb7365db6f3a4a9d8d9922bb0b800f9cbaad641 (diff) | |
parent | e090aa80321b64c3b793f3b047e31ecf1af9538d (diff) | |
download | linux-09cea96caa59fabab3030c53bd698b9b568d959a.tar.bz2 |
Merge branch 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc
* 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc: (151 commits)
powerpc: Fix usage of 64-bit instruction in 32-bit altivec code
MAINTAINERS: Add PowerPC patterns
powerpc/pseries: Track previous CPPR values to correctly EOI interrupts
powerpc/pseries: Correct pseries/dlpar.c build break without CONFIG_SMP
powerpc: Make "intspec" pointers in irq_host->xlate() const
powerpc/8xx: DTLB Miss cleanup
powerpc/8xx: Remove DIRTY pte handling in DTLB Error.
powerpc/8xx: Start using dcbX instructions in various copy routines
powerpc/8xx: Restore _PAGE_WRITETHRU
powerpc/8xx: Add missing Guarded setting in DTLB Error.
powerpc/8xx: Fixup DAR from buggy dcbX instructions.
powerpc/8xx: Tag DAR with 0x00f0 to catch buggy instructions.
powerpc/8xx: Update TLB asm so it behaves as linux mm expects.
powerpc/8xx: Invalidate non present TLBs
powerpc/pseries: Serialize cpu hotplug operations during deactivate Vs deallocate
pseries/pseries: Add code to online/offline CPUs of a DLPAR node
powerpc: stop_this_cpu: remove the cpu from the online map.
powerpc/pseries: Add kernel based CPU DLPAR handling
sysfs/cpu: Add probe/release files
powerpc/pseries: Kernel DLPAR Infrastructure
...
Diffstat (limited to 'drivers/macintosh')
-rw-r--r-- | drivers/macintosh/macio_asic.c | 52 | ||||
-rw-r--r-- | drivers/macintosh/mediabay.c | 328 | ||||
-rw-r--r-- | drivers/macintosh/nvram.c | 11 | ||||
-rw-r--r-- | drivers/macintosh/therm_adt746x.c | 15 | ||||
-rw-r--r-- | drivers/macintosh/via-pmu.c | 160 | ||||
-rw-r--r-- | drivers/macintosh/windfarm_smu_controls.c | 2 |
6 files changed, 282 insertions, 286 deletions
diff --git a/drivers/macintosh/macio_asic.c b/drivers/macintosh/macio_asic.c index 588a5b0bc4b5..26a303a1d1ab 100644 --- a/drivers/macintosh/macio_asic.c +++ b/drivers/macintosh/macio_asic.c @@ -379,6 +379,11 @@ static struct macio_dev * macio_add_one_device(struct macio_chip *chip, dev->ofdev.dev.parent = parent; dev->ofdev.dev.bus = &macio_bus_type; dev->ofdev.dev.release = macio_release_dev; + dev->ofdev.dev.dma_parms = &dev->dma_parms; + + /* Standard DMA paremeters */ + dma_set_max_seg_size(&dev->ofdev.dev, 65536); + dma_set_seg_boundary(&dev->ofdev.dev, 0xffffffff); #ifdef CONFIG_PCI /* Set the DMA ops to the ones from the PCI device, this could be @@ -538,6 +543,42 @@ void macio_unregister_driver(struct macio_driver *drv) driver_unregister(&drv->driver); } +/* Managed MacIO resources */ +struct macio_devres { + u32 res_mask; +}; + +static void maciom_release(struct device *gendev, void *res) +{ + struct macio_dev *dev = to_macio_device(gendev); + struct macio_devres *dr = res; + int i, max; + + max = min(dev->n_resources, 32); + for (i = 0; i < max; i++) { + if (dr->res_mask & (1 << i)) + macio_release_resource(dev, i); + } +} + +int macio_enable_devres(struct macio_dev *dev) +{ + struct macio_devres *dr; + + dr = devres_find(&dev->ofdev.dev, maciom_release, NULL, NULL); + if (!dr) { + dr = devres_alloc(maciom_release, sizeof(*dr), GFP_KERNEL); + if (!dr) + return -ENOMEM; + } + return devres_get(&dev->ofdev.dev, dr, NULL, NULL) != NULL; +} + +static struct macio_devres * find_macio_dr(struct macio_dev *dev) +{ + return devres_find(&dev->ofdev.dev, maciom_release, NULL, NULL); +} + /** * macio_request_resource - Request an MMIO resource * @dev: pointer to the device holding the resource @@ -555,6 +596,8 @@ void macio_unregister_driver(struct macio_driver *drv) int macio_request_resource(struct macio_dev *dev, int resource_no, const char *name) { + struct macio_devres *dr = find_macio_dr(dev); + if (macio_resource_len(dev, resource_no) == 0) return 0; @@ -562,6 +605,9 @@ int macio_request_resource(struct macio_dev *dev, int resource_no, macio_resource_len(dev, resource_no), name)) goto err_out; + + if (dr && resource_no < 32) + dr->res_mask |= 1 << resource_no; return 0; @@ -582,10 +628,14 @@ err_out: */ void macio_release_resource(struct macio_dev *dev, int resource_no) { + struct macio_devres *dr = find_macio_dr(dev); + if (macio_resource_len(dev, resource_no) == 0) return; release_mem_region(macio_resource_start(dev, resource_no), macio_resource_len(dev, resource_no)); + if (dr && resource_no < 32) + dr->res_mask &= ~(1 << resource_no); } /** @@ -744,3 +794,5 @@ EXPORT_SYMBOL(macio_request_resource); EXPORT_SYMBOL(macio_release_resource); EXPORT_SYMBOL(macio_request_resources); EXPORT_SYMBOL(macio_release_resources); +EXPORT_SYMBOL(macio_enable_devres); + diff --git a/drivers/macintosh/mediabay.c b/drivers/macintosh/mediabay.c index 029ad8ce8a7e..08002b88f342 100644 --- a/drivers/macintosh/mediabay.c +++ b/drivers/macintosh/mediabay.c @@ -33,15 +33,6 @@ #include <linux/adb.h> #include <linux/pmu.h> - -#define MB_DEBUG - -#ifdef MB_DEBUG -#define MBDBG(fmt, arg...) printk(KERN_INFO fmt , ## arg) -#else -#define MBDBG(fmt, arg...) do { } while (0) -#endif - #define MB_FCR32(bay, r) ((bay)->base + ((r) >> 2)) #define MB_FCR8(bay, r) (((volatile u8 __iomem *)((bay)->base)) + (r)) @@ -76,28 +67,14 @@ struct media_bay_info { int index; int cached_gpio; int sleeping; + int user_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) - int cd_index; -#endif }; #define MAX_BAYS 2 static struct media_bay_info media_bays[MAX_BAYS]; -int media_bay_count = 0; - -#ifdef CONFIG_BLK_DEV_IDE_PMAC -/* check the busy bit in the media-bay ide interface - (assumes the media-bay contains an ide device) */ -#define MB_IDE_READY(i) ((readb(media_bays[i].cd_base + 0x70) & 0x80) == 0) -#endif +static int media_bay_count = 0; /* * Wait that number of ms between each step in normal polling mode @@ -130,21 +107,11 @@ int media_bay_count = 0; /* * Wait this many ticks after an IDE device (e.g. CD-ROM) is inserted - * (or until the device is ready) before waiting for busy bit to disappear + * (or until the device is ready) before calling into the driver */ #define MB_IDE_WAIT 1000 /* - * Timeout waiting for busy bit of an IDE device to go down - */ -#define MB_IDE_TIMEOUT 5000 - -/* - * Max retries of the full power up/down sequence for an IDE device - */ -#define MAX_CD_RETRIES 3 - -/* * States of a media bay */ enum { @@ -153,7 +120,6 @@ enum { mb_enabling_bay, /* enable bits set, waiting MB_RESET_DELAY */ mb_resetting, /* reset bit unset, waiting MB_SETUP_DELAY */ mb_ide_resetting, /* IDE reset bit unser, waiting MB_IDE_WAIT */ - mb_ide_waiting, /* Waiting for BUSY bit to go away until MB_IDE_TIMEOUT */ mb_up, /* Media bay full */ mb_powering_down /* Powering down (avoid too fast down/up) */ }; @@ -373,12 +339,12 @@ static inline void set_mb_power(struct media_bay_info* bay, int onoff) if (onoff) { bay->ops->power(bay, 1); bay->state = mb_powering_up; - MBDBG("mediabay%d: powering up\n", bay->index); + pr_debug("mediabay%d: powering up\n", bay->index); } else { /* Make sure everything is powered down & disabled */ bay->ops->power(bay, 0); bay->state = mb_powering_down; - MBDBG("mediabay%d: powering down\n", bay->index); + pr_debug("mediabay%d: powering down\n", bay->index); } bay->timer = msecs_to_jiffies(MB_POWER_DELAY); } @@ -387,107 +353,118 @@ static void poll_media_bay(struct media_bay_info* bay) { int id = bay->ops->content(bay); - if (id == bay->last_value) { - if (id != bay->content_id) { - bay->value_count += msecs_to_jiffies(MB_POLL_DELAY); - if (bay->value_count >= msecs_to_jiffies(MB_STABLE_DELAY)) { - /* If the device type changes without going thru - * "MB_NO", we force a pass by "MB_NO" to make sure - * things are properly reset - */ - if ((id != MB_NO) && (bay->content_id != MB_NO)) { - id = MB_NO; - MBDBG("mediabay%d: forcing MB_NO\n", bay->index); - } - MBDBG("mediabay%d: switching to %d\n", bay->index, id); - set_mb_power(bay, id != MB_NO); - bay->content_id = id; - if (id == MB_NO) { -#ifdef CONFIG_BLK_DEV_IDE_PMAC - bay->cd_retry = 0; -#endif - printk(KERN_INFO "media bay %d is empty\n", bay->index); - } - } - } - } else { + static char *mb_content_types[] = { + "a floppy drive", + "a floppy drive", + "an unsuported audio device", + "an ATA device", + "an unsupported PCI device", + "an unknown device", + }; + + if (id != bay->last_value) { bay->last_value = id; bay->value_count = 0; + return; + } + if (id == bay->content_id) + return; + + bay->value_count += msecs_to_jiffies(MB_POLL_DELAY); + if (bay->value_count >= msecs_to_jiffies(MB_STABLE_DELAY)) { + /* If the device type changes without going thru + * "MB_NO", we force a pass by "MB_NO" to make sure + * things are properly reset + */ + if ((id != MB_NO) && (bay->content_id != MB_NO)) { + id = MB_NO; + pr_debug("mediabay%d: forcing MB_NO\n", bay->index); + } + pr_debug("mediabay%d: switching to %d\n", bay->index, id); + set_mb_power(bay, id != MB_NO); + bay->content_id = id; + if (id >= MB_NO || id < 0) + printk(KERN_INFO "mediabay%d: Bay is now empty\n", bay->index); + else + printk(KERN_INFO "mediabay%d: Bay contains %s\n", + bay->index, mb_content_types[id]); } } -#ifdef CONFIG_BLK_DEV_IDE_PMAC -int check_media_bay(struct device_node *which_bay, int what) +int check_media_bay(struct macio_dev *baydev) { - int i; + struct media_bay_info* bay; + int id; - for (i=0; i<media_bay_count; i++) - if (media_bays[i].mdev && which_bay == media_bays[i].mdev->ofdev.node) { - if ((what == media_bays[i].content_id) && media_bays[i].state == mb_up) - return 0; - media_bays[i].cd_index = -1; - return -EINVAL; - } - return -ENODEV; + if (baydev == NULL) + return MB_NO; + + /* This returns an instant snapshot, not locking, sine + * we may be called with the bay lock held. The resulting + * fuzzyness of the result if called at the wrong time is + * not actually a huge deal + */ + bay = macio_get_drvdata(baydev); + if (bay == NULL) + return MB_NO; + id = bay->content_id; + if (bay->state != mb_up) + return MB_NO; + if (id == MB_FD1) + return MB_FD; + return id; } -EXPORT_SYMBOL(check_media_bay); +EXPORT_SYMBOL_GPL(check_media_bay); -int check_media_bay_by_base(unsigned long base, int what) +void lock_media_bay(struct macio_dev *baydev) { - int i; - - for (i=0; i<media_bay_count; i++) - if (media_bays[i].mdev && base == (unsigned long) media_bays[i].cd_base) { - if ((what == media_bays[i].content_id) && media_bays[i].state == mb_up) - return 0; - media_bays[i].cd_index = -1; - return -EINVAL; - } + struct media_bay_info* bay; - return -ENODEV; + if (baydev == NULL) + return; + bay = macio_get_drvdata(baydev); + if (bay == NULL) + return; + mutex_lock(&bay->lock); + bay->user_lock = 1; } -EXPORT_SYMBOL_GPL(check_media_bay_by_base); +EXPORT_SYMBOL_GPL(lock_media_bay); -int media_bay_set_ide_infos(struct device_node* which_bay, unsigned long base, - int irq, ide_hwif_t *hwif) +void unlock_media_bay(struct macio_dev *baydev) { - int i; + struct media_bay_info* bay; - for (i=0; i<media_bay_count; i++) { - struct media_bay_info* bay = &media_bays[i]; - - if (bay->mdev && which_bay == bay->mdev->ofdev.node) { - int timeout = 5000, index = hwif->index; - - 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) { - 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; - mutex_unlock(&bay->lock); - return 0; - } - mdelay(1); - } while(--timeout); - printk(KERN_DEBUG "Timeount waiting IDE in bay %d\n", i); - mutex_unlock(&bay->lock); - return -ENODEV; - } + if (baydev == NULL) + return; + bay = macio_get_drvdata(baydev); + if (bay == NULL) + return; + if (bay->user_lock) { + bay->user_lock = 0; + mutex_unlock(&bay->lock); } +} +EXPORT_SYMBOL_GPL(unlock_media_bay); - return -ENODEV; +static int mb_broadcast_hotplug(struct device *dev, void *data) +{ + struct media_bay_info* bay = data; + struct macio_dev *mdev; + struct macio_driver *drv; + int state; + + if (dev->bus != &macio_bus_type) + return 0; + + state = bay->state == mb_up ? bay->content_id : MB_NO; + if (state == MB_FD1) + state = MB_FD; + mdev = to_macio_device(dev); + drv = to_macio_driver(dev->driver); + if (dev->driver && drv->mediabay_event) + drv->mediabay_event(mdev, state); + return 0; } -EXPORT_SYMBOL_GPL(media_bay_set_ide_infos); -#endif /* CONFIG_BLK_DEV_IDE_PMAC */ static void media_bay_step(int i) { @@ -497,8 +474,8 @@ static void media_bay_step(int i) if (bay->state != mb_powering_down) poll_media_bay(bay); - /* If timer expired or polling IDE busy, run state machine */ - if ((bay->state != mb_ide_waiting) && (bay->timer != 0)) { + /* If timer expired run state machine */ + if (bay->timer != 0) { bay->timer -= msecs_to_jiffies(MB_POLL_DELAY); if (bay->timer > 0) return; @@ -508,100 +485,50 @@ static void media_bay_step(int i) switch(bay->state) { case mb_powering_up: if (bay->ops->setup_bus(bay, bay->last_value) < 0) { - MBDBG("mediabay%d: device not supported (kind:%d)\n", i, bay->content_id); + pr_debug("mediabay%d: device not supported (kind:%d)\n", + i, bay->content_id); set_mb_power(bay, 0); break; } bay->timer = msecs_to_jiffies(MB_RESET_DELAY); bay->state = mb_enabling_bay; - MBDBG("mediabay%d: enabling (kind:%d)\n", i, bay->content_id); + pr_debug("mediabay%d: enabling (kind:%d)\n", i, bay->content_id); break; case mb_enabling_bay: bay->ops->un_reset(bay); bay->timer = msecs_to_jiffies(MB_SETUP_DELAY); bay->state = mb_resetting; - MBDBG("mediabay%d: waiting reset (kind:%d)\n", i, bay->content_id); + pr_debug("mediabay%d: releasing bay reset (kind:%d)\n", + i, bay->content_id); break; case mb_resetting: if (bay->content_id != MB_CD) { - MBDBG("mediabay%d: bay is up (kind:%d)\n", i, bay->content_id); + pr_debug("mediabay%d: bay is up (kind:%d)\n", i, + bay->content_id); bay->state = mb_up; + device_for_each_child(&bay->mdev->ofdev.dev, + bay, mb_broadcast_hotplug); break; } -#ifdef CONFIG_BLK_DEV_IDE_PMAC - MBDBG("mediabay%d: waiting IDE reset (kind:%d)\n", i, bay->content_id); + pr_debug("mediabay%d: releasing ATA reset (kind:%d)\n", + i, bay->content_id); bay->ops->un_reset_ide(bay); bay->timer = msecs_to_jiffies(MB_IDE_WAIT); bay->state = mb_ide_resetting; -#else - printk(KERN_DEBUG "media-bay %d is ide (not compiled in kernel)\n", i); - set_mb_power(bay, 0); -#endif /* CONFIG_BLK_DEV_IDE_PMAC */ break; -#ifdef CONFIG_BLK_DEV_IDE_PMAC + case mb_ide_resetting: - bay->timer = msecs_to_jiffies(MB_IDE_TIMEOUT); - bay->state = mb_ide_waiting; - MBDBG("mediabay%d: waiting IDE ready (kind:%d)\n", i, bay->content_id); + pr_debug("mediabay%d: bay is up (kind:%d)\n", i, bay->content_id); + bay->state = mb_up; + device_for_each_child(&bay->mdev->ofdev.dev, + bay, mb_broadcast_hotplug); break; - case mb_ide_waiting: - if (bay->cd_base == NULL) { - bay->timer = 0; - bay->state = mb_up; - MBDBG("mediabay%d: up before IDE init\n", i); - break; - } else if (MB_IDE_READY(i)) { - bay->timer = 0; - bay->state = mb_up; - if (bay->cd_index < 0) { - printk("mediabay %d, registering IDE...\n", i); - pmu_suspend(); - ide_port_scan(bay->cd_port); - if (bay->cd_port->present) - bay->cd_index = bay->cd_port->index; - pmu_resume(); - } - if (bay->cd_index == -1) { - /* We eventually do a retry */ - bay->cd_retry++; - printk("IDE register error\n"); - set_mb_power(bay, 0); - } else { - printk(KERN_DEBUG "media-bay %d is ide%d\n", i, bay->cd_index); - MBDBG("mediabay %d IDE ready\n", i); - } - break; - } else if (bay->timer > 0) - bay->timer -= msecs_to_jiffies(MB_POLL_DELAY); - if (bay->timer <= 0) { - printk("\nIDE Timeout in bay %d !, IDE state is: 0x%02x\n", - i, readb(bay->cd_base + 0x70)); - MBDBG("mediabay%d: nIDE Timeout !\n", i); - set_mb_power(bay, 0); - bay->timer = 0; - } - break; -#endif /* CONFIG_BLK_DEV_IDE_PMAC */ + case mb_powering_down: bay->state = mb_empty; -#ifdef CONFIG_BLK_DEV_IDE_PMAC - if (bay->cd_index >= 0) { - printk(KERN_DEBUG "Unregistering mb %d ide, index:%d\n", i, - bay->cd_index); - ide_port_unregister_devices(bay->cd_port); - bay->cd_index = -1; - } - if (bay->cd_retry) { - if (bay->cd_retry > MAX_CD_RETRIES) { - /* Should add an error sound (sort of beep in dmasound) */ - printk("\nmedia-bay %d, IDE device badly inserted or unrecognised\n", i); - } else { - /* Force a new power down/up sequence */ - bay->content_id = MB_NO; - } - } -#endif /* CONFIG_BLK_DEV_IDE_PMAC */ - MBDBG("mediabay%d: end of power down\n", i); + device_for_each_child(&bay->mdev->ofdev.dev, + bay, mb_broadcast_hotplug); + pr_debug("mediabay%d: end of power down\n", i); break; } } @@ -676,11 +603,6 @@ static int __devinit media_bay_attach(struct macio_dev *mdev, const struct of_de bay->last_value = bay->ops->content(bay); bay->value_count = msecs_to_jiffies(MB_STABLE_DELAY); bay->state = mb_empty; - do { - msleep(MB_POLL_DELAY); - media_bay_step(i); - } while((bay->state != mb_empty) && - (bay->state != mb_up)); /* Mark us ready by filling our mdev data */ macio_set_drvdata(mdev, bay); @@ -725,7 +647,7 @@ static int media_bay_resume(struct macio_dev *mdev) 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); + printk("mediabay%d: Content changed during sleep...\n", bay->index); mutex_unlock(&bay->lock); return 0; } @@ -733,9 +655,6 @@ static int media_bay_resume(struct macio_dev *mdev) bay->last_value = bay->content_id; bay->value_count = msecs_to_jiffies(MB_STABLE_DELAY); bay->timer = msecs_to_jiffies(MB_POWER_DELAY); -#ifdef CONFIG_BLK_DEV_IDE_PMAC - bay->cd_retry = 0; -#endif do { msleep(MB_POLL_DELAY); media_bay_step(bay->index); @@ -823,9 +742,6 @@ static int __init media_bay_init(void) for (i=0; i<MAX_BAYS; i++) { memset((char *)&media_bays[i], 0, sizeof(struct media_bay_info)); media_bays[i].content_id = -1; -#ifdef CONFIG_BLK_DEV_IDE_PMAC - media_bays[i].cd_index = -1; -#endif } if (!machine_is(powermac)) return 0; diff --git a/drivers/macintosh/nvram.c b/drivers/macintosh/nvram.c index b195d753d2ed..c876349c32de 100644 --- a/drivers/macintosh/nvram.c +++ b/drivers/macintosh/nvram.c @@ -13,7 +13,6 @@ #include <linux/fcntl.h> #include <linux/nvram.h> #include <linux/init.h> -#include <linux/smp_lock.h> #include <asm/uaccess.h> #include <asm/nvram.h> @@ -21,7 +20,6 @@ static loff_t nvram_llseek(struct file *file, loff_t offset, int origin) { - lock_kernel(); switch (origin) { case 1: offset += file->f_pos; @@ -30,12 +28,10 @@ static loff_t nvram_llseek(struct file *file, loff_t offset, int origin) offset += NVRAM_SIZE; break; } - if (offset < 0) { - unlock_kernel(); + if (offset < 0) return -EINVAL; - } + file->f_pos = offset; - unlock_kernel(); return file->f_pos; } @@ -76,8 +72,7 @@ static ssize_t write_nvram(struct file *file, const char __user *buf, return p - buf; } -static int nvram_ioctl(struct inode *inode, struct file *file, - unsigned int cmd, unsigned long arg) +static long nvram_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { switch(cmd) { case PMAC_NVRAM_GET_OFFSET: diff --git a/drivers/macintosh/therm_adt746x.c b/drivers/macintosh/therm_adt746x.c index 556f0feaa4df..5ff47ba7f2d0 100644 --- a/drivers/macintosh/therm_adt746x.c +++ b/drivers/macintosh/therm_adt746x.c @@ -79,6 +79,7 @@ struct thermostat { u8 limits[3]; int last_speed[2]; int last_var[2]; + int pwm_inv[2]; }; static enum {ADT7460, ADT7467} therm_type; @@ -229,19 +230,23 @@ static void write_fan_speed(struct thermostat *th, int speed, int fan) if (speed >= 0) { manual = read_reg(th, MANUAL_MODE[fan]); + manual &= ~INVERT_MASK; write_reg(th, MANUAL_MODE[fan], - (manual|MANUAL_MASK) & (~INVERT_MASK)); + manual | MANUAL_MASK | th->pwm_inv[fan]); write_reg(th, FAN_SPD_SET[fan], speed); } else { /* back to automatic */ if(therm_type == ADT7460) { manual = read_reg(th, MANUAL_MODE[fan]) & (~MANUAL_MASK); - + manual &= ~INVERT_MASK; + manual |= th->pwm_inv[fan]; write_reg(th, MANUAL_MODE[fan], manual|REM_CONTROL[fan]); } else { manual = read_reg(th, MANUAL_MODE[fan]); + manual &= ~INVERT_MASK; + manual |= th->pwm_inv[fan]; write_reg(th, MANUAL_MODE[fan], manual&(~AUTO_MASK)); } } @@ -387,7 +392,7 @@ static int probe_thermostat(struct i2c_client *client, i2c_set_clientdata(client, th); th->clt = client; - rc = read_reg(th, 0); + rc = read_reg(th, CONFIG_REG); if (rc < 0) { dev_err(&client->dev, "Thermostat failed to read config!\n"); kfree(th); @@ -418,6 +423,10 @@ static int probe_thermostat(struct i2c_client *client, thermostat = th; + /* record invert bit status because fw can corrupt it after suspend */ + th->pwm_inv[0] = read_reg(th, MANUAL_MODE[0]) & INVERT_MASK; + th->pwm_inv[1] = read_reg(th, MANUAL_MODE[1]) & INVERT_MASK; + /* be sure to really write fan speed the first time */ th->last_speed[0] = -2; th->last_speed[1] = -2; diff --git a/drivers/macintosh/via-pmu.c b/drivers/macintosh/via-pmu.c index 6f308a4757ee..db379c381432 100644 --- a/drivers/macintosh/via-pmu.c +++ b/drivers/macintosh/via-pmu.c @@ -36,6 +36,7 @@ #include <linux/spinlock.h> #include <linux/pm.h> #include <linux/proc_fs.h> +#include <linux/seq_file.h> #include <linux/init.h> #include <linux/interrupt.h> #include <linux/device.h> @@ -186,17 +187,11 @@ static int init_pmu(void); static void pmu_start(void); static irqreturn_t via_pmu_interrupt(int irq, void *arg); static irqreturn_t gpio1_interrupt(int irq, void *arg); -static int proc_get_info(char *page, char **start, off_t off, - int count, int *eof, void *data); -static int proc_get_irqstats(char *page, char **start, off_t off, - int count, int *eof, void *data); +static const struct file_operations pmu_info_proc_fops; +static const struct file_operations pmu_irqstats_proc_fops; static void pmu_pass_intr(unsigned char *data, int len); -static int proc_get_batt(char *page, char **start, off_t off, - int count, int *eof, void *data); -static int proc_read_options(char *page, char **start, off_t off, - int count, int *eof, void *data); -static int proc_write_options(struct file *file, const char __user *buffer, - unsigned long count, void *data); +static const struct file_operations pmu_battery_proc_fops; +static const struct file_operations pmu_options_proc_fops; #ifdef CONFIG_ADB struct adb_driver via_pmu_driver = { @@ -507,19 +502,15 @@ static int __init via_pmu_dev_init(void) for (i=0; i<pmu_battery_count; i++) { char title[16]; sprintf(title, "battery_%ld", i); - proc_pmu_batt[i] = create_proc_read_entry(title, 0, proc_pmu_root, - proc_get_batt, (void *)i); + proc_pmu_batt[i] = proc_create_data(title, 0, proc_pmu_root, + &pmu_battery_proc_fops, (void *)i); } - proc_pmu_info = create_proc_read_entry("info", 0, proc_pmu_root, - proc_get_info, NULL); - proc_pmu_irqstats = create_proc_read_entry("interrupts", 0, proc_pmu_root, - proc_get_irqstats, NULL); - proc_pmu_options = create_proc_entry("options", 0600, proc_pmu_root); - if (proc_pmu_options) { - proc_pmu_options->read_proc = proc_read_options; - proc_pmu_options->write_proc = proc_write_options; - } + proc_pmu_info = proc_create("info", 0, proc_pmu_root, &pmu_info_proc_fops); + proc_pmu_irqstats = proc_create("interrupts", 0, proc_pmu_root, + &pmu_irqstats_proc_fops); + proc_pmu_options = proc_create("options", 0600, proc_pmu_root, + &pmu_options_proc_fops); } return 0; } @@ -799,27 +790,33 @@ query_battery_state(void) 2, PMU_SMART_BATTERY_STATE, pmu_cur_battery+1); } -static int -proc_get_info(char *page, char **start, off_t off, - int count, int *eof, void *data) +static int pmu_info_proc_show(struct seq_file *m, void *v) { - char* p = page; - - p += sprintf(p, "PMU driver version : %d\n", PMU_DRIVER_VERSION); - p += sprintf(p, "PMU firmware version : %02x\n", pmu_version); - p += sprintf(p, "AC Power : %d\n", + seq_printf(m, "PMU driver version : %d\n", PMU_DRIVER_VERSION); + seq_printf(m, "PMU firmware version : %02x\n", pmu_version); + seq_printf(m, "AC Power : %d\n", ((pmu_power_flags & PMU_PWR_AC_PRESENT) != 0) || pmu_battery_count == 0); - p += sprintf(p, "Battery count : %d\n", pmu_battery_count); + seq_printf(m, "Battery count : %d\n", pmu_battery_count); + + return 0; +} - return p - page; +static int pmu_info_proc_open(struct inode *inode, struct file *file) +{ + return single_open(file, pmu_info_proc_show, NULL); } -static int -proc_get_irqstats(char *page, char **start, off_t off, - int count, int *eof, void *data) +static const struct file_operations pmu_info_proc_fops = { + .owner = THIS_MODULE, + .open = pmu_info_proc_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + +static int pmu_irqstats_proc_show(struct seq_file *m, void *v) { int i; - char* p = page; static const char *irq_names[] = { "Total CB1 triggered events", "Total GPIO1 triggered events", @@ -835,60 +832,76 @@ proc_get_irqstats(char *page, char **start, off_t off, }; for (i=0; i<11; i++) { - p += sprintf(p, " %2u: %10u (%s)\n", + seq_printf(m, " %2u: %10u (%s)\n", i, pmu_irq_stats[i], irq_names[i]); } - return p - page; + return 0; } -static int -proc_get_batt(char *page, char **start, off_t off, - int count, int *eof, void *data) +static int pmu_irqstats_proc_open(struct inode *inode, struct file *file) { - long batnum = (long)data; - char *p = page; + return single_open(file, pmu_irqstats_proc_show, NULL); +} + +static const struct file_operations pmu_irqstats_proc_fops = { + .owner = THIS_MODULE, + .open = pmu_irqstats_proc_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + +static int pmu_battery_proc_show(struct seq_file *m, void *v) +{ + long batnum = (long)m->private; - p += sprintf(p, "\n"); - p += sprintf(p, "flags : %08x\n", - pmu_batteries[batnum].flags); - p += sprintf(p, "charge : %d\n", - pmu_batteries[batnum].charge); - p += sprintf(p, "max_charge : %d\n", - pmu_batteries[batnum].max_charge); - p += sprintf(p, "current : %d\n", - pmu_batteries[batnum].amperage); - p += sprintf(p, "voltage : %d\n", - pmu_batteries[batnum].voltage); - p += sprintf(p, "time rem. : %d\n", - pmu_batteries[batnum].time_remaining); - - return p - page; + seq_putc(m, '\n'); + seq_printf(m, "flags : %08x\n", pmu_batteries[batnum].flags); + seq_printf(m, "charge : %d\n", pmu_batteries[batnum].charge); + seq_printf(m, "max_charge : %d\n", pmu_batteries[batnum].max_charge); + seq_printf(m, "current : %d\n", pmu_batteries[batnum].amperage); + seq_printf(m, "voltage : %d\n", pmu_batteries[batnum].voltage); + seq_printf(m, "time rem. : %d\n", pmu_batteries[batnum].time_remaining); + return 0; } -static int -proc_read_options(char *page, char **start, off_t off, - int count, int *eof, void *data) +static int pmu_battery_proc_open(struct inode *inode, struct file *file) { - char *p = page; + return single_open(file, pmu_battery_proc_show, PDE(inode)->data); +} +static const struct file_operations pmu_battery_proc_fops = { + .owner = THIS_MODULE, + .open = pmu_battery_proc_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + +static int pmu_options_proc_show(struct seq_file *m, void *v) +{ #if defined(CONFIG_SUSPEND) && defined(CONFIG_PPC32) if (pmu_kind == PMU_KEYLARGO_BASED && pmac_call_feature(PMAC_FTR_SLEEP_STATE,NULL,0,-1) >= 0) - p += sprintf(p, "lid_wakeup=%d\n", option_lid_wakeup); + seq_printf(m, "lid_wakeup=%d\n", option_lid_wakeup); #endif if (pmu_kind == PMU_KEYLARGO_BASED) - p += sprintf(p, "server_mode=%d\n", option_server_mode); + seq_printf(m, "server_mode=%d\n", option_server_mode); - return p - page; + return 0; } - -static int -proc_write_options(struct file *file, const char __user *buffer, - unsigned long count, void *data) + +static int pmu_options_proc_open(struct inode *inode, struct file *file) +{ + return single_open(file, pmu_options_proc_show, NULL); +} + +static ssize_t pmu_options_proc_write(struct file *file, + const char __user *buffer, size_t count, loff_t *pos) { char tmp[33]; char *label, *val; - unsigned long fcount = count; + size_t fcount = count; if (!count) return -EINVAL; @@ -927,6 +940,15 @@ proc_write_options(struct file *file, const char __user *buffer, return fcount; } +static const struct file_operations pmu_options_proc_fops = { + .owner = THIS_MODULE, + .open = pmu_options_proc_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, + .write = pmu_options_proc_write, +}; + #ifdef CONFIG_ADB /* Send an ADB command */ static int pmu_send_request(struct adb_request *req, int sync) diff --git a/drivers/macintosh/windfarm_smu_controls.c b/drivers/macintosh/windfarm_smu_controls.c index 961fa0e7c2cf..6c68b9e5f5c4 100644 --- a/drivers/macintosh/windfarm_smu_controls.c +++ b/drivers/macintosh/windfarm_smu_controls.c @@ -202,6 +202,8 @@ static struct smu_fan_control *smu_fan_create(struct device_node *node, fct->ctrl.name = "cpu-front-fan-1"; else if (!strcmp(l, "CPU A PUMP")) fct->ctrl.name = "cpu-pump-0"; + else if (!strcmp(l, "CPU B PUMP")) + fct->ctrl.name = "cpu-pump-1"; else if (!strcmp(l, "Slots Fan") || !strcmp(l, "Slots fan") || !strcmp(l, "EXPANSION SLOTS INTAKE")) fct->ctrl.name = "slots-fan"; |