Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /* pmc - Driver implementation for power management functions
0003  * of Power Management Controller (PMC) on SPARCstation-Voyager.
0004  *
0005  * Copyright (c) 2002 Eric Brower (ebrower@usa.net)
0006  */
0007 
0008 #include <linux/kernel.h>
0009 #include <linux/fs.h>
0010 #include <linux/errno.h>
0011 #include <linux/init.h>
0012 #include <linux/pm.h>
0013 #include <linux/of.h>
0014 #include <linux/of_device.h>
0015 #include <linux/module.h>
0016 
0017 #include <asm/io.h>
0018 #include <asm/oplib.h>
0019 #include <linux/uaccess.h>
0020 #include <asm/auxio.h>
0021 #include <asm/processor.h>
0022 
0023 /* Debug
0024  *
0025  * #define PMC_DEBUG_LED
0026  * #define PMC_NO_IDLE
0027  */
0028 
0029 #define PMC_OBPNAME "SUNW,pmc"
0030 #define PMC_DEVNAME "pmc"
0031 
0032 #define PMC_IDLE_REG    0x00
0033 #define PMC_IDLE_ON 0x01
0034 
0035 static u8 __iomem *regs;
0036 
0037 #define pmc_readb(offs)     (sbus_readb(regs+offs))
0038 #define pmc_writeb(val, offs)   (sbus_writeb(val, regs+offs))
0039 
0040 /*
0041  * CPU idle callback function
0042  * See .../arch/sparc/kernel/process.c
0043  */
0044 static void pmc_swift_idle(void)
0045 {
0046 #ifdef PMC_DEBUG_LED
0047     set_auxio(0x00, AUXIO_LED);
0048 #endif
0049 
0050     pmc_writeb(pmc_readb(PMC_IDLE_REG) | PMC_IDLE_ON, PMC_IDLE_REG);
0051 
0052 #ifdef PMC_DEBUG_LED
0053     set_auxio(AUXIO_LED, 0x00);
0054 #endif
0055 }
0056 
0057 static int pmc_probe(struct platform_device *op)
0058 {
0059     regs = of_ioremap(&op->resource[0], 0,
0060               resource_size(&op->resource[0]), PMC_OBPNAME);
0061     if (!regs) {
0062         printk(KERN_ERR "%s: unable to map registers\n", PMC_DEVNAME);
0063         return -ENODEV;
0064     }
0065 
0066 #ifndef PMC_NO_IDLE
0067     /* Assign power management IDLE handler */
0068     sparc_idle = pmc_swift_idle;
0069 #endif
0070 
0071     printk(KERN_INFO "%s: power management initialized\n", PMC_DEVNAME);
0072     return 0;
0073 }
0074 
0075 static const struct of_device_id pmc_match[] = {
0076     {
0077         .name = PMC_OBPNAME,
0078     },
0079     {},
0080 };
0081 MODULE_DEVICE_TABLE(of, pmc_match);
0082 
0083 static struct platform_driver pmc_driver = {
0084     .driver = {
0085         .name = "pmc",
0086         .of_match_table = pmc_match,
0087     },
0088     .probe      = pmc_probe,
0089 };
0090 
0091 static int __init pmc_init(void)
0092 {
0093     return platform_driver_register(&pmc_driver);
0094 }
0095 
0096 /* This driver is not critical to the boot process
0097  * and is easiest to ioremap when SBus is already
0098  * initialized, so we install ourselves thusly:
0099  */
0100 __initcall(pmc_init);