Beispiel #1
0
int cros_ec_cmd_xfer(struct cros_ec_device *ec_dev,
		     struct cros_ec_command *msg)
{
	int ret;

	mutex_lock(&ec_dev->lock);
	if (ec_dev->proto_version == EC_PROTO_VERSION_UNKNOWN) {
		ret = cros_ec_query_all(ec_dev);
		if (ret) {
			dev_err(ec_dev->dev,
				"EC version unknown and query failed; aborting command\n");
			mutex_unlock(&ec_dev->lock);
			return ret;
		}
	}

	if (msg->insize > ec_dev->max_response) {
		dev_dbg(ec_dev->dev, "clamping message receive buffer\n");
		msg->insize = ec_dev->max_response;
	}

	if (msg->command < EC_CMD_PASSTHRU_OFFSET(1)) {
		if (msg->outsize > ec_dev->max_request) {
			dev_err(ec_dev->dev,
				"request of size %u is too big (max: %u)\n",
				msg->outsize,
				ec_dev->max_request);
			mutex_unlock(&ec_dev->lock);
			return -EMSGSIZE;
		}
	} else {
		if (msg->outsize > ec_dev->max_passthru) {
			dev_err(ec_dev->dev,
				"passthru rq of size %u is too big (max: %u)\n",
				msg->outsize,
				ec_dev->max_passthru);
			mutex_unlock(&ec_dev->lock);
			return -EMSGSIZE;
		}
	}
	ret = send_command(ec_dev, msg);
	mutex_unlock(&ec_dev->lock);

	return ret;
}
Beispiel #2
0
int cros_ec_register(struct cros_ec_device *ec_dev)
{
    struct device *dev = ec_dev->dev;
    int err = 0;

    ec_dev->max_request = sizeof(struct ec_params_hello);
    ec_dev->max_response = sizeof(struct ec_response_get_protocol_info);
    ec_dev->max_passthru = 0;

    ec_dev->din = devm_kzalloc(dev, ec_dev->din_size, GFP_KERNEL);
    if (!ec_dev->din)
        return -ENOMEM;

    ec_dev->dout = devm_kzalloc(dev, ec_dev->dout_size, GFP_KERNEL);
    if (!ec_dev->dout)
        return -ENOMEM;

    mutex_init(&ec_dev->lock);

    cros_ec_query_all(ec_dev);

    err = mfd_add_devices(ec_dev->dev, PLATFORM_DEVID_AUTO, &ec_cell, 1,
                          NULL, ec_dev->irq, NULL);
    if (err) {
        dev_err(dev,
                "Failed to register Embedded Controller subdevice %d\n",
                err);
        return err;
    }

    if (ec_dev->max_passthru) {
        /*
         * Register a PD device as well on top of this device.
         * We make the following assumptions:
         * - behind an EC, we have a pd
         * - only one device added.
         * - the EC is responsive at init time (it is not true for a
         *   sensor hub.
         */
        err = mfd_add_devices(ec_dev->dev, PLATFORM_DEVID_AUTO,
                              &ec_pd_cell, 1, NULL, ec_dev->irq, NULL);
        if (err) {
            dev_err(dev,
                    "Failed to register Power Delivery subdevice %d\n",
                    err);
            return err;
        }
    }

    if (IS_ENABLED(CONFIG_OF) && dev->of_node) {
        err = of_platform_populate(dev->of_node, NULL, NULL, dev);
        if (err) {
            mfd_remove_devices(dev);
            dev_err(dev, "Failed to register sub-devices\n");
            return err;
        }
    }

    dev_info(dev, "Chrome EC device registered\n");

    return 0;
}
Beispiel #3
0
int cros_ec_register(struct cros_ec_device *ec_dev)
{
	struct device *dev = ec_dev->dev;
	int err = 0;

	BLOCKING_INIT_NOTIFIER_HEAD(&ec_dev->event_notifier);

	ec_dev->max_request = sizeof(struct ec_params_hello);
	ec_dev->max_response = sizeof(struct ec_response_get_protocol_info);
	ec_dev->max_passthru = 0;

	ec_dev->din = devm_kzalloc(dev, ec_dev->din_size, GFP_KERNEL);
	if (!ec_dev->din)
		return -ENOMEM;

	ec_dev->dout = devm_kzalloc(dev, ec_dev->dout_size, GFP_KERNEL);
	if (!ec_dev->dout)
		return -ENOMEM;

	mutex_init(&ec_dev->lock);

	err = cros_ec_query_all(ec_dev);
	if (err) {
		dev_err(dev, "Cannot identify the EC: error %d\n", err);
		return err;
	}

	if (ec_dev->irq) {
		err = devm_request_threaded_irq(dev, ec_dev->irq, NULL,
				ec_irq_thread, IRQF_TRIGGER_LOW | IRQF_ONESHOT,
				"chromeos-ec", ec_dev);
		if (err) {
			dev_err(dev, "Failed to request IRQ %d: %d",
				ec_dev->irq, err);
			return err;
		}
	}

	err = mfd_add_devices(ec_dev->dev, PLATFORM_DEVID_AUTO, &ec_cell, 1,
			      NULL, ec_dev->irq, NULL);
	if (err) {
		dev_err(dev,
			"Failed to register Embedded Controller subdevice %d\n",
			err);
		return err;
	}

	if (ec_dev->max_passthru) {
		/*
		 * Register a PD device as well on top of this device.
		 * We make the following assumptions:
		 * - behind an EC, we have a pd
		 * - only one device added.
		 * - the EC is responsive at init time (it is not true for a
		 *   sensor hub.
		 */
		err = mfd_add_devices(ec_dev->dev, PLATFORM_DEVID_AUTO,
				      &ec_pd_cell, 1, NULL, ec_dev->irq, NULL);
		if (err) {
			dev_err(dev,
				"Failed to register Power Delivery subdevice %d\n",
				err);
			return err;
		}
	}

	if (IS_ENABLED(CONFIG_OF) && dev->of_node) {
		err = devm_of_platform_populate(dev);
		if (err) {
			mfd_remove_devices(dev);
			dev_err(dev, "Failed to register sub-devices\n");
			return err;
		}
	}

	/*
	 * Clear sleep event - this will fail harmlessly on platforms that
	 * don't implement the sleep event host command.
	 */
	err = cros_ec_sleep_event(ec_dev, 0);
	if (err < 0)
		dev_dbg(ec_dev->dev, "Error %d clearing sleep event to ec",
			err);

	dev_info(dev, "Chrome EC device registered\n");

	return 0;
}