Merge branch 'merge'

This commit is contained in:
Paul Mackerras 2006-08-01 10:37:25 +10:00
commit 57cad8084e
1510 changed files with 22919 additions and 13479 deletions

View file

@ -109,7 +109,7 @@ config PMAC_SMU
config PMAC_APM_EMU
tristate "APM emulation"
depends on PPC_PMAC && PPC32 && PM
depends on PPC_PMAC && PPC32 && PM && ADB_PMU
config PMAC_MEDIABAY
bool "Support PowerBook hotswap media bay"
@ -122,7 +122,8 @@ config PMAC_MEDIABAY
config PMAC_BACKLIGHT
bool "Backlight control for LCD screens"
depends on ADB_PMU && (BROKEN || !PPC64)
depends on ADB_PMU && FB = y && (BROKEN || !PPC64)
select FB_BACKLIGHT
help
Say Y here to enable Macintosh specific extensions of the generic
backlight code. With this enabled, the brightness keys on older

View file

@ -45,14 +45,11 @@
#include <linux/pmu.h>
#include <asm/machdep.h>
#include <asm/backlight.h>
#ifdef CONFIG_PPC_PMAC
#include <asm/pmac_feature.h>
#endif
#ifdef CONFIG_PMAC_BACKLIGHT
#include <asm/backlight.h>
#endif
MODULE_AUTHOR("Franz Sirl <[email protected]>");
#define KEYB_KEYREG 0 /* register # for key up/down data */
@ -237,11 +234,6 @@ static struct adb_ids keyboard_ids;
static struct adb_ids mouse_ids;
static struct adb_ids buttons_ids;
#ifdef CONFIG_PMAC_BACKLIGHT
/* Exported to via-pmu.c */
int disable_kernel_backlight = 0;
#endif /* CONFIG_PMAC_BACKLIGHT */
/* Kind of keyboard, see Apple technote 1152 */
#define ADB_KEYBOARD_UNKNOWN 0
#define ADB_KEYBOARD_ANSI 0x0100
@ -527,7 +519,7 @@ adbhid_buttons_input(unsigned char *data, int nb, struct pt_regs *regs, int auto
case 0xa: /* brightness decrease */
#ifdef CONFIG_PMAC_BACKLIGHT
if (!disable_kernel_backlight && down)
if (down)
pmac_backlight_key_down();
#endif
input_report_key(adbhid[id]->input, KEY_BRIGHTNESSDOWN, down);
@ -535,7 +527,7 @@ adbhid_buttons_input(unsigned char *data, int nb, struct pt_regs *regs, int auto
case 0x9: /* brightness increase */
#ifdef CONFIG_PMAC_BACKLIGHT
if (!disable_kernel_backlight && down)
if (down)
pmac_backlight_key_up();
#endif
input_report_key(adbhid[id]->input, KEY_BRIGHTNESSUP, down);

View file

@ -332,7 +332,7 @@ static void macio_create_fixup_irq(struct macio_dev *dev, int index,
{
unsigned int irq;
irq = irq_create_mapping(NULL, line, 0);
irq = irq_create_mapping(NULL, line);
if (irq != NO_IRQ) {
dev->interrupt[index].start = irq;
dev->interrupt[index].flags = IORESOURCE_IRQ;

View file

@ -75,9 +75,11 @@ struct smu_device {
struct of_device *of_dev;
int doorbell; /* doorbell gpio */
u32 __iomem *db_buf; /* doorbell buffer */
int db_irq;
struct device_node *db_node;
unsigned int db_irq;
int msg;
int msg_irq;
struct device_node *msg_node;
unsigned int msg_irq;
struct smu_cmd_buf *cmd_buf; /* command buffer virtual */
u32 cmd_buf_abs; /* command buffer absolute */
struct list_head cmd_list;
@ -93,6 +95,7 @@ struct smu_device {
*/
static struct smu_device *smu;
static DEFINE_MUTEX(smu_part_access);
static int smu_irq_inited;
static void smu_i2c_retry(unsigned long data);
@ -257,6 +260,10 @@ int smu_queue_cmd(struct smu_cmd *cmd)
smu_start_cmd();
spin_unlock_irqrestore(&smu->lock, flags);
/* Workaround for early calls when irq isn't available */
if (!smu_irq_inited || smu->db_irq == NO_IRQ)
smu_spinwait_cmd(cmd);
return 0;
}
EXPORT_SYMBOL(smu_queue_cmd);
@ -478,14 +485,15 @@ int __init smu_init (void)
smu->cmd_buf_abs = (u32)smu_cmdbuf_abs;
smu->cmd_buf = (struct smu_cmd_buf *)abs_to_virt(smu_cmdbuf_abs);
np = of_find_node_by_name(NULL, "smu-doorbell");
if (np == NULL) {
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;
}
data = get_property(np, "reg", NULL);
data = get_property(smu->db_node, "reg", NULL);
if (data == NULL) {
of_node_put(np);
of_node_put(smu->db_node);
smu->db_node = NULL;
printk(KERN_ERR "SMU: Can't find doorbell GPIO address !\n");
goto fail;
}
@ -497,25 +505,21 @@ int __init smu_init (void)
smu->doorbell = *data;
if (smu->doorbell < 0x50)
smu->doorbell += 0x50;
smu->db_irq = irq_of_parse_and_map(np, 0);
of_node_put(np);
/* Now look for the smu-interrupt GPIO */
do {
np = of_find_node_by_name(NULL, "smu-interrupt");
if (np == NULL)
smu->msg_node = of_find_node_by_name(NULL, "smu-interrupt");
if (smu->msg_node == NULL)
break;
data = get_property(np, "reg", NULL);
data = get_property(smu->msg_node, "reg", NULL);
if (data == NULL) {
of_node_put(np);
of_node_put(smu->msg_node);
smu->msg_node = NULL;
break;
}
smu->msg = *data;
if (smu->msg < 0x50)
smu->msg += 0x50;
smu->msg_irq = irq_of_parse_and_map(np, 0);
of_node_put(np);
} while(0);
/* Doorbell buffer is currently hard-coded, I didn't find a proper
@ -547,6 +551,19 @@ static int smu_late_init(void)
smu->i2c_timer.function = smu_i2c_retry;
smu->i2c_timer.data = (unsigned long)smu;
if (smu->db_node) {
smu->db_irq = irq_of_parse_and_map(smu->db_node, 0);
if (smu->db_irq == NO_IRQ)
printk(KERN_ERR "smu: failed to map irq for node %s\n",
smu->db_node->full_name);
}
if (smu->msg_node) {
smu->msg_irq = irq_of_parse_and_map(smu->msg_node, 0);
if (smu->msg_irq == NO_IRQ)
printk(KERN_ERR "smu: failed to map irq for node %s\n",
smu->msg_node->full_name);
}
/*
* Try to request the interrupts
*/
@ -571,6 +588,7 @@ static int smu_late_init(void)
}
}
smu_irq_inited = 1;
return 0;
}
/* This has to be before arch_initcall as the low i2c stuff relies on the
@ -742,6 +760,11 @@ static void smu_i2c_low_completion(struct smu_cmd *scmd, void *misc)
if (fail && --cmd->retries > 0) {
DPRINTK("SMU: i2c failure, starting timer...\n");
BUG_ON(cmd != smu->cmd_i2c_cur);
if (!smu_irq_inited) {
mdelay(5);
smu_i2c_retry(0);
return;
}
mod_timer(&smu->i2c_timer, jiffies + msecs_to_jiffies(5));
return;
}

View file

@ -15,8 +15,9 @@
#define MAX_PMU_LEVEL 0xFF
static struct device_node *vias;
static struct backlight_properties pmu_backlight_data;
static spinlock_t pmu_backlight_lock;
static int sleeping;
static int pmu_backlight_get_level_brightness(struct fb_info *info,
int level)
@ -40,23 +41,36 @@ static int pmu_backlight_update_status(struct backlight_device *bd)
{
struct fb_info *info = class_get_devdata(&bd->class_dev);
struct adb_request req;
int pmulevel, level = bd->props->brightness;
unsigned long flags;
int level = bd->props->brightness;
if (vias == NULL)
return -ENODEV;
spin_lock_irqsave(&pmu_backlight_lock, flags);
/* Don't update brightness when sleeping */
if (sleeping)
goto out;
if (bd->props->power != FB_BLANK_UNBLANK ||
bd->props->fb_blank != FB_BLANK_UNBLANK)
level = 0;
pmulevel = pmu_backlight_get_level_brightness(info, level);
if (level > 0) {
int pmulevel = pmu_backlight_get_level_brightness(info, level);
pmu_request(&req, NULL, 2, PMU_BACKLIGHT_BRIGHT, pmulevel);
pmu_wait_complete(&req);
pmu_request(&req, NULL, 2, PMU_BACKLIGHT_BRIGHT, pmulevel);
pmu_wait_complete(&req);
pmu_request(&req, NULL, 2, PMU_POWER_CTRL,
PMU_POW_BACKLIGHT | (level > 0 ? PMU_POW_ON : PMU_POW_OFF));
pmu_wait_complete(&req);
pmu_request(&req, NULL, 2, PMU_POWER_CTRL,
PMU_POW_BACKLIGHT | PMU_POW_ON);
pmu_wait_complete(&req);
} else {
pmu_request(&req, NULL, 2, PMU_POWER_CTRL,
PMU_POW_BACKLIGHT | PMU_POW_OFF);
pmu_wait_complete(&req);
}
out:
spin_unlock_irqrestore(&pmu_backlight_lock, flags);
return 0;
}
@ -73,15 +87,39 @@ static struct backlight_properties pmu_backlight_data = {
.max_brightness = (FB_BACKLIGHT_LEVELS - 1),
};
void __init pmu_backlight_init(struct device_node *in_vias)
#ifdef CONFIG_PM
static int pmu_backlight_sleep_call(struct pmu_sleep_notifier *self, int when)
{
unsigned long flags;
spin_lock_irqsave(&pmu_backlight_lock, flags);
switch (when) {
case PBOOK_SLEEP_REQUEST:
sleeping = 1;
break;
case PBOOK_WAKE:
sleeping = 0;
break;
}
spin_unlock_irqrestore(&pmu_backlight_lock, flags);
return PBOOK_SLEEP_OK;
}
static struct pmu_sleep_notifier pmu_backlight_sleep_notif = {
.notifier_call = pmu_backlight_sleep_call,
};
#endif
void __init pmu_backlight_init()
{
struct backlight_device *bd;
struct fb_info *info;
char name[10];
int level, autosave;
vias = in_vias;
/* Special case for the old PowerBook since I can't test on it */
autosave =
machine_is_compatible("AAPL,3400/2400") ||
@ -141,6 +179,10 @@ void __init pmu_backlight_init(struct device_node *in_vias)
pmac_backlight = bd;
mutex_unlock(&pmac_backlight_mutex);
#ifdef CONFIG_PM
pmu_register_sleep_notifier(&pmu_backlight_sleep_notif);
#endif
printk("pmubl: Backlight initialized (%s)\n", name);
return;

View file

@ -16,7 +16,6 @@
* a sleep or a freq. switch
* - Move sleep code out of here to pmac_pm, merge into new
* common PM infrastructure
* - Move backlight code out as well
* - Save/Restore PCI space properly
*
*/
@ -60,9 +59,7 @@
#include <asm/mmu_context.h>
#include <asm/cputable.h>
#include <asm/time.h>
#ifdef CONFIG_PMAC_BACKLIGHT
#include <asm/backlight.h>
#endif
#include "via-pmu-event.h"
@ -177,10 +174,6 @@ static int query_batt_timer = BATTERY_POLLING_COUNT;
static struct adb_request batt_req;
static struct proc_dir_entry *proc_pmu_batt[PMU_MAX_BATTERIES];
#if defined(CONFIG_INPUT_ADBHID) && defined(CONFIG_PMAC_BACKLIGHT)
extern int disable_kernel_backlight;
#endif /* defined(CONFIG_INPUT_ADBHID) && defined(CONFIG_PMAC_BACKLIGHT) */
int __fake_sleep;
int asleep;
BLOCKING_NOTIFIER_HEAD(sleep_notifier_list);
@ -466,7 +459,7 @@ static int __init via_pmu_dev_init(void)
#ifdef CONFIG_PMAC_BACKLIGHT
/* Initialize backlight */
pmu_backlight_init(vias);
pmu_backlight_init();
#endif
#ifdef CONFIG_PPC32
@ -1403,11 +1396,8 @@ next:
else if ((1 << pirq) & PMU_INT_SNDBRT) {
#ifdef CONFIG_PMAC_BACKLIGHT
if (len == 3)
#ifdef CONFIG_INPUT_ADBHID
if (!disable_kernel_backlight)
#endif /* CONFIG_INPUT_ADBHID */
pmac_backlight_set_legacy_brightness(data[1] >> 4);
#endif /* CONFIG_PMAC_BACKLIGHT */
pmac_backlight_set_legacy_brightness_pmu(data[1] >> 4);
#endif
}
/* Tick interrupt */
else if ((1 << pirq) & PMU_INT_TICK) {
@ -2414,7 +2404,7 @@ struct pmu_private {
spinlock_t lock;
#if defined(CONFIG_INPUT_ADBHID) && defined(CONFIG_PMAC_BACKLIGHT)
int backlight_locker;
#endif /* defined(CONFIG_INPUT_ADBHID) && defined(CONFIG_PMAC_BACKLIGHT) */
#endif
};
static LIST_HEAD(all_pmu_pvt);
@ -2464,7 +2454,7 @@ pmu_open(struct inode *inode, struct file *file)
spin_lock_irqsave(&all_pvt_lock, flags);
#if defined(CONFIG_INPUT_ADBHID) && defined(CONFIG_PMAC_BACKLIGHT)
pp->backlight_locker = 0;
#endif /* defined(CONFIG_INPUT_ADBHID) && defined(CONFIG_PMAC_BACKLIGHT) */
#endif
list_add(&pp->list, &all_pmu_pvt);
spin_unlock_irqrestore(&all_pvt_lock, flags);
file->private_data = pp;
@ -2559,13 +2549,12 @@ pmu_release(struct inode *inode, struct file *file)
spin_lock_irqsave(&all_pvt_lock, flags);
list_del(&pp->list);
spin_unlock_irqrestore(&all_pvt_lock, flags);
#if defined(CONFIG_INPUT_ADBHID) && defined(CONFIG_PMAC_BACKLIGHT)
if (pp->backlight_locker) {
spin_lock_irqsave(&pmu_lock, flags);
disable_kernel_backlight--;
spin_unlock_irqrestore(&pmu_lock, flags);
}
#endif /* defined(CONFIG_INPUT_ADBHID) && defined(CONFIG_PMAC_BACKLIGHT) */
if (pp->backlight_locker)
pmac_backlight_enable();
#endif
kfree(pp);
}
unlock_kernel();
@ -2642,18 +2631,18 @@ pmu_ioctl(struct inode * inode, struct file *filp,
#ifdef CONFIG_INPUT_ADBHID
case PMU_IOC_GRAB_BACKLIGHT: {
struct pmu_private *pp = filp->private_data;
unsigned long flags;
if (pp->backlight_locker)
return 0;
pp->backlight_locker = 1;
spin_lock_irqsave(&pmu_lock, flags);
disable_kernel_backlight++;
spin_unlock_irqrestore(&pmu_lock, flags);
pmac_backlight_disable();
return 0;
}
#endif /* CONFIG_INPUT_ADBHID */
#endif /* CONFIG_PMAC_BACKLIGHT_LEGACY */
case PMU_IOC_GET_MODEL:
return put_user(pmu_kind, argp);
case PMU_IOC_HAS_ADB: