diff options
31 files changed, 869 insertions, 286 deletions
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index cd5fbf6f0784..b905744d7915 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig | |||
@@ -52,6 +52,7 @@ config BCM47XX | |||
52 | select SSB | 52 | select SSB |
53 | select SSB_DRIVER_MIPS | 53 | select SSB_DRIVER_MIPS |
54 | select SSB_DRIVER_EXTIF | 54 | select SSB_DRIVER_EXTIF |
55 | select SSB_EMBEDDED | ||
55 | select SSB_PCICORE_HOSTMODE if PCI | 56 | select SSB_PCICORE_HOSTMODE if PCI |
56 | select GENERIC_GPIO | 57 | select GENERIC_GPIO |
57 | select SYS_HAS_EARLY_PRINTK | 58 | select SYS_HAS_EARLY_PRINTK |
diff --git a/arch/mips/bcm47xx/gpio.c b/arch/mips/bcm47xx/gpio.c index f5a53acf995a..9b798800258c 100644 --- a/arch/mips/bcm47xx/gpio.c +++ b/arch/mips/bcm47xx/gpio.c | |||
@@ -12,68 +12,51 @@ | |||
12 | #include <asm/mach-bcm47xx/bcm47xx.h> | 12 | #include <asm/mach-bcm47xx/bcm47xx.h> |
13 | #include <asm/mach-bcm47xx/gpio.h> | 13 | #include <asm/mach-bcm47xx/gpio.h> |
14 | 14 | ||
15 | int bcm47xx_gpio_to_irq(unsigned gpio) | 15 | #if (BCM47XX_CHIPCO_GPIO_LINES > BCM47XX_EXTIF_GPIO_LINES) |
16 | static DECLARE_BITMAP(gpio_in_use, BCM47XX_CHIPCO_GPIO_LINES); | ||
17 | #else | ||
18 | static DECLARE_BITMAP(gpio_in_use, BCM47XX_EXTIF_GPIO_LINES); | ||
19 | #endif | ||
20 | |||
21 | int gpio_request(unsigned gpio, const char *tag) | ||
16 | { | 22 | { |
17 | if (ssb_bcm47xx.chipco.dev) | 23 | if (ssb_chipco_available(&ssb_bcm47xx.chipco) && |
18 | return ssb_mips_irq(ssb_bcm47xx.chipco.dev) + 2; | 24 | ((unsigned)gpio >= BCM47XX_CHIPCO_GPIO_LINES)) |
19 | else if (ssb_bcm47xx.extif.dev) | ||
20 | return ssb_mips_irq(ssb_bcm47xx.extif.dev) + 2; | ||
21 | else | ||
22 | return -EINVAL; | 25 | return -EINVAL; |
23 | } | ||
24 | EXPORT_SYMBOL_GPL(bcm47xx_gpio_to_irq); | ||
25 | 26 | ||
26 | int bcm47xx_gpio_get_value(unsigned gpio) | 27 | if (ssb_extif_available(&ssb_bcm47xx.extif) && |
27 | { | 28 | ((unsigned)gpio >= BCM47XX_EXTIF_GPIO_LINES)) |
28 | if (ssb_bcm47xx.chipco.dev) | 29 | return -EINVAL; |
29 | return ssb_chipco_gpio_in(&ssb_bcm47xx.chipco, 1 << gpio); | ||
30 | else if (ssb_bcm47xx.extif.dev) | ||
31 | return ssb_extif_gpio_in(&ssb_bcm47xx.extif, 1 << gpio); | ||
32 | else | ||
33 | return 0; | ||
34 | } | ||
35 | EXPORT_SYMBOL_GPL(bcm47xx_gpio_get_value); | ||
36 | 30 | ||
37 | void bcm47xx_gpio_set_value(unsigned gpio, int value) | 31 | if (test_and_set_bit(gpio, gpio_in_use)) |
38 | { | 32 | return -EBUSY; |
39 | if (ssb_bcm47xx.chipco.dev) | ||
40 | ssb_chipco_gpio_out(&ssb_bcm47xx.chipco, | ||
41 | 1 << gpio, | ||
42 | value ? 1 << gpio : 0); | ||
43 | else if (ssb_bcm47xx.extif.dev) | ||
44 | ssb_extif_gpio_out(&ssb_bcm47xx.extif, | ||
45 | 1 << gpio, | ||
46 | value ? 1 << gpio : 0); | ||
47 | } | ||
48 | EXPORT_SYMBOL_GPL(bcm47xx_gpio_set_value); | ||
49 | 33 | ||
50 | int bcm47xx_gpio_direction_input(unsigned gpio) | ||
51 | { | ||
52 | if (ssb_bcm47xx.chipco.dev && (gpio < BCM47XX_CHIPCO_GPIO_LINES)) | ||
53 | ssb_chipco_gpio_outen(&ssb_bcm47xx.chipco, | ||
54 | 1 << gpio, 0); | ||
55 | else if (ssb_bcm47xx.extif.dev && (gpio < BCM47XX_EXTIF_GPIO_LINES)) | ||
56 | ssb_extif_gpio_outen(&ssb_bcm47xx.extif, | ||
57 | 1 << gpio, 0); | ||
58 | else | ||
59 | return -EINVAL; | ||
60 | return 0; | 34 | return 0; |
61 | } | 35 | } |
62 | EXPORT_SYMBOL_GPL(bcm47xx_gpio_direction_input); | 36 | EXPORT_SYMBOL(gpio_request); |
63 | 37 | ||
64 | int bcm47xx_gpio_direction_output(unsigned gpio, int value) | 38 | void gpio_free(unsigned gpio) |
65 | { | 39 | { |
66 | bcm47xx_gpio_set_value(gpio, value); | 40 | if (ssb_chipco_available(&ssb_bcm47xx.chipco) && |
41 | ((unsigned)gpio >= BCM47XX_CHIPCO_GPIO_LINES)) | ||
42 | return; | ||
43 | |||
44 | if (ssb_extif_available(&ssb_bcm47xx.extif) && | ||
45 | ((unsigned)gpio >= BCM47XX_EXTIF_GPIO_LINES)) | ||
46 | return; | ||
47 | |||
48 | clear_bit(gpio, gpio_in_use); | ||
49 | } | ||
50 | EXPORT_SYMBOL(gpio_free); | ||
67 | 51 | ||
68 | if (ssb_bcm47xx.chipco.dev && (gpio < BCM47XX_CHIPCO_GPIO_LINES)) | 52 | int gpio_to_irq(unsigned gpio) |
69 | ssb_chipco_gpio_outen(&ssb_bcm47xx.chipco, | 53 | { |
70 | 1 << gpio, 1 << gpio); | 54 | if (ssb_chipco_available(&ssb_bcm47xx.chipco)) |
71 | else if (ssb_bcm47xx.extif.dev && (gpio < BCM47XX_EXTIF_GPIO_LINES)) | 55 | return ssb_mips_irq(ssb_bcm47xx.chipco.dev) + 2; |
72 | ssb_extif_gpio_outen(&ssb_bcm47xx.extif, | 56 | else if (ssb_extif_available(&ssb_bcm47xx.extif)) |
73 | 1 << gpio, 1 << gpio); | 57 | return ssb_mips_irq(ssb_bcm47xx.extif.dev) + 2; |
74 | else | 58 | else |
75 | return -EINVAL; | 59 | return -EINVAL; |
76 | return 0; | ||
77 | } | 60 | } |
78 | EXPORT_SYMBOL_GPL(bcm47xx_gpio_direction_output); | 61 | EXPORT_SYMBOL_GPL(gpio_to_irq); |
79 | 62 | ||
diff --git a/arch/mips/bcm47xx/setup.c b/arch/mips/bcm47xx/setup.c index 8d36f186890e..2f580fa160c9 100644 --- a/arch/mips/bcm47xx/setup.c +++ b/arch/mips/bcm47xx/setup.c | |||
@@ -27,6 +27,7 @@ | |||
27 | 27 | ||
28 | #include <linux/types.h> | 28 | #include <linux/types.h> |
29 | #include <linux/ssb/ssb.h> | 29 | #include <linux/ssb/ssb.h> |
30 | #include <linux/ssb/ssb_embedded.h> | ||
30 | #include <asm/bootinfo.h> | 31 | #include <asm/bootinfo.h> |
31 | #include <asm/reboot.h> | 32 | #include <asm/reboot.h> |
32 | #include <asm/time.h> | 33 | #include <asm/time.h> |
@@ -41,7 +42,7 @@ static void bcm47xx_machine_restart(char *command) | |||
41 | printk(KERN_ALERT "Please stand by while rebooting the system...\n"); | 42 | printk(KERN_ALERT "Please stand by while rebooting the system...\n"); |
42 | local_irq_disable(); | 43 | local_irq_disable(); |
43 | /* Set the watchdog timer to reset immediately */ | 44 | /* Set the watchdog timer to reset immediately */ |
44 | ssb_chipco_watchdog_timer_set(&ssb_bcm47xx.chipco, 1); | 45 | ssb_watchdog_timer_set(&ssb_bcm47xx, 1); |
45 | while (1) | 46 | while (1) |
46 | cpu_relax(); | 47 | cpu_relax(); |
47 | } | 48 | } |
@@ -50,7 +51,7 @@ static void bcm47xx_machine_halt(void) | |||
50 | { | 51 | { |
51 | /* Disable interrupts and watchdog and spin forever */ | 52 | /* Disable interrupts and watchdog and spin forever */ |
52 | local_irq_disable(); | 53 | local_irq_disable(); |
53 | ssb_chipco_watchdog_timer_set(&ssb_bcm47xx.chipco, 0); | 54 | ssb_watchdog_timer_set(&ssb_bcm47xx, 0); |
54 | while (1) | 55 | while (1) |
55 | cpu_relax(); | 56 | cpu_relax(); |
56 | } | 57 | } |
diff --git a/arch/mips/bcm47xx/wgt634u.c b/arch/mips/bcm47xx/wgt634u.c index d1d90c9ef2fa..ef00e7f58c24 100644 --- a/arch/mips/bcm47xx/wgt634u.c +++ b/arch/mips/bcm47xx/wgt634u.c | |||
@@ -11,6 +11,9 @@ | |||
11 | #include <linux/leds.h> | 11 | #include <linux/leds.h> |
12 | #include <linux/mtd/physmap.h> | 12 | #include <linux/mtd/physmap.h> |
13 | #include <linux/ssb/ssb.h> | 13 | #include <linux/ssb/ssb.h> |
14 | #include <linux/interrupt.h> | ||
15 | #include <linux/reboot.h> | ||
16 | #include <linux/gpio.h> | ||
14 | #include <asm/mach-bcm47xx/bcm47xx.h> | 17 | #include <asm/mach-bcm47xx/bcm47xx.h> |
15 | 18 | ||
16 | /* GPIO definitions for the WGT634U */ | 19 | /* GPIO definitions for the WGT634U */ |
@@ -99,6 +102,30 @@ static struct platform_device *wgt634u_devices[] __initdata = { | |||
99 | &wgt634u_gpio_leds, | 102 | &wgt634u_gpio_leds, |
100 | }; | 103 | }; |
101 | 104 | ||
105 | static irqreturn_t gpio_interrupt(int irq, void *ignored) | ||
106 | { | ||
107 | int state; | ||
108 | |||
109 | /* Interrupts are shared, check if the current one is | ||
110 | a GPIO interrupt. */ | ||
111 | if (!ssb_chipco_irq_status(&ssb_bcm47xx.chipco, | ||
112 | SSB_CHIPCO_IRQ_GPIO)) | ||
113 | return IRQ_NONE; | ||
114 | |||
115 | state = gpio_get_value(WGT634U_GPIO_RESET); | ||
116 | |||
117 | /* Interrupt are level triggered, revert the interrupt polarity | ||
118 | to clear the interrupt. */ | ||
119 | gpio_polarity(WGT634U_GPIO_RESET, state); | ||
120 | |||
121 | if (!state) { | ||
122 | printk(KERN_INFO "Reset button pressed"); | ||
123 | ctrl_alt_del(); | ||
124 | } | ||
125 | |||
126 | return IRQ_HANDLED; | ||
127 | } | ||
128 | |||
102 | static int __init wgt634u_init(void) | 129 | static int __init wgt634u_init(void) |
103 | { | 130 | { |
104 | /* There is no easy way to detect that we are running on a WGT634U | 131 | /* There is no easy way to detect that we are running on a WGT634U |
@@ -112,6 +139,19 @@ static int __init wgt634u_init(void) | |||
112 | ((et0mac[1] == 0x09 && et0mac[2] == 0x5b) || | 139 | ((et0mac[1] == 0x09 && et0mac[2] == 0x5b) || |
113 | (et0mac[1] == 0x0f && et0mac[2] == 0xb5))) { | 140 | (et0mac[1] == 0x0f && et0mac[2] == 0xb5))) { |
114 | struct ssb_mipscore *mcore = &ssb_bcm47xx.mipscore; | 141 | struct ssb_mipscore *mcore = &ssb_bcm47xx.mipscore; |
142 | |||
143 | printk(KERN_INFO "WGT634U machine detected.\n"); | ||
144 | |||
145 | if (!request_irq(gpio_to_irq(WGT634U_GPIO_RESET), | ||
146 | gpio_interrupt, IRQF_SHARED, | ||
147 | "WGT634U GPIO", &ssb_bcm47xx.chipco)) { | ||
148 | gpio_direction_input(WGT634U_GPIO_RESET); | ||
149 | gpio_intmask(WGT634U_GPIO_RESET, 1); | ||
150 | ssb_chipco_irq_mask(&ssb_bcm47xx.chipco, | ||
151 | SSB_CHIPCO_IRQ_GPIO, | ||
152 | SSB_CHIPCO_IRQ_GPIO); | ||
153 | } | ||
154 | |||
115 | wgt634u_flash_data.width = mcore->flash_buswidth; | 155 | wgt634u_flash_data.width = mcore->flash_buswidth; |
116 | wgt634u_flash_resource.start = mcore->flash_window; | 156 | wgt634u_flash_resource.start = mcore->flash_window; |
117 | wgt634u_flash_resource.end = mcore->flash_window | 157 | wgt634u_flash_resource.end = mcore->flash_window |
diff --git a/arch/mips/emma2rh/common/irq.c b/arch/mips/emma2rh/common/irq.c index d95604773667..91cbd959ab67 100644 --- a/arch/mips/emma2rh/common/irq.c +++ b/arch/mips/emma2rh/common/irq.c | |||
@@ -29,7 +29,6 @@ | |||
29 | 29 | ||
30 | #include <asm/system.h> | 30 | #include <asm/system.h> |
31 | #include <asm/mipsregs.h> | 31 | #include <asm/mipsregs.h> |
32 | #include <asm/debug.h> | ||
33 | #include <asm/addrspace.h> | 32 | #include <asm/addrspace.h> |
34 | #include <asm/bootinfo.h> | 33 | #include <asm/bootinfo.h> |
35 | 34 | ||
diff --git a/arch/mips/emma2rh/common/prom.c b/arch/mips/emma2rh/common/prom.c index 5e92b3a9c5b8..e14a2e3d8842 100644 --- a/arch/mips/emma2rh/common/prom.c +++ b/arch/mips/emma2rh/common/prom.c | |||
@@ -30,7 +30,6 @@ | |||
30 | #include <asm/addrspace.h> | 30 | #include <asm/addrspace.h> |
31 | #include <asm/bootinfo.h> | 31 | #include <asm/bootinfo.h> |
32 | #include <asm/emma2rh/emma2rh.h> | 32 | #include <asm/emma2rh/emma2rh.h> |
33 | #include <asm/debug.h> | ||
34 | 33 | ||
35 | const char *get_system_type(void) | 34 | const char *get_system_type(void) |
36 | { | 35 | { |
diff --git a/arch/mips/emma2rh/markeins/platform.c b/arch/mips/emma2rh/markeins/platform.c index d70627de7cfe..fb9cda253ab0 100644 --- a/arch/mips/emma2rh/markeins/platform.c +++ b/arch/mips/emma2rh/markeins/platform.c | |||
@@ -35,7 +35,6 @@ | |||
35 | #include <asm/irq.h> | 35 | #include <asm/irq.h> |
36 | #include <asm/reboot.h> | 36 | #include <asm/reboot.h> |
37 | #include <asm/traps.h> | 37 | #include <asm/traps.h> |
38 | #include <asm/debug.h> | ||
39 | 38 | ||
40 | #include <asm/emma2rh/emma2rh.h> | 39 | #include <asm/emma2rh/emma2rh.h> |
41 | 40 | ||
diff --git a/include/asm-mips/cevt-r4k.h b/arch/mips/include/asm/cevt-r4k.h index fa4328f9124f..fa4328f9124f 100644 --- a/include/asm-mips/cevt-r4k.h +++ b/arch/mips/include/asm/cevt-r4k.h | |||
diff --git a/arch/mips/include/asm/mach-bcm47xx/gpio.h b/arch/mips/include/asm/mach-bcm47xx/gpio.h index cfc8f4d618ce..d8ff4cd89ab5 100644 --- a/arch/mips/include/asm/mach-bcm47xx/gpio.h +++ b/arch/mips/include/asm/mach-bcm47xx/gpio.h | |||
@@ -9,47 +9,46 @@ | |||
9 | #ifndef __BCM47XX_GPIO_H | 9 | #ifndef __BCM47XX_GPIO_H |
10 | #define __BCM47XX_GPIO_H | 10 | #define __BCM47XX_GPIO_H |
11 | 11 | ||
12 | #include <linux/ssb/ssb_embedded.h> | ||
13 | #include <asm/mach-bcm47xx/bcm47xx.h> | ||
14 | |||
12 | #define BCM47XX_EXTIF_GPIO_LINES 5 | 15 | #define BCM47XX_EXTIF_GPIO_LINES 5 |
13 | #define BCM47XX_CHIPCO_GPIO_LINES 16 | 16 | #define BCM47XX_CHIPCO_GPIO_LINES 16 |
14 | 17 | ||
15 | extern int bcm47xx_gpio_to_irq(unsigned gpio); | 18 | extern int gpio_request(unsigned gpio, const char *label); |
16 | extern int bcm47xx_gpio_get_value(unsigned gpio); | 19 | extern void gpio_free(unsigned gpio); |
17 | extern void bcm47xx_gpio_set_value(unsigned gpio, int value); | 20 | extern int gpio_to_irq(unsigned gpio); |
18 | extern int bcm47xx_gpio_direction_input(unsigned gpio); | ||
19 | extern int bcm47xx_gpio_direction_output(unsigned gpio, int value); | ||
20 | |||
21 | static inline int gpio_request(unsigned gpio, const char *label) | ||
22 | { | ||
23 | return 0; | ||
24 | } | ||
25 | 21 | ||
26 | static inline void gpio_free(unsigned gpio) | 22 | static inline int gpio_get_value(unsigned gpio) |
27 | { | 23 | { |
24 | return ssb_gpio_in(&ssb_bcm47xx, 1 << gpio); | ||
28 | } | 25 | } |
29 | 26 | ||
30 | static inline int gpio_to_irq(unsigned gpio) | 27 | static inline void gpio_set_value(unsigned gpio, int value) |
31 | { | 28 | { |
32 | return bcm47xx_gpio_to_irq(gpio); | 29 | ssb_gpio_out(&ssb_bcm47xx, 1 << gpio, value ? 1 << gpio : 0); |
33 | } | 30 | } |
34 | 31 | ||
35 | static inline int gpio_get_value(unsigned gpio) | 32 | static inline int gpio_direction_input(unsigned gpio) |
36 | { | 33 | { |
37 | return bcm47xx_gpio_get_value(gpio); | 34 | return ssb_gpio_outen(&ssb_bcm47xx, 1 << gpio, 0); |
38 | } | 35 | } |
39 | 36 | ||
40 | static inline void gpio_set_value(unsigned gpio, int value) | 37 | static inline int gpio_direction_output(unsigned gpio, int value) |
41 | { | 38 | { |
42 | bcm47xx_gpio_set_value(gpio, value); | 39 | return ssb_gpio_outen(&ssb_bcm47xx, 1 << gpio, 1 << gpio); |
43 | } | 40 | } |
44 | 41 | ||
45 | static inline int gpio_direction_input(unsigned gpio) | 42 | static int gpio_intmask(unsigned gpio, int value) |
46 | { | 43 | { |
47 | return bcm47xx_gpio_direction_input(gpio); | 44 | return ssb_gpio_intmask(&ssb_bcm47xx, 1 << gpio, |
45 | value ? 1 << gpio : 0); | ||
48 | } | 46 | } |
49 | 47 | ||
50 | static inline int gpio_direction_output(unsigned gpio, int value) | 48 | static int gpio_polarity(unsigned gpio, int value) |
51 | { | 49 | { |
52 | return bcm47xx_gpio_direction_output(gpio, value); | 50 | return ssb_gpio_polarity(&ssb_bcm47xx, 1 << gpio, |
51 | value ? 1 << gpio : 0); | ||
53 | } | 52 | } |
54 | 53 | ||
55 | 54 | ||
diff --git a/arch/mips/include/asm/mach-bcm47xx/war.h b/arch/mips/include/asm/mach-bcm47xx/war.h index 4a2b7986b582..87cd4651dda3 100644 --- a/arch/mips/include/asm/mach-bcm47xx/war.h +++ b/arch/mips/include/asm/mach-bcm47xx/war.h | |||
@@ -5,8 +5,8 @@ | |||
5 | * | 5 | * |
6 | * Copyright (C) 2002, 2004, 2007 by Ralf Baechle <ralf@linux-mips.org> | 6 | * Copyright (C) 2002, 2004, 2007 by Ralf Baechle <ralf@linux-mips.org> |
7 | */ | 7 | */ |
8 | #ifndef __ASM_MIPS_MACH_BCM947XX_WAR_H | 8 | #ifndef __ASM_MIPS_MACH_BCM47XX_WAR_H |
9 | #define __ASM_MIPS_MACH_BCM947XX_WAR_H | 9 | #define __ASM_MIPS_MACH_BCM47XX_WAR_H |
10 | 10 | ||
11 | #define R4600_V1_INDEX_ICACHEOP_WAR 0 | 11 | #define R4600_V1_INDEX_ICACHEOP_WAR 0 |
12 | #define R4600_V1_HIT_CACHEOP_WAR 0 | 12 | #define R4600_V1_HIT_CACHEOP_WAR 0 |
@@ -22,4 +22,4 @@ | |||
22 | #define R10000_LLSC_WAR 0 | 22 | #define R10000_LLSC_WAR 0 |
23 | #define MIPS34K_MISSED_ITLB_WAR 0 | 23 | #define MIPS34K_MISSED_ITLB_WAR 0 |
24 | 24 | ||
25 | #endif /* __ASM_MIPS_MACH_BCM947XX_WAR_H */ | 25 | #endif /* __ASM_MIPS_MACH_BCM47XX_WAR_H */ |
diff --git a/arch/mips/include/asm/mach-ip22/ds1286.h b/arch/mips/include/asm/mach-ip22/ds1286.h deleted file mode 100644 index f19f1eafbc71..000000000000 --- a/arch/mips/include/asm/mach-ip22/ds1286.h +++ /dev/null | |||
@@ -1,18 +0,0 @@ | |||
1 | /* | ||
2 | * This file is subject to the terms and conditions of the GNU General Public | ||
3 | * License. See the file "COPYING" in the main directory of this archive | ||
4 | * for more details. | ||
5 | * | ||
6 | * Copyright (C) 1998, 2001, 03 by Ralf Baechle | ||
7 | * | ||
8 | * RTC routines for PC style attached Dallas chip. | ||
9 | */ | ||
10 | #ifndef __ASM_MACH_IP22_DS1286_H | ||
11 | #define __ASM_MACH_IP22_DS1286_H | ||
12 | |||
13 | #include <asm/sgi/hpc3.h> | ||
14 | |||
15 | #define rtc_read(reg) (hpc3c0->rtcregs[(reg)] & 0xff) | ||
16 | #define rtc_write(data, reg) do { hpc3c0->rtcregs[(reg)] = (data); } while(0) | ||
17 | |||
18 | #endif /* __ASM_MACH_IP22_DS1286_H */ | ||
diff --git a/arch/mips/include/asm/mach-ip28/ds1286.h b/arch/mips/include/asm/mach-ip28/ds1286.h deleted file mode 100644 index 471bb9a33e0f..000000000000 --- a/arch/mips/include/asm/mach-ip28/ds1286.h +++ /dev/null | |||
@@ -1,4 +0,0 @@ | |||
1 | #ifndef __ASM_MACH_IP28_DS1286_H | ||
2 | #define __ASM_MACH_IP28_DS1286_H | ||
3 | #include <asm/mach-ip22/ds1286.h> | ||
4 | #endif /* __ASM_MACH_IP28_DS1286_H */ | ||
diff --git a/arch/mips/include/asm/spinlock.h b/arch/mips/include/asm/spinlock.h index 5d98a3cb85b7..1a1f320c30d8 100644 --- a/arch/mips/include/asm/spinlock.h +++ b/arch/mips/include/asm/spinlock.h | |||
@@ -147,7 +147,7 @@ static inline void __raw_spin_unlock(raw_spinlock_t *lock) | |||
147 | " ori %[ticket], %[ticket], 0x2000 \n" | 147 | " ori %[ticket], %[ticket], 0x2000 \n" |
148 | " xori %[ticket], %[ticket], 0x2000 \n" | 148 | " xori %[ticket], %[ticket], 0x2000 \n" |
149 | " sc %[ticket], %[ticket_ptr] \n" | 149 | " sc %[ticket], %[ticket_ptr] \n" |
150 | " beqzl %[ticket], 2f \n" | 150 | " beqzl %[ticket], 1b \n" |
151 | : [ticket_ptr] "+m" (lock->lock), | 151 | : [ticket_ptr] "+m" (lock->lock), |
152 | [ticket] "=&r" (tmp)); | 152 | [ticket] "=&r" (tmp)); |
153 | } else { | 153 | } else { |
diff --git a/arch/mips/kernel/proc.c b/arch/mips/kernel/proc.c index 75bb1300dd7a..26760cad8b69 100644 --- a/arch/mips/kernel/proc.c +++ b/arch/mips/kernel/proc.c | |||
@@ -39,7 +39,7 @@ static int show_cpuinfo(struct seq_file *m, void *v) | |||
39 | seq_printf(m, "processor\t\t: %ld\n", n); | 39 | seq_printf(m, "processor\t\t: %ld\n", n); |
40 | sprintf(fmt, "cpu model\t\t: %%s V%%d.%%d%s\n", | 40 | sprintf(fmt, "cpu model\t\t: %%s V%%d.%%d%s\n", |
41 | cpu_data[n].options & MIPS_CPU_FPU ? " FPU V%d.%d" : ""); | 41 | cpu_data[n].options & MIPS_CPU_FPU ? " FPU V%d.%d" : ""); |
42 | seq_printf(m, fmt, __cpu_name[smp_processor_id()], | 42 | seq_printf(m, fmt, __cpu_name[n], |
43 | (version >> 4) & 0x0f, version & 0x0f, | 43 | (version >> 4) & 0x0f, version & 0x0f, |
44 | (fp_vers >> 4) & 0x0f, fp_vers & 0x0f); | 44 | (fp_vers >> 4) & 0x0f, fp_vers & 0x0f); |
45 | seq_printf(m, "BogoMIPS\t\t: %lu.%02lu\n", | 45 | seq_printf(m, "BogoMIPS\t\t: %lu.%02lu\n", |
diff --git a/arch/mips/kernel/vmlinux.lds.S b/arch/mips/kernel/vmlinux.lds.S index afb119f35682..58738c8d754f 100644 --- a/arch/mips/kernel/vmlinux.lds.S +++ b/arch/mips/kernel/vmlinux.lds.S | |||
@@ -104,7 +104,7 @@ SECTIONS | |||
104 | . = ALIGN(_PAGE_SIZE); | 104 | . = ALIGN(_PAGE_SIZE); |
105 | __nosave_end = .; | 105 | __nosave_end = .; |
106 | 106 | ||
107 | . = ALIGN(32); | 107 | . = ALIGN(1 << CONFIG_MIPS_L1_CACHE_SHIFT); |
108 | .data.cacheline_aligned : { | 108 | .data.cacheline_aligned : { |
109 | *(.data.cacheline_aligned) | 109 | *(.data.cacheline_aligned) |
110 | } | 110 | } |
diff --git a/arch/mips/pci/fixup-emma2rh.c b/arch/mips/pci/fixup-emma2rh.c index a2705895561d..846eae9cdd05 100644 --- a/arch/mips/pci/fixup-emma2rh.c +++ b/arch/mips/pci/fixup-emma2rh.c | |||
@@ -29,7 +29,6 @@ | |||
29 | #include <linux/pci.h> | 29 | #include <linux/pci.h> |
30 | 30 | ||
31 | #include <asm/bootinfo.h> | 31 | #include <asm/bootinfo.h> |
32 | #include <asm/debug.h> | ||
33 | 32 | ||
34 | #include <asm/emma2rh/emma2rh.h> | 33 | #include <asm/emma2rh/emma2rh.h> |
35 | 34 | ||
diff --git a/arch/mips/pci/ops-pnx8550.c b/arch/mips/pci/ops-pnx8550.c index 0e160d9f07c3..1e6213fa7bdb 100644 --- a/arch/mips/pci/ops-pnx8550.c +++ b/arch/mips/pci/ops-pnx8550.c | |||
@@ -29,8 +29,6 @@ | |||
29 | 29 | ||
30 | #include <asm/mach-pnx8550/pci.h> | 30 | #include <asm/mach-pnx8550/pci.h> |
31 | #include <asm/mach-pnx8550/glb.h> | 31 | #include <asm/mach-pnx8550/glb.h> |
32 | #include <asm/debug.h> | ||
33 | |||
34 | 32 | ||
35 | static inline void clear_status(void) | 33 | static inline void clear_status(void) |
36 | { | 34 | { |
diff --git a/arch/mips/pci/pci-emma2rh.c b/arch/mips/pci/pci-emma2rh.c index d99591a0cdfe..772e283daa63 100644 --- a/arch/mips/pci/pci-emma2rh.c +++ b/arch/mips/pci/pci-emma2rh.c | |||
@@ -29,7 +29,6 @@ | |||
29 | #include <linux/pci.h> | 29 | #include <linux/pci.h> |
30 | 30 | ||
31 | #include <asm/bootinfo.h> | 31 | #include <asm/bootinfo.h> |
32 | #include <asm/debug.h> | ||
33 | 32 | ||
34 | #include <asm/emma2rh/emma2rh.h> | 33 | #include <asm/emma2rh/emma2rh.h> |
35 | 34 | ||
diff --git a/arch/mips/pci/pci.c b/arch/mips/pci/pci.c index c7fe6ec621e6..a377e9d2d029 100644 --- a/arch/mips/pci/pci.c +++ b/arch/mips/pci/pci.c | |||
@@ -34,6 +34,8 @@ static struct pci_controller *hose_head, **hose_tail = &hose_head; | |||
34 | unsigned long PCIBIOS_MIN_IO = 0x0000; | 34 | unsigned long PCIBIOS_MIN_IO = 0x0000; |
35 | unsigned long PCIBIOS_MIN_MEM = 0; | 35 | unsigned long PCIBIOS_MIN_MEM = 0; |
36 | 36 | ||
37 | static int pci_initialized; | ||
38 | |||
37 | /* | 39 | /* |
38 | * We need to avoid collisions with `mirrored' VGA ports | 40 | * We need to avoid collisions with `mirrored' VGA ports |
39 | * and other strange ISA hardware, so we always want the | 41 | * and other strange ISA hardware, so we always want the |
@@ -74,6 +76,42 @@ pcibios_align_resource(void *data, struct resource *res, | |||
74 | res->start = start; | 76 | res->start = start; |
75 | } | 77 | } |
76 | 78 | ||
79 | static void __devinit pcibios_scanbus(struct pci_controller *hose) | ||
80 | { | ||
81 | static int next_busno; | ||
82 | static int need_domain_info; | ||
83 | struct pci_bus *bus; | ||
84 | |||
85 | if (!hose->iommu) | ||
86 | PCI_DMA_BUS_IS_PHYS = 1; | ||
87 | |||
88 | if (hose->get_busno && pci_probe_only) | ||
89 | next_busno = (*hose->get_busno)(); | ||
90 | |||
91 | bus = pci_scan_bus(next_busno, hose->pci_ops, hose); | ||
92 | hose->bus = bus; | ||
93 | |||
94 | need_domain_info = need_domain_info || hose->index; | ||
95 | hose->need_domain_info = need_domain_info; | ||
96 | if (bus) { | ||
97 | next_busno = bus->subordinate + 1; | ||
98 | /* Don't allow 8-bit bus number overflow inside the hose - | ||
99 | reserve some space for bridges. */ | ||
100 | if (next_busno > 224) { | ||
101 | next_busno = 0; | ||
102 | need_domain_info = 1; | ||
103 | } | ||
104 | |||
105 | if (!pci_probe_only) { | ||
106 | pci_bus_size_bridges(bus); | ||
107 | pci_bus_assign_resources(bus); | ||
108 | pci_enable_bridges(bus); | ||
109 | } | ||
110 | } | ||
111 | } | ||
112 | |||
113 | static DEFINE_MUTEX(pci_scan_mutex); | ||
114 | |||
77 | void __devinit register_pci_controller(struct pci_controller *hose) | 115 | void __devinit register_pci_controller(struct pci_controller *hose) |
78 | { | 116 | { |
79 | if (request_resource(&iomem_resource, hose->mem_resource) < 0) | 117 | if (request_resource(&iomem_resource, hose->mem_resource) < 0) |
@@ -93,6 +131,17 @@ void __devinit register_pci_controller(struct pci_controller *hose) | |||
93 | printk(KERN_WARNING | 131 | printk(KERN_WARNING |
94 | "registering PCI controller with io_map_base unset\n"); | 132 | "registering PCI controller with io_map_base unset\n"); |
95 | } | 133 | } |
134 | |||
135 | /* | ||
136 | * Scan the bus if it is register after the PCI subsystem | ||
137 | * initialization. | ||
138 | */ | ||
139 | if (pci_initialized) { | ||
140 | mutex_lock(&pci_scan_mutex); | ||
141 | pcibios_scanbus(hose); | ||
142 | mutex_unlock(&pci_scan_mutex); | ||
143 | } | ||
144 | |||
96 | return; | 145 | return; |
97 | 146 | ||
98 | out: | 147 | out: |
@@ -125,38 +174,15 @@ static u8 __init common_swizzle(struct pci_dev *dev, u8 *pinp) | |||
125 | static int __init pcibios_init(void) | 174 | static int __init pcibios_init(void) |
126 | { | 175 | { |
127 | struct pci_controller *hose; | 176 | struct pci_controller *hose; |
128 | struct pci_bus *bus; | ||
129 | int next_busno; | ||
130 | int need_domain_info = 0; | ||
131 | 177 | ||
132 | /* Scan all of the recorded PCI controllers. */ | 178 | /* Scan all of the recorded PCI controllers. */ |
133 | for (next_busno = 0, hose = hose_head; hose; hose = hose->next) { | 179 | for (hose = hose_head; hose; hose = hose->next) |
134 | 180 | pcibios_scanbus(hose); | |
135 | if (!hose->iommu) | ||
136 | PCI_DMA_BUS_IS_PHYS = 1; | ||
137 | |||
138 | if (hose->get_busno && pci_probe_only) | ||
139 | next_busno = (*hose->get_busno)(); | ||
140 | |||
141 | bus = pci_scan_bus(next_busno, hose->pci_ops, hose); | ||
142 | hose->bus = bus; | ||
143 | need_domain_info = need_domain_info || hose->index; | ||
144 | hose->need_domain_info = need_domain_info; | ||
145 | if (bus) { | ||
146 | next_busno = bus->subordinate + 1; | ||
147 | /* Don't allow 8-bit bus number overflow inside the hose - | ||
148 | reserve some space for bridges. */ | ||
149 | if (next_busno > 224) { | ||
150 | next_busno = 0; | ||
151 | need_domain_info = 1; | ||
152 | } | ||
153 | } | ||
154 | } | ||
155 | 181 | ||
156 | if (!pci_probe_only) | ||
157 | pci_assign_unassigned_resources(); | ||
158 | pci_fixup_irqs(common_swizzle, pcibios_map_irq); | 182 | pci_fixup_irqs(common_swizzle, pcibios_map_irq); |
159 | 183 | ||
184 | pci_initialized = 1; | ||
185 | |||
160 | return 0; | 186 | return 0; |
161 | } | 187 | } |
162 | 188 | ||
diff --git a/arch/mips/rb532/time.c b/arch/mips/rb532/time.c index 8e7a46855b50..1377d599f0e3 100644 --- a/arch/mips/rb532/time.c +++ b/arch/mips/rb532/time.c | |||
@@ -28,7 +28,6 @@ | |||
28 | #include <linux/timex.h> | 28 | #include <linux/timex.h> |
29 | 29 | ||
30 | #include <asm/mipsregs.h> | 30 | #include <asm/mipsregs.h> |
31 | #include <asm/debug.h> | ||
32 | #include <asm/time.h> | 31 | #include <asm/time.h> |
33 | #include <asm/mach-rc32434/rc32434.h> | 32 | #include <asm/mach-rc32434/rc32434.h> |
34 | 33 | ||
diff --git a/arch/mips/sgi-ip22/ip22-platform.c b/arch/mips/sgi-ip22/ip22-platform.c index 52486c4d2b01..deddbf0ebe5c 100644 --- a/arch/mips/sgi-ip22/ip22-platform.c +++ b/arch/mips/sgi-ip22/ip22-platform.c | |||
@@ -192,3 +192,18 @@ static int __init sgi_button_devinit(void) | |||
192 | } | 192 | } |
193 | 193 | ||
194 | device_initcall(sgi_button_devinit); | 194 | device_initcall(sgi_button_devinit); |
195 | |||
196 | static int __init sgi_ds1286_devinit(void) | ||
197 | { | ||
198 | struct resource res; | ||
199 | |||
200 | memset(&res, 0, sizeof(res)); | ||
201 | res.start = HPC3_CHIP0_BASE + offsetof(struct hpc3_regs, rtcregs); | ||
202 | res.end = res.start + sizeof(hpc3c0->rtcregs) - 1; | ||
203 | res.flags = IORESOURCE_MEM; | ||
204 | |||
205 | return IS_ERR(platform_device_register_simple("rtc-ds1286", -1, | ||
206 | &res, 1)); | ||
207 | } | ||
208 | |||
209 | device_initcall(sgi_ds1286_devinit); | ||
diff --git a/arch/mips/sgi-ip22/ip22-setup.c b/arch/mips/sgi-ip22/ip22-setup.c index 896a1ef84829..b9a931358e23 100644 --- a/arch/mips/sgi-ip22/ip22-setup.c +++ b/arch/mips/sgi-ip22/ip22-setup.c | |||
@@ -4,7 +4,6 @@ | |||
4 | * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) | 4 | * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) |
5 | * Copyright (C) 1997, 1998 Ralf Baechle (ralf@gnu.org) | 5 | * Copyright (C) 1997, 1998 Ralf Baechle (ralf@gnu.org) |
6 | */ | 6 | */ |
7 | #include <linux/ds1286.h> | ||
8 | #include <linux/init.h> | 7 | #include <linux/init.h> |
9 | #include <linux/kernel.h> | 8 | #include <linux/kernel.h> |
10 | #include <linux/kdev_t.h> | 9 | #include <linux/kdev_t.h> |
diff --git a/arch/mips/sgi-ip22/ip22-time.c b/arch/mips/sgi-ip22/ip22-time.c index 10e505491655..3dcb27ec0c53 100644 --- a/arch/mips/sgi-ip22/ip22-time.c +++ b/arch/mips/sgi-ip22/ip22-time.c | |||
@@ -10,7 +10,6 @@ | |||
10 | * Copyright (C) 2003, 06 Ralf Baechle (ralf@linux-mips.org) | 10 | * Copyright (C) 2003, 06 Ralf Baechle (ralf@linux-mips.org) |
11 | */ | 11 | */ |
12 | #include <linux/bcd.h> | 12 | #include <linux/bcd.h> |
13 | #include <linux/ds1286.h> | ||
14 | #include <linux/init.h> | 13 | #include <linux/init.h> |
15 | #include <linux/irq.h> | 14 | #include <linux/irq.h> |
16 | #include <linux/kernel.h> | 15 | #include <linux/kernel.h> |
@@ -29,69 +28,6 @@ | |||
29 | #include <asm/sgi/hpc3.h> | 28 | #include <asm/sgi/hpc3.h> |
30 | #include <asm/sgi/ip22.h> | 29 | #include <asm/sgi/ip22.h> |
31 | 30 | ||
32 | /* | ||
33 | * Note that mktime uses month from 1 to 12 while rtc_time_to_tm | ||
34 | * uses 0 to 11. | ||
35 | */ | ||
36 | unsigned long read_persistent_clock(void) | ||
37 | { | ||
38 | unsigned int yrs, mon, day, hrs, min, sec; | ||
39 | unsigned int save_control; | ||
40 | unsigned long flags; | ||
41 | |||
42 | spin_lock_irqsave(&rtc_lock, flags); | ||
43 | save_control = hpc3c0->rtcregs[RTC_CMD] & 0xff; | ||
44 | hpc3c0->rtcregs[RTC_CMD] = save_control | RTC_TE; | ||
45 | |||
46 | sec = BCD2BIN(hpc3c0->rtcregs[RTC_SECONDS] & 0xff); | ||
47 | min = BCD2BIN(hpc3c0->rtcregs[RTC_MINUTES] & 0xff); | ||
48 | hrs = BCD2BIN(hpc3c0->rtcregs[RTC_HOURS] & 0x3f); | ||
49 | day = BCD2BIN(hpc3c0->rtcregs[RTC_DATE] & 0xff); | ||
50 | mon = BCD2BIN(hpc3c0->rtcregs[RTC_MONTH] & 0x1f); | ||
51 | yrs = BCD2BIN(hpc3c0->rtcregs[RTC_YEAR] & 0xff); | ||
52 | |||
53 | hpc3c0->rtcregs[RTC_CMD] = save_control; | ||
54 | spin_unlock_irqrestore(&rtc_lock, flags); | ||
55 | |||
56 | if (yrs < 45) | ||
57 | yrs += 30; | ||
58 | if ((yrs += 40) < 70) | ||
59 | yrs += 100; | ||
60 | |||
61 | return mktime(yrs + 1900, mon, day, hrs, min, sec); | ||
62 | } | ||
63 | |||
64 | int rtc_mips_set_time(unsigned long tim) | ||
65 | { | ||
66 | struct rtc_time tm; | ||
67 | unsigned int save_control; | ||
68 | unsigned long flags; | ||
69 | |||
70 | rtc_time_to_tm(tim, &tm); | ||
71 | |||
72 | tm.tm_mon += 1; /* tm_mon starts at zero */ | ||
73 | tm.tm_year -= 40; | ||
74 | if (tm.tm_year >= 100) | ||
75 | tm.tm_year -= 100; | ||
76 | |||
77 | spin_lock_irqsave(&rtc_lock, flags); | ||
78 | save_control = hpc3c0->rtcregs[RTC_CMD] & 0xff; | ||
79 | hpc3c0->rtcregs[RTC_CMD] = save_control | RTC_TE; | ||
80 | |||
81 | hpc3c0->rtcregs[RTC_YEAR] = BIN2BCD(tm.tm_year); | ||
82 | hpc3c0->rtcregs[RTC_MONTH] = BIN2BCD(tm.tm_mon); | ||
83 | hpc3c0->rtcregs[RTC_DATE] = BIN2BCD(tm.tm_mday); | ||
84 | hpc3c0->rtcregs[RTC_HOURS] = BIN2BCD(tm.tm_hour); | ||
85 | hpc3c0->rtcregs[RTC_MINUTES] = BIN2BCD(tm.tm_min); | ||
86 | hpc3c0->rtcregs[RTC_SECONDS] = BIN2BCD(tm.tm_sec); | ||
87 | hpc3c0->rtcregs[RTC_HUNDREDTH_SECOND] = 0; | ||
88 | |||
89 | hpc3c0->rtcregs[RTC_CMD] = save_control; | ||
90 | spin_unlock_irqrestore(&rtc_lock, flags); | ||
91 | |||
92 | return 0; | ||
93 | } | ||
94 | |||
95 | static unsigned long dosample(void) | 31 | static unsigned long dosample(void) |
96 | { | 32 | { |
97 | u32 ct0, ct1; | 33 | u32 ct0, ct1; |
diff --git a/arch/mips/sgi-ip27/ip27-timer.c b/arch/mips/sgi-ip27/ip27-timer.c index 8b4e854af925..1327c2746fb7 100644 --- a/arch/mips/sgi-ip27/ip27-timer.c +++ b/arch/mips/sgi-ip27/ip27-timer.c | |||
@@ -13,12 +13,12 @@ | |||
13 | #include <linux/time.h> | 13 | #include <linux/time.h> |
14 | #include <linux/timex.h> | 14 | #include <linux/timex.h> |
15 | #include <linux/mm.h> | 15 | #include <linux/mm.h> |
16 | #include <linux/platform_device.h> | ||
16 | 17 | ||
17 | #include <asm/time.h> | 18 | #include <asm/time.h> |
18 | #include <asm/pgtable.h> | 19 | #include <asm/pgtable.h> |
19 | #include <asm/sgialib.h> | 20 | #include <asm/sgialib.h> |
20 | #include <asm/sn/ioc3.h> | 21 | #include <asm/sn/ioc3.h> |
21 | #include <asm/m48t35.h> | ||
22 | #include <asm/sn/klconfig.h> | 22 | #include <asm/sn/klconfig.h> |
23 | #include <asm/sn/arch.h> | 23 | #include <asm/sn/arch.h> |
24 | #include <asm/sn/addrs.h> | 24 | #include <asm/sn/addrs.h> |
@@ -28,51 +28,6 @@ | |||
28 | 28 | ||
29 | #define TICK_SIZE (tick_nsec / 1000) | 29 | #define TICK_SIZE (tick_nsec / 1000) |
30 | 30 | ||
31 | #if 0 | ||
32 | static int set_rtc_mmss(unsigned long nowtime) | ||
33 | { | ||
34 | int retval = 0; | ||
35 | int real_seconds, real_minutes, cmos_minutes; | ||
36 | struct m48t35_rtc *rtc; | ||
37 | nasid_t nid; | ||
38 | |||
39 | nid = get_nasid(); | ||
40 | rtc = (struct m48t35_rtc *)(KL_CONFIG_CH_CONS_INFO(nid)->memory_base + | ||
41 | IOC3_BYTEBUS_DEV0); | ||
42 | |||
43 | rtc->control |= M48T35_RTC_READ; | ||
44 | cmos_minutes = BCD2BIN(rtc->min); | ||
45 | rtc->control &= ~M48T35_RTC_READ; | ||
46 | |||
47 | /* | ||
48 | * Since we're only adjusting minutes and seconds, don't interfere with | ||
49 | * hour overflow. This avoids messing with unknown time zones but | ||
50 | * requires your RTC not to be off by more than 15 minutes | ||
51 | */ | ||
52 | real_seconds = nowtime % 60; | ||
53 | real_minutes = nowtime / 60; | ||
54 | if (((abs(real_minutes - cmos_minutes) + 15)/30) & 1) | ||
55 | real_minutes += 30; /* correct for half hour time zone */ | ||
56 | real_minutes %= 60; | ||
57 | |||
58 | if (abs(real_minutes - cmos_minutes) < 30) { | ||
59 | real_seconds = BIN2BCD(real_seconds); | ||
60 | real_minutes = BIN2BCD(real_minutes); | ||
61 | rtc->control |= M48T35_RTC_SET; | ||
62 | rtc->sec = real_seconds; | ||
63 | rtc->min = real_minutes; | ||
64 | rtc->control &= ~M48T35_RTC_SET; | ||
65 | } else { | ||
66 | printk(KERN_WARNING | ||
67 | "set_rtc_mmss: can't update from %d to %d\n", | ||
68 | cmos_minutes, real_minutes); | ||
69 | retval = -1; | ||
70 | } | ||
71 | |||
72 | return retval; | ||
73 | } | ||
74 | #endif | ||
75 | |||
76 | /* Includes for ioc3_init(). */ | 31 | /* Includes for ioc3_init(). */ |
77 | #include <asm/sn/types.h> | 32 | #include <asm/sn/types.h> |
78 | #include <asm/sn/sn0/addrs.h> | 33 | #include <asm/sn/sn0/addrs.h> |
@@ -80,37 +35,6 @@ static int set_rtc_mmss(unsigned long nowtime) | |||
80 | #include <asm/sn/sn0/hubio.h> | 35 | #include <asm/sn/sn0/hubio.h> |
81 | #include <asm/pci/bridge.h> | 36 | #include <asm/pci/bridge.h> |
82 | 37 | ||
83 | unsigned long read_persistent_clock(void) | ||
84 | { | ||
85 | unsigned int year, month, date, hour, min, sec; | ||
86 | struct m48t35_rtc *rtc; | ||
87 | nasid_t nid; | ||
88 | |||
89 | nid = get_nasid(); | ||
90 | rtc = (struct m48t35_rtc *)(KL_CONFIG_CH_CONS_INFO(nid)->memory_base + | ||
91 | IOC3_BYTEBUS_DEV0); | ||
92 | |||
93 | rtc->control |= M48T35_RTC_READ; | ||
94 | sec = rtc->sec; | ||
95 | min = rtc->min; | ||
96 | hour = rtc->hour; | ||
97 | date = rtc->date; | ||
98 | month = rtc->month; | ||
99 | year = rtc->year; | ||
100 | rtc->control &= ~M48T35_RTC_READ; | ||
101 | |||
102 | sec = BCD2BIN(sec); | ||
103 | min = BCD2BIN(min); | ||
104 | hour = BCD2BIN(hour); | ||
105 | date = BCD2BIN(date); | ||
106 | month = BCD2BIN(month); | ||
107 | year = BCD2BIN(year); | ||
108 | |||
109 | year += 1970; | ||
110 | |||
111 | return mktime(year, month, date, hour, min, sec); | ||
112 | } | ||
113 | |||
114 | static void enable_rt_irq(unsigned int irq) | 38 | static void enable_rt_irq(unsigned int irq) |
115 | { | 39 | { |
116 | } | 40 | } |
@@ -286,6 +210,7 @@ void __cpuinit cpu_time_init(void) | |||
286 | 210 | ||
287 | void __cpuinit hub_rtc_init(cnodeid_t cnode) | 211 | void __cpuinit hub_rtc_init(cnodeid_t cnode) |
288 | { | 212 | { |
213 | |||
289 | /* | 214 | /* |
290 | * We only need to initialize the current node. | 215 | * We only need to initialize the current node. |
291 | * If this is not the current node then it is a cpuless | 216 | * If this is not the current node then it is a cpuless |
@@ -301,3 +226,23 @@ void __cpuinit hub_rtc_init(cnodeid_t cnode) | |||
301 | LOCAL_HUB_S(PI_RT_PEND_B, 0); | 226 | LOCAL_HUB_S(PI_RT_PEND_B, 0); |
302 | } | 227 | } |
303 | } | 228 | } |
229 | |||
230 | static int __init sgi_ip27_rtc_devinit(void) | ||
231 | { | ||
232 | struct resource res; | ||
233 | |||
234 | memset(&res, 0, sizeof(res)); | ||
235 | res.start = XPHYSADDR(KL_CONFIG_CH_CONS_INFO(master_nasid)->memory_base + | ||
236 | IOC3_BYTEBUS_DEV0); | ||
237 | res.end = res.start + 32767; | ||
238 | res.flags = IORESOURCE_MEM; | ||
239 | |||
240 | return IS_ERR(platform_device_register_simple("rtc-m48t35", -1, | ||
241 | &res, 1)); | ||
242 | } | ||
243 | |||
244 | /* | ||
245 | * kludge make this a device_initcall after ioc3 resource conflicts | ||
246 | * are resolved | ||
247 | */ | ||
248 | late_initcall(sgi_ip27_rtc_devinit); | ||
diff --git a/arch/mips/sgi-ip32/ip32-platform.c b/arch/mips/sgi-ip32/ip32-platform.c index 3d63721e0e80..511e9ff2acfd 100644 --- a/arch/mips/sgi-ip32/ip32-platform.c +++ b/arch/mips/sgi-ip32/ip32-platform.c | |||
@@ -90,6 +90,22 @@ static __init int sgio2btns_devinit(void) | |||
90 | 90 | ||
91 | device_initcall(sgio2btns_devinit); | 91 | device_initcall(sgio2btns_devinit); |
92 | 92 | ||
93 | static struct resource sgio2_cmos_rsrc[] = { | ||
94 | { | ||
95 | .start = 0x70, | ||
96 | .end = 0x71, | ||
97 | .flags = IORESOURCE_IO | ||
98 | } | ||
99 | }; | ||
100 | |||
101 | static __init int sgio2_cmos_devinit(void) | ||
102 | { | ||
103 | return IS_ERR(platform_device_register_simple("rtc_cmos", -1, | ||
104 | sgio2_cmos_rsrc, 1)); | ||
105 | } | ||
106 | |||
107 | device_initcall(sgio2_cmos_devinit); | ||
108 | |||
93 | MODULE_AUTHOR("Ralf Baechle <ralf@linux-mips.org>"); | 109 | MODULE_AUTHOR("Ralf Baechle <ralf@linux-mips.org>"); |
94 | MODULE_LICENSE("GPL"); | 110 | MODULE_LICENSE("GPL"); |
95 | MODULE_DESCRIPTION("8250 UART probe driver for SGI IP32 aka O2"); | 111 | MODULE_DESCRIPTION("8250 UART probe driver for SGI IP32 aka O2"); |
diff --git a/arch/mips/sgi-ip32/ip32-setup.c b/arch/mips/sgi-ip32/ip32-setup.c index 1024bf40bd9e..c5a5d4a31b4b 100644 --- a/arch/mips/sgi-ip32/ip32-setup.c +++ b/arch/mips/sgi-ip32/ip32-setup.c | |||
@@ -62,11 +62,6 @@ static inline void str2eaddr(unsigned char *ea, unsigned char *str) | |||
62 | } | 62 | } |
63 | #endif | 63 | #endif |
64 | 64 | ||
65 | unsigned long read_persistent_clock(void) | ||
66 | { | ||
67 | return mc146818_get_cmos_time(); | ||
68 | } | ||
69 | |||
70 | /* An arbitrary time; this can be decreased if reliability looks good */ | 65 | /* An arbitrary time; this can be decreased if reliability looks good */ |
71 | #define WAIT_MS 10 | 66 | #define WAIT_MS 10 |
72 | 67 | ||
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig index b57fba5c6d02..f3d7fd3406a6 100644 --- a/drivers/rtc/Kconfig +++ b/drivers/rtc/Kconfig | |||
@@ -352,6 +352,11 @@ config RTC_DRV_DS1216 | |||
352 | help | 352 | help |
353 | If you say yes here you get support for the Dallas DS1216 RTC chips. | 353 | If you say yes here you get support for the Dallas DS1216 RTC chips. |
354 | 354 | ||
355 | config RTC_DRV_DS1286 | ||
356 | tristate "Dallas DS1286" | ||
357 | help | ||
358 | If you say yes here you get support for the Dallas DS1286 RTC chips. | ||
359 | |||
355 | config RTC_DRV_DS1302 | 360 | config RTC_DRV_DS1302 |
356 | tristate "Dallas DS1302" | 361 | tristate "Dallas DS1302" |
357 | depends on SH_SECUREEDGE5410 | 362 | depends on SH_SECUREEDGE5410 |
@@ -405,6 +410,15 @@ config RTC_DRV_M48T86 | |||
405 | This driver can also be built as a module. If so, the module | 410 | This driver can also be built as a module. If so, the module |
406 | will be called rtc-m48t86. | 411 | will be called rtc-m48t86. |
407 | 412 | ||
413 | config RTC_DRV_M48T35 | ||
414 | tristate "ST M48T35" | ||
415 | help | ||
416 | If you say Y here you will get support for the | ||
417 | ST M48T35 RTC chip. | ||
418 | |||
419 | This driver can also be built as a module, if so, the module | ||
420 | will be called "rtc-m48t35". | ||
421 | |||
408 | config RTC_DRV_M48T59 | 422 | config RTC_DRV_M48T59 |
409 | tristate "ST M48T59/M48T08/M48T02" | 423 | tristate "ST M48T59/M48T08/M48T02" |
410 | help | 424 | help |
diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile index 10f41f85c38a..37a71b727262 100644 --- a/drivers/rtc/Makefile +++ b/drivers/rtc/Makefile | |||
@@ -23,6 +23,7 @@ obj-$(CONFIG_RTC_DRV_AT91SAM9) += rtc-at91sam9.o | |||
23 | obj-$(CONFIG_RTC_DRV_BFIN) += rtc-bfin.o | 23 | obj-$(CONFIG_RTC_DRV_BFIN) += rtc-bfin.o |
24 | obj-$(CONFIG_RTC_DRV_CMOS) += rtc-cmos.o | 24 | obj-$(CONFIG_RTC_DRV_CMOS) += rtc-cmos.o |
25 | obj-$(CONFIG_RTC_DRV_DS1216) += rtc-ds1216.o | 25 | obj-$(CONFIG_RTC_DRV_DS1216) += rtc-ds1216.o |
26 | obj-$(CONFIG_RTC_DRV_DS1286) += rtc-ds1286.o | ||
26 | obj-$(CONFIG_RTC_DRV_DS1302) += rtc-ds1302.o | 27 | obj-$(CONFIG_RTC_DRV_DS1302) += rtc-ds1302.o |
27 | obj-$(CONFIG_RTC_DRV_DS1305) += rtc-ds1305.o | 28 | obj-$(CONFIG_RTC_DRV_DS1305) += rtc-ds1305.o |
28 | obj-$(CONFIG_RTC_DRV_DS1307) += rtc-ds1307.o | 29 | obj-$(CONFIG_RTC_DRV_DS1307) += rtc-ds1307.o |
@@ -36,6 +37,7 @@ obj-$(CONFIG_RTC_DRV_FM3130) += rtc-fm3130.o | |||
36 | obj-$(CONFIG_RTC_DRV_ISL1208) += rtc-isl1208.o | 37 | obj-$(CONFIG_RTC_DRV_ISL1208) += rtc-isl1208.o |
37 | obj-$(CONFIG_RTC_DRV_M41T80) += rtc-m41t80.o | 38 | obj-$(CONFIG_RTC_DRV_M41T80) += rtc-m41t80.o |
38 | obj-$(CONFIG_RTC_DRV_M41T94) += rtc-m41t94.o | 39 | obj-$(CONFIG_RTC_DRV_M41T94) += rtc-m41t94.o |
40 | obj-$(CONFIG_RTC_DRV_M48T35) += rtc-m48t35.o | ||
39 | obj-$(CONFIG_RTC_DRV_M48T59) += rtc-m48t59.o | 41 | obj-$(CONFIG_RTC_DRV_M48T59) += rtc-m48t59.o |
40 | obj-$(CONFIG_RTC_DRV_M48T86) += rtc-m48t86.o | 42 | obj-$(CONFIG_RTC_DRV_M48T86) += rtc-m48t86.o |
41 | obj-$(CONFIG_RTC_DRV_BQ4802) += rtc-bq4802.o | 43 | obj-$(CONFIG_RTC_DRV_BQ4802) += rtc-bq4802.o |
diff --git a/drivers/rtc/rtc-ds1286.c b/drivers/rtc/rtc-ds1286.c new file mode 100644 index 000000000000..4b4c1b6a4187 --- /dev/null +++ b/drivers/rtc/rtc-ds1286.c | |||
@@ -0,0 +1,409 @@ | |||
1 | /* | ||
2 | * DS1286 Real Time Clock interface for Linux | ||
3 | * | ||
4 | * Copyright (C) 1998, 1999, 2000 Ralf Baechle | ||
5 | * Copyright (C) 2008 Thomas Bogendoerfer | ||
6 | * | ||
7 | * Based on code written by Paul Gortmaker. | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify it | ||
10 | * under the terms of the GNU General Public License as published by the | ||
11 | * Free Software Foundation; either version 2 of the License, or (at your | ||
12 | * option) any later version. | ||
13 | */ | ||
14 | |||
15 | #include <linux/module.h> | ||
16 | #include <linux/rtc.h> | ||
17 | #include <linux/platform_device.h> | ||
18 | #include <linux/bcd.h> | ||
19 | #include <linux/ds1286.h> | ||
20 | |||
21 | #define DRV_VERSION "1.0" | ||
22 | |||
23 | struct ds1286_priv { | ||
24 | struct rtc_device *rtc; | ||
25 | u32 __iomem *rtcregs; | ||
26 | size_t size; | ||
27 | unsigned long baseaddr; | ||
28 | spinlock_t lock; | ||
29 | }; | ||
30 | |||
31 | static inline u8 ds1286_rtc_read(struct ds1286_priv *priv, int reg) | ||
32 | { | ||
33 | return __raw_readl(&priv->rtcregs[reg]) & 0xff; | ||
34 | } | ||
35 | |||
36 | static inline void ds1286_rtc_write(struct ds1286_priv *priv, u8 data, int reg) | ||
37 | { | ||
38 | __raw_writel(data, &priv->rtcregs[reg]); | ||
39 | } | ||
40 | |||
41 | #ifdef CONFIG_RTC_INTF_DEV | ||
42 | |||
43 | static int ds1286_ioctl(struct device *dev, unsigned int cmd, unsigned long arg) | ||
44 | { | ||
45 | struct ds1286_priv *priv = dev_get_drvdata(dev); | ||
46 | unsigned long flags; | ||
47 | unsigned char val; | ||
48 | |||
49 | switch (cmd) { | ||
50 | case RTC_AIE_OFF: | ||
51 | /* Mask alarm int. enab. bit */ | ||
52 | spin_lock_irqsave(&priv->lock, flags); | ||
53 | val = ds1286_rtc_read(priv, RTC_CMD); | ||
54 | val |= RTC_TDM; | ||
55 | ds1286_rtc_write(priv, val, RTC_CMD); | ||
56 | spin_unlock_irqrestore(&priv->lock, flags); | ||
57 | break; | ||
58 | case RTC_AIE_ON: | ||
59 | /* Allow alarm interrupts. */ | ||
60 | spin_lock_irqsave(&priv->lock, flags); | ||
61 | val = ds1286_rtc_read(priv, RTC_CMD); | ||
62 | val &= ~RTC_TDM; | ||
63 | ds1286_rtc_write(priv, val, RTC_CMD); | ||
64 | spin_unlock_irqrestore(&priv->lock, flags); | ||
65 | break; | ||
66 | case RTC_WIE_OFF: | ||
67 | /* Mask watchdog int. enab. bit */ | ||
68 | spin_lock_irqsave(&priv->lock, flags); | ||
69 | val = ds1286_rtc_read(priv, RTC_CMD); | ||
70 | val |= RTC_WAM; | ||
71 | ds1286_rtc_write(priv, val, RTC_CMD); | ||
72 | spin_unlock_irqrestore(&priv->lock, flags); | ||
73 | break; | ||
74 | case RTC_WIE_ON: | ||
75 | /* Allow watchdog interrupts. */ | ||
76 | spin_lock_irqsave(&priv->lock, flags); | ||
77 | val = ds1286_rtc_read(priv, RTC_CMD); | ||
78 | val &= ~RTC_WAM; | ||
79 | ds1286_rtc_write(priv, val, RTC_CMD); | ||
80 | spin_unlock_irqrestore(&priv->lock, flags); | ||
81 | break; | ||
82 | default: | ||
83 | return -ENOIOCTLCMD; | ||
84 | } | ||
85 | return 0; | ||
86 | } | ||
87 | |||
88 | #else | ||
89 | #define ds1286_ioctl NULL | ||
90 | #endif | ||
91 | |||
92 | #ifdef CONFIG_PROC_FS | ||
93 | |||
94 | static int ds1286_proc(struct device *dev, struct seq_file *seq) | ||
95 | { | ||
96 | struct ds1286_priv *priv = dev_get_drvdata(dev); | ||
97 | unsigned char month, cmd, amode; | ||
98 | const char *s; | ||
99 | |||
100 | month = ds1286_rtc_read(priv, RTC_MONTH); | ||
101 | seq_printf(seq, | ||
102 | "oscillator\t: %s\n" | ||
103 | "square_wave\t: %s\n", | ||
104 | (month & RTC_EOSC) ? "disabled" : "enabled", | ||
105 | (month & RTC_ESQW) ? "disabled" : "enabled"); | ||
106 | |||
107 | amode = ((ds1286_rtc_read(priv, RTC_MINUTES_ALARM) & 0x80) >> 5) | | ||
108 | ((ds1286_rtc_read(priv, RTC_HOURS_ALARM) & 0x80) >> 6) | | ||
109 | ((ds1286_rtc_read(priv, RTC_DAY_ALARM) & 0x80) >> 7); | ||
110 | switch (amode) { | ||
111 | case 7: | ||
112 | s = "each minute"; | ||
113 | break; | ||
114 | case 3: | ||
115 | s = "minutes match"; | ||
116 | break; | ||
117 | case 1: | ||
118 | s = "hours and minutes match"; | ||
119 | break; | ||
120 | case 0: | ||
121 | s = "days, hours and minutes match"; | ||
122 | break; | ||
123 | default: | ||
124 | s = "invalid"; | ||
125 | break; | ||
126 | } | ||
127 | seq_printf(seq, "alarm_mode\t: %s\n", s); | ||
128 | |||
129 | cmd = ds1286_rtc_read(priv, RTC_CMD); | ||
130 | seq_printf(seq, | ||
131 | "alarm_enable\t: %s\n" | ||
132 | "wdog_alarm\t: %s\n" | ||
133 | "alarm_mask\t: %s\n" | ||
134 | "wdog_alarm_mask\t: %s\n" | ||
135 | "interrupt_mode\t: %s\n" | ||
136 | "INTB_mode\t: %s_active\n" | ||
137 | "interrupt_pins\t: %s\n", | ||
138 | (cmd & RTC_TDF) ? "yes" : "no", | ||
139 | (cmd & RTC_WAF) ? "yes" : "no", | ||
140 | (cmd & RTC_TDM) ? "disabled" : "enabled", | ||
141 | (cmd & RTC_WAM) ? "disabled" : "enabled", | ||
142 | (cmd & RTC_PU_LVL) ? "pulse" : "level", | ||
143 | (cmd & RTC_IBH_LO) ? "low" : "high", | ||
144 | (cmd & RTC_IPSW) ? "unswapped" : "swapped"); | ||
145 | return 0; | ||
146 | } | ||
147 | |||
148 | #else | ||
149 | #define ds1286_proc NULL | ||
150 | #endif | ||
151 | |||
152 | static int ds1286_read_time(struct device *dev, struct rtc_time *tm) | ||
153 | { | ||
154 | struct ds1286_priv *priv = dev_get_drvdata(dev); | ||
155 | unsigned char save_control; | ||
156 | unsigned long flags; | ||
157 | unsigned long uip_watchdog = jiffies; | ||
158 | |||
159 | /* | ||
160 | * read RTC once any update in progress is done. The update | ||
161 | * can take just over 2ms. We wait 10 to 20ms. There is no need to | ||
162 | * to poll-wait (up to 1s - eeccch) for the falling edge of RTC_UIP. | ||
163 | * If you need to know *exactly* when a second has started, enable | ||
164 | * periodic update complete interrupts, (via ioctl) and then | ||
165 | * immediately read /dev/rtc which will block until you get the IRQ. | ||
166 | * Once the read clears, read the RTC time (again via ioctl). Easy. | ||
167 | */ | ||
168 | |||
169 | if (ds1286_rtc_read(priv, RTC_CMD) & RTC_TE) | ||
170 | while (time_before(jiffies, uip_watchdog + 2*HZ/100)) | ||
171 | barrier(); | ||
172 | |||
173 | /* | ||
174 | * Only the values that we read from the RTC are set. We leave | ||
175 | * tm_wday, tm_yday and tm_isdst untouched. Even though the | ||
176 | * RTC has RTC_DAY_OF_WEEK, we ignore it, as it is only updated | ||
177 | * by the RTC when initially set to a non-zero value. | ||
178 | */ | ||
179 | spin_lock_irqsave(&priv->lock, flags); | ||
180 | save_control = ds1286_rtc_read(priv, RTC_CMD); | ||
181 | ds1286_rtc_write(priv, (save_control|RTC_TE), RTC_CMD); | ||
182 | |||
183 | tm->tm_sec = ds1286_rtc_read(priv, RTC_SECONDS); | ||
184 | tm->tm_min = ds1286_rtc_read(priv, RTC_MINUTES); | ||
185 | tm->tm_hour = ds1286_rtc_read(priv, RTC_HOURS) & 0x3f; | ||
186 | tm->tm_mday = ds1286_rtc_read(priv, RTC_DATE); | ||
187 | tm->tm_mon = ds1286_rtc_read(priv, RTC_MONTH) & 0x1f; | ||
188 | tm->tm_year = ds1286_rtc_read(priv, RTC_YEAR); | ||
189 | |||
190 | ds1286_rtc_write(priv, save_control, RTC_CMD); | ||
191 | spin_unlock_irqrestore(&priv->lock, flags); | ||
192 | |||
193 | tm->tm_sec = bcd2bin(tm->tm_sec); | ||
194 | tm->tm_min = bcd2bin(tm->tm_min); | ||
195 | tm->tm_hour = bcd2bin(tm->tm_hour); | ||
196 | tm->tm_mday = bcd2bin(tm->tm_mday); | ||
197 | tm->tm_mon = bcd2bin(tm->tm_mon); | ||
198 | tm->tm_year = bcd2bin(tm->tm_year); | ||
199 | |||
200 | /* | ||
201 | * Account for differences between how the RTC uses the values | ||
202 | * and how they are defined in a struct rtc_time; | ||
203 | */ | ||
204 | if (tm->tm_year < 45) | ||
205 | tm->tm_year += 30; | ||
206 | tm->tm_year += 40; | ||
207 | if (tm->tm_year < 70) | ||
208 | tm->tm_year += 100; | ||
209 | |||
210 | tm->tm_mon--; | ||
211 | |||
212 | return rtc_valid_tm(tm); | ||
213 | } | ||
214 | |||
215 | static int ds1286_set_time(struct device *dev, struct rtc_time *tm) | ||
216 | { | ||
217 | struct ds1286_priv *priv = dev_get_drvdata(dev); | ||
218 | unsigned char mon, day, hrs, min, sec; | ||
219 | unsigned char save_control; | ||
220 | unsigned int yrs; | ||
221 | unsigned long flags; | ||
222 | |||
223 | yrs = tm->tm_year + 1900; | ||
224 | mon = tm->tm_mon + 1; /* tm_mon starts at zero */ | ||
225 | day = tm->tm_mday; | ||
226 | hrs = tm->tm_hour; | ||
227 | min = tm->tm_min; | ||
228 | sec = tm->tm_sec; | ||
229 | |||
230 | if (yrs < 1970) | ||
231 | return -EINVAL; | ||
232 | |||
233 | yrs -= 1940; | ||
234 | if (yrs > 255) /* They are unsigned */ | ||
235 | return -EINVAL; | ||
236 | |||
237 | if (yrs >= 100) | ||
238 | yrs -= 100; | ||
239 | |||
240 | sec = bin2bcd(sec); | ||
241 | min = bin2bcd(min); | ||
242 | hrs = bin2bcd(hrs); | ||
243 | day = bin2bcd(day); | ||
244 | mon = bin2bcd(mon); | ||
245 | yrs = bin2bcd(yrs); | ||
246 | |||
247 | spin_lock_irqsave(&priv->lock, flags); | ||
248 | save_control = ds1286_rtc_read(priv, RTC_CMD); | ||
249 | ds1286_rtc_write(priv, (save_control|RTC_TE), RTC_CMD); | ||
250 | |||
251 | ds1286_rtc_write(priv, yrs, RTC_YEAR); | ||
252 | ds1286_rtc_write(priv, mon, RTC_MONTH); | ||
253 | ds1286_rtc_write(priv, day, RTC_DATE); | ||
254 | ds1286_rtc_write(priv, hrs, RTC_HOURS); | ||
255 | ds1286_rtc_write(priv, min, RTC_MINUTES); | ||
256 | ds1286_rtc_write(priv, sec, RTC_SECONDS); | ||
257 | ds1286_rtc_write(priv, 0, RTC_HUNDREDTH_SECOND); | ||
258 | |||
259 | ds1286_rtc_write(priv, save_control, RTC_CMD); | ||
260 | spin_unlock_irqrestore(&priv->lock, flags); | ||
261 | return 0; | ||
262 | } | ||
263 | |||
264 | static int ds1286_read_alarm(struct device *dev, struct rtc_wkalrm *alm) | ||
265 | { | ||
266 | struct ds1286_priv *priv = dev_get_drvdata(dev); | ||
267 | unsigned char cmd; | ||
268 | unsigned long flags; | ||
269 | |||
270 | /* | ||
271 | * Only the values that we read from the RTC are set. That | ||
272 | * means only tm_wday, tm_hour, tm_min. | ||
273 | */ | ||
274 | spin_lock_irqsave(&priv->lock, flags); | ||
275 | alm->time.tm_min = ds1286_rtc_read(priv, RTC_MINUTES_ALARM) & 0x7f; | ||
276 | alm->time.tm_hour = ds1286_rtc_read(priv, RTC_HOURS_ALARM) & 0x1f; | ||
277 | alm->time.tm_wday = ds1286_rtc_read(priv, RTC_DAY_ALARM) & 0x07; | ||
278 | cmd = ds1286_rtc_read(priv, RTC_CMD); | ||
279 | spin_unlock_irqrestore(&priv->lock, flags); | ||
280 | |||
281 | alm->time.tm_min = bcd2bin(alm->time.tm_min); | ||
282 | alm->time.tm_hour = bcd2bin(alm->time.tm_hour); | ||
283 | alm->time.tm_sec = 0; | ||
284 | return 0; | ||
285 | } | ||
286 | |||
287 | static int ds1286_set_alarm(struct device *dev, struct rtc_wkalrm *alm) | ||
288 | { | ||
289 | struct ds1286_priv *priv = dev_get_drvdata(dev); | ||
290 | unsigned char hrs, min, sec; | ||
291 | |||
292 | hrs = alm->time.tm_hour; | ||
293 | min = alm->time.tm_min; | ||
294 | sec = alm->time.tm_sec; | ||
295 | |||
296 | if (hrs >= 24) | ||
297 | hrs = 0xff; | ||
298 | |||
299 | if (min >= 60) | ||
300 | min = 0xff; | ||
301 | |||
302 | if (sec != 0) | ||
303 | return -EINVAL; | ||
304 | |||
305 | min = bin2bcd(min); | ||
306 | hrs = bin2bcd(hrs); | ||
307 | |||
308 | spin_lock(&priv->lock); | ||
309 | ds1286_rtc_write(priv, hrs, RTC_HOURS_ALARM); | ||
310 | ds1286_rtc_write(priv, min, RTC_MINUTES_ALARM); | ||
311 | spin_unlock(&priv->lock); | ||
312 | |||
313 | return 0; | ||
314 | } | ||
315 | |||
316 | static const struct rtc_class_ops ds1286_ops = { | ||
317 | .ioctl = ds1286_ioctl, | ||
318 | .proc = ds1286_proc, | ||
319 | .read_time = ds1286_read_time, | ||
320 | .set_time = ds1286_set_time, | ||
321 | .read_alarm = ds1286_read_alarm, | ||
322 | .set_alarm = ds1286_set_alarm, | ||
323 | }; | ||
324 | |||
325 | static int __devinit ds1286_probe(struct platform_device *pdev) | ||
326 | { | ||
327 | struct rtc_device *rtc; | ||
328 | struct resource *res; | ||
329 | struct ds1286_priv *priv; | ||
330 | int ret = 0; | ||
331 | |||
332 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
333 | if (!res) | ||
334 | return -ENODEV; | ||
335 | priv = kzalloc(sizeof(struct ds1286_priv), GFP_KERNEL); | ||
336 | if (!priv) | ||
337 | return -ENOMEM; | ||
338 | |||
339 | priv->size = res->end - res->start + 1; | ||
340 | if (!request_mem_region(res->start, priv->size, pdev->name)) { | ||
341 | ret = -EBUSY; | ||
342 | goto out; | ||
343 | } | ||
344 | priv->baseaddr = res->start; | ||
345 | priv->rtcregs = ioremap(priv->baseaddr, priv->size); | ||
346 | if (!priv->rtcregs) { | ||
347 | ret = -ENOMEM; | ||
348 | goto out; | ||
349 | } | ||
350 | spin_lock_init(&priv->lock); | ||
351 | rtc = rtc_device_register("ds1286", &pdev->dev, | ||
352 | &ds1286_ops, THIS_MODULE); | ||
353 | if (IS_ERR(rtc)) { | ||
354 | ret = PTR_ERR(rtc); | ||
355 | goto out; | ||
356 | } | ||
357 | priv->rtc = rtc; | ||
358 | platform_set_drvdata(pdev, priv); | ||
359 | return 0; | ||
360 | |||
361 | out: | ||
362 | if (priv->rtc) | ||
363 | rtc_device_unregister(priv->rtc); | ||
364 | if (priv->rtcregs) | ||
365 | iounmap(priv->rtcregs); | ||
366 | if (priv->baseaddr) | ||
367 | release_mem_region(priv->baseaddr, priv->size); | ||
368 | kfree(priv); | ||
369 | return ret; | ||
370 | } | ||
371 | |||
372 | static int __devexit ds1286_remove(struct platform_device *pdev) | ||
373 | { | ||
374 | struct ds1286_priv *priv = platform_get_drvdata(pdev); | ||
375 | |||
376 | rtc_device_unregister(priv->rtc); | ||
377 | iounmap(priv->rtcregs); | ||
378 | release_mem_region(priv->baseaddr, priv->size); | ||
379 | kfree(priv); | ||
380 | return 0; | ||
381 | } | ||
382 | |||
383 | static struct platform_driver ds1286_platform_driver = { | ||
384 | .driver = { | ||
385 | .name = "rtc-ds1286", | ||
386 | .owner = THIS_MODULE, | ||
387 | }, | ||
388 | .probe = ds1286_probe, | ||
389 | .remove = __devexit_p(ds1286_remove), | ||
390 | }; | ||
391 | |||
392 | static int __init ds1286_init(void) | ||
393 | { | ||
394 | return platform_driver_register(&ds1286_platform_driver); | ||
395 | } | ||
396 | |||
397 | static void __exit ds1286_exit(void) | ||
398 | { | ||
399 | platform_driver_unregister(&ds1286_platform_driver); | ||
400 | } | ||
401 | |||
402 | MODULE_AUTHOR("Thomas Bogendoerfer <tsbogend@alpha.franken.de>"); | ||
403 | MODULE_DESCRIPTION("DS1286 RTC driver"); | ||
404 | MODULE_LICENSE("GPL"); | ||
405 | MODULE_VERSION(DRV_VERSION); | ||
406 | MODULE_ALIAS("platform:rtc-ds1286"); | ||
407 | |||
408 | module_init(ds1286_init); | ||
409 | module_exit(ds1286_exit); | ||
diff --git a/drivers/rtc/rtc-m48t35.c b/drivers/rtc/rtc-m48t35.c new file mode 100644 index 000000000000..b9c1fe4a198e --- /dev/null +++ b/drivers/rtc/rtc-m48t35.c | |||
@@ -0,0 +1,234 @@ | |||
1 | /* | ||
2 | * Driver for the SGS-Thomson M48T35 Timekeeper RAM chip | ||
3 | * | ||
4 | * Copyright (C) 2000 Silicon Graphics, Inc. | ||
5 | * Written by Ulf Carlsson (ulfc@engr.sgi.com) | ||
6 | * | ||
7 | * Copyright (C) 2008 Thomas Bogendoerfer | ||
8 | * | ||
9 | * Based on code written by Paul Gortmaker. | ||
10 | * | ||
11 | * This program is free software; you can redistribute it and/or modify it | ||
12 | * under the terms of the GNU General Public License as published by the | ||
13 | * Free Software Foundation; either version 2 of the License, or (at your | ||
14 | * option) any later version. | ||
15 | */ | ||
16 | |||
17 | #include <linux/module.h> | ||
18 | #include <linux/rtc.h> | ||
19 | #include <linux/platform_device.h> | ||
20 | #include <linux/bcd.h> | ||
21 | |||
22 | #define DRV_VERSION "1.0" | ||
23 | |||
24 | struct m48t35_rtc { | ||
25 | u8 pad[0x7ff8]; /* starts at 0x7ff8 */ | ||
26 | u8 control; | ||
27 | u8 sec; | ||
28 | u8 min; | ||
29 | u8 hour; | ||
30 | u8 day; | ||
31 | u8 date; | ||
32 | u8 month; | ||
33 | u8 year; | ||
34 | }; | ||
35 | |||
36 | #define M48T35_RTC_SET 0x80 | ||
37 | #define M48T35_RTC_READ 0x40 | ||
38 | |||
39 | struct m48t35_priv { | ||
40 | struct rtc_device *rtc; | ||
41 | struct m48t35_rtc __iomem *reg; | ||
42 | size_t size; | ||
43 | unsigned long baseaddr; | ||
44 | spinlock_t lock; | ||
45 | }; | ||
46 | |||
47 | static int m48t35_read_time(struct device *dev, struct rtc_time *tm) | ||
48 | { | ||
49 | struct m48t35_priv *priv = dev_get_drvdata(dev); | ||
50 | u8 control; | ||
51 | |||
52 | /* | ||
53 | * Only the values that we read from the RTC are set. We leave | ||
54 | * tm_wday, tm_yday and tm_isdst untouched. Even though the | ||
55 | * RTC has RTC_DAY_OF_WEEK, we ignore it, as it is only updated | ||
56 | * by the RTC when initially set to a non-zero value. | ||
57 | */ | ||
58 | spin_lock_irq(&priv->lock); | ||
59 | control = readb(&priv->reg->control); | ||
60 | writeb(control | M48T35_RTC_READ, &priv->reg->control); | ||
61 | tm->tm_sec = readb(&priv->reg->sec); | ||
62 | tm->tm_min = readb(&priv->reg->min); | ||
63 | tm->tm_hour = readb(&priv->reg->hour); | ||
64 | tm->tm_mday = readb(&priv->reg->date); | ||
65 | tm->tm_mon = readb(&priv->reg->month); | ||
66 | tm->tm_year = readb(&priv->reg->year); | ||
67 | writeb(control, &priv->reg->control); | ||
68 | spin_unlock_irq(&priv->lock); | ||
69 | |||
70 | tm->tm_sec = bcd2bin(tm->tm_sec); | ||
71 | tm->tm_min = bcd2bin(tm->tm_min); | ||
72 | tm->tm_hour = bcd2bin(tm->tm_hour); | ||
73 | tm->tm_mday = bcd2bin(tm->tm_mday); | ||
74 | tm->tm_mon = bcd2bin(tm->tm_mon); | ||
75 | tm->tm_year = bcd2bin(tm->tm_year); | ||
76 | |||
77 | /* | ||
78 | * Account for differences between how the RTC uses the values | ||
79 | * and how they are defined in a struct rtc_time; | ||
80 | */ | ||
81 | tm->tm_year += 70; | ||
82 | if (tm->tm_year <= 69) | ||
83 | tm->tm_year += 100; | ||
84 | |||
85 | tm->tm_mon--; | ||
86 | return rtc_valid_tm(tm); | ||
87 | } | ||
88 | |||
89 | static int m48t35_set_time(struct device *dev, struct rtc_time *tm) | ||
90 | { | ||
91 | struct m48t35_priv *priv = dev_get_drvdata(dev); | ||
92 | unsigned char mon, day, hrs, min, sec; | ||
93 | unsigned int yrs; | ||
94 | u8 control; | ||
95 | |||
96 | yrs = tm->tm_year + 1900; | ||
97 | mon = tm->tm_mon + 1; /* tm_mon starts at zero */ | ||
98 | day = tm->tm_mday; | ||
99 | hrs = tm->tm_hour; | ||
100 | min = tm->tm_min; | ||
101 | sec = tm->tm_sec; | ||
102 | |||
103 | if (yrs < 1970) | ||
104 | return -EINVAL; | ||
105 | |||
106 | yrs -= 1970; | ||
107 | if (yrs > 255) /* They are unsigned */ | ||
108 | return -EINVAL; | ||
109 | |||
110 | if (yrs > 169) | ||
111 | return -EINVAL; | ||
112 | |||
113 | if (yrs >= 100) | ||
114 | yrs -= 100; | ||
115 | |||
116 | sec = bin2bcd(sec); | ||
117 | min = bin2bcd(min); | ||
118 | hrs = bin2bcd(hrs); | ||
119 | day = bin2bcd(day); | ||
120 | mon = bin2bcd(mon); | ||
121 | yrs = bin2bcd(yrs); | ||
122 | |||
123 | spin_lock_irq(&priv->lock); | ||
124 | control = readb(&priv->reg->control); | ||
125 | writeb(control | M48T35_RTC_SET, &priv->reg->control); | ||
126 | writeb(yrs, &priv->reg->year); | ||
127 | writeb(mon, &priv->reg->month); | ||
128 | writeb(day, &priv->reg->date); | ||
129 | writeb(hrs, &priv->reg->hour); | ||
130 | writeb(min, &priv->reg->min); | ||
131 | writeb(sec, &priv->reg->sec); | ||
132 | writeb(control, &priv->reg->control); | ||
133 | spin_unlock_irq(&priv->lock); | ||
134 | return 0; | ||
135 | } | ||
136 | |||
137 | static const struct rtc_class_ops m48t35_ops = { | ||
138 | .read_time = m48t35_read_time, | ||
139 | .set_time = m48t35_set_time, | ||
140 | }; | ||
141 | |||
142 | static int __devinit m48t35_probe(struct platform_device *pdev) | ||
143 | { | ||
144 | struct rtc_device *rtc; | ||
145 | struct resource *res; | ||
146 | struct m48t35_priv *priv; | ||
147 | int ret = 0; | ||
148 | |||
149 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
150 | if (!res) | ||
151 | return -ENODEV; | ||
152 | priv = kzalloc(sizeof(struct m48t35_priv), GFP_KERNEL); | ||
153 | if (!priv) | ||
154 | return -ENOMEM; | ||
155 | |||
156 | priv->size = res->end - res->start + 1; | ||
157 | /* | ||
158 | * kludge: remove the #ifndef after ioc3 resource | ||
159 | * conflicts are resolved | ||
160 | */ | ||
161 | #ifndef CONFIG_SGI_IP27 | ||
162 | if (!request_mem_region(res->start, priv->size, pdev->name)) { | ||
163 | ret = -EBUSY; | ||
164 | goto out; | ||
165 | } | ||
166 | #endif | ||
167 | priv->baseaddr = res->start; | ||
168 | priv->reg = ioremap(priv->baseaddr, priv->size); | ||
169 | if (!priv->reg) { | ||
170 | ret = -ENOMEM; | ||
171 | goto out; | ||
172 | } | ||
173 | spin_lock_init(&priv->lock); | ||
174 | rtc = rtc_device_register("m48t35", &pdev->dev, | ||
175 | &m48t35_ops, THIS_MODULE); | ||
176 | if (IS_ERR(rtc)) { | ||
177 | ret = PTR_ERR(rtc); | ||
178 | goto out; | ||
179 | } | ||
180 | priv->rtc = rtc; | ||
181 | platform_set_drvdata(pdev, priv); | ||
182 | return 0; | ||
183 | |||
184 | out: | ||
185 | if (priv->rtc) | ||
186 | rtc_device_unregister(priv->rtc); | ||
187 | if (priv->reg) | ||
188 | iounmap(priv->reg); | ||
189 | if (priv->baseaddr) | ||
190 | release_mem_region(priv->baseaddr, priv->size); | ||
191 | kfree(priv); | ||
192 | return ret; | ||
193 | } | ||
194 | |||
195 | static int __devexit m48t35_remove(struct platform_device *pdev) | ||
196 | { | ||
197 | struct m48t35_priv *priv = platform_get_drvdata(pdev); | ||
198 | |||
199 | rtc_device_unregister(priv->rtc); | ||
200 | iounmap(priv->reg); | ||
201 | #ifndef CONFIG_SGI_IP27 | ||
202 | release_mem_region(priv->baseaddr, priv->size); | ||
203 | #endif | ||
204 | kfree(priv); | ||
205 | return 0; | ||
206 | } | ||
207 | |||
208 | static struct platform_driver m48t35_platform_driver = { | ||
209 | .driver = { | ||
210 | .name = "rtc-m48t35", | ||
211 | .owner = THIS_MODULE, | ||
212 | }, | ||
213 | .probe = m48t35_probe, | ||
214 | .remove = __devexit_p(m48t35_remove), | ||
215 | }; | ||
216 | |||
217 | static int __init m48t35_init(void) | ||
218 | { | ||
219 | return platform_driver_register(&m48t35_platform_driver); | ||
220 | } | ||
221 | |||
222 | static void __exit m48t35_exit(void) | ||
223 | { | ||
224 | platform_driver_unregister(&m48t35_platform_driver); | ||
225 | } | ||
226 | |||
227 | MODULE_AUTHOR("Thomas Bogendoerfer <tsbogend@alpha.franken.de>"); | ||
228 | MODULE_DESCRIPTION("M48T35 RTC driver"); | ||
229 | MODULE_LICENSE("GPL"); | ||
230 | MODULE_VERSION(DRV_VERSION); | ||
231 | MODULE_ALIAS("platform:rtc-m48t35"); | ||
232 | |||
233 | module_init(m48t35_init); | ||
234 | module_exit(m48t35_exit); | ||
diff --git a/include/linux/ds1286.h b/include/linux/ds1286.h index d8989860e4ce..45ea0aa0aeb9 100644 --- a/include/linux/ds1286.h +++ b/include/linux/ds1286.h | |||
@@ -8,8 +8,6 @@ | |||
8 | #ifndef __LINUX_DS1286_H | 8 | #ifndef __LINUX_DS1286_H |
9 | #define __LINUX_DS1286_H | 9 | #define __LINUX_DS1286_H |
10 | 10 | ||
11 | #include <asm/ds1286.h> | ||
12 | |||
13 | /********************************************************************** | 11 | /********************************************************************** |
14 | * register summary | 12 | * register summary |
15 | **********************************************************************/ | 13 | **********************************************************************/ |