/* * arch/arm/mach-ns9xxx/plat-uio.c * * Copyright (C) 2008 by Digi International Inc. * All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published by * the Free Software Foundation. */ #include #include #include #include #include "clock.h" #define DRIVER_NAME "uio" struct ns9xxx_uio_platdata { struct uio_info uioinfo; struct clk clk; }; static struct platform_device *__init ns9xxx_plat_uio_alloc( struct ns9xxx_uio_platdata **pdata) { struct platform_device *pdev; static int id; BUG_ON(!pdata); pdev = platform_device_alloc(DRIVER_NAME, id); if (!pdev) goto err; *pdata = kzalloc(sizeof(**pdata), GFP_KERNEL); if (!*pdata) { err: platform_device_put(pdev); return ERR_PTR(-ENOMEM); } (*pdata)->clk.owner = THIS_MODULE; (*pdata)->clk.name = DRIVER_NAME; (*pdata)->clk.id = id; pdev->dev.platform_data = *pdata; ++id; return pdev; } static int __init ns9xxx_plat_uio_inc20otter_init(void) { struct ns9xxx_uio_platdata *uninitialized_var(pdata); struct platform_device *pdev = ns9xxx_plat_uio_alloc(&pdata); struct resource res[] = { { .start = 0x70000000, .end = 0x70001fff, .flags = IORESOURCE_MEM, }, { .start = 0xa0700000, .end = 0xa070027b, .flags = IORESOURCE_MEM, } }; int ret; if (IS_ERR(pdev)) { ret = PTR_ERR(pdev); pr_debug("%s: err_alloc_pdev -> %d\n", __func__, ret); goto err_alloc_pdev; } ret = platform_device_add_resources(pdev, res, ARRAY_SIZE(res)); if (ret) { pr_debug("%s: err_add_resources -> %d\n", __func__, ret); goto err_add_resources; } ret = clk_register(&pdata->clk); if (ret) { pr_debug("%s: err_clk_register -> %d", __func__, ret); goto err_clk_register; } pdata->uioinfo.name = "inc20otter CS3"; pdata->uioinfo.version = "0.0a"; pdata->uioinfo.irq = UIO_IRQ_NONE; ret = platform_device_add(pdev); if (ret) { clk_unregister(&pdata->clk); err_clk_register: err_add_resources: /* this kfrees pdata, too */ platform_device_put(pdev); err_alloc_pdev: return ret; } return 0; } static int __init ns9xxx_plat_uio_init(void) { if (machine_is_inc20otter()) ns9xxx_plat_uio_inc20otter_init(); return 0; } arch_initcall(ns9xxx_plat_uio_init);