dt/sparc: Eliminate users of of_platform_{,un}register_driver
[linux-3.10.git] / arch / sparc / kernel / apc.c
index 6707422..f679c57 100644 (file)
 #include <linux/errno.h>
 #include <linux/init.h>
 #include <linux/miscdevice.h>
-#include <linux/smp_lock.h>
 #include <linux/pm.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
 
 #include <asm/io.h>
-#include <asm/sbus.h>
 #include <asm/oplib.h>
 #include <asm/uaccess.h>
 #include <asm/auxio.h>
 #define APC_OBPNAME    "power-management"
 #define APC_DEVNAME "apc"
 
-volatile static u8 __iomem *regs; 
-static int apc_regsize;
-static int apc_no_idle __initdata = 0;
+static u8 __iomem *regs;
+static int apc_no_idle __devinitdata = 0;
 
-#define apc_readb(offs)                        (sbus_readb(regs+offs))
+#define apc_readb(offs)                (sbus_readb(regs+offs))
 #define apc_writeb(val, offs)  (sbus_writeb(val, regs+offs))
 
 /* Specify "apc=noidle" on the kernel command line to 
@@ -56,7 +55,7 @@ __setup("apc=", apc_setup);
  * CPU idle callback function
  * See .../arch/sparc/kernel/process.c
  */
-void apc_swift_idle(void)
+static void apc_swift_idle(void)
 {
 #ifdef APC_DEBUG_LED
        set_auxio(0x00, AUXIO_LED); 
@@ -69,14 +68,13 @@ void apc_swift_idle(void)
 #endif
 } 
 
-static inline void apc_free(void)
+static inline void apc_free(struct platform_device *op)
 {
-       sbus_iounmap(regs, apc_regsize);
+       of_iounmap(&op->resource[0], regs, resource_size(&op->resource[0]));
 }
 
 static int apc_open(struct inode *inode, struct file *f)
 {
-       cycle_kernel_lock();
        return 0;
 }
 
@@ -85,16 +83,14 @@ static int apc_release(struct inode *inode, struct file *f)
        return 0;
 }
 
-static int apc_ioctl(struct inode *inode, struct file *f, 
-                    unsigned int cmd, unsigned long __arg)
+static long apc_ioctl(struct file *f, unsigned int cmd, unsigned long __arg)
 {
-       __u8 inarg, __user *arg;
+       __u8 inarg, __user *arg = (__u8 __user *) __arg;
 
-       arg = (__u8 __user *) __arg;
        switch (cmd) {
        case APCIOCGFANCTL:
                if (put_user(apc_readb(APC_FANCTL_REG) & APC_REGMASK, arg))
-                               return -EFAULT;
+                       return -EFAULT;
                break;
 
        case APCIOCGCPWR:
@@ -112,16 +108,19 @@ static int apc_ioctl(struct inode *inode, struct file *f,
                        return -EFAULT;
                apc_writeb(inarg & APC_REGMASK, APC_FANCTL_REG);
                break;
+
        case APCIOCSCPWR:
                if (get_user(inarg, arg))
                        return -EFAULT;
                apc_writeb(inarg & APC_REGMASK, APC_CPOWER_REG);
                break;
+
        case APCIOCSBPORT:
                if (get_user(inarg, arg))
                        return -EFAULT;
                apc_writeb(inarg & APC_BPMASK, APC_BPORT_REG);
                break;
+
        default:
                return -EINVAL;
        };
@@ -130,59 +129,66 @@ static int apc_ioctl(struct inode *inode, struct file *f,
 }
 
 static const struct file_operations apc_fops = {
-       .ioctl =        apc_ioctl,
-       .open =         apc_open,
-       .release =      apc_release,
+       .unlocked_ioctl =       apc_ioctl,
+       .open =                 apc_open,
+       .release =              apc_release,
+       .llseek =               noop_llseek,
 };
 
 static struct miscdevice apc_miscdev = { APC_MINOR, APC_DEVNAME, &apc_fops };
 
-static int __init apc_probe(void)
+static int __devinit apc_probe(struct platform_device *op)
 {
-       struct sbus_bus *sbus = NULL;
-       struct sbus_dev *sdev = NULL;
-       int iTmp = 0;
-
-       for_each_sbus(sbus) {
-               for_each_sbusdev(sdev, sbus) {
-                       if (!strcmp(sdev->prom_name, APC_OBPNAME)) {
-                               goto sbus_done;
-                       }
-               }
-       }
-
-sbus_done:
-       if (!sdev) {
-               return -ENODEV;
-       }
+       int err;
 
-       apc_regsize = sdev->reg_addrs[0].reg_size;
-       regs = sbus_ioremap(&sdev->resource[0], 0, 
-                                  apc_regsize, APC_OBPNAME);
-       if(!regs) {
+       regs = of_ioremap(&op->resource[0], 0,
+                         resource_size(&op->resource[0]), APC_OBPNAME);
+       if (!regs) {
                printk(KERN_ERR "%s: unable to map registers\n", APC_DEVNAME);
                return -ENODEV;
        }
 
-       iTmp = misc_register(&apc_miscdev);
-       if (iTmp != 0) {
+       err = misc_register(&apc_miscdev);
+       if (err) {
                printk(KERN_ERR "%s: unable to register device\n", APC_DEVNAME);
-               apc_free();
+               apc_free(op);
                return -ENODEV;
        }
 
        /* Assign power management IDLE handler */
-       if(!apc_no_idle)
+       if (!apc_no_idle)
                pm_idle = apc_swift_idle;       
 
        printk(KERN_INFO "%s: power management initialized%s\n", 
-               APC_DEVNAME, apc_no_idle ? " (CPU idle disabled)" : "");
+              APC_DEVNAME, apc_no_idle ? " (CPU idle disabled)" : "");
+
        return 0;
 }
 
+static struct of_device_id __initdata apc_match[] = {
+       {
+               .name = APC_OBPNAME,
+       },
+       {},
+};
+MODULE_DEVICE_TABLE(of, apc_match);
+
+static struct platform_driver apc_driver = {
+       .driver = {
+               .name = "apc",
+               .owner = THIS_MODULE,
+               .of_match_table = apc_match,
+       },
+       .probe          = apc_probe,
+};
+
+static int __init apc_init(void)
+{
+       return platform_driver_register(&apc_driver);
+}
+
 /* This driver is not critical to the boot process
  * and is easiest to ioremap when SBus is already
  * initialized, so we install ourselves thusly:
  */
-__initcall(apc_probe);
-
+__initcall(apc_init);