Back to home page

OSCL-LXR

 
 

    


0001 /*
0002  * IBM PowerPC IBM eBus Infrastructure Support.
0003  *
0004  * Copyright (c) 2005 IBM Corporation
0005  *  Joachim Fenkes <fenkes@de.ibm.com>
0006  *  Heiko J Schick <schickhj@de.ibm.com>
0007  *
0008  * All rights reserved.
0009  *
0010  * This source code is distributed under a dual license of GPL v2.0 and OpenIB
0011  * BSD.
0012  *
0013  * OpenIB BSD License
0014  *
0015  * Redistribution and use in source and binary forms, with or without
0016  * modification, are permitted provided that the following conditions are met:
0017  *
0018  * Redistributions of source code must retain the above copyright notice, this
0019  * list of conditions and the following disclaimer.
0020  *
0021  * Redistributions in binary form must reproduce the above copyright notice,
0022  * this list of conditions and the following disclaimer in the documentation
0023  * and/or other materials
0024  * provided with the distribution.
0025  *
0026  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
0027  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
0028  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
0029  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
0030  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
0031  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
0032  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
0033  * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
0034  * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
0035  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
0036  * POSSIBILITY OF SUCH DAMAGE.
0037  */
0038 
0039 #include <linux/init.h>
0040 #include <linux/export.h>
0041 #include <linux/console.h>
0042 #include <linux/kobject.h>
0043 #include <linux/dma-map-ops.h>
0044 #include <linux/interrupt.h>
0045 #include <linux/irqdomain.h>
0046 #include <linux/of.h>
0047 #include <linux/slab.h>
0048 #include <linux/stat.h>
0049 #include <linux/of_platform.h>
0050 #include <asm/ibmebus.h>
0051 #include <asm/machdep.h>
0052 
0053 static struct device ibmebus_bus_device = { /* fake "parent" device */
0054     .init_name = "ibmebus",
0055 };
0056 
0057 struct bus_type ibmebus_bus_type;
0058 
0059 /* These devices will automatically be added to the bus during init */
0060 static const struct of_device_id ibmebus_matches[] __initconst = {
0061     { .compatible = "IBM,lhca" },
0062     { .compatible = "IBM,lhea" },
0063     {},
0064 };
0065 
0066 static void *ibmebus_alloc_coherent(struct device *dev,
0067                     size_t size,
0068                     dma_addr_t *dma_handle,
0069                     gfp_t flag,
0070                     unsigned long attrs)
0071 {
0072     void *mem;
0073 
0074     mem = kmalloc(size, flag);
0075     *dma_handle = (dma_addr_t)mem;
0076 
0077     return mem;
0078 }
0079 
0080 static void ibmebus_free_coherent(struct device *dev,
0081                   size_t size, void *vaddr,
0082                   dma_addr_t dma_handle,
0083                   unsigned long attrs)
0084 {
0085     kfree(vaddr);
0086 }
0087 
0088 static dma_addr_t ibmebus_map_page(struct device *dev,
0089                    struct page *page,
0090                    unsigned long offset,
0091                    size_t size,
0092                    enum dma_data_direction direction,
0093                    unsigned long attrs)
0094 {
0095     return (dma_addr_t)(page_address(page) + offset);
0096 }
0097 
0098 static void ibmebus_unmap_page(struct device *dev,
0099                    dma_addr_t dma_addr,
0100                    size_t size,
0101                    enum dma_data_direction direction,
0102                    unsigned long attrs)
0103 {
0104     return;
0105 }
0106 
0107 static int ibmebus_map_sg(struct device *dev,
0108               struct scatterlist *sgl,
0109               int nents, enum dma_data_direction direction,
0110               unsigned long attrs)
0111 {
0112     struct scatterlist *sg;
0113     int i;
0114 
0115     for_each_sg(sgl, sg, nents, i) {
0116         sg->dma_address = (dma_addr_t) sg_virt(sg);
0117         sg->dma_length = sg->length;
0118     }
0119 
0120     return nents;
0121 }
0122 
0123 static void ibmebus_unmap_sg(struct device *dev,
0124                  struct scatterlist *sg,
0125                  int nents, enum dma_data_direction direction,
0126                  unsigned long attrs)
0127 {
0128     return;
0129 }
0130 
0131 static int ibmebus_dma_supported(struct device *dev, u64 mask)
0132 {
0133     return mask == DMA_BIT_MASK(64);
0134 }
0135 
0136 static u64 ibmebus_dma_get_required_mask(struct device *dev)
0137 {
0138     return DMA_BIT_MASK(64);
0139 }
0140 
0141 static const struct dma_map_ops ibmebus_dma_ops = {
0142     .alloc              = ibmebus_alloc_coherent,
0143     .free               = ibmebus_free_coherent,
0144     .map_sg             = ibmebus_map_sg,
0145     .unmap_sg           = ibmebus_unmap_sg,
0146     .dma_supported      = ibmebus_dma_supported,
0147     .get_required_mask  = ibmebus_dma_get_required_mask,
0148     .map_page           = ibmebus_map_page,
0149     .unmap_page         = ibmebus_unmap_page,
0150 };
0151 
0152 static int ibmebus_match_path(struct device *dev, const void *data)
0153 {
0154     struct device_node *dn = to_platform_device(dev)->dev.of_node;
0155     return (of_find_node_by_path(data) == dn);
0156 }
0157 
0158 static int ibmebus_match_node(struct device *dev, const void *data)
0159 {
0160     return to_platform_device(dev)->dev.of_node == data;
0161 }
0162 
0163 static int ibmebus_create_device(struct device_node *dn)
0164 {
0165     struct platform_device *dev;
0166     int ret;
0167 
0168     dev = of_device_alloc(dn, NULL, &ibmebus_bus_device);
0169     if (!dev)
0170         return -ENOMEM;
0171 
0172     dev->dev.bus = &ibmebus_bus_type;
0173     dev->dev.dma_ops = &ibmebus_dma_ops;
0174 
0175     ret = of_device_add(dev);
0176     if (ret)
0177         platform_device_put(dev);
0178     return ret;
0179 }
0180 
0181 static int ibmebus_create_devices(const struct of_device_id *matches)
0182 {
0183     struct device_node *root, *child;
0184     struct device *dev;
0185     int ret = 0;
0186 
0187     root = of_find_node_by_path("/");
0188 
0189     for_each_child_of_node(root, child) {
0190         if (!of_match_node(matches, child))
0191             continue;
0192 
0193         dev = bus_find_device(&ibmebus_bus_type, NULL, child,
0194                       ibmebus_match_node);
0195         if (dev) {
0196             put_device(dev);
0197             continue;
0198         }
0199 
0200         ret = ibmebus_create_device(child);
0201         if (ret) {
0202             printk(KERN_ERR "%s: failed to create device (%i)",
0203                    __func__, ret);
0204             of_node_put(child);
0205             break;
0206         }
0207     }
0208 
0209     of_node_put(root);
0210     return ret;
0211 }
0212 
0213 int ibmebus_register_driver(struct platform_driver *drv)
0214 {
0215     /* If the driver uses devices that ibmebus doesn't know, add them */
0216     ibmebus_create_devices(drv->driver.of_match_table);
0217 
0218     drv->driver.bus = &ibmebus_bus_type;
0219     return driver_register(&drv->driver);
0220 }
0221 EXPORT_SYMBOL(ibmebus_register_driver);
0222 
0223 void ibmebus_unregister_driver(struct platform_driver *drv)
0224 {
0225     driver_unregister(&drv->driver);
0226 }
0227 EXPORT_SYMBOL(ibmebus_unregister_driver);
0228 
0229 int ibmebus_request_irq(u32 ist, irq_handler_t handler,
0230             unsigned long irq_flags, const char *devname,
0231             void *dev_id)
0232 {
0233     unsigned int irq = irq_create_mapping(NULL, ist);
0234 
0235     if (!irq)
0236         return -EINVAL;
0237 
0238     return request_irq(irq, handler, irq_flags, devname, dev_id);
0239 }
0240 EXPORT_SYMBOL(ibmebus_request_irq);
0241 
0242 void ibmebus_free_irq(u32 ist, void *dev_id)
0243 {
0244     unsigned int irq = irq_find_mapping(NULL, ist);
0245 
0246     free_irq(irq, dev_id);
0247     irq_dispose_mapping(irq);
0248 }
0249 EXPORT_SYMBOL(ibmebus_free_irq);
0250 
0251 static char *ibmebus_chomp(const char *in, size_t count)
0252 {
0253     char *out = kmalloc(count + 1, GFP_KERNEL);
0254 
0255     if (!out)
0256         return NULL;
0257 
0258     memcpy(out, in, count);
0259     out[count] = '\0';
0260     if (out[count - 1] == '\n')
0261         out[count - 1] = '\0';
0262 
0263     return out;
0264 }
0265 
0266 static ssize_t probe_store(struct bus_type *bus, const char *buf, size_t count)
0267 {
0268     struct device_node *dn = NULL;
0269     struct device *dev;
0270     char *path;
0271     ssize_t rc = 0;
0272 
0273     path = ibmebus_chomp(buf, count);
0274     if (!path)
0275         return -ENOMEM;
0276 
0277     dev = bus_find_device(&ibmebus_bus_type, NULL, path,
0278                   ibmebus_match_path);
0279     if (dev) {
0280         put_device(dev);
0281         printk(KERN_WARNING "%s: %s has already been probed\n",
0282                __func__, path);
0283         rc = -EEXIST;
0284         goto out;
0285     }
0286 
0287     if ((dn = of_find_node_by_path(path))) {
0288         rc = ibmebus_create_device(dn);
0289         of_node_put(dn);
0290     } else {
0291         printk(KERN_WARNING "%s: no such device node: %s\n",
0292                __func__, path);
0293         rc = -ENODEV;
0294     }
0295 
0296 out:
0297     kfree(path);
0298     if (rc)
0299         return rc;
0300     return count;
0301 }
0302 static BUS_ATTR_WO(probe);
0303 
0304 static ssize_t remove_store(struct bus_type *bus, const char *buf, size_t count)
0305 {
0306     struct device *dev;
0307     char *path;
0308 
0309     path = ibmebus_chomp(buf, count);
0310     if (!path)
0311         return -ENOMEM;
0312 
0313     if ((dev = bus_find_device(&ibmebus_bus_type, NULL, path,
0314                    ibmebus_match_path))) {
0315         of_device_unregister(to_platform_device(dev));
0316         put_device(dev);
0317 
0318         kfree(path);
0319         return count;
0320     } else {
0321         printk(KERN_WARNING "%s: %s not on the bus\n",
0322                __func__, path);
0323 
0324         kfree(path);
0325         return -ENODEV;
0326     }
0327 }
0328 static BUS_ATTR_WO(remove);
0329 
0330 static struct attribute *ibmbus_bus_attrs[] = {
0331     &bus_attr_probe.attr,
0332     &bus_attr_remove.attr,
0333     NULL,
0334 };
0335 ATTRIBUTE_GROUPS(ibmbus_bus);
0336 
0337 static int ibmebus_bus_bus_match(struct device *dev, struct device_driver *drv)
0338 {
0339     const struct of_device_id *matches = drv->of_match_table;
0340 
0341     if (!matches)
0342         return 0;
0343 
0344     return of_match_device(matches, dev) != NULL;
0345 }
0346 
0347 static int ibmebus_bus_device_probe(struct device *dev)
0348 {
0349     int error = -ENODEV;
0350     struct platform_driver *drv;
0351     struct platform_device *of_dev;
0352 
0353     drv = to_platform_driver(dev->driver);
0354     of_dev = to_platform_device(dev);
0355 
0356     if (!drv->probe)
0357         return error;
0358 
0359     get_device(dev);
0360 
0361     if (of_driver_match_device(dev, dev->driver))
0362         error = drv->probe(of_dev);
0363     if (error)
0364         put_device(dev);
0365 
0366     return error;
0367 }
0368 
0369 static void ibmebus_bus_device_remove(struct device *dev)
0370 {
0371     struct platform_device *of_dev = to_platform_device(dev);
0372     struct platform_driver *drv = to_platform_driver(dev->driver);
0373 
0374     if (dev->driver && drv->remove)
0375         drv->remove(of_dev);
0376 }
0377 
0378 static void ibmebus_bus_device_shutdown(struct device *dev)
0379 {
0380     struct platform_device *of_dev = to_platform_device(dev);
0381     struct platform_driver *drv = to_platform_driver(dev->driver);
0382 
0383     if (dev->driver && drv->shutdown)
0384         drv->shutdown(of_dev);
0385 }
0386 
0387 /*
0388  * ibmebus_bus_device_attrs
0389  */
0390 static ssize_t devspec_show(struct device *dev,
0391                 struct device_attribute *attr, char *buf)
0392 {
0393     struct platform_device *ofdev;
0394 
0395     ofdev = to_platform_device(dev);
0396     return sprintf(buf, "%pOF\n", ofdev->dev.of_node);
0397 }
0398 static DEVICE_ATTR_RO(devspec);
0399 
0400 static ssize_t name_show(struct device *dev,
0401                 struct device_attribute *attr, char *buf)
0402 {
0403     struct platform_device *ofdev;
0404 
0405     ofdev = to_platform_device(dev);
0406     return sprintf(buf, "%pOFn\n", ofdev->dev.of_node);
0407 }
0408 static DEVICE_ATTR_RO(name);
0409 
0410 static ssize_t modalias_show(struct device *dev,
0411                 struct device_attribute *attr, char *buf)
0412 {
0413     return of_device_modalias(dev, buf, PAGE_SIZE);
0414 }
0415 static DEVICE_ATTR_RO(modalias);
0416 
0417 static struct attribute *ibmebus_bus_device_attrs[] = {
0418     &dev_attr_devspec.attr,
0419     &dev_attr_name.attr,
0420     &dev_attr_modalias.attr,
0421     NULL,
0422 };
0423 ATTRIBUTE_GROUPS(ibmebus_bus_device);
0424 
0425 struct bus_type ibmebus_bus_type = {
0426     .name      = "ibmebus",
0427     .uevent    = of_device_uevent_modalias,
0428     .bus_groups = ibmbus_bus_groups,
0429     .match     = ibmebus_bus_bus_match,
0430     .probe     = ibmebus_bus_device_probe,
0431     .remove    = ibmebus_bus_device_remove,
0432     .shutdown  = ibmebus_bus_device_shutdown,
0433     .dev_groups = ibmebus_bus_device_groups,
0434 };
0435 EXPORT_SYMBOL(ibmebus_bus_type);
0436 
0437 static int __init ibmebus_bus_init(void)
0438 {
0439     int err;
0440 
0441     printk(KERN_INFO "IBM eBus Device Driver\n");
0442 
0443     err = bus_register(&ibmebus_bus_type);
0444     if (err) {
0445         printk(KERN_ERR "%s: failed to register IBM eBus.\n",
0446                __func__);
0447         return err;
0448     }
0449 
0450     err = device_register(&ibmebus_bus_device);
0451     if (err) {
0452         printk(KERN_WARNING "%s: device_register returned %i\n",
0453                __func__, err);
0454         bus_unregister(&ibmebus_bus_type);
0455 
0456         return err;
0457     }
0458 
0459     err = ibmebus_create_devices(ibmebus_matches);
0460     if (err) {
0461         device_unregister(&ibmebus_bus_device);
0462         bus_unregister(&ibmebus_bus_type);
0463         return err;
0464     }
0465 
0466     return 0;
0467 }
0468 machine_postcore_initcall(pseries, ibmebus_bus_init);