Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * Greybus Bridged-Phy Bus driver
0004  *
0005  * Copyright 2014 Google Inc.
0006  * Copyright 2014 Linaro Ltd.
0007  */
0008 
0009 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
0010 
0011 #include <linux/types.h>
0012 #include <linux/module.h>
0013 #include <linux/kernel.h>
0014 #include <linux/slab.h>
0015 #include <linux/device.h>
0016 #include <linux/greybus.h>
0017 
0018 #include "gbphy.h"
0019 
0020 #define GB_GBPHY_AUTOSUSPEND_MS 3000
0021 
0022 struct gbphy_host {
0023     struct gb_bundle *bundle;
0024     struct list_head devices;
0025 };
0026 
0027 static DEFINE_IDA(gbphy_id);
0028 
0029 static ssize_t protocol_id_show(struct device *dev,
0030                 struct device_attribute *attr, char *buf)
0031 {
0032     struct gbphy_device *gbphy_dev = to_gbphy_dev(dev);
0033 
0034     return sprintf(buf, "0x%02x\n", gbphy_dev->cport_desc->protocol_id);
0035 }
0036 static DEVICE_ATTR_RO(protocol_id);
0037 
0038 static struct attribute *gbphy_dev_attrs[] = {
0039     &dev_attr_protocol_id.attr,
0040     NULL,
0041 };
0042 
0043 ATTRIBUTE_GROUPS(gbphy_dev);
0044 
0045 static void gbphy_dev_release(struct device *dev)
0046 {
0047     struct gbphy_device *gbphy_dev = to_gbphy_dev(dev);
0048 
0049     ida_simple_remove(&gbphy_id, gbphy_dev->id);
0050     kfree(gbphy_dev);
0051 }
0052 
0053 #ifdef CONFIG_PM
0054 static int gb_gbphy_idle(struct device *dev)
0055 {
0056     pm_runtime_mark_last_busy(dev);
0057     pm_request_autosuspend(dev);
0058     return 0;
0059 }
0060 #endif
0061 
0062 static const struct dev_pm_ops gb_gbphy_pm_ops = {
0063     SET_RUNTIME_PM_OPS(pm_generic_runtime_suspend,
0064                pm_generic_runtime_resume,
0065                gb_gbphy_idle)
0066 };
0067 
0068 static const struct device_type greybus_gbphy_dev_type = {
0069     .name    =  "gbphy_device",
0070     .release =  gbphy_dev_release,
0071     .pm =   &gb_gbphy_pm_ops,
0072 };
0073 
0074 static int gbphy_dev_uevent(struct device *dev, struct kobj_uevent_env *env)
0075 {
0076     struct gbphy_device *gbphy_dev = to_gbphy_dev(dev);
0077     struct greybus_descriptor_cport *cport_desc = gbphy_dev->cport_desc;
0078     struct gb_bundle *bundle = gbphy_dev->bundle;
0079     struct gb_interface *intf = bundle->intf;
0080     struct gb_module *module = intf->module;
0081     struct gb_host_device *hd = intf->hd;
0082 
0083     if (add_uevent_var(env, "BUS=%u", hd->bus_id))
0084         return -ENOMEM;
0085     if (add_uevent_var(env, "MODULE=%u", module->module_id))
0086         return -ENOMEM;
0087     if (add_uevent_var(env, "INTERFACE=%u", intf->interface_id))
0088         return -ENOMEM;
0089     if (add_uevent_var(env, "GREYBUS_ID=%08x/%08x",
0090                intf->vendor_id, intf->product_id))
0091         return -ENOMEM;
0092     if (add_uevent_var(env, "BUNDLE=%u", gbphy_dev->bundle->id))
0093         return -ENOMEM;
0094     if (add_uevent_var(env, "BUNDLE_CLASS=%02x", bundle->class))
0095         return -ENOMEM;
0096     if (add_uevent_var(env, "GBPHY=%u", gbphy_dev->id))
0097         return -ENOMEM;
0098     if (add_uevent_var(env, "PROTOCOL_ID=%02x", cport_desc->protocol_id))
0099         return -ENOMEM;
0100 
0101     return 0;
0102 }
0103 
0104 static const struct gbphy_device_id *
0105 gbphy_dev_match_id(struct gbphy_device *gbphy_dev,
0106            struct gbphy_driver *gbphy_drv)
0107 {
0108     const struct gbphy_device_id *id = gbphy_drv->id_table;
0109 
0110     if (!id)
0111         return NULL;
0112 
0113     for (; id->protocol_id; id++)
0114         if (id->protocol_id == gbphy_dev->cport_desc->protocol_id)
0115             return id;
0116 
0117     return NULL;
0118 }
0119 
0120 static int gbphy_dev_match(struct device *dev, struct device_driver *drv)
0121 {
0122     struct gbphy_driver *gbphy_drv = to_gbphy_driver(drv);
0123     struct gbphy_device *gbphy_dev = to_gbphy_dev(dev);
0124     const struct gbphy_device_id *id;
0125 
0126     id = gbphy_dev_match_id(gbphy_dev, gbphy_drv);
0127     if (id)
0128         return 1;
0129 
0130     return 0;
0131 }
0132 
0133 static int gbphy_dev_probe(struct device *dev)
0134 {
0135     struct gbphy_driver *gbphy_drv = to_gbphy_driver(dev->driver);
0136     struct gbphy_device *gbphy_dev = to_gbphy_dev(dev);
0137     const struct gbphy_device_id *id;
0138     int ret;
0139 
0140     id = gbphy_dev_match_id(gbphy_dev, gbphy_drv);
0141     if (!id)
0142         return -ENODEV;
0143 
0144     /* for old kernels we need get_sync to resume parent devices */
0145     ret = gb_pm_runtime_get_sync(gbphy_dev->bundle);
0146     if (ret < 0)
0147         return ret;
0148 
0149     pm_runtime_set_autosuspend_delay(dev, GB_GBPHY_AUTOSUSPEND_MS);
0150     pm_runtime_use_autosuspend(dev);
0151     pm_runtime_get_noresume(dev);
0152     pm_runtime_set_active(dev);
0153     pm_runtime_enable(dev);
0154 
0155     /*
0156      * Drivers should call put on the gbphy dev before returning
0157      * from probe if they support runtime pm.
0158      */
0159     ret = gbphy_drv->probe(gbphy_dev, id);
0160     if (ret) {
0161         pm_runtime_disable(dev);
0162         pm_runtime_set_suspended(dev);
0163         pm_runtime_put_noidle(dev);
0164         pm_runtime_dont_use_autosuspend(dev);
0165     }
0166 
0167     gb_pm_runtime_put_autosuspend(gbphy_dev->bundle);
0168 
0169     return ret;
0170 }
0171 
0172 static void gbphy_dev_remove(struct device *dev)
0173 {
0174     struct gbphy_driver *gbphy_drv = to_gbphy_driver(dev->driver);
0175     struct gbphy_device *gbphy_dev = to_gbphy_dev(dev);
0176 
0177     gbphy_drv->remove(gbphy_dev);
0178 
0179     pm_runtime_disable(dev);
0180     pm_runtime_set_suspended(dev);
0181     pm_runtime_put_noidle(dev);
0182     pm_runtime_dont_use_autosuspend(dev);
0183 }
0184 
0185 static struct bus_type gbphy_bus_type = {
0186     .name =     "gbphy",
0187     .match =    gbphy_dev_match,
0188     .probe =    gbphy_dev_probe,
0189     .remove =   gbphy_dev_remove,
0190     .uevent =   gbphy_dev_uevent,
0191 };
0192 
0193 int gb_gbphy_register_driver(struct gbphy_driver *driver,
0194                  struct module *owner, const char *mod_name)
0195 {
0196     int retval;
0197 
0198     if (greybus_disabled())
0199         return -ENODEV;
0200 
0201     driver->driver.bus = &gbphy_bus_type;
0202     driver->driver.name = driver->name;
0203     driver->driver.owner = owner;
0204     driver->driver.mod_name = mod_name;
0205 
0206     retval = driver_register(&driver->driver);
0207     if (retval)
0208         return retval;
0209 
0210     pr_info("registered new driver %s\n", driver->name);
0211     return 0;
0212 }
0213 EXPORT_SYMBOL_GPL(gb_gbphy_register_driver);
0214 
0215 void gb_gbphy_deregister_driver(struct gbphy_driver *driver)
0216 {
0217     driver_unregister(&driver->driver);
0218 }
0219 EXPORT_SYMBOL_GPL(gb_gbphy_deregister_driver);
0220 
0221 static struct gbphy_device *gb_gbphy_create_dev(struct gb_bundle *bundle,
0222                         struct greybus_descriptor_cport *cport_desc)
0223 {
0224     struct gbphy_device *gbphy_dev;
0225     int retval;
0226     int id;
0227 
0228     id = ida_simple_get(&gbphy_id, 1, 0, GFP_KERNEL);
0229     if (id < 0)
0230         return ERR_PTR(id);
0231 
0232     gbphy_dev = kzalloc(sizeof(*gbphy_dev), GFP_KERNEL);
0233     if (!gbphy_dev) {
0234         ida_simple_remove(&gbphy_id, id);
0235         return ERR_PTR(-ENOMEM);
0236     }
0237 
0238     gbphy_dev->id = id;
0239     gbphy_dev->bundle = bundle;
0240     gbphy_dev->cport_desc = cport_desc;
0241     gbphy_dev->dev.parent = &bundle->dev;
0242     gbphy_dev->dev.bus = &gbphy_bus_type;
0243     gbphy_dev->dev.type = &greybus_gbphy_dev_type;
0244     gbphy_dev->dev.groups = gbphy_dev_groups;
0245     gbphy_dev->dev.dma_mask = bundle->dev.dma_mask;
0246     dev_set_name(&gbphy_dev->dev, "gbphy%d", id);
0247 
0248     retval = device_register(&gbphy_dev->dev);
0249     if (retval) {
0250         put_device(&gbphy_dev->dev);
0251         return ERR_PTR(retval);
0252     }
0253 
0254     return gbphy_dev;
0255 }
0256 
0257 static void gb_gbphy_disconnect(struct gb_bundle *bundle)
0258 {
0259     struct gbphy_host *gbphy_host = greybus_get_drvdata(bundle);
0260     struct gbphy_device *gbphy_dev, *temp;
0261     int ret;
0262 
0263     ret = gb_pm_runtime_get_sync(bundle);
0264     if (ret < 0)
0265         gb_pm_runtime_get_noresume(bundle);
0266 
0267     list_for_each_entry_safe(gbphy_dev, temp, &gbphy_host->devices, list) {
0268         list_del(&gbphy_dev->list);
0269         device_unregister(&gbphy_dev->dev);
0270     }
0271 
0272     kfree(gbphy_host);
0273 }
0274 
0275 static int gb_gbphy_probe(struct gb_bundle *bundle,
0276               const struct greybus_bundle_id *id)
0277 {
0278     struct gbphy_host *gbphy_host;
0279     struct gbphy_device *gbphy_dev;
0280     int i;
0281 
0282     if (bundle->num_cports == 0)
0283         return -ENODEV;
0284 
0285     gbphy_host = kzalloc(sizeof(*gbphy_host), GFP_KERNEL);
0286     if (!gbphy_host)
0287         return -ENOMEM;
0288 
0289     gbphy_host->bundle = bundle;
0290     INIT_LIST_HEAD(&gbphy_host->devices);
0291     greybus_set_drvdata(bundle, gbphy_host);
0292 
0293     /*
0294      * Create a bunch of children devices, one per cport, and bind the
0295      * bridged phy drivers to them.
0296      */
0297     for (i = 0; i < bundle->num_cports; ++i) {
0298         gbphy_dev = gb_gbphy_create_dev(bundle, &bundle->cport_desc[i]);
0299         if (IS_ERR(gbphy_dev)) {
0300             gb_gbphy_disconnect(bundle);
0301             return PTR_ERR(gbphy_dev);
0302         }
0303         list_add(&gbphy_dev->list, &gbphy_host->devices);
0304     }
0305 
0306     gb_pm_runtime_put_autosuspend(bundle);
0307 
0308     return 0;
0309 }
0310 
0311 static const struct greybus_bundle_id gb_gbphy_id_table[] = {
0312     { GREYBUS_DEVICE_CLASS(GREYBUS_CLASS_BRIDGED_PHY) },
0313     { },
0314 };
0315 MODULE_DEVICE_TABLE(greybus, gb_gbphy_id_table);
0316 
0317 static struct greybus_driver gb_gbphy_driver = {
0318     .name       = "gbphy",
0319     .probe      = gb_gbphy_probe,
0320     .disconnect = gb_gbphy_disconnect,
0321     .id_table   = gb_gbphy_id_table,
0322 };
0323 
0324 static int __init gbphy_init(void)
0325 {
0326     int retval;
0327 
0328     retval = bus_register(&gbphy_bus_type);
0329     if (retval) {
0330         pr_err("gbphy bus register failed (%d)\n", retval);
0331         return retval;
0332     }
0333 
0334     retval = greybus_register(&gb_gbphy_driver);
0335     if (retval) {
0336         pr_err("error registering greybus driver\n");
0337         goto error_gbphy;
0338     }
0339 
0340     return 0;
0341 
0342 error_gbphy:
0343     bus_unregister(&gbphy_bus_type);
0344     ida_destroy(&gbphy_id);
0345     return retval;
0346 }
0347 module_init(gbphy_init);
0348 
0349 static void __exit gbphy_exit(void)
0350 {
0351     greybus_deregister(&gb_gbphy_driver);
0352     bus_unregister(&gbphy_bus_type);
0353     ida_destroy(&gbphy_id);
0354 }
0355 module_exit(gbphy_exit);
0356 
0357 MODULE_LICENSE("GPL v2");