diff options
Diffstat (limited to 'arch')
-rw-r--r-- | arch/arm/Kconfig | 2 | ||||
-rw-r--r-- | arch/arm/Makefile | 3 | ||||
-rw-r--r-- | arch/arm/mach-pxa/Kconfig | 5 | ||||
-rw-r--r-- | arch/arm/mach-pxa/Makefile | 1 | ||||
-rw-r--r-- | arch/arm/mach-pxa/Makefile.boot | 2 | ||||
-rw-r--r-- | arch/arm/mach-pxa/mp900.c | 107 | ||||
-rw-r--r-- | arch/arm/mach-sa1100/Kconfig | 13 | ||||
-rw-r--r-- | arch/arm/mach-sa1100/Makefile | 1 | ||||
-rw-r--r-- | arch/arm/mach-sa1100/cpu-sa1110.c | 13 | ||||
-rw-r--r-- | arch/arm/mach-sa1100/generic.c | 6 | ||||
-rw-r--r-- | arch/arm/mach-sa1100/jornada720.c | 68 | ||||
-rw-r--r-- | arch/arm/mach-sa1100/jornada720_apm.c | 165 | ||||
-rw-r--r-- | arch/arm/mach-sa1100/jornada720_ssp.c | 60 | ||||
-rw-r--r-- | arch/sh/boards/hp6xx/hp6xx_apm.c | 3 | ||||
-rw-r--r-- | arch/sh/boards/hp6xx/pm.c | 43 | ||||
-rw-r--r-- | arch/sh/boards/hp6xx/setup.c | 54 | ||||
-rw-r--r-- | arch/sh/cchips/hd6446x/Makefile | 2 | ||||
-rw-r--r-- | arch/sh/cchips/hd6446x/hd64461.c | 13 | ||||
-rw-r--r-- | arch/sh/kernel/cpu/irq/intc.c | 11 |
19 files changed, 503 insertions, 69 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index b786e68914d4a2..84d5106978563c 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -962,7 +962,7 @@ source "drivers/cpufreq/Kconfig" config CPU_FREQ_SA1100 bool - depends on CPU_FREQ && (SA1100_H3100 || SA1100_H3600 || SA1100_H3800 || SA1100_LART || SA1100_PLEB || SA1100_BADGE4 || SA1100_HACKKIT) + depends on CPU_FREQ && (SA1100_JORNADA720 || SA1100_H3100 || SA1100_H3600 || SA1100_H3800 || SA1100_LART || SA1100_PLEB || SA1100_BADGE4 || SA1100_HACKKIT) default y config CPU_FREQ_SA1110 diff --git a/arch/arm/Makefile b/arch/arm/Makefile index e72db27e0ba074..033afb5c966c95 100644 --- a/arch/arm/Makefile +++ b/arch/arm/Makefile @@ -109,6 +109,9 @@ ifeq ($(CONFIG_ARCH_SA1100),y) textofs-$(CONFIG_SA1111) := 0x00208000 endif machine-$(CONFIG_ARCH_PXA) := pxa +ifeq ($(CONFIG_ARCH_PXA),y) + textofs-$(CONFIG_ARCH_MP900C) := 0x00228000 +endif machine-$(CONFIG_ARCH_L7200) := l7200 machine-$(CONFIG_ARCH_INTEGRATOR) := integrator textofs-$(CONFIG_ARCH_CLPS711X) := 0x00028000 diff --git a/arch/arm/mach-pxa/Kconfig b/arch/arm/mach-pxa/Kconfig index 5da7a68204920c..a2803517621683 100644 --- a/arch/arm/mach-pxa/Kconfig +++ b/arch/arm/mach-pxa/Kconfig @@ -29,6 +29,11 @@ config ARCH_GUMSTIX Say Y here if you intend to run this kernel on a Gumstix Full Function Minature Computer. +config ARCH_MP900C + bool "NEC MobilePro900C" + depends on ARCH_PXA + select PXA25x + config ARCH_LUBBOCK bool "Intel DBPXA250 Development Platform" select PXA25x diff --git a/arch/arm/mach-pxa/Makefile b/arch/arm/mach-pxa/Makefile index 0e6d05bb81aa9a..eb42cb0523268a 100644 --- a/arch/arm/mach-pxa/Makefile +++ b/arch/arm/mach-pxa/Makefile @@ -36,6 +36,7 @@ obj-$(CONFIG_MACH_TOSA) += tosa.o obj-$(CONFIG_MACH_EM_X270) += em-x270.o obj-$(CONFIG_MACH_MAGICIAN) += magician.o obj-$(CONFIG_ARCH_PXA_ESERIES) += eseries.o +obj-$(CONFIG_ARCH_MP900C) += mp900.o ifeq ($(CONFIG_MACH_ZYLONITE),y) obj-y += zylonite.o diff --git a/arch/arm/mach-pxa/Makefile.boot b/arch/arm/mach-pxa/Makefile.boot index 1ead67178eca36..7f6be91cfcbdbb 100644 --- a/arch/arm/mach-pxa/Makefile.boot +++ b/arch/arm/mach-pxa/Makefile.boot @@ -1,2 +1,2 @@ - zreladdr-y := 0xa0008000 + zreladdr-y := 0xa0228000 diff --git a/arch/arm/mach-pxa/mp900.c b/arch/arm/mach-pxa/mp900.c new file mode 100644 index 00000000000000..9eb8a0802f36ad --- /dev/null +++ b/arch/arm/mach-pxa/mp900.c @@ -0,0 +1,107 @@ +/* + * linux/arch/arm/mach-pxa/mp900.c + * + * Support for the NEC MobilePro900/C platform + * + * Based on mach-pxa/gumstix.c + * + * 2007, 2008 Kristoffer Ericson <kristoffer.ericson@gmail.com> + * 2007, 2008 Michael Petchkovsky <mkpetch@internode.on.net> + * + * 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/init.h> +#include <linux/device.h> +#include <linux/platform_device.h> +#include <linux/types.h> +#include <linux/usb/isp116x.h> + +#include <asm/hardware.h> +#include <asm/arch-pxa/pxa-regs.h> +#include <asm/arch/mfp-pxa25x.h> +#include <asm/mach-types.h> +#include <asm/mach/arch.h> +#include "generic.h" + +static unsigned long mp900c_pin_config[] = { + GPIO1_GPIO | WAKEUP_ON_EDGE_RISE, + GPIO13_GPIO | WAKEUP_ON_EDGE_RISE, +}; + +static void isp116x_pfm_delay(struct device *dev, int delay) +{ + + /* 400Mhz PXA2 = 2.5ns / instruction */ + + int cyc = delay / 10; + + /* 4 Instructions = 4 x 2.5ns = 10ns */ + __asm__ volatile ("0:\n" + "subs %0, %1, #1\n" + "bge 0b\n" + :"=r" (cyc) + :"0"(cyc) + ); +} + +static struct isp116x_platform_data isp116x_pfm_data = { + .remote_wakeup_enable = 1, + .delay = isp116x_pfm_delay, +}; + +static struct resource isp116x_pfm_resources[] = { + [0] = { + .start = 0x0d000000, + .end = 0x0d000000 + 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = 0x0d000000 + 4, + .end = 0x0d000000 + 5, + .flags = IORESOURCE_MEM, + }, + [2] = { + .start = 61, + .end = 61, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device mp900c_dummy_device = { + .name = "mp900c_dummy", + .id = -1, +}; + +static struct platform_device mp900c_usb = { + .name = "isp116x-hcd", + .num_resources = ARRAY_SIZE(isp116x_pfm_resources), + .resource = isp116x_pfm_resources, + .dev.platform_data = &isp116x_pfm_data, +}; + +static struct platform_device *devices[] __initdata = { + &mp900c_dummy_device, + &mp900c_usb, +}; + +static void __init mp900c_init(void) +{ + printk(KERN_INFO "MobilePro 900/C machine init\n"); + pxa2xx_mfp_config(ARRAY_AND_SIZE(mp900c_pin_config)); + platform_add_devices(devices, ARRAY_SIZE(devices)); +} + +/* Maintainer - Michael Petchkovsky <mkpetch@internode.on.net> */ +MACHINE_START(NEC_MP900, "MobilePro900/C") + .phys_io = 0x40000000, + .boot_params = 0xa0220100, + .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc, + .timer = &pxa_timer, + .map_io = pxa_map_io, + .init_irq = pxa25x_init_irq, + .init_machine = mp900c_init, +MACHINE_END + diff --git a/arch/arm/mach-sa1100/Kconfig b/arch/arm/mach-sa1100/Kconfig index f99d9013905fea..36a0ab30b1d62e 100644 --- a/arch/arm/mach-sa1100/Kconfig +++ b/arch/arm/mach-sa1100/Kconfig @@ -101,6 +101,13 @@ config SA1100_JORNADA720 handheld computer. See <http://www.hp.com/jornada/products/720> for details. +config SA1100_JORNADA720_FLASHROM + bool "HP Jornada 720 FlashRom" + depends on SA1100_JORNADA720 + help + Say Y here if you want to build a kernel for the HP Jornada 720 + with an added flashrom board. + config SA1100_JORNADA720_SSP bool "HP Jornada 720 Extended SSP driver" select SA1100_SSP @@ -111,6 +118,12 @@ config SA1100_JORNADA720_SSP keyboard, touchscreen, backlight and battery. This driver also activates the generic SSP which it extends. +config SA1100_JORNADA720_APM + bool "HP Jornada720 APM Support" + depends on SA1100_JORNADA720 && SA1100_JORNADA720 + help + Say Y here if you want battery status and other APM features. + config SA1100_HACKKIT bool "HackKit Core CPU Board" help diff --git a/arch/arm/mach-sa1100/Makefile b/arch/arm/mach-sa1100/Makefile index 8e0244631d6518..7b5d2a53bdbac8 100644 --- a/arch/arm/mach-sa1100/Makefile +++ b/arch/arm/mach-sa1100/Makefile @@ -32,6 +32,7 @@ led-$(CONFIG_SA1100_HACKKIT) += leds-hackkit.o obj-$(CONFIG_SA1100_JORNADA720) += jornada720.o obj-$(CONFIG_SA1100_JORNADA720_SSP) += jornada720_ssp.o +obj-$(CONFIG_SA1100_JORNADA720_APM) += jornada720_apm.o obj-$(CONFIG_SA1100_LART) += lart.o led-$(CONFIG_SA1100_LART) += leds-lart.o diff --git a/arch/arm/mach-sa1100/cpu-sa1110.c b/arch/arm/mach-sa1100/cpu-sa1110.c index 36b47ff5af11dd..ba7352aaa5ee78 100644 --- a/arch/arm/mach-sa1100/cpu-sa1110.c +++ b/arch/arm/mach-sa1100/cpu-sa1110.c @@ -108,6 +108,15 @@ static struct sdram_params sdram_tbl[] __initdata = { .twr = 8, .refresh = 64000, .cas_latency = 3, + }, { /* Micron MT48LC128M4A2 */ + .name = "MT48LC32M16A2", + .rows = 15, + .tck = 10, /* 2 CLKs */ + .trcd = 20, /* 2 CLKs */ + .trp = 20, /* 2 CLKs */ + .twr = 16, /* 1 CLK + 7.5ns */ + .refresh = 64000, + .cas_latency = 3, }, }; @@ -374,7 +383,11 @@ static int __init sa1110_clk_init(void) if (machine_is_h3100()) name = "KM416S4030CT"; if (machine_is_jornada720()) +#ifdef CONFIG_SA1100_JORNADA720_FLASHROM + name = "MT48LC32M16A2"; +#else name = "K4S281632B-1H"; +#endif } sdram = sa1110_find_sdram(name); diff --git a/arch/arm/mach-sa1100/generic.c b/arch/arm/mach-sa1100/generic.c index 0c2fa1c4fb4c77..3fc54b08aea88b 100644 --- a/arch/arm/mach-sa1100/generic.c +++ b/arch/arm/mach-sa1100/generic.c @@ -110,7 +110,7 @@ unsigned int sa11x0_getspeed(unsigned int cpu) #else /* * We still need to provide this so building without cpufreq works. - */ + */ unsigned int cpufreq_get(unsigned int cpu) { return cclk_frequency_100khz[PPCR & 0xf] * 100; @@ -386,7 +386,7 @@ EXPORT_SYMBOL(sa1100fb_lcd_power); */ static struct map_desc standard_io_desc[] __initdata = { - { /* PCM */ + { /* PCM */ .virtual = 0xf8000000, .pfn = __phys_to_pfn(0x80000000), .length = 0x00100000, @@ -425,7 +425,7 @@ void __init sa1110_mb_disable(void) unsigned long flags; local_irq_save(flags); - + PGSR &= ~GPIO_MBGNT; GPCR = GPIO_MBGNT; GPDR = (GPDR & ~GPIO_MBREQ) | GPIO_MBGNT; diff --git a/arch/arm/mach-sa1100/jornada720.c b/arch/arm/mach-sa1100/jornada720.c index 52ac37d1e23aa9..23c853623de00d 100644 --- a/arch/arm/mach-sa1100/jornada720.c +++ b/arch/arm/mach-sa1100/jornada720.c @@ -43,6 +43,8 @@ /* line 110 of HP's doc */ #define TUCR_VAL 0x20000400 +#define SBI_SKCR __REG(SA1111_VBASE) + /* memory space (line 52 of HP's doc) */ #define SA1111REGSTART 0x40000000 #define SA1111REGLEN 0x00001fff @@ -52,6 +54,8 @@ /* 512kB framebuffer */ #define EPSONFBLEN 512*1024 +extern void sa1110_mb_disable(void); + static struct s1d13xxxfb_regval s1d13xxxfb_initregs[] = { /* line 344 of HP's doc */ {0x0001,0x00}, // Miscellaneous Register @@ -226,32 +230,60 @@ static struct platform_device jornada_ssp_device = { .id = -1, }; +static struct platform_device jornada_bllcd_device = { + .name = "jornada_bllcd", + .id = -1, +}; + +static struct platform_device jornada_kbd_device = { + .name = "jornada720_kbd", + .id = -1, +}; + +static struct platform_device jornada_ts_device = { + .name = "jornada_ts", + .id = -1, +}; + +static struct platform_device jornada_apm_device = { + .name = "jornada_apm", + .id = -1, +}; + static struct platform_device *devices[] __initdata = { &sa1111_device, -#ifdef CONFIG_SA1100_JORNADA720_SSP &jornada_ssp_device, -#endif &s1d13xxxfb_device, + &jornada_bllcd_device, + &jornada_kbd_device, + &jornada_ts_device, + &jornada_apm_device, }; static int __init jornada720_init(void) { int ret = -ENODEV; - if (machine_is_jornada720()) { - /* we want to use gpio20 as input to drive the clock of our uart 3 */ - GPDR |= GPIO_GPIO20; /* Clear gpio20 pin as input */ - TUCR = TUCR_VAL; - GPSR = GPIO_GPIO20; /* start gpio20 pin */ - udelay(1); - GPCR = GPIO_GPIO20; /* stop gpio20 */ - udelay(1); - GPSR = GPIO_GPIO20; /* restart gpio20 */ - udelay(20); /* give it some time to restart */ - - ret = platform_add_devices(devices, ARRAY_SIZE(devices)); - } + printk(KERN_INFO "HP Jornada 710/720/728 Machine Init\n"); + /* we want to use gpio20 as input to drive the clock of our uart 3 */ + GPDR |= GPIO_GPIO20; /* Clear gpio20 pin as input */ + TUCR = TUCR_VAL; + GPSR = GPIO_GPIO20; /* start gpio20 pin */ + udelay(10); + GPCR = GPIO_GPIO20; /* stop gpio20 */ + udelay(10); + GPSR = GPIO_GPIO20; /* restart gpio20 */ + udelay(40); /* give it some time to restart */ +#ifdef CONFIG_SA1100_JORNADA720_FLASHROM + SBI_SKCR = SKCR_OE_EN | SKCR_PLL_BYPASS | SKCR_RDYEN | SKCR_RCLKEN; + mdelay(100); + + /* Need to disable this so we dont get frozen at dma sa1111 configuring */ + sa1110_mb_disable(); +#endif + ret = platform_add_devices(devices, ARRAY_SIZE(devices)); + return ret; } @@ -285,6 +317,7 @@ static void __init jornada720_map_io(void) sa1100_register_uart(1, 1); } +#ifdef CONFIG_SA1100_JORNADA720_FLASHROM static struct mtd_partition jornada720_partitions[] = { { .name = "JORNADA720 boot firmware", @@ -338,7 +371,7 @@ static struct flash_platform_data jornada720_flash_data = { static struct resource jornada720_flash_resource = { .start = SA1100_CS0_PHYS, - .end = SA1100_CS0_PHYS + SZ_32M - 1, + .end = SA1100_CS0_PHYS + SZ_64M - 1, .flags = IORESOURCE_MEM, }; @@ -346,6 +379,7 @@ static void __init jornada720_mach_init(void) { sa11x0_set_flash_data(&jornada720_flash_data, &jornada720_flash_resource, 1); } +#endif MACHINE_START(JORNADA720, "HP Jornada 720") /* Maintainer: Kristoffer Ericson <Kristoffer.Ericson@gmail.com> */ @@ -355,5 +389,7 @@ MACHINE_START(JORNADA720, "HP Jornada 720") .map_io = jornada720_map_io, .init_irq = sa1100_init_irq, .timer = &sa1100_timer, +#ifdef CONFIG_JORNADA720_FLASHROM .init_machine = jornada720_mach_init, +#endif MACHINE_END diff --git a/arch/arm/mach-sa1100/jornada720_apm.c b/arch/arm/mach-sa1100/jornada720_apm.c new file mode 100644 index 00000000000000..05736a6b7fbb2d --- /dev/null +++ b/arch/arm/mach-sa1100/jornada720_apm.c @@ -0,0 +1,165 @@ +/* + * arch/arm/mach-sa1100/jornada720_apm.c + * + * HP Jornada 710/720/728 battery detection (apm) platform driver + * + * Copyright (C) 2007,2008 Kristoffer Ericson <Kristoffer.Ericson@gmail.com> + * Copyright (C) 2006 Filip Zyzniewski <filip.zyzniewski@tefnet.pl> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 (or later) as + * published by the Free Software Foundation. + */ + +#include <linux/init.h> +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/delay.h> +#include <linux/platform_device.h> +#include <linux/apm-emulation.h> + +#include <asm/hardware.h> +#include <asm/arch/jornada720.h> + +MODULE_AUTHOR("Filip Zyzniewski <filip.zyzniewski@tefnet.pl>, Kristoffer Ericson <kristoffer.ericson@gmail.com>"); +MODULE_DESCRIPTION("HP Jornada 710/720/728 battery status reporting"); +MODULE_LICENSE("GPL"); + +/** + * voltage && detection + */ +#define max_voltage 670 /* max voltage without ac power */ +#define min_voltage 430 /* min voltage */ +#define ac_connected() ((GPLR & GPIO_GPIO4) ? 0 : 1) /* is ac connected? */ +#define ac_charging() (! (GPLR & GPIO_GPIO26) ) /* are we charging? */ + +/** + * battery calculations + */ +#define main_diff (max_voltage - min_voltage) /* just to keep defines small */ +#define main_ac_coeff 100 / 105 /* correcting battery values when with ac */ +#define main_divisor (main_diff * main_diff) / 100 /* battery power to percent */ +#define main_lin_corr (main_diff * main_diff) / 2 /* adjusting for non-linearity */ + +int jornada720_apm_get_battery_raw(int battnum) +{ + unsigned char low_byte, high_byte, msb; + + jornada_ssp_start(); + + /* if ssp connection fails we bail out */ + if(jornada_ssp_inout(GETBATTERYDATA) < 0) { + printk(KERN_WARNING "APM: Failed trying to aquire battery data \n"); + jornada_ssp_end(); + return -1; + } + + low_byte = jornada_ssp_inout(TXDUMMY); /* backup battery value */ + high_byte = jornada_ssp_inout(TXDUMMY); /* main battery value */ + msb = jornada_ssp_inout(TXDUMMY); /* status */ + + jornada_ssp_end(); + + /* main battery */ + if (battnum) { + if ((msb & 0x03) == 0x03) return -1; /* main battery absent */ + return ((msb & 0x03) << 8) + low_byte; /* wrapping values */ + } + /* backup battery */ + else { + if ((msb & 0x0c) == 0x00) return -1; /* backup battery abset */ + return ((msb & 0x0c) << 6) + high_byte; /* wrapping values */ + } +} + +int jornada720_apm_get_battery(int battnum) +{ + int ret = jornada720_apm_get_battery_raw(battnum); + + if (ret == -1) + return ret; + + /* main battery only, cannot calculate backup battery */ + if (battnum) { + ret -= min_voltage; /* we want 0 for fully drained battery */ + + /* trying to get values more linear */ + ret *= ret; + if (ret > 37000) + ret = ret * 3/2 - main_lin_corr; + else + ret = ret * 7/10; + + ret /= main_divisor; /* 0-100% range */ + + if (ac_connected()) /* adjusting for ac fluctuations */ + ret = ret * main_ac_coeff; + + if (ret > 100) + ret = 100; /* should never report above 100% */ + } + return ret; +} + +static void jornada720_apm_get_power_status(struct apm_power_info *info) +{ + + info->battery_life = jornada720_apm_get_battery(1); /* main battery */ + + if (info->battery_life == -1) { + info->battery_status = APM_BATTERY_STATUS_NOT_PRESENT; + info->battery_flag = APM_BATTERY_FLAG_NOT_PRESENT; + + } else if (info->battery_life < 30) { + info->battery_status = APM_BATTERY_STATUS_LOW; + info->battery_flag = APM_BATTERY_FLAG_LOW; + + } else if (info->battery_life < 5) { + info->battery_status = APM_BATTERY_STATUS_CRITICAL; + info->battery_flag = APM_BATTERY_FLAG_CRITICAL; + + } else { + info->battery_status = APM_BATTERY_STATUS_HIGH; + info->battery_flag = APM_BATTERY_FLAG_HIGH; + } + + if (ac_charging()) + info->battery_status = APM_BATTERY_STATUS_CHARGING; + + info->ac_line_status = ac_connected(); +} + +static int __devinit jornada720_apm_probe(struct platform_device *pdev) +{ + printk(KERN_INFO "jornada720_apm: Initializing\n"); + + apm_get_power_status = jornada720_apm_get_power_status; + return 0; +} + +static int __devexit jornada720_apm_remove(struct platform_device *pdev) +{ + if (apm_get_power_status == jornada720_apm_get_power_status) + apm_get_power_status=NULL; + return 0; +} + +static struct platform_driver jornada720_apm_driver = { + .driver = { + .name = "jornada_apm", + }, + .probe = jornada720_apm_probe, + .remove = __devexit_p(jornada720_apm_remove), +}; + +static int __init jornada720_apm_init(void) +{ + return platform_driver_register(&jornada720_apm_driver); +} + +static void __exit jornada720_apm_exit(void) { + platform_driver_unregister(&jornada720_apm_driver); +} + +module_init(jornada720_apm_init); +module_exit(jornada720_apm_exit); diff --git a/arch/arm/mach-sa1100/jornada720_ssp.c b/arch/arm/mach-sa1100/jornada720_ssp.c index 395c39bed7d823..7ab256ac0aee78 100644 --- a/arch/arm/mach-sa1100/jornada720_ssp.c +++ b/arch/arm/mach-sa1100/jornada720_ssp.c @@ -24,6 +24,8 @@ #include <asm/hardware/ssp.h> #include <asm/arch/jornada720.h> +#define SA1100_PPDR_LFCLK 0x400 + static DEFINE_SPINLOCK(jornada_ssp_lock); static unsigned long jornada_ssp_flags; @@ -44,7 +46,7 @@ u8 inline jornada_ssp_reverse(u8 byte) ((0x04 & byte) << 3) | ((0x02 & byte) << 5) | ((0x01 & byte) << 7); -}; +} EXPORT_SYMBOL(jornada_ssp_reverse); /** @@ -75,7 +77,7 @@ int jornada_ssp_byte(u8 byte) ssp_read_word(&ret); return jornada_ssp_reverse(ret); -}; +} EXPORT_SYMBOL(jornada_ssp_byte); /** @@ -130,27 +132,38 @@ int jornada_ssp_end() }; EXPORT_SYMBOL(jornada_ssp_end); -static int __init jornada_ssp_probe(struct platform_device *dev) +static int __init jornada_ssp_probe(struct platform_device *pdev) { int ret; - GPSR = GPIO_GPIO25; - +#ifdef CONFIG_SA1100_JORNADA720_FLASHROM + printk(KERN_INFO "SSP: Resetting SSP bus\n"); + PPSR &= (SA1100_PPDR_LFCLK | 0x80 | 0x10); + udelay(500); + + PPDR |= (SA1100_PPDR_LFCLK | 0x80 | 0x10); + udelay(500); + + PPSR |= SA1100_PPDR_LFCLK; + udelay(500); + + /* init of Serial 4 port */ + GPSR = 0x02000000; + GPDR |= 0x02000000; + Ser4SSCR0 = 0x0307; + Ser4MCCR0 = 0; + Ser4SSSR = 0; + Ser4SSCR1 = 0x18; + Ser4SSCR0 = 0x0387; +#endif + ret = ssp_init(); - - /* worked fine, lets not bother with anything else */ + if (!ret) { printk(KERN_INFO "SSP: device initialized with irq\n"); return ret; } - - printk(KERN_WARNING "SSP: initialization failed, trying non-irq solution \n"); - - /* init of Serial 4 port */ - Ser4MCCR0 = 0; - Ser4SSCR0 = 0x0387; - Ser4SSCR1 = 0x18; - + /* clear out any left over data */ ssp_flush(); @@ -178,24 +191,25 @@ static int __init jornada_ssp_probe(struct platform_device *dev) return 0; }; -static int jornada_ssp_remove(struct platform_device *dev) +static int jornada_ssp_remove(struct platform_device *pdev) { - /* Note that this doesnt actually remove the driver, since theres nothing to remove - * It just makes sure everything is turned off */ GPSR = GPIO_GPIO25; ssp_exit(); return 0; }; -struct platform_driver jornadassp_driver = { - .probe = jornada_ssp_probe, - .remove = jornada_ssp_remove, - .driver = { - .name = "jornada_ssp", +static struct platform_driver jornadassp_driver = { + .driver = { + .name = "jornada_ssp", }, + .probe = jornada_ssp_probe, + .remove = __devexit_p(jornada_ssp_remove), }; static int __init jornada_ssp_init(void) { + printk(KERN_INFO "jornada720_ssp.c: Entering function\n"); return platform_driver_register(&jornadassp_driver); } + +module_init(jornada_ssp_init); diff --git a/arch/sh/boards/hp6xx/hp6xx_apm.c b/arch/sh/boards/hp6xx/hp6xx_apm.c index 177f4f028e0dd5..9ae221cc65439a 100644 --- a/arch/sh/boards/hp6xx/hp6xx_apm.c +++ b/arch/sh/boards/hp6xx/hp6xx_apm.c @@ -1,6 +1,7 @@ /* * bios-less APM driver for hp680 * + * Copyright 2008 (c) Kristoffer Ericson <kristoffer.ericson@gmail.com> * Copyright 2005 (c) Andriy Skulysh <askulysh@gmail.com> * Copyright 2008 (c) Kristoffer Ericson <kristoffer.ericson@gmail.com> * @@ -81,6 +82,8 @@ static irqreturn_t hp6x0_apm_interrupt(int irq, void *dev) return IRQ_HANDLED; } +extern void (*apm_get_power_status)(struct apm_power_info *); + static int __init hp6x0_apm_init(void) { int ret; diff --git a/arch/sh/boards/hp6xx/pm.c b/arch/sh/boards/hp6xx/pm.c index d22f6eac9ccabb..6a2112aeb7c041 100644 --- a/arch/sh/boards/hp6xx/pm.c +++ b/arch/sh/boards/hp6xx/pm.c @@ -10,14 +10,25 @@ #include <linux/suspend.h> #include <linux/errno.h> #include <linux/time.h> +#include <linux/apm-emulation.h> #include <asm/io.h> #include <asm/hd64461.h> #include <asm/hp6xx.h> #include <asm/cpu/dac.h> #include <asm/pm.h> -#define STBCR 0xffffff82 -#define STBCR2 0xffffff88 +#define STBCR 0xffffff82 /* STBCR (Standby control register) SH7709A */ +#define STBCR2 0xffffff88 /* STBCR2 (Standby control register 2) SH7709A */ +/* 1 = true, 0 = false + bit 0 - Clock supply to SCI1 (IRDA) halted + bit 1 - Clock supply to SCI2 (SCIF) halted + bit 2 - Clock supply to ADC halted and all registers initialized + bit 3 - Clock supply to DAC halted + bit 4 - Clock supply to DMAC halted + bit 5 - Clock supply to UBC is halted + bit 6 - Pins MD5 to MD0 are changed in standby mode + bit 7 - Reserved +*/ static int hp6x0_pm_enter(suspend_state_t state) { @@ -28,38 +39,48 @@ static int hp6x0_pm_enter(suspend_state_t state) #endif #ifdef CONFIG_HD64461_ENABLER + /* disable all CF interrupts */ outb(0, HD64461_PCC1CSCIER); - scr = inb(HD64461_PCC1SCR); scr |= HD64461_PCCSCR_VCC1; outb(scr, HD64461_PCC1SCR); + /* get standby status of all devices */ hd64461_stbcr = inw(HD64461_STBCR); + /* add standby mode to CF slot */ hd64461_stbcr |= HD64461_STBCR_SPC1ST; outw(hd64461_stbcr, HD64461_STBCR); #endif - ctrl_outb(0x1f, DACR); + /* chan 0/1 D/A conversion and DA 0/1 output are enabled */ + outb(0x1f, DACR); - stbcr = ctrl_inb(STBCR); - ctrl_outb(0x01, STBCR); + /* halt clocksupply to SCI */ + stbcr = inb(STBCR); + outb(0x01, STBCR); - stbcr2 = ctrl_inb(STBCR2); - ctrl_outb(0x7f , STBCR2); + /* state and drop all clocksupply */ + stbcr2 = inb(STBCR2); + outb(0x7f , STBCR2); + /* allow IO Ports D + C, disallow A + B */ outw(0xf07f, HD64461_SCPUCR); + /* Zzzzz */ pm_enter(); + /* wakeup, Lets restore the old values */ outw(0, HD64461_SCPUCR); - ctrl_outb(stbcr, STBCR); - ctrl_outb(stbcr2, STBCR2); + outb(stbcr, STBCR); + outb(stbcr2, STBCR2); #ifdef CONFIG_HD64461_ENABLER + /* get standby status of all devices */ hd64461_stbcr = inw(HD64461_STBCR); + /* remove standby mode for CF slot */ hd64461_stbcr &= ~HD64461_STBCR_SPC1ST; outw(hd64461_stbcr, HD64461_STBCR); - + /* turn on CF interrupt again */ outb(0x4c, HD64461_PCC1CSCIER); outb(0x00, HD64461_PCC1CSCR); #endif diff --git a/arch/sh/boards/hp6xx/setup.c b/arch/sh/boards/hp6xx/setup.c index 2f414ac3c69090..65a46fac744dca 100644 --- a/arch/sh/boards/hp6xx/setup.c +++ b/arch/sh/boards/hp6xx/setup.c @@ -21,7 +21,7 @@ #define SCPCR 0xa4000116 #define SCPDR 0xa4000136 -/* CF Slot */ +/* CF slot configured as storage */ static struct resource cf_ide_resources[] = { [0] = { .start = 0x15000000 + 0x1f0, @@ -51,9 +51,21 @@ static struct platform_device jornadakbd_device = { .id = -1, }; +static struct platform_device hp6xxled_device = { + .name = "hp6xx-led", + .id = -1, +}; + +static struct platform_device jornadats_device = { + .name = "jornada_ts", + .id = -1, +}; + static struct platform_device *hp6xx_devices[] __initdata = { &cf_ide_device, &jornadakbd_device, + &jornadats_device, + &hp6xxled_device, }; static void __init hp6xx_init_irq(void) @@ -73,23 +85,25 @@ static void __init hp6xx_setup(char **cmdline_p) u16 v; v = inw(HD64461_STBCR); - v |= HD64461_STBCR_SURTST | HD64461_STBCR_SIRST | - HD64461_STBCR_STM1ST | HD64461_STBCR_STM0ST | - HD64461_STBCR_SAFEST | HD64461_STBCR_SPC0ST | - HD64461_STBCR_SMIAST | HD64461_STBCR_SAFECKE_OST| + v |= HD64461_STBCR_SURTST | HD64461_STBCR_SIRST | + HD64461_STBCR_STM1ST | HD64461_STBCR_STM0ST | + HD64461_STBCR_SAFEST | HD64461_STBCR_SPC0ST | + HD64461_STBCR_SMIAST | HD64461_STBCR_SAFECKE_OST| HD64461_STBCR_SAFECKE_IST; #ifndef CONFIG_HD64461_ENABLER - v |= HD64461_STBCR_SPC1ST; + v |= HD6446x_STBCR_PCC1; #endif - outw(v, HD64461_STBCR); - v = inw(HD64461_GPADR); + ctrl_outw(v, HD64461_STBCR); + v = ctrl_inw(HD64461_GPADR); v |= HD64461_GPADR_SPEAKER | HD64461_GPADR_PCMCIA0; - outw(v, HD64461_GPADR); + ctrl_outw(v, HD64461_GPADR); - outw(HD64461_PCCGCR_VCC0 | HD64461_PCCSCR_VCC1, HD64461_PCC0GCR); + /* set voltage control pin to high level (PCC0SEL)*/ + ctrl_outw(HD64461_PCCGCR_VCC0 | HD64461_PCCSCR_VCC1, HD64461_PCC0GCR); #ifndef CONFIG_HD64461_ENABLER - outw(HD64461_PCCGCR_VCC0 | HD64461_PCCSCR_VCC1, HD64461_PCC1GCR); + /* set voltage control pin to high level (PCC1SEL)*/ + ctrl_outw(HD64461_PCCGCR_VCC0 | HD64461_PCCSCR_VCC1, HD64461_PCC1GCR); #endif sh_dac_output(0, DAC_SPEAKER_VOLUME); @@ -107,15 +121,31 @@ static void __init hp6xx_setup(char **cmdline_p) v &= ~SCPCR_TS_MASK; v |= SCPCR_TS_ENABLE; ctrl_outw(v, SCPCR); + } device_initcall(hp6xx_devices_setup); +static void __iomem *port_map(unsigned long port, unsigned int size) +{ + /* this is for all drivers actually accepting io_offset */ + if (0xf300<=port && port<=0xf31f) + port = port - 0xf000; + + /* non-port? then just return it */ + if (PXSEG(port)) + return (void __iomem *)(port); + + /* add base value and return it */ + return (void __iomem *)(0xba000000 + port); +} + static struct sh_machine_vector mv_hp6xx __initmv = { - .mv_name = "hp6xx", + .mv_name = "HP Jornada 6xx", .mv_setup = hp6xx_setup, /* IRQ's : CPU(64) + CCHIP(16) + FREE_TO_USE(6) */ .mv_nr_irqs = HD64461_IRQBASE + HD64461_IRQ_NUM + 6, .mv_irq_demux = hd64461_irq_demux, /* Enable IRQ0 -> IRQ3 in IRQ_MODE */ .mv_init_irq = hp6xx_init_irq, + .mv_ioport_map = port_map, }; diff --git a/arch/sh/cchips/hd6446x/Makefile b/arch/sh/cchips/hd6446x/Makefile index f7de4076e242de..ea4a9bdfe4ca66 100644 --- a/arch/sh/cchips/hd6446x/Makefile +++ b/arch/sh/cchips/hd6446x/Makefile @@ -1,4 +1,4 @@ obj-$(CONFIG_HD64461) += hd64461.o -obj-$(CONFIG_HD64465) += hd64465/ +obj-$(CONFIG_HD64465) += hd64465.o EXTRA_CFLAGS += -Werror diff --git a/arch/sh/cchips/hd6446x/hd64461.c b/arch/sh/cchips/hd6446x/hd64461.c index f1a4a0763c5991..488dccd58c0702 100644 --- a/arch/sh/cchips/hd6446x/hd64461.c +++ b/arch/sh/cchips/hd6446x/hd64461.c @@ -137,6 +137,8 @@ static struct irqaction irq0 = { int __init setup_hd64461(void) { int i; + unsigned char cscier; + if (!MACH_HD64461) return 0; @@ -159,11 +161,20 @@ int __init setup_hd64461(void) setup_irq(CONFIG_HD64461_IRQ, &irq0); #ifdef CONFIG_HD64461_ENABLER - printk(KERN_INFO "HD64461: enabling PCMCIA devices\n"); + printk(KERN_INFO "HD64461: enabling pcmcia slot 1 (storage)\n"); outb(0x4c, HD64461_PCC1CSCIER); outb(0x00, HD64461_PCC1CSCR); #endif +#ifdef CONFIG_HD64461_PCMCIA + printk(KERN_INFO "HD64461: enabling pcmcia slot 0 (io / storage)\n"); + + cscier = HD64461_PCCCSCIER_IREQE_FALLING | HD64461_PCCCSCIER_RE | + HD64461_PCCCSCIER_SCE | HD64461_PCCCSCIER_CDE; + + outb(cscier, HD64461_PCC0CSCIER); +#endif + return 0; } diff --git a/arch/sh/kernel/cpu/irq/intc.c b/arch/sh/kernel/cpu/irq/intc.c index da5dae787888fe..c71da6242547a7 100644 --- a/arch/sh/kernel/cpu/irq/intc.c +++ b/arch/sh/kernel/cpu/irq/intc.c @@ -223,12 +223,23 @@ static void intc_disable(unsigned int irq) unsigned long handle = (unsigned long) get_irq_chip_data(irq); unsigned long addr; unsigned int cpu; + unsigned int IRR0_var; + unsigned int IRR0 = 0xa4000004; for (cpu = 0; cpu < SMP_NR(d, _INTC_ADDR_D(handle)); cpu++) { addr = INTC_REG(d, _INTC_ADDR_D(handle), cpu); intc_disable_fns[_INTC_MODE(handle)](addr, handle,intc_reg_fns\ [_INTC_FN(handle)], irq); } + + #ifdef CONFIG_CPU_SUBTYPE_SH7709 + /* need to mask out IRQ0->IRQ5 interrupt */ + if ((irq < 37) && (irq > 31)) { + IRR0_var = ctrl_inb(IRR0); + IRR0_var &= ~(1 << (irq - 32)); + ctrl_outb(IRR0_var, IRR0); + } + #endif } #ifdef CONFIG_CPU_SH3 |