struct mga_connector {
struct drm_connector base;
- struct mga_i2c_chan *i2c;
};
struct mga_mc {
struct mga_connector connector;
struct mgag200_pll pixpll;
+ struct mga_i2c_chan i2c;
struct drm_simple_display_pipe display_pipe;
};
int mgag200_modeset_init(struct mga_device *mdev);
/* mgag200_i2c.c */
-struct mga_i2c_chan *mgag200_i2c_create(struct drm_device *dev);
-void mgag200_i2c_destroy(struct mga_i2c_chan *i2c);
+int mgag200_i2c_init(struct mga_device *mdev, struct mga_i2c_chan *i2c);
/* mgag200_mm.c */
int mgag200_mm_init(struct mga_device *mdev);
return (mga_i2c_read_gpio(mdev) & i2c->clock) ? 1 : 0;
}
-struct mga_i2c_chan *mgag200_i2c_create(struct drm_device *dev)
+static void mgag200_i2c_release(void *res)
{
- struct mga_device *mdev = to_mga_device(dev);
- struct mga_i2c_chan *i2c;
+ struct mga_i2c_chan *i2c = res;
+
+ i2c_del_adapter(&i2c->adapter);
+}
+
+int mgag200_i2c_init(struct mga_device *mdev, struct mga_i2c_chan *i2c)
+{
+ struct drm_device *dev = &mdev->base;
int ret;
int data, clock;
break;
}
- i2c = kzalloc(sizeof(struct mga_i2c_chan), GFP_KERNEL);
- if (!i2c)
- return ERR_PTR(-ENOMEM);
-
i2c->data = data;
i2c->clock = clock;
i2c->adapter.owner = THIS_MODULE;
ret = i2c_bit_add_bus(&i2c->adapter);
if (ret)
- goto err_kfree;
+ return ret;
- return i2c;
-
-err_kfree:
- kfree(i2c);
- return ERR_PTR(ret);
-}
-
-void mgag200_i2c_destroy(struct mga_i2c_chan *i2c)
-{
- if (!i2c)
- return;
- i2c_del_adapter(&i2c->adapter);
- kfree(i2c);
+ return devm_add_action_or_reset(dev->dev, mgag200_i2c_release, i2c);
}
-
return MODE_OK;
}
-static void mga_connector_destroy(struct drm_connector *connector)
-{
- struct mga_connector *mga_connector = to_mga_connector(connector);
- mgag200_i2c_destroy(mga_connector->i2c);
- drm_connector_cleanup(connector);
-}
-
static const struct drm_connector_helper_funcs mga_vga_connector_helper_funcs = {
.get_modes = mgag200_vga_connector_helper_get_modes,
.mode_valid = mga_vga_mode_valid,
static const struct drm_connector_funcs mga_vga_connector_funcs = {
.reset = drm_atomic_helper_connector_reset,
.fill_modes = drm_helper_probe_single_connector_modes,
- .destroy = mga_connector_destroy,
+ .destroy = drm_connector_cleanup,
.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
};
struct drm_device *dev = &mdev->base;
struct mga_connector *mconnector = &mdev->connector;
struct drm_connector *connector = &mconnector->base;
- struct mga_i2c_chan *i2c;
+ struct mga_i2c_chan *i2c = &mdev->i2c;
int ret;
- i2c = mgag200_i2c_create(dev);
- if (IS_ERR(i2c)) {
- ret = PTR_ERR(i2c)
+ ret = mgag200_i2c_init(mdev, i2c);
+ if (ret) {
drm_err(dev, "failed to add DDC bus: %d\n", ret);
return ret;
}
DRM_MODE_CONNECTOR_VGA,
&i2c->adapter);
if (ret)
- goto err_mgag200_i2c_destroy;
+ return ret;
drm_connector_helper_add(connector, &mga_vga_connector_helper_funcs);
- mconnector->i2c = i2c;
-
return 0;
-
-err_mgag200_i2c_destroy:
- mgag200_i2c_destroy(i2c);
- return ret;
}
/*