greybus: PWM: convert to a gpbridge driver
authorGreg Kroah-Hartman <gregkh@google.com>
Thu, 5 May 2016 09:02:31 +0000 (14:32 +0530)
committerGreg Kroah-Hartman <gregkh@google.com>
Thu, 5 May 2016 20:38:57 +0000 (13:38 -0700)
This converts the PWM driver to be a gpbridge driver, moving it away
from the "legacy" interface.

Testing Done: Tested on gbsim.

Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
Signed-off-by: Vaibhav Hiremath <vaibhav.hiremath@linaro.org>
[vaibhav.hiremath@linaro.org: 1.Changed code to retain init/exit fns of
drivers. 2.Exit path fix. 3. Fixed review comments]
Reviewed-by: Viresh Kumar <viresh.kumar@linaro.org>
Tested-by: Viresh Kumar <viresh.kumar@linaro.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
drivers/staging/greybus/gpbridge.c
drivers/staging/greybus/gpbridge.h
drivers/staging/greybus/legacy.c
drivers/staging/greybus/pwm.c

index 2a23a309b83e5ad65ba6b8780d75eedb66ad9cb6..a446749789f96b61349ead6c32259915a275765c 100644 (file)
@@ -252,6 +252,7 @@ static int gb_gpbridge_probe(struct gb_bundle *bundle,
 
 static const struct greybus_bundle_id gb_gpbridge_id_table[] = {
        { GREYBUS_DEVICE_CLASS(GREYBUS_CLASS_BRIDGED_PHY) },
+       { GREYBUS_DEVICE_CLASS(GREYBUS_CLASS_PWM) },
        { GREYBUS_DEVICE_CLASS(GREYBUS_CLASS_UART) },
        { },
 };
@@ -284,8 +285,8 @@ static int __init gpbridge_init(void)
                pr_err("error initializing gpio protocol\n");
                goto error_gpio;
        }
-       if (gb_pwm_protocol_init()) {
-               pr_err("error initializing pwm protocol\n");
+       if (gb_pwm_driver_init()) {
+               pr_err("error initializing pwm driver\n");
                goto error_pwm;
        }
        if (gb_uart_driver_init()) {
@@ -320,7 +321,7 @@ error_usb:
 error_sdio:
        gb_uart_driver_exit();
 error_uart:
-       gb_pwm_protocol_exit();
+       gb_pwm_driver_exit();
 error_pwm:
        gb_gpio_protocol_exit();
 error_gpio:
@@ -339,7 +340,7 @@ static void __exit gpbridge_exit(void)
        gb_usb_protocol_exit();
        gb_sdio_protocol_exit();
        gb_uart_driver_exit();
-       gb_pwm_protocol_exit();
+       gb_pwm_driver_exit();
        gb_gpio_protocol_exit();
 
        greybus_deregister(&gb_gpbridge_driver);
index fb17f02861d17385b4051cb1aa56c215ea547929..8681bd33e67144f995a40fb2e1cd90b3dee23f1f 100644 (file)
@@ -69,8 +69,8 @@ void gb_##__driver##_exit(void)                               \
 extern int gb_gpio_protocol_init(void);
 extern void gb_gpio_protocol_exit(void);
 
-extern int gb_pwm_protocol_init(void);
-extern void gb_pwm_protocol_exit(void);
+extern int gb_pwm_driver_init(void);
+extern void gb_pwm_driver_exit(void);
 
 extern int gb_uart_driver_init(void);
 extern void gb_uart_driver_exit(void);
index f391a5dccba4507a2a5fcbe51e02a1d955d3cf9b..f9bcdded9b6a5d44c5fb8972576aae4707409347 100644 (file)
@@ -240,7 +240,6 @@ static const struct greybus_bundle_id legacy_id_table[] = {
        { GREYBUS_DEVICE_CLASS(GREYBUS_CLASS_I2C) },
        { GREYBUS_DEVICE_CLASS(GREYBUS_CLASS_USB) },
        { GREYBUS_DEVICE_CLASS(GREYBUS_CLASS_SDIO) },
-       { GREYBUS_DEVICE_CLASS(GREYBUS_CLASS_PWM) },
        { GREYBUS_DEVICE_CLASS(GREYBUS_CLASS_SPI) },
        { GREYBUS_DEVICE_CLASS(GREYBUS_CLASS_CAMERA) },
        { }
index 176301a498659e6a14ea6daec38fa558c965dbb2..b11e77df4a6cf134ce5324a0f15e9a94e519d002 100644 (file)
@@ -178,8 +178,10 @@ static const struct pwm_ops gb_pwm_ops = {
        .owner = THIS_MODULE,
 };
 
-static int gb_pwm_connection_init(struct gb_connection *connection)
+static int gb_pwm_probe(struct gpbridge_device *gpbdev,
+                       const struct gpbridge_device_id *id)
 {
+       struct gb_connection *connection;
        struct gb_pwm_chip *pwmc;
        struct pwm_chip *pwm;
        int ret;
@@ -187,17 +189,35 @@ static int gb_pwm_connection_init(struct gb_connection *connection)
        pwmc = kzalloc(sizeof(*pwmc), GFP_KERNEL);
        if (!pwmc)
                return -ENOMEM;
+
+       connection = gb_connection_create(gpbdev->bundle,
+                                         le16_to_cpu(gpbdev->cport_desc->id),
+                                         NULL);
+       if (IS_ERR(connection)) {
+               ret = PTR_ERR(connection);
+               goto exit_pwmc_free;
+       }
+
        pwmc->connection = connection;
        gb_connection_set_data(connection, pwmc);
+       gb_gpbridge_set_data(gpbdev, pwmc);
+
+       ret = gb_connection_enable(connection);
+       if (ret)
+               goto exit_connection_destroy;
+
+       ret = gb_gpbridge_get_version(connection);
+       if (ret)
+               goto exit_connection_disable;
 
        /* Query number of pwms present */
        ret = gb_pwm_count_operation(pwmc);
        if (ret)
-               goto out_err;
+               goto exit_connection_disable;
 
        pwm = &pwmc->chip;
 
-       pwm->dev = &connection->bundle->dev;
+       pwm->dev = &gpbdev->dev;
        pwm->ops = &gb_pwm_ops;
        pwm->base = -1;                 /* Allocate base dynamically */
        pwm->npwm = pwmc->pwm_max + 1;
@@ -205,36 +225,42 @@ static int gb_pwm_connection_init(struct gb_connection *connection)
 
        ret = pwmchip_add(pwm);
        if (ret) {
-               dev_err(&connection->bundle->dev,
+               dev_err(&gpbdev->dev,
                        "failed to register PWM: %d\n", ret);
-               goto out_err;
+               goto exit_connection_disable;
        }
 
        return 0;
-out_err:
+
+exit_connection_disable:
+       gb_connection_disable(connection);
+exit_connection_destroy:
+       gb_connection_destroy(connection);
+exit_pwmc_free:
        kfree(pwmc);
        return ret;
 }
 
-static void gb_pwm_connection_exit(struct gb_connection *connection)
+static void gb_pwm_remove(struct gpbridge_device *gpbdev)
 {
-       struct gb_pwm_chip *pwmc = gb_connection_get_data(connection);
-       if (!pwmc)
-               return;
+       struct gb_pwm_chip *pwmc = gb_gpbridge_get_data(gpbdev);
+       struct gb_connection *connection = pwmc->connection;
 
        pwmchip_remove(&pwmc->chip);
-       /* kref_put(pwmc->connection) */
+       gb_connection_disable(connection);
+       gb_connection_destroy(connection);
        kfree(pwmc);
 }
 
-static struct gb_protocol pwm_protocol = {
-       .name                   = "pwm",
-       .id                     = GREYBUS_PROTOCOL_PWM,
-       .major                  = GB_PWM_VERSION_MAJOR,
-       .minor                  = GB_PWM_VERSION_MINOR,
-       .connection_init        = gb_pwm_connection_init,
-       .connection_exit        = gb_pwm_connection_exit,
-       .request_recv           = NULL, /* no incoming requests */
+static const struct gpbridge_device_id gb_pwm_id_table[] = {
+       { GPBRIDGE_PROTOCOL(GREYBUS_PROTOCOL_PWM) },
+       { },
 };
 
-gb_builtin_protocol_driver(pwm_protocol);
+static struct gpbridge_driver pwm_driver = {
+       .name           = "pwm",
+       .probe          = gb_pwm_probe,
+       .remove         = gb_pwm_remove,
+       .id_table       = gb_pwm_id_table,
+};
+gb_gpbridge_builtin_driver(pwm_driver);