提交 15beb694 编写于 作者: J Joshua Kinard 提交者: Linus Torvalds

mips: ip32: add platform data hooks to use DS1685 driver

This modifies the IP32 (SGI O2) platform and reset code to utilize the new
rtc-ds1685 driver.  The old mc146818rtc.h header is removed and ip32_defconfig
is updated as well.
Signed-off-by: NJoshua Kinard <kumba@gentoo.org>
Acked-by: NRalf Baechle <ralf@linux-mips.org>
Cc: Alessandro Zummo <a.zummo@towertech.it>
Signed-off-by: NAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: NLinus Torvalds <torvalds@linux-foundation.org>
上级 9e522c0d
master alk-4.19.24 alk-4.19.30 alk-4.19.34 alk-4.19.36 alk-4.19.43 alk-4.19.48 alk-4.19.57 ck-4.19.67 ck-4.19.81 ck-4.19.91 github/fork/deepanshu1422/fix-typo-in-comment github/fork/haosdent/fix-typo linux-next v4.19.91 v4.19.90 v4.19.89 v4.19.88 v4.19.87 v4.19.86 v4.19.85 v4.19.84 v4.19.83 v4.19.82 v4.19.81 v4.19.80 v4.19.79 v4.19.78 v4.19.77 v4.19.76 v4.19.75 v4.19.74 v4.19.73 v4.19.72 v4.19.71 v4.19.70 v4.19.69 v4.19.68 v4.19.67 v4.19.66 v4.19.65 v4.19.64 v4.19.63 v4.19.62 v4.19.61 v4.19.60 v4.19.59 v4.19.58 v4.19.57 v4.19.56 v4.19.55 v4.19.54 v4.19.53 v4.19.52 v4.19.51 v4.19.50 v4.19.49 v4.19.48 v4.19.47 v4.19.46 v4.19.45 v4.19.44 v4.19.43 v4.19.42 v4.19.41 v4.19.40 v4.19.39 v4.19.38 v4.19.37 v4.19.36 v4.19.35 v4.19.34 v4.19.33 v4.19.32 v4.19.31 v4.19.30 v4.19.29 v4.19.28 v4.19.27 v4.19.26 v4.19.25 v4.19.24 v4.19.23 v4.19.22 v4.19.21 v4.19.20 v4.19.19 v4.19.18 v4.19.17 v4.19.16 v4.19.15 v4.19.14 v4.19.13 v4.19.12 v4.19.11 v4.19.10 v4.19.9 v4.19.8 v4.19.7 v4.19.6 v4.19.5 v4.19.4 v4.19.3 v4.19.2 v4.19.1 v4.19 v4.19-rc8 v4.19-rc7 v4.19-rc6 v4.19-rc5 v4.19-rc4 v4.19-rc3 v4.19-rc2 v4.19-rc1 ck-release-21 ck-release-20 ck-release-19.2 ck-release-19.1 ck-release-19 ck-release-18 ck-release-17.2 ck-release-17.1 ck-release-17 ck-release-16 ck-release-15.1 ck-release-15 ck-release-14 ck-release-13.2 ck-release-13 ck-release-12 ck-release-11 ck-release-10 ck-release-9 ck-release-7 alk-release-15 alk-release-14 alk-release-13.2 alk-release-13 alk-release-12 alk-release-11 alk-release-10 alk-release-9 alk-release-7
无相关合并请求
......@@ -105,7 +105,8 @@ CONFIG_RTC_CLASS=y
# CONFIG_RTC_HCTOSYS is not set
# CONFIG_RTC_INTF_SYSFS is not set
# CONFIG_RTC_INTF_PROC is not set
CONFIG_RTC_DRV_CMOS=y
CONFIG_RTC_DRV_DS1685_FAMILY=y
CONFIG_RTC_DRV_DS1685=y
CONFIG_EXT2_FS=y
CONFIG_EXT2_FS_XATTR=y
CONFIG_EXT2_FS_POSIX_ACL=y
......
/*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*
* Copyright (C) 1998, 2001, 03 by Ralf Baechle
* Copyright (C) 2000 Harald Koerfgen
*
* RTC routines for IP32 style attached Dallas chip.
*/
#ifndef __ASM_MACH_IP32_MC146818RTC_H
#define __ASM_MACH_IP32_MC146818RTC_H
#include <asm/ip32/mace.h>
#define RTC_PORT(x) (0x70 + (x))
static unsigned char CMOS_READ(unsigned long addr)
{
return mace->isa.rtc[addr << 8];
}
static inline void CMOS_WRITE(unsigned char data, unsigned long addr)
{
mace->isa.rtc[addr << 8] = data;
}
/*
* FIXME: Do it right. For now just assume that no one lives in 20th century
* and no O2 user in 22th century ;-)
*/
#define mc146818_decode_year(year) ((year) + 2000)
#define RTC_ALWAYS_BCD 0
#endif /* __ASM_MACH_IP32_MC146818RTC_H */
......@@ -9,10 +9,13 @@
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/serial_8250.h>
#include <linux/rtc/ds1685.h>
#include <asm/ip32/mace.h>
#include <asm/ip32/ip32_ints.h>
extern void ip32_prepare_poweroff(void);
#define MACEISA_SERIAL1_OFFS offsetof(struct sgi_mace, isa.serial1)
#define MACEISA_SERIAL2_OFFS offsetof(struct sgi_mace, isa.serial2)
......@@ -90,18 +93,47 @@ static __init int sgio2btns_devinit(void)
device_initcall(sgio2btns_devinit);
static struct resource sgio2_cmos_rsrc[] = {
#define MACE_RTC_RES_START (MACE_BASE + offsetof(struct sgi_mace, isa.rtc))
#define MACE_RTC_RES_END (MACE_RTC_RES_START + 32767)
static struct resource ip32_rtc_resources[] = {
{
.start = 0x70,
.end = 0x71,
.flags = IORESOURCE_IO
.start = MACEISA_RTC_IRQ,
.end = MACEISA_RTC_IRQ,
.flags = IORESOURCE_IRQ
}, {
.start = MACE_RTC_RES_START,
.end = MACE_RTC_RES_END,
.flags = IORESOURCE_MEM,
}
};
static __init int sgio2_cmos_devinit(void)
/* RTC registers on IP32 are each padded by 256 bytes (0x100). */
static struct ds1685_rtc_platform_data
ip32_rtc_platform_data[] = {
{
.regstep = 0x100,
.bcd_mode = true,
.no_irq = false,
.uie_unsupported = false,
.alloc_io_resources = true,
.plat_prepare_poweroff = ip32_prepare_poweroff,
},
};
struct platform_device ip32_rtc_device = {
.name = "rtc-ds1685",
.id = -1,
.dev = {
.platform_data = ip32_rtc_platform_data,
},
.num_resources = ARRAY_SIZE(ip32_rtc_resources),
.resource = ip32_rtc_resources,
};
+static int __init sgio2_rtc_devinit(void)
{
return IS_ERR(platform_device_register_simple("rtc_cmos", -1,
sgio2_cmos_rsrc, 1));
return platform_device_register(&ip32_rtc_device);
}
device_initcall(sgio2_cmos_devinit);
......
......@@ -11,10 +11,11 @@
#include <linux/compiler.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/sched.h>
#include <linux/notifier.h>
#include <linux/delay.h>
#include <linux/ds17287rtc.h>
#include <linux/rtc/ds1685.h>
#include <linux/interrupt.h>
#include <linux/pm.h>
......@@ -33,53 +34,40 @@
#define POWERDOWN_FREQ (HZ / 4)
#define PANIC_FREQ (HZ / 8)
static struct timer_list power_timer, blink_timer, debounce_timer;
static int has_panicked, shuting_down;
extern struct platform_device ip32_rtc_device;
static void ip32_machine_restart(char *command) __noreturn;
static void ip32_machine_halt(void) __noreturn;
static void ip32_machine_power_off(void) __noreturn;
static struct timer_list power_timer, blink_timer;
static int has_panicked, shutting_down;
static void ip32_machine_restart(char *cmd)
static __noreturn void ip32_poweroff(void *data)
{
crime->control = CRIME_CONTROL_HARD_RESET;
while (1);
}
void (*poweroff_func)(struct platform_device *) =
symbol_get(ds1685_rtc_poweroff);
#ifdef CONFIG_MODULES
/* If the first __symbol_get failed, our module wasn't loaded. */
if (!poweroff_func) {
request_module("rtc-ds1685");
poweroff_func = symbol_get(ds1685_rtc_poweroff);
}
#endif
static inline void ip32_machine_halt(void)
{
ip32_machine_power_off();
}
if (!poweroff_func)
pr_emerg("RTC not available for power-off. Spinning forever ...\n");
else {
(*poweroff_func)((struct platform_device *)data);
symbol_put(ds1685_rtc_poweroff);
}
static void ip32_machine_power_off(void)
{
unsigned char reg_a, xctrl_a, xctrl_b;
disable_irq(MACEISA_RTC_IRQ);
reg_a = CMOS_READ(RTC_REG_A);
/* setup for kickstart & wake-up (DS12287 Ref. Man. p. 19) */
reg_a &= ~DS_REGA_DV2;
reg_a |= DS_REGA_DV1;
CMOS_WRITE(reg_a | DS_REGA_DV0, RTC_REG_A);
wbflush();
xctrl_b = CMOS_READ(DS_B1_XCTRL4B)
| DS_XCTRL4B_ABE | DS_XCTRL4B_KFE;
CMOS_WRITE(xctrl_b, DS_B1_XCTRL4B);
xctrl_a = CMOS_READ(DS_B1_XCTRL4A) & ~DS_XCTRL4A_IFS;
CMOS_WRITE(xctrl_a, DS_B1_XCTRL4A);
wbflush();
/* adios amigos... */
CMOS_WRITE(xctrl_a | DS_XCTRL4A_PAB, DS_B1_XCTRL4A);
CMOS_WRITE(reg_a, RTC_REG_A);
wbflush();
while (1);
unreachable();
}
static void power_timeout(unsigned long data)
static void ip32_machine_restart(char *cmd) __noreturn;
static void ip32_machine_restart(char *cmd)
{
ip32_machine_power_off();
msleep(20);
crime->control = CRIME_CONTROL_HARD_RESET;
unreachable();
}
static void blink_timeout(unsigned long data)
......@@ -89,44 +77,27 @@ static void blink_timeout(unsigned long data)
mod_timer(&blink_timer, jiffies + data);
}
static void debounce(unsigned long data)
static void ip32_machine_halt(void)
{
unsigned char reg_a, reg_c, xctrl_a;
reg_c = CMOS_READ(RTC_INTR_FLAGS);
reg_a = CMOS_READ(RTC_REG_A);
CMOS_WRITE(reg_a | DS_REGA_DV0, RTC_REG_A);
wbflush();
xctrl_a = CMOS_READ(DS_B1_XCTRL4A);
if ((xctrl_a & DS_XCTRL4A_IFS) || (reg_c & RTC_IRQF )) {
/* Interrupt still being sent. */
debounce_timer.expires = jiffies + 50;
add_timer(&debounce_timer);
/* clear interrupt source */
CMOS_WRITE(xctrl_a & ~DS_XCTRL4A_IFS, DS_B1_XCTRL4A);
CMOS_WRITE(reg_a & ~DS_REGA_DV0, RTC_REG_A);
return;
}
CMOS_WRITE(reg_a & ~DS_REGA_DV0, RTC_REG_A);
if (has_panicked)
ip32_machine_restart(NULL);
ip32_poweroff(&ip32_rtc_device);
}
enable_irq(MACEISA_RTC_IRQ);
static void power_timeout(unsigned long data)
{
ip32_poweroff(&ip32_rtc_device);
}
static inline void ip32_power_button(void)
void ip32_prepare_poweroff(void)
{
if (has_panicked)
return;
if (shuting_down || kill_cad_pid(SIGINT, 1)) {
if (shutting_down || kill_cad_pid(SIGINT, 1)) {
/* No init process or button pressed twice. */
ip32_machine_power_off();
ip32_poweroff(&ip32_rtc_device);
}
shuting_down = 1;
shutting_down = 1;
blink_timer.data = POWERDOWN_FREQ;
blink_timeout(POWERDOWN_FREQ);
......@@ -136,27 +107,6 @@ static inline void ip32_power_button(void)
add_timer(&power_timer);
}
static irqreturn_t ip32_rtc_int(int irq, void *dev_id)
{
unsigned char reg_c;
reg_c = CMOS_READ(RTC_INTR_FLAGS);
if (!(reg_c & RTC_IRQF)) {
printk(KERN_WARNING
"%s: RTC IRQ without RTC_IRQF\n", __func__);
}
/* Wait until interrupt goes away */
disable_irq_nosync(MACEISA_RTC_IRQ);
init_timer(&debounce_timer);
debounce_timer.function = debounce;
debounce_timer.expires = jiffies + 50;
add_timer(&debounce_timer);
printk(KERN_DEBUG "Power button pressed\n");
ip32_power_button();
return IRQ_HANDLED;
}
static int panic_event(struct notifier_block *this, unsigned long event,
void *ptr)
{
......@@ -190,15 +140,12 @@ static __init int ip32_reboot_setup(void)
_machine_restart = ip32_machine_restart;
_machine_halt = ip32_machine_halt;
pm_power_off = ip32_machine_power_off;
pm_power_off = ip32_machine_halt;
init_timer(&blink_timer);
blink_timer.function = blink_timeout;
atomic_notifier_chain_register(&panic_notifier_list, &panic_block);
if (request_irq(MACEISA_RTC_IRQ, ip32_rtc_int, 0, "rtc", NULL))
panic("Can't allocate MACEISA RTC IRQ");
return 0;
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册
反馈
建议
客服 返回
顶部