1/* 2 * Copyright 2008 Sascha Hauer, kernel@pengutronix.de 3 * 4 * This program is free software; you can redistribute it and/or 5 * modify it under the terms of the GNU General Public License 6 * as published by the Free Software Foundation; either version 2 7 * of the License, or (at your option) any later version. 8 * This program is distributed in the hope that it will be useful, 9 * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 * GNU General Public License for more details. 12 * 13 * You should have received a copy of the GNU General Public License 14 * along with this program; if not, write to the Free Software 15 * Foundation, Inc., 51 Franklin Street, Fifth Floor, 16 * Boston, MA 02110-1301, USA. 17 */ 18 19#include <linux/kernel.h> 20#include <linux/slab.h> 21#include <linux/init.h> 22#include <linux/platform_device.h> 23#include <linux/amba/bus.h> 24 25struct platform_device *__init mxs_add_platform_device_dmamask( 26 const char *name, int id, 27 const struct resource *res, unsigned int num_resources, 28 const void *data, size_t size_data, u64 dmamask) 29{ 30 int ret = -ENOMEM; 31 struct platform_device *pdev; 32 33 pdev = platform_device_alloc(name, id); 34 if (!pdev) 35 goto err; 36 37 if (dmamask) { 38 /* 39 * This memory isn't freed when the device is put, 40 * I don't have a nice idea for that though. Conceptually 41 * dma_mask in struct device should not be a pointer. 42 * See http://thread.gmane.org/gmane.linux.kernel.pci/9081 43 */ 44 pdev->dev.dma_mask = 45 kmalloc(sizeof(*pdev->dev.dma_mask), GFP_KERNEL); 46 if (!pdev->dev.dma_mask) 47 /* ret is still -ENOMEM; */ 48 goto err; 49 50 *pdev->dev.dma_mask = dmamask; 51 pdev->dev.coherent_dma_mask = dmamask; 52 } 53 54 if (res) { 55 ret = platform_device_add_resources(pdev, res, num_resources); 56 if (ret) 57 goto err; 58 } 59 60 if (data) { 61 ret = platform_device_add_data(pdev, data, size_data); 62 if (ret) 63 goto err; 64 } 65 66 ret = platform_device_add(pdev); 67 if (ret) { 68err: 69 if (dmamask) 70 kfree(pdev->dev.dma_mask); 71 platform_device_put(pdev); 72 return ERR_PTR(ret); 73 } 74 75 return pdev; 76} 77 78int __init mxs_add_amba_device(const struct amba_device *dev) 79{ 80 struct amba_device *adev = amba_device_alloc(dev->dev.init_name, 81 dev->res.start, resource_size(&dev->res)); 82 83 if (!adev) { 84 pr_err("%s: failed to allocate memory", __func__); 85 return -ENOMEM; 86 } 87 88 adev->irq[0] = dev->irq[0]; 89 adev->irq[1] = dev->irq[1]; 90 91 return amba_device_add(adev, &iomem_resource); 92} 93 94struct device mxs_apbh_bus = { 95 .init_name = "mxs_apbh", 96 .parent = &platform_bus, 97}; 98 99static int __init mxs_device_init(void) 100{ 101 return device_register(&mxs_apbh_bus); 102} 103core_initcall(mxs_device_init); 104