diff options
Diffstat (limited to 'arch/sparc/kernel/time.c')
| -rw-r--r-- | arch/sparc/kernel/time.c | 109 |
1 files changed, 40 insertions, 69 deletions
diff --git a/arch/sparc/kernel/time.c b/arch/sparc/kernel/time.c index 7dadcdb4ca42..9631e8f4ae60 100644 --- a/arch/sparc/kernel/time.c +++ b/arch/sparc/kernel/time.c | |||
| @@ -42,6 +42,7 @@ | |||
| 42 | #include <asm/sun4paddr.h> | 42 | #include <asm/sun4paddr.h> |
| 43 | #include <asm/page.h> | 43 | #include <asm/page.h> |
| 44 | #include <asm/pcic.h> | 44 | #include <asm/pcic.h> |
| 45 | #include <asm/of_device.h> | ||
| 45 | 46 | ||
| 46 | extern unsigned long wall_jiffies; | 47 | extern unsigned long wall_jiffies; |
| 47 | 48 | ||
| @@ -273,83 +274,31 @@ static __inline__ void sun4_clock_probe(void) | |||
| 273 | #endif | 274 | #endif |
| 274 | } | 275 | } |
| 275 | 276 | ||
| 276 | /* Probe for the mostek real time clock chip. */ | 277 | static int __devinit clock_probe(struct of_device *op, const struct of_device_id *match) |
| 277 | static __inline__ void clock_probe(void) | ||
| 278 | { | 278 | { |
| 279 | struct linux_prom_registers clk_reg[2]; | 279 | struct device_node *dp = op->node; |
| 280 | char model[128]; | 280 | char *model = of_get_property(dp, "model", NULL); |
| 281 | register int node, cpuunit, bootbus; | ||
| 282 | struct resource r; | ||
| 283 | |||
| 284 | cpuunit = bootbus = 0; | ||
| 285 | memset(&r, 0, sizeof(r)); | ||
| 286 | |||
| 287 | /* Determine the correct starting PROM node for the probe. */ | ||
| 288 | node = prom_getchild(prom_root_node); | ||
| 289 | switch (sparc_cpu_model) { | ||
| 290 | case sun4c: | ||
| 291 | break; | ||
| 292 | case sun4m: | ||
| 293 | node = prom_getchild(prom_searchsiblings(node, "obio")); | ||
| 294 | break; | ||
| 295 | case sun4d: | ||
| 296 | node = prom_getchild(bootbus = prom_searchsiblings(prom_getchild(cpuunit = prom_searchsiblings(node, "cpu-unit")), "bootbus")); | ||
| 297 | break; | ||
| 298 | default: | ||
| 299 | prom_printf("CLOCK: Unsupported architecture!\n"); | ||
| 300 | prom_halt(); | ||
| 301 | } | ||
| 302 | 281 | ||
| 303 | /* Find the PROM node describing the real time clock. */ | 282 | if (!model) |
| 304 | sp_clock_typ = MSTK_INVALID; | 283 | return -ENODEV; |
| 305 | node = prom_searchsiblings(node,"eeprom"); | ||
| 306 | if (!node) { | ||
| 307 | prom_printf("CLOCK: No clock found!\n"); | ||
| 308 | prom_halt(); | ||
| 309 | } | ||
| 310 | 284 | ||
| 311 | /* Get the model name and setup everything up. */ | 285 | if (!strcmp(model, "mk48t02")) { |
| 312 | model[0] = '\0'; | ||
| 313 | prom_getstring(node, "model", model, sizeof(model)); | ||
| 314 | if (strcmp(model, "mk48t02") == 0) { | ||
| 315 | sp_clock_typ = MSTK48T02; | 286 | sp_clock_typ = MSTK48T02; |
| 316 | if (prom_getproperty(node, "reg", (char *) clk_reg, sizeof(clk_reg)) == -1) { | 287 | |
| 317 | prom_printf("clock_probe: FAILED!\n"); | ||
| 318 | prom_halt(); | ||
| 319 | } | ||
| 320 | if (sparc_cpu_model == sun4d) | ||
| 321 | prom_apply_generic_ranges (bootbus, cpuunit, clk_reg, 1); | ||
| 322 | else | ||
| 323 | prom_apply_obio_ranges(clk_reg, 1); | ||
| 324 | /* Map the clock register io area read-only */ | 288 | /* Map the clock register io area read-only */ |
| 325 | r.flags = clk_reg[0].which_io; | 289 | mstk48t02_regs = of_ioremap(&op->resource[0], 0, |
| 326 | r.start = clk_reg[0].phys_addr; | 290 | sizeof(struct mostek48t02), |
| 327 | mstk48t02_regs = sbus_ioremap(&r, 0, | 291 | "mk48t02"); |
| 328 | sizeof(struct mostek48t02), "mk48t02"); | ||
| 329 | mstk48t08_regs = NULL; /* To catch weirdness */ | 292 | mstk48t08_regs = NULL; /* To catch weirdness */ |
| 330 | } else if (strcmp(model, "mk48t08") == 0) { | 293 | } else if (!strcmp(model, "mk48t08")) { |
| 331 | sp_clock_typ = MSTK48T08; | 294 | sp_clock_typ = MSTK48T08; |
| 332 | if(prom_getproperty(node, "reg", (char *) clk_reg, | 295 | mstk48t08_regs = of_ioremap(&op->resource[0], 0, |
| 333 | sizeof(clk_reg)) == -1) { | 296 | sizeof(struct mostek48t08), |
| 334 | prom_printf("clock_probe: FAILED!\n"); | 297 | "mk48t08"); |
| 335 | prom_halt(); | ||
| 336 | } | ||
| 337 | if (sparc_cpu_model == sun4d) | ||
| 338 | prom_apply_generic_ranges (bootbus, cpuunit, clk_reg, 1); | ||
| 339 | else | ||
| 340 | prom_apply_obio_ranges(clk_reg, 1); | ||
| 341 | /* Map the clock register io area read-only */ | ||
| 342 | /* XXX r/o attribute is somewhere in r.flags */ | ||
| 343 | r.flags = clk_reg[0].which_io; | ||
| 344 | r.start = clk_reg[0].phys_addr; | ||
| 345 | mstk48t08_regs = sbus_ioremap(&r, 0, | ||
| 346 | sizeof(struct mostek48t08), "mk48t08"); | ||
| 347 | 298 | ||
| 348 | mstk48t02_regs = &mstk48t08_regs->regs; | 299 | mstk48t02_regs = &mstk48t08_regs->regs; |
| 349 | } else { | 300 | } else |
| 350 | prom_printf("CLOCK: Unknown model name '%s'\n",model); | 301 | return -ENODEV; |
| 351 | prom_halt(); | ||
| 352 | } | ||
| 353 | 302 | ||
| 354 | /* Report a low battery voltage condition. */ | 303 | /* Report a low battery voltage condition. */ |
| 355 | if (has_low_battery()) | 304 | if (has_low_battery()) |
| @@ -358,6 +307,28 @@ static __inline__ void clock_probe(void) | |||
| 358 | /* Kick start the clock if it is completely stopped. */ | 307 | /* Kick start the clock if it is completely stopped. */ |
| 359 | if (mostek_read(mstk48t02_regs + MOSTEK_SEC) & MSTK_STOP) | 308 | if (mostek_read(mstk48t02_regs + MOSTEK_SEC) & MSTK_STOP) |
| 360 | kick_start_clock(); | 309 | kick_start_clock(); |
| 310 | |||
| 311 | return 0; | ||
| 312 | } | ||
| 313 | |||
| 314 | static struct of_device_id clock_match[] = { | ||
| 315 | { | ||
| 316 | .name = "eeprom", | ||
| 317 | }, | ||
| 318 | {}, | ||
| 319 | }; | ||
| 320 | |||
| 321 | static struct of_platform_driver clock_driver = { | ||
| 322 | .name = "clock", | ||
| 323 | .match_table = clock_match, | ||
| 324 | .probe = clock_probe, | ||
| 325 | }; | ||
| 326 | |||
| 327 | |||
| 328 | /* Probe for the mostek real time clock chip. */ | ||
| 329 | static void clock_init(void) | ||
| 330 | { | ||
| 331 | of_register_driver(&clock_driver, &of_bus_type); | ||
| 361 | } | 332 | } |
| 362 | 333 | ||
| 363 | void __init sbus_time_init(void) | 334 | void __init sbus_time_init(void) |
| @@ -376,7 +347,7 @@ void __init sbus_time_init(void) | |||
| 376 | if (ARCH_SUN4) | 347 | if (ARCH_SUN4) |
| 377 | sun4_clock_probe(); | 348 | sun4_clock_probe(); |
| 378 | else | 349 | else |
| 379 | clock_probe(); | 350 | clock_init(); |
| 380 | 351 | ||
| 381 | sparc_init_timers(timer_interrupt); | 352 | sparc_init_timers(timer_interrupt); |
| 382 | 353 | ||
