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 ...
This commit is contained in:
@@ -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);
|
||||
|
||||
|
@@ -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,20 +107,10 @@ 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
|
||||
*/
|
||||
@@ -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;
|
||||
struct media_bay_info* bay;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
return -ENODEV;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(media_bay_set_ide_infos);
|
||||
#endif /* CONFIG_BLK_DEV_IDE_PMAC */
|
||||
EXPORT_SYMBOL_GPL(unlock_media_bay);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
|
@@ -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:
|
||||
|
@@ -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;
|
||||
|
@@ -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 p - page;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
proc_get_irqstats(char *page, char **start, off_t off,
|
||||
int count, int *eof, void *data)
|
||||
static int pmu_info_proc_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
return single_open(file, pmu_info_proc_show, NULL);
|
||||
}
|
||||
|
||||
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)
|
||||
|
@@ -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";
|
||||
|
Reference in New Issue
Block a user