2  * Bus for UWB Multi-interface Controller capabilities.
 
   4  * Copyright (C) 2007 Cambridge Silicon Radio Ltd.
 
   6  * This file is released under the GNU GPL v2.
 
   8 #include <linux/kernel.h>
 
   9 #include <linux/sysfs.h>
 
  10 #include <linux/workqueue.h>
 
  11 #include <linux/uwb/umc.h>
 
  12 #include <linux/pci.h>
 
  14 static int umc_bus_pre_reset_helper(struct device *dev, void *data)
 
  19                 struct umc_dev *umc = to_umc_dev(dev);
 
  20                 struct umc_driver *umc_drv = to_umc_driver(dev->driver);
 
  22                 if (umc_drv->pre_reset)
 
  23                         ret = umc_drv->pre_reset(umc);
 
  25                         device_release_driver(dev);
 
  30 static int umc_bus_post_reset_helper(struct device *dev, void *data)
 
  35                 struct umc_dev *umc = to_umc_dev(dev);
 
  36                 struct umc_driver *umc_drv = to_umc_driver(dev->driver);
 
  38                 if (umc_drv->post_reset)
 
  39                         ret = umc_drv->post_reset(umc);
 
  41                 ret = device_attach(dev);
 
  47  * umc_controller_reset - reset the whole UMC controller
 
  48  * @umc: the UMC device for the radio controller.
 
  50  * Drivers or all capabilities of the controller will have their
 
  51  * pre_reset methods called or be unbound from their device.  Then all
 
  52  * post_reset methods will be called or the drivers will be rebound.
 
  54  * Radio controllers must provide pre_reset and post_reset methods and
 
  55  * reset the hardware in their start method.
 
  57  * If this is called while a probe() or remove() is in progress it
 
  58  * will return -EAGAIN and not perform the reset.
 
  60 int umc_controller_reset(struct umc_dev *umc)
 
  62         struct device *parent = umc->dev.parent;
 
  65         if(down_trylock(&parent->sem))
 
  67         ret = device_for_each_child(parent, parent, umc_bus_pre_reset_helper);
 
  69                 device_for_each_child(parent, parent, umc_bus_post_reset_helper);
 
  74 EXPORT_SYMBOL_GPL(umc_controller_reset);
 
  77  * umc_match_pci_id - match a UMC driver to a UMC device's parent PCI device.
 
  78  * @umc_drv: umc driver with match_data pointing to a zero-terminated
 
  79  * table of pci_device_id's.
 
  80  * @umc: umc device whose parent is to be matched.
 
  82 int umc_match_pci_id(struct umc_driver *umc_drv, struct umc_dev *umc)
 
  84         const struct pci_device_id *id_table = umc_drv->match_data;
 
  87         if (umc->dev.parent->bus != &pci_bus_type)
 
  90         pci = to_pci_dev(umc->dev.parent);
 
  91         return pci_match_id(id_table, pci) != NULL;
 
  93 EXPORT_SYMBOL_GPL(umc_match_pci_id);
 
  95 static int umc_bus_rescan_helper(struct device *dev, void *data)
 
 100                 ret = device_attach(dev);
 
 105 static void umc_bus_rescan(struct device *parent)
 
 110          * We can't use bus_rescan_devices() here as it deadlocks when
 
 111          * it tries to retake the dev->parent semaphore.
 
 113         err = device_for_each_child(parent, NULL, umc_bus_rescan_helper);
 
 115                 printk(KERN_WARNING "%s: rescan of bus failed: %d\n",
 
 116                        KBUILD_MODNAME, err);
 
 119 static int umc_bus_match(struct device *dev, struct device_driver *drv)
 
 121         struct umc_dev *umc = to_umc_dev(dev);
 
 122         struct umc_driver *umc_driver = to_umc_driver(drv);
 
 124         if (umc->cap_id == umc_driver->cap_id) {
 
 125                 if (umc_driver->match)
 
 126                         return umc_driver->match(umc_driver, umc);
 
 133 static int umc_device_probe(struct device *dev)
 
 136         struct umc_driver *umc_driver;
 
 139         umc_driver = to_umc_driver(dev->driver);
 
 140         umc = to_umc_dev(dev);
 
 143         err = umc_driver->probe(umc);
 
 147                 umc_bus_rescan(dev->parent);
 
 152 static int umc_device_remove(struct device *dev)
 
 155         struct umc_driver *umc_driver;
 
 157         umc_driver = to_umc_driver(dev->driver);
 
 158         umc = to_umc_dev(dev);
 
 160         umc_driver->remove(umc);
 
 165 static int umc_device_suspend(struct device *dev, pm_message_t state)
 
 168         struct umc_driver *umc_driver;
 
 171         umc = to_umc_dev(dev);
 
 174                 umc_driver = to_umc_driver(dev->driver);
 
 175                 if (umc_driver->suspend)
 
 176                         err = umc_driver->suspend(umc, state);
 
 181 static int umc_device_resume(struct device *dev)
 
 184         struct umc_driver *umc_driver;
 
 187         umc = to_umc_dev(dev);
 
 190                 umc_driver = to_umc_driver(dev->driver);
 
 191                 if (umc_driver->resume)
 
 192                         err = umc_driver->resume(umc);
 
 197 static ssize_t capability_id_show(struct device *dev, struct device_attribute *attr, char *buf)
 
 199         struct umc_dev *umc = to_umc_dev(dev);
 
 201         return sprintf(buf, "0x%02x\n", umc->cap_id);
 
 204 static ssize_t version_show(struct device *dev, struct device_attribute *attr, char *buf)
 
 206         struct umc_dev *umc = to_umc_dev(dev);
 
 208         return sprintf(buf, "0x%04x\n", umc->version);
 
 211 static struct device_attribute umc_dev_attrs[] = {
 
 212         __ATTR_RO(capability_id),
 
 217 struct bus_type umc_bus_type = {
 
 219         .match          = umc_bus_match,
 
 220         .probe          = umc_device_probe,
 
 221         .remove         = umc_device_remove,
 
 222         .suspend        = umc_device_suspend,
 
 223         .resume         = umc_device_resume,
 
 224         .dev_attrs      = umc_dev_attrs,
 
 226 EXPORT_SYMBOL_GPL(umc_bus_type);
 
 228 static int __init umc_bus_init(void)
 
 230         return bus_register(&umc_bus_type);
 
 232 module_init(umc_bus_init);
 
 234 static void __exit umc_bus_exit(void)
 
 236         bus_unregister(&umc_bus_type);
 
 238 module_exit(umc_bus_exit);
 
 240 MODULE_DESCRIPTION("UWB Multi-interface Controller capability bus");
 
 241 MODULE_AUTHOR("Cambridge Silicon Radio Ltd.");
 
 242 MODULE_LICENSE("GPL");