diff options
Diffstat (limited to 'arch/arm')
89 files changed, 1570 insertions, 1762 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 4b15f5f1e25..16a5d522b2f 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -154,6 +154,7 @@ config ARCH_RPC select FIQ select TIMER_ACORN select ARCH_MAY_HAVE_PC_FDC + select ISA_DMA_API help On the Acorn Risc-PC, Linux can support the internal IDE disk and CD-ROM interface, serial and parallel port, and the floppy drive. @@ -206,6 +207,7 @@ config ARCH_IMX config ARCH_H720X bool "Hynix-HMS720x-based" + select ISA_DMA_API help This enables support for systems based on the Hynix HMS720x @@ -290,12 +292,14 @@ config ISA (MCA) or VESA. ISA is an older system, now being displaced by PCI; newer boards don't support it. If you have ISA, say Y, otherwise N. +# Select ISA DMA controller support config ISA_DMA bool + select ISA_DMA_API +# Select ISA DMA interface config ISA_DMA_API bool - default y config PCI bool "PCI support" if ARCH_INTEGRATOR_AP || ARCH_VERSATILE_PB @@ -656,7 +660,6 @@ source "kernel/power/Kconfig" config APM tristate "Advanced Power Management Emulation" - depends on PM_LEGACY ---help--- APM is a BIOS specification for saving power using several different techniques. This is mostly useful for battery powered laptops with diff --git a/arch/arm/Makefile b/arch/arm/Makefile index 81bd2193fe6..afaf3a1e903 100644 --- a/arch/arm/Makefile +++ b/arch/arm/Makefile @@ -8,7 +8,7 @@ # Copyright (C) 1995-2001 by Russell King LDFLAGS_vmlinux :=-p --no-undefined -X -CPPFLAGS_vmlinux.lds = -DKERNEL_RAM_ADDR=$(TEXTADDR) +CPPFLAGS_vmlinux.lds = -DTEXT_OFFSET=$(TEXT_OFFSET) OBJCOPYFLAGS :=-O binary -R .note -R .comment -S GZFLAGS :=-9 #CFLAGS +=-pipe @@ -65,7 +65,7 @@ CHECKFLAGS += -D__arm__ #Default value head-y := arch/arm/kernel/head.o arch/arm/kernel/init_task.o -textaddr-y := 0xC0008000 +textofs-y := 0x00008000 machine-$(CONFIG_ARCH_RPC) := rpc machine-$(CONFIG_ARCH_EBSA110) := ebsa110 @@ -73,22 +73,20 @@ textaddr-y := 0xC0008000 incdir-$(CONFIG_ARCH_CLPS7500) := cl7500 machine-$(CONFIG_FOOTBRIDGE) := footbridge incdir-$(CONFIG_FOOTBRIDGE) := ebsa285 -textaddr-$(CONFIG_ARCH_CO285) := 0x60008000 machine-$(CONFIG_ARCH_CO285) := footbridge incdir-$(CONFIG_ARCH_CO285) := ebsa285 machine-$(CONFIG_ARCH_SHARK) := shark machine-$(CONFIG_ARCH_SA1100) := sa1100 ifeq ($(CONFIG_ARCH_SA1100),y) # SA1111 DMA bug: we don't want the kernel to live in precious DMA-able memory -textaddr-$(CONFIG_SA1111) := 0xc0208000 + textofs-$(CONFIG_SA1111) := 0x00208000 endif machine-$(CONFIG_ARCH_PXA) := pxa machine-$(CONFIG_ARCH_L7200) := l7200 machine-$(CONFIG_ARCH_INTEGRATOR) := integrator machine-$(CONFIG_ARCH_CAMELOT) := epxa10db -textaddr-$(CONFIG_ARCH_CLPS711X) := 0xc0028000 + textofs-$(CONFIG_ARCH_CLPS711X) := 0x00028000 machine-$(CONFIG_ARCH_CLPS711X) := clps711x -textaddr-$(CONFIG_ARCH_FORTUNET) := 0xc0008000 machine-$(CONFIG_ARCH_IOP3XX) := iop3xx machine-$(CONFIG_ARCH_IXP4XX) := ixp4xx machine-$(CONFIG_ARCH_IXP2000) := ixp2000 @@ -110,7 +108,8 @@ CFLAGS_3c589_cs.o :=-DISA_SIXTEEN_BIT_PERIPHERAL export CFLAGS_3c589_cs.o endif -TEXTADDR := $(textaddr-y) +# The byte offset of the kernel image in RAM from the start of RAM. +TEXT_OFFSET := $(textofs-y) ifeq ($(incdir-y),) incdir-y := $(machine-y) @@ -123,7 +122,7 @@ else MACHINE := endif -export TEXTADDR GZFLAGS +export TEXT_OFFSET GZFLAGS # Do we have FASTFPE? FASTFPE :=arch/arm/fastfpe diff --git a/arch/arm/boot/Makefile b/arch/arm/boot/Makefile index 937a353bc37..a174d63395e 100644 --- a/arch/arm/boot/Makefile +++ b/arch/arm/boot/Makefile @@ -15,7 +15,7 @@ include $(srctree)/$(MACHINE)/Makefile.boot endif # Note: the following conditions must always be true: -# ZRELADDR == virt_to_phys(TEXTADDR) +# ZRELADDR == virt_to_phys(PAGE_OFFSET + TEXT_OFFSET) # PARAMS_PHYS must be within 4MB of ZRELADDR # INITRD_PHYS must be in RAM ZRELADDR := $(zreladdr-y) diff --git a/arch/arm/common/Kconfig b/arch/arm/common/Kconfig index 666ba393575..d7509c7a3c5 100644 --- a/arch/arm/common/Kconfig +++ b/arch/arm/common/Kconfig @@ -23,5 +23,8 @@ config SHARP_LOCOMO config SHARP_PARAM bool +config SHARPSL_PM + bool + config SHARP_SCOOP bool diff --git a/arch/arm/common/Makefile b/arch/arm/common/Makefile index a87886564b1..ec8d17c9690 100644 --- a/arch/arm/common/Makefile +++ b/arch/arm/common/Makefile @@ -3,7 +3,6 @@ # obj-y += rtctime.o -obj-$(CONFIG_ARM_AMBA) += amba.o obj-$(CONFIG_ARM_GIC) += gic.o obj-$(CONFIG_ICST525) += icst525.o obj-$(CONFIG_ICST307) += icst307.o @@ -13,4 +12,5 @@ obj-$(CONFIG_DMABOUNCE) += dmabounce.o obj-$(CONFIG_TIMER_ACORN) += time-acorn.o obj-$(CONFIG_SHARP_LOCOMO) += locomo.o obj-$(CONFIG_SHARP_PARAM) += sharpsl_param.o +obj-$(CONFIG_SHARPSL_PM) += sharpsl_pm.o obj-$(CONFIG_SHARP_SCOOP) += scoop.o diff --git a/arch/arm/common/amba.c b/arch/arm/common/amba.c deleted file mode 100644 index c95ec9eab99..00000000000 --- a/arch/arm/common/amba.c +++ /dev/null @@ -1,359 +0,0 @@ -/* - * linux/arch/arm/common/amba.c - * - * Copyright (C) 2003 Deep Blue Solutions Ltd, All Rights Reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#include <linux/module.h> -#include <linux/init.h> -#include <linux/device.h> -#include <linux/string.h> -#include <linux/slab.h> - -#include <asm/io.h> -#include <asm/irq.h> -#include <asm/hardware/amba.h> -#include <asm/sizes.h> - -#define to_amba_device(d) container_of(d, struct amba_device, dev) -#define to_amba_driver(d) container_of(d, struct amba_driver, drv) - -static struct amba_id * -amba_lookup(struct amba_id *table, struct amba_device *dev) -{ - int ret = 0; - - while (table->mask) { - ret = (dev->periphid & table->mask) == table->id; - if (ret) - break; - table++; - } - - return ret ? table : NULL; -} - -static int amba_match(struct device *dev, struct device_driver *drv) -{ - struct amba_device *pcdev = to_amba_device(dev); - struct amba_driver *pcdrv = to_amba_driver(drv); - - return amba_lookup(pcdrv->id_table, pcdev) != NULL; -} - -#ifdef CONFIG_HOTPLUG -static int amba_uevent(struct device *dev, char **envp, int nr_env, char *buf, int bufsz) -{ - struct amba_device *pcdev = to_amba_device(dev); - - if (nr_env < 2) - return -ENOMEM; - - snprintf(buf, bufsz, "AMBA_ID=%08x", pcdev->periphid); - *envp++ = buf; - *envp++ = NULL; - return 0; -} -#else -#define amba_uevent NULL -#endif - -static int amba_suspend(struct device *dev, pm_message_t state) -{ - struct amba_driver *drv = to_amba_driver(dev->driver); - int ret = 0; - - if (dev->driver && drv->suspend) - ret = drv->suspend(to_amba_device(dev), state); - return ret; -} - -static int amba_resume(struct device *dev) -{ - struct amba_driver *drv = to_amba_driver(dev->driver); - int ret = 0; - - if (dev->driver && drv->resume) - ret = drv->resume(to_amba_device(dev)); - return ret; -} - -/* - * Primecells are part of the Advanced Microcontroller Bus Architecture, - * so we call the bus "amba". - */ -static struct bus_type amba_bustype = { - .name = "amba", - .match = amba_match, - .uevent = amba_uevent, - .suspend = amba_suspend, - .resume = amba_resume, -}; - -static int __init amba_init(void) -{ - return bus_register(&amba_bustype); -} - -postcore_initcall(amba_init); - -/* - * These are the device model conversion veneers; they convert the - * device model structures to our more specific structures. - */ -static int amba_probe(struct device *dev) -{ - struct amba_device *pcdev = to_amba_device(dev); - struct amba_driver *pcdrv = to_amba_driver(dev->driver); - struct amba_id *id; - - id = amba_lookup(pcdrv->id_table, pcdev); - - return pcdrv->probe(pcdev, id); -} - -static int amba_remove(struct device *dev) -{ - struct amba_driver *drv = to_amba_driver(dev->driver); - return drv->remove(to_amba_device(dev)); -} - -static void amba_shutdown(struct device *dev) -{ - struct amba_driver *drv = to_amba_driver(dev->driver); - drv->shutdown(to_amba_device(dev)); -} - -/** - * amba_driver_register - register an AMBA device driver - * @drv: amba device driver structure - * - * Register an AMBA device driver with the Linux device model - * core. If devices pre-exist, the drivers probe function will - * be called. - */ -int amba_driver_register(struct amba_driver *drv) -{ - drv->drv.bus = &amba_bustype; - -#define SETFN(fn) if (drv->fn) drv->drv.fn = amba_##fn - SETFN(probe); - SETFN(remove); - SETFN(shutdown); - - return driver_register(&drv->drv); -} - -/** - * amba_driver_unregister - remove an AMBA device driver - * @drv: AMBA device driver structure to remove - * - * Unregister an AMBA device driver from the Linux device - * model. The device model will call the drivers remove function - * for each device the device driver is currently handling. - */ -void amba_driver_unregister(struct amba_driver *drv) -{ - driver_unregister(&drv->drv); -} - - -static void amba_device_release(struct device *dev) -{ - struct amba_device *d = to_amba_device(dev); - - if (d->res.parent) - release_resource(&d->res); - kfree(d); -} - -#define amba_attr(name,fmt,arg...) \ -static ssize_t show_##name(struct device *_dev, struct device_attribute *attr, char *buf) \ -{ \ - struct amba_device *dev = to_amba_device(_dev); \ - return sprintf(buf, fmt, arg); \ -} \ -static DEVICE_ATTR(name, S_IRUGO, show_##name, NULL) - -amba_attr(id, "%08x\n", dev->periphid); -amba_attr(irq0, "%u\n", dev->irq[0]); -amba_attr(irq1, "%u\n", dev->irq[1]); -amba_attr(resource, "\t%08lx\t%08lx\t%08lx\n", - dev->res.start, dev->res.end, dev->res.flags); - -/** - * amba_device_register - register an AMBA device - * @dev: AMBA device to register - * @parent: parent memory resource - * - * Setup the AMBA device, reading the cell ID if present. - * Claim the resource, and register the AMBA device with - * the Linux device manager. - */ -int amba_device_register(struct amba_device *dev, struct resource *parent) -{ - u32 pid, cid; - void __iomem *tmp; - int i, ret; - - dev->dev.release = amba_device_release; - dev->dev.bus = &amba_bustype; - dev->dev.dma_mask = &dev->dma_mask; - dev->res.name = dev->dev.bus_id; - - if (!dev->dev.coherent_dma_mask && dev->dma_mask) - dev_warn(&dev->dev, "coherent dma mask is unset\n"); - - ret = request_resource(parent, &dev->res); - if (ret == 0) { - tmp = ioremap(dev->res.start, SZ_4K); - if (!tmp) { - ret = -ENOMEM; - goto out; - } - - for (pid = 0, i = 0; i < 4; i++) - pid |= (readl(tmp + 0xfe0 + 4 * i) & 255) << (i * 8); - for (cid = 0, i = 0; i < 4; i++) - cid |= (readl(tmp + 0xff0 + 4 * i) & 255) << (i * 8); - - iounmap(tmp); - - if (cid == 0xb105f00d) - dev->periphid = pid; - - if (dev->periphid) - ret = device_register(&dev->dev); - else - ret = -ENODEV; - - if (ret == 0) { - device_create_file(&dev->dev, &dev_attr_id); - if (dev->irq[0] != NO_IRQ) - device_create_file(&dev->dev, &dev_attr_irq0); - if (dev->irq[1] != NO_IRQ) - device_create_file(&dev->dev, &dev_attr_irq1); - device_create_file(&dev->dev, &dev_attr_resource); - } else { - out: - release_resource(&dev->res); - } - } - return ret; -} - -/** - * amba_device_unregister - unregister an AMBA device - * @dev: AMBA device to remove - * - * Remove the specified AMBA device from the Linux device - * manager. All files associated with this object will be - * destroyed, and device drivers notified that the device has - * been removed. The AMBA device's resources including - * the amba_device structure will be freed once all - * references to it have been dropped. - */ -void amba_device_unregister(struct amba_device *dev) -{ - device_unregister(&dev->dev); -} - - -struct find_data { - struct amba_device *dev; - struct device *parent; - const char *busid; - unsigned int id; - unsigned int mask; -}; - -static int amba_find_match(struct device *dev, void *data) -{ - struct find_data *d = data; - struct amba_device *pcdev = to_amba_device(dev); - int r; - - r = (pcdev->periphid & d->mask) == d->id; - if (d->parent) - r &= d->parent == dev->parent; - if (d->busid) - r &= strcmp(dev->bus_id, d->busid) == 0; - - if (r) { - get_device(dev); - d->dev = pcdev; - } - - return r; -} - -/** - * amba_find_device - locate an AMBA device given a bus id - * @busid: bus id for device (or NULL) - * @parent: parent device (or NULL) - * @id: peripheral ID (or 0) - * @mask: peripheral ID mask (or 0) - * - * Return the AMBA device corresponding to the supplied parameters. - * If no device matches, returns NULL. - * - * NOTE: When a valid device is found, its refcount is - * incremented, and must be decremented before the returned - * reference. - */ -struct amba_device * -amba_find_device(const char *busid, struct device *parent, unsigned int id, - unsigned int mask) -{ - struct find_data data; - - data.dev = NULL; - data.parent = parent; - data.busid = busid; - data.id = id; - data.mask = mask; - - bus_for_each_dev(&amba_bustype, NULL, &data, amba_find_match); - - return data.dev; -} - -/** - * amba_request_regions - request all mem regions associated with device - * @dev: amba_device structure for device - * @name: name, or NULL to use driver name - */ -int amba_request_regions(struct amba_device *dev, const char *name) -{ - int ret = 0; - - if (!name) - name = dev->dev.driver->name; - - if (!request_mem_region(dev->res.start, SZ_4K, name)) - ret = -EBUSY; - - return ret; -} - -/** - * amba_release_regions - release mem regions assoicated with device - * @dev: amba_device structure for device - * - * Release regions claimed by a successful call to amba_request_regions. - */ -void amba_release_regions(struct amba_device *dev) -{ - release_mem_region(dev->res.start, SZ_4K); -} - -EXPORT_SYMBOL(amba_driver_register); -EXPORT_SYMBOL(amba_driver_unregister); -EXPORT_SYMBOL(amba_device_register); -EXPORT_SYMBOL(amba_device_unregister); -EXPORT_SYMBOL(amba_find_device); -EXPORT_SYMBOL(amba_request_regions); -EXPORT_SYMBOL(amba_release_regions); diff --git a/arch/arm/common/scoop.c b/arch/arm/common/scoop.c index 0c3cbd9a388..b6de43e7369 100644 --- a/arch/arm/common/scoop.c +++ b/arch/arm/common/scoop.c @@ -33,7 +33,6 @@ void reset_scoop(struct device *dev) SCOOP_REG(sdev->base,SCOOP_MCR) = 0x0100; // 00 SCOOP_REG(sdev->base,SCOOP_CDR) = 0x0000; // 04 - SCOOP_REG(sdev->base,SCOOP_CPR) = 0x0000; // 0C SCOOP_REG(sdev->base,SCOOP_CCR) = 0x0000; // 10 SCOOP_REG(sdev->base,SCOOP_IMR) = 0x0000; // 18 SCOOP_REG(sdev->base,SCOOP_IRM) = 0x00FF; // 14 @@ -154,6 +153,7 @@ int __init scoop_probe(struct platform_device *pdev) SCOOP_REG(devptr->base, SCOOP_MCR) = 0x0140; reset_scoop(&pdev->dev); + SCOOP_REG(devptr->base, SCOOP_CPR) = 0x0000; SCOOP_REG(devptr->base, SCOOP_GPCR) = inf->io_dir & 0xffff; SCOOP_REG(devptr->base, SCOOP_GPWR) = inf->io_out & 0xffff; diff --git a/arch/arm/common/sharpsl_pm.c b/arch/arm/common/sharpsl_pm.c new file mode 100644 index 00000000000..978d32e82d3 --- /dev/null +++ b/arch/arm/common/sharpsl_pm.c @@ -0,0 +1,839 @@ +/* + * Battery and Power Management code for the Sharp SL-C7xx and SL-Cxx00 + * series of PDAs + * + * Copyright (c) 2004-2005 Richard Purdie + * + * Based on code written by Sharp for 2.4 kernels + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + */ + +#undef DEBUG + +#include <linux/module.h> +#include <linux/timer.h> +#include <linux/init.h> +#include <linux/kernel.h> +#include <linux/apm_bios.h> +#include <linux/delay.h> +#include <linux/interrupt.h> +#include <linux/platform_device.h> + +#include <asm/hardware.h> +#include <asm/mach-types.h> +#include <asm/irq.h> +#include <asm/apm.h> +#include <asm/arch/pm.h> +#include <asm/arch/pxa-regs.h> +#include <asm/arch/sharpsl.h> +#include <asm/hardware/sharpsl_pm.h> + +/* + * Constants + */ +#define SHARPSL_CHARGE_ON_TIME_INTERVAL (msecs_to_jiffies(1*60*1000)) /* 1 min */ +#define SHARPSL_CHARGE_FINISH_TIME (msecs_to_jiffies(10*60*1000)) /* 10 min */ +#define SHARPSL_BATCHK_TIME (msecs_to_jiffies(15*1000)) /* 15 sec */ +#define SHARPSL_BATCHK_TIME_SUSPEND (60*10) /* 10 min */ +#define SHARPSL_WAIT_CO_TIME 15 /* 15 sec */ +#define SHARPSL_WAIT_DISCHARGE_ON 100 /* 100 msec */ +#define SHARPSL_CHECK_BATTERY_WAIT_TIME_TEMP 10 /* 10 msec */ +#define SHARPSL_CHECK_BATTERY_WAIT_TIME_VOLT 10 /* 10 msec */ +#define SHARPSL_CHECK_BATTERY_WAIT_TIME_ACIN 10 /* 10 msec */ +#define SHARPSL_CHARGE_WAIT_TIME 15 /* 15 msec */ +#define SHARPSL_CHARGE_CO_CHECK_TIME 5 /* 5 msec */ +#define SHARPSL_CHARGE_RETRY_CNT 1 /* eqv. 10 min */ + +#define SHARPSL_CHARGE_ON_VOLT 0x99 /* 2.9V */ +#define SHARPSL_CHARGE_ON_TEMP 0xe0 /* 2.9V */ +#define SHARPSL_CHARGE_ON_ACIN_HIGH 0x9b /* 6V */ +#define SHARPSL_CHARGE_ON_ACIN_LOW 0x34 /* 2V */ +#define SHARPSL_FATAL_ACIN_VOLT 182 /* 3.45V */ +#define SHARPSL_FATAL_NOACIN_VOLT 170 /* 3.40V */ + +/* + * Prototypes + */ +static int sharpsl_off_charge_battery(void); +static int sharpsl_check_battery_temp(void); +static int sharpsl_check_battery_voltage(void); +static int sharpsl_ac_check(void); +static int sharpsl_fatal_check(void); +static int sharpsl_average_value(int ad); +static void sharpsl_average_clear(void); +static void sharpsl_charge_toggle(void *private_); +static void sharpsl_battery_thread(void *private_); + + +/* + * Variables + */ +struct sharpsl_pm_status sharpsl_pm; +DECLARE_WORK(toggle_charger, sharpsl_charge_toggle, NULL); +DECLARE_WORK(sharpsl_bat, sharpsl_battery_thread, NULL); + + +static int get_percentage(int voltage) +{ + int i = sharpsl_pm.machinfo->bat_levels - 1; + struct battery_thresh *thresh; + + if (sharpsl_pm.charge_mode == CHRG_ON) + thresh=sharpsl_pm.machinfo->bat_levels_acin; + else + thresh=sharpsl_pm.machinfo->bat_levels_noac; + + while (i > 0 && (voltage > thresh[i].voltage)) + i--; + + return thresh[i].percentage; +} + +static int get_apm_status(int voltage) +{ + int low_thresh, high_thresh; + + if (sharpsl_pm.charge_mode == CHRG_ON) { + high_thresh = sharpsl_pm.machinfo->status_high_acin; + low_thresh = sharpsl_pm.machinfo->status_low_acin; + } else { + high_thresh = sharpsl_pm.machinfo->status_high_noac; + low_thresh = sharpsl_pm.machinfo->status_low_noac; + } + + if (voltage >= high_thresh) + return APM_BATTERY_STATUS_HIGH; + if (voltage >= low_thresh) + return APM_BATTERY_STATUS_LOW; + return APM_BATTERY_STATUS_CRITICAL; +} + +void sharpsl_battery_kick(void) +{ + schedule_delayed_work(&sharpsl_bat, msecs_to_jiffies(125)); +} +EXPORT_SYMBOL(sharpsl_battery_kick); + + +static void sharpsl_battery_thread(void *private_) +{ + int voltage, percent, apm_status, i = 0; + + if (!sharpsl_pm.machinfo) + return; + + sharpsl_pm.battstat.ac_status = (sharpsl_pm.machinfo->read_devdata(SHARPSL_STATUS_ACIN) ? APM_AC_ONLINE : APM_AC_OFFLINE); + + /* Corgi cannot confirm when battery fully charged so periodically kick! */ + if (machine_is_corgi() && (sharpsl_pm.charge_mode == CHRG_ON) + && time_after(jiffies, sharpsl_pm.charge_start_time + SHARPSL_CHARGE_ON_TIME_INTERVAL)) + schedule_work(&toggle_charger); + + while(1) { + voltage = sharpsl_pm.machinfo->read_devdata(SHARPSL_BATT_VOLT); + + if (voltage > 0) break; + if (i++ > 5) { + voltage = sharpsl_pm.machinfo->bat_levels_noac[0].voltage; + dev_warn(sharpsl_pm.dev, "Warning: Cannot read main battery!\n"); + break; + } + } + + voltage = sharpsl_average_value(voltage); + apm_status = get_apm_status(voltage); + percent = get_percentage(voltage); + + /* At low battery voltages, the voltage has a tendency to start + creeping back up so we try to avoid this here */ + if ((sharpsl_pm.battstat.ac_status == APM_AC_ONLINE) || (apm_status == APM_BATTERY_STATUS_HIGH) || percent <= sharpsl_pm.battstat.mainbat_percent) { + sharpsl_pm.battstat.mainbat_voltage = voltage; + sharpsl_pm.battstat.mainbat_status = apm_status; + sharpsl_pm.battstat.mainbat_percent = percent; + } + + dev_dbg(sharpsl_pm.dev, "Battery: voltage: %d, status: %d, percentage: %d, time: %d\n", voltage, + sharpsl_pm.battstat.mainbat_status, sharpsl_pm.battstat.mainbat_percent, jiffies); + + /* If battery is low. limit backlight intensity to save power. */ + if ((sharpsl_pm.battstat.ac_status != APM_AC_ONLINE) + && ((sharpsl_pm.battstat.mainbat_status == APM_BATTERY_STATUS_LOW) || + (sharpsl_pm.battstat.mainbat_status == APM_BATTERY_STATUS_CRITICAL))) { + if (!(sharpsl_pm.flags & SHARPSL_BL_LIMIT)) { + corgibl_limit_intensity(1); + sharpsl_pm.flags |= SHARPSL_BL_LIMIT; + } + } else if (sharpsl_pm.flags & SHARPSL_BL_LIMIT) { + corgibl_limit_intensity(0); + sharpsl_pm.flags &= ~SHARPSL_BL_LIMIT; + } + + /* Suspend if critical battery level */ + if ((sharpsl_pm.battstat.ac_status != APM_AC_ONLINE) + && (sharpsl_pm.battstat.mainbat_status == APM_BATTERY_STATUS_CRITICAL) + && !(sharpsl_pm.flags & SHARPSL_APM_QUEUED)) { + sharpsl_pm.flags |= SHARPSL_APM_QUEUED; + dev_err(sharpsl_pm.dev, "Fatal Off\n"); + apm_queue_event(APM_CRITICAL_SUSPEND); + } + + schedule_delayed_work(&sharpsl_bat, SHARPSL_BATCHK_TIME); +} + +void sharpsl_pm_led(int val) +{ + if (val == SHARPSL_LED_ERROR) { + dev_err(sharpsl_pm.dev, "Charging Error!\n"); + } else if (val == SHARPSL_LED_ON) { + dev_dbg(sharpsl_pm.dev, "Charge LED On\n"); + + } else { + dev_dbg(sharpsl_pm.dev, "Charge LED Off\n"); + + } +} + +static void sharpsl_charge_on(void) +{ + dev_dbg(sharpsl_pm.dev, "Turning Charger On\n"); + + sharpsl_pm.full_count = 0; + sharpsl_pm.charge_mode = CHRG_ON; + schedule_delayed_work(&toggle_charger, msecs_to_jiffies(250)); + schedule_delayed_work(&sharpsl_bat, msecs_to_jiffies(500)); +} + +static void sharpsl_charge_off(void) +{ + dev_dbg(sharpsl_pm.dev, "Turning Charger Off\n"); + + sharpsl_pm.machinfo->charge(0); + sharpsl_pm_led(SHARPSL_LED_OFF); + sharpsl_pm.charge_mode = CHRG_OFF; + + schedule_work(&sharpsl_bat); +} + +static void sharpsl_charge_error(void) +{ + sharpsl_pm_led(SHARPSL_LED_ERROR); + sharpsl_pm.machinfo->charge(0); + sharpsl_pm.charge_mode = CHRG_ERROR; +} + +static void sharpsl_charge_toggle(void *private_) +{ + dev_dbg(sharpsl_pm.dev, "Toogling Charger at time: %lx\n", jiffies); + + if (!sharpsl_pm.machinfo->read_devdata(SHARPSL_STATUS_ACIN)) { + sharpsl_charge_off(); + return; + } else if ((sharpsl_check_battery_temp() < 0) || (sharpsl_ac_check() < 0)) { + sharpsl_charge_error(); + return; + } + + sharpsl_pm_led(SHARPSL_LED_ON); + sharpsl_pm.machinfo->charge(0); + mdelay(SHARPSL_CHARGE_WAIT_TIME); + sharpsl_pm.machinfo->charge(1); + + sharpsl_pm.charge_start_time = jiffies; +} + +static void sharpsl_ac_timer(unsigned long data) +{ + int acin = sharpsl_pm.machinfo->read_devdata(SHARPSL_STATUS_ACIN); + + dev_dbg(sharpsl_pm.dev, "AC Status: %d\n",acin); + + sharpsl_average_clear(); + if (acin && (sharpsl_pm.charge_mode != CHRG_ON)) + sharpsl_charge_on(); + else if (sharpsl_pm.charge_mode == CHRG_ON) + sharpsl_charge_off(); + + schedule_work(&sharpsl_bat); +} + + +irqreturn_t sharpsl_ac_isr(int irq, void *dev_id, struct pt_regs *fp) +{ + /* Delay the event slightly to debounce */ + /* Must be a smaller delay than the chrg_full_isr below */ + mod_timer(&sharpsl_pm.ac_timer, jiffies + msecs_to_jiffies(250)); + + return IRQ_HANDLED; +} + +static void sharpsl_chrg_full_timer(unsigned long data) +{ + dev_dbg(sharpsl_pm.dev, "Charge Full at time: %lx\n", jiffies); + + sharpsl_pm.full_count++; + + if (!sharpsl_pm.machinfo->read_devdata(SHARPSL_STATUS_ACIN)) { + dev_dbg(sharpsl_pm.dev, "Charge Full: AC removed - stop charging!\n"); + if (sharpsl_pm.charge_mode == CHRG_ON) + sharpsl_charge_off(); + } else if (sharpsl_pm.full_count < 2) { + dev_dbg(sharpsl_pm.dev, "Charge Full: Count too low\n"); + schedule_work(&toggle_charger); + } else if (time_after(jiffies, sharpsl_pm.charge_start_time + SHARPSL_CHARGE_FINISH_TIME)) { + dev_dbg(sharpsl_pm.dev, "Charge Full: Interrupt generated too slowly - retry.\n"); + schedule_work(&toggle_charger); + } else { + sharpsl_charge_off(); + sharpsl_pm.charge_mode = CHRG_DONE; + dev_dbg(sharpsl_pm.dev, "Charge Full: Charging Finished\n"); + } +} + +/* Charging Finished Interrupt (Not present on Corgi) */ +/* Can trigger at the same time as an AC staus change so + delay until after that has been processed */ +irqreturn_t sharpsl_chrg_full_isr(int irq, void *dev_id, struct pt_regs *fp) +{ + if (sharpsl_pm.flags & SHARPSL_SUSPENDED) + return IRQ_HANDLED; + + /* delay until after any ac interrupt */ + mod_timer(&sharpsl_pm.chrg_full_timer, jiffies + msecs_to_jiffies(500)); + + return IRQ_HANDLED; +} + +irqreturn_t sharpsl_fatal_isr(int irq, void *dev_id, struct pt_regs *fp) +{ + int is_fatal = 0; + + if (!sharpsl_pm.machinfo->read_devdata(SHARPSL_STATUS_LOCK)) { + dev_err(sharpsl_pm.dev, "Battery now Unlocked! Suspending.\n"); + is_fatal = 1; + } + + if (!sharpsl_pm.machinfo->read_devdata(SHARPSL_STATUS_FATAL)) { + dev_err(sharpsl_pm.dev, "Fatal Batt Error! Suspending.\n"); + is_fatal = 1; + } + + if (!(sharpsl_pm.flags & SHARPSL_APM_QUEUED) && is_fatal) { + sharpsl_pm.flags |= SHARPSL_APM_QUEUED; + apm_queue_event(APM_CRITICAL_SUSPEND); + } + + return IRQ_HANDLED; +} + +/* + * Maintain an average of the last 10 readings + */ +#define SHARPSL_CNV_VALUE_NUM 10 +static int sharpsl_ad_index; + +static void sharpsl_average_clear(void) +{ + sharpsl_ad_index = 0; +} + +static int sharpsl_average_value(int ad) +{ + int i, ad_val = 0; + static int sharpsl_ad[SHARPSL_CNV_VALUE_NUM+1]; + + if (sharpsl_pm.battstat.mainbat_status != APM_BATTERY_STATUS_HIGH) { + sharpsl_ad_index = 0; + return ad; + } + + sharpsl_ad[sharpsl_ad_index] = ad; + sharpsl_ad_index++; + if (sharpsl_ad_index >= SHARPSL_CNV_VALUE_NUM) { + for (i=0; i < (SHARPSL_CNV_VALUE_NUM-1); i++) + sharpsl_ad[i] = sharpsl_ad[i+1]; + sharpsl_ad_index = SHARPSL_CNV_VALUE_NUM - 1; + } + for (i=0; i < sharpsl_ad_index; i++) + ad_val += sharpsl_ad[i]; + + return (ad_val / sharpsl_ad_index); +} + +/* + * Take an array of 5 integers, remove the maximum and minimum values + * and return the average. + */ +static int get_select_val(int *val) +{ + int i, j, k, temp, sum = 0; + + /* Find MAX val */ + temp = val[0]; + j=0; + for (i=1; i<5; i++) { + if (temp < val[i]) { + temp = val[i]; + j = i; + } + } + + /* Find MIN val */ + temp = val[4]; + k=4; + for (i=3; i>=0; i--) { + if (temp > val[i]) { + temp = val[i]; + k = i; + } + } + + for (i=0; i<5; i++) + if (i != j && i != k ) + sum += val[i]; + + dev_dbg(sharpsl_pm.dev, "Average: %d from values: %d, %d, %d, %d, %d\n", sum/3, val[0], val[1], val[2], val[3], val[4]); + + return (sum/3); +} + +static int sharpsl_check_battery_temp(void) +{ + int val, i, buff[5]; + + /* Check battery temperature */ + for (i=0; i<5; i++) { + mdelay(SHARPSL_CHECK_BATTERY_WAIT_TIME_TEMP); + sharpsl_pm.machinfo->measure_temp(1); + mdelay(SHARPSL_CHECK_BATTERY_WAIT_TIME_TEMP); + buff[i] = sharpsl_pm.machinfo->read_devdata(SHARPSL_BATT_TEMP); + sharpsl_pm.machinfo->measure_temp(0); + } + + val = get_select_val(buff); + + dev_dbg(sharpsl_pm.dev, "Temperature: %d\n", val); + if (val > SHARPSL_CHARGE_ON_TEMP) + return -1; + + return 0; +} + +static int sharpsl_check_battery_voltage(void) +{ + int val, i, buff[5]; + + /* disable charge, enable discharge */ + sharpsl_pm.machinfo->charge(0); + sharpsl_pm.machinfo->discharge(1); + mdelay(SHARPSL_WAIT_DISCHARGE_ON); + + if (sharpsl_pm.machinfo->discharge1) + sharpsl_pm.machinfo->discharge1(1); + + /* Check battery voltage */ + for (i=0; i<5; i++) { + buff[i] = sharpsl_pm.machinfo->read_devdata(SHARPSL_BATT_VOLT); + mdelay(SHARPSL_CHECK_BATTERY_WAIT_TIME_VOLT); + } + + if (sharpsl_pm.machinfo->discharge1) + sharpsl_pm.machinfo->discharge1(0); + + sharpsl_pm.machinfo->discharge(0); + + val = get_select_val(buff); + dev_dbg(sharpsl_pm.dev, "Battery Voltage: %d\n", val); + + if (val < SHARPSL_CHARGE_ON_VOLT) + return -1; + + return 0; +} + +static int sharpsl_ac_check(void) +{ + int temp, i, buff[5]; + + for (i=0; i<5; i++) { + buff[i] = sharpsl_pm.machinfo->read_devdata(SHARPSL_ACIN_VOLT); + mdelay(SHARPSL_CHECK_BATTERY_WAIT_TIME_ACIN); + } + + temp = get_select_val(buff); + dev_dbg(sharpsl_pm.dev, "AC Voltage: %d\n",temp); + + if ((temp > SHARPSL_CHARGE_ON_ACIN_HIGH) || (temp < SHARPSL_CHARGE_ON_ACIN_LOW)) { + dev_err(sharpsl_pm.dev, "Error: AC check failed.\n"); + return -1; + } + + return 0; +} + +#ifdef CONFIG_PM +static int sharpsl_pm_suspend(struct platform_device *pdev, pm_message_t state) +{ + sharpsl_pm.flags |= SHARPSL_SUSPENDED; + flush_scheduled_work(); + + if (sharpsl_pm.charge_mode == CHRG_ON) + sharpsl_pm.flags |= SHARPSL_DO_OFFLINE_CHRG; + else + sharpsl_pm.flags &= ~SHARPSL_DO_OFFLINE_CHRG; + + return 0; +} + +static int sharpsl_pm_resume(struct platform_device *pdev) +{ + /* Clear the reset source indicators as they break the bootloader upon reboot */ + RCSR = 0x0f; + sharpsl_average_clear(); + sharpsl_pm.flags &= ~SHARPSL_APM_QUEUED; + sharpsl_pm.flags &= ~SHARPSL_SUSPENDED; + + return 0; +} + +static void corgi_goto_sleep(unsigned long alarm_time, unsigned int alarm_enable, suspend_state_t state) +{ + dev_dbg(sharpsl_pm.dev, "Time is: %08x\n",RCNR); + + dev_dbg(sharpsl_pm.dev, "Offline Charge Activate = %d\n",sharpsl_pm.flags & SHARPSL_DO_OFFLINE_CHRG); + /* not charging and AC-IN! */ + + if ((sharpsl_pm.flags & SHARPSL_DO_OFFLINE_CHRG) && (sharpsl_pm.machinfo->read_devdata(SHARPSL_STATUS_ACIN))) { + dev_dbg(sharpsl_pm.dev, "Activating Offline Charger...\n"); + sharpsl_pm.charge_mode = CHRG_OFF; + sharpsl_pm.flags &= ~SHARPSL_DO_OFFLINE_CHRG; + sharpsl_off_charge_battery(); + } + + sharpsl_pm.machinfo->presuspend(); + + PEDR = 0xffffffff; /* clear it */ + + sharpsl_pm.flags &= ~SHARPSL_ALARM_ACTIVE; + if ((sharpsl_pm.charge_mode == CHRG_ON) && ((alarm_enable && ((alarm_time - RCNR) > (SHARPSL_BATCHK_TIME_SUSPEND + 30))) || !alarm_enable)) { + RTSR &= RTSR_ALE; + RTAR = RCNR + SHARPSL_BATCHK_TIME_SUSPEND; + dev_dbg(sharpsl_pm.dev, "Charging alarm at: %08x\n",RTAR); + sharpsl_pm.flags |= SHARPSL_ALARM_ACTIVE; + } else if (alarm_enable) { + RTSR &= RTSR_ALE; + RTAR = alarm_time; + dev_dbg(sharpsl_pm.dev, "User alarm at: %08x\n",RTAR); + } else { + dev_dbg(sharpsl_pm.dev, "No alarms set.\n"); + } + + pxa_pm_enter(state); + + sharpsl_pm.machinfo->postsuspend(); + + dev_dbg(sharpsl_pm.dev, "Corgi woken up from suspend: %08x\n",PEDR); +} + +static int corgi_enter_suspend(unsigned long alarm_time, unsigned int alarm_enable, suspend_state_t state) +{ + if (!sharpsl_pm.machinfo->should_wakeup(!(sharpsl_pm.flags & SHARPSL_ALARM_ACTIVE) && alarm_enable) ) + { + if (!(sharpsl_pm.flags & SHARPSL_ALARM_ACTIVE)) { + dev_dbg(sharpsl_pm.dev, "No user triggered wakeup events and not charging. Strange. Suspend.\n"); + corgi_goto_sleep(alarm_time, alarm_enable, state); + return 1; + } + if(sharpsl_off_charge_battery()) { + dev_dbg(sharpsl_pm.dev, "Charging. Suspend...\n"); + corgi_goto_sleep(alarm_time, alarm_enable, state); + return 1; + } + dev_dbg(sharpsl_pm.dev, "User triggered wakeup in offline charger.\n"); + } + + if ((!sharpsl_pm.machinfo->read_devdata(SHARPSL_STATUS_LOCK)) || (sharpsl_fatal_check() < 0) ) + { + dev_err(sharpsl_pm.dev, "Fatal condition. Suspend.\n"); + corgi_goto_sleep(alarm_time, alarm_enable, state); + return 1; + } + + return 0; +} + +static int corgi_pxa_pm_enter(suspend_state_t state) +{ + unsigned long alarm_time = RTAR; + unsigned int alarm_status = ((RTSR & RTSR_ALE) != 0); + + dev_dbg(sharpsl_pm.dev, "SharpSL suspending for first time.\n"); + + corgi_goto_sleep(alarm_time, alarm_status, state); + + while (corgi_enter_suspend(alarm_time,alarm_status,state)) + {} + + dev_dbg(sharpsl_pm.dev, "SharpSL resuming...\n"); + + return 0; +} +#endif + + +/* + * Check for fatal battery errors + * Fatal returns -1 + */ +static int sharpsl_fatal_check(void) +{ + int buff[5], temp, i, acin; + + dev_dbg(sharpsl_pm.dev, "sharpsl_fatal_check entered\n"); + + /* Check AC-Adapter */ + acin = sharpsl_pm.machinfo->read_devdata(SHARPSL_STATUS_ACIN); + + if (acin && (sharpsl_pm.charge_mode == CHRG_ON)) { + sharpsl_pm.machinfo->charge(0); + udelay(100); + sharpsl_pm.machinfo->discharge(1); /* enable discharge */ + mdelay(SHARPSL_WAIT_DISCHARGE_ON); + } + + if (sharpsl_pm.machinfo->discharge1) + sharpsl_pm.machinfo->discharge1(1); + + /* Check battery : check inserting battery ? */ + for (i=0; i<5; i++) { + buff[i] = sharpsl_pm.machinfo->read_devdata(SHARPSL_BATT_VOLT); + mdelay(SHARPSL_CHECK_BATTERY_WAIT_TIME_VOLT); + } + + if (sharpsl_pm.machinfo->discharge1) + sharpsl_pm.machinfo->discharge1(0); + + if (acin && (sharpsl_pm.charge_mode == CHRG_ON)) { + udelay(100); + sharpsl_pm.machinfo->charge(1); + sharpsl_pm.machinfo->discharge(0); + } + + temp = get_select_val(buff); + dev_dbg(sharpsl_pm.dev, "sharpsl_fatal_check: acin: %d, discharge voltage: %d, no discharge: %d\n", acin, temp, sharpsl_pm.machinfo->read_devdata(SHARPSL_BATT_VOLT)); + + if ((acin && (temp < SHARPSL_FATAL_ACIN_VOLT)) || + (!acin && (temp < SHARPSL_FATAL_NOACIN_VOLT))) + return -1; + return 0; +} + +static int sharpsl_off_charge_error(void) +{ + dev_err(sharpsl_pm.dev, "Offline Charger: Error occured.\n"); + sharpsl_pm.machinfo->charge(0); + sharpsl_pm_led(SHARPSL_LED_ERROR); + sharpsl_pm.charge_mode = CHRG_ERROR; + return 1; +} + +/* + * Charging Control while suspended + * Return 1 - go straight to sleep + * Return 0 - sleep or wakeup depending on other factors + */ +static int sharpsl_off_charge_battery(void) +{ + int time; + + dev_dbg(sharpsl_pm.dev, "Charge Mode: %d\n", sharpsl_pm.charge_mode); + + if (sharpsl_pm.charge_mode == CHRG_OFF) { + dev_dbg(sharpsl_pm.dev, "Offline Charger: Step 1\n"); + + /* AC Check */ + if ((sharpsl_ac_check() < 0) || (sharpsl_check_battery_temp() < 0)) + return sharpsl_off_charge_error(); + + /* Start Charging */ + sharpsl_pm_led(SHARPSL_LED_ON); + sharpsl_pm.machinfo->charge(0); + mdelay(SHARPSL_CHARGE_WAIT_TIME); + sharpsl_pm.machinfo->charge(1); + + sharpsl_pm.charge_mode = CHRG_ON; + sharpsl_pm.full_count = 0; + + return 1; + } else if (sharpsl_pm.charge_mode != CHRG_ON) { + return 1; + } + + if (sharpsl_pm.full_count == 0) { + int time; + + dev_dbg(sharpsl_pm.dev, "Offline Charger: Step 2\n"); + + if ((sharpsl_check_battery_temp() < 0) || (sharpsl_check_battery_voltage() < 0)) + return sharpsl_off_charge_error(); + + sharpsl_pm.machinfo->charge(0); + mdelay(SHARPSL_CHARGE_WAIT_TIME); + sharpsl_pm.machinfo->charge(1); + sharpsl_pm.charge_mode = CHRG_ON; + + mdelay(SHARPSL_CHARGE_CO_CHECK_TIME); + + time = RCNR; + while(1) { + /* Check if any wakeup event had occured */ + if (sharpsl_pm.machinfo->charger_wakeup() != 0) + return 0; + /* Check for timeout */ + if ((RCNR - time) > SHARPSL_WAIT_CO_TIME) + return 1; + if (sharpsl_pm.machinfo->read_devdata(SHARPSL_STATUS_CHRGFULL)) { + dev_dbg(sharpsl_pm.dev, "Offline Charger: Charge full occured. Retrying to check\n"); + sharpsl_pm.full_count++; + sharpsl_pm.machinfo->charge(0); + mdelay(SHARPSL_CHARGE_WAIT_TIME); + sharpsl_pm.machinfo->charge(1); + return 1; + } + } + } + + dev_dbg(sharpsl_pm.dev, "Offline Charger: Step 3\n"); + + mdelay(SHARPSL_CHARGE_CO_CHECK_TIME); + + time = RCNR; + while(1) { + /* Check if any wakeup event had occured */ + if (sharpsl_pm.machinfo->charger_wakeup() != 0) + return 0; + /* Check for timeout */ + if ((RCNR-time) > SHARPSL_WAIT_CO_TIME) { + if (sharpsl_pm.full_count > SHARPSL_CHARGE_RETRY_CNT) { + dev_dbg(sharpsl_pm.dev, "Offline Charger: Not charged sufficiently. Retrying.\n"); + sharpsl_pm.full_count = 0; + } + sharpsl_pm.full_count++; + return 1; + } + if (sharpsl_pm.machinfo->read_devdata(SHARPSL_STATUS_CHRGFULL)) { + dev_dbg(sharpsl_pm.dev, "Offline Charger: Charging complete.\n"); + sharpsl_pm_led(SHARPSL_LED_OFF); + sharpsl_pm.machinfo->charge(0); + sharpsl_pm.charge_mode = CHRG_DONE; + return 1; + } + } +} + + +static ssize_t battery_percentage_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n",sharpsl_pm.battstat.mainbat_percent); +} + +static ssize_t battery_voltage_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n",sharpsl_pm.battstat.mainbat_voltage); +} + +static DEVICE_ATTR(battery_percentage, 0444, battery_percentage_show, NULL); +static DEVICE_ATTR(battery_voltage, 0444, battery_voltage_show, NULL); + +extern void (*apm_get_power_status)(struct apm_power_info *); + +static void sharpsl_apm_get_power_status(struct apm_power_info *info) +{ + info->ac_line_status = sharpsl_pm.battstat.ac_status; + + if (sharpsl_pm.charge_mode == CHRG_ON) + info->battery_status = APM_BATTERY_STATUS_CHARGING; + else + info->battery_status = sharpsl_pm.battstat.mainbat_status; + + info->battery_flag = (1 << info->battery_status); + info->battery_life = sharpsl_pm.battstat.mainbat_percent; +} + +static struct pm_ops sharpsl_pm_ops = { + .pm_disk_mode = PM_DISK_FIRMWARE, + .prepare = pxa_pm_prepare, + .enter = corgi_pxa_pm_enter, + .finish = pxa_pm_finish, +}; + +static int __init sharpsl_pm_probe(struct platform_device *pdev) +{ + if (!pdev->dev.platform_data) + return -EINVAL; + + sharpsl_pm.dev = &pdev->dev; + sharpsl_pm.machinfo = pdev->dev.platform_data; + sharpsl_pm.charge_mode = CHRG_OFF; + sharpsl_pm.flags = 0; + + init_timer(&sharpsl_pm.ac_timer); + sharpsl_pm.ac_timer.function = sharpsl_ac_timer; + + init_timer(&sharpsl_pm.chrg_full_timer); + sharpsl_pm.chrg_full_timer.function = sharpsl_chrg_full_timer; + + sharpsl_pm.machinfo->init(); + + device_create_file(&pdev->dev, &dev_attr_battery_percentage); + device_create_file(&pdev->dev, &dev_attr_battery_voltage); + + apm_get_power_status = sharpsl_apm_get_power_status; + + pm_set_ops(&sharpsl_pm_ops); + + mod_timer(&sharpsl_pm.ac_timer, jiffies + msecs_to_jiffies(250)); + + return 0; +} + +static int sharpsl_pm_remove(struct platform_device *pdev) +{ + pm_set_ops(NULL); + + device_remove_file(&pdev->dev, &dev_attr_battery_percentage); + device_remove_file(&pdev->dev, &dev_attr_battery_voltage); + + sharpsl_pm.machinfo->exit(); + + del_timer_sync(&sharpsl_pm.chrg_full_timer); + del_timer_sync(&sharpsl_pm.ac_timer); + + return 0; +} + +static struct platform_driver sharpsl_pm_driver = { + .probe = sharpsl_pm_probe, + .remove = sharpsl_pm_remove, + .suspend = sharpsl_pm_suspend, + .resume = sharpsl_pm_resume, + .driver = { + .name = "sharpsl-pm", + }, +}; + +static int __devinit sharpsl_pm_init(void) +{ + return platform_driver_register(&sharpsl_pm_driver); +} + +static void sharpsl_pm_exit(void) +{ + platform_driver_unregister(&sharpsl_pm_driver); +} + +late_initcall(sharpsl_pm_init); +module_exit(sharpsl_pm_exit); diff --git a/arch/arm/configs/ixp4xx_defconfig b/arch/arm/configs/ixp4xx_defconfig index f74c926beb4..613afab6272 100644 --- a/arch/arm/configs/ixp4xx_defconfig +++ b/arch/arm/configs/ixp4xx_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.14-rc1-git5 -# Tue Sep 20 17:26:28 2005 +# Linux kernel version: 2.6.15 +# Tue Jan 3 03:20:40 2006 # CONFIG_ARM=y CONFIG_MMU=y @@ -33,6 +33,7 @@ CONFIG_SYSCTL=y CONFIG_KOBJECT_UEVENT=y # CONFIG_IKCONFIG is not set CONFIG_INITRAMFS_SOURCE="" +CONFIG_CC_OPTIMIZE_FOR_SIZE=y CONFIG_EMBEDDED=y CONFIG_KALLSYMS=y # CONFIG_KALLSYMS_ALL is not set @@ -42,7 +43,6 @@ CONFIG_BUG=y CONFIG_BASE_FULL=y CONFIG_FUTEX=y CONFIG_EPOLL=y -CONFIG_CC_OPTIMIZE_FOR_SIZE=y CONFIG_SHMEM=y CONFIG_CC_ALIGN_FUNCTIONS=0 CONFIG_CC_ALIGN_LABELS=0 @@ -62,6 +62,23 @@ CONFIG_MODVERSIONS=y CONFIG_KMOD=y # +# Block layer +# + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +CONFIG_DEFAULT_AS=y +# CONFIG_DEFAULT_DEADLINE is not set +# CONFIG_DEFAULT_CFQ is not set +# CONFIG_DEFAULT_NOOP is not set +CONFIG_DEFAULT_IOSCHED="anticipatory" + +# # System Type # # CONFIG_ARCH_CLPS7500 is not set @@ -83,6 +100,7 @@ CONFIG_ARCH_IXP4XX=y # CONFIG_ARCH_LH7A40X is not set # CONFIG_ARCH_OMAP is not set # CONFIG_ARCH_VERSATILE is not set +# CONFIG_ARCH_REALVIEW is not set # CONFIG_ARCH_IMX is not set # CONFIG_ARCH_H720X is not set # CONFIG_ARCH_AAEC2000 is not set @@ -102,6 +120,7 @@ CONFIG_MACH_IXDPG425=y CONFIG_MACH_IXDP465=y CONFIG_ARCH_IXCDP1100=y CONFIG_ARCH_PRPMC1100=y +CONFIG_MACH_NAS100D=y CONFIG_ARCH_IXDP4XX=y CONFIG_CPU_IXP46X=y # CONFIG_MACH_GTWX5715 is not set @@ -155,6 +174,7 @@ CONFIG_FLATMEM_MANUAL=y CONFIG_FLATMEM=y CONFIG_FLAT_NODE_MEM_MAP=y # CONFIG_SPARSEMEM_STATIC is not set +CONFIG_SPLIT_PTLOCK_CPUS=4096 CONFIG_ALIGNMENT_TRAP=y # @@ -173,6 +193,7 @@ CONFIG_CMDLINE="console=ttyS0,115200 ip=bootp root=/dev/nfs" # At least one emulation must be selected # CONFIG_FPE_NWFPE=y +# CONFIG_FPE_NWFPE_XP is not set # CONFIG_FPE_FASTFPE is not set # @@ -187,6 +208,8 @@ CONFIG_BINFMT_ELF=y # Power management options # CONFIG_PM=y +CONFIG_PM_LEGACY=y +# CONFIG_PM_DEBUG is not set CONFIG_APM=y # @@ -271,6 +294,10 @@ CONFIG_IP_VS_SH=m CONFIG_NETFILTER=y # CONFIG_NETFILTER_DEBUG is not set CONFIG_BRIDGE_NETFILTER=y + +# +# Core Netfilter Configuration +# # CONFIG_NETFILTER_NETLINK is not set # @@ -286,6 +313,7 @@ CONFIG_IP_NF_IRC=m # CONFIG_IP_NF_NETBIOS_NS is not set # CONFIG_IP_NF_TFTP is not set # CONFIG_IP_NF_AMANDA is not set +# CONFIG_IP_NF_PPTP is not set CONFIG_IP_NF_QUEUE=m CONFIG_IP_NF_IPTABLES=m CONFIG_IP_NF_MATCH_LIMIT=m @@ -319,6 +347,7 @@ CONFIG_IP_NF_TARGET_REJECT=m CONFIG_IP_NF_TARGET_LOG=m CONFIG_IP_NF_TARGET_ULOG=m CONFIG_IP_NF_TARGET_TCPMSS=m +# CONFIG_IP_NF_TARGET_NFQUEUE is not set CONFIG_IP_NF_NAT=m CONFIG_IP_NF_NAT_NEEDED=y CONFIG_IP_NF_TARGET_MASQUERADE=m @@ -380,10 +409,18 @@ CONFIG_ECONET=m CONFIG_ECONET_AUNUDP=y CONFIG_ECONET_NATIVE=y CONFIG_WAN_ROUTER=m + +# +# QoS and/or fair queueing +# CONFIG_NET_SCHED=y CONFIG_NET_SCH_CLK_JIFFIES=y # CONFIG_NET_SCH_CLK_GETTIMEOFDAY is not set # CONFIG_NET_SCH_CLK_CPU is not set + +# +# Queueing/Scheduling +# CONFIG_NET_SCH_CBQ=m CONFIG_NET_SCH_HTB=m # CONFIG_NET_SCH_HFSC is not set @@ -397,8 +434,10 @@ CONFIG_NET_SCH_GRED=m CONFIG_NET_SCH_DSMARK=m # CONFIG_NET_SCH_NETEM is not set CONFIG_NET_SCH_INGRESS=m -CONFIG_NET_QOS=y -CONFIG_NET_ESTIMATOR=y + +# +# Classification +# CONFIG_NET_CLS=y # CONFIG_NET_CLS_BASIC is not set CONFIG_NET_CLS_TCINDEX=m @@ -407,13 +446,14 @@ CONFIG_NET_CLS_ROUTE=y CONFIG_NET_CLS_FW=m CONFIG_NET_CLS_U32=m # CONFIG_CLS_U32_PERF is not set -# CONFIG_NET_CLS_IND is not set # CONFIG_CLS_U32_MARK is not set CONFIG_NET_CLS_RSVP=m CONFIG_NET_CLS_RSVP6=m # CONFIG_NET_EMATCH is not set # CONFIG_NET_CLS_ACT is not set CONFIG_NET_CLS_POLICE=y +# CONFIG_NET_CLS_IND is not set +CONFIG_NET_ESTIMATOR=y # # Network testing @@ -437,6 +477,11 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y # CONFIG_DEBUG_DRIVER is not set # +# Connector - unified userspace <-> kernelspace linker +# +# CONFIG_CONNECTOR is not set + +# # Memory Technology Devices (MTD) # CONFIG_MTD=y @@ -458,6 +503,7 @@ CONFIG_MTD_BLOCK=y # CONFIG_FTL is not set # CONFIG_NFTL is not set # CONFIG_INFTL is not set +# CONFIG_RFD_FTL is not set # # RAM/ROM/Flash chip drivers @@ -492,7 +538,6 @@ CONFIG_MTD_COMPLEX_MAPPINGS=y # CONFIG_MTD_PHYSMAP is not set # CONFIG_MTD_ARM_INTEGRATOR is not set CONFIG_MTD_IXP4XX=y -# CONFIG_MTD_EDB7312 is not set # CONFIG_MTD_PCI is not set # CONFIG_MTD_PLATRAM is not set @@ -523,6 +568,11 @@ CONFIG_MTD_NAND_IDS=m # CONFIG_MTD_NAND_NANDSIM is not set # +# OneNAND Flash Device Drivers +# +# CONFIG_MTD_ONENAND is not set + +# # Parallel port support # # CONFIG_PARPORT is not set @@ -548,14 +598,6 @@ CONFIG_BLK_DEV_RAM_COUNT=16 CONFIG_BLK_DEV_RAM_SIZE=8192 CONFIG_BLK_DEV_INITRD=y # CONFIG_CDROM_PKTCDVD is not set - -# -# IO Schedulers -# -CONFIG_IOSCHED_NOOP=y -CONFIG_IOSCHED_AS=y -CONFIG_IOSCHED_DEADLINE=y -CONFIG_IOSCHED_CFQ=y # CONFIG_ATA_OVER_ETH is not set # @@ -668,6 +710,7 @@ CONFIG_NET_ETHERNET=y CONFIG_MII=y # CONFIG_HAPPYMEAL is not set # CONFIG_SUNGEM is not set +# CONFIG_CASSINI is not set # CONFIG_NET_VENDOR_3COM is not set # CONFIG_SMC91X is not set # CONFIG_DM9000 is not set @@ -739,6 +782,7 @@ CONFIG_NET_RADIO=y # # Wireless 802.11b ISA/PCI cards support # +# CONFIG_AIRO is not set CONFIG_HERMES=y # CONFIG_PLX_HERMES is not set # CONFIG_TMD_HERMES is not set @@ -782,6 +826,7 @@ CONFIG_WAN_ROUTER_DRIVERS=y # # ATM drivers # +# CONFIG_ATM_DUMMY is not set CONFIG_ATM_TCP=m # CONFIG_ATM_LANAI is not set # CONFIG_ATM_ENI is not set @@ -902,6 +947,7 @@ CONFIG_IXP4XX_WATCHDOG=y # TPM devices # # CONFIG_TCG_TPM is not set +# CONFIG_TELCLOCK is not set # # I2C support @@ -954,6 +1000,7 @@ CONFIG_SENSORS_EEPROM=y # CONFIG_SENSORS_PCF8591 is not set # CONFIG_SENSORS_RTC8564 is not set # CONFIG_SENSORS_MAX6875 is not set +# CONFIG_RTC_X1205_I2C is not set # CONFIG_I2C_DEBUG_CORE is not set # CONFIG_I2C_DEBUG_ALGO is not set # CONFIG_I2C_DEBUG_BUS is not set @@ -1036,6 +1083,10 @@ CONFIG_USB_ARCH_HAS_OHCI=y # CONFIG_USB is not set # +# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' +# + +# # USB Gadget Support # # CONFIG_USB_GADGET is not set @@ -1110,6 +1161,7 @@ CONFIG_RAMFS=y CONFIG_JFFS2_FS=y CONFIG_JFFS2_FS_DEBUG=0 CONFIG_JFFS2_FS_WRITEBUFFER=y +# CONFIG_JFFS2_SUMMARY is not set # CONFIG_JFFS2_COMPRESSION_OPTIONS is not set CONFIG_JFFS2_ZLIB=y CONFIG_JFFS2_RTIME=y @@ -1190,7 +1242,9 @@ CONFIG_DETECT_SOFTLOCKUP=y CONFIG_DEBUG_BUGVERBOSE=y # CONFIG_DEBUG_INFO is not set # CONFIG_DEBUG_FS is not set +# CONFIG_DEBUG_VM is not set CONFIG_FRAME_POINTER=y +# CONFIG_RCU_TORTURE_TEST is not set # CONFIG_DEBUG_USER is not set # CONFIG_DEBUG_WAITQ is not set CONFIG_DEBUG_ERRORS=y diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile index c11169b5ed9..de94b0f3ee2 100644 --- a/arch/arm/kernel/Makefile +++ b/arch/arm/kernel/Makefile @@ -2,15 +2,16 @@ # Makefile for the linux kernel. # -AFLAGS_head.o := -DKERNEL_RAM_ADDR=$(TEXTADDR) +AFLAGS_head.o := -DTEXT_OFFSET=$(TEXT_OFFSET) # Object file lists. -obj-y := compat.o dma.o entry-armv.o entry-common.o irq.o \ +obj-y := compat.o entry-armv.o entry-common.o irq.o \ process.o ptrace.o semaphore.o setup.o signal.o sys_arm.o \ time.o traps.o obj-$(CONFIG_APM) += apm.o +obj-$(CONFIG_ISA_DMA_API) += dma.o obj-$(CONFIG_ARCH_ACORN) += ecard.o obj-$(CONFIG_FOOTBRIDGE) += isa.o obj-$(CONFIG_FIQ) += fiq.o diff --git a/arch/arm/kernel/apm.c b/arch/arm/kernel/apm.c index a2843be0555..b9df1b782bb 100644 --- a/arch/arm/kernel/apm.c +++ b/arch/arm/kernel/apm.c @@ -20,7 +20,6 @@ #include <linux/apm_bios.h> #include <linux/sched.h> #include <linux/pm.h> -#include <linux/pm_legacy.h> #include <linux/device.h> #include <linux/kernel.h> #include <linux/list.h> @@ -81,6 +80,7 @@ struct apm_user { */ static int suspends_pending; static int apm_disabled; +static int arm_apm_active; static DECLARE_WAIT_QUEUE_HEAD(apm_waitqueue); static DECLARE_WAIT_QUEUE_HEAD(apm_suspend_waitqueue); @@ -477,9 +477,9 @@ static int kapmd(void *arg) apm_event_t event; wait_event_interruptible(kapmd_wait, - !queue_empty(&kapmd_queue) || !pm_active); + !queue_empty(&kapmd_queue) || !arm_apm_active); - if (!pm_active) + if (!arm_apm_active) break; spin_lock_irq(&kapmd_queue_lock); @@ -522,16 +522,11 @@ static int __init apm_init(void) return -ENODEV; } - if (PM_IS_ACTIVE()) { - printk(KERN_NOTICE "apm: overridden by ACPI.\n"); - return -EINVAL; - } - - pm_active = 1; + arm_apm_active = 1; ret = kernel_thread(kapmd, NULL, CLONE_KERNEL); if (ret < 0) { - pm_active = 0; + arm_apm_active = 0; return ret; } @@ -543,7 +538,7 @@ static int __init apm_init(void) if (ret != 0) { remove_proc_entry("apm", NULL); - pm_active = 0; + arm_apm_active = 0; wake_up(&kapmd_wait); wait_for_completion(&kapmd_exit); } @@ -556,7 +551,7 @@ static void __exit apm_exit(void) misc_deregister(&apm_device); remove_proc_entry("apm", NULL); - pm_active = 0; + arm_apm_active = 0; wake_up(&kapmd_wait); wait_for_completion(&kapmd_exit); } diff --git a/arch/arm/kernel/dma-isa.c b/arch/arm/kernel/dma-isa.c index e9a36304ec3..03532769a97 100644 --- a/arch/arm/kernel/dma-isa.c +++ b/arch/arm/kernel/dma-isa.c @@ -18,7 +18,7 @@ */ #include <linux/ioport.h> #include <linux/init.h> -#include <linux/pci.h> +#include <linux/dma-mapping.h> #include <asm/dma.h> #include <asm/io.h> @@ -65,37 +65,41 @@ static void isa_enable_dma(dmach_t channel, dma_t *dma) { if (dma->invalid) { unsigned long address, length; - unsigned int mode, direction; + unsigned int mode; + enum dma_data_direction direction; mode = channel & 3; switch (dma->dma_mode & DMA_MODE_MASK) { case DMA_MODE_READ: mode |= ISA_DMA_MODE_READ; - direction = PCI_DMA_FROMDEVICE; + direction = DMA_FROM_DEVICE; break; case DMA_MODE_WRITE: mode |= ISA_DMA_MODE_WRITE; - direction = PCI_DMA_TODEVICE; + direction = DMA_TO_DEVICE; break; case DMA_MODE_CASCADE: mode |= ISA_DMA_MODE_CASCADE; - direction = PCI_DMA_BIDIRECTIONAL; + direction = DMA_BIDIRECTIONAL; break; default: - direction = PCI_DMA_NONE; + direction = DMA_NONE; break; } - if (!dma->using_sg) { + if (!dma->sg) { /* * Cope with ISA-style drivers which expect cache * coherence. */ - dma->buf.dma_address = pci_map_single(NULL, - dma->buf.__address, dma->buf.length, + dma->sg = &dma->buf; + dma->sgcount = 1; + dma->buf.length = dma->count; + dma->buf.dma_address = dma_map_single(NULL, + dma->addr, dma->count, direction); } diff --git a/arch/arm/kernel/dma.c b/arch/arm/kernel/dma.c index 2b788388423..5a0f4bc5da9 100644 --- a/arch/arm/kernel/dma.c +++ b/arch/arm/kernel/dma.c @@ -12,8 +12,6 @@ * DMA facilities. */ #include <linux/module.h> -#include <linux/slab.h> -#include <linux/mman.h> #include <linux/init.h> #include <linux/spinlock.h> #include <linux/errno.h> @@ -23,8 +21,7 @@ #include <asm/mach/dma.h> DEFINE_SPINLOCK(dma_spin_lock); - -#if MAX_DMA_CHANNELS > 0 +EXPORT_SYMBOL(dma_spin_lock); static dma_t dma_chan[MAX_DMA_CHANNELS]; @@ -81,6 +78,7 @@ bad_dma: busy: return -EBUSY; } +EXPORT_SYMBOL(request_dma); /* * Free DMA channel @@ -112,6 +110,7 @@ void free_dma(dmach_t channel) bad_dma: printk(KERN_ERR "dma: trying to free DMA%d\n", channel); } +EXPORT_SYMBOL(free_dma); /* Set DMA Scatter-Gather list */ @@ -125,15 +124,15 @@ void set_dma_sg (dmach_t channel, struct scatterlist *sg, int nr_sg) dma->sg = sg; dma->sgcount = nr_sg; - dma->using_sg = 1; dma->invalid = 1; } +EXPORT_SYMBOL(set_dma_sg); /* Set DMA address * * Copy address to the structure, and set the invalid bit */ -void set_dma_addr (dmach_t channel, unsigned long physaddr) +void __set_dma_addr (dmach_t channel, void *addr) { dma_t *dma = dma_chan + channel; @@ -141,12 +140,11 @@ void set_dma_addr (dmach_t channel, unsigned long physaddr) printk(KERN_ERR "dma%d: altering DMA address while " "DMA active\n", channel); - dma->sg = &dma->buf; - dma->sgcount = 1; - dma->buf.__address = bus_to_virt(physaddr); - dma->using_sg = 0; + dma->sg = NULL; + dma->addr = addr; dma->invalid = 1; } +EXPORT_SYMBOL(__set_dma_addr); /* Set DMA byte count * @@ -160,12 +158,11 @@ void set_dma_count (dmach_t channel, unsigned long count) printk(KERN_ERR "dma%d: altering DMA count while " "DMA active\n", channel); - dma->sg = &dma->buf; - dma->sgcount = 1; - dma->buf.length = count; - dma->using_sg = 0; + dma->sg = NULL; + dma->count = count; dma->invalid = 1; } +EXPORT_SYMBOL(set_dma_count); /* Set DMA direction mode */ @@ -180,6 +177,7 @@ void set_dma_mode (dmach_t channel, dmamode_t mode) dma->dma_mode = mode; dma->invalid = 1; } +EXPORT_SYMBOL(set_dma_mode); /* Enable DMA channel */ @@ -200,6 +198,7 @@ free_dma: printk(KERN_ERR "dma%d: trying to enable free DMA\n", channel); BUG(); } +EXPORT_SYMBOL(enable_dma); /* Disable DMA channel */ @@ -220,6 +219,7 @@ free_dma: printk(KERN_ERR "dma%d: trying to disable free DMA\n", channel); BUG(); } +EXPORT_SYMBOL(disable_dma); /* * Is the specified DMA channel active? @@ -233,6 +233,7 @@ void set_dma_page(dmach_t channel, char pagenr) { printk(KERN_ERR "dma%d: trying to set_dma_page\n", channel); } +EXPORT_SYMBOL(set_dma_page); void set_dma_speed(dmach_t channel, int cycle_ns) { @@ -243,6 +244,7 @@ void set_dma_speed(dmach_t channel, int cycle_ns) ret = dma->d_ops->setspeed(channel, dma, cycle_ns); dma->speed = ret; } +EXPORT_SYMBOL(set_dma_speed); int get_dma_residue(dmach_t channel) { @@ -254,49 +256,12 @@ int get_dma_residue(dmach_t channel) return ret; } +EXPORT_SYMBOL(get_dma_residue); -void __init init_dma(void) +static int __init init_dma(void) { arch_dma_init(dma_chan); -} - -#else - -int request_dma(dmach_t channel, const char *device_id) -{ - return -EINVAL; -} - -int get_dma_residue(dmach_t channel) -{ return 0; } -#define GLOBAL_ALIAS(_a,_b) asm (".set " #_a "," #_b "; .globl " #_a) -GLOBAL_ALIAS(disable_dma, get_dma_residue); -GLOBAL_ALIAS(enable_dma, get_dma_residue); -GLOBAL_ALIAS(free_dma, get_dma_residue); -GLOBAL_ALIAS(get_dma_list, get_dma_residue); -GLOBAL_ALIAS(set_dma_mode, get_dma_residue); -GLOBAL_ALIAS(set_dma_page, get_dma_residue); -GLOBAL_ALIAS(set_dma_count, get_dma_residue); -GLOBAL_ALIAS(set_dma_addr, get_dma_residue); -GLOBAL_ALIAS(set_dma_sg, get_dma_residue); -GLOBAL_ALIAS(set_dma_speed, get_dma_residue); -GLOBAL_ALIAS(init_dma, get_dma_residue); - -#endif - -EXPORT_SYMBOL(request_dma); -EXPORT_SYMBOL(free_dma); -EXPORT_SYMBOL(enable_dma); -EXPORT_SYMBOL(disable_dma); -EXPORT_SYMBOL(set_dma_addr); -EXPORT_SYMBOL(set_dma_count); -EXPORT_SYMBOL(set_dma_mode); -EXPORT_SYMBOL(set_dma_page); -EXPORT_SYMBOL(get_dma_residue); -EXPORT_SYMBOL(set_dma_sg); -EXPORT_SYMBOL(set_dma_speed); - -EXPORT_SYMBOL(dma_spin_lock); +core_initcall(init_dma); diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S index 2a8d27e18fa..a52baedf626 100644 --- a/arch/arm/kernel/entry-armv.S +++ b/arch/arm/kernel/entry-armv.S @@ -18,8 +18,6 @@ #include <asm/memory.h> #include <asm/glue.h> #include <asm/vfpmacros.h> -#include <asm/hardware.h> /* should be moved into entry-macro.S */ -#include <asm/arch/irqs.h> /* should be moved into entry-macro.S */ #include <asm/arch/entry-macro.S> #include "entry-header.S" diff --git a/arch/arm/kernel/head.S b/arch/arm/kernel/head.S index d7d69fd7039..1e985f2cd70 100644 --- a/arch/arm/kernel/head.S +++ b/arch/arm/kernel/head.S @@ -33,6 +33,8 @@ #define MACHINFO_PGOFFIO 12 #define MACHINFO_NAME 16 +#define KERNEL_RAM_ADDR (PAGE_OFFSET + TEXT_OFFSET) + /* * swapper_pg_dir is the virtual address of the initial page table. * We place the page tables 16K below KERNEL_RAM_ADDR. Therefore, we must diff --git a/arch/arm/kernel/irq.c b/arch/arm/kernel/irq.c index d7099dbbb87..869c466e625 100644 --- a/arch/arm/kernel/irq.c +++ b/arch/arm/kernel/irq.c @@ -1027,7 +1027,6 @@ void __init init_irq_proc(void) void __init init_IRQ(void) { struct irqdesc *desc; - extern void init_dma(void); int irq; #ifdef CONFIG_SMP @@ -1041,7 +1040,6 @@ void __init init_IRQ(void) } init_arch_irq(); - init_dma(); } static int __init noirqdebug_setup(char *str) diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c index 30494aab829..54a21bdcba5 100644 --- a/arch/arm/kernel/process.c +++ b/arch/arm/kernel/process.c @@ -28,10 +28,9 @@ #include <linux/init.h> #include <linux/cpu.h> -#include <asm/system.h> -#include <asm/io.h> #include <asm/leds.h> #include <asm/processor.h> +#include <asm/system.h> #include <asm/uaccess.h> #include <asm/mach/time.h> diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c index 85774165e9f..2cab741ad0f 100644 --- a/arch/arm/kernel/setup.c +++ b/arch/arm/kernel/setup.c @@ -26,8 +26,6 @@ #include <asm/cpu.h> #include <asm/elf.h> -#include <asm/hardware.h> -#include <asm/io.h> #include <asm/procinfo.h> #include <asm/setup.h> #include <asm/mach-types.h> diff --git a/arch/arm/kernel/time.c b/arch/arm/kernel/time.c index fc4729106a3..d7d932c0286 100644 --- a/arch/arm/kernel/time.c +++ b/arch/arm/kernel/time.c @@ -29,9 +29,6 @@ #include <linux/sysdev.h> #include <linux/timer.h> -#include <asm/hardware.h> -#include <asm/io.h> -#include <asm/irq.h> #include <asm/leds.h> #include <asm/thread_info.h> #include <asm/mach/time.h> diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c index 45e9ea6cd2a..c9fe6f5f7ee 100644 --- a/arch/arm/kernel/traps.c +++ b/arch/arm/kernel/traps.c @@ -23,7 +23,6 @@ #include <asm/atomic.h> #include <asm/cacheflush.h> -#include <asm/io.h> #include <asm/system.h> #include <asm/uaccess.h> #include <asm/unistd.h> diff --git a/arch/arm/kernel/vmlinux.lds.S b/arch/arm/kernel/vmlinux.lds.S index 9a47770114d..2b254e88595 100644 --- a/arch/arm/kernel/vmlinux.lds.S +++ b/arch/arm/kernel/vmlinux.lds.S @@ -17,15 +17,13 @@ jiffies = jiffies_64; jiffies = jiffies_64 + 4; #endif +SECTIONS +{ #ifdef CONFIG_XIP_KERNEL -#define TEXTADDR XIP_VIRT_ADDR(CONFIG_XIP_PHYS_ADDR) + . = XIP_VIRT_ADDR(CONFIG_XIP_PHYS_ADDR); #else -#define TEXTADDR KERNEL_RAM_ADDR + . = PAGE_OFFSET + TEXT_OFFSET; #endif - -SECTIONS -{ - . = TEXTADDR; .init : { /* Init code and data */ _stext = .; _sinittext = .; @@ -104,7 +102,7 @@ SECTIONS #ifdef CONFIG_XIP_KERNEL __data_loc = ALIGN(4); /* location in binary */ - . = KERNEL_RAM_ADDR; + . = PAGE_OFFSET + TEXT_OFFSET; #else . = ALIGN(THREAD_SIZE); __data_loc = .; diff --git a/arch/arm/mach-aaec2000/clock.c b/arch/arm/mach-aaec2000/clock.c index 0340ddc4824..1c84c60941e 100644 --- a/arch/arm/mach-aaec2000/clock.c +++ b/arch/arm/mach-aaec2000/clock.c @@ -15,9 +15,9 @@ #include <linux/errno.h> #include <linux/err.h> #include <linux/string.h> +#include <linux/clk.h> #include <asm/semaphore.h> -#include <asm/hardware/clock.h> #include "clock.h" @@ -58,17 +58,6 @@ void clk_disable(struct clk *clk) } EXPORT_SYMBOL(clk_disable); -int clk_use(struct clk *clk) -{ - return 0; -} -EXPORT_SYMBOL(clk_use); - -void clk_unuse(struct clk *clk) -{ -} -EXPORT_SYMBOL(clk_unuse); - unsigned long clk_get_rate(struct clk *clk) { return clk->rate; diff --git a/arch/arm/mach-aaec2000/core.c b/arch/arm/mach-aaec2000/core.c index 4e706d9ad36..dce4815cf53 100644 --- a/arch/arm/mach-aaec2000/core.c +++ b/arch/arm/mach-aaec2000/core.c @@ -20,11 +20,11 @@ #include <linux/interrupt.h> #include <linux/timex.h> #include <linux/signal.h> +#include <linux/amba/bus.h> #include <asm/hardware.h> #include <asm/irq.h> #include <asm/sizes.h> -#include <asm/hardware/amba.h> #include <asm/mach/flash.h> #include <asm/mach/irq.h> diff --git a/arch/arm/mach-aaec2000/core.h b/arch/arm/mach-aaec2000/core.h index daefc0ea14a..b6029a95f19 100644 --- a/arch/arm/mach-aaec2000/core.h +++ b/arch/arm/mach-aaec2000/core.h @@ -9,7 +9,7 @@ * */ -#include <asm/hardware/amba_clcd.h> +#include <linux/amba/clcd.h> struct sys_timer; diff --git a/arch/arm/mach-clps711x/dma.c b/arch/arm/mach-clps711x/dma.c deleted file mode 100644 index af5a4de38ea..00000000000 --- a/arch/arm/mach-clps711x/dma.c +++ /dev/null @@ -1,27 +0,0 @@ -/* - * linux/arch/arm/mach-clps711x/dma.c - * - * Copyright (C) 2000 Deep Blue Solutions Ltd - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ -#include <linux/init.h> - -#include <asm/dma.h> -#include <asm/mach/dma.h> - -void __init arch_dma_init(dma_t *dma) -{ -} diff --git a/arch/arm/mach-epxa10db/dma.c b/arch/arm/mach-epxa10db/dma.c deleted file mode 100644 index 0151e9f1c06..00000000000 --- a/arch/arm/mach-epxa10db/dma.c +++ /dev/null @@ -1,28 +0,0 @@ -/* - * linux/arch/arm/mach-epxa10db/dma.c - * - * Copyright (C) 1999 ARM Limited - * Copyright (C) 2000 Deep Blue Solutions Ltd - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ -#include <linux/init.h> - -#include <asm/dma.h> -#include <asm/mach/dma.h> - -void __init arch_dma_init(dma_t *dma) -{ -} diff --git a/arch/arm/mach-footbridge/dma.c b/arch/arm/mach-footbridge/dma.c index a6b1396b095..7a54578b51a 100644 --- a/arch/arm/mach-footbridge/dma.c +++ b/arch/arm/mach-footbridge/dma.c @@ -15,6 +15,7 @@ #include <asm/dma.h> #include <asm/io.h> +#include <asm/scatterlist.h> #include <asm/mach/dma.h> #include <asm/hardware/dec21285.h> diff --git a/arch/arm/mach-imx/mx1ads.c b/arch/arm/mach-imx/mx1ads.c index 708e1b3faa1..c9e0cd8ed01 100644 --- a/arch/arm/mach-imx/mx1ads.c +++ b/arch/arm/mach-imx/mx1ads.c @@ -29,27 +29,27 @@ #include "generic.h" #include <asm/serial.h> -static struct resource mx1ads_resources[] = { +static struct resource cs89x0_resources[] = { [0] = { - .start = IMX_CS4_VIRT, - .end = IMX_CS4_VIRT + 16, + .start = IMX_CS4_PHYS + 0x300, + .end = IMX_CS4_PHYS + 0x300 + 16, .flags = IORESOURCE_MEM, }, [1] = { - .start = 13, - .end = 13, + .start = IRQ_GPIOC(17), + .end = IRQ_GPIOC(17), .flags = IORESOURCE_IRQ, }, }; -static struct platform_device mx1ads_device = { - .name = "mx1ads", - .num_resources = ARRAY_SIZE(mx1ads_resources), - .resource = mx1ads_resources, +static struct platform_device cs89x0_device = { + .name = "cirrus-cs89x0", + .num_resources = ARRAY_SIZE(cs89x0_resources), + .resource = cs89x0_resources, }; static struct platform_device *devices[] __initdata = { - &mx1ads_device, + &cs89x0_device, }; static void __init @@ -61,45 +61,10 @@ mx1ads_init(void) platform_add_devices(devices, ARRAY_SIZE(devices)); } -static struct map_desc mx1ads_io_desc[] __initdata = { - { - .virtual = IMX_CS0_VIRT, - .pfn = __phys_to_pfn(IMX_CS0_PHYS), - .length = IMX_CS0_SIZE, - .type = MT_DEVICE - }, { - .virtual = IMX_CS1_VIRT, - .pfn = __phys_to_pfn(IMX_CS1_PHYS), - .length = IMX_CS1_SIZE, - .type = MT_DEVICE - }, { - .virtual = IMX_CS2_VIRT, - .pfn = __phys_to_pfn(IMX_CS2_PHYS), - .length = IMX_CS2_SIZE, - .type = MT_DEVICE - }, { - .virtual = IMX_CS3_VIRT, - .pfn = __phys_to_pfn(IMX_CS3_PHYS), - .length = IMX_CS3_SIZE, - .type = MT_DEVICE - }, { - .virtual = IMX_CS4_VIRT, - .pfn = __phys_to_pfn(IMX_CS4_PHYS), - .length = IMX_CS4_SIZE, - .type = MT_DEVICE - }, { - .virtual = IMX_CS5_VIRT, - .pfn = __phys_to_pfn(IMX_CS5_PHYS), - .length = IMX_CS5_SIZE, - .type = MT_DEVICE - } -}; - static void __init mx1ads_map_io(void) { imx_map_io(); - iotable_init(mx1ads_io_desc, ARRAY_SIZE(mx1ads_io_desc)); } MACHINE_START(MX1ADS, "Motorola MX1ADS") diff --git a/arch/arm/mach-integrator/clock.c b/arch/arm/mach-integrator/clock.c index 73c360685ca..40684e01e86 100644 --- a/arch/arm/mach-integrator/clock.c +++ b/arch/arm/mach-integrator/clock.c @@ -14,9 +14,9 @@ #include <linux/errno.h> #include <linux/err.h> #include <linux/string.h> +#include <linux/clk.h> #include <asm/semaphore.h> -#include <asm/hardware/clock.h> #include <asm/hardware/icst525.h> #include "clock.h" @@ -58,17 +58,6 @@ void clk_disable(struct clk *clk) } EXPORT_SYMBOL(clk_disable); -int clk_use(struct clk *clk) -{ - return 0; -} -EXPORT_SYMBOL(clk_use); - -void clk_unuse(struct clk *clk) -{ -} -EXPORT_SYMBOL(clk_unuse); - unsigned long clk_get_rate(struct clk *clk) { return clk->rate; diff --git a/arch/arm/mach-integrator/core.c b/arch/arm/mach-integrator/core.c index dacbf504dae..20071a2767c 100644 --- a/arch/arm/mach-integrator/core.c +++ b/arch/arm/mach-integrator/core.c @@ -15,11 +15,11 @@ #include <linux/interrupt.h> #include <linux/sched.h> #include <linux/smp.h> +#include <linux/amba/bus.h> #include <asm/hardware.h> #include <asm/irq.h> #include <asm/io.h> -#include <asm/hardware/amba.h> #include <asm/hardware/arm_timer.h> #include <asm/arch/cm.h> #include <asm/system.h> diff --git a/arch/arm/mach-integrator/dma.c b/arch/arm/mach-integrator/dma.c deleted file mode 100644 index aae6f23cd72..00000000000 --- a/arch/arm/mach-integrator/dma.c +++ /dev/null @@ -1,35 +0,0 @@ -/* - * linux/arch/arm/mach-integrator/dma.c - * - * Copyright (C) 1999 ARM Limited - * Copyright (C) 2000 Deep Blue Solutions Ltd - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ -#include <linux/slab.h> -#include <linux/mman.h> -#include <linux/init.h> - -#include <asm/page.h> -#include <asm/pgtable.h> -#include <asm/dma.h> -#include <asm/io.h> -#include <asm/hardware.h> - -#include <asm/mach/dma.h> - -void __init arch_dma_init(dma_t *dma) -{ -} diff --git a/arch/arm/mach-integrator/impd1.c b/arch/arm/mach-integrator/impd1.c index a4bafee77a0..a85d471c5bf 100644 --- a/arch/arm/mach-integrator/impd1.c +++ b/arch/arm/mach-integrator/impd1.c @@ -18,11 +18,11 @@ #include <linux/device.h> #include <linux/errno.h> #include <linux/mm.h> +#include <linux/amba/bus.h> +#include <linux/amba/clcd.h> #include <asm/io.h> #include <asm/hardware/icst525.h> -#include <asm/hardware/amba.h> -#include <asm/hardware/amba_clcd.h> #include <asm/arch/lm.h> #include <asm/arch/impd1.h> #include <asm/sizes.h> diff --git a/arch/arm/mach-integrator/integrator_ap.c b/arch/arm/mach-integrator/integrator_ap.c index 4c0f7c65fac..3afedeb56a6 100644 --- a/arch/arm/mach-integrator/integrator_ap.c +++ b/arch/arm/mach-integrator/integrator_ap.c @@ -25,6 +25,8 @@ #include <linux/slab.h> #include <linux/string.h> #include <linux/sysdev.h> +#include <linux/amba/bus.h> +#include <linux/amba/kmi.h> #include <asm/hardware.h> #include <asm/io.h> @@ -32,8 +34,6 @@ #include <asm/setup.h> #include <asm/param.h> /* HZ */ #include <asm/mach-types.h> -#include <asm/hardware/amba.h> -#include <asm/hardware/amba_kmi.h> #include <asm/arch/lm.h> diff --git a/arch/arm/mach-integrator/integrator_cp.c b/arch/arm/mach-integrator/integrator_cp.c index 93f7ccb22c2..16cf2482a3e 100644 --- a/arch/arm/mach-integrator/integrator_cp.c +++ b/arch/arm/mach-integrator/integrator_cp.c @@ -16,15 +16,15 @@ #include <linux/slab.h> #include <linux/string.h> #include <linux/sysdev.h> +#include <linux/amba/bus.h> +#include <linux/amba/kmi.h> +#include <linux/amba/clcd.h> #include <asm/hardware.h> #include <asm/io.h> #include <asm/irq.h> #include <asm/setup.h> #include <asm/mach-types.h> -#include <asm/hardware/amba.h> -#include <asm/hardware/amba_kmi.h> -#include <asm/hardware/amba_clcd.h> #include <asm/hardware/icst525.h> #include <asm/arch/cm.h> diff --git a/arch/arm/mach-integrator/time.c b/arch/arm/mach-integrator/time.c index 1a844ca139e..9f46aaef896 100644 --- a/arch/arm/mach-integrator/time.c +++ b/arch/arm/mach-integrator/time.c @@ -14,8 +14,8 @@ #include <linux/interrupt.h> #include <linux/init.h> #include <linux/device.h> +#include <linux/amba/bus.h> -#include <asm/hardware/amba.h> #include <asm/hardware.h> #include <asm/io.h> #include <asm/uaccess.h> diff --git a/arch/arm/mach-iop3xx/iop331-setup.c b/arch/arm/mach-iop3xx/iop331-setup.c index 53f60614498..e6ea1cba6a1 100644 --- a/arch/arm/mach-iop3xx/iop331-setup.c +++ b/arch/arm/mach-iop3xx/iop331-setup.c @@ -18,7 +18,7 @@ #include <linux/platform_device.h> #include <linux/serial.h> #include <linux/tty.h> -#include <linux/serial_core.h> +#include <linux/serial_8250.h> #include <asm/io.h> #include <asm/pgtable.h> @@ -50,32 +50,74 @@ static struct map_desc iop331_std_desc[] __initdata = { } }; -static struct uart_port iop331_serial_ports[] = { - { - .membase = (char*)(IOP331_UART0_VIRT), - .mapbase = (IOP331_UART0_PHYS), - .irq = IRQ_IOP331_UART0, - .flags = UPF_SKIP_TEST, - .iotype = UPIO_MEM, - .regshift = 2, - .uartclk = IOP331_UART_XTAL, - .line = 0, - .type = PORT_XSCALE, - .fifosize = 32 - } , { - .membase = (char*)(IOP331_UART1_VIRT), - .mapbase = (IOP331_UART1_PHYS), - .irq = IRQ_IOP331_UART1, - .flags = UPF_SKIP_TEST, - .iotype = UPIO_MEM, - .regshift = 2, - .uartclk = IOP331_UART_XTAL, - .line = 1, - .type = PORT_XSCALE, - .fifosize = 32 +static struct resource iop33x_uart0_resources[] = { + [0] = { + .start = IOP331_UART0_PHYS, + .end = IOP331_UART0_PHYS + 0x3f, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_IOP331_UART0, + .end = IRQ_IOP331_UART0, + .flags = IORESOURCE_IRQ + } +}; + +static struct resource iop33x_uart1_resources[] = { + [0] = { + .start = IOP331_UART1_PHYS, + .end = IOP331_UART1_PHYS + 0x3f, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_IOP331_UART1, + .end = IRQ_IOP331_UART1, + .flags = IORESOURCE_IRQ } }; +static struct plat_serial8250_port iop33x_uart0_data[] = { + { + .membase = (char*)(IOP331_UART0_VIRT), + .mapbase = (IOP331_UART0_PHYS), + .irq = IRQ_IOP331_UART0, + .uartclk = IOP331_UART_XTAL, + .regshift = 2, + .iotype = UPIO_MEM, + .flags = UPF_SKIP_TEST, + }, + { }, +}; + +static struct plat_serial8250_port iop33x_uart1_data[] = { + { + .membase = (char*)(IOP331_UART1_VIRT), + .mapbase = (IOP331_UART1_PHYS), + .irq = IRQ_IOP331_UART1, + .uartclk = IOP331_UART_XTAL, + .regshift = 2, + .iotype = UPIO_MEM, + .flags = UPF_SKIP_TEST, + }, + { }, +}; + +static struct platform_device iop33x_uart0 = { + .name = "serial8250", + .id = 0, + .dev.platform_data = iop33x_uart0_data, + .num_resources = 2, + .resource = iop33x_uart0_resources, +}; + +static struct platform_device iop33x_uart1 = { + .name = "serial8250", + .id = 1, + .dev.platform_data = iop33x_uart1_data, + .num_resources = 2, + .resource = iop33x_uart1_resources, +}; + static struct resource iop33x_i2c_0_resources[] = { [0] = { .start = 0xfffff680, @@ -117,6 +159,8 @@ static struct platform_device iop33x_i2c_1_controller = { }; static struct platform_device *iop33x_devices[] __initdata = { + &iop33x_uart0, + &iop33x_uart1, &iop33x_i2c_0_controller, &iop33x_i2c_1_controller }; @@ -133,8 +177,6 @@ void __init iop33x_init(void) void __init iop331_map_io(void) { iotable_init(iop331_std_desc, ARRAY_SIZE(iop331_std_desc)); - early_serial_setup(&iop331_serial_ports[0]); - early_serial_setup(&iop331_serial_ports[1]); } #ifdef CONFIG_ARCH_IOP331 diff --git a/arch/arm/mach-ixp4xx/Kconfig b/arch/arm/mach-ixp4xx/Kconfig index 385285851cb..daadc78e271 100644 --- a/arch/arm/mach-ixp4xx/Kconfig +++ b/arch/arm/mach-ixp4xx/Kconfig @@ -71,6 +71,14 @@ config ARCH_PRPMC1100 PrPCM1100 Processor Mezanine Module. For more information on this platform, see <file:Documentation/arm/IXP4xx>. +config MACH_NAS100D + bool + prompt "NAS100D" + help + Say 'Y' here if you want your kernel to support Iomega's + NAS 100d device. For more information on this platform, + see http://www.nslu2-linux.org/wiki/NAS100d/HomePage + # # Avila and IXDP share the same source for now. Will change in future # diff --git a/arch/arm/mach-ixp4xx/Makefile b/arch/arm/mach-ixp4xx/Makefile index 7a15629c18d..0471044fa17 100644 --- a/arch/arm/mach-ixp4xx/Makefile +++ b/arch/arm/mach-ixp4xx/Makefile @@ -9,4 +9,5 @@ obj-$(CONFIG_MACH_IXDPG425) += ixdpg425-pci.o coyote-setup.o obj-$(CONFIG_ARCH_ADI_COYOTE) += coyote-pci.o coyote-setup.o obj-$(CONFIG_MACH_GTWX5715) += gtwx5715-pci.o gtwx5715-setup.o obj-$(CONFIG_MACH_NSLU2) += nslu2-pci.o nslu2-setup.o nslu2-power.o +obj-$(CONFIG_MACH_NAS100D) += nas100d-pci.o nas100d-setup.o nas100d-power.o diff --git a/arch/arm/mach-ixp4xx/common-pci.c b/arch/arm/mach-ixp4xx/common-pci.c index 9795da270e3..6e3462ed530 100644 --- a/arch/arm/mach-ixp4xx/common-pci.c +++ b/arch/arm/mach-ixp4xx/common-pci.c @@ -341,6 +341,29 @@ int dma_needs_bounce(struct device *dev, dma_addr_t dma_addr, size_t size) return (dev->bus == &pci_bus_type ) && ((dma_addr + size) >= SZ_64M); } +/* + * Only first 64MB of memory can be accessed via PCI. + * We use GFP_DMA to allocate safe buffers to do map/unmap. + * This is really ugly and we need a better way of specifying + * DMA-capable regions of memory. + */ +void __init ixp4xx_adjust_zones(int node, unsigned long *zone_size, + unsigned long *zhole_size) +{ + unsigned int sz = SZ_64M >> PAGE_SHIFT; + + /* + * Only adjust if > 64M on current system + */ + if (node || (zone_size[0] <= sz)) + return; + + zone_size[1] = zone_size[0] - sz; + zone_size[0] = sz; + zhole_size[1] = zhole_size[0]; + zhole_size[0] = 0; +} + void __init ixp4xx_pci_preinit(void) { unsigned long processor_id; diff --git a/arch/arm/mach-ixp4xx/common.c b/arch/arm/mach-ixp4xx/common.c index f3c687cf007..6b393691d0e 100644 --- a/arch/arm/mach-ixp4xx/common.c +++ b/arch/arm/mach-ixp4xx/common.c @@ -142,6 +142,8 @@ static int ixp4xx_set_irq_type(unsigned int irq, unsigned int type) *int_reg &= ~(IXP4XX_GPIO_STYLE_CLEAR << (line * IXP4XX_GPIO_STYLE_SIZE)); + *IXP4XX_GPIO_GPISR = (1 << line); + /* Set the new style */ *int_reg |= (int_style << (line * IXP4XX_GPIO_STYLE_SIZE)); @@ -169,7 +171,7 @@ static void ixp4xx_irq_ack(unsigned int irq) int line = (irq < 32) ? irq2gpio[irq] : -1; if (line >= 0) - gpio_line_isr_clear(line); + *IXP4XX_GPIO_GPISR = (1 << line); } /* @@ -330,11 +332,27 @@ static struct platform_device *ixp46x_devices[] __initdata = { &ixp46x_i2c_controller }; +unsigned long ixp4xx_exp_bus_size; + void __init ixp4xx_sys_init(void) { + ixp4xx_exp_bus_size = SZ_16M; + if (cpu_is_ixp46x()) { + int region; + platform_add_devices(ixp46x_devices, ARRAY_SIZE(ixp46x_devices)); + + for (region = 0; region < 7; region++) { + if((*(IXP4XX_EXP_REG(0x4 * region)) & 0x200)) { + ixp4xx_exp_bus_size = SZ_32M; + break; + } + } } + + printk("IXP4xx: Using %uMiB expansion bus window size\n", + ixp4xx_exp_bus_size >> 20); } diff --git a/arch/arm/mach-ixp4xx/coyote-pci.c b/arch/arm/mach-ixp4xx/coyote-pci.c index 60de8a94cff..e6b7fcd923f 100644 --- a/arch/arm/mach-ixp4xx/coyote-pci.c +++ b/arch/arm/mach-ixp4xx/coyote-pci.c @@ -33,9 +33,6 @@ void __init coyote_pci_preinit(void) set_irq_type(IRQ_COYOTE_PCI_SLOT0, IRQT_LOW); set_irq_type(IRQ_COYOTE_PCI_SLOT1, IRQT_LOW); - gpio_line_isr_clear(COYOTE_PCI_SLOT0_PIN); - gpio_line_isr_clear(COYOTE_PCI_SLOT1_PIN); - ixp4xx_pci_preinit(); } diff --git a/arch/arm/mach-ixp4xx/coyote-setup.c b/arch/arm/mach-ixp4xx/coyote-setup.c index 050c9276891..679594a7398 100644 --- a/arch/arm/mach-ixp4xx/coyote-setup.c +++ b/arch/arm/mach-ixp4xx/coyote-setup.c @@ -14,6 +14,7 @@ #include <linux/serial.h> #include <linux/tty.h> #include <linux/serial_8250.h> +#include <linux/slab.h> #include <asm/types.h> #include <asm/setup.h> @@ -30,8 +31,6 @@ static struct flash_platform_data coyote_flash_data = { }; static struct resource coyote_flash_resource = { - .start = COYOTE_FLASH_BASE, - .end = COYOTE_FLASH_BASE + COYOTE_FLASH_SIZE - 1, .flags = IORESOURCE_MEM, }; @@ -81,6 +80,11 @@ static struct platform_device *coyote_devices[] __initdata = { static void __init coyote_init(void) { + ixp4xx_sys_init(); + + coyote_flash_resource.start = IXP4XX_EXP_BUS_BASE(0); + coyote_flash_resource.end = IXP4XX_EXP_BUS_BASE(0) + SZ_32M - 1; + *IXP4XX_EXP_CS0 |= IXP4XX_FLASH_WRITABLE; *IXP4XX_EXP_CS1 = *IXP4XX_EXP_CS0; @@ -91,8 +95,6 @@ static void __init coyote_init(void) coyote_uart_data[0].irq = IRQ_IXP4XX_UART1; } - - ixp4xx_sys_init(); platform_add_devices(coyote_devices, ARRAY_SIZE(coyote_devices)); } diff --git a/arch/arm/mach-ixp4xx/gtwx5715-setup.c b/arch/arm/mach-ixp4xx/gtwx5715-setup.c index 29a6d02fa85..03867048997 100644 --- a/arch/arm/mach-ixp4xx/gtwx5715-setup.c +++ b/arch/arm/mach-ixp4xx/gtwx5715-setup.c @@ -27,6 +27,7 @@ #include <linux/serial.h> #include <linux/tty.h> #include <linux/serial_8250.h> +#include <linux/slab.h> #include <asm/types.h> #include <asm/setup.h> @@ -106,11 +107,9 @@ static struct flash_platform_data gtwx5715_flash_data = { .width = 2, }; -static struct resource gtwx5715_flash_resource = { - .start = GTWX5715_FLASH_BASE, - .end = GTWX5715_FLASH_BASE + GTWX5715_FLASH_SIZE - 1, +static struct gtw5715_flash_resource = { .flags = IORESOURCE_MEM, -}; +} static struct platform_device gtwx5715_flash = { .name = "IXP4XX-Flash", @@ -129,6 +128,14 @@ static struct platform_device *gtwx5715_devices[] __initdata = { static void __init gtwx5715_init(void) { + ixp4xx_sys_init(); + + if (!flash_resource) + printk(KERN_ERR "Could not allocate flash resource\n"); + + gtwx5715_flash_resource.start = IXP4XX_EXP_BUS_BASE(0); + gtwx5715_flash_resource.end = IXP4XX_EXP_BUS_BASE(0) + SZ_8M - 1; + platform_add_devices(gtwx5715_devices, ARRAY_SIZE(gtwx5715_devices)); } diff --git a/arch/arm/mach-ixp4xx/ixdp425-pci.c b/arch/arm/mach-ixp4xx/ixdp425-pci.c index f9a1d3e7d69..da415d5d7f3 100644 --- a/arch/arm/mach-ixp4xx/ixdp425-pci.c +++ b/arch/arm/mach-ixp4xx/ixdp425-pci.c @@ -32,11 +32,6 @@ void __init ixdp425_pci_preinit(void) set_irq_type(IRQ_IXDP425_PCI_INTC, IRQT_LOW); set_irq_type(IRQ_IXDP425_PCI_INTD, IRQT_LOW); - gpio_line_isr_clear(IXDP425_PCI_INTA_PIN); - gpio_line_isr_clear(IXDP425_PCI_INTB_PIN); - gpio_line_isr_clear(IXDP425_PCI_INTC_PIN); - gpio_line_isr_clear(IXDP425_PCI_INTD_PIN); - ixp4xx_pci_preinit(); } diff --git a/arch/arm/mach-ixp4xx/ixdp425-setup.c b/arch/arm/mach-ixp4xx/ixdp425-setup.c index 3a22d84e104..c2e105c89c9 100644 --- a/arch/arm/mach-ixp4xx/ixdp425-setup.c +++ b/arch/arm/mach-ixp4xx/ixdp425-setup.c @@ -14,6 +14,7 @@ #include <linux/serial.h> #include <linux/tty.h> #include <linux/serial_8250.h> +#include <linux/slab.h> #include <asm/types.h> #include <asm/setup.h> @@ -30,8 +31,6 @@ static struct flash_platform_data ixdp425_flash_data = { }; static struct resource ixdp425_flash_resource = { - .start = IXDP425_FLASH_BASE, - .end = IXDP425_FLASH_BASE + IXDP425_FLASH_SIZE - 1, .flags = IORESOURCE_MEM, }; @@ -108,17 +107,13 @@ static struct platform_device *ixdp425_devices[] __initdata = { &ixdp425_uart }; - static void __init ixdp425_init(void) { ixp4xx_sys_init(); - /* - * IXP465 has 32MB window - */ - if (machine_is_ixdp465()) { - ixdp425_flash_resource.end += IXDP425_FLASH_SIZE; - } + ixdp425_flash_resource.start = IXP4XX_EXP_BUS_BASE(0); + ixdp425_flash_resource.end = + IXP4XX_EXP_BUS_BASE(0) + ixp4xx_exp_bus_size - 1; platform_add_devices(ixdp425_devices, ARRAY_SIZE(ixdp425_devices)); } diff --git a/arch/arm/mach-ixp4xx/ixdpg425-pci.c b/arch/arm/mach-ixp4xx/ixdpg425-pci.c index fe5e7660de1..526fb6175bc 100644 --- a/arch/arm/mach-ixp4xx/ixdpg425-pci.c +++ b/arch/arm/mach-ixp4xx/ixdpg425-pci.c @@ -32,9 +32,6 @@ void __init ixdpg425_pci_preinit(void) set_irq_type(IRQ_IXP4XX_GPIO6, IRQT_LOW); set_irq_type(IRQ_IXP4XX_GPIO7, IRQT_LOW); - gpio_line_isr_clear(6); - gpio_line_isr_clear(7); - ixp4xx_pci_preinit(); } diff --git a/arch/arm/mach-ixp4xx/nas100d-pci.c b/arch/arm/mach-ixp4xx/nas100d-pci.c new file mode 100644 index 00000000000..26b7c001ff6 --- /dev/null +++ b/arch/arm/mach-ixp4xx/nas100d-pci.c @@ -0,0 +1,71 @@ +/* + * arch/arm/mach-ixp4xx/nas100d-pci.c + * + * NAS 100d board-level PCI initialization + * + * based on ixdp425-pci.c: + * Copyright (C) 2002 Intel Corporation. + * Copyright (C) 2003-2004 MontaVista Software, Inc. + * + * Maintainer: http://www.nslu2-linux.org/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + */ + +#include <linux/config.h> +#include <linux/pci.h> +#include <linux/init.h> + +#include <asm/mach/pci.h> +#include <asm/mach-types.h> + +void __init nas100d_pci_preinit(void) +{ + set_irq_type(IRQ_NAS100D_PCI_INTA, IRQT_LOW); + set_irq_type(IRQ_NAS100D_PCI_INTB, IRQT_LOW); + set_irq_type(IRQ_NAS100D_PCI_INTC, IRQT_LOW); + set_irq_type(IRQ_NAS100D_PCI_INTD, IRQT_LOW); + set_irq_type(IRQ_NAS100D_PCI_INTE, IRQT_LOW); + + ixp4xx_pci_preinit(); +} + +static int __init nas100d_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +{ + static int pci_irq_table[NAS100D_PCI_MAX_DEV][NAS100D_PCI_IRQ_LINES] = + { + { IRQ_NAS100D_PCI_INTA, -1, -1 }, + { IRQ_NAS100D_PCI_INTB, -1, -1 }, + { IRQ_NAS100D_PCI_INTC, IRQ_NAS100D_PCI_INTD, IRQ_NAS100D_PCI_INTE }, + }; + + int irq = -1; + + if (slot >= 1 && slot <= NAS100D_PCI_MAX_DEV && + pin >= 1 && pin <= NAS100D_PCI_IRQ_LINES) + irq = pci_irq_table[slot-1][pin-1]; + + return irq; +} + +struct hw_pci __initdata nas100d_pci = { + .nr_controllers = 1, + .preinit = nas100d_pci_preinit, + .swizzle = pci_std_swizzle, + .setup = ixp4xx_setup, + .scan = ixp4xx_scan_bus, + .map_irq = nas100d_map_irq, +}; + +int __init nas100d_pci_init(void) +{ + if (machine_is_nas100d()) + pci_common_init(&nas100d_pci); + + return 0; +} + +subsys_initcall(nas100d_pci_init); diff --git a/arch/arm/mach-ixp4xx/nas100d-power.c b/arch/arm/mach-ixp4xx/nas100d-power.c new file mode 100644 index 00000000000..2bec69bfa71 --- /dev/null +++ b/arch/arm/mach-ixp4xx/nas100d-power.c @@ -0,0 +1,67 @@ +/* + * arch/arm/mach-ixp4xx/nas100d-power.c + * + * NAS 100d Power/Reset driver + * + * Copyright (C) 2005 Tower Technologies + * + * based on nas100d-io.c + * Copyright (C) 2004 Karen Spearel + * + * Author: Alessandro Zummo <a.zummo@towertech.it> + * Maintainers: http://www.nslu2-linux.org/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + */ + +#include <linux/module.h> +#include <linux/reboot.h> +#include <linux/interrupt.h> + +#include <asm/mach-types.h> + +extern void ctrl_alt_del(void); + +static irqreturn_t nas100d_reset_handler(int irq, void *dev_id, struct pt_regs *regs) +{ + /* Signal init to do the ctrlaltdel action, this will bypass init if + * it hasn't started and do a kernel_restart. + */ + ctrl_alt_del(); + + return IRQ_HANDLED; +} + +static int __init nas100d_power_init(void) +{ + if (!(machine_is_nas100d())) + return 0; + + set_irq_type(NAS100D_RB_IRQ, IRQT_LOW); + + if (request_irq(NAS100D_RB_IRQ, &nas100d_reset_handler, + SA_INTERRUPT, "NAS100D reset button", NULL) < 0) { + + printk(KERN_DEBUG "Reset Button IRQ %d not available\n", + NAS100D_RB_IRQ); + + return -EIO; + } + + return 0; +} + +static void __exit nas100d_power_exit(void) +{ + free_irq(NAS100D_RB_IRQ, NULL); +} + +module_init(nas100d_power_init); +module_exit(nas100d_power_exit); + +MODULE_AUTHOR("Alessandro Zummo <a.zummo@towertech.it>"); +MODULE_DESCRIPTION("NAS100D Power/Reset driver"); +MODULE_LICENSE("GPL"); diff --git a/arch/arm/mach-ixp4xx/nas100d-setup.c b/arch/arm/mach-ixp4xx/nas100d-setup.c new file mode 100644 index 00000000000..49998a8bd4e --- /dev/null +++ b/arch/arm/mach-ixp4xx/nas100d-setup.c @@ -0,0 +1,135 @@ +/* + * arch/arm/mach-ixp4xx/nas100d-setup.c + * + * NAS 100d board-setup + * + * based ixdp425-setup.c: + * Copyright (C) 2003-2004 MontaVista Software, Inc. + * + * Author: Alessandro Zummo <a.zummo@towertech.it> + * Author: Rod Whitby <rod@whitby.id.au> + * Maintainers: http://www.nslu2-linux.org/ + * + */ + +#include <linux/kernel.h> +#include <linux/serial.h> +#include <linux/serial_8250.h> + +#include <asm/mach-types.h> +#include <asm/mach/arch.h> +#include <asm/mach/flash.h> + +static struct flash_platform_data nas100d_flash_data = { + .map_name = "cfi_probe", + .width = 2, +}; + +static struct resource nas100d_flash_resource = { + .flags = IORESOURCE_MEM, +}; + +static struct platform_device nas100d_flash = { + .name = "IXP4XX-Flash", + .id = 0, + .dev.platform_data = &nas100d_flash_data, + .num_resources = 1, + .resource = &nas100d_flash_resource, +}; + +static struct ixp4xx_i2c_pins nas100d_i2c_gpio_pins = { + .sda_pin = NAS100D_SDA_PIN, + .scl_pin = NAS100D_SCL_PIN, +}; + +static struct platform_device nas100d_i2c_controller = { + .name = "IXP4XX-I2C", + .id = 0, + .dev.platform_data = &nas100d_i2c_gpio_pins, + .num_resources = 0, +}; + +static struct resource nas100d_uart_resources[] = { + { + .start = IXP4XX_UART1_BASE_PHYS, + .end = IXP4XX_UART1_BASE_PHYS + 0x0fff, + .flags = IORESOURCE_MEM, + }, + { + .start = IXP4XX_UART2_BASE_PHYS, + .end = IXP4XX_UART2_BASE_PHYS + 0x0fff, + .flags = IORESOURCE_MEM, + } +}; + +static struct plat_serial8250_port nas100d_uart_data[] = { + { + .mapbase = IXP4XX_UART1_BASE_PHYS, + .membase = (char *)IXP4XX_UART1_BASE_VIRT + REG_OFFSET, + .irq = IRQ_IXP4XX_UART1, + .flags = UPF_BOOT_AUTOCONF, + .iotype = UPIO_MEM, + .regshift = 2, + .uartclk = IXP4XX_UART_XTAL, + }, + { + .mapbase = IXP4XX_UART2_BASE_PHYS, + .membase = (char *)IXP4XX_UART2_BASE_VIRT + REG_OFFSET, + .irq = IRQ_IXP4XX_UART2, + .flags = UPF_BOOT_AUTOCONF, + .iotype = UPIO_MEM, + .regshift = 2, + .uartclk = IXP4XX_UART_XTAL, + }, + { } +}; + +static struct platform_device nas100d_uart = { + .name = "serial8250", + .id = PLAT8250_DEV_PLATFORM, + .dev.platform_data = nas100d_uart_data, + .num_resources = 2, + .resource = nas100d_uart_resources, +}; + +static struct platform_device *nas100d_devices[] __initdata = { + &nas100d_i2c_controller, + &nas100d_flash, + &nas100d_uart, +}; + +static void nas100d_power_off(void) +{ + /* This causes the box to drop the power and go dead. */ + + /* enable the pwr cntl gpio */ + gpio_line_config(NAS100D_PO_GPIO, IXP4XX_GPIO_OUT); + + /* do the deed */ + gpio_line_set(NAS100D_PO_GPIO, IXP4XX_GPIO_HIGH); +} + +static void __init nas100d_init(void) +{ + ixp4xx_sys_init(); + + nas100d_flash_resource.start = IXP4XX_EXP_BUS_BASE(0); + nas100d_flash_resource.end = + IXP4XX_EXP_BUS_BASE(0) + ixp4xx_exp_bus_size - 1; + + pm_power_off = nas100d_power_off; + + platform_add_devices(nas100d_devices, ARRAY_SIZE(nas100d_devices)); +} + +MACHINE_START(NAS100D, "Iomega NAS 100d") + /* Maintainer: www.nslu2-linux.org */ + .phys_ram = PHYS_OFFSET, + .phys_io = IXP4XX_PERIPHERAL_BASE_PHYS, + .io_pg_offst = ((IXP4XX_PERIPHERAL_BASE_VIRT) >> 18) & 0xFFFC, + .boot_params = 0x00000100, + .map_io = ixp4xx_map_io, + .init_irq = ixp4xx_init_irq, + .timer = &ixp4xx_timer, + .init_machine = nas100d_init, +MACHINE_END diff --git a/arch/arm/mach-ixp4xx/nslu2-pci.c b/arch/arm/mach-ixp4xx/nslu2-pci.c index a575f2e0b2c..ece860444d5 100644 --- a/arch/arm/mach-ixp4xx/nslu2-pci.c +++ b/arch/arm/mach-ixp4xx/nslu2-pci.c @@ -28,14 +28,6 @@ void __init nslu2_pci_preinit(void) set_irq_type(IRQ_NSLU2_PCI_INTB, IRQT_LOW); set_irq_type(IRQ_NSLU2_PCI_INTC, IRQT_LOW); - gpio_line_isr_clear(NSLU2_PCI_INTA_PIN); - gpio_line_isr_clear(NSLU2_PCI_INTB_PIN); - gpio_line_isr_clear(NSLU2_PCI_INTC_PIN); - - /* INTD is not configured as GPIO is used - * for the power input button. - */ - ixp4xx_pci_preinit(); } diff --git a/arch/arm/mach-ixp4xx/nslu2-power.c b/arch/arm/mach-ixp4xx/nslu2-power.c index 18fbc8c0fb3..b0ad9e901f6 100644 --- a/arch/arm/mach-ixp4xx/nslu2-power.c +++ b/arch/arm/mach-ixp4xx/nslu2-power.c @@ -54,9 +54,6 @@ static int __init nslu2_power_init(void) set_irq_type(NSLU2_RB_IRQ, IRQT_LOW); set_irq_type(NSLU2_PB_IRQ, IRQT_HIGH); - gpio_line_isr_clear(NSLU2_RB_GPIO); - gpio_line_isr_clear(NSLU2_PB_GPIO); - if (request_irq(NSLU2_RB_IRQ, &nslu2_reset_handler, SA_INTERRUPT, "NSLU2 reset button", NULL) < 0) { diff --git a/arch/arm/mach-omap1/board-palmte.c b/arch/arm/mach-omap1/board-palmte.c index 540b20d78cc..5c975eb5c34 100644 --- a/arch/arm/mach-omap1/board-palmte.c +++ b/arch/arm/mach-omap1/board-palmte.c @@ -19,6 +19,7 @@ #include <linux/init.h> #include <linux/platform_device.h> #include <linux/notifier.h> +#include <linux/clk.h> #include <asm/hardware.h> #include <asm/mach-types.h> @@ -30,7 +31,6 @@ #include <asm/arch/usb.h> #include <asm/arch/board.h> #include <asm/arch/common.h> -#include <asm/hardware/clock.h> static void __init omap_generic_init_irq(void) { diff --git a/arch/arm/mach-omap1/clock.c b/arch/arm/mach-omap1/clock.c index 4277eee44ed..9d862f86bba 100644 --- a/arch/arm/mach-omap1/clock.c +++ b/arch/arm/mach-omap1/clock.c @@ -16,9 +16,9 @@ #include <linux/list.h> #include <linux/errno.h> #include <linux/err.h> +#include <linux/clk.h> #include <asm/io.h> -#include <asm/hardware/clock.h> #include <asm/arch/usb.h> #include <asm/arch/clock.h> diff --git a/arch/arm/mach-omap1/serial.c b/arch/arm/mach-omap1/serial.c index 6810cfb8446..fcfb81d13cf 100644 --- a/arch/arm/mach-omap1/serial.c +++ b/arch/arm/mach-omap1/serial.c @@ -17,10 +17,10 @@ #include <linux/tty.h> #include <linux/serial_8250.h> #include <linux/serial_reg.h> +#include <linux/clk.h> #include <asm/io.h> #include <asm/mach-types.h> -#include <asm/hardware/clock.h> #include <asm/arch/board.h> #include <asm/arch/mux.h> diff --git a/arch/arm/mach-omap2/clock.c b/arch/arm/mach-omap2/clock.c index 85818d9f263..5407b954915 100644 --- a/arch/arm/mach-omap2/clock.c +++ b/arch/arm/mach-omap2/clock.c @@ -22,10 +22,10 @@ #include <linux/list.h> #include <linux/errno.h> #include <linux/delay.h> +#include <linux/clk.h> #include <asm/io.h> -#include <asm/hardware/clock.h> #include <asm/arch/clock.h> #include <asm/arch/sram.h> #include <asm/arch/prcm.h> diff --git a/arch/arm/mach-omap2/serial.c b/arch/arm/mach-omap2/serial.c index f4df04fe1dd..e1bd46a96e1 100644 --- a/arch/arm/mach-omap2/serial.c +++ b/arch/arm/mach-omap2/serial.c @@ -16,9 +16,9 @@ #include <linux/init.h> #include <linux/serial_8250.h> #include <linux/serial_reg.h> +#include <linux/clk.h> #include <asm/io.h> -#include <asm/hardware/clock.h> #include <asm/arch/common.h> #include <asm/arch/board.h> diff --git a/arch/arm/mach-omap2/timer-gp.c b/arch/arm/mach-omap2/timer-gp.c index 9ec11443200..23d36b1c40f 100644 --- a/arch/arm/mach-omap2/timer-gp.c +++ b/arch/arm/mach-omap2/timer-gp.c @@ -21,10 +21,11 @@ #include <linux/time.h> #include <linux/interrupt.h> #include <linux/err.h> +#include <linux/clk.h> + #include <asm/mach/time.h> #include <asm/delay.h> #include <asm/io.h> -#include <asm/hardware/clock.h> #define OMAP2_GP_TIMER1_BASE 0x48028000 #define OMAP2_GP_TIMER2_BASE 0x4802a000 diff --git a/arch/arm/mach-pxa/Kconfig b/arch/arm/mach-pxa/Kconfig index 2a58499c096..c1d77f5b382 100644 --- a/arch/arm/mach-pxa/Kconfig +++ b/arch/arm/mach-pxa/Kconfig @@ -112,12 +112,14 @@ config IWMMXT config PXA_SHARP_C7xx bool select PXA_SSP + select SHARPSL_PM help Enable support for all Sharp C7xx models config PXA_SHARP_Cxx00 bool select PXA_SSP + select SHARPSL_PM help Enable common support for Sharp Cxx00 models diff --git a/arch/arm/mach-pxa/corgi_pm.c b/arch/arm/mach-pxa/corgi_pm.c index 599be14754f..7a1ab73e9e1 100644 --- a/arch/arm/mach-pxa/corgi_pm.c +++ b/arch/arm/mach-pxa/corgi_pm.c @@ -33,19 +33,7 @@ static void corgi_charger_init(void) pxa_gpio_mode(CORGI_GPIO_CHRG_ON | GPIO_OUT); pxa_gpio_mode(CORGI_GPIO_CHRG_UKN | GPIO_OUT); pxa_gpio_mode(CORGI_GPIO_KEY_INT | GPIO_IN); -} - -static void corgi_charge_led(int val) -{ - if (val == SHARPSL_LED_ERROR) { - dev_dbg(sharpsl_pm.dev, "Charge LED Error\n"); - } else if (val == SHARPSL_LED_ON) { - dev_dbg(sharpsl_pm.dev, "Charge LED On\n"); - GPSR0 = GPIO_bit(CORGI_GPIO_LED_ORANGE); - } else { - dev_dbg(sharpsl_pm.dev, "Charge LED Off\n"); - GPCR0 = GPIO_bit(CORGI_GPIO_LED_ORANGE); - } + sharpsl_pm_pxa_init(); } static void corgi_measure_temp(int on) @@ -138,15 +126,15 @@ static int corgi_should_wakeup(unsigned int resume_on_alarm) dev_dbg(sharpsl_pm.dev, "GPLR0 = %x,%x\n", GPLR0, PEDR); if ((PEDR & GPIO_bit(CORGI_GPIO_AC_IN))) { - if (STATUS_AC_IN()) { + if (sharpsl_pm.machinfo->read_devdata(SHARPSL_STATUS_ACIN)) { /* charge on */ dev_dbg(sharpsl_pm.dev, "ac insert\n"); sharpsl_pm.flags |= SHARPSL_DO_OFFLINE_CHRG; } else { /* charge off */ dev_dbg(sharpsl_pm.dev, "ac remove\n"); - CHARGE_LED_OFF(); - CHARGE_OFF(); + sharpsl_pm_led(SHARPSL_LED_OFF); + sharpsl_pm.machinfo->charge(0); sharpsl_pm.charge_mode = CHRG_OFF; } } @@ -172,23 +160,39 @@ static unsigned long corgi_charger_wakeup(void) return ~GPLR0 & ( GPIO_bit(CORGI_GPIO_AC_IN) | GPIO_bit(CORGI_GPIO_KEY_INT) | GPIO_bit(CORGI_GPIO_WAKEUP) ); } -static int corgi_acin_status(void) +unsigned long corgipm_read_devdata(int type) { - return ((GPLR(CORGI_GPIO_AC_IN) & GPIO_bit(CORGI_GPIO_AC_IN)) != 0); + switch(type) { + case SHARPSL_STATUS_ACIN: + return ((GPLR(CORGI_GPIO_AC_IN) & GPIO_bit(CORGI_GPIO_AC_IN)) != 0); + case SHARPSL_STATUS_LOCK: + return READ_GPIO_BIT(sharpsl_pm.machinfo->gpio_batlock); + case SHARPSL_STATUS_CHRGFULL: + return READ_GPIO_BIT(sharpsl_pm.machinfo->gpio_batfull); + case SHARPSL_STATUS_FATAL: + return READ_GPIO_BIT(sharpsl_pm.machinfo->gpio_fatal); + case SHARPSL_ACIN_VOLT: + return sharpsl_pm_pxa_read_max1111(MAX1111_ACIN_VOLT); + case SHARPSL_BATT_TEMP: + return sharpsl_pm_pxa_read_max1111(MAX1111_BATT_TEMP); + case SHARPSL_BATT_VOLT: + default: + return sharpsl_pm_pxa_read_max1111(MAX1111_BATT_VOLT); + } } static struct sharpsl_charger_machinfo corgi_pm_machinfo = { .init = corgi_charger_init, + .exit = sharpsl_pm_pxa_remove, .gpio_batlock = CORGI_GPIO_BAT_COVER, .gpio_acin = CORGI_GPIO_AC_IN, .gpio_batfull = CORGI_GPIO_CHRG_FULL, - .status_acin = corgi_acin_status, .discharge = corgi_discharge, .charge = corgi_charge, - .chargeled = corgi_charge_led, .measure_temp = corgi_measure_temp, .presuspend = corgi_presuspend, .postsuspend = corgi_postsuspend, + .read_devdata = corgipm_read_devdata, .charger_wakeup = corgi_charger_wakeup, .should_wakeup = corgi_should_wakeup, .bat_levels = 40, diff --git a/arch/arm/mach-pxa/mainstone.c b/arch/arm/mach-pxa/mainstone.c index 277498ae5b6..8da9d3efe9a 100644 --- a/arch/arm/mach-pxa/mainstone.c +++ b/arch/arm/mach-pxa/mainstone.c @@ -427,6 +427,12 @@ static void __init mainstone_init(void) printk(KERN_NOTICE "Mainstone configured to boot from %s\n", mst_flash_data[0].name); + /* system bus arbiter setting + * - Core_Park + * - LCD_wt:DMA_wt:CORE_Wt = 2:3:4 + */ + ARB_CNTRL = ARB_CORE_PARK | 0x234; + /* * On Mainstone, we route AC97_SYSCLK via GPIO45 to * the audio daughter card diff --git a/arch/arm/mach-pxa/sharpsl.h b/arch/arm/mach-pxa/sharpsl.h index b0c40a1d667..da4769caaf7 100644 --- a/arch/arm/mach-pxa/sharpsl.h +++ b/arch/arm/mach-pxa/sharpsl.h @@ -1,7 +1,17 @@ /* - * SharpSL SSP Driver + * Copyright (c) 2004-2005 Richard Purdie + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * */ +#include <asm/hardware/sharpsl_pm.h> + +/* + * SharpSL SSP Driver + */ struct corgissp_machinfo { int port; int cs_lcdcon; @@ -14,18 +24,18 @@ struct corgissp_machinfo { void corgi_ssp_set_machinfo(struct corgissp_machinfo *machinfo); + /* * SharpSL Backlight */ - void corgi_bl_set_intensity(int intensity); void spitz_bl_set_intensity(int intensity); void akita_bl_set_intensity(int intensity); + /* * SharpSL Touchscreen Driver */ - unsigned long corgi_get_hsync_len(void); unsigned long spitz_get_hsync_len(void); void corgi_put_hsync(void); @@ -33,89 +43,22 @@ void spitz_put_hsync(void); void corgi_wait_hsync(void); void spitz_wait_hsync(void); + /* * SharpSL Battery/PM Driver */ -struct sharpsl_charger_machinfo { - void (*init)(void); - int gpio_acin; - int gpio_batfull; - int gpio_batlock; - int gpio_fatal; - int (*status_acin)(void); - void (*discharge)(int); - void (*discharge1)(int); - void (*charge)(int); - void (*chargeled)(int); - void (*measure_temp)(int); - void (*presuspend)(void); - void (*postsuspend)(void); - unsigned long (*charger_wakeup)(void); - int (*should_wakeup)(unsigned int resume_on_alarm); - int bat_levels; - struct battery_thresh *bat_levels_noac; - struct battery_thresh *bat_levels_acin; - int status_high_acin; - int status_low_acin; - int status_high_noac; - int status_low_noac; -}; - -struct battery_thresh { - int voltage; - int percentage; -}; - -struct battery_stat { - int ac_status; /* APM AC Present/Not Present */ - int mainbat_status; /* APM Main Battery Status */ - int mainbat_percent; /* Main Battery Percentage Charge */ - int mainbat_voltage; /* Main Battery Voltage */ -}; - -struct sharpsl_pm_status { - struct device *dev; - struct timer_list ac_timer; - struct timer_list chrg_full_timer; - - int charge_mode; -#define CHRG_ERROR (-1) -#define CHRG_OFF (0) -#define CHRG_ON (1) -#define CHRG_DONE (2) - - unsigned int flags; -#define SHARPSL_SUSPENDED (1 << 0) /* Device is Suspended */ -#define SHARPSL_ALARM_ACTIVE (1 << 1) /* Alarm is for charging event (not user) */ -#define SHARPSL_BL_LIMIT (1 << 2) /* Backlight Intensity Limited */ -#define SHARPSL_APM_QUEUED (1 << 3) /* APM Event Queued */ -#define SHARPSL_DO_OFFLINE_CHRG (1 << 4) /* Trigger the offline charger */ +#define READ_GPIO_BIT(x) (GPLR(x) & GPIO_bit(x)) - int full_count; - unsigned long charge_start_time; - struct sharpsl_charger_machinfo *machinfo; - struct battery_stat battstat; -}; +/* MAX1111 Channel Definitions */ +#define MAX1111_BATT_VOLT 4u +#define MAX1111_BATT_TEMP 2u +#define MAX1111_ACIN_VOLT 6u -extern struct sharpsl_pm_status sharpsl_pm; extern struct battery_thresh spitz_battery_levels_acin[]; extern struct battery_thresh spitz_battery_levels_noac[]; +void sharpsl_pm_pxa_init(void); +void sharpsl_pm_pxa_remove(void); +int sharpsl_pm_pxa_read_max1111(int channel); -#define READ_GPIO_BIT(x) (GPLR(x) & GPIO_bit(x)) - -#define SHARPSL_LED_ERROR 2 -#define SHARPSL_LED_ON 1 -#define SHARPSL_LED_OFF 0 -#define CHARGE_ON() sharpsl_pm.machinfo->charge(1) -#define CHARGE_OFF() sharpsl_pm.machinfo->charge(0) -#define CHARGE_LED_ON() sharpsl_pm.machinfo->chargeled(SHARPSL_LED_ON) -#define CHARGE_LED_OFF() sharpsl_pm.machinfo->chargeled(SHARPSL_LED_OFF) -#define CHARGE_LED_ERR() sharpsl_pm.machinfo->chargeled(SHARPSL_LED_ERROR) -#define DISCHARGE_ON() sharpsl_pm.machinfo->discharge(1) -#define DISCHARGE_OFF() sharpsl_pm.machinfo->discharge(0) -#define STATUS_AC_IN() sharpsl_pm.machinfo->status_acin() -#define STATUS_BATT_LOCKED() READ_GPIO_BIT(sharpsl_pm.machinfo->gpio_batlock) -#define STATUS_CHRG_FULL() READ_GPIO_BIT(sharpsl_pm.machinfo->gpio_batfull) -#define STATUS_FATAL() READ_GPIO_BIT(sharpsl_pm.machinfo->gpio_fatal) diff --git a/arch/arm/mach-pxa/sharpsl_pm.c b/arch/arm/mach-pxa/sharpsl_pm.c index c10be00fb52..6d402b262d8 100644 --- a/arch/arm/mach-pxa/sharpsl_pm.c +++ b/arch/arm/mach-pxa/sharpsl_pm.c @@ -15,48 +15,20 @@ #undef DEBUG #include <linux/module.h> -#include <linux/timer.h> #include <linux/init.h> #include <linux/kernel.h> -#include <linux/apm_bios.h> -#include <linux/delay.h> #include <linux/interrupt.h> #include <linux/platform_device.h> #include <asm/hardware.h> -#include <asm/hardware/scoop.h> #include <asm/mach-types.h> #include <asm/irq.h> #include <asm/apm.h> - #include <asm/arch/pm.h> #include <asm/arch/pxa-regs.h> #include <asm/arch/sharpsl.h> #include "sharpsl.h" -/* - * Constants - */ -#define SHARPSL_CHARGE_ON_TIME_INTERVAL (msecs_to_jiffies(1*60*1000)) /* 1 min */ -#define SHARPSL_CHARGE_FINISH_TIME (msecs_to_jiffies(10*60*1000)) /* 10 min */ -#define SHARPSL_BATCHK_TIME (msecs_to_jiffies(15*1000)) /* 15 sec */ -#define SHARPSL_BATCHK_TIME_SUSPEND (60*10) /* 10 min */ -#define SHARPSL_WAIT_CO_TIME 15 /* 15 sec */ -#define SHARPSL_WAIT_DISCHARGE_ON 100 /* 100 msec */ -#define SHARPSL_CHECK_BATTERY_WAIT_TIME_TEMP 10 /* 10 msec */ -#define SHARPSL_CHECK_BATTERY_WAIT_TIME_VOLT 10 /* 10 msec */ -#define SHARPSL_CHECK_BATTERY_WAIT_TIME_ACIN 10 /* 10 msec */ -#define SHARPSL_CHARGE_WAIT_TIME 15 /* 15 msec */ -#define SHARPSL_CHARGE_CO_CHECK_TIME 5 /* 5 msec */ -#define SHARPSL_CHARGE_RETRY_CNT 1 /* eqv. 10 min */ - -#define SHARPSL_CHARGE_ON_VOLT 0x99 /* 2.9V */ -#define SHARPSL_CHARGE_ON_TEMP 0xe0 /* 2.9V */ -#define SHARPSL_CHARGE_ON_ACIN_HIGH 0x9b /* 6V */ -#define SHARPSL_CHARGE_ON_ACIN_LOW 0x34 /* 2V */ -#define SHARPSL_FATAL_ACIN_VOLT 182 /* 3.45V */ -#define SHARPSL_FATAL_NOACIN_VOLT 170 /* 3.40V */ - struct battery_thresh spitz_battery_levels_acin[] = { { 213, 100}, { 212, 98}, @@ -151,763 +123,17 @@ struct battery_thresh spitz_battery_levels_noac[] = { #define MAXCTRL_SEL_SH 4 #define MAXCTRL_STR 1u << 7 -/* MAX1111 Channel Definitions */ -#define BATT_AD 4u -#define BATT_THM 2u -#define JK_VAD 6u - - -/* - * Prototypes - */ -static int sharpsl_read_main_battery(void); -static int sharpsl_off_charge_battery(void); -static int sharpsl_check_battery_temp(void); -static int sharpsl_check_battery_voltage(void); -static int sharpsl_ac_check(void); -static int sharpsl_fatal_check(void); -static int sharpsl_average_value(int ad); -static void sharpsl_average_clear(void); -static void sharpsl_charge_toggle(void *private_); -static void sharpsl_battery_thread(void *private_); - - -/* - * Variables - */ -struct sharpsl_pm_status sharpsl_pm; -DECLARE_WORK(toggle_charger, sharpsl_charge_toggle, NULL); -DECLARE_WORK(sharpsl_bat, sharpsl_battery_thread, NULL); - - -static int get_percentage(int voltage) -{ - int i = sharpsl_pm.machinfo->bat_levels - 1; - struct battery_thresh *thresh; - - if (sharpsl_pm.charge_mode == CHRG_ON) - thresh=sharpsl_pm.machinfo->bat_levels_acin; - else - thresh=sharpsl_pm.machinfo->bat_levels_noac; - - while (i > 0 && (voltage > thresh[i].voltage)) - i--; - - return thresh[i].percentage; -} - -static int get_apm_status(int voltage) -{ - int low_thresh, high_thresh; - - if (sharpsl_pm.charge_mode == CHRG_ON) { - high_thresh = sharpsl_pm.machinfo->status_high_acin; - low_thresh = sharpsl_pm.machinfo->status_low_acin; - } else { - high_thresh = sharpsl_pm.machinfo->status_high_noac; - low_thresh = sharpsl_pm.machinfo->status_low_noac; - } - - if (voltage >= high_thresh) - return APM_BATTERY_STATUS_HIGH; - if (voltage >= low_thresh) - return APM_BATTERY_STATUS_LOW; - return APM_BATTERY_STATUS_CRITICAL; -} - -void sharpsl_battery_kick(void) -{ - schedule_delayed_work(&sharpsl_bat, msecs_to_jiffies(125)); -} -EXPORT_SYMBOL(sharpsl_battery_kick); - - -static void sharpsl_battery_thread(void *private_) -{ - int voltage, percent, apm_status, i = 0; - - if (!sharpsl_pm.machinfo) - return; - - sharpsl_pm.battstat.ac_status = (STATUS_AC_IN() ? APM_AC_ONLINE : APM_AC_OFFLINE); - - /* Corgi cannot confirm when battery fully charged so periodically kick! */ - if (machine_is_corgi() && (sharpsl_pm.charge_mode == CHRG_ON) - && time_after(jiffies, sharpsl_pm.charge_start_time + SHARPSL_CHARGE_ON_TIME_INTERVAL)) - schedule_work(&toggle_charger); - - while(1) { - voltage = sharpsl_read_main_battery(); - if (voltage > 0) break; - if (i++ > 5) { - voltage = sharpsl_pm.machinfo->bat_levels_noac[0].voltage; - dev_warn(sharpsl_pm.dev, "Warning: Cannot read main battery!\n"); - break; - } - } - - voltage = sharpsl_average_value(voltage); - apm_status = get_apm_status(voltage); - percent = get_percentage(voltage); - - /* At low battery voltages, the voltage has a tendency to start - creeping back up so we try to avoid this here */ - if ((sharpsl_pm.battstat.ac_status == APM_AC_ONLINE) || (apm_status == APM_BATTERY_STATUS_HIGH) || percent <= sharpsl_pm.battstat.mainbat_percent) { - sharpsl_pm.battstat.mainbat_voltage = voltage; - sharpsl_pm.battstat.mainbat_status = apm_status; - sharpsl_pm.battstat.mainbat_percent = percent; - } - - dev_dbg(sharpsl_pm.dev, "Battery: voltage: %d, status: %d, percentage: %d, time: %d\n", voltage, - sharpsl_pm.battstat.mainbat_status, sharpsl_pm.battstat.mainbat_percent, jiffies); - - /* If battery is low. limit backlight intensity to save power. */ - if ((sharpsl_pm.battstat.ac_status != APM_AC_ONLINE) - && ((sharpsl_pm.battstat.mainbat_status == APM_BATTERY_STATUS_LOW) || - (sharpsl_pm.battstat.mainbat_status == APM_BATTERY_STATUS_CRITICAL))) { - if (!(sharpsl_pm.flags & SHARPSL_BL_LIMIT)) { - corgibl_limit_intensity(1); - sharpsl_pm.flags |= SHARPSL_BL_LIMIT; - } - } else if (sharpsl_pm.flags & SHARPSL_BL_LIMIT) { - corgibl_limit_intensity(0); - sharpsl_pm.flags &= ~SHARPSL_BL_LIMIT; - } - - /* Suspend if critical battery level */ - if ((sharpsl_pm.battstat.ac_status != APM_AC_ONLINE) - && (sharpsl_pm.battstat.mainbat_status == APM_BATTERY_STATUS_CRITICAL) - && !(sharpsl_pm.flags & SHARPSL_APM_QUEUED)) { - sharpsl_pm.flags |= SHARPSL_APM_QUEUED; - dev_err(sharpsl_pm.dev, "Fatal Off\n"); - apm_queue_event(APM_CRITICAL_SUSPEND); - } - - schedule_delayed_work(&sharpsl_bat, SHARPSL_BATCHK_TIME); -} - -static void sharpsl_charge_on(void) -{ - dev_dbg(sharpsl_pm.dev, "Turning Charger On\n"); - - sharpsl_pm.full_count = 0; - sharpsl_pm.charge_mode = CHRG_ON; - schedule_delayed_work(&toggle_charger, msecs_to_jiffies(250)); - schedule_delayed_work(&sharpsl_bat, msecs_to_jiffies(500)); -} - -static void sharpsl_charge_off(void) -{ - dev_dbg(sharpsl_pm.dev, "Turning Charger Off\n"); - - CHARGE_OFF(); - CHARGE_LED_OFF(); - sharpsl_pm.charge_mode = CHRG_OFF; - - schedule_work(&sharpsl_bat); -} - -static void sharpsl_charge_error(void) -{ - CHARGE_LED_ERR(); - CHARGE_OFF(); - sharpsl_pm.charge_mode = CHRG_ERROR; -} - -static void sharpsl_charge_toggle(void *private_) -{ - dev_dbg(sharpsl_pm.dev, "Toogling Charger at time: %lx\n", jiffies); - - if (STATUS_AC_IN() == 0) { - sharpsl_charge_off(); - return; - } else if ((sharpsl_check_battery_temp() < 0) || (sharpsl_ac_check() < 0)) { - sharpsl_charge_error(); - return; - } - - CHARGE_LED_ON(); - CHARGE_OFF(); - mdelay(SHARPSL_CHARGE_WAIT_TIME); - CHARGE_ON(); - - sharpsl_pm.charge_start_time = jiffies; -} - -static void sharpsl_ac_timer(unsigned long data) -{ - int acin = STATUS_AC_IN(); - - dev_dbg(sharpsl_pm.dev, "AC Status: %d\n",acin); - - sharpsl_average_clear(); - if (acin && (sharpsl_pm.charge_mode != CHRG_ON)) - sharpsl_charge_on(); - else if (sharpsl_pm.charge_mode == CHRG_ON) - sharpsl_charge_off(); - - schedule_work(&sharpsl_bat); -} - - -static irqreturn_t sharpsl_ac_isr(int irq, void *dev_id, struct pt_regs *fp) -{ - /* Delay the event slightly to debounce */ - /* Must be a smaller delay than the chrg_full_isr below */ - mod_timer(&sharpsl_pm.ac_timer, jiffies + msecs_to_jiffies(250)); - - return IRQ_HANDLED; -} - -static void sharpsl_chrg_full_timer(unsigned long data) -{ - dev_dbg(sharpsl_pm.dev, "Charge Full at time: %lx\n", jiffies); - - sharpsl_pm.full_count++; - - if (STATUS_AC_IN() == 0) { - dev_dbg(sharpsl_pm.dev, "Charge Full: AC removed - stop charging!\n"); - if (sharpsl_pm.charge_mode == CHRG_ON) - sharpsl_charge_off(); - } else if (sharpsl_pm.full_count < 2) { - dev_dbg(sharpsl_pm.dev, "Charge Full: Count too low\n"); - schedule_work(&toggle_charger); - } else if (time_after(jiffies, sharpsl_pm.charge_start_time + SHARPSL_CHARGE_FINISH_TIME)) { - dev_dbg(sharpsl_pm.dev, "Charge Full: Interrupt generated too slowly - retry.\n"); - schedule_work(&toggle_charger); - } else { - sharpsl_charge_off(); - sharpsl_pm.charge_mode = CHRG_DONE; - dev_dbg(sharpsl_pm.dev, "Charge Full: Charging Finished\n"); - } -} - -/* Charging Finished Interrupt (Not present on Corgi) */ -/* Can trigger at the same time as an AC staus change so - delay until after that has been processed */ -static irqreturn_t sharpsl_chrg_full_isr(int irq, void *dev_id, struct pt_regs *fp) -{ - if (sharpsl_pm.flags & SHARPSL_SUSPENDED) - return IRQ_HANDLED; - - /* delay until after any ac interrupt */ - mod_timer(&sharpsl_pm.chrg_full_timer, jiffies + msecs_to_jiffies(500)); - - return IRQ_HANDLED; -} - -static irqreturn_t sharpsl_fatal_isr(int irq, void *dev_id, struct pt_regs *fp) -{ - int is_fatal = 0; - - if (STATUS_BATT_LOCKED() == 0) { - dev_err(sharpsl_pm.dev, "Battery now Unlocked! Suspending.\n"); - is_fatal = 1; - } - - if (sharpsl_pm.machinfo->gpio_fatal && (STATUS_FATAL() == 0)) { - dev_err(sharpsl_pm.dev, "Fatal Batt Error! Suspending.\n"); - is_fatal = 1; - } - - if (!(sharpsl_pm.flags & SHARPSL_APM_QUEUED) && is_fatal) { - sharpsl_pm.flags |= SHARPSL_APM_QUEUED; - apm_queue_event(APM_CRITICAL_SUSPEND); - } - - return IRQ_HANDLED; -} - -/* - * Maintain an average of the last 10 readings - */ -#define SHARPSL_CNV_VALUE_NUM 10 -static int sharpsl_ad_index; - -static void sharpsl_average_clear(void) -{ - sharpsl_ad_index = 0; -} - -static int sharpsl_average_value(int ad) -{ - int i, ad_val = 0; - static int sharpsl_ad[SHARPSL_CNV_VALUE_NUM+1]; - - if (sharpsl_pm.battstat.mainbat_status != APM_BATTERY_STATUS_HIGH) { - sharpsl_ad_index = 0; - return ad; - } - - sharpsl_ad[sharpsl_ad_index] = ad; - sharpsl_ad_index++; - if (sharpsl_ad_index >= SHARPSL_CNV_VALUE_NUM) { - for (i=0; i < (SHARPSL_CNV_VALUE_NUM-1); i++) - sharpsl_ad[i] = sharpsl_ad[i+1]; - sharpsl_ad_index = SHARPSL_CNV_VALUE_NUM - 1; - } - for (i=0; i < sharpsl_ad_index; i++) - ad_val += sharpsl_ad[i]; - - return (ad_val / sharpsl_ad_index); -} - - /* * Read MAX1111 ADC */ -static int read_max1111(int channel) +int sharpsl_pm_pxa_read_max1111(int channel) { return corgi_ssp_max1111_get((channel << MAXCTRL_SEL_SH) | MAXCTRL_PD0 | MAXCTRL_PD1 | MAXCTRL_SGL | MAXCTRL_UNI | MAXCTRL_STR); } -static int sharpsl_read_main_battery(void) -{ - return read_max1111(BATT_AD); -} - -static int sharpsl_read_temp(void) +void sharpsl_pm_pxa_init(void) { - int temp; - - sharpsl_pm.machinfo->measure_temp(1); - - mdelay(SHARPSL_CHECK_BATTERY_WAIT_TIME_TEMP); - temp = read_max1111(BATT_THM); - - sharpsl_pm.machinfo->measure_temp(0); - - return temp; -} - -static int sharpsl_read_acin(void) -{ - return read_max1111(JK_VAD); -} - -/* - * Take an array of 5 integers, remove the maximum and minimum values - * and return the average. - */ -static int get_select_val(int *val) -{ - int i, j, k, temp, sum = 0; - - /* Find MAX val */ - temp = val[0]; - j=0; - for (i=1; i<5; i++) { - if (temp < val[i]) { - temp = val[i]; - j = i; - } - } - - /* Find MIN val */ - temp = val[4]; - k=4; - for (i=3; i>=0; i--) { - if (temp > val[i]) { - temp = val[i]; - k = i; - } - } - - for (i=0; i<5; i++) - if (i != j && i != k ) - sum += val[i]; - - dev_dbg(sharpsl_pm.dev, "Average: %d from values: %d, %d, %d, %d, %d\n", sum/3, val[0], val[1], val[2], val[3], val[4]); - - return (sum/3); -} - -static int sharpsl_check_battery_temp(void) -{ - int val, i, buff[5]; - - /* Check battery temperature */ - for (i=0; i<5; i++) { - mdelay(SHARPSL_CHECK_BATTERY_WAIT_TIME_TEMP); - buff[i] = sharpsl_read_temp(); - } - - val = get_select_val(buff); - - dev_dbg(sharpsl_pm.dev, "Temperature: %d\n", val); - if (val > SHARPSL_CHARGE_ON_TEMP) - return -1; - - return 0; -} - -static int sharpsl_check_battery_voltage(void) -{ - int val, i, buff[5]; - - /* disable charge, enable discharge */ - CHARGE_OFF(); - DISCHARGE_ON(); - mdelay(SHARPSL_WAIT_DISCHARGE_ON); - - if (sharpsl_pm.machinfo->discharge1) - sharpsl_pm.machinfo->discharge1(1); - - /* Check battery voltage */ - for (i=0; i<5; i++) { - buff[i] = sharpsl_read_main_battery(); - mdelay(SHARPSL_CHECK_BATTERY_WAIT_TIME_VOLT); - } - - if (sharpsl_pm.machinfo->discharge1) - sharpsl_pm.machinfo->discharge1(0); - - DISCHARGE_OFF(); - - val = get_select_val(buff); - dev_dbg(sharpsl_pm.dev, "Battery Voltage: %d\n", val); - - if (val < SHARPSL_CHARGE_ON_VOLT) - return -1; - - return 0; -} - -static int sharpsl_ac_check(void) -{ - int temp, i, buff[5]; - - for (i=0; i<5; i++) { - buff[i] = sharpsl_read_acin(); - mdelay(SHARPSL_CHECK_BATTERY_WAIT_TIME_ACIN); - } - - temp = get_select_val(buff); - dev_dbg(sharpsl_pm.dev, "AC Voltage: %d\n",temp); - - if ((temp > SHARPSL_CHARGE_ON_ACIN_HIGH) || (temp < SHARPSL_CHARGE_ON_ACIN_LOW)) { - dev_err(sharpsl_pm.dev, "Error: AC check failed.\n"); - return -1; - } - - return 0; -} - -#ifdef CONFIG_PM -static int sharpsl_pm_suspend(struct platform_device *pdev, pm_message_t state) -{ - sharpsl_pm.flags |= SHARPSL_SUSPENDED; - flush_scheduled_work(); - - if (sharpsl_pm.charge_mode == CHRG_ON) - sharpsl_pm.flags |= SHARPSL_DO_OFFLINE_CHRG; - else - sharpsl_pm.flags &= ~SHARPSL_DO_OFFLINE_CHRG; - - return 0; -} - -static int sharpsl_pm_resume(struct platform_device *pdev) -{ - /* Clear the reset source indicators as they break the bootloader upon reboot */ - RCSR = 0x0f; - sharpsl_average_clear(); - sharpsl_pm.flags &= ~SHARPSL_APM_QUEUED; - sharpsl_pm.flags &= ~SHARPSL_SUSPENDED; - - return 0; -} - -static void corgi_goto_sleep(unsigned long alarm_time, unsigned int alarm_enable, suspend_state_t state) -{ - dev_dbg(sharpsl_pm.dev, "Time is: %08x\n",RCNR); - - dev_dbg(sharpsl_pm.dev, "Offline Charge Activate = %d\n",sharpsl_pm.flags & SHARPSL_DO_OFFLINE_CHRG); - /* not charging and AC-IN! */ - - if ((sharpsl_pm.flags & SHARPSL_DO_OFFLINE_CHRG) && (STATUS_AC_IN() != 0)) { - dev_dbg(sharpsl_pm.dev, "Activating Offline Charger...\n"); - sharpsl_pm.charge_mode = CHRG_OFF; - sharpsl_pm.flags &= ~SHARPSL_DO_OFFLINE_CHRG; - sharpsl_off_charge_battery(); - } - - sharpsl_pm.machinfo->presuspend(); - - PEDR = 0xffffffff; /* clear it */ - - sharpsl_pm.flags &= ~SHARPSL_ALARM_ACTIVE; - if ((sharpsl_pm.charge_mode == CHRG_ON) && ((alarm_enable && ((alarm_time - RCNR) > (SHARPSL_BATCHK_TIME_SUSPEND + 30))) || !alarm_enable)) { - RTSR &= RTSR_ALE; - RTAR = RCNR + SHARPSL_BATCHK_TIME_SUSPEND; - dev_dbg(sharpsl_pm.dev, "Charging alarm at: %08x\n",RTAR); - sharpsl_pm.flags |= SHARPSL_ALARM_ACTIVE; - } else if (alarm_enable) { - RTSR &= RTSR_ALE; - RTAR = alarm_time; - dev_dbg(sharpsl_pm.dev, "User alarm at: %08x\n",RTAR); - } else { - dev_dbg(sharpsl_pm.dev, "No alarms set.\n"); - } - - pxa_pm_enter(state); - - sharpsl_pm.machinfo->postsuspend(); - - dev_dbg(sharpsl_pm.dev, "Corgi woken up from suspend: %08x\n",PEDR); -} - -static int corgi_enter_suspend(unsigned long alarm_time, unsigned int alarm_enable, suspend_state_t state) -{ - if (!sharpsl_pm.machinfo->should_wakeup(!(sharpsl_pm.flags & SHARPSL_ALARM_ACTIVE) && alarm_enable) ) - { - if (!(sharpsl_pm.flags & SHARPSL_ALARM_ACTIVE)) { - dev_dbg(sharpsl_pm.dev, "No user triggered wakeup events and not charging. Strange. Suspend.\n"); - corgi_goto_sleep(alarm_time, alarm_enable, state); - return 1; - } - if(sharpsl_off_charge_battery()) { - dev_dbg(sharpsl_pm.dev, "Charging. Suspend...\n"); - corgi_goto_sleep(alarm_time, alarm_enable, state); - return 1; - } - dev_dbg(sharpsl_pm.dev, "User triggered wakeup in offline charger.\n"); - } - - if ((STATUS_BATT_LOCKED() == 0) || (sharpsl_fatal_check() < 0) ) - { - dev_err(sharpsl_pm.dev, "Fatal condition. Suspend.\n"); - corgi_goto_sleep(alarm_time, alarm_enable, state); - return 1; - } - - return 0; -} - -static int corgi_pxa_pm_enter(suspend_state_t state) -{ - unsigned long alarm_time = RTAR; - unsigned int alarm_status = ((RTSR & RTSR_ALE) != 0); - - dev_dbg(sharpsl_pm.dev, "SharpSL suspending for first time.\n"); - - corgi_goto_sleep(alarm_time, alarm_status, state); - - while (corgi_enter_suspend(alarm_time,alarm_status,state)) - {} - - dev_dbg(sharpsl_pm.dev, "SharpSL resuming...\n"); - - return 0; -} -#endif - - -/* - * Check for fatal battery errors - * Fatal returns -1 - */ -static int sharpsl_fatal_check(void) -{ - int buff[5], temp, i, acin; - - dev_dbg(sharpsl_pm.dev, "sharpsl_fatal_check entered\n"); - - /* Check AC-Adapter */ - acin = STATUS_AC_IN(); - - if (acin && (sharpsl_pm.charge_mode == CHRG_ON)) { - CHARGE_OFF(); - udelay(100); - DISCHARGE_ON(); /* enable discharge */ - mdelay(SHARPSL_WAIT_DISCHARGE_ON); - } - - if (sharpsl_pm.machinfo->discharge1) - sharpsl_pm.machinfo->discharge1(1); - - /* Check battery : check inserting battery ? */ - for (i=0; i<5; i++) { - buff[i] = sharpsl_read_main_battery(); - mdelay(SHARPSL_CHECK_BATTERY_WAIT_TIME_VOLT); - } - - if (sharpsl_pm.machinfo->discharge1) - sharpsl_pm.machinfo->discharge1(0); - - if (acin && (sharpsl_pm.charge_mode == CHRG_ON)) { - udelay(100); - CHARGE_ON(); - DISCHARGE_OFF(); - } - - temp = get_select_val(buff); - dev_dbg(sharpsl_pm.dev, "sharpsl_fatal_check: acin: %d, discharge voltage: %d, no discharge: %d\n", acin, temp, sharpsl_read_main_battery()); - - if ((acin && (temp < SHARPSL_FATAL_ACIN_VOLT)) || - (!acin && (temp < SHARPSL_FATAL_NOACIN_VOLT))) - return -1; - return 0; -} - -static int sharpsl_off_charge_error(void) -{ - dev_err(sharpsl_pm.dev, "Offline Charger: Error occured.\n"); - CHARGE_OFF(); - CHARGE_LED_ERR(); - sharpsl_pm.charge_mode = CHRG_ERROR; - return 1; -} - -/* - * Charging Control while suspended - * Return 1 - go straight to sleep - * Return 0 - sleep or wakeup depending on other factors - */ -static int sharpsl_off_charge_battery(void) -{ - int time; - - dev_dbg(sharpsl_pm.dev, "Charge Mode: %d\n", sharpsl_pm.charge_mode); - - if (sharpsl_pm.charge_mode == CHRG_OFF) { - dev_dbg(sharpsl_pm.dev, "Offline Charger: Step 1\n"); - - /* AC Check */ - if ((sharpsl_ac_check() < 0) || (sharpsl_check_battery_temp() < 0)) - return sharpsl_off_charge_error(); - - /* Start Charging */ - CHARGE_LED_ON(); - CHARGE_OFF(); - mdelay(SHARPSL_CHARGE_WAIT_TIME); - CHARGE_ON(); - - sharpsl_pm.charge_mode = CHRG_ON; - sharpsl_pm.full_count = 0; - - return 1; - } else if (sharpsl_pm.charge_mode != CHRG_ON) { - return 1; - } - - if (sharpsl_pm.full_count == 0) { - int time; - - dev_dbg(sharpsl_pm.dev, "Offline Charger: Step 2\n"); - - if ((sharpsl_check_battery_temp() < 0) || (sharpsl_check_battery_voltage() < 0)) - return sharpsl_off_charge_error(); - - CHARGE_OFF(); - mdelay(SHARPSL_CHARGE_WAIT_TIME); - CHARGE_ON(); - sharpsl_pm.charge_mode = CHRG_ON; - - mdelay(SHARPSL_CHARGE_CO_CHECK_TIME); - - time = RCNR; - while(1) { - /* Check if any wakeup event had occured */ - if (sharpsl_pm.machinfo->charger_wakeup() != 0) - return 0; - /* Check for timeout */ - if ((RCNR - time) > SHARPSL_WAIT_CO_TIME) - return 1; - if (STATUS_CHRG_FULL()) { - dev_dbg(sharpsl_pm.dev, "Offline Charger: Charge full occured. Retrying to check\n"); - sharpsl_pm.full_count++; - CHARGE_OFF(); - mdelay(SHARPSL_CHARGE_WAIT_TIME); - CHARGE_ON(); - return 1; - } - } - } - - dev_dbg(sharpsl_pm.dev, "Offline Charger: Step 3\n"); - - mdelay(SHARPSL_CHARGE_CO_CHECK_TIME); - - time = RCNR; - while(1) { - /* Check if any wakeup event had occured */ - if (sharpsl_pm.machinfo->charger_wakeup() != 0) - return 0; - /* Check for timeout */ - if ((RCNR-time) > SHARPSL_WAIT_CO_TIME) { - if (sharpsl_pm.full_count > SHARPSL_CHARGE_RETRY_CNT) { - dev_dbg(sharpsl_pm.dev, "Offline Charger: Not charged sufficiently. Retrying.\n"); - sharpsl_pm.full_count = 0; - } - sharpsl_pm.full_count++; - return 1; - } - if (STATUS_CHRG_FULL()) { - dev_dbg(sharpsl_pm.dev, "Offline Charger: Charging complete.\n"); - CHARGE_LED_OFF(); - CHARGE_OFF(); - sharpsl_pm.charge_mode = CHRG_DONE; - return 1; - } - } -} - - -static ssize_t battery_percentage_show(struct device *dev, struct device_attribute *attr, char *buf) -{ - return sprintf(buf, "%d\n",sharpsl_pm.battstat.mainbat_percent); -} - -static ssize_t battery_voltage_show(struct device *dev, struct device_attribute *attr, char *buf) -{ - return sprintf(buf, "%d\n",sharpsl_pm.battstat.mainbat_voltage); -} - -static DEVICE_ATTR(battery_percentage, 0444, battery_percentage_show, NULL); -static DEVICE_ATTR(battery_voltage, 0444, battery_voltage_show, NULL); - -extern void (*apm_get_power_status)(struct apm_power_info *); - -static void sharpsl_apm_get_power_status(struct apm_power_info *info) -{ - info->ac_line_status = sharpsl_pm.battstat.ac_status; - - if (sharpsl_pm.charge_mode == CHRG_ON) - info->battery_status = APM_BATTERY_STATUS_CHARGING; - else - info->battery_status = sharpsl_pm.battstat.mainbat_status; - - info->battery_flag = (1 << info->battery_status); - info->battery_life = sharpsl_pm.battstat.mainbat_percent; -} - -static struct pm_ops sharpsl_pm_ops = { - .pm_disk_mode = PM_DISK_FIRMWARE, - .prepare = pxa_pm_prepare, - .enter = corgi_pxa_pm_enter, - .finish = pxa_pm_finish, -}; - -static int __init sharpsl_pm_probe(struct platform_device *pdev) -{ - if (!pdev->dev.platform_data) - return -EINVAL; - - sharpsl_pm.dev = &pdev->dev; - sharpsl_pm.machinfo = pdev->dev.platform_data; - sharpsl_pm.charge_mode = CHRG_OFF; - sharpsl_pm.flags = 0; - - sharpsl_pm.machinfo->init(); - - init_timer(&sharpsl_pm.ac_timer); - sharpsl_pm.ac_timer.function = sharpsl_ac_timer; - - init_timer(&sharpsl_pm.chrg_full_timer); - sharpsl_pm.chrg_full_timer.function = sharpsl_chrg_full_timer; - pxa_gpio_mode(sharpsl_pm.machinfo->gpio_acin | GPIO_IN); pxa_gpio_mode(sharpsl_pm.machinfo->gpio_batfull | GPIO_IN); pxa_gpio_mode(sharpsl_pm.machinfo->gpio_batlock | GPIO_IN); @@ -938,26 +164,10 @@ static int __init sharpsl_pm_probe(struct platform_device *pdev) } else set_irq_type(IRQ_GPIO(sharpsl_pm.machinfo->gpio_batfull),IRQT_RISING); } - - device_create_file(&pdev->dev, &dev_attr_battery_percentage); - device_create_file(&pdev->dev, &dev_attr_battery_voltage); - - apm_get_power_status = sharpsl_apm_get_power_status; - - pm_set_ops(&sharpsl_pm_ops); - - mod_timer(&sharpsl_pm.ac_timer, jiffies + msecs_to_jiffies(250)); - - return 0; } -static int sharpsl_pm_remove(struct platform_device *pdev) +void sharpsl_pm_pxa_remove(void) { - pm_set_ops(NULL); - - device_remove_file(&pdev->dev, &dev_attr_battery_percentage); - device_remove_file(&pdev->dev, &dev_attr_battery_voltage); - free_irq(IRQ_GPIO(sharpsl_pm.machinfo->gpio_acin), sharpsl_ac_isr); free_irq(IRQ_GPIO(sharpsl_pm.machinfo->gpio_batlock), sharpsl_fatal_isr); @@ -966,32 +176,4 @@ static int sharpsl_pm_remove(struct platform_device *pdev) if (!machine_is_corgi()) free_irq(IRQ_GPIO(sharpsl_pm.machinfo->gpio_batfull), sharpsl_chrg_full_isr); - - del_timer_sync(&sharpsl_pm.chrg_full_timer); - del_timer_sync(&sharpsl_pm.ac_timer); - - return 0; } - -static struct platform_driver sharpsl_pm_driver = { - .probe = sharpsl_pm_probe, - .remove = sharpsl_pm_remove, - .suspend = sharpsl_pm_suspend, - .resume = sharpsl_pm_resume, - .driver = { - .name = "sharpsl-pm", - }, -}; - -static int __devinit sharpsl_pm_init(void) -{ - return platform_driver_register(&sharpsl_pm_driver); -} - -static void sharpsl_pm_exit(void) -{ - platform_driver_unregister(&sharpsl_pm_driver); -} - -late_initcall(sharpsl_pm_init); -module_exit(sharpsl_pm_exit); diff --git a/arch/arm/mach-pxa/spitz.c b/arch/arm/mach-pxa/spitz.c index 2df1b56615b..f2007db0cda 100644 --- a/arch/arm/mach-pxa/spitz.c +++ b/arch/arm/mach-pxa/spitz.c @@ -36,6 +36,7 @@ #include <asm/arch/irq.h> #include <asm/arch/irda.h> #include <asm/arch/mmc.h> +#include <asm/arch/ohci.h> #include <asm/arch/udc.h> #include <asm/arch/pxafb.h> #include <asm/arch/akita.h> @@ -126,10 +127,12 @@ static void spitz_card_pwr_ctrl(int device, unsigned short new_cpr) cpr &= ~0x0002; if (device == SPITZ_PWR_SD) cpr &= ~0x0004; - write_scoop_reg(&spitzscoop_device.dev, SCOOP_CPR, cpr | new_cpr); if (!(cpr & 0x0002) && !(cpr & 0x0004)) { + write_scoop_reg(&spitzscoop_device.dev, SCOOP_CPR, 0x0000); mdelay(1); reset_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_CF_POWER); + } else { + write_scoop_reg(&spitzscoop_device.dev, SCOOP_CPR, cpr | new_cpr); } } } @@ -335,6 +338,35 @@ static struct pxamci_platform_data spitz_mci_platform_data = { /* + * USB Host (OHCI) + */ +static int spitz_ohci_init(struct device *dev) +{ + /* Only Port 2 is connected */ + pxa_gpio_mode(SPITZ_GPIO_USB_CONNECT | GPIO_IN); + pxa_gpio_mode(SPITZ_GPIO_USB_HOST | GPIO_OUT); + pxa_gpio_mode(SPITZ_GPIO_USB_DEVICE | GPIO_IN); + + /* Setup USB Port 2 Output Control Register */ + UP2OCR = UP2OCR_HXS | UP2OCR_HXOE | UP2OCR_DPPDE | UP2OCR_DMPDE; + + GPSR(SPITZ_GPIO_USB_HOST) = GPIO_bit(SPITZ_GPIO_USB_HOST); + + UHCHR = (UHCHR) & + ~(UHCHR_SSEP1 | UHCHR_SSEP2 | UHCHR_SSEP3 | UHCHR_SSE); + + UHCRHDA |= UHCRHDA_NOCP; + + return 0; +} + +static struct pxaohci_platform_data spitz_ohci_platform_data = { + .port_mode = PMM_NPS_MODE, + .init = spitz_ohci_init, +}; + + +/* * Irda */ static void spitz_irda_transceiver_mode(struct device *dev, int mode) @@ -411,6 +443,7 @@ static void __init common_init(void) platform_add_devices(devices, ARRAY_SIZE(devices)); pxa_set_mci_info(&spitz_mci_platform_data); + pxa_set_ohci_info(&spitz_ohci_platform_data); pxa_set_ficp_info(&spitz_ficp_platform_data); set_pxa_fb_parent(&spitzssp_device.dev); set_pxa_fb_info(&spitz_pxafb_info); diff --git a/arch/arm/mach-pxa/spitz_pm.c b/arch/arm/mach-pxa/spitz_pm.c index 3ce7486daa5..5e5bdc89848 100644 --- a/arch/arm/mach-pxa/spitz_pm.c +++ b/arch/arm/mach-pxa/spitz_pm.c @@ -33,19 +33,7 @@ static void spitz_charger_init(void) { pxa_gpio_mode(SPITZ_GPIO_KEY_INT | GPIO_IN); pxa_gpio_mode(SPITZ_GPIO_SYNC | GPIO_IN); -} - -static void spitz_charge_led(int val) -{ - if (val == SHARPSL_LED_ERROR) { - dev_dbg(sharpsl_pm.dev, "Charge LED Error\n"); - } else if (val == SHARPSL_LED_ON) { - dev_dbg(sharpsl_pm.dev, "Charge LED On\n"); - set_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_LED_ORANGE); - } else { - dev_dbg(sharpsl_pm.dev, "Charge LED Off\n"); - reset_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_LED_ORANGE); - } + sharpsl_pm_pxa_init(); } static void spitz_measure_temp(int on) @@ -92,7 +80,7 @@ static void spitz_discharge1(int on) static void spitz_presuspend(void) { - spitz_last_ac_status = STATUS_AC_IN(); + spitz_last_ac_status = sharpsl_pm.machinfo->read_devdata(SHARPSL_STATUS_ACIN); /* GPIO Sleep Register */ PGSR0 = 0x00144018; @@ -138,7 +126,7 @@ static void spitz_postsuspend(void) static int spitz_should_wakeup(unsigned int resume_on_alarm) { int is_resume = 0; - int acin = STATUS_AC_IN(); + int acin = sharpsl_pm.machinfo->read_devdata(SHARPSL_STATUS_ACIN); if (spitz_last_ac_status != acin) { if (acin) { @@ -148,8 +136,8 @@ static int spitz_should_wakeup(unsigned int resume_on_alarm) } else { /* charge off */ dev_dbg(sharpsl_pm.dev, "AC Removed\n"); - CHARGE_LED_OFF(); - CHARGE_OFF(); + sharpsl_pm_led(SHARPSL_LED_OFF); + sharpsl_pm.machinfo->charge(0); sharpsl_pm.charge_mode = CHRG_OFF; } spitz_last_ac_status = acin; @@ -175,25 +163,41 @@ static unsigned long spitz_charger_wakeup(void) return (~GPLR0 & GPIO_bit(SPITZ_GPIO_KEY_INT)) | (GPLR0 & GPIO_bit(SPITZ_GPIO_SYNC)); } -static int spitz_acin_status(void) +unsigned long spitzpm_read_devdata(int type) { - return (((~GPLR(SPITZ_GPIO_AC_IN)) & GPIO_bit(SPITZ_GPIO_AC_IN)) != 0); + switch(type) { + case SHARPSL_STATUS_ACIN: + return (((~GPLR(SPITZ_GPIO_AC_IN)) & GPIO_bit(SPITZ_GPIO_AC_IN)) != 0); + case SHARPSL_STATUS_LOCK: + return READ_GPIO_BIT(sharpsl_pm.machinfo->gpio_batlock); + case SHARPSL_STATUS_CHRGFULL: + return READ_GPIO_BIT(sharpsl_pm.machinfo->gpio_batfull); + case SHARPSL_STATUS_FATAL: + return READ_GPIO_BIT(sharpsl_pm.machinfo->gpio_fatal); + case SHARPSL_ACIN_VOLT: + return sharpsl_pm_pxa_read_max1111(MAX1111_ACIN_VOLT); + case SHARPSL_BATT_TEMP: + return sharpsl_pm_pxa_read_max1111(MAX1111_BATT_TEMP); + case SHARPSL_BATT_VOLT: + default: + return sharpsl_pm_pxa_read_max1111(MAX1111_BATT_VOLT); + } } struct sharpsl_charger_machinfo spitz_pm_machinfo = { .init = spitz_charger_init, + .exit = sharpsl_pm_pxa_remove, .gpio_batlock = SPITZ_GPIO_BAT_COVER, .gpio_acin = SPITZ_GPIO_AC_IN, .gpio_batfull = SPITZ_GPIO_CHRG_FULL, .gpio_fatal = SPITZ_GPIO_FATAL_BAT, - .status_acin = spitz_acin_status, .discharge = spitz_discharge, .discharge1 = spitz_discharge1, .charge = spitz_charge, - .chargeled = spitz_charge_led, .measure_temp = spitz_measure_temp, .presuspend = spitz_presuspend, .postsuspend = spitz_postsuspend, + .read_devdata = spitzpm_read_devdata, .charger_wakeup = spitz_charger_wakeup, .should_wakeup = spitz_should_wakeup, .bat_levels = 40, diff --git a/arch/arm/mach-realview/clock.c b/arch/arm/mach-realview/clock.c index 002635c97bb..ec3f7e79862 100644 --- a/arch/arm/mach-realview/clock.c +++ b/arch/arm/mach-realview/clock.c @@ -13,9 +13,9 @@ #include <linux/list.h> #include <linux/errno.h> #include <linux/err.h> +#include <linux/clk.h> #include <asm/semaphore.h> -#include <asm/hardware/clock.h> #include <asm/hardware/icst307.h> #include "clock.h" @@ -57,17 +57,6 @@ void clk_disable(struct clk *clk) } EXPORT_SYMBOL(clk_disable); -int clk_use(struct clk *clk) -{ - return 0; -} -EXPORT_SYMBOL(clk_use); - -void clk_unuse(struct clk *clk) -{ -} -EXPORT_SYMBOL(clk_unuse); - unsigned long clk_get_rate(struct clk *clk) { return clk->rate; diff --git a/arch/arm/mach-realview/core.c b/arch/arm/mach-realview/core.c index af6580f1ceb..4a222f59f2c 100644 --- a/arch/arm/mach-realview/core.c +++ b/arch/arm/mach-realview/core.c @@ -24,14 +24,14 @@ #include <linux/dma-mapping.h> #include <linux/sysdev.h> #include <linux/interrupt.h> +#include <linux/amba/bus.h> +#include <linux/amba/clcd.h> #include <asm/system.h> #include <asm/hardware.h> #include <asm/io.h> #include <asm/irq.h> #include <asm/leds.h> -#include <asm/hardware/amba.h> -#include <asm/hardware/amba_clcd.h> #include <asm/hardware/arm_timer.h> #include <asm/hardware/icst307.h> diff --git a/arch/arm/mach-realview/core.h b/arch/arm/mach-realview/core.h index c06e6041df4..93e86d9f439 100644 --- a/arch/arm/mach-realview/core.h +++ b/arch/arm/mach-realview/core.h @@ -22,7 +22,8 @@ #ifndef __ASM_ARCH_REALVIEW_H #define __ASM_ARCH_REALVIEW_H -#include <asm/hardware/amba.h> +#include <linux/amba/bus.h> + #include <asm/leds.h> #include <asm/io.h> diff --git a/arch/arm/mach-realview/realview_eb.c b/arch/arm/mach-realview/realview_eb.c index 7dc32503fdf..112f7592aca 100644 --- a/arch/arm/mach-realview/realview_eb.c +++ b/arch/arm/mach-realview/realview_eb.c @@ -23,6 +23,7 @@ #include <linux/init.h> #include <linux/platform_device.h> #include <linux/sysdev.h> +#include <linux/amba/bus.h> #include <asm/hardware.h> #include <asm/io.h> @@ -30,7 +31,6 @@ #include <asm/leds.h> #include <asm/mach-types.h> #include <asm/hardware/gic.h> -#include <asm/hardware/amba.h> #include <asm/hardware/icst307.h> #include <asm/mach/arch.h> diff --git a/arch/arm/mach-rpc/dma.c b/arch/arm/mach-rpc/dma.c index bc0747439fb..bd86ffba881 100644 --- a/arch/arm/mach-rpc/dma.c +++ b/arch/arm/mach-rpc/dma.c @@ -13,7 +13,7 @@ #include <linux/mman.h> #include <linux/init.h> #include <linux/interrupt.h> -#include <linux/pci.h> +#include <linux/dma-mapping.h> #include <asm/page.h> #include <asm/dma.h> @@ -148,11 +148,14 @@ static void iomd_enable_dma(dmach_t channel, dma_t *dma) * Cope with ISA-style drivers which expect cache * coherence. */ - if (!dma->using_sg) { - dma->buf.dma_address = pci_map_single(NULL, - dma->buf.__address, dma->buf.length, + if (!dma->sg) { + dma->sg = &dma->buf; + dma->sgcount = 1; + dma->buf.length = dma->count; + dma->buf.dma_address = dma_map_single(NULL, + dma->addr, dma->count, dma->dma_mode == DMA_MODE_READ ? - PCI_DMA_FROMDEVICE : PCI_DMA_TODEVICE); + DMA_FROM_DEVICE : DMA_TO_DEVICE); } iomd_writeb(DMA_CR_C, dma_base + CR); @@ -239,7 +242,7 @@ static void floppy_enable_dma(dmach_t channel, dma_t *dma) unsigned int fiqhandler_length; struct pt_regs regs; - if (dma->using_sg) + if (dma->sg) BUG(); if (dma->dma_mode == DMA_MODE_READ) { @@ -252,8 +255,8 @@ static void floppy_enable_dma(dmach_t channel, dma_t *dma) fiqhandler_length = &floppy_fiqout_end - &floppy_fiqout_start; } - regs.ARM_r9 = dma->buf.length; - regs.ARM_r10 = (unsigned long)dma->buf.__address; + regs.ARM_r9 = dma->count; + regs.ARM_r10 = (unsigned long)dma->addr; regs.ARM_fp = (unsigned long)FLOPPYDMA_BASE; if (claim_fiq(&fh)) { diff --git a/arch/arm/mach-s3c2410/clock.c b/arch/arm/mach-s3c2410/clock.c index 82e8253b1fa..5830ae3ddd1 100644 --- a/arch/arm/mach-s3c2410/clock.c +++ b/arch/arm/mach-s3c2410/clock.c @@ -34,16 +34,15 @@ #include <linux/err.h> #include <linux/platform_device.h> #include <linux/sysdev.h> - #include <linux/interrupt.h> #include <linux/ioport.h> +#include <linux/clk.h> #include <asm/hardware.h> #include <asm/atomic.h> #include <asm/irq.h> #include <asm/io.h> -#include <asm/hardware/clock.h> #include <asm/arch/regs-clock.h> #include "clock.h" @@ -151,18 +150,6 @@ void clk_disable(struct clk *clk) } -int clk_use(struct clk *clk) -{ - atomic_inc(&clk->used); - return 0; -} - - -void clk_unuse(struct clk *clk) -{ - atomic_dec(&clk->used); -} - unsigned long clk_get_rate(struct clk *clk) { if (IS_ERR(clk)) @@ -196,8 +183,6 @@ EXPORT_SYMBOL(clk_get); EXPORT_SYMBOL(clk_put); EXPORT_SYMBOL(clk_enable); EXPORT_SYMBOL(clk_disable); -EXPORT_SYMBOL(clk_use); -EXPORT_SYMBOL(clk_unuse); EXPORT_SYMBOL(clk_get_rate); EXPORT_SYMBOL(clk_round_rate); EXPORT_SYMBOL(clk_set_rate); @@ -370,7 +355,6 @@ static struct clk init_clocks[] = { int s3c24xx_register_clock(struct clk *clk) { clk->owner = THIS_MODULE; - atomic_set(&clk->used, 0); if (clk->enable == NULL) clk->enable = clk_null_enable; diff --git a/arch/arm/mach-s3c2410/clock.h b/arch/arm/mach-s3c2410/clock.h index 7953b6f397b..177d5c8decf 100644 --- a/arch/arm/mach-s3c2410/clock.h +++ b/arch/arm/mach-s3c2410/clock.h @@ -16,7 +16,6 @@ struct clk { struct clk *parent; const char *name; int id; - atomic_t used; unsigned long rate; unsigned long ctrlbit; int (*enable)(struct clk *, int enable); diff --git a/arch/arm/mach-s3c2410/s3c2440-clock.c b/arch/arm/mach-s3c2410/s3c2440-clock.c index c67e0979aec..b557a2be8a0 100644 --- a/arch/arm/mach-s3c2410/s3c2440-clock.c +++ b/arch/arm/mach-s3c2410/s3c2440-clock.c @@ -29,16 +29,15 @@ #include <linux/err.h> #include <linux/device.h> #include <linux/sysdev.h> - #include <linux/interrupt.h> #include <linux/ioport.h> +#include <linux/clk.h> #include <asm/hardware.h> #include <asm/atomic.h> #include <asm/irq.h> #include <asm/io.h> -#include <asm/hardware/clock.h> #include <asm/arch/regs-clock.h> #include "clock.h" diff --git a/arch/arm/mach-s3c2410/s3c2440.c b/arch/arm/mach-s3c2410/s3c2440.c index 4d63e7133b4..b7fe6d9453f 100644 --- a/arch/arm/mach-s3c2410/s3c2440.c +++ b/arch/arm/mach-s3c2410/s3c2440.c @@ -28,6 +28,7 @@ #include <linux/init.h> #include <linux/platform_device.h> #include <linux/sysdev.h> +#include <linux/clk.h> #include <asm/mach/arch.h> #include <asm/mach/map.h> @@ -36,7 +37,6 @@ #include <asm/hardware.h> #include <asm/io.h> #include <asm/irq.h> -#include <asm/hardware/clock.h> #include <asm/arch/regs-clock.h> #include <asm/arch/regs-serial.h> diff --git a/arch/arm/mach-s3c2410/time.c b/arch/arm/mach-s3c2410/time.c index 8a00e3c3cd0..10a2976aefd 100644 --- a/arch/arm/mach-s3c2410/time.c +++ b/arch/arm/mach-s3c2410/time.c @@ -24,6 +24,7 @@ #include <linux/init.h> #include <linux/interrupt.h> #include <linux/err.h> +#include <linux/clk.h> #include <asm/system.h> #include <asm/leds.h> @@ -35,7 +36,6 @@ #include <asm/arch/regs-timer.h> #include <asm/arch/regs-irq.h> #include <asm/mach/time.h> -#include <asm/hardware/clock.h> #include "clock.h" #include "cpu.h" @@ -191,7 +191,6 @@ static void s3c2410_timer_setup (void) if (IS_ERR(clk)) panic("failed to get clock for system timer"); - clk_use(clk); clk_enable(clk); pclk = clk_get_rate(clk); diff --git a/arch/arm/mach-sa1100/pm.c b/arch/arm/mach-sa1100/pm.c index 59c7964cfe1..786c8534231 100644 --- a/arch/arm/mach-sa1100/pm.c +++ b/arch/arm/mach-sa1100/pm.c @@ -135,29 +135,11 @@ unsigned long sleep_phys_sp(void *sp) } /* - * Called after processes are frozen, but before we shut down devices. - */ -static int sa11x0_pm_prepare(suspend_state_t state) -{ - return 0; -} - -/* - * Called after devices are re-setup, but before processes are thawed. - */ -static int sa11x0_pm_finish(suspend_state_t state) -{ - return 0; -} - -/* * Set to PM_DISK_FIRMWARE so we can quickly veto suspend-to-disk. */ static struct pm_ops sa11x0_pm_ops = { .pm_disk_mode = PM_DISK_FIRMWARE, - .prepare = sa11x0_pm_prepare, .enter = sa11x0_pm_enter, - .finish = sa11x0_pm_finish, }; static int __init sa11x0_pm_init(void) diff --git a/arch/arm/mach-versatile/clock.c b/arch/arm/mach-versatile/clock.c index b96a2ea15d4..dcf10014f5c 100644 --- a/arch/arm/mach-versatile/clock.c +++ b/arch/arm/mach-versatile/clock.c @@ -14,9 +14,9 @@ #include <linux/errno.h> #include <linux/err.h> #include <linux/string.h> +#include <linux/clk.h> #include <asm/semaphore.h> -#include <asm/hardware/clock.h> #include <asm/hardware/icst307.h> #include "clock.h" @@ -58,17 +58,6 @@ void clk_disable(struct clk *clk) } EXPORT_SYMBOL(clk_disable); -int clk_use(struct clk *clk) -{ - return 0; -} -EXPORT_SYMBOL(clk_use); - -void clk_unuse(struct clk *clk) -{ -} -EXPORT_SYMBOL(clk_unuse); - unsigned long clk_get_rate(struct clk *clk) { return clk->rate; diff --git a/arch/arm/mach-versatile/core.c b/arch/arm/mach-versatile/core.c index a1ca46630dd..90023745b23 100644 --- a/arch/arm/mach-versatile/core.c +++ b/arch/arm/mach-versatile/core.c @@ -25,14 +25,14 @@ #include <linux/platform_device.h> #include <linux/sysdev.h> #include <linux/interrupt.h> +#include <linux/amba/bus.h> +#include <linux/amba/clcd.h> #include <asm/system.h> #include <asm/hardware.h> #include <asm/io.h> #include <asm/irq.h> #include <asm/leds.h> -#include <asm/hardware/amba.h> -#include <asm/hardware/amba_clcd.h> #include <asm/hardware/arm_timer.h> #include <asm/hardware/icst307.h> diff --git a/arch/arm/mach-versatile/core.h b/arch/arm/mach-versatile/core.h index 588c20669d5..afcaa858eb1 100644 --- a/arch/arm/mach-versatile/core.h +++ b/arch/arm/mach-versatile/core.h @@ -22,7 +22,7 @@ #ifndef __ASM_ARCH_VERSATILE_H #define __ASM_ARCH_VERSATILE_H -#include <asm/hardware/amba.h> +#include <linux/amba/bus.h> extern void __init versatile_init(void); extern void __init versatile_init_irq(void); diff --git a/arch/arm/mach-versatile/versatile_ab.c b/arch/arm/mach-versatile/versatile_ab.c index 8b0b3bef24a..e74c8a2fbb9 100644 --- a/arch/arm/mach-versatile/versatile_ab.c +++ b/arch/arm/mach-versatile/versatile_ab.c @@ -23,12 +23,12 @@ #include <linux/init.h> #include <linux/device.h> #include <linux/sysdev.h> +#include <linux/amba/bus.h> #include <asm/hardware.h> #include <asm/io.h> #include <asm/irq.h> #include <asm/mach-types.h> -#include <asm/hardware/amba.h> #include <asm/mach/arch.h> diff --git a/arch/arm/mach-versatile/versatile_pb.c b/arch/arm/mach-versatile/versatile_pb.c index 7c3078c3891..22d5ca07f75 100644 --- a/arch/arm/mach-versatile/versatile_pb.c +++ b/arch/arm/mach-versatile/versatile_pb.c @@ -23,12 +23,12 @@ #include <linux/init.h> #include <linux/device.h> #include <linux/sysdev.h> +#include <linux/amba/bus.h> #include <asm/hardware.h> #include <asm/io.h> #include <asm/irq.h> #include <asm/mach-types.h> -#include <asm/hardware/amba.h> #include <asm/mach/arch.h> #include <asm/mach/mmc.h> diff --git a/arch/arm/mm/consistent.c b/arch/arm/mm/consistent.c index dbfe9e891f0..0513ed1b2fc 100644 --- a/arch/arm/mm/consistent.c +++ b/arch/arm/mm/consistent.c @@ -19,7 +19,6 @@ #include <linux/dma-mapping.h> #include <asm/cacheflush.h> -#include <asm/io.h> #include <asm/tlbflush.h> #define CONSISTENT_BASE (0xffc00000) diff --git a/arch/arm/mm/discontig.c b/arch/arm/mm/discontig.c index 0d097bb1bc4..1e560218950 100644 --- a/arch/arm/mm/discontig.c +++ b/arch/arm/mm/discontig.c @@ -9,10 +9,8 @@ * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */ - #include <linux/module.h> -#include <linux/mm.h> -#include <linux/init.h> +#include <linux/mmzone.h> #include <linux/bootmem.h> #if MAX_NUMNODES != 4 && MAX_NUMNODES != 16 diff --git a/arch/arm/mm/mm-armv.c b/arch/arm/mm/mm-armv.c index 9e50127be63..d0245a31d4d 100644 --- a/arch/arm/mm/mm-armv.c +++ b/arch/arm/mm/mm-armv.c @@ -19,7 +19,6 @@ #include <asm/pgalloc.h> #include <asm/page.h> -#include <asm/io.h> #include <asm/setup.h> #include <asm/tlbflush.h> diff --git a/arch/arm/plat-omap/clock.c b/arch/arm/plat-omap/clock.c index 7ce39b986e2..84fd65656fc 100644 --- a/arch/arm/plat-omap/clock.c +++ b/arch/arm/plat-omap/clock.c @@ -19,10 +19,10 @@ #include <linux/errno.h> #include <linux/err.h> #include <linux/string.h> +#include <linux/clk.h> #include <asm/io.h> #include <asm/semaphore.h> -#include <asm/hardware/clock.h> #include <asm/arch/clock.h> diff --git a/arch/arm/plat-omap/common.c b/arch/arm/plat-omap/common.c index ccdb452630c..adffc5a859e 100644 --- a/arch/arm/plat-omap/common.c +++ b/arch/arm/plat-omap/common.c @@ -18,12 +18,12 @@ #include <linux/tty.h> #include <linux/serial_8250.h> #include <linux/serial_reg.h> +#include <linux/clk.h> #include <asm/hardware.h> #include <asm/system.h> #include <asm/pgtable.h> #include <asm/mach/map.h> -#include <asm/hardware/clock.h> #include <asm/io.h> #include <asm/setup.h> diff --git a/arch/arm/plat-omap/cpu-omap.c b/arch/arm/plat-omap/cpu-omap.c index fd894bb0010..98edc9fdd6d 100644 --- a/arch/arm/plat-omap/cpu-omap.c +++ b/arch/arm/plat-omap/cpu-omap.c @@ -19,13 +19,12 @@ #include <linux/delay.h> #include <linux/init.h> #include <linux/err.h> +#include <linux/clk.h> #include <asm/hardware.h> #include <asm/io.h> #include <asm/system.h> -#include <asm/hardware/clock.h> - /* TODO: Add support for SDRAM timing changes */ int omap_verify_speed(struct cpufreq_policy *policy) diff --git a/arch/arm/plat-omap/gpio.c b/arch/arm/plat-omap/gpio.c index 76f721d8513..ca3681a824a 100644 --- a/arch/arm/plat-omap/gpio.c +++ b/arch/arm/plat-omap/gpio.c @@ -19,9 +19,9 @@ #include <linux/ptrace.h> #include <linux/sysdev.h> #include <linux/err.h> +#include <linux/clk.h> #include <asm/hardware.h> -#include <asm/hardware/clock.h> #include <asm/irq.h> #include <asm/arch/irqs.h> #include <asm/arch/gpio.h> diff --git a/arch/arm/plat-omap/mcbsp.c b/arch/arm/plat-omap/mcbsp.c index ea9475c8665..be0e0f32a59 100644 --- a/arch/arm/plat-omap/mcbsp.c +++ b/arch/arm/plat-omap/mcbsp.c @@ -19,6 +19,7 @@ #include <linux/completion.h> #include <linux/interrupt.h> #include <linux/err.h> +#include <linux/clk.h> #include <asm/delay.h> #include <asm/io.h> @@ -30,8 +31,6 @@ #include <asm/arch/dsp_common.h> #include <asm/arch/mcbsp.h> -#include <asm/hardware/clock.h> - #ifdef CONFIG_MCBSP_DEBUG #define DBG(x...) printk(x) #else diff --git a/arch/arm/plat-omap/ocpi.c b/arch/arm/plat-omap/ocpi.c index b8614822748..e40fcc8b43d 100644 --- a/arch/arm/plat-omap/ocpi.c +++ b/arch/arm/plat-omap/ocpi.c @@ -31,9 +31,9 @@ #include <linux/init.h> #include <linux/spinlock.h> #include <linux/err.h> +#include <linux/clk.h> #include <asm/io.h> -#include <asm/hardware/clock.h> #include <asm/hardware.h> #define OCPI_BASE 0xfffec320 |