static void __init omap_hsmmc_init_one(struct omap2_hsmmc_info *hsmmcinfo,
int ctrl_nr)
{
struct omap_hwmod *oh;
struct omap_hwmod *ohs[1];
struct omap_device *od;
struct platform_device *pdev;
char oh_name[MAX_OMAP_MMC_HWMOD_NAME_LEN];
struct omap_hsmmc_platform_data *mmc_data;
struct omap_hsmmc_dev_attr *mmc_dev_attr;
char *name;
int res;
mmc_data = kzalloc(sizeof(*mmc_data), GFP_KERNEL);
if (!mmc_data)
return;
res = omap_hsmmc_pdata_init(hsmmcinfo, mmc_data);
if (res < 0)
goto free_mmc;
name = "omap_hsmmc";
res = snprintf(oh_name, MAX_OMAP_MMC_HWMOD_NAME_LEN,
"mmc%d", ctrl_nr);
WARN(res >= MAX_OMAP_MMC_HWMOD_NAME_LEN,
"String buffer overflow in MMC%d device setup\n", ctrl_nr);
oh = omap_hwmod_lookup(oh_name);
if (!oh) {
pr_err("Could not look up %s\n", oh_name);
goto free_name;
}
ohs[0] = oh;
if (oh->dev_attr != NULL) {
mmc_dev_attr = oh->dev_attr;
mmc_data->controller_flags = mmc_dev_attr->flags;
/*
* erratum 2.1.1.128 doesn't apply if board has
* a transceiver is attached
*/
if (hsmmcinfo->transceiver)
mmc_data->controller_flags &=
~OMAP_HSMMC_BROKEN_MULTIBLOCK_READ;
}
pdev = platform_device_alloc(name, ctrl_nr - 1);
if (!pdev) {
pr_err("Could not allocate pdev for %s\n", name);
goto free_name;
}
dev_set_name(&pdev->dev, "%s.%d", pdev->name, pdev->id);
od = omap_device_alloc(pdev, ohs, 1);
if (IS_ERR(od)) {
pr_err("Could not allocate od for %s\n", name);
goto put_pdev;
}
res = platform_device_add_data(pdev, mmc_data,
sizeof(struct omap_hsmmc_platform_data));
if (res) {
pr_err("Could not add pdata for %s\n", name);
goto put_pdev;
}
hsmmcinfo->pdev = pdev;
if (hsmmcinfo->deferred)
goto free_mmc;
res = omap_device_register(pdev);
if (res) {
pr_err("Could not register od for %s\n", name);
goto free_od;
}
goto free_mmc;
free_od:
omap_device_delete(od);
put_pdev:
platform_device_put(pdev);
free_name:
kfree(mmc_data->name);
free_mmc:
kfree(mmc_data);
}
开发者ID:Endika,项目名称:linux,代码行数:90,代码来源:hsmmc.c
示例6: omap_hsmmc_reset
/**
* omap_hsmmc_reset() - Full reset of each HS-MMC controller
*
* Ensure that each MMC controller is fully reset. Controllers
* left in an unknown state (by bootloader) may prevent retention
* or OFF-mode. This is especially important in cases where the
* MMC driver is not enabled, _or_ built as a module.
*
* In order for reset to work, interface, functional and debounce
* clocks must be enabled. The debounce clock comes from func_32k_clk
* and is not under SW control, so we only enable i- and f-clocks.
**/
static void __init omap_hsmmc_reset(void)
{
u32 i, nr_controllers = cpu_is_omap44xx() ? OMAP44XX_NR_MMC :
(cpu_is_omap34xx() ? OMAP34XX_NR_MMC : OMAP24XX_NR_MMC);
for (i = 0; i < nr_controllers; i++) {
u32 v, base = 0;
struct clk *iclk, *fclk;
struct device *dev = &dummy_pdev.dev;
switch (i) {
case 0:
base = OMAP2_MMC1_BASE;
break;
case 1:
base = OMAP2_MMC2_BASE;
break;
case 2:
base = OMAP3_MMC3_BASE;
break;
case 3:
if (!cpu_is_omap44xx())
return;
base = OMAP4_MMC4_BASE;
break;
case 4:
if (!cpu_is_omap44xx())
return;
base = OMAP4_MMC5_BASE;
break;
}
if (cpu_is_omap44xx())
base += OMAP4_MMC_REG_OFFSET;
dummy_pdev.id = i;
dev_set_name(&dummy_pdev.dev, "mmci-omap-hs.%d", i);
iclk = clk_get(dev, "ick");
if (iclk && clk_enable(iclk))
iclk = NULL;
fclk = clk_get(dev, "fck");
if (fclk && clk_enable(fclk))
fclk = NULL;
if (!iclk || !fclk) {
printk(KERN_WARNING
"%s: Unable to enable clocks for MMC%d, "
"cannot reset.\n", __func__, i);
break;
}
omap_writel(MMCHS_SYSCONFIG_SWRESET, base + MMCHS_SYSCONFIG);
v = omap_readl(base + MMCHS_SYSSTATUS);
while (!(omap_readl(base + MMCHS_SYSSTATUS) &
MMCHS_SYSSTATUS_RESETDONE))
cpu_relax();
if (fclk) {
clk_disable(fclk);
clk_put(fclk);
}
if (iclk) {
clk_disable(iclk);
clk_put(iclk);
}
}
}
static int zynq_rpmsg_initialize(struct platform_device *pdev)
{
int ret = 0;
int index;
struct virtio_device *virtio_dev;
/* Register ipi handler. */
ret = set_ipi_handler(zynq_rpmsg_p->vring0, ipi_handler,
"Firmware kick");
if (ret) {
dev_err(&pdev->dev, "IPI handler already registered\n");
return -ENODEV;
}
/* Initialize work. */
INIT_WORK(&zynq_rpmsg_work, handle_event);
/* Memory allocations for vrings. */
ret = dma_declare_coherent_memory(&pdev->dev,
zynq_rpmsg_p->mem_start,
zynq_rpmsg_p->mem_start,
zynq_rpmsg_p->mem_end -
zynq_rpmsg_p->mem_start + 1,
DMA_MEMORY_IO);
if (!ret) {
dev_err(&pdev->dev, "dma_declare_coherent_memory failed\n");
return -ENODEV;
}
ret = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32));
if (ret) {
dev_err(&pdev->dev, "dma_set_coherent_mask: %d\n", ret);
return -ENODEV;
}
/* Initialize a mid-level device. Needed because of bad data structure
* handling and assumptions within the virtio rpmsg bus. We are doing it
* to just make sure that the virtio device has a parent device which
* then itself has a parent in the form of the platform device. */
device_initialize(&(zynq_rpmsg_p->mid_dev));
zynq_rpmsg_p->mid_dev.parent = &(pdev->dev);
zynq_rpmsg_p->mid_dev.type = &mid_level_type;
index = ida_simple_get(&rpmsg_zynq_dev_index, 0, 0, GFP_KERNEL);
if (index < 0) {
put_device(&(zynq_rpmsg_p->mid_dev));
return -ENODEV;
}
dev_set_name(&(zynq_rpmsg_p->mid_dev), "rpmsg_mid%d", index);
device_add(&(zynq_rpmsg_p->mid_dev));
/* Setup the virtio device structure. */
virtio_dev = &(zynq_rpmsg_p->virtio_dev);
virtio_dev->id.device = zynq_rpmsg_p->virtioid;
virtio_dev->config = &zynq_rpmsg_virtio_config_ops;
virtio_dev->dev.parent = &(zynq_rpmsg_p->mid_dev);
virtio_dev->dev.release = zynq_rpmsg_vdev_release;
/* Register the virtio device. */
ret = register_virtio_device(virtio_dev);
dev_info(&(zynq_rpmsg_platform->dev), "virtio device registered \r\n");
return ret;
}
/*
* Register a new MMC card with the driver model.
*/
int mmc_add_card(struct mmc_card *card)
{
int ret;
const char *type;
const char *uhs_bus_speed_mode = "";
dev_set_name(&card->dev, "%s:%04x", mmc_hostname(card->host), card->rca);
switch (card->type) {
case MMC_TYPE_MMC:
type = "MMC";
break;
case MMC_TYPE_SD:
type = "SD";
if (mmc_card_blockaddr(card)) {
if (mmc_card_ext_capacity(card))
type = "SDXC";
else
type = "SDHC";
}
break;
case MMC_TYPE_SDIO:
type = "SDIO";
break;
case MMC_TYPE_SD_COMBO:
type = "SD-combo";
if (mmc_card_blockaddr(card))
type = "SDHC-combo";
break;
default:
type = "?";
break;
}
if (mmc_sd_card_uhs(card)) {
switch (card->sd_bus_speed) {
case UHS_SDR104_BUS_SPEED:
uhs_bus_speed_mode = "SDR104 ";
break;
case UHS_SDR50_BUS_SPEED:
uhs_bus_speed_mode = "SDR50 ";
break;
case UHS_DDR50_BUS_SPEED:
uhs_bus_speed_mode = "DDR50 ";
break;
case UHS_SDR25_BUS_SPEED:
uhs_bus_speed_mode = "SDR25 ";
break;
case UHS_SDR12_BUS_SPEED:
uhs_bus_speed_mode = "SDR12 ";
break;
default:
uhs_bus_speed_mode = "";
break;
}
}
if (mmc_host_is_spi(card->host)) {
printk(KERN_INFO "%s: new %s%s%s card on SPI\n",
mmc_hostname(card->host),
mmc_card_highspeed(card) ? "high speed " : "",
mmc_card_ddr_mode(card) ? "DDR " : "",
type);
} else {
pr_info("%s: new %s%s%s%s card at address %04x\n",
mmc_hostname(card->host),
mmc_sd_card_uhs(card) ? "ultra high speed " :
(mmc_card_highspeed(card) ? "high speed " : ""),
mmc_card_ddr_mode(card) ? "DDR " : "",
uhs_bus_speed_mode,
type, card->rca);
}
#ifdef CONFIG_DEBUG_FS
mmc_add_card_debugfs(card);
#endif
ret = device_add(&card->dev);
if (ret)
return ret;
mmc_card_set_present(card);
return 0;
}
开发者ID:AnDr0id,项目名称:SGH-I747,代码行数:87,代码来源:bus.c
示例12: pr_debug
static struct amba_device *of_amba_device_create(struct device_node *node,
const char *bus_id,
void *platform_data,
struct device *parent)
{
struct amba_device *dev;
const void *prop;
int i, ret;
pr_debug("Creating amba device %s\n", node->full_name);
if (!of_device_is_available(node) ||
of_node_test_and_set_flag(node, OF_POPULATED))
return NULL;
dev = amba_device_alloc(NULL, 0, 0);
if (!dev)
goto err_clear_flag;
/* setup generic device info */
dev->dev.of_node = of_node_get(node);
dev->dev.fwnode = &node->fwnode;
dev->dev.parent = parent ? : &platform_bus;
dev->dev.platform_data = platform_data;
if (bus_id)
dev_set_name(&dev->dev, "%s", bus_id);
else
of_device_make_bus_id(&dev->dev);
of_dma_configure(&dev->dev, dev->dev.of_node);
/* Allow the HW Peripheral ID to be overridden */
prop = of_get_property(node, "arm,primecell-periphid", NULL);
if (prop)
dev->periphid = of_read_ulong(prop, 1);
/* Decode the IRQs and address ranges */
for (i = 0; i < AMBA_NR_IRQS; i++)
dev->irq[i] = irq_of_parse_and_map(node, i);
ret = of_address_to_resource(node, 0, &dev->res);
if (ret) {
pr_err("amba: of_address_to_resource() failed (%d) for %s\n",
ret, node->full_name);
goto err_free;
}
ret = amba_device_add(dev, &iomem_resource);
if (ret) {
pr_err("amba_device_add() failed (%d) for %s\n",
ret, node->full_name);
goto err_free;
}
return dev;
err_free:
amba_device_put(dev);
err_clear_flag:
of_node_clear_flag(node, OF_POPULATED);
return NULL;
}
开发者ID:mhei,项目名称:linux,代码行数:61,代码来源:platform.c
示例13: chp_new
/**
* chp_new - register a new channel-path
* @chpid - channel-path ID
*
* Create and register data structure representing new channel-path. Return
* zero on success, non-zero otherwise.
*/
int chp_new(struct chp_id chpid)
{
struct channel_path *chp;
int ret;
if (chp_is_registered(chpid))
return 0;
chp = kzalloc(sizeof(struct channel_path), GFP_KERNEL);
if (!chp)
return -ENOMEM;
/* fill in status, etc. */
chp->chpid = chpid;
chp->state = 1;
chp->dev.parent = &channel_subsystems[chpid.cssid]->device;
chp->dev.release = chp_release;
dev_set_name(&chp->dev, "chp%x.%02x", chpid.cssid, chpid.id);
/* Obtain channel path description and fill it in. */
ret = chsc_determine_base_channel_path_desc(chpid, &chp->desc);
if (ret)
goto out_free;
if ((chp->desc.flags & 0x80) == 0) {
ret = -ENODEV;
goto out_free;
}
/* Get channel-measurement characteristics. */
if (css_chsc_characteristics.scmc && css_chsc_characteristics.secm) {
ret = chsc_get_channel_measurement_chars(chp);
if (ret)
goto out_free;
} else {
chp->cmg = -1;
}
/* make it known to the system */
ret = device_register(&chp->dev);
if (ret) {
CIO_MSG_EVENT(0, "Could not register chp%x.%02x: %d\n",
chpid.cssid, chpid.id, ret);
goto out_free;
}
ret = sysfs_create_group(&chp->dev.kobj, &chp_attr_group);
if (ret) {
device_unregister(&chp->dev);
goto out;
}
mutex_lock(&channel_subsystems[chpid.cssid]->mutex);
if (channel_subsystems[chpid.cssid]->cm_enabled) {
ret = chp_add_cmg_attr(chp);
if (ret) {
sysfs_remove_group(&chp->dev.kobj, &chp_attr_group);
device_unregister(&chp->dev);
mutex_unlock(&channel_subsystems[chpid.cssid]->mutex);
goto out;
}
}
channel_subsystems[chpid.cssid]->chps[chpid.id] = chp;
mutex_unlock(&channel_subsystems[chpid.cssid]->mutex);
goto out;
out_free:
kfree(chp);
out:
return ret;
}
/**
* zfcp_port_enqueue - enqueue port to port list of adapter
* @adapter: adapter where remote port is added
* @wwpn: WWPN of the remote port to be enqueued
* @status: initial status for the port
* @d_id: destination id of the remote port to be enqueued
* Returns: pointer to enqueued port on success, ERR_PTR on error
*
* All port internal structures are set up and the sysfs entry is generated.
* d_id is used to enqueue ports with a well known address like the Directory
* Service for nameserver lookup.
*/
struct zfcp_port *zfcp_port_enqueue(struct zfcp_adapter *adapter, u64 wwpn,
u32 status, u32 d_id)
{
struct zfcp_port *port;
int retval = -ENOMEM;
kref_get(&adapter->ref);
port = zfcp_get_port_by_wwpn(adapter, wwpn);
if (port) {
put_device(&port->dev);
retval = -EEXIST;
goto err_out;
}
port = kzalloc(sizeof(struct zfcp_port), GFP_KERNEL);
if (!port)
goto err_out;
rwlock_init(&port->unit_list_lock);
INIT_LIST_HEAD(&port->unit_list);
atomic_set(&port->units, 0);
INIT_WORK(&port->gid_pn_work, zfcp_fc_port_did_lookup);
INIT_WORK(&port->test_link_work, zfcp_fc_link_test_work);
INIT_WORK(&port->rport_work, zfcp_scsi_rport_work);
port->adapter = adapter;
port->d_id = d_id;
port->wwpn = wwpn;
port->rport_task = RPORT_NONE;
port->dev.parent = &adapter->ccw_device->dev;
port->dev.release = zfcp_port_release;
if (dev_set_name(&port->dev, "0x%016llx", (unsigned long long)wwpn)) {
kfree(port);
goto err_out;
}
retval = -EINVAL;
if (device_register(&port->dev)) {
put_device(&port->dev);
goto err_out;
}
if (sysfs_create_group(&port->dev.kobj,
&zfcp_sysfs_port_attrs))
goto err_out_put;
write_lock_irq(&adapter->port_list_lock);
list_add_tail(&port->list, &adapter->port_list);
write_unlock_irq(&adapter->port_list_lock);
atomic_set_mask(status | ZFCP_STATUS_COMMON_RUNNING, &port->status);
return port;
err_out_put:
device_unregister(&port->dev);
err_out:
zfcp_ccw_adapter_put(adapter);
return ERR_PTR(retval);
}
/**
* usb_alloc_dev - usb device constructor (usbcore-internal)
* @parent: hub to which device is connected; null to allocate a root hub
* @bus: bus used to access the device
* @port1: one-based index of port; ignored for root hubs
* Context: !in_interrupt()
*
* Only hub drivers (including virtual root hub drivers for host
* controllers) should ever call this.
*
* This call may not be used in a non-sleeping context.
*/
struct usb_device *usb_alloc_dev(struct usb_device *parent,
struct usb_bus *bus, unsigned port1)
{
struct usb_device *dev;
struct usb_hcd *usb_hcd = container_of(bus, struct usb_hcd, self);
unsigned root_hub = 0;
dev = kzalloc(sizeof(*dev), GFP_KERNEL);
if (!dev)
return NULL;
if (!usb_get_hcd(bus_to_hcd(bus))) {
kfree(dev);
return NULL;
}
device_initialize(&dev->dev);
dev->dev.bus = &usb_bus_type;
dev->dev.type = &usb_device_type;
dev->dev.groups = usb_device_groups;
dev->dev.dma_mask = bus->controller->dma_mask;
set_dev_node(&dev->dev, dev_to_node(bus->controller));
dev->state = USB_STATE_ATTACHED;
atomic_set(&dev->urbnum, 0);
INIT_LIST_HEAD(&dev->ep0.urb_list);
dev->ep0.desc.bLength = USB_DT_ENDPOINT_SIZE;
dev->ep0.desc.bDescriptorType = USB_DT_ENDPOINT;
/* ep0 maxpacket comes later, from device descriptor */
usb_enable_endpoint(dev, &dev->ep0, true);
dev->can_submit = 1;
/* Save readable and stable topology id, distinguishing devices
* by location for diagnostics, tools, driver model, etc. The
* string is a path along hub ports, from the root. Each device's
* dev->devpath will be stable until USB is re-cabled, and hubs
* are often labeled with these port numbers. The name isn't
* as stable: bus->busnum changes easily from modprobe order,
* cardbus or pci hotplugging, and so on.
*/
if (unlikely(!parent)) {
dev->devpath[0] = '0';
dev->dev.parent = bus->controller;
dev_set_name(&dev->dev, "usb%d", bus->busnum);
root_hub = 1;
} else {
/* match any labeling on the hubs; it's one-based */
if (parent->devpath[0] == '0')
snprintf(dev->devpath, sizeof dev->devpath,
"%d", port1);
else
snprintf(dev->devpath, sizeof dev->devpath,
"%s.%d", parent->devpath, port1);
dev->dev.parent = &parent->dev;
dev_set_name(&dev->dev, "%d-%s", bus->busnum, dev->devpath);
/* hub driver sets up TT records */
}
dev->portnum = port1;
dev->bus = bus;
dev->parent = parent;
INIT_LIST_HEAD(&dev->filelist);
#ifdef CONFIG_PM
mutex_init(&dev->pm_mutex);
INIT_DELAYED_WORK(&dev->autosuspend, usb_autosuspend_work);
dev->autosuspend_delay = usb_autosuspend_delay * HZ;
dev->connect_time = jiffies;
dev->active_duration = -jiffies;
#endif
if (root_hub) /* Root hub always ok [and always wired] */
dev->authorized = 1;
else {
dev->authorized = usb_hcd->authorized_default;
dev->wusb = usb_bus_is_wusb(bus)? 1 : 0;
}
return dev;
}
请发表评论