/* * These are the device model conversion veneers; they convert the * device model structures to our more specific structures. */ static int amba_probe(struct device *dev) { struct amba_device *pcdev = to_amba_device(dev); struct amba_driver *pcdrv = to_amba_driver(dev->driver); struct amba_id *id = amba_lookup(pcdrv->id_table, pcdev); int ret; do { ret = amba_get_enable_vcore(pcdev); if (ret) break; ret = amba_get_enable_pclk(pcdev); if (ret) break; ret = pcdrv->probe(pcdev, id); if (ret == 0) break; amba_put_disable_pclk(pcdev); amba_put_disable_vcore(pcdev); } while (0); return ret; }
/* * These are the device model conversion veneers; they convert the * device model structures to our more specific structures. */ static int amba_probe(struct device *dev) { struct amba_device *pcdev = to_amba_device(dev); struct amba_driver *pcdrv = to_amba_driver(dev->driver); const struct amba_id *id = amba_lookup(pcdrv->id_table, pcdev); int ret; do { ret = amba_get_enable_pclk(pcdev); if (ret) break; pm_runtime_get_noresume(dev); pm_runtime_set_active(dev); pm_runtime_enable(dev); ret = pcdrv->probe(pcdev, id); if (ret == 0) break; pm_runtime_disable(dev); pm_runtime_set_suspended(dev); pm_runtime_put_noidle(dev); amba_put_disable_pclk(pcdev); } while (0); return ret; }
/* * These are the device model conversion veneers; they convert the * device model structures to our more specific structures. */ static int amba_probe(struct device *dev) { struct amba_device *pcdev = to_amba_device(dev); struct amba_driver *pcdrv = to_amba_driver(dev->driver); const struct amba_id *id = amba_lookup(pcdrv->id_table, pcdev); int ret; do { ret = amba_get_enable_vcore(pcdev); if (ret) break; #ifndef CONFIG_MP_PLATFORM_ARM_MSTAR_ETM ret = amba_get_enable_pclk(pcdev); if (ret) break; #endif ret = pcdrv->probe(pcdev, id); if (ret == 0) break; amba_put_disable_pclk(pcdev); amba_put_disable_vcore(pcdev); } while (0); return ret; }
/* * These are the device model conversion veneers; they convert the * device model structures to our more specific structures. */ static int amba_probe(struct device *dev) { struct amba_device *pcdev = to_amba_device(dev); struct amba_driver *pcdrv = to_amba_driver(dev->driver); const struct amba_id *id = amba_lookup(pcdrv->id_table, pcdev); int ret; do { ret = of_clk_set_defaults(dev->of_node, false); if (ret < 0) break; ret = dev_pm_domain_attach(dev, true); if (ret == -EPROBE_DEFER) break; ret = amba_get_enable_pclk(pcdev); if (ret) { dev_pm_domain_detach(dev, true); break; } pm_runtime_get_noresume(dev); pm_runtime_set_active(dev); pm_runtime_enable(dev); ret = pcdrv->probe(pcdev, id); if (ret == 0) break; pm_runtime_disable(dev); pm_runtime_set_suspended(dev); pm_runtime_put_noidle(dev); amba_put_disable_pclk(pcdev); dev_pm_domain_detach(dev, true); } while (0); return ret; }
/** * amba_device_register - register an AMBA device * @dev: AMBA device to register * @parent: parent memory resource * * Setup the AMBA device, reading the cell ID if present. * Claim the resource, and register the AMBA device with * the Linux device manager. */ int amba_device_register(struct amba_device *dev, struct resource *parent) { u32 size; void __iomem *tmp; int i, ret; device_initialize(&dev->dev); /* * Copy from device_add */ if (dev->dev.init_name) { dev_set_name(&dev->dev, "%s", dev->dev.init_name); dev->dev.init_name = NULL; } dev->dev.release = amba_device_release; dev->dev.bus = &amba_bustype; dev->dev.dma_mask = &dev->dma_mask; dev->res.name = dev_name(&dev->dev); if (!dev->dev.coherent_dma_mask && dev->dma_mask) dev_warn(&dev->dev, "coherent dma mask is unset\n"); ret = request_resource(parent, &dev->res); if (ret) goto err_out; /* * Dynamically calculate the size of the resource * and use this for iomap */ size = resource_size(&dev->res); tmp = ioremap(dev->res.start, size); if (!tmp) { ret = -ENOMEM; goto err_release; } ret = amba_get_enable_pclk(dev); if (ret == 0) { u32 pid, cid; /* * Read pid and cid based on size of resource * they are located at end of region */ for (pid = 0, i = 0; i < 4; i++) pid |= (readl(tmp + size - 0x20 + 4 * i) & 255) << (i * 8); for (cid = 0, i = 0; i < 4; i++) cid |= (readl(tmp + size - 0x10 + 4 * i) & 255) << (i * 8); amba_put_disable_pclk(dev); if (cid == AMBA_CID) dev->periphid = pid; if (!dev->periphid) ret = -ENODEV; } iounmap(tmp); if (ret) goto err_release; ret = device_add(&dev->dev); if (ret) goto err_release; if (dev->irq[0] != NO_IRQ) ret = device_create_file(&dev->dev, &dev_attr_irq0); if (ret == 0 && dev->irq[1] != NO_IRQ) ret = device_create_file(&dev->dev, &dev_attr_irq1); if (ret == 0) return ret; device_unregister(&dev->dev); err_release: release_resource(&dev->res); err_out: return ret; }
static int amba_device_try_add(struct amba_device *dev, struct resource *parent) { u32 size; void __iomem *tmp; int i, ret; WARN_ON(dev->irq[0] == (unsigned int)-1); WARN_ON(dev->irq[1] == (unsigned int)-1); ret = request_resource(parent, &dev->res); if (ret) goto err_out; /* Hard-coded primecell ID instead of plug-n-play */ if (dev->periphid != 0) goto skip_probe; /* * Dynamically calculate the size of the resource * and use this for iomap */ size = resource_size(&dev->res); tmp = ioremap(dev->res.start, size); if (!tmp) { ret = -ENOMEM; goto err_release; } ret = dev_pm_domain_attach(&dev->dev, true); if (ret == -EPROBE_DEFER) { iounmap(tmp); goto err_release; } ret = amba_get_enable_pclk(dev); if (ret == 0) { u32 pid, cid; /* * Read pid and cid based on size of resource * they are located at end of region */ for (pid = 0, i = 0; i < 4; i++) pid |= (readl(tmp + size - 0x20 + 4 * i) & 255) << (i * 8); for (cid = 0, i = 0; i < 4; i++) cid |= (readl(tmp + size - 0x10 + 4 * i) & 255) << (i * 8); amba_put_disable_pclk(dev); if (cid == AMBA_CID || cid == CORESIGHT_CID) dev->periphid = pid; if (!dev->periphid) ret = -ENODEV; } iounmap(tmp); dev_pm_domain_detach(&dev->dev, true); if (ret) goto err_release; skip_probe: ret = device_add(&dev->dev); if (ret) goto err_release; if (dev->irq[0]) ret = device_create_file(&dev->dev, &dev_attr_irq0); if (ret == 0 && dev->irq[1]) ret = device_create_file(&dev->dev, &dev_attr_irq1); if (ret == 0) return ret; device_unregister(&dev->dev); err_release: release_resource(&dev->res); err_out: return ret; }