コード例 #1
0
ファイル: spi-dw-mmio.c プロジェクト: 020gzh/linux
static int dw_spi_mmio_probe(struct platform_device *pdev)
{
	struct dw_spi_mmio *dwsmmio;
	struct dw_spi *dws;
	struct resource *mem;
	int ret;
	int num_cs;

	dwsmmio = devm_kzalloc(&pdev->dev, sizeof(struct dw_spi_mmio),
			GFP_KERNEL);
	if (!dwsmmio)
		return -ENOMEM;

	dws = &dwsmmio->dws;

	/* Get basic io resource and map it */
	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	dws->regs = devm_ioremap_resource(&pdev->dev, mem);
	if (IS_ERR(dws->regs)) {
		dev_err(&pdev->dev, "SPI region map failed\n");
		return PTR_ERR(dws->regs);
	}

	dws->irq = platform_get_irq(pdev, 0);
	if (dws->irq < 0) {
		dev_err(&pdev->dev, "no irq resource?\n");
		return dws->irq; /* -ENXIO */
	}

	dwsmmio->clk = devm_clk_get(&pdev->dev, NULL);
	if (IS_ERR(dwsmmio->clk))
		return PTR_ERR(dwsmmio->clk);
	ret = clk_prepare_enable(dwsmmio->clk);
	if (ret)
		return ret;

	dws->bus_num = pdev->id;

	dws->max_freq = clk_get_rate(dwsmmio->clk);

	device_property_read_u32(&pdev->dev, "reg-io-width", &dws->reg_io_width);

	num_cs = 4;

	device_property_read_u32(&pdev->dev, "num-cs", &num_cs);

	dws->num_cs = num_cs;

	if (pdev->dev.of_node) {
		int i;

		for (i = 0; i < dws->num_cs; i++) {
			int cs_gpio = of_get_named_gpio(pdev->dev.of_node,
					"cs-gpios", i);

			if (cs_gpio == -EPROBE_DEFER) {
				ret = cs_gpio;
				goto out;
			}

			if (gpio_is_valid(cs_gpio)) {
				ret = devm_gpio_request(&pdev->dev, cs_gpio,
						dev_name(&pdev->dev));
				if (ret)
					goto out;
			}
		}
	}

	ret = dw_spi_add_host(&pdev->dev, dws);
	if (ret)
		goto out;

	platform_set_drvdata(pdev, dwsmmio);
	return 0;

out:
	clk_disable_unprepare(dwsmmio->clk);
	return ret;
}
コード例 #2
0
static int dsps_create_musb_pdev(struct dsps_glue *glue, u8 id)
{
	struct device *dev = glue->dev;
	struct platform_device *pdev = to_platform_device(dev);
	struct musb_hdrc_platform_data  *pdata = dev->platform_data;
	struct device_node *np = pdev->dev.of_node;
	struct musb_hdrc_config	*config;
	struct platform_device	*musb;
	struct resource *res;
	struct resource	resources[2];
	char res_name[11];
	int ret;

	resources[0].start = dsps_control_module_phys[id];
	resources[0].end = resources[0].start + SZ_4 - 1;
	resources[0].flags = IORESOURCE_MEM;

	glue->usb_ctrl[id] = devm_request_and_ioremap(&pdev->dev, resources);
	if (glue->usb_ctrl[id] == NULL) {
		dev_err(dev, "Failed to obtain usb_ctrl%d memory\n", id);
		ret = -ENODEV;
		goto err0;
	}

	/* first resource is for usbss, so start index from 1 */
	res = platform_get_resource(pdev, IORESOURCE_MEM, id + 1);
	if (!res) {
		dev_err(dev, "failed to get memory for instance %d\n", id);
		ret = -ENODEV;
		goto err0;
	}
	res->parent = NULL;
	resources[0] = *res;

	/* first resource is for usbss, so start index from 1 */
	res = platform_get_resource(pdev, IORESOURCE_IRQ, id + 1);
	if (!res) {
		dev_err(dev, "failed to get irq for instance %d\n", id);
		ret = -ENODEV;
		goto err0;
	}
	res->parent = NULL;
	resources[1] = *res;
	resources[1].name = "mc";

	/* allocate the child platform device */
	musb = platform_device_alloc("musb-hdrc", PLATFORM_DEVID_AUTO);
	if (!musb) {
		dev_err(dev, "failed to allocate musb device\n");
		ret = -ENOMEM;
		goto err0;
	}

	musb->dev.parent		= dev;
	musb->dev.dma_mask		= &musb_dmamask;
	musb->dev.coherent_dma_mask	= musb_dmamask;

	glue->musb[id]			= musb;

	ret = platform_device_add_resources(musb, resources, 2);
	if (ret) {
		dev_err(dev, "failed to add resources\n");
		goto err2;
	}

	if (np) {
		pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
		if (!pdata) {
			dev_err(&pdev->dev,
				"failed to allocate musb platfrom data\n");
			ret = -ENOMEM;
			goto err2;
		}

		config = devm_kzalloc(&pdev->dev, sizeof(*config), GFP_KERNEL);
		if (!config) {
			dev_err(&pdev->dev,
				"failed to allocate musb hdrc config\n");
			goto err2;
		}

		of_property_read_u32(np, "num-eps", (u32 *)&config->num_eps);
		of_property_read_u32(np, "ram-bits", (u32 *)&config->ram_bits);
		snprintf(res_name, sizeof(res_name), "port%d-mode", id);
		of_property_read_u32(np, res_name, (u32 *)&pdata->mode);
		of_property_read_u32(np, "power", (u32 *)&pdata->power);
		config->multipoint = of_property_read_bool(np, "multipoint");

		pdata->config		= config;
	}

	pdata->platform_ops		= &dsps_ops;

	ret = platform_device_add_data(musb, pdata, sizeof(*pdata));
	if (ret) {
		dev_err(dev, "failed to add platform_data\n");
		goto err2;
	}

	ret = platform_device_add(musb);
	if (ret) {
		dev_err(dev, "failed to register musb device\n");
		goto err2;
	}

	return 0;

err2:
	platform_device_put(musb);
err0:
	return ret;
}
コード例 #3
0
static int hx8357_probe(struct spi_device *spi)
{
	struct lcd_device *lcdev;
	struct hx8357_data *lcd;
	int i, ret;

	lcd = devm_kzalloc(&spi->dev, sizeof(*lcd), GFP_KERNEL);
	if (!lcd) {
		dev_err(&spi->dev, "Couldn't allocate lcd internal structure!\n");
		return -ENOMEM;
	}

	ret = spi_setup(spi);
	if (ret < 0) {
		dev_err(&spi->dev, "SPI setup failed.\n");
		return ret;
	}

	lcd->spi = spi;

	lcd->reset = of_get_named_gpio(spi->dev.of_node, "gpios-reset", 0);
	if (!gpio_is_valid(lcd->reset)) {
		dev_err(&spi->dev, "Missing dt property: gpios-reset\n");
		return -EINVAL;
	}

	ret = devm_gpio_request_one(&spi->dev, lcd->reset,
				    GPIOF_OUT_INIT_HIGH,
				    "hx8357-reset");
	if (ret) {
		dev_err(&spi->dev,
			"failed to request gpio %d: %d\n",
			lcd->reset, ret);
		return -EINVAL;
	}

	for (i = 0; i < HX8357_NUM_IM_PINS; i++) {
		lcd->im_pins[i] = of_get_named_gpio(spi->dev.of_node,
						"im-gpios", i);
		if (lcd->im_pins[i] == -EPROBE_DEFER) {
			dev_info(&spi->dev, "GPIO requested is not here yet, deferring the probe\n");
			return -EPROBE_DEFER;
		}
		if (!gpio_is_valid(lcd->im_pins[i])) {
			dev_err(&spi->dev, "Missing dt property: im-gpios\n");
			return -EINVAL;
		}

		ret = devm_gpio_request_one(&spi->dev, lcd->im_pins[i],
					GPIOF_OUT_INIT_LOW, "im_pins");
		if (ret) {
			dev_err(&spi->dev, "failed to request gpio %d: %d\n",
				lcd->im_pins[i], ret);
			return -EINVAL;
		}
	}

	lcdev = lcd_device_register("mxsfb", &spi->dev, lcd, &hx8357_ops);
	if (IS_ERR(lcdev)) {
		ret = PTR_ERR(lcdev);
		return ret;
	}
	spi_set_drvdata(spi, lcdev);

	ret = hx8357_lcd_init(lcdev);
	if (ret) {
		dev_err(&spi->dev, "Couldn't initialize panel\n");
		goto init_error;
	}

	dev_info(&spi->dev, "Panel probed\n");

	return 0;

init_error:
	lcd_device_unregister(lcdev);
	return ret;
}
コード例 #4
0
static __devinit int max14688_probe (struct i2c_client *client,
    const struct i2c_device_id *id)
{
    struct max14688_platform_data *pdata = client->dev.platform_data;
    struct max14688 *me;
    u8 chip_id, chip_rev;
    int i, rc;
    u8 pincontrol2 = 0;

    log_dbg(MAX14688_NAME" attached\n");

    log_dbg("wake_lock_init\n");
    wake_lock_init(&ear_key_wake_lock, WAKE_LOCK_SUSPEND, "ear_key");

    me = kzalloc(sizeof(struct max14688), GFP_KERNEL);

    if (me == NULL) {
	    log_err("Failed to allloate headset per device info\n");
	    return -ENOMEM;
    }

    if (client->dev.of_node) {
	    pdata = devm_kzalloc(&client->dev, sizeof(struct max14688_platform_data), GFP_KERNEL);
	    if (unlikely(!pdata)) {
		    log_err("out of memory (%uB requested)\n", sizeof(struct max14688_platform_data));
		    return -ENOMEM;
	    }
	    client->dev.platform_data = pdata;

	    max14688_parse_dt(&client->dev, pdata);
    } else {
	    pdata = devm_kzalloc(&client->dev, sizeof(struct max14688_platform_data), GFP_KERNEL);
	    if (unlikely(!pdata)) {
		    log_err("out of memory (%uB requested)\n", sizeof(struct max14688_platform_data));
		    return -ENOMEM;
	    } else {
		    pdata = client->dev.platform_data;
	    }
    }

    i2c_set_clientdata(client, me);

    spin_lock_init(&me->irq_lock);
    mutex_init(&me->lock);
    me->dev  = &client->dev;
    me->kobj = &client->dev.kobj;
    me->irq  = -1;

    me->gpio_int = pdata->gpio_int;
    me->gpio_detect = pdata->gpio_detect;

    INIT_DELAYED_WORK(&me->irq_work, max14688_irq_work);
    INIT_DELAYED_WORK(&me->det_work, max14688_det_work);
#ifdef I2C_SUSPEND_WORKAROUND
    INIT_DELAYED_WORK(&me->check_suspended_work, max14688_check_suspended_worker);
#endif

    rc = gpio_request(me->gpio_detect, MAX14688_NAME"-detect");
    if (unlikely(rc)) {
	    return rc;
    }

    rc = gpio_direction_input(me->gpio_detect);
    if (rc < 0) {
	    log_err("Failed to configure gpio%d (me->gpio_detect) gpio_direction_input\n", me->gpio_detect);
	    gpio_free(me->gpio_detect);
	    return rc;
    }

    rc = gpio_request(me->gpio_int, MAX14688_NAME"-irq");
    if (unlikely(rc)) {
	    return rc;
    }

    rc = gpio_direction_input(me->gpio_int);
    if (rc < 0) {
	    log_err("Failed to configure gpio%d (me->gpio_int) gpio_direction_input\n", me->gpio_int);
	    gpio_free(me->gpio_int);
	    return rc;
    }

    me->irq = gpio_to_irq(me->gpio_int);

    /* Save jack lookup table given via platform data */
    me->jack_matches        = pdata->jack_matches;
    me->num_of_jack_matches = pdata->num_of_jack_matches;

    /* Save button lookup table given via platform data */
    me->button_matches        = pdata->button_matches;
    me->num_of_button_matches = pdata->num_of_button_matches;

    me->matched_jack   = -1;
    me->matched_button = -1;

    /* Platform-specific Calls */
    me->detect_jack = pdata->detect_jack;
    me->read_mic_impedence = pdata->read_mic_impedence;
    me->read_left_impedence = pdata->read_left_impedence;
    me->report_jack = pdata->report_jack;
    me->report_button = pdata->report_button;

    /* Disable & Clear all interrupts */
    max14688_write(me, MASK, 0x00);
    max14688_read(me, INTERRUPT, &me->irq_saved);

    /* INT AUTO disable(INT follows the state diagram and flow chart) */
    max14688_read(me, PINCONTROL2, &pincontrol2);
    max14688_write(me, PINCONTROL2, ~PINCONTROL2_INTAUTO & pincontrol2);
    max14688_read(me, PINCONTROL2, &pincontrol2);

    log_dbg("%s[pincontrol2 = %d]\n", __func__, pincontrol2);

    /* Default MODE setting */
    max14688_write_mode0(me, MAX14688_MODE_LOW);
    max14688_write_mode1(me, MAX14688_MODE_LOW);

    me->irq_saved = 0;
    me->irq_unmask = 0;

    log_dbg("%s[me->irq_saved = %d]\n", __func__, me->irq_saved);

    /* Register input_dev */
    me->input_dev = input_allocate_device();
    if (unlikely(!me->input_dev)) {
	    log_err("failed to allocate memory for new input device\n");
	    rc = -ENOMEM;
	    goto abort;
    }
    /* initialize switch device */
    me->sdev.name             = pdata->switch_name;

    rc = switch_dev_register(&me->sdev);

    if (rc < 0) {
	    log_err("Failed to register switch device\n");
	    switch_dev_unregister(&me->sdev);
	    goto abort;
    }

    me->input_dev->name       = DRIVER_NAME;
    me->input_dev->phys       = DRIVER_NAME"/input0";
    me->input_dev->dev.parent = me->dev;

    for (i = 0; i < me->num_of_jack_matches; i++) {
	    if (likely(me->jack_matches[i].evt_type < EV_MAX)) {
		    input_set_capability(me->input_dev,
				    me->jack_matches[i].evt_type, me->jack_matches[i].evt_code1);
		    if (likely(me->jack_matches[i].evt_code2))
			    input_set_capability(me->input_dev,
					    me->jack_matches[i].evt_type, me->jack_matches[i].evt_code2);
	    }
    }

    for (i = 0; i < me->num_of_button_matches; i++) {
	    if (likely(me->button_matches[i].evt_type < EV_MAX)) {
		    input_set_capability(me->input_dev,
				    me->button_matches[i].evt_type, me->button_matches[i].evt_code);
	    }
    }

    rc = input_register_device(me->input_dev);
    if (unlikely(rc)) {
	    log_err("failed to register input device [%d]\n", rc);
	    input_free_device(me->input_dev);
	    me->input_dev = NULL;
	    goto abort;
    }

    /* Create max14688 sysfs attributes */
    me->attr_grp = &max14688_attr_group;
    rc = sysfs_create_group(me->kobj, me->attr_grp);
    if (unlikely(rc)) {
	    log_err("failed to create attribute group [%d]\n", rc);
	    me->attr_grp = NULL;
	    goto abort;
    }

    /* Get MAX14688 IRQ */
    if (unlikely(me->irq < 0)) {
	    log_warn("interrupt disabled\n");
    } else {
	    /* Request system IRQ for MAX14688 */
	    rc = request_threaded_irq(me->irq, NULL, max14688_isr,
			    IRQF_ONESHOT | IRQF_TRIGGER_FALLING, DRIVER_NAME, me);
	    if (unlikely(rc < 0)) {
		    log_err("failed to request IRQ(%u) [%d]\n", me->irq, rc);
		    me->irq = -1;
		    goto abort;
	    }
	    disable_irq((unsigned int)me->irq);
    }

    max14688_enable_irq(me, IRQ_DET);

    /* Complete initialization */

    log_info(DRIVER_DESC" "DRIVER_VERSION" Installed\n");

    chip_id  = 0;
    chip_rev = 0;
    max14688_read_device_id(me, &chip_id, &chip_rev);
    log_info("chip id %02X rev %02X\n", chip_id, chip_rev);

#ifdef CONFIG_EARJACK_DEBUGGER
    if (lge_get_board_revno() < HW_REV_1_0) {
	    if (!(max14688_get_status(me, STATUS_INT) && max14688_get_status(me, STATUS_MICIN))) {
		log_info("not connecting earjack debugger\n");
		msm_serial_set_uart_console(0);
	}
    }
#endif
    if (me->detect_jack(me->dev)) {
	max14688_irq_jack_inserted(me);
    }

    return 0;

abort:
    i2c_set_clientdata(client, NULL);
    max14688_destroy(me);
    return rc;
}
コード例 #5
0
static int amd_xgbe_phy_probe(struct phy_device *phydev)
{
	struct amd_xgbe_phy_priv *priv;
	struct platform_device *phy_pdev;
	struct device *dev, *phy_dev;
	unsigned int phy_resnum, phy_irqnum;
	int ret;

	if (!phydev->bus || !phydev->bus->parent)
		return -EINVAL;

	dev = phydev->bus->parent;

	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
	if (!priv)
		return -ENOMEM;

	priv->pdev = to_platform_device(dev);
	priv->adev = ACPI_COMPANION(dev);
	priv->dev = dev;
	priv->phydev = phydev;
	mutex_init(&priv->an_mutex);
	INIT_WORK(&priv->an_irq_work, amd_xgbe_an_irq_work);
	INIT_WORK(&priv->an_work, amd_xgbe_an_state_machine);

	if (!priv->adev || acpi_disabled) {
		struct device_node *bus_node;
		struct device_node *phy_node;

		bus_node = priv->dev->of_node;
		phy_node = of_parse_phandle(bus_node, "phy-handle", 0);
		if (!phy_node) {
			dev_err(dev, "unable to parse phy-handle\n");
			ret = -EINVAL;
			goto err_priv;
		}

		phy_pdev = of_find_device_by_node(phy_node);
		of_node_put(phy_node);

		if (!phy_pdev) {
			dev_err(dev, "unable to obtain phy device\n");
			ret = -EINVAL;
			goto err_priv;
		}

		phy_resnum = 0;
		phy_irqnum = 0;
	} else {
		/* In ACPI, the XGBE and PHY resources are the grouped
		 * together with the PHY resources at the end
		 */
		phy_pdev = priv->pdev;
		phy_resnum = amd_xgbe_phy_resource_count(phy_pdev,
							 IORESOURCE_MEM) - 3;
		phy_irqnum = amd_xgbe_phy_resource_count(phy_pdev,
							 IORESOURCE_IRQ) - 1;
	}
	phy_dev = &phy_pdev->dev;

	/* Get the device mmio areas */
	priv->rxtx_res = platform_get_resource(phy_pdev, IORESOURCE_MEM,
					       phy_resnum++);
	priv->rxtx_regs = devm_ioremap_resource(dev, priv->rxtx_res);
	if (IS_ERR(priv->rxtx_regs)) {
		dev_err(dev, "rxtx ioremap failed\n");
		ret = PTR_ERR(priv->rxtx_regs);
		goto err_put;
	}

	priv->sir0_res = platform_get_resource(phy_pdev, IORESOURCE_MEM,
					       phy_resnum++);
	priv->sir0_regs = devm_ioremap_resource(dev, priv->sir0_res);
	if (IS_ERR(priv->sir0_regs)) {
		dev_err(dev, "sir0 ioremap failed\n");
		ret = PTR_ERR(priv->sir0_regs);
		goto err_rxtx;
	}

	priv->sir1_res = platform_get_resource(phy_pdev, IORESOURCE_MEM,
					       phy_resnum++);
	priv->sir1_regs = devm_ioremap_resource(dev, priv->sir1_res);
	if (IS_ERR(priv->sir1_regs)) {
		dev_err(dev, "sir1 ioremap failed\n");
		ret = PTR_ERR(priv->sir1_regs);
		goto err_sir0;
	}

	/* Get the auto-negotiation interrupt */
	ret = platform_get_irq(phy_pdev, phy_irqnum);
	if (ret < 0) {
		dev_err(dev, "platform_get_irq failed\n");
		goto err_sir1;
	}
	priv->an_irq = ret;

	/* Get the device speed set property */
	ret = device_property_read_u32(phy_dev, XGBE_PHY_SPEEDSET_PROPERTY,
				       &priv->speed_set);
	if (ret) {
		dev_err(dev, "invalid %s property\n",
			XGBE_PHY_SPEEDSET_PROPERTY);
		goto err_sir1;
	}

	switch (priv->speed_set) {
	case AMD_XGBE_PHY_SPEEDSET_1000_10000:
	case AMD_XGBE_PHY_SPEEDSET_2500_10000:
		break;
	default:
		dev_err(dev, "invalid %s property\n",
			XGBE_PHY_SPEEDSET_PROPERTY);
		ret = -EINVAL;
		goto err_sir1;
	}

	if (device_property_present(phy_dev, XGBE_PHY_BLWC_PROPERTY)) {
		ret = device_property_read_u32_array(phy_dev,
						     XGBE_PHY_BLWC_PROPERTY,
						     priv->serdes_blwc,
						     XGBE_PHY_SPEEDS);
		if (ret) {
			dev_err(dev, "invalid %s property\n",
				XGBE_PHY_BLWC_PROPERTY);
			goto err_sir1;
		}
	} else {
		memcpy(priv->serdes_blwc, amd_xgbe_phy_serdes_blwc,
		       sizeof(priv->serdes_blwc));
	}

	if (device_property_present(phy_dev, XGBE_PHY_CDR_RATE_PROPERTY)) {
		ret = device_property_read_u32_array(phy_dev,
						     XGBE_PHY_CDR_RATE_PROPERTY,
						     priv->serdes_cdr_rate,
						     XGBE_PHY_SPEEDS);
		if (ret) {
			dev_err(dev, "invalid %s property\n",
				XGBE_PHY_CDR_RATE_PROPERTY);
			goto err_sir1;
		}
	} else {
		memcpy(priv->serdes_cdr_rate, amd_xgbe_phy_serdes_cdr_rate,
		       sizeof(priv->serdes_cdr_rate));
	}

	if (device_property_present(phy_dev, XGBE_PHY_PQ_SKEW_PROPERTY)) {
		ret = device_property_read_u32_array(phy_dev,
						     XGBE_PHY_PQ_SKEW_PROPERTY,
						     priv->serdes_pq_skew,
						     XGBE_PHY_SPEEDS);
		if (ret) {
			dev_err(dev, "invalid %s property\n",
				XGBE_PHY_PQ_SKEW_PROPERTY);
			goto err_sir1;
		}
	} else {
		memcpy(priv->serdes_pq_skew, amd_xgbe_phy_serdes_pq_skew,
		       sizeof(priv->serdes_pq_skew));
	}

	if (device_property_present(phy_dev, XGBE_PHY_TX_AMP_PROPERTY)) {
		ret = device_property_read_u32_array(phy_dev,
						     XGBE_PHY_TX_AMP_PROPERTY,
						     priv->serdes_tx_amp,
						     XGBE_PHY_SPEEDS);
		if (ret) {
			dev_err(dev, "invalid %s property\n",
				XGBE_PHY_TX_AMP_PROPERTY);
			goto err_sir1;
		}
	} else {
		memcpy(priv->serdes_tx_amp, amd_xgbe_phy_serdes_tx_amp,
		       sizeof(priv->serdes_tx_amp));
	}

	phydev->priv = priv;

	if (!priv->adev || acpi_disabled)
		platform_device_put(phy_pdev);

	return 0;

err_sir1:
	devm_iounmap(dev, priv->sir1_regs);
	devm_release_mem_region(dev, priv->sir1_res->start,
				resource_size(priv->sir1_res));

err_sir0:
	devm_iounmap(dev, priv->sir0_regs);
	devm_release_mem_region(dev, priv->sir0_res->start,
				resource_size(priv->sir0_res));

err_rxtx:
	devm_iounmap(dev, priv->rxtx_regs);
	devm_release_mem_region(dev, priv->rxtx_res->start,
				resource_size(priv->rxtx_res));

err_put:
	if (!priv->adev || acpi_disabled)
		platform_device_put(phy_pdev);

err_priv:
	devm_kfree(dev, priv);

	return ret;
}
コード例 #6
0
ファイル: phy-twl6030-usb.c プロジェクト: 020gzh/linux
static int twl6030_usb_probe(struct platform_device *pdev)
{
	u32 ret;
	struct twl6030_usb	*twl;
	int			status, err;
	struct device_node	*np = pdev->dev.of_node;
	struct device		*dev = &pdev->dev;
	struct twl4030_usb_data	*pdata = dev_get_platdata(dev);

	twl = devm_kzalloc(dev, sizeof(*twl), GFP_KERNEL);
	if (!twl)
		return -ENOMEM;

	twl->dev		= &pdev->dev;
	twl->irq1		= platform_get_irq(pdev, 0);
	twl->irq2		= platform_get_irq(pdev, 1);
	twl->linkstat		= MUSB_UNKNOWN;

	twl->comparator.set_vbus	= twl6030_set_vbus;
	twl->comparator.start_srp	= twl6030_start_srp;

	ret = omap_usb2_set_comparator(&twl->comparator);
	if (ret == -ENODEV) {
		dev_info(&pdev->dev, "phy not ready, deferring probe");
		return -EPROBE_DEFER;
	}

	if (np) {
		twl->regulator = "usb";
	} else if (pdata) {
		if (pdata->features & TWL6032_SUBCLASS)
			twl->regulator = "ldousb";
		else
			twl->regulator = "vusb";
	} else {
		dev_err(&pdev->dev, "twl6030 initialized without pdata\n");
		return -EINVAL;
	}

	/* init spinlock for workqueue */
	spin_lock_init(&twl->lock);

	err = twl6030_usb_ldo_init(twl);
	if (err) {
		dev_err(&pdev->dev, "ldo init failed\n");
		return err;
	}

	platform_set_drvdata(pdev, twl);
	if (device_create_file(&pdev->dev, &dev_attr_vbus))
		dev_warn(&pdev->dev, "could not create sysfs file\n");

	INIT_WORK(&twl->set_vbus_work, otg_set_vbus_work);

	status = request_threaded_irq(twl->irq1, NULL, twl6030_usbotg_irq,
			IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING | IRQF_ONESHOT,
			"twl6030_usb", twl);
	if (status < 0) {
		dev_err(&pdev->dev, "can't get IRQ %d, err %d\n",
			twl->irq1, status);
		device_remove_file(twl->dev, &dev_attr_vbus);
		return status;
	}

	status = request_threaded_irq(twl->irq2, NULL, twl6030_usb_irq,
			IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING | IRQF_ONESHOT,
			"twl6030_usb", twl);
	if (status < 0) {
		dev_err(&pdev->dev, "can't get IRQ %d, err %d\n",
			twl->irq2, status);
		free_irq(twl->irq1, twl);
		device_remove_file(twl->dev, &dev_attr_vbus);
		return status;
	}

	twl->asleep = 0;
	twl6030_enable_irq(twl);
	dev_info(&pdev->dev, "Initialized TWL6030 USB module\n");

	return 0;
}
コード例 #7
0
static int pwm_backlight_probe(struct platform_device *pdev)
{
	struct backlight_properties props;
	struct platform_pwm_backlight_data *data = NULL;
	struct backlight_device *bl;
	struct pwm_bl_data *pb;
	const char *pwm_request_label = NULL;
	int ret;
	int bl_delay_on = 0;
	printk("[BACKLIGHT] %s : %d\n", __func__, __LINE__);
	if (pdev->dev.platform_data)
		data = pdev->dev.platform_data;

	else if (pdev->dev.of_node) {
		u32 val;
		data = kzalloc(sizeof(struct platform_pwm_backlight_data),
				GFP_KERNEL);
		if (!data)
			return -ENOMEM;

		if (of_property_read_u32(pdev->dev.of_node, "pwm-id", &val)) {
			ret = -EINVAL;
			goto err_read;
		}
		data->pwm_id = val;

		if (of_property_read_u32(pdev->dev.of_node,
				"max-brightness", &val)) {
			ret = -EINVAL;
			goto err_read;
		}
		data->max_brightness = val;

		if (of_property_read_u32(pdev->dev.of_node,
				"dft-brightness", &val)) {
			ret = -EINVAL;
			goto err_read;
		}
		data->dft_brightness = val;

		if (of_property_read_u32(pdev->dev.of_node,
				"polarity", &val)) {
			ret = -EINVAL;
			goto err_read;
		}
		data->polarity = val;

		if (of_property_read_u32(pdev->dev.of_node,
				"pwm-period-ns", &val)) {
			ret = -EINVAL;
			goto err_read;
		}
		data->pwm_period_ns = val;

		if (of_property_read_string(pdev->dev.of_node,
			"pwm-request-label", &pwm_request_label)) {
			ret = -EINVAL;
			goto err_read;
		}

		if (of_property_read_u32(pdev->dev.of_node,
				"bl-on-delay", &val)) {
			bl_delay_on = 0;
		} else
			bl_delay_on = val;

		if (of_property_read_u32(pdev->dev.of_node,
				"pwm_pin_name", &val)) {
			pwm_pin = -1;
		} else
			pwm_pin = val;

		if (of_property_read_u32(pdev->dev.of_node,
				"pwm_pin_reboot_func", &val)) {
			pwm_pin_reboot_func = -1;
		} else
			pwm_pin_reboot_func = val;

		pdev->dev.platform_data = data;

	}
	if (!data) {
		dev_err(&pdev->dev, "failed to find platform data\n");
		return -EINVAL;
	}

	if (data->init) {
		ret = data->init(&pdev->dev);
		if (ret < 0)
			return ret;
	}

	pb = devm_kzalloc(&pdev->dev, sizeof(*pb), GFP_KERNEL);
	if (!pb) {
		dev_err(&pdev->dev, "no memory for state\n");
		ret = -ENOMEM;
		goto err_alloc;
	}

	pb->period = data->pwm_period_ns;

	pb->notify = data->notify;
	pb->notify_after = data->notify_after;
	pb->check_fb = data->check_fb;
	pb->lth_brightness = data->lth_brightness *
		(data->pwm_period_ns / data->max_brightness);
	pb->dev = &pdev->dev;
	if (pdev->dev.of_node)
		pb->pwm = pwm_request(data->pwm_id, pwm_request_label);
	else
		pb->pwm = pwm_request(data->pwm_id, "backlight");

	if (IS_ERR(pb->pwm)) {
		dev_err(&pdev->dev, "unable to request PWM for backlight\n");
		ret = PTR_ERR(pb->pwm);
		goto err_alloc;
	} else
		dev_dbg(&pdev->dev, "got pwm for backlight\n");

	memset(&props, 0, sizeof(struct backlight_properties));
	props.type = BACKLIGHT_RAW;
	props.max_brightness = data->max_brightness;
	//bl = backlight_device_register(dev_name(&pdev->dev), &pdev->dev, pb,
	//			       &pwm_backlight_ops, &props);

	bl = backlight_device_register("panel", &pdev->dev, pb,
				       &pwm_backlight_ops, &props);

	if (IS_ERR(bl)) {
		dev_err(&pdev->dev, "failed to register backlight\n");
		ret = PTR_ERR(bl);
		goto err_bl;
	}

	bl->props.brightness = data->dft_brightness;
	pwm_set_polarity(pb->pwm, data->polarity);

	pr_info("pwm_backlight_probe bl-delay-on %d\r\n", bl_delay_on);
	pr_info("pwm_backlight_probe pwm_pin  %d\r\n", pwm_pin);
	pr_info("pwm_backlight_probe pwm_pin_reboot_func %d\r\n", pwm_pin_reboot_func);

	if (bl_delay_on == 0)
		backlight_update_status(bl);
	else {
		INIT_DELAYED_WORK(&(pb->bl_delay_on_work), bl_delay_on_func);
		schedule_delayed_work(&(pb->bl_delay_on_work),
			msecs_to_jiffies(bl_delay_on));
	}

	platform_set_drvdata(pdev, bl);
#ifdef CONFIG_BACKLIGHT_USE_EARLYSUSPEND
	pb->bd_early_suspend.suspend = backlight_driver_early_suspend;
	pb->bd_early_suspend.resume = backlight_driver_late_resume;
	pb->bd_early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN;
	register_early_suspend(&pb->bd_early_suspend);
#endif

	printk("[BACKLIGHT] %s : %d\n", __func__, __LINE__);
	return 0;

err_bl:
	pwm_free(pb->pwm);
err_alloc:
	if (data->exit)
		data->exit(&pdev->dev);
err_read:
	if (pdev->dev.of_node)
		kfree(data);
	return ret;
}
コード例 #8
0
ファイル: coresight-stm.c プロジェクト: AlexShiLucky/linux
static int stm_probe(struct amba_device *adev, const struct amba_id *id)
{
	int ret;
	void __iomem *base;
	unsigned long *guaranteed;
	struct device *dev = &adev->dev;
	struct coresight_platform_data *pdata = NULL;
	struct stm_drvdata *drvdata;
	struct resource *res = &adev->res;
	struct resource ch_res;
	size_t res_size, bitmap_size;
	struct coresight_desc desc = { 0 };
	struct device_node *np = adev->dev.of_node;

	if (np) {
		pdata = of_get_coresight_platform_data(dev, np);
		if (IS_ERR(pdata))
			return PTR_ERR(pdata);
		adev->dev.platform_data = pdata;
	}
	drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL);
	if (!drvdata)
		return -ENOMEM;

	drvdata->dev = &adev->dev;
	drvdata->atclk = devm_clk_get(&adev->dev, "atclk"); /* optional */
	if (!IS_ERR(drvdata->atclk)) {
		ret = clk_prepare_enable(drvdata->atclk);
		if (ret)
			return ret;
	}
	dev_set_drvdata(dev, drvdata);

	base = devm_ioremap_resource(dev, res);
	if (IS_ERR(base))
		return PTR_ERR(base);
	drvdata->base = base;

	ret = stm_get_resource_byname(np, "stm-stimulus-base", &ch_res);
	if (ret)
		return ret;
	drvdata->chs.phys = ch_res.start;

	base = devm_ioremap_resource(dev, &ch_res);
	if (IS_ERR(base))
		return PTR_ERR(base);
	drvdata->chs.base = base;

	drvdata->write_bytes = stm_fundamental_data_size(drvdata);

	if (boot_nr_channel) {
		drvdata->numsp = boot_nr_channel;
		res_size = min((resource_size_t)(boot_nr_channel *
				  BYTES_PER_CHANNEL), resource_size(res));
	} else {
		drvdata->numsp = stm_num_stimulus_port(drvdata);
		res_size = min((resource_size_t)(drvdata->numsp *
				 BYTES_PER_CHANNEL), resource_size(res));
	}
	bitmap_size = BITS_TO_LONGS(drvdata->numsp) * sizeof(long);

	guaranteed = devm_kzalloc(dev, bitmap_size, GFP_KERNEL);
	if (!guaranteed)
		return -ENOMEM;
	drvdata->chs.guaranteed = guaranteed;

	spin_lock_init(&drvdata->spinlock);

	stm_init_default_data(drvdata);
	stm_init_generic_data(drvdata);

	if (stm_register_device(dev, &drvdata->stm, THIS_MODULE)) {
		dev_info(dev,
			 "stm_register_device failed, probing deferred\n");
		return -EPROBE_DEFER;
	}

	desc.type = CORESIGHT_DEV_TYPE_SOURCE;
	desc.subtype.source_subtype = CORESIGHT_DEV_SUBTYPE_SOURCE_SOFTWARE;
	desc.ops = &stm_cs_ops;
	desc.pdata = pdata;
	desc.dev = dev;
	desc.groups = coresight_stm_groups;
	drvdata->csdev = coresight_register(&desc);
	if (IS_ERR(drvdata->csdev)) {
		ret = PTR_ERR(drvdata->csdev);
		goto stm_unregister;
	}

	pm_runtime_put(&adev->dev);

	dev_info(dev, "%s initialized\n", (char *)id->data);
	return 0;

stm_unregister:
	stm_unregister_device(&drvdata->stm);
	return ret;
}
コード例 #9
0
ファイル: core.c プロジェクト: stevenvo/cs500-build-rpi
static int dwc3_probe(struct platform_device *pdev)
{
	struct device		*dev = &pdev->dev;
	struct dwc3_platform_data *pdata = dev_get_platdata(dev);
	struct device_node	*node = dev->of_node;
	struct resource		*res;
	struct dwc3		*dwc;

	int			ret = -ENOMEM;

	void __iomem		*regs;
	void			*mem;

	mem = devm_kzalloc(dev, sizeof(*dwc) + DWC3_ALIGN_MASK, GFP_KERNEL);
	if (!mem) {
		dev_err(dev, "not enough memory\n");
		return -ENOMEM;
	}
	dwc = PTR_ALIGN(mem, DWC3_ALIGN_MASK + 1);
	dwc->mem = mem;

	res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
	if (!res) {
		dev_err(dev, "missing IRQ\n");
		return -ENODEV;
	}
	dwc->xhci_resources[1].start = res->start;
	dwc->xhci_resources[1].end = res->end;
	dwc->xhci_resources[1].flags = res->flags;
	dwc->xhci_resources[1].name = res->name;

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!res) {
		dev_err(dev, "missing memory resource\n");
		return -ENODEV;
	}

	if (node) {
		dwc->maximum_speed = of_usb_get_maximum_speed(node);

		dwc->usb2_phy = devm_usb_get_phy_by_phandle(dev, "usb-phy", 0);
		dwc->usb3_phy = devm_usb_get_phy_by_phandle(dev, "usb-phy", 1);

		dwc->needs_fifo_resize = of_property_read_bool(node, "tx-fifo-resize");
		dwc->dr_mode = of_usb_get_dr_mode(node);
	} else if (pdata) {
		dwc->maximum_speed = pdata->maximum_speed;

		dwc->usb2_phy = devm_usb_get_phy(dev, USB_PHY_TYPE_USB2);
		dwc->usb3_phy = devm_usb_get_phy(dev, USB_PHY_TYPE_USB3);

		dwc->needs_fifo_resize = pdata->tx_fifo_resize;
		dwc->dr_mode = pdata->dr_mode;
	} else {
		dwc->usb2_phy = devm_usb_get_phy(dev, USB_PHY_TYPE_USB2);
		dwc->usb3_phy = devm_usb_get_phy(dev, USB_PHY_TYPE_USB3);
	}

	/* default to superspeed if no maximum_speed passed */
	if (dwc->maximum_speed == USB_SPEED_UNKNOWN)
		dwc->maximum_speed = USB_SPEED_SUPER;

	if (IS_ERR(dwc->usb2_phy)) {
		ret = PTR_ERR(dwc->usb2_phy);

		/*
		 * if -ENXIO is returned, it means PHY layer wasn't
		 * enabled, so it makes no sense to return -EPROBE_DEFER
		 * in that case, since no PHY driver will ever probe.
		 */
		if (ret == -ENXIO)
			return ret;

		dev_err(dev, "no usb2 phy configured\n");
		return -EPROBE_DEFER;
	}

	if (IS_ERR(dwc->usb3_phy)) {
		ret = PTR_ERR(dwc->usb3_phy);

		/*
		 * if -ENXIO is returned, it means PHY layer wasn't
		 * enabled, so it makes no sense to return -EPROBE_DEFER
		 * in that case, since no PHY driver will ever probe.
		 */
		if (ret == -ENXIO)
			return ret;

		dev_err(dev, "no usb3 phy configured\n");
		return -EPROBE_DEFER;
	}

	dwc->xhci_resources[0].start = res->start;
	dwc->xhci_resources[0].end = dwc->xhci_resources[0].start +
					DWC3_XHCI_REGS_END;
	dwc->xhci_resources[0].flags = res->flags;
	dwc->xhci_resources[0].name = res->name;

	res->start += DWC3_GLOBALS_REGS_START;

	/*
	 * Request memory region but exclude xHCI regs,
	 * since it will be requested by the xhci-plat driver.
	 */
	regs = devm_ioremap_resource(dev, res);
	if (IS_ERR(regs))
		return PTR_ERR(regs);

	usb_phy_set_suspend(dwc->usb2_phy, 0);
	usb_phy_set_suspend(dwc->usb3_phy, 0);

	spin_lock_init(&dwc->lock);
	platform_set_drvdata(pdev, dwc);

	dwc->regs	= regs;
	dwc->regs_size	= resource_size(res);
	dwc->dev	= dev;

	dev->dma_mask	= dev->parent->dma_mask;
	dev->dma_parms	= dev->parent->dma_parms;
	dma_set_coherent_mask(dev, dev->parent->coherent_dma_mask);

	pm_runtime_enable(dev);
	pm_runtime_get_sync(dev);
	pm_runtime_forbid(dev);

	dwc3_cache_hwparams(dwc);

	ret = dwc3_alloc_event_buffers(dwc, DWC3_EVENT_BUFFERS_SIZE);
	if (ret) {
		dev_err(dwc->dev, "failed to allocate event buffers\n");
		ret = -ENOMEM;
		goto err0;
	}

	ret = dwc3_core_init(dwc);
	if (ret) {
		dev_err(dev, "failed to initialize core\n");
		goto err0;
	}

	ret = dwc3_event_buffers_setup(dwc);
	if (ret) {
		dev_err(dwc->dev, "failed to setup event buffers\n");
		goto err1;
	}

	if (IS_ENABLED(CONFIG_USB_DWC3_HOST))
		dwc->dr_mode = USB_DR_MODE_HOST;
	else if (IS_ENABLED(CONFIG_USB_DWC3_GADGET))
		dwc->dr_mode = USB_DR_MODE_PERIPHERAL;

	if (dwc->dr_mode == USB_DR_MODE_UNKNOWN)
		dwc->dr_mode = USB_DR_MODE_OTG;

	switch (dwc->dr_mode) {
	case USB_DR_MODE_PERIPHERAL:
		dwc3_set_mode(dwc, DWC3_GCTL_PRTCAP_DEVICE);
		ret = dwc3_gadget_init(dwc);
		if (ret) {
			dev_err(dev, "failed to initialize gadget\n");
			goto err2;
		}
		break;
	case USB_DR_MODE_HOST:
		dwc3_set_mode(dwc, DWC3_GCTL_PRTCAP_HOST);
		ret = dwc3_host_init(dwc);
		if (ret) {
			dev_err(dev, "failed to initialize host\n");
			goto err2;
		}
		break;
	case USB_DR_MODE_OTG:
		dwc3_set_mode(dwc, DWC3_GCTL_PRTCAP_OTG);
		ret = dwc3_host_init(dwc);
		if (ret) {
			dev_err(dev, "failed to initialize host\n");
			goto err2;
		}

		ret = dwc3_gadget_init(dwc);
		if (ret) {
			dev_err(dev, "failed to initialize gadget\n");
			goto err2;
		}
		break;
	default:
		dev_err(dev, "Unsupported mode of operation %d\n", dwc->dr_mode);
		goto err2;
	}

	ret = dwc3_debugfs_init(dwc);
	if (ret) {
		dev_err(dev, "failed to initialize debugfs\n");
		goto err3;
	}

	pm_runtime_allow(dev);

	return 0;

err3:
	switch (dwc->dr_mode) {
	case USB_DR_MODE_PERIPHERAL:
		dwc3_gadget_exit(dwc);
		break;
	case USB_DR_MODE_HOST:
		dwc3_host_exit(dwc);
		break;
	case USB_DR_MODE_OTG:
		dwc3_host_exit(dwc);
		dwc3_gadget_exit(dwc);
		break;
	default:
		/* do nothing */
		break;
	}

err2:
	dwc3_event_buffers_cleanup(dwc);

err1:
	dwc3_core_exit(dwc);

err0:
	dwc3_free_event_buffers(dwc);

	return ret;
}
コード例 #10
0
static int tegra_camera_probe(struct platform_device *pdev)
{
	int err;
	struct tegra_camera_dev *dev;

	dev_info(&pdev->dev, "%s\n", __func__);
	dev = devm_kzalloc(&pdev->dev, sizeof(struct tegra_camera_dev),
			GFP_KERNEL);
	if (!dev) {
		err = -ENOMEM;
		dev_err(&pdev->dev, "%s: unable to allocate memory\n",
			__func__);
		goto alloc_err;
	}

#if defined(CONFIG_ARCH_ACER_T20)
	t20_dev = dev;
#elif defined(CONFIG_ARCH_ACER_T30)
	t30_dev = dev;
#endif

	mutex_init(&dev->tegra_camera_lock);

	/* Powergate VE when boot */
	mutex_lock(&dev->tegra_camera_lock);
	dev->power_refcnt = 0;
#ifndef CONFIG_ARCH_TEGRA_2x_SOC
	err = tegra_powergate_partition(TEGRA_POWERGATE_VENC);
	if (err)
		dev_err(&pdev->dev, "%s: powergate failed.\n", __func__);
#endif
	mutex_unlock(&dev->tegra_camera_lock);

	dev->dev = &pdev->dev;

	/* Get regulator pointer */
#ifdef CONFIG_ARCH_TEGRA_2x_SOC
	dev->reg = regulator_get(&pdev->dev, "vcsi");
#else
	dev->reg = regulator_get(&pdev->dev, "avdd_dsi_csi");
#endif
	if (IS_ERR_OR_NULL(dev->reg)) {
		dev_err(&pdev->dev, "%s: couldn't get regulator\n", __func__);
		return PTR_ERR(dev->reg);
	}

	dev->misc_dev.minor = MISC_DYNAMIC_MINOR;
	dev->misc_dev.name = TEGRA_CAMERA_NAME;
	dev->misc_dev.fops = &tegra_camera_fops;
	dev->misc_dev.parent = &pdev->dev;

	err = misc_register(&dev->misc_dev);
	if (err) {
		dev_err(&pdev->dev, "%s: Unable to register misc device!\n",
		       TEGRA_CAMERA_NAME);
		goto misc_register_err;
	}

	err = tegra_camera_clk_get(pdev, "isp", &dev->isp_clk);
	if (err)
		goto misc_register_err;
	err = tegra_camera_clk_get(pdev, "vi", &dev->vi_clk);
	if (err)
		goto vi_clk_get_err;
	err = tegra_camera_clk_get(pdev, "vi_sensor", &dev->vi_sensor_clk);
	if (err)
		goto vi_sensor_clk_get_err;
	err = tegra_camera_clk_get(pdev, "csus", &dev->csus_clk);
	if (err)
		goto csus_clk_get_err;
	err = tegra_camera_clk_get(pdev, "csi", &dev->csi_clk);
	if (err)
		goto csi_clk_get_err;

	/* dev is set in order to restore in _remove */
	platform_set_drvdata(pdev, dev);

	return 0;

csi_clk_get_err:
	clk_put(dev->csus_clk);
csus_clk_get_err:
	clk_put(dev->vi_sensor_clk);
vi_sensor_clk_get_err:
	clk_put(dev->vi_clk);
vi_clk_get_err:
	clk_put(dev->isp_clk);
misc_register_err:
	regulator_put(dev->reg);
alloc_err:
	return err;
}
コード例 #11
0
ファイル: 8250_aspeed_vuart.c プロジェクト: mkrufky/linux
static int aspeed_vuart_probe(struct platform_device *pdev)
{
	struct uart_8250_port port;
	struct aspeed_vuart *vuart;
	struct device_node *np;
	struct resource *res;
	u32 clk, prop;
	int rc;

	np = pdev->dev.of_node;

	vuart = devm_kzalloc(&pdev->dev, sizeof(*vuart), GFP_KERNEL);
	if (!vuart)
		return -ENOMEM;

	vuart->dev = &pdev->dev;

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	vuart->regs = devm_ioremap_resource(&pdev->dev, res);
	if (IS_ERR(vuart->regs))
		return PTR_ERR(vuart->regs);

	memset(&port, 0, sizeof(port));
	port.port.private_data = vuart;
	port.port.membase = vuart->regs;
	port.port.mapbase = res->start;
	port.port.mapsize = resource_size(res);
	port.port.startup = aspeed_vuart_startup;
	port.port.shutdown = aspeed_vuart_shutdown;
	port.port.dev = &pdev->dev;

	rc = sysfs_create_group(&vuart->dev->kobj, &aspeed_vuart_attr_group);
	if (rc < 0)
		return rc;

	if (of_property_read_u32(np, "clock-frequency", &clk)) {
		vuart->clk = devm_clk_get(&pdev->dev, NULL);
		if (IS_ERR(vuart->clk)) {
			dev_warn(&pdev->dev,
				"clk or clock-frequency not defined\n");
			rc = PTR_ERR(vuart->clk);
			goto err_sysfs_remove;
		}

		rc = clk_prepare_enable(vuart->clk);
		if (rc < 0)
			goto err_sysfs_remove;

		clk = clk_get_rate(vuart->clk);
	}

	/* If current-speed was set, then try not to change it. */
	if (of_property_read_u32(np, "current-speed", &prop) == 0)
		port.port.custom_divisor = clk / (16 * prop);

	/* Check for shifted address mapping */
	if (of_property_read_u32(np, "reg-offset", &prop) == 0)
		port.port.mapbase += prop;

	/* Check for registers offset within the devices address range */
	if (of_property_read_u32(np, "reg-shift", &prop) == 0)
		port.port.regshift = prop;

	/* Check for fifo size */
	if (of_property_read_u32(np, "fifo-size", &prop) == 0)
		port.port.fifosize = prop;

	/* Check for a fixed line number */
	rc = of_alias_get_id(np, "serial");
	if (rc >= 0)
		port.port.line = rc;

	port.port.irq = irq_of_parse_and_map(np, 0);
	port.port.irqflags = IRQF_SHARED;
	port.port.iotype = UPIO_MEM;
	port.port.type = PORT_16550A;
	port.port.uartclk = clk;
	port.port.flags = UPF_SHARE_IRQ | UPF_BOOT_AUTOCONF
		| UPF_FIXED_PORT | UPF_FIXED_TYPE | UPF_NO_THRE_TEST;

	if (of_property_read_bool(np, "no-loopback-test"))
		port.port.flags |= UPF_SKIP_TEST;

	if (port.port.fifosize)
		port.capabilities = UART_CAP_FIFO;

	if (of_property_read_bool(np, "auto-flow-control"))
		port.capabilities |= UART_CAP_AFE;

	rc = serial8250_register_8250_port(&port);
	if (rc < 0)
		goto err_clk_disable;

	vuart->line = rc;

	aspeed_vuart_set_enabled(vuart, true);
	aspeed_vuart_set_host_tx_discard(vuart, true);
	platform_set_drvdata(pdev, vuart);

	return 0;

err_clk_disable:
	clk_disable_unprepare(vuart->clk);
	irq_dispose_mapping(port.port.irq);
err_sysfs_remove:
	sysfs_remove_group(&vuart->dev->kobj, &aspeed_vuart_attr_group);
	return rc;
}
コード例 #12
0
ファイル: core.c プロジェクト: mauelsha/linux
static int sh_pfc_probe(struct platform_device *pdev)
{
	const struct platform_device_id *platid = platform_get_device_id(pdev);
#ifdef CONFIG_OF
	struct device_node *np = pdev->dev.of_node;
#endif
	const struct sh_pfc_soc_info *info;
	struct sh_pfc *pfc;
	int ret;

#ifdef CONFIG_OF
	if (np)
		info = of_device_get_match_data(&pdev->dev);
	else
#endif
		info = platid ? (const void *)platid->driver_data : NULL;

	if (info == NULL)
		return -ENODEV;

	pfc = devm_kzalloc(&pdev->dev, sizeof(*pfc), GFP_KERNEL);
	if (pfc == NULL)
		return -ENOMEM;

	pfc->info = info;
	pfc->dev = &pdev->dev;

	ret = sh_pfc_map_resources(pfc, pdev);
	if (unlikely(ret < 0))
		return ret;

	spin_lock_init(&pfc->lock);

	if (info->ops && info->ops->init) {
		ret = info->ops->init(pfc);
		if (ret < 0)
			return ret;
	}

	pinctrl_provide_dummies();

	ret = sh_pfc_init_ranges(pfc);
	if (ret < 0)
		return ret;

	/*
	 * Initialize pinctrl bindings first
	 */
	ret = sh_pfc_register_pinctrl(pfc);
	if (unlikely(ret != 0))
		return ret;

#ifdef CONFIG_PINCTRL_SH_PFC_GPIO
	/*
	 * Then the GPIO chip
	 */
	ret = sh_pfc_register_gpiochip(pfc);
	if (unlikely(ret != 0)) {
		/*
		 * If the GPIO chip fails to come up we still leave the
		 * PFC state as it is, given that there are already
		 * extant users of it that have succeeded by this point.
		 */
		dev_notice(pfc->dev, "failed to init GPIO chip, ignoring...\n");
	}
#endif

	platform_set_drvdata(pdev, pfc);

	dev_info(pfc->dev, "%s support registered\n", info->name);

	return 0;
}
コード例 #13
0
ファイル: core.c プロジェクト: mauelsha/linux
static int sh_pfc_map_resources(struct sh_pfc *pfc,
				struct platform_device *pdev)
{
	unsigned int num_windows, num_irqs;
	struct sh_pfc_window *windows;
	unsigned int *irqs = NULL;
	struct resource *res;
	unsigned int i;
	int irq;

	/* Count the MEM and IRQ resources. */
	for (num_windows = 0;; num_windows++) {
		res = platform_get_resource(pdev, IORESOURCE_MEM, num_windows);
		if (!res)
			break;
	}
	for (num_irqs = 0;; num_irqs++) {
		irq = platform_get_irq(pdev, num_irqs);
		if (irq == -EPROBE_DEFER)
			return irq;
		if (irq < 0)
			break;
	}

	if (num_windows == 0)
		return -EINVAL;

	/* Allocate memory windows and IRQs arrays. */
	windows = devm_kzalloc(pfc->dev, num_windows * sizeof(*windows),
			       GFP_KERNEL);
	if (windows == NULL)
		return -ENOMEM;

	pfc->num_windows = num_windows;
	pfc->windows = windows;

	if (num_irqs) {
		irqs = devm_kzalloc(pfc->dev, num_irqs * sizeof(*irqs),
				    GFP_KERNEL);
		if (irqs == NULL)
			return -ENOMEM;

		pfc->num_irqs = num_irqs;
		pfc->irqs = irqs;
	}

	/* Fill them. */
	for (i = 0; i < num_windows; i++) {
		res = platform_get_resource(pdev, IORESOURCE_MEM, i);
		windows->phys = res->start;
		windows->size = resource_size(res);
		windows->virt = devm_ioremap_resource(pfc->dev, res);
		if (IS_ERR(windows->virt))
			return -ENOMEM;
		windows++;
	}
	for (i = 0; i < num_irqs; i++)
		*irqs++ = platform_get_irq(pdev, i);

	return 0;
}
コード例 #14
0
static int spdif_probe(struct platform_device *pdev)
{
	/*struct device_node *spdif_np = pdev->dev.of_node;*/
	struct resource *memregion;
	struct resource *mem_res;
	struct rockchip_spdif_info *spdif;
	int ret;

	RK_SPDIF_DBG("Entered %s\n", __func__);

	spdif = devm_kzalloc(&pdev->dev, sizeof(
		struct rockchip_spdif_info), GFP_KERNEL);
	if (!spdif) {
		dev_err(&pdev->dev, "Can't allocate spdif info\n");
		return -ENOMEM;
	}
	platform_set_drvdata(pdev, spdif);

	spin_lock_init(&spdif->lock);

	/* get spdif register regoin. */
	mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!mem_res) {
		dev_err(&pdev->dev, "No memory resource\n");
		ret = -ENOENT;
		goto err_;
	}
	memregion = devm_request_mem_region(&pdev->
			dev, mem_res->start,
			resource_size(mem_res), "rockchip-spdif");
	if (!memregion) {
		dev_err(&pdev->dev, "Memory region already claimed\n");
		ret = -EBUSY;
		goto err_;
	}
	spdif->regs = devm_ioremap(&pdev->dev, memregion->
			start, resource_size(memregion));
	if (!spdif->regs) {
		dev_err(&pdev->dev, "ioremap failed\n");
		ret = -ENOMEM;
		goto err_;
	}

	/* get spdif clock and init. */
	spdif->hclk = devm_clk_get(&pdev->dev, "spdif_hclk");
	if (IS_ERR(spdif->hclk)) {
		dev_err(&pdev->dev, "Can't retrieve spdif hclock\n");
		spdif->hclk = NULL;
	}
	clk_prepare_enable(spdif->hclk);

	/* get spdif clock and init. */
	spdif->clk = devm_clk_get(&pdev->dev, "spdif_mclk");
	if (IS_ERR(spdif->clk)) {
		dev_err(&pdev->dev, "Can't retrieve spdif clock\n");
		ret = -ENOMEM;
		goto err_;
	}
	clk_set_rate(spdif->clk, 12288000);
	clk_set_rate(spdif->clk, 11289600);
	clk_prepare_enable(spdif->clk);

	spdif->dma_playback.addr = mem_res->start + DATA_OUTBUF;
	spdif->dma_playback.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
	spdif->dma_playback.maxburst = 4;

	/* set dev name to driver->name for sound card register */
	dev_set_name(&pdev->dev, "%s", pdev->dev.driver->name);

	ret = snd_soc_register_component(&pdev->
		dev, &rockchip_spdif_component,	&rockchip_spdif_dai, 1);
	if (ret) {
		dev_err(&pdev->dev, "Could not register DAI: %d\n", ret);
		ret = -ENOMEM;
		goto err_;
	}

	ret = rockchip_pcm_platform_register(&pdev->dev);
	if (ret) {
		dev_err(&pdev->dev, "Could not register PCM: %d\n", ret);
		goto err_;
	}

	RK_SPDIF_DBG("spdif:spdif probe ok!\n");

	return 0;

err_:
	platform_set_drvdata(pdev, NULL);

	return ret;
}
コード例 #15
0
static int __devinit max8973_probe(struct i2c_client *client,
				     const struct i2c_device_id *id)
{
	struct max8973_regulator_platform_data *pdata;
	struct regulator_dev *rdev;
	struct max8973_chip *max;
	int ret;

	pdata = client->dev.platform_data;
	if (!pdata) {
		dev_err(&client->dev, "%s(): No Platform data", __func__);
		return -EIO;
	}

	max = devm_kzalloc(&client->dev, sizeof(*max), GFP_KERNEL);
	if (!max) {
		dev_err(&client->dev, "%s(): Memory allocation failed\n",
						__func__);
		return -ENOMEM;
	}

	max->dev = &client->dev;

	max->desc.name = id->name;
	max->desc.id = 0;
	max->desc.ops = &max8973_dcdc_ops;
	max->desc.type = REGULATOR_VOLTAGE;
	max->desc.owner = THIS_MODULE;
	max->regmap = devm_regmap_init_i2c(client, &max8973_regmap_config);
	if (IS_ERR(max->regmap)) {
		ret = PTR_ERR(max->regmap);
		dev_err(&client->dev,
			"%s(): regmap allocation failed with err %d\n",
			__func__, ret);
		return ret;
	}
	i2c_set_clientdata(client, max);

	max->enable_external_control = pdata->enable_ext_control;
	max->dvs_gpio = pdata->dvs_gpio;
	max->curr_gpio_val = pdata->dvs_def_state;
	max->curr_vout_reg = MAX8973_VOUT + pdata->dvs_def_state;
	max->lru_index[0] = max->curr_vout_reg;
	max->valid_dvs_gpio = false;

	if (gpio_is_valid(max->dvs_gpio)) {
		int gpio_flags;
		int i;

		gpio_flags = (pdata->dvs_def_state) ?
				GPIOF_OUT_INIT_HIGH : GPIOF_OUT_INIT_LOW;
		ret = gpio_request_one(max->dvs_gpio,
				gpio_flags, "max8973-dvs");
		if (ret) {
			dev_err(&client->dev,
				"%s(): Could not obtain dvs GPIO %d: %d\n",
				__func__, max->dvs_gpio, ret);
			return ret;
		}
		max->valid_dvs_gpio = true;

		/*
		 * Initialize the lru index with vout_reg id
		 * The index 0 will be most recently used and
		 * set with the max->curr_vout_reg */
		for (i = 0; i < MAX8973_MAX_VOUT_REG; ++i)
			max->lru_index[i] = i;
		max->lru_index[0] = max->curr_vout_reg;
		max->lru_index[max->curr_vout_reg] = 0;
	}

	ret = max8973_init_dcdc(max, pdata);
	if (ret < 0) {
		dev_err(max->dev, "%s(): Init failed with err = %d\n",
				__func__, ret);
		goto err_init;
	}

	/* Register the regulators */
	rdev = regulator_register(&max->desc, &client->dev,
			pdata->reg_init_data, max, NULL);
	if (IS_ERR(rdev)) {
		dev_err(max->dev,
			"%s(): regulator register failed with err %s\n",
			__func__, id->name);
		ret = PTR_ERR(rdev);
		goto err_init;
	}

	max->rdev = rdev;
	return 0;

err_init:
	if (gpio_is_valid(max->dvs_gpio))
		gpio_free(max->dvs_gpio);
	return ret;
}
コード例 #16
0
ファイル: tsc200x-core.c プロジェクト: KaMiila/linux
int tsc200x_probe(struct device *dev, int irq, const struct input_id *tsc_id,
		  struct regmap *regmap,
		  int (*tsc200x_cmd)(struct device *dev, u8 cmd))
{
	const struct tsc2005_platform_data *pdata = dev_get_platdata(dev);
	struct device_node *np = dev->of_node;

	struct tsc200x *ts;
	struct input_dev *input_dev;
	unsigned int max_x = MAX_12BIT;
	unsigned int max_y = MAX_12BIT;
	unsigned int max_p = MAX_12BIT;
	unsigned int fudge_x = TSC200X_DEF_X_FUZZ;
	unsigned int fudge_y = TSC200X_DEF_Y_FUZZ;
	unsigned int fudge_p = TSC200X_DEF_P_FUZZ;
	unsigned int x_plate_ohm = TSC200X_DEF_RESISTOR;
	unsigned int esd_timeout;
	int error;

	if (!np && !pdata) {
		dev_err(dev, "no platform data\n");
		return -ENODEV;
	}

	if (irq <= 0) {
		dev_err(dev, "no irq\n");
		return -ENODEV;
	}

	if (IS_ERR(regmap))
		return PTR_ERR(regmap);

	if (!tsc200x_cmd) {
		dev_err(dev, "no cmd function\n");
		return -ENODEV;
	}

	if (pdata) {
		fudge_x	= pdata->ts_x_fudge;
		fudge_y	= pdata->ts_y_fudge;
		fudge_p	= pdata->ts_pressure_fudge;
		max_x	= pdata->ts_x_max;
		max_y	= pdata->ts_y_max;
		max_p	= pdata->ts_pressure_max;
		x_plate_ohm = pdata->ts_x_plate_ohm;
		esd_timeout = pdata->esd_timeout_ms;
	} else {
		x_plate_ohm = TSC200X_DEF_RESISTOR;
		of_property_read_u32(np, "ti,x-plate-ohms", &x_plate_ohm);
		esd_timeout = 0;
		of_property_read_u32(np, "ti,esd-recovery-timeout-ms",
								&esd_timeout);
	}

	ts = devm_kzalloc(dev, sizeof(*ts), GFP_KERNEL);
	if (!ts)
		return -ENOMEM;

	input_dev = devm_input_allocate_device(dev);
	if (!input_dev)
		return -ENOMEM;

	ts->irq = irq;
	ts->dev = dev;
	ts->idev = input_dev;
	ts->regmap = regmap;
	ts->tsc200x_cmd = tsc200x_cmd;
	ts->x_plate_ohm = x_plate_ohm;
	ts->esd_timeout = esd_timeout;

	ts->reset_gpio = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_HIGH);
	if (IS_ERR(ts->reset_gpio)) {
		error = PTR_ERR(ts->reset_gpio);
		dev_err(dev, "error acquiring reset gpio: %d\n", error);
		return error;
	}

	ts->vio = devm_regulator_get_optional(dev, "vio");
	if (IS_ERR(ts->vio)) {
		error = PTR_ERR(ts->vio);
		dev_err(dev, "vio regulator missing (%d)", error);
		return error;
	}

	if (!ts->reset_gpio && pdata)
		ts->set_reset = pdata->set_reset;

	mutex_init(&ts->mutex);

	spin_lock_init(&ts->lock);
	setup_timer(&ts->penup_timer, tsc200x_penup_timer, (unsigned long)ts);

	INIT_DELAYED_WORK(&ts->esd_work, tsc200x_esd_work);

	snprintf(ts->phys, sizeof(ts->phys),
		 "%s/input-ts", dev_name(dev));

	if (tsc_id->product == 2004) {
		input_dev->name = "TSC200X touchscreen";
	} else {
		input_dev->name = devm_kasprintf(dev, GFP_KERNEL,
						 "TSC%04d touchscreen",
						 tsc_id->product);
		if (!input_dev->name)
			return -ENOMEM;
	}

	input_dev->phys = ts->phys;
	input_dev->id = *tsc_id;
	input_dev->dev.parent = dev;
	input_dev->evbit[0] = BIT(EV_ABS) | BIT(EV_KEY);
	input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);

	input_set_abs_params(input_dev, ABS_X, 0, max_x, fudge_x, 0);
	input_set_abs_params(input_dev, ABS_Y, 0, max_y, fudge_y, 0);
	input_set_abs_params(input_dev, ABS_PRESSURE, 0, max_p, fudge_p, 0);

	if (np)
		touchscreen_parse_properties(input_dev, false);

	input_dev->open = tsc200x_open;
	input_dev->close = tsc200x_close;

	input_set_drvdata(input_dev, ts);

	/* Ensure the touchscreen is off */
	tsc200x_stop_scan(ts);

	error = devm_request_threaded_irq(dev, irq, NULL,
					  tsc200x_irq_thread,
					  IRQF_TRIGGER_RISING | IRQF_ONESHOT,
					  "tsc200x", ts);
	if (error) {
		dev_err(dev, "Failed to request irq, err: %d\n", error);
		return error;
	}

	/* enable regulator for DT */
	if (ts->vio) {
		error = regulator_enable(ts->vio);
		if (error)
			return error;
	}

	dev_set_drvdata(dev, ts);
	error = sysfs_create_group(&dev->kobj, &tsc200x_attr_group);
	if (error) {
		dev_err(dev,
			"Failed to create sysfs attributes, err: %d\n", error);
		goto disable_regulator;
	}

	error = input_register_device(ts->idev);
	if (error) {
		dev_err(dev,
			"Failed to register input device, err: %d\n", error);
		goto err_remove_sysfs;
	}

	irq_set_irq_wake(irq, 1);
	return 0;

err_remove_sysfs:
	sysfs_remove_group(&dev->kobj, &tsc200x_attr_group);
disable_regulator:
	if (ts->vio)
		regulator_disable(ts->vio);
	return error;
}
コード例 #17
0
ファイル: tegra2_emc.c プロジェクト: Lloir/nvidia-linux-3.10
static struct tegra_emc_pdata *tegra_emc_dt_parse_pdata(
		struct platform_device *pdev)
{
	struct device_node *np = pdev->dev.of_node;
	struct device_node *tnp, *iter;
	struct tegra_emc_pdata *pdata;
	int ret, i, num_tables;
	u32 tegra_bct_strapping;

	if (!np)
		return NULL;

	tegra_bct_strapping = tegra_get_bct_strapping();
	if (of_find_property(np, "nvidia,use-ram-code", NULL)) {
		tnp = tegra_emc_ramcode_devnode(np);
		if (!tnp)
			dev_warn(&pdev->dev,
				 "can't find emc table for ram-code 0x%02x\n",
				 tegra_bct_strapping);
	} else
		tnp = of_node_get(np);

	if (!tnp)
		return NULL;

	num_tables = 0;
	for_each_child_of_node(tnp, iter)
		if (of_device_is_compatible(iter, "nvidia,tegra20-emc-table"))
			num_tables++;

	if (!num_tables) {
		pdata = NULL;
		goto out;
	}

	pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
	pdata->tables = devm_kzalloc(&pdev->dev,
				     sizeof(*pdata->tables) * num_tables,
				     GFP_KERNEL);

	i = 0;
	for_each_child_of_node(tnp, iter) {
		u32 prop;

		ret = of_property_read_u32(iter, "clock-frequency", &prop);
		if (ret) {
			dev_err(&pdev->dev, "no clock-frequency in %s\n",
				iter->full_name);
			continue;
		}
		pdata->tables[i].rate = prop;

		ret = of_property_read_u32_array(iter, "nvidia,emc-registers",
						 pdata->tables[i].regs,
						 TEGRA_EMC_NUM_REGS);
		if (ret) {
			dev_err(&pdev->dev,
				"malformed emc-registers property in %s\n",
				iter->full_name);
			continue;
		}

		i++;
	}
コード例 #18
0
ファイル: soc-compress.c プロジェクト: Codefollows/ps4-linux
/**
 * snd_soc_new_compress - create a new compress.
 *
 * @rtd: The runtime for which we will create compress
 * @num: the device index number (zero based - shared with normal PCMs)
 *
 * Return: 0 for success, else error.
 */
int snd_soc_new_compress(struct snd_soc_pcm_runtime *rtd, int num)
{
	struct snd_soc_codec *codec = rtd->codec;
	struct snd_soc_platform *platform = rtd->platform;
	struct snd_soc_dai *codec_dai = rtd->codec_dai;
	struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
	struct snd_compr *compr;
	struct snd_pcm *be_pcm;
	char new_name[64];
	int ret = 0, direction = 0;

	if (rtd->num_codecs > 1) {
		dev_err(rtd->card->dev, "Multicodec not supported for compressed stream\n");
		return -EINVAL;
	}

	/* check client and interface hw capabilities */
	snprintf(new_name, sizeof(new_name), "%s %s-%d",
			rtd->dai_link->stream_name, codec_dai->name, num);

	if (codec_dai->driver->playback.channels_min)
		direction = SND_COMPRESS_PLAYBACK;
	else if (codec_dai->driver->capture.channels_min)
		direction = SND_COMPRESS_CAPTURE;
	else
		return -EINVAL;

	compr = kzalloc(sizeof(*compr), GFP_KERNEL);
	if (compr == NULL) {
		snd_printk(KERN_ERR "Cannot allocate compr\n");
		return -ENOMEM;
	}

	compr->ops = devm_kzalloc(rtd->card->dev, sizeof(soc_compr_ops),
				  GFP_KERNEL);
	if (compr->ops == NULL) {
		dev_err(rtd->card->dev, "Cannot allocate compressed ops\n");
		ret = -ENOMEM;
		goto compr_err;
	}

	if (rtd->dai_link->dynamic) {
		snprintf(new_name, sizeof(new_name), "(%s)",
			rtd->dai_link->stream_name);

		ret = snd_pcm_new_internal(rtd->card->snd_card, new_name, num,
				rtd->dai_link->dpcm_playback,
				rtd->dai_link->dpcm_capture, &be_pcm);
		if (ret < 0) {
			dev_err(rtd->card->dev, "ASoC: can't create compressed for %s\n",
				rtd->dai_link->name);
			goto compr_err;
		}

		rtd->pcm = be_pcm;
		rtd->fe_compr = 1;
		if (rtd->dai_link->dpcm_playback)
			be_pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream->private_data = rtd;
		else if (rtd->dai_link->dpcm_capture)
			be_pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream->private_data = rtd;
		memcpy(compr->ops, &soc_compr_dyn_ops, sizeof(soc_compr_dyn_ops));
	} else
		memcpy(compr->ops, &soc_compr_ops, sizeof(soc_compr_ops));

	/* Add copy callback for not memory mapped DSPs */
	if (platform->driver->compr_ops && platform->driver->compr_ops->copy)
		compr->ops->copy = soc_compr_copy;

	mutex_init(&compr->lock);
	ret = snd_compress_new(rtd->card->snd_card, num, direction, compr);
	if (ret < 0) {
		pr_err("compress asoc: can't create compress for codec %s\n",
			codec->component.name);
		goto compr_err;
	}

	/* DAPM dai link stream work */
	INIT_DELAYED_WORK(&rtd->delayed_work, close_delayed_work);

	rtd->compr = compr;
	compr->private_data = rtd;

	printk(KERN_INFO "compress asoc: %s <-> %s mapping ok\n", codec_dai->name,
		cpu_dai->name);
	return ret;

compr_err:
	kfree(compr);
	return ret;
}
コード例 #19
0
static int __devinit pil_modem_driver_probe(struct platform_device *pdev)
{
	struct modem_data *drv;
	struct resource *res;
	struct pil_desc *desc;
	int ret;

	drv = devm_kzalloc(&pdev->dev, sizeof(*drv), GFP_KERNEL);
	if (!drv)
		return -ENOMEM;
	platform_set_drvdata(pdev, drv);

	drv->irq = platform_get_irq(pdev, 0);
	if (drv->irq < 0)
		return drv->irq;

	drv->xo = devm_clk_get(&pdev->dev, "xo");
	if (IS_ERR(drv->xo))
		return PTR_ERR(drv->xo);

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	drv->base = devm_request_and_ioremap(&pdev->dev, res);
	if (!drv->base)
		return -ENOMEM;

	res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
	drv->wdog = devm_request_and_ioremap(&pdev->dev, res);
	if (!drv->wdog)
		return -ENOMEM;

	res = platform_get_resource(pdev, IORESOURCE_MEM, 2);
	if (!res)
		return -EINVAL;

	drv->cbase = devm_ioremap(&pdev->dev, res->start, resource_size(res));
	if (!drv->cbase)
		return -ENOMEM;

	desc = &drv->pil_desc;
	desc->name = "modem";
	desc->dev = &pdev->dev;
	desc->owner = THIS_MODULE;
	desc->proxy_timeout = 10000;

	if (pas_supported(PAS_MODEM) > 0) {
		desc->ops = &pil_modem_ops_trusted;
		dev_info(&pdev->dev, "using secure boot\n");
	} else {
		desc->ops = &pil_modem_ops;
		dev_info(&pdev->dev, "using non-secure boot\n");
	}
	ret = pil_desc_init(desc);
	if (ret)
		return ret;

	drv->notifier.notifier_call = modem_notif_handler,
	ret = modem_register_notifier(&drv->notifier);
	if (ret)
		goto err_notify;

	drv->subsys_desc.name = "modem";
	drv->subsys_desc.depends_on = "adsp";
	drv->subsys_desc.dev = &pdev->dev;
	drv->subsys_desc.owner = THIS_MODULE;
	drv->subsys_desc.start = modem_start;
	drv->subsys_desc.stop = modem_stop;
	drv->subsys_desc.shutdown = modem_shutdown;
	drv->subsys_desc.powerup = modem_powerup;
	drv->subsys_desc.ramdump = modem_ramdump;
	drv->subsys_desc.crash_shutdown = modem_crash_shutdown;

	INIT_WORK(&drv->fatal_work, modem_fatal_fn);
	INIT_DELAYED_WORK(&drv->unlock_work, modem_unlock_timeout);

	drv->subsys = subsys_register(&drv->subsys_desc);
	if (IS_ERR(drv->subsys)) {
		ret = PTR_ERR(drv->subsys);
		goto err_subsys;
	}

	drv->ramdump_dev = create_ramdump_device("modem", &pdev->dev);
	if (!drv->ramdump_dev) {
		ret = -ENOMEM;
		goto err_ramdump;
	}

	ret = devm_request_irq(&pdev->dev, drv->irq, modem_wdog_bite_irq,
			IRQF_TRIGGER_RISING, "modem_watchdog", drv);
	if (ret)
		goto err_irq;
	return 0;

err_irq:
	destroy_ramdump_device(drv->ramdump_dev);
err_ramdump:
	subsys_unregister(drv->subsys);
err_subsys:
	modem_unregister_notifier(&drv->notifier);
err_notify:
	pil_desc_release(desc);
	return ret;
}
コード例 #20
0
/* create encoder */
struct drm_encoder *xilinx_drm_encoder_create(struct drm_device *drm)
{
	struct xilinx_drm_encoder *encoder;
	struct device_node *sub_node;
	struct i2c_driver *i2c_driver;
	struct drm_i2c_encoder_driver *drm_i2c_driver;
	struct device_driver *device_driver;
	struct platform_driver *platform_driver;
	struct drm_platform_encoder_driver *drm_platform_driver;
	int ret = 0;

	encoder = devm_kzalloc(drm->dev, sizeof(*encoder), GFP_KERNEL);
	if (!encoder)
		return ERR_PTR(-ENOMEM);

	encoder->dpms = DRM_MODE_DPMS_OFF;

	/* initialize encoder */
	encoder->slave.base.possible_crtcs = 1;
	ret = drm_encoder_init(drm, &encoder->slave.base,
			       &xilinx_drm_encoder_funcs,
			       DRM_MODE_ENCODER_TMDS);
	if (ret) {
		DRM_ERROR("failed to initialize drm encoder\n");
		return ERR_PTR(ret);
	}

	drm_encoder_helper_add(&encoder->slave.base,
			       &xilinx_drm_encoder_helper_funcs);

	/* get slave encoder */
	sub_node = of_parse_phandle(drm->dev->of_node, "xlnx,encoder-slave", 0);
	if (!sub_node) {
		DRM_ERROR("failed to get an encoder slave node\n");
		return ERR_PTR(-ENODEV);
	}

	/* initialize slave encoder */
	encoder->i2c_slv = of_find_i2c_device_by_node(sub_node);
	if (encoder->i2c_slv) {
		i2c_driver = to_i2c_driver(encoder->i2c_slv->dev.driver);
		drm_i2c_driver = to_drm_i2c_encoder_driver(i2c_driver);
		if (!drm_i2c_driver) {
			DRM_ERROR("failed to initialize i2c slave\n");
			ret = -EPROBE_DEFER;
			goto err_out;
		}

		ret = drm_i2c_driver->encoder_init(encoder->i2c_slv, drm,
						   &encoder->slave);
	} else {
		encoder->platform_slv = of_find_device_by_node(sub_node);
		if (!encoder->platform_slv) {
			DRM_DEBUG_KMS("failed to get an encoder slv\n");
			return ERR_PTR(-EPROBE_DEFER);
		}

		device_driver = encoder->platform_slv->dev.driver;
		if (!device_driver) {
			DRM_DEBUG_KMS("failed to get device driver\n");
			return ERR_PTR(-EPROBE_DEFER);
		}

		platform_driver = to_platform_driver(device_driver);
		drm_platform_driver =
			to_drm_platform_encoder_driver(platform_driver);
		if (!drm_platform_driver) {
			DRM_ERROR("failed to initialize platform slave\n");
			ret = -EPROBE_DEFER;
			goto err_out;
		}

		ret = drm_platform_driver->encoder_init(encoder->platform_slv,
							drm,
							&encoder->slave);
	}

	of_node_put(sub_node);

	if (ret) {
		DRM_ERROR("failed to initialize encoder slave\n");
		goto err_out;
	}

	if (!encoder->slave.slave_funcs) {
		DRM_ERROR("there's no encoder slave function\n");
		ret = -ENODEV;
		goto err_out;
	}

	return &encoder->slave.base;

err_out:
	return ERR_PTR(ret);
}
コード例 #21
0
ファイル: platform.c プロジェクト: forgivemyheart/linux
static struct dma_chan *dw_dma_of_xlate(struct of_phandle_args *dma_spec,
					struct of_dma *ofdma)
{
	struct dw_dma *dw = ofdma->of_dma_data;
	struct dw_dma_slave slave = {
		.dma_dev = dw->dma.dev,
	};
	dma_cap_mask_t cap;

	if (dma_spec->args_count != 3)
		return NULL;

	slave.src_id = dma_spec->args[0];
	slave.dst_id = dma_spec->args[0];
	slave.m_master = dma_spec->args[1];
	slave.p_master = dma_spec->args[2];

	if (WARN_ON(slave.src_id >= DW_DMA_MAX_NR_REQUESTS ||
		    slave.dst_id >= DW_DMA_MAX_NR_REQUESTS ||
		    slave.m_master >= dw->pdata->nr_masters ||
		    slave.p_master >= dw->pdata->nr_masters))
		return NULL;

	dma_cap_zero(cap);
	dma_cap_set(DMA_SLAVE, cap);

	/* TODO: there should be a simpler way to do this */
	return dma_request_channel(cap, dw_dma_filter, &slave);
}

#ifdef CONFIG_ACPI
static bool dw_dma_acpi_filter(struct dma_chan *chan, void *param)
{
	struct acpi_dma_spec *dma_spec = param;
	struct dw_dma_slave slave = {
		.dma_dev = dma_spec->dev,
		.src_id = dma_spec->slave_id,
		.dst_id = dma_spec->slave_id,
		.m_master = 0,
		.p_master = 1,
	};

	return dw_dma_filter(chan, &slave);
}

static void dw_dma_acpi_controller_register(struct dw_dma *dw)
{
	struct device *dev = dw->dma.dev;
	struct acpi_dma_filter_info *info;
	int ret;

	info = devm_kzalloc(dev, sizeof(*info), GFP_KERNEL);
	if (!info)
		return;

	dma_cap_zero(info->dma_cap);
	dma_cap_set(DMA_SLAVE, info->dma_cap);
	info->filter_fn = dw_dma_acpi_filter;

	ret = devm_acpi_dma_controller_register(dev, acpi_dma_simple_xlate,
						info);
	if (ret)
		dev_err(dev, "could not register acpi_dma_controller\n");
}
#else /* !CONFIG_ACPI */
static inline void dw_dma_acpi_controller_register(struct dw_dma *dw) {}
#endif /* !CONFIG_ACPI */

#ifdef CONFIG_OF
static struct dw_dma_platform_data *
dw_dma_parse_dt(struct platform_device *pdev)
{
	struct device_node *np = pdev->dev.of_node;
	struct dw_dma_platform_data *pdata;
	u32 tmp, arr[DW_DMA_MAX_NR_MASTERS], mb[DW_DMA_MAX_NR_CHANNELS];
	u32 nr_masters;
	u32 nr_channels;

	if (!np) {
		dev_err(&pdev->dev, "Missing DT data\n");
		return NULL;
	}

	if (of_property_read_u32(np, "dma-masters", &nr_masters))
		return NULL;
	if (nr_masters < 1 || nr_masters > DW_DMA_MAX_NR_MASTERS)
		return NULL;

	if (of_property_read_u32(np, "dma-channels", &nr_channels))
		return NULL;
	if (nr_channels > DW_DMA_MAX_NR_CHANNELS)
		return NULL;

	pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
	if (!pdata)
		return NULL;

	pdata->nr_masters = nr_masters;
	pdata->nr_channels = nr_channels;

	if (of_property_read_bool(np, "is_private"))
		pdata->is_private = true;

	/*
	 * All known devices, which use DT for configuration, support
	 * memory-to-memory transfers. So enable it by default.
	 */
	pdata->is_memcpy = true;

	if (!of_property_read_u32(np, "chan_allocation_order", &tmp))
		pdata->chan_allocation_order = (unsigned char)tmp;

	if (!of_property_read_u32(np, "chan_priority", &tmp))
		pdata->chan_priority = tmp;

	if (!of_property_read_u32(np, "block_size", &tmp))
		pdata->block_size = tmp;

	if (!of_property_read_u32_array(np, "data-width", arr, nr_masters)) {
		for (tmp = 0; tmp < nr_masters; tmp++)
			pdata->data_width[tmp] = arr[tmp];
	} else if (!of_property_read_u32_array(np, "data_width", arr, nr_masters)) {
		for (tmp = 0; tmp < nr_masters; tmp++)
			pdata->data_width[tmp] = BIT(arr[tmp] & 0x07);
	}

	if (!of_property_read_u32_array(np, "multi-block", mb, nr_channels)) {
		for (tmp = 0; tmp < nr_channels; tmp++)
			pdata->multi_block[tmp] = mb[tmp];
	} else {
		for (tmp = 0; tmp < nr_channels; tmp++)
			pdata->multi_block[tmp] = 1;
	}

	return pdata;
}
#else
static inline struct dw_dma_platform_data *
dw_dma_parse_dt(struct platform_device *pdev)
{
	return NULL;
}
#endif

static int dw_probe(struct platform_device *pdev)
{
	struct dw_dma_chip *chip;
	struct device *dev = &pdev->dev;
	struct resource *mem;
	const struct dw_dma_platform_data *pdata;
	int err;

	chip = devm_kzalloc(dev, sizeof(*chip), GFP_KERNEL);
	if (!chip)
		return -ENOMEM;

	chip->irq = platform_get_irq(pdev, 0);
	if (chip->irq < 0)
		return chip->irq;

	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	chip->regs = devm_ioremap_resource(dev, mem);
	if (IS_ERR(chip->regs))
		return PTR_ERR(chip->regs);

	err = dma_coerce_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32));
	if (err)
		return err;

	pdata = dev_get_platdata(dev);
	if (!pdata)
		pdata = dw_dma_parse_dt(pdev);

	chip->dev = dev;
	chip->pdata = pdata;

	chip->clk = devm_clk_get(chip->dev, "hclk");
	if (IS_ERR(chip->clk))
		return PTR_ERR(chip->clk);
	err = clk_prepare_enable(chip->clk);
	if (err)
		return err;

	pm_runtime_enable(&pdev->dev);

	err = dw_dma_probe(chip);
	if (err)
		goto err_dw_dma_probe;

	platform_set_drvdata(pdev, chip);

	if (pdev->dev.of_node) {
		err = of_dma_controller_register(pdev->dev.of_node,
						 dw_dma_of_xlate, chip->dw);
		if (err)
			dev_err(&pdev->dev,
				"could not register of_dma_controller\n");
	}

	if (ACPI_HANDLE(&pdev->dev))
		dw_dma_acpi_controller_register(chip->dw);

	return 0;

err_dw_dma_probe:
	pm_runtime_disable(&pdev->dev);
	clk_disable_unprepare(chip->clk);
	return err;
}

static int dw_remove(struct platform_device *pdev)
{
	struct dw_dma_chip *chip = platform_get_drvdata(pdev);

	if (pdev->dev.of_node)
		of_dma_controller_free(pdev->dev.of_node);

	dw_dma_remove(chip);
	pm_runtime_disable(&pdev->dev);
	clk_disable_unprepare(chip->clk);

	return 0;
}

static void dw_shutdown(struct platform_device *pdev)
{
	struct dw_dma_chip *chip = platform_get_drvdata(pdev);

	/*
	 * We have to call dw_dma_disable() to stop any ongoing transfer. On
	 * some platforms we can't do that since DMA device is powered off.
	 * Moreover we have no possibility to check if the platform is affected
	 * or not. That's why we call pm_runtime_get_sync() / pm_runtime_put()
	 * unconditionally. On the other hand we can't use
	 * pm_runtime_suspended() because runtime PM framework is not fully
	 * used by the driver.
	 */
	pm_runtime_get_sync(chip->dev);
	dw_dma_disable(chip);
	pm_runtime_put_sync_suspend(chip->dev);

	clk_disable_unprepare(chip->clk);
}

#ifdef CONFIG_OF
static const struct of_device_id dw_dma_of_id_table[] = {
	{ .compatible = "snps,dma-spear1340" },
	{}
};
コード例 #22
0
ファイル: of_coresight.c プロジェクト: Anjali05/linux
struct coresight_platform_data *
of_get_coresight_platform_data(struct device *dev,
			       const struct device_node *node)
{
	int ret = 0;
	struct coresight_platform_data *pdata;
	struct coresight_connection *conn;
	struct device_node *ep = NULL;
	const struct device_node *parent = NULL;
	bool legacy_binding = false;

	pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
	if (!pdata)
		return ERR_PTR(-ENOMEM);

	/* Use device name as sysfs handle */
	pdata->name = dev_name(dev);
	pdata->cpu = of_coresight_get_cpu(node);

	/* Get the number of input and output port for this component */
	of_coresight_get_ports(node, &pdata->nr_inport, &pdata->nr_outport);

	/* If there are no output connections, we are done */
	if (!pdata->nr_outport)
		return pdata;

	ret = of_coresight_alloc_memory(dev, pdata);
	if (ret)
		return ERR_PTR(ret);

	parent = of_coresight_get_output_ports_node(node);
	/*
	 * If the DT uses obsoleted bindings, the ports are listed
	 * under the device and we need to filter out the input
	 * ports.
	 */
	if (!parent) {
		legacy_binding = true;
		parent = node;
		dev_warn_once(dev, "Uses obsolete Coresight DT bindings\n");
	}

	conn = pdata->conns;

	/* Iterate through each output port to discover topology */
	while ((ep = of_graph_get_next_endpoint(parent, ep))) {
		/*
		 * Legacy binding mixes input/output ports under the
		 * same parent. So, skip the input ports if we are dealing
		 * with legacy binding, as they processed with their
		 * connected output ports.
		 */
		if (legacy_binding && of_coresight_legacy_ep_is_input(ep))
			continue;

		ret = of_coresight_parse_endpoint(dev, ep, conn);
		switch (ret) {
		case 1:
			conn++;		/* Fall through */
		case 0:
			break;
		default:
			return ERR_PTR(ret);
		}
	}

	return pdata;
}
コード例 #23
0
static int __init cpubw_probe(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
	struct devfreq_dev_profile *p = &cpubw_profile;
	struct devfreq *df;
	u32 *data, ports[MAX_PATHS * 2];
	int ret, len, i;

	if (of_find_property(dev->of_node, PROP_PORTS, &len)) {
		len /= sizeof(ports[0]);
		if (len % 2 || len > ARRAY_SIZE(ports)) {
			dev_err(dev, "Unexpected number of ports\n");
			return -EINVAL;
		}

		ret = of_property_read_u32_array(dev->of_node, PROP_PORTS,
						 ports, len);
		if (ret)
			return ret;

		num_paths = len / 2;
	} else {
		return -EINVAL;
	}

	for (i = 0; i < num_paths; i++) {
		bw_levels[0].vectors[i].src = ports[2 * i];
		bw_levels[0].vectors[i].dst = ports[2 * i + 1];
		bw_levels[1].vectors[i].src = ports[2 * i];
		bw_levels[1].vectors[i].dst = ports[2 * i + 1];
	}
	bw_levels[0].num_paths = num_paths;
	bw_levels[1].num_paths = num_paths;

	if (of_find_property(dev->of_node, PROP_TBL, &len)) {
		len /= sizeof(*data);
		data = devm_kzalloc(dev, len * sizeof(*data), GFP_KERNEL);
		if (!data)
			return -ENOMEM;

		p->freq_table = devm_kzalloc(dev,
					     len * sizeof(*p->freq_table),
					     GFP_KERNEL);
		if (!p->freq_table)
			return -ENOMEM;

		ret = of_property_read_u32_array(dev->of_node, PROP_TBL,
						 data, len);
		if (ret)
			return ret;

		for (i = 0; i < len; i++)
			p->freq_table[i] = data[i];
		p->max_state = len;
		p->initial_freq = data[len-1];
	}

	bus_client = msm_bus_scale_register_client(&bw_data);
	if (!bus_client) {
		dev_err(dev, "Unable to register bus client\n");
		return -ENODEV;
	}

	df = devfreq_add_device(dev, &cpubw_profile, "msm_cpufreq", NULL);
	if (IS_ERR(df)) {
		msm_bus_scale_unregister_client(bus_client);
		return PTR_ERR(df);
	}

	return 0;
}
コード例 #24
0
static int arizona_spi_probe(struct spi_device *spi)
{
	const struct spi_device_id *id = spi_get_device_id(spi);
	struct arizona *arizona;
	const struct regmap_config *regmap_config;
	const struct regmap_config *regmap_32bit_config = NULL;
	unsigned long type;
	int ret;

	if (spi->dev.of_node)
		type = arizona_of_get_type(&spi->dev);
	else
		type = id->driver_data;

	switch (type) {
#ifdef CONFIG_MFD_WM5102
	case WM5102:
		regmap_config = &wm5102_spi_regmap;
		break;
#endif
#ifdef CONFIG_MFD_FLORIDA
	case WM8280:
	case WM5110:
		regmap_config = &florida_spi_regmap;
		break;
#endif
#ifdef CONFIG_MFD_CLEARWATER
	case WM8285:
	case WM1840:
		regmap_config = &clearwater_16bit_spi_regmap;
		regmap_32bit_config = &clearwater_32bit_spi_regmap;
		break;
#endif
#ifdef CONFIG_MFD_LARGO
	case WM1831:
	case CS47L24:
		regmap_config = &largo_spi_regmap;
		break;
#endif
#ifdef CONFIG_MFD_MARLEY
	case CS47L35:
		regmap_config = &marley_16bit_spi_regmap;
		regmap_32bit_config = &marley_32bit_spi_regmap;
		break;
#endif
#ifdef CONFIG_MFD_MOON
	case CS47L90:
	case CS47L91:
		regmap_config = &moon_16bit_spi_regmap;
		regmap_32bit_config = &moon_32bit_spi_regmap;
		break;
#endif
	default:
		dev_err(&spi->dev, "Unknown device type %ld\n",
			id->driver_data);
		return -EINVAL;
	}

	arizona = devm_kzalloc(&spi->dev, sizeof(*arizona), GFP_KERNEL);
	if (arizona == NULL)
		return -ENOMEM;

	arizona->regmap = devm_regmap_init_spi(spi, regmap_config);
	if (IS_ERR(arizona->regmap)) {
		ret = PTR_ERR(arizona->regmap);
		dev_err(&spi->dev, "Failed to allocate register map: %d\n",
			ret);
		return ret;
	}

	if (regmap_32bit_config) {
		arizona->regmap_32bit = devm_regmap_init_spi(spi,
							   regmap_32bit_config);
		if (IS_ERR(arizona->regmap_32bit)) {
			ret = PTR_ERR(arizona->regmap_32bit);
			dev_err(&spi->dev,
				"Failed to allocate dsp register map: %d\n",
				ret);
			return ret;
		}
	}
	arizona->type = id->driver_data;
	arizona->dev = &spi->dev;
	arizona->irq = spi->irq;

	return arizona_dev_init(arizona);
}
コード例 #25
0
ファイル: max77693-haptic.c プロジェクト: 3null/linux
static int max77693_haptic_probe(struct platform_device *pdev)
{
	struct max77693_dev *max77693 = dev_get_drvdata(pdev->dev.parent);
	struct max77693_haptic *haptic;
	int error;

	haptic = devm_kzalloc(&pdev->dev, sizeof(*haptic), GFP_KERNEL);
	if (!haptic)
		return -ENOMEM;

	haptic->regmap_pmic = max77693->regmap;
	haptic->regmap_haptic = max77693->regmap_haptic;
	haptic->dev = &pdev->dev;
	haptic->type = MAX77693_HAPTIC_LRA;
	haptic->mode = MAX77693_HAPTIC_EXTERNAL_MODE;
	haptic->pwm_divisor = MAX77693_HAPTIC_PWM_DIVISOR_128;
	haptic->suspend_state = false;

	INIT_WORK(&haptic->work, max77693_haptic_play_work);

	/* Get pwm and regulatot for haptic device */
	haptic->pwm_dev = devm_pwm_get(&pdev->dev, NULL);
	if (IS_ERR(haptic->pwm_dev)) {
		dev_err(&pdev->dev, "failed to get pwm device\n");
		return PTR_ERR(haptic->pwm_dev);
	}

	haptic->motor_reg = devm_regulator_get(&pdev->dev, "haptic");
	if (IS_ERR(haptic->motor_reg)) {
		dev_err(&pdev->dev, "failed to get regulator\n");
		return PTR_ERR(haptic->motor_reg);
	}

	/* Initialize input device for haptic device */
	haptic->input_dev = devm_input_allocate_device(&pdev->dev);
	if (!haptic->input_dev) {
		dev_err(&pdev->dev, "failed to allocate input device\n");
		return -ENOMEM;
	}

	haptic->input_dev->name = "max77693-haptic";
	haptic->input_dev->id.version = 1;
	haptic->input_dev->dev.parent = &pdev->dev;
	haptic->input_dev->open = max77693_haptic_open;
	haptic->input_dev->close = max77693_haptic_close;
	input_set_drvdata(haptic->input_dev, haptic);
	input_set_capability(haptic->input_dev, EV_FF, FF_RUMBLE);

	error = input_ff_create_memless(haptic->input_dev, NULL,
				max77693_haptic_play_effect);
	if (error) {
		dev_err(&pdev->dev, "failed to create force-feedback\n");
		return error;
	}

	error = input_register_device(haptic->input_dev);
	if (error) {
		dev_err(&pdev->dev, "failed to register input device\n");
		return error;
	}

	platform_set_drvdata(pdev, haptic);

	return 0;
}
コード例 #26
0
struct esxxx_platform_data *es705_populate_dt_pdata(struct device *dev)
{
	struct esxxx_platform_data *pdata;
	struct device_node *node = of_get_parent(dev->of_node);

	dev_info(dev, "%s(): parent node %s\n",
			__func__, node->full_name);

	pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
	if (!pdata) {
		dev_err(dev, "%s(): platform data allocation failed\n",
			__func__);
		goto err;
	}
	pdata->reset_gpio = of_get_named_gpio(node, "es705-reset-gpio", 0);
	if (pdata->reset_gpio < 0)
		of_property_read_u32(node, "es705-reset-expander-gpio",
								&pdata->reset_gpio);
	if (pdata->reset_gpio < 0) {
		dev_err(dev, "%s(): get reset_gpio failed\n", __func__);
		goto alloc_err;
	}
	dev_dbg(dev, "%s(): reset gpio %d\n", __func__, pdata->reset_gpio);

	pdata->gpioa_gpio = of_get_named_gpio(node, "es705-gpioa-gpio", 0);
	if (pdata->gpioa_gpio < 0) {
		dev_err(dev, "%s(): get gpioa_gpio failed\n", __func__);
		goto alloc_err;
	}
	dev_dbg(dev, "%s(): gpioa gpio %d\n", __func__, pdata->gpioa_gpio);

	pdata->gpiob_gpio = of_get_named_gpio(node, "es705-gpiob-gpio", 0);
	if (pdata->gpiob_gpio < 0) {
		dev_err(dev, "%s(): get gpiob_gpio failed\n", __func__);
		goto alloc_err;
	}
	dev_info(dev, "%s(): gpiob gpio %d\n", __func__, pdata->gpiob_gpio);

	pdata->uart_tx_gpio = of_get_named_gpio(node, "es705-uart-tx", 0);
	if (pdata->uart_tx_gpio < 0) {
		dev_info(dev, "%s(): get uart_tx_gpio failed\n", __func__);
		pdata->uart_tx_gpio = -1;
	}
	dev_dbg(dev, "%s(): uart tx gpio %d\n", __func__, pdata->uart_tx_gpio);

	pdata->uart_rx_gpio = of_get_named_gpio(node, "es705-uart-rx", 0);
	if (pdata->uart_rx_gpio < 0) {
		dev_info(dev, "%s(): get uart_rx_gpio failed\n", __func__);
		pdata->uart_rx_gpio = -1;
	}
	dev_dbg(dev, "%s(): uart rx gpio %d\n", __func__, pdata->uart_rx_gpio);

	pdata->wakeup_gpio = of_get_named_gpio(node, "es705-wakeup-gpio", 0);
	if (pdata->wakeup_gpio < 0) {
		dev_info(dev, "%s(): get wakeup_gpio failed\n", __func__);
		pdata->wakeup_gpio = -1;
	}
	dev_dbg(dev, "%s(): wakeup gpio %d\n", __func__, pdata->wakeup_gpio);

	pdata->uart_gpio = of_get_named_gpio(node, "es705-uart-gpio", 0);
	if (pdata->uart_gpio < 0) {
		dev_info(dev, "%s(): get uart_gpio failed\n", __func__);
		pdata->uart_gpio = -1;
	}
	dev_dbg(dev, "%s(): uart gpio %d\n", __func__, pdata->uart_gpio);

	pdata->irq_base = gpio_to_irq(pdata->gpiob_gpio);
	dev_info(dev, "%s(): irq_base %d\n", __func__, pdata->irq_base);

	return pdata;
alloc_err:
	devm_kfree(dev, pdata);
err:
	return NULL;
}
コード例 #27
0
ファイル: mxs-lradc.c プロジェクト: Anjali05/linux
static int mxs_lradc_probe(struct platform_device *pdev)
{
	const struct of_device_id *of_id;
	struct device *dev = &pdev->dev;
	struct device_node *node = dev->of_node;
	struct mxs_lradc *lradc;
	struct mfd_cell *cells = NULL;
	struct resource *res;
	int ret = 0;
	u32 ts_wires = 0;

	lradc = devm_kzalloc(&pdev->dev, sizeof(*lradc), GFP_KERNEL);
	if (!lradc)
		return -ENOMEM;

	of_id = of_match_device(mxs_lradc_dt_ids, &pdev->dev);
	if (!of_id)
		return -EINVAL;

	lradc->soc = (enum mxs_lradc_id)of_id->data;

	lradc->clk = devm_clk_get(&pdev->dev, NULL);
	if (IS_ERR(lradc->clk)) {
		dev_err(dev, "Failed to get the delay unit clock\n");
		return PTR_ERR(lradc->clk);
	}

	ret = clk_prepare_enable(lradc->clk);
	if (ret) {
		dev_err(dev, "Failed to enable the delay unit clock\n");
		return ret;
	}

	ret = of_property_read_u32(node, "fsl,lradc-touchscreen-wires",
					 &ts_wires);

	if (!ret) {
		lradc->buffer_vchans = BUFFER_VCHANS_LIMITED;

		switch (ts_wires) {
		case 4:
			lradc->touchscreen_wire = MXS_LRADC_TOUCHSCREEN_4WIRE;
			break;
		case 5:
			if (lradc->soc == IMX28_LRADC) {
				lradc->touchscreen_wire =
					MXS_LRADC_TOUCHSCREEN_5WIRE;
				break;
			}
			/* fall through - to an error message for i.MX23 */
		default:
			dev_err(&pdev->dev,
				"Unsupported number of touchscreen wires (%d)\n"
				, ts_wires);
			ret = -EINVAL;
			goto err_clk;
		}
	} else {
		lradc->buffer_vchans = BUFFER_VCHANS_ALL;
	}

	platform_set_drvdata(pdev, lradc);

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!res) {
		ret = -ENOMEM;
		goto err_clk;
	}

	switch (lradc->soc) {
	case IMX23_LRADC:
		mx23_adc_resources[RES_MEM] = *res;
		mx23_touchscreen_resources[RES_MEM] = *res;
		cells = mx23_cells;
		break;
	case IMX28_LRADC:
		mx28_adc_resources[RES_MEM] = *res;
		mx28_touchscreen_resources[RES_MEM] = *res;
		cells = mx28_cells;
		break;
	default:
		dev_err(dev, "Unsupported SoC\n");
		ret = -ENODEV;
		goto err_clk;
	}

	ret = devm_mfd_add_devices(&pdev->dev, PLATFORM_DEVID_NONE,
				   &cells[ADC_CELL], 1, NULL, 0, NULL);
	if (ret) {
		dev_err(&pdev->dev, "Failed to add the ADC subdevice\n");
		goto err_clk;
	}

	if (!lradc->touchscreen_wire)
		return 0;

	ret = devm_mfd_add_devices(&pdev->dev, PLATFORM_DEVID_NONE,
				   &cells[TSC_CELL], 1, NULL, 0, NULL);
	if (ret) {
		dev_err(&pdev->dev,
			"Failed to add the touchscreen subdevice\n");
		goto err_clk;
	}

	return 0;

err_clk:
	clk_disable_unprepare(lradc->clk);

	return ret;
}
コード例 #28
0
static int pil_femto_modem_driver_probe(
    struct platform_device *pdev)
{
    struct femto_modem_data *drv;
    struct q6v5_data *q6;
    struct pil_desc *q6_desc;
    struct device_node *p_node = pdev->dev.of_node;
    int ret = 0;

    drv = devm_kzalloc(&pdev->dev, sizeof(*drv), GFP_KERNEL);
    if (!drv)
        return -ENOMEM;
    platform_set_drvdata(pdev, drv);

    /* Retrieve the maximum number of modems */
    ret = of_property_read_u32(p_node, "qcom,max-num-modems",
                               &drv->max_num_modems);
    if (ret)
        return ret;

    /* Max number of modems must be greater than zero */
    if (!drv->max_num_modems)
        return -EINVAL;

    /* Allocate memory for modem structs */
    drv->modem = devm_kzalloc(&pdev->dev,
                              (sizeof(*(drv->modem)) * drv->max_num_modems), GFP_KERNEL);
    if (!drv->modem)
        return -ENOMEM;

    /* This controls the loading of the MBA firmware to Q6[0] */
    q6 = pil_q6v5_init(pdev);
    if (IS_ERR(q6))
        return PTR_ERR(q6);
    drv->q6 = q6;

    /* This is needed for legacy code.  Always on. */
    q6->self_auth = 1;

    q6_desc = &q6->desc;
    q6_desc->ops = &pil_msa_mss_ops;
    q6_desc->owner = THIS_MODULE;
    q6_desc->proxy_timeout = 0;
    q6_desc->map_fw_mem = pil_femto_modem_map_fw_mem;
    q6_desc->unmap_fw_mem = pil_femto_modem_unmap_fw_mem;

    /* For this target, PBL interactions are different. */
    pil_msa_mss_ops.proxy_vote = NULL;
    pil_msa_mss_ops.proxy_unvote = NULL;

    /* Initialize the number of discovered modems. */
    drv->disc_modems = 0;

    /* Parse the device tree to get RMB regs and filenames for each modem */
    ret = of_platform_populate(p_node, NULL, NULL, &pdev->dev);
    if (ret)
        return ret;

    /* Initialize the PIL descriptor */
    ret = pil_desc_init(q6_desc);

    if (ret)
        return ret;

    /* Create the sysfs attributes */
    ret = pil_femto_modem_create_sysfs(drv);

    if (ret)
        pil_desc_release(q6_desc);

    return ret;
}
コード例 #29
0
ファイル: extcon-max8997.c プロジェクト: DenisLug/mptcp
static int max8997_muic_probe(struct platform_device *pdev)
{
	struct max8997_dev *max8997 = dev_get_drvdata(pdev->dev.parent);
	struct max8997_platform_data *pdata = dev_get_platdata(max8997->dev);
	struct max8997_muic_info *info;
	int delay_jiffies;
	int ret, i;

	info = devm_kzalloc(&pdev->dev, sizeof(struct max8997_muic_info),
			    GFP_KERNEL);
	if (!info)
		return -ENOMEM;

	info->dev = &pdev->dev;
	info->muic = max8997->muic;

	platform_set_drvdata(pdev, info);
	mutex_init(&info->mutex);

	INIT_WORK(&info->irq_work, max8997_muic_irq_work);

	for (i = 0; i < ARRAY_SIZE(muic_irqs); i++) {
		struct max8997_muic_irq *muic_irq = &muic_irqs[i];
		unsigned int virq = 0;

		virq = irq_create_mapping(max8997->irq_domain, muic_irq->irq);
		if (!virq) {
			ret = -EINVAL;
			goto err_irq;
		}
		muic_irq->virq = virq;

		ret = request_threaded_irq(virq, NULL,
				max8997_muic_irq_handler,
				IRQF_NO_SUSPEND,
				muic_irq->name, info);
		if (ret) {
			dev_err(&pdev->dev,
				"failed: irq request (IRQ: %d, error :%d)\n",
				muic_irq->irq, ret);
			goto err_irq;
		}
	}

	/* External connector */
	info->edev = devm_extcon_dev_allocate(&pdev->dev, max8997_extcon_cable);
	if (IS_ERR(info->edev)) {
		dev_err(&pdev->dev, "failed to allocate memory for extcon\n");
		ret = -ENOMEM;
		goto err_irq;
	}

	ret = devm_extcon_dev_register(&pdev->dev, info->edev);
	if (ret) {
		dev_err(&pdev->dev, "failed to register extcon device\n");
		goto err_irq;
	}

	if (pdata && pdata->muic_pdata) {
		struct max8997_muic_platform_data *muic_pdata
			= pdata->muic_pdata;

		/* Initialize registers according to platform data */
		for (i = 0; i < muic_pdata->num_init_data; i++) {
			max8997_write_reg(info->muic,
					muic_pdata->init_data[i].addr,
					muic_pdata->init_data[i].data);
		}

		/*
		 * Default usb/uart path whether UART/USB or AUX_UART/AUX_USB
		 * h/w path of COMP2/COMN1 on CONTROL1 register.
		 */
		if (muic_pdata->path_uart)
			info->path_uart = muic_pdata->path_uart;
		else
			info->path_uart = CONTROL1_SW_UART;

		if (muic_pdata->path_usb)
			info->path_usb = muic_pdata->path_usb;
		else
			info->path_usb = CONTROL1_SW_USB;

		/*
		 * Default delay time for detecting cable state
		 * after certain time.
		 */
		if (muic_pdata->detcable_delay_ms)
			delay_jiffies =
				msecs_to_jiffies(muic_pdata->detcable_delay_ms);
		else
			delay_jiffies = msecs_to_jiffies(DELAY_MS_DEFAULT);
	} else {
		info->path_uart = CONTROL1_SW_UART;
		info->path_usb = CONTROL1_SW_USB;
		delay_jiffies = msecs_to_jiffies(DELAY_MS_DEFAULT);
	}

	/* Set initial path for UART */
	 max8997_muic_set_path(info, info->path_uart, true);

	/* Set ADC debounce time */
	max8997_muic_set_debounce_time(info, ADC_DEBOUNCE_TIME_25MS);

	/*
	 * Detect accessory after completing the initialization of platform
	 *
	 * - Use delayed workqueue to detect cable state and then
	 * notify cable state to notifiee/platform through uevent.
	 * After completing the booting of platform, the extcon provider
	 * driver should notify cable state to upper layer.
	 */
	INIT_DELAYED_WORK(&info->wq_detcable, max8997_muic_detect_cable_wq);
	queue_delayed_work(system_power_efficient_wq, &info->wq_detcable,
			delay_jiffies);

	return 0;

err_irq:
	while (--i >= 0)
		free_irq(muic_irqs[i].virq, info);
	return ret;
}
コード例 #30
0
static int __devinit pil_pronto_probe(struct platform_device *pdev)
{
	struct pronto_data *drv;
	struct resource *res;
	struct pil_desc *desc;
	int ret;
	uint32_t regval;

	drv = devm_kzalloc(&pdev->dev, sizeof(*drv), GFP_KERNEL);
	if (!drv)
		return -ENOMEM;
	platform_set_drvdata(pdev, drv);

	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "pmu_base");
	drv->base = devm_request_and_ioremap(&pdev->dev, res);
	if (!drv->base)
		return -ENOMEM;

	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "clk_base");
	drv->reset_base = devm_request_and_ioremap(&pdev->dev, res);
	if (!drv->reset_base)
		return -ENOMEM;

	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "halt_base");
	drv->axi_halt_base = devm_request_and_ioremap(&pdev->dev, res);
	if (!drv->axi_halt_base)
		return -ENOMEM;

	desc = &drv->desc;
	ret = of_property_read_string(pdev->dev.of_node, "qcom,firmware-name",
				      &desc->name);
	if (ret)
		return ret;

	desc->dev = &pdev->dev;
	desc->owner = THIS_MODULE;
	desc->proxy_timeout = 10000;

	if (pas_supported(PAS_WCNSS) > 0) {
		desc->ops = &pil_pronto_ops_trusted;
		dev_info(&pdev->dev, "using secure boot\n");
	} else {
		desc->ops = &pil_pronto_ops;
		dev_info(&pdev->dev, "using non-secure boot\n");
	}

	drv->vreg = devm_regulator_get(&pdev->dev, "vdd_pronto_pll");
	if (IS_ERR(drv->vreg)) {
		dev_err(&pdev->dev, "failed to get pronto pll supply");
		return PTR_ERR(drv->vreg);
	}

	ret = regulator_set_voltage(drv->vreg, 1800000, 1800000);
	if (ret) {
		dev_err(&pdev->dev, "failed to set pll supply voltage\n");
		return ret;
	}

	ret = regulator_set_optimum_mode(drv->vreg, 18000);
	if (ret < 0) {
		dev_err(&pdev->dev, "failed to set pll supply mode\n");
		return ret;
	}

	drv->cxo = devm_clk_get(&pdev->dev, "xo");
	if (IS_ERR(drv->cxo))
		return PTR_ERR(drv->cxo);

	scm_pas_init(MSM_BUS_MASTER_CRYPTO_CORE0);

	ret = pil_desc_init(desc);
	if (ret)
		return ret;

	drv->subsys_desc.name = desc->name;
	drv->subsys_desc.dev = &pdev->dev;
	drv->subsys_desc.owner = THIS_MODULE;
	drv->subsys_desc.shutdown = wcnss_shutdown;
	drv->subsys_desc.powerup = wcnss_powerup;
	drv->subsys_desc.ramdump = wcnss_ramdump;
	drv->subsys_desc.crash_shutdown = crash_shutdown;
	drv->subsys_desc.start = pronto_start;
	drv->subsys_desc.stop = pronto_stop;
	drv->subsys_desc.err_fatal_handler = wcnss_err_fatal_intr_handler;
	drv->subsys_desc.wdog_bite_handler = wcnss_wdog_bite_irq_hdlr;

	INIT_DELAYED_WORK(&drv->cancel_vote_work, wcnss_post_bootup);

	drv->subsys = subsys_register(&drv->subsys_desc);
	if (IS_ERR(drv->subsys)) {
		ret = PTR_ERR(drv->subsys);
		goto err_subsys;
	}

	drv->ramdump_dev = create_ramdump_device("pronto", &pdev->dev);
	if (!drv->ramdump_dev) {
		ret = -ENOMEM;
		goto err_irq;
	}

	/* Initialize common_ss GDSCR to wait 4 cycles between states */
	regval = readl_relaxed(drv->base + PRONTO_PMU_COMMON_GDSCR)
		& PRONTO_PMU_COMMON_GDSCR_SW_COLLAPSE;
	regval |= (2 << EN_REST_WAIT) | (2 << EN_FEW_WAIT)
		  | (2 << CLK_DIS_WAIT);
	writel_relaxed(regval, drv->base + PRONTO_PMU_COMMON_GDSCR);

	return 0;

err_irq:
	subsys_unregister(drv->subsys);
err_subsys:
	pil_desc_release(desc);
	return ret;
}