From: Greg Kroah-Hartman Date: Thu, 5 May 2016 09:02:31 +0000 (+0530) Subject: greybus: PWM: convert to a gpbridge driver X-Git-Url: https://git.karo-electronics.de/?a=commitdiff_plain;h=320549086d1e985c09fd6635075ab45a3421038e;p=linux-beck.git greybus: PWM: convert to a gpbridge driver 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 Signed-off-by: Vaibhav Hiremath [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 Tested-by: Viresh Kumar Signed-off-by: Greg Kroah-Hartman --- diff --git a/drivers/staging/greybus/gpbridge.c b/drivers/staging/greybus/gpbridge.c index 2a23a309b83e..a446749789f9 100644 --- a/drivers/staging/greybus/gpbridge.c +++ b/drivers/staging/greybus/gpbridge.c @@ -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); diff --git a/drivers/staging/greybus/gpbridge.h b/drivers/staging/greybus/gpbridge.h index fb17f02861d1..8681bd33e671 100644 --- a/drivers/staging/greybus/gpbridge.h +++ b/drivers/staging/greybus/gpbridge.h @@ -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); diff --git a/drivers/staging/greybus/legacy.c b/drivers/staging/greybus/legacy.c index f391a5dccba4..f9bcdded9b6a 100644 --- a/drivers/staging/greybus/legacy.c +++ b/drivers/staging/greybus/legacy.c @@ -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) }, { } diff --git a/drivers/staging/greybus/pwm.c b/drivers/staging/greybus/pwm.c index 176301a49865..b11e77df4a6c 100644 --- a/drivers/staging/greybus/pwm.c +++ b/drivers/staging/greybus/pwm.c @@ -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);