Commit 17b5001b authored by Russell King's avatar Russell King

imx-drm: convert to componentised device support

Use the componentised device support for imx-drm.  This requires all
the sub-components and the master device to register with the component
device support.
Acked-by: default avatarPhilipp Zabel <p.zabel@pengutronix.de>
Acked-by: default avatarShawn Guo <shawn.guo@linaro.org>
Reviewed-by: default avatarFabio Estevam <fabio.estevam@freescale.com>
Signed-off-by: default avatarRussell King <rmk+kernel@arm.linux.org.uk>
parent f2d66aad
...@@ -21,7 +21,7 @@ memory { ...@@ -21,7 +21,7 @@ memory {
reg = <0x90000000 0x20000000>; reg = <0x90000000 0x20000000>;
}; };
display@di0 { display0: display@di0 {
compatible = "fsl,imx-parallel-display"; compatible = "fsl,imx-parallel-display";
crtcs = <&ipu 0>; crtcs = <&ipu 0>;
interface-pix-fmt = "rgb24"; interface-pix-fmt = "rgb24";
...@@ -43,7 +43,7 @@ timing0: dvi { ...@@ -43,7 +43,7 @@ timing0: dvi {
}; };
}; };
display@di1 { display1: display@di1 {
compatible = "fsl,imx-parallel-display"; compatible = "fsl,imx-parallel-display";
crtcs = <&ipu 1>; crtcs = <&ipu 1>;
interface-pix-fmt = "rgb565"; interface-pix-fmt = "rgb565";
...@@ -81,6 +81,12 @@ power { ...@@ -81,6 +81,12 @@ power {
}; };
}; };
imx-drm {
compatible = "fsl,imx-drm";
crtcs = <&ipu 0>, <&ipu 1>;
connectors = <&display0>, <&display1>;
};
sound { sound {
compatible = "fsl,imx51-babbage-sgtl5000", compatible = "fsl,imx51-babbage-sgtl5000",
"fsl,imx-audio-sgtl5000"; "fsl,imx-audio-sgtl5000";
......
...@@ -21,7 +21,7 @@ memory { ...@@ -21,7 +21,7 @@ memory {
}; };
soc { soc {
display@di1 { display1: display@di1 {
compatible = "fsl,imx-parallel-display"; compatible = "fsl,imx-parallel-display";
crtcs = <&ipu 1>; crtcs = <&ipu 1>;
interface-pix-fmt = "bgr666"; interface-pix-fmt = "bgr666";
...@@ -53,6 +53,12 @@ backlight { ...@@ -53,6 +53,12 @@ backlight {
default-brightness-level = <6>; default-brightness-level = <6>;
}; };
imx-drm {
compatible = "fsl,imx-drm";
crtcs = <&ipu 1>;
connectors = <&display1>;
};
leds { leds {
compatible = "gpio-leds"; compatible = "gpio-leds";
pinctrl-names = "default"; pinctrl-names = "default";
......
...@@ -43,6 +43,12 @@ disp1: display@disp1 { ...@@ -43,6 +43,12 @@ disp1: display@disp1 {
status = "disabled"; status = "disabled";
}; };
imx-drm {
compatible = "fsl,imx-drm";
crtcs = <&ipu 1>;
connectors = <&disp1>, <&tve>;
};
reg_3p2v: 3p2v { reg_3p2v: 3p2v {
compatible = "regulator-fixed"; compatible = "regulator-fixed";
regulator-name = "3P2V"; regulator-name = "3P2V";
......
...@@ -21,7 +21,7 @@ memory { ...@@ -21,7 +21,7 @@ memory {
reg = <0x70000000 0x40000000>; reg = <0x70000000 0x40000000>;
}; };
display@di0 { display0: display@di0 {
compatible = "fsl,imx-parallel-display"; compatible = "fsl,imx-parallel-display";
crtcs = <&ipu 0>; crtcs = <&ipu 0>;
interface-pix-fmt = "rgb565"; interface-pix-fmt = "rgb565";
...@@ -72,6 +72,12 @@ volume-down { ...@@ -72,6 +72,12 @@ volume-down {
}; };
}; };
imx-drm {
compatible = "fsl,imx-drm";
crtcs = <&ipu 0>;
connectors = <&display0>;
};
leds { leds {
compatible = "gpio-leds"; compatible = "gpio-leds";
pinctrl-names = "default"; pinctrl-names = "default";
......
...@@ -20,6 +20,10 @@ / { ...@@ -20,6 +20,10 @@ / {
compatible = "fsl,imx6q-sabresd", "fsl,imx6q"; compatible = "fsl,imx6q-sabresd", "fsl,imx6q";
}; };
&imx_drm {
crtcs = <&ipu1 0>, <&ipu1 1>, <&ipu2 0>, <&ipu2 1>;
};
&sata { &sata {
status = "okay"; status = "okay";
}; };
...@@ -62,6 +62,12 @@ volume-down { ...@@ -62,6 +62,12 @@ volume-down {
}; };
}; };
imx_drm: imx-drm {
compatible = "fsl,imx-drm";
crtcs = <&ipu1 0>, <&ipu1 1>;
connectors = <&ldb>;
};
sound { sound {
compatible = "fsl,imx6q-sabresd-wm8962", compatible = "fsl,imx6q-sabresd-wm8962",
"fsl,imx-audio-wm8962"; "fsl,imx-audio-wm8962";
......
...@@ -13,7 +13,7 @@ ...@@ -13,7 +13,7 @@
* GNU General Public License for more details. * GNU General Public License for more details.
* *
*/ */
#include <linux/component.h>
#include <linux/device.h> #include <linux/device.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <drm/drmP.h> #include <drm/drmP.h>
...@@ -90,6 +90,8 @@ static int imx_drm_driver_unload(struct drm_device *drm) ...@@ -90,6 +90,8 @@ static int imx_drm_driver_unload(struct drm_device *drm)
{ {
struct imx_drm_device *imxdrm = drm->dev_private; struct imx_drm_device *imxdrm = drm->dev_private;
component_unbind_all(drm->dev, drm);
imx_drm_device_put(); imx_drm_device_put();
drm_vblank_cleanup(drm); drm_vblank_cleanup(drm);
...@@ -371,11 +373,8 @@ static void imx_drm_connector_unregister( ...@@ -371,11 +373,8 @@ static void imx_drm_connector_unregister(
} }
/* /*
* Called by the CRTC driver when all CRTCs are registered. This * Main DRM initialisation. This binds, initialises and registers
* puts all the pieces together and initializes the driver. * with DRM the subcomponents of the driver.
* Once this is called no more CRTCs can be registered since
* the drm core has hardcoded the number of crtcs in several
* places.
*/ */
static int imx_drm_driver_load(struct drm_device *drm, unsigned long flags) static int imx_drm_driver_load(struct drm_device *drm, unsigned long flags)
{ {
...@@ -428,8 +427,15 @@ static int imx_drm_driver_load(struct drm_device *drm, unsigned long flags) ...@@ -428,8 +427,15 @@ static int imx_drm_driver_load(struct drm_device *drm, unsigned long flags)
platform_set_drvdata(drm->platformdev, drm); platform_set_drvdata(drm->platformdev, drm);
mutex_unlock(&imxdrm->mutex); mutex_unlock(&imxdrm->mutex);
/* Now try and bind all our sub-components */
ret = component_bind_all(drm->dev, drm);
if (ret)
goto err_relock;
return 0; return 0;
err_relock:
mutex_lock(&imxdrm->mutex);
err_vblank: err_vblank:
drm_vblank_cleanup(drm); drm_vblank_cleanup(drm);
err_kms: err_kms:
...@@ -809,6 +815,70 @@ static struct drm_driver imx_drm_driver = { ...@@ -809,6 +815,70 @@ static struct drm_driver imx_drm_driver = {
.patchlevel = 0, .patchlevel = 0,
}; };
static int compare_parent_of(struct device *dev, void *data)
{
struct of_phandle_args *args = data;
return dev->parent && dev->parent->of_node == args->np;
}
static int compare_of(struct device *dev, void *data)
{
return dev->of_node == data;
}
static int imx_drm_add_components(struct device *master, struct master *m)
{
struct device_node *np = master->of_node;
unsigned i;
int ret;
for (i = 0; ; i++) {
struct of_phandle_args args;
ret = of_parse_phandle_with_fixed_args(np, "crtcs", 1,
i, &args);
if (ret)
break;
ret = component_master_add_child(m, compare_parent_of, &args);
of_node_put(args.np);
if (ret)
return ret;
}
for (i = 0; ; i++) {
struct device_node *node;
node = of_parse_phandle(np, "connectors", i);
if (!node)
break;
ret = component_master_add_child(m, compare_of, node);
of_node_put(node);
if (ret)
return ret;
}
return 0;
}
static int imx_drm_bind(struct device *dev)
{
return drm_platform_init(&imx_drm_driver, to_platform_device(dev));
}
static void imx_drm_unbind(struct device *dev)
{
drm_put_dev(dev_get_drvdata(dev));
}
static const struct component_master_ops imx_drm_ops = {
.add_components = imx_drm_add_components,
.bind = imx_drm_bind,
.unbind = imx_drm_unbind,
};
static int imx_drm_platform_probe(struct platform_device *pdev) static int imx_drm_platform_probe(struct platform_device *pdev)
{ {
int ret; int ret;
...@@ -819,27 +889,31 @@ static int imx_drm_platform_probe(struct platform_device *pdev) ...@@ -819,27 +889,31 @@ static int imx_drm_platform_probe(struct platform_device *pdev)
imx_drm_device->dev = &pdev->dev; imx_drm_device->dev = &pdev->dev;
return drm_platform_init(&imx_drm_driver, pdev); return component_master_add(&pdev->dev, &imx_drm_ops);
} }
static int imx_drm_platform_remove(struct platform_device *pdev) static int imx_drm_platform_remove(struct platform_device *pdev)
{ {
drm_put_dev(platform_get_drvdata(pdev)); component_master_del(&pdev->dev, &imx_drm_ops);
return 0; return 0;
} }
static const struct of_device_id imx_drm_dt_ids[] = {
{ .compatible = "fsl,imx-drm", },
{ /* sentinel */ },
};
MODULE_DEVICE_TABLE(of, imx_drm_dt_ids);
static struct platform_driver imx_drm_pdrv = { static struct platform_driver imx_drm_pdrv = {
.probe = imx_drm_platform_probe, .probe = imx_drm_platform_probe,
.remove = imx_drm_platform_remove, .remove = imx_drm_platform_remove,
.driver = { .driver = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
.name = "imx-drm", .name = "imx-drm",
.of_match_table = imx_drm_dt_ids,
}, },
}; };
static struct platform_device *imx_drm_pdev;
static int __init imx_drm_init(void) static int __init imx_drm_init(void)
{ {
int ret; int ret;
...@@ -852,12 +926,6 @@ static int __init imx_drm_init(void) ...@@ -852,12 +926,6 @@ static int __init imx_drm_init(void)
INIT_LIST_HEAD(&imx_drm_device->connector_list); INIT_LIST_HEAD(&imx_drm_device->connector_list);
INIT_LIST_HEAD(&imx_drm_device->encoder_list); INIT_LIST_HEAD(&imx_drm_device->encoder_list);
imx_drm_pdev = platform_device_register_simple("imx-drm", -1, NULL, 0);
if (IS_ERR(imx_drm_pdev)) {
ret = PTR_ERR(imx_drm_pdev);
goto err_pdev;
}
ret = platform_driver_register(&imx_drm_pdrv); ret = platform_driver_register(&imx_drm_pdrv);
if (ret) if (ret)
goto err_pdrv; goto err_pdrv;
...@@ -865,8 +933,6 @@ static int __init imx_drm_init(void) ...@@ -865,8 +933,6 @@ static int __init imx_drm_init(void)
return 0; return 0;
err_pdrv: err_pdrv:
platform_device_unregister(imx_drm_pdev);
err_pdev:
kfree(imx_drm_device); kfree(imx_drm_device);
return ret; return ret;
...@@ -874,7 +940,6 @@ static int __init imx_drm_init(void) ...@@ -874,7 +940,6 @@ static int __init imx_drm_init(void)
static void __exit imx_drm_exit(void) static void __exit imx_drm_exit(void)
{ {
platform_device_unregister(imx_drm_pdev);
platform_driver_unregister(&imx_drm_pdrv); platform_driver_unregister(&imx_drm_pdrv);
kfree(imx_drm_device); kfree(imx_drm_device);
......
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
* Copyright (C) 2010, Guennadi Liakhovetski <g.liakhovetski@gmx.de> * Copyright (C) 2010, Guennadi Liakhovetski <g.liakhovetski@gmx.de>
*/ */
#include <linux/component.h>
#include <linux/irq.h> #include <linux/irq.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/err.h> #include <linux/err.h>
...@@ -1582,21 +1583,22 @@ static const struct of_device_id imx_hdmi_dt_ids[] = { ...@@ -1582,21 +1583,22 @@ static const struct of_device_id imx_hdmi_dt_ids[] = {
}; };
MODULE_DEVICE_TABLE(of, imx_hdmi_dt_ids); MODULE_DEVICE_TABLE(of, imx_hdmi_dt_ids);
static int imx_hdmi_platform_probe(struct platform_device *pdev) static int imx_hdmi_bind(struct device *dev, struct device *master, void *data)
{ {
struct platform_device *pdev = to_platform_device(dev);
const struct of_device_id *of_id = const struct of_device_id *of_id =
of_match_device(imx_hdmi_dt_ids, &pdev->dev); of_match_device(imx_hdmi_dt_ids, dev);
struct device_node *np = pdev->dev.of_node; struct device_node *np = dev->of_node;
struct device_node *ddc_node; struct device_node *ddc_node;
struct imx_hdmi *hdmi; struct imx_hdmi *hdmi;
struct resource *iores; struct resource *iores;
int ret, irq; int ret, irq;
hdmi = devm_kzalloc(&pdev->dev, sizeof(*hdmi), GFP_KERNEL); hdmi = devm_kzalloc(dev, sizeof(*hdmi), GFP_KERNEL);
if (!hdmi) if (!hdmi)
return -ENOMEM; return -ENOMEM;
hdmi->dev = &pdev->dev; hdmi->dev = dev;
hdmi->sample_rate = 48000; hdmi->sample_rate = 48000;
hdmi->ratio = 100; hdmi->ratio = 100;
...@@ -1620,13 +1622,13 @@ static int imx_hdmi_platform_probe(struct platform_device *pdev) ...@@ -1620,13 +1622,13 @@ static int imx_hdmi_platform_probe(struct platform_device *pdev)
if (irq < 0) if (irq < 0)
return -EINVAL; return -EINVAL;
ret = devm_request_irq(&pdev->dev, irq, imx_hdmi_irq, 0, ret = devm_request_irq(dev, irq, imx_hdmi_irq, 0,
dev_name(&pdev->dev), hdmi); dev_name(dev), hdmi);
if (ret) if (ret)
return ret; return ret;
iores = platform_get_resource(pdev, IORESOURCE_MEM, 0); iores = platform_get_resource(pdev, IORESOURCE_MEM, 0);
hdmi->regs = devm_ioremap_resource(&pdev->dev, iores); hdmi->regs = devm_ioremap_resource(dev, iores);
if (IS_ERR(hdmi->regs)) if (IS_ERR(hdmi->regs))
return PTR_ERR(hdmi->regs); return PTR_ERR(hdmi->regs);
...@@ -1665,7 +1667,7 @@ static int imx_hdmi_platform_probe(struct platform_device *pdev) ...@@ -1665,7 +1667,7 @@ static int imx_hdmi_platform_probe(struct platform_device *pdev)
} }
/* Product and revision IDs */ /* Product and revision IDs */
dev_info(&pdev->dev, dev_info(dev,
"Detected HDMI controller 0x%x:0x%x:0x%x:0x%x\n", "Detected HDMI controller 0x%x:0x%x:0x%x:0x%x\n",
hdmi_readb(hdmi, HDMI_DESIGN_ID), hdmi_readb(hdmi, HDMI_DESIGN_ID),
hdmi_readb(hdmi, HDMI_REVISION_ID), hdmi_readb(hdmi, HDMI_REVISION_ID),
...@@ -1699,7 +1701,7 @@ static int imx_hdmi_platform_probe(struct platform_device *pdev) ...@@ -1699,7 +1701,7 @@ static int imx_hdmi_platform_probe(struct platform_device *pdev)
imx_drm_encoder_add_possible_crtcs(hdmi->imx_drm_encoder, np); imx_drm_encoder_add_possible_crtcs(hdmi->imx_drm_encoder, np);
platform_set_drvdata(pdev, hdmi); dev_set_drvdata(dev, hdmi);
return 0; return 0;
...@@ -1711,9 +1713,10 @@ static int imx_hdmi_platform_probe(struct platform_device *pdev) ...@@ -1711,9 +1713,10 @@ static int imx_hdmi_platform_probe(struct platform_device *pdev)
return ret; return ret;
} }
static int imx_hdmi_platform_remove(struct platform_device *pdev) static void imx_hdmi_unbind(struct device *dev, struct device *master,
void *data)
{ {
struct imx_hdmi *hdmi = platform_get_drvdata(pdev); struct imx_hdmi *hdmi = dev_get_drvdata(dev);
struct drm_connector *connector = &hdmi->connector; struct drm_connector *connector = &hdmi->connector;
struct drm_encoder *encoder = &hdmi->encoder; struct drm_encoder *encoder = &hdmi->encoder;
...@@ -1724,7 +1727,21 @@ static int imx_hdmi_platform_remove(struct platform_device *pdev) ...@@ -1724,7 +1727,21 @@ static int imx_hdmi_platform_remove(struct platform_device *pdev)
clk_disable_unprepare(hdmi->iahb_clk); clk_disable_unprepare(hdmi->iahb_clk);
clk_disable_unprepare(hdmi->isfr_clk); clk_disable_unprepare(hdmi->isfr_clk);
i2c_put_adapter(hdmi->ddc); i2c_put_adapter(hdmi->ddc);
}
static const struct component_ops hdmi_ops = {
.bind = imx_hdmi_bind,
.unbind = imx_hdmi_unbind,
};
static int imx_hdmi_platform_probe(struct platform_device *pdev)
{
return component_add(&pdev->dev, &hdmi_ops);
}
static int imx_hdmi_platform_remove(struct platform_device *pdev)
{
component_del(&pdev->dev, &hdmi_ops);
return 0; return 0;
} }
......
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
#include <linux/module.h> #include <linux/module.h>
#include <linux/clk.h> #include <linux/clk.h>
#include <linux/component.h>
#include <drm/drmP.h> #include <drm/drmP.h>
#include <drm/drm_fb_helper.h> #include <drm/drm_fb_helper.h>
#include <drm/drm_crtc_helper.h> #include <drm/drm_crtc_helper.h>
...@@ -450,11 +451,11 @@ static const struct of_device_id imx_ldb_dt_ids[] = { ...@@ -450,11 +451,11 @@ static const struct of_device_id imx_ldb_dt_ids[] = {
}; };
MODULE_DEVICE_TABLE(of, imx_ldb_dt_ids); MODULE_DEVICE_TABLE(of, imx_ldb_dt_ids);
static int imx_ldb_probe(struct platform_device *pdev) static int imx_ldb_bind(struct device *dev, struct device *master, void *data)
{ {
struct device_node *np = pdev->dev.of_node; struct device_node *np = dev->of_node;
const struct of_device_id *of_id = const struct of_device_id *of_id =
of_match_device(imx_ldb_dt_ids, &pdev->dev); of_match_device(imx_ldb_dt_ids, dev);
struct device_node *child; struct device_node *child;
const u8 *edidp; const u8 *edidp;
struct imx_ldb *imx_ldb; struct imx_ldb *imx_ldb;
...@@ -464,17 +465,17 @@ static int imx_ldb_probe(struct platform_device *pdev) ...@@ -464,17 +465,17 @@ static int imx_ldb_probe(struct platform_device *pdev)
int ret; int ret;
int i; int i;
imx_ldb = devm_kzalloc(&pdev->dev, sizeof(*imx_ldb), GFP_KERNEL); imx_ldb = devm_kzalloc(dev, sizeof(*imx_ldb), GFP_KERNEL);
if (!imx_ldb) if (!imx_ldb)
return -ENOMEM; return -ENOMEM;
imx_ldb->regmap = syscon_regmap_lookup_by_phandle(np, "gpr"); imx_ldb->regmap = syscon_regmap_lookup_by_phandle(np, "gpr");
if (IS_ERR(imx_ldb->regmap)) { if (IS_ERR(imx_ldb->regmap)) {
dev_err(&pdev->dev, "failed to get parent regmap\n"); dev_err(dev, "failed to get parent regmap\n");
return PTR_ERR(imx_ldb->regmap); return PTR_ERR(imx_ldb->regmap);
} }
imx_ldb->dev = &pdev->dev; imx_ldb->dev = dev;
if (of_id) if (of_id)
imx_ldb->lvds_mux = of_id->data; imx_ldb->lvds_mux = of_id->data;
...@@ -512,7 +513,7 @@ static int imx_ldb_probe(struct platform_device *pdev) ...@@ -512,7 +513,7 @@ static int imx_ldb_probe(struct platform_device *pdev)
return -EINVAL; return -EINVAL;
if (dual && i > 0) { if (dual && i > 0) {
dev_warn(&pdev->dev, "dual-channel mode, ignoring second output\n"); dev_warn(dev, "dual-channel mode, ignoring second output\n");
continue; continue;
} }
...@@ -551,7 +552,7 @@ static int imx_ldb_probe(struct platform_device *pdev) ...@@ -551,7 +552,7 @@ static int imx_ldb_probe(struct platform_device *pdev)
break; break;
case LVDS_BIT_MAP_JEIDA: case LVDS_BIT_MAP_JEIDA:
if (datawidth == 18) { if (datawidth == 18) {
dev_err(&pdev->dev, "JEIDA standard only supported in 24 bit\n"); dev_err(dev, "JEIDA standard only supported in 24 bit\n");
return -EINVAL; return -EINVAL;
} }
if (i == 0 || dual) if (i == 0 || dual)
...@@ -560,7 +561,7 @@ static int imx_ldb_probe(struct platform_device *pdev) ...@@ -560,7 +561,7 @@ static int imx_ldb_probe(struct platform_device *pdev)
imx_ldb->ldb_ctrl |= LDB_DATA_WIDTH_CH1_24 | LDB_BIT_MAP_CH1_JEIDA; imx_ldb->ldb_ctrl |= LDB_DATA_WIDTH_CH1_24 | LDB_BIT_MAP_CH1_JEIDA;
break; break;
default: default:
dev_err(&pdev->dev, "data mapping not specified or invalid\n"); dev_err(dev, "data mapping not specified or invalid\n");
return -EINVAL; return -EINVAL;
} }
...@@ -571,14 +572,15 @@ static int imx_ldb_probe(struct platform_device *pdev) ...@@ -571,14 +572,15 @@ static int imx_ldb_probe(struct platform_device *pdev)
imx_drm_encoder_add_possible_crtcs(channel->imx_drm_encoder, child); imx_drm_encoder_add_possible_crtcs(channel->imx_drm_encoder, child);
} }
platform_set_drvdata(pdev, imx_ldb); dev_set_drvdata(dev, imx_ldb);
return 0; return 0;
} }
static int imx_ldb_remove(struct platform_device *pdev) static void imx_ldb_unbind(struct device *dev, struct device *master,
void *data)
{ {
struct imx_ldb *imx_ldb = platform_get_drvdata(pdev); struct imx_ldb *imx_ldb = dev_get_drvdata(dev);
int i; int i;
for (i = 0; i < 2; i++) { for (i = 0; i < 2; i++) {
...@@ -591,7 +593,21 @@ static int imx_ldb_remove(struct platform_device *pdev) ...@@ -591,7 +593,21 @@ static int imx_ldb_remove(struct platform_device *pdev)
imx_drm_remove_connector(channel->imx_drm_connector); imx_drm_remove_connector(channel->imx_drm_connector);
imx_drm_remove_encoder(channel->imx_drm_encoder); imx_drm_remove_encoder(channel->imx_drm_encoder);
} }
}
static const struct component_ops imx_ldb_ops = {
.bind = imx_ldb_bind,
.unbind = imx_ldb_unbind,
};
static int imx_ldb_probe(struct platform_device *pdev)
{
return component_add(&pdev->dev, &imx_ldb_ops);
}
static int imx_ldb_remove(struct platform_device *pdev)
{
component_del(&pdev->dev, &imx_ldb_ops);
return 0; return 0;
} }
......
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
#include <linux/clk.h> #include <linux/clk.h>
#include <linux/clk-provider.h> #include <linux/clk-provider.h>
#include <linux/component.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/regmap.h> #include <linux/regmap.h>
...@@ -583,9 +584,10 @@ static const int of_get_tve_mode(struct device_node *np) ...@@ -583,9 +584,10 @@ static const int of_get_tve_mode(struct device_node *np)
return -EINVAL; return -EINVAL;
} }
static int imx_tve_probe(struct platform_device *pdev) static int imx_tve_bind(struct device *dev, struct device *master, void *data)
{ {
struct device_node *np = pdev->dev.of_node; struct platform_device *pdev = to_platform_device(dev);
struct device_node *np = dev->of_node;
struct device_node *ddc_node; struct device_node *ddc_node;
struct imx_tve *tve; struct imx_tve *tve;
struct resource *res; struct resource *res;
...@@ -594,11 +596,11 @@ static int imx_tve_probe(struct platform_device *pdev) ...@@ -594,11 +596,11 @@ static int imx_tve_probe(struct platform_device *pdev)
int irq; int irq;
int ret; int ret;
tve = devm_kzalloc(&pdev->dev, sizeof(*tve), GFP_KERNEL); tve = devm_kzalloc(dev, sizeof(*tve), GFP_KERNEL);
if (!tve) if (!tve)
return -ENOMEM; return -ENOMEM;
tve->dev = &pdev->dev; tve->dev = dev;
spin_lock_init(&tve->lock); spin_lock_init(&tve->lock);
ddc_node = of_parse_phandle(np, "ddc", 0); ddc_node = of_parse_phandle(np, "ddc", 0);
...@@ -609,7 +611,7 @@ static int imx_tve_probe(struct platform_device *pdev) ...@@ -609,7 +611,7 @@ static int imx_tve_probe(struct platform_device *pdev)
tve->mode = of_get_tve_mode(np); tve->mode = of_get_tve_mode(np);
if (tve->mode != TVE_MODE_VGA) { if (tve->mode != TVE_MODE_VGA) {
dev_err(&pdev->dev, "only VGA mode supported, currently\n"); dev_err(dev, "only VGA mode supported, currently\n");
return -EINVAL; return -EINVAL;
} }
...@@ -618,7 +620,7 @@ static int imx_tve_probe(struct platform_device *pdev) ...@@ -618,7 +620,7 @@ static int imx_tve_probe(struct platform_device *pdev)
&tve->hsync_pin); &tve->hsync_pin);
if (ret < 0) { if (ret < 0) {
dev_err(&pdev->dev, "failed to get vsync pin\n"); dev_err(dev, "failed to get vsync pin\n");
return ret; return ret;
} }
...@@ -626,40 +628,40 @@ static int imx_tve_probe(struct platform_device *pdev) ...@@ -626,40 +628,40 @@ static int imx_tve_probe(struct platform_device *pdev)
&tve->vsync_pin); &tve->vsync_pin);
if (ret < 0) { if (ret < 0) {
dev_err(&pdev->dev, "failed to get vsync pin\n"); dev_err(dev, "failed to get vsync pin\n");
return ret; return ret;
} }
} }
res = platform_get_resource(pdev, IORESOURCE_MEM, 0); res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
base = devm_ioremap_resource(&pdev->dev, res); base = devm_ioremap_resource(dev, res);
if (IS_ERR(base)) if (IS_ERR(base))
return PTR_ERR(base); return PTR_ERR(base);
tve_regmap_config.lock_arg = tve; tve_regmap_config.lock_arg = tve;
tve->regmap = devm_regmap_init_mmio_clk(&pdev->dev, "tve", base, tve->regmap = devm_regmap_init_mmio_clk(dev, "tve", base,
&tve_regmap_config); &tve_regmap_config);
if (IS_ERR(tve->regmap)) { if (IS_ERR(tve->regmap)) {
dev_err(&pdev->dev, "failed to init regmap: %ld\n", dev_err(dev, "failed to init regmap: %ld\n",
PTR_ERR(tve->regmap)); PTR_ERR(tve->regmap));
return PTR_ERR(tve->regmap); return PTR_ERR(tve->regmap);
} }
irq = platform_get_irq(pdev, 0); irq = platform_get_irq(pdev, 0);
if (irq < 0) { if (irq < 0) {
dev_err(&pdev->dev, "failed to get irq\n"); dev_err(dev, "failed to get irq\n");
return irq; return irq;
} }
ret = devm_request_threaded_irq(&pdev->dev, irq, NULL, ret = devm_request_threaded_irq(dev, irq, NULL,
imx_tve_irq_handler, IRQF_ONESHOT, imx_tve_irq_handler, IRQF_ONESHOT,
"imx-tve", tve); "imx-tve", tve);
if (ret < 0) { if (ret < 0) {
dev_err(&pdev->dev, "failed to request irq: %d\n", ret); dev_err(dev, "failed to request irq: %d\n", ret);
return ret; return ret;
} }
tve->dac_reg = devm_regulator_get(&pdev->dev, "dac"); tve->dac_reg = devm_regulator_get(dev, "dac");
if (!IS_ERR(tve->dac_reg)) { if (!IS_ERR(tve->dac_reg)) {
regulator_set_voltage(tve->dac_reg, 2750000, 2750000); regulator_set_voltage(tve->dac_reg, 2750000, 2750000);
ret = regulator_enable(tve->dac_reg); ret = regulator_enable(tve->dac_reg);
...@@ -667,17 +669,17 @@ static int imx_tve_probe(struct platform_device *pdev) ...@@ -667,17 +669,17 @@ static int imx_tve_probe(struct platform_device *pdev)
return ret; return ret;
} }
tve->clk = devm_clk_get(&pdev->dev, "tve"); tve->clk = devm_clk_get(dev, "tve");
if (IS_ERR(tve->clk)) { if (IS_ERR(tve->clk)) {
dev_err(&pdev->dev, "failed to get high speed tve clock: %ld\n", dev_err(dev, "failed to get high speed tve clock: %ld\n",
PTR_ERR(tve->clk)); PTR_ERR(tve->clk));
return PTR_ERR(tve->clk); return PTR_ERR(tve->clk);
} }
/* this is the IPU DI clock input selector, can be parented to tve_di */ /* this is the IPU DI clock input selector, can be parented to tve_di */
tve->di_sel_clk = devm_clk_get(&pdev->dev, "di_sel"); tve->di_sel_clk = devm_clk_get(dev, "di_sel");
if (IS_ERR(tve->di_sel_clk)) { if (IS_ERR(tve->di_sel_clk)) {
dev_err(&pdev->dev, "failed to get ipu di mux clock: %ld\n", dev_err(dev, "failed to get ipu di mux clock: %ld\n",
PTR_ERR(tve->di_sel_clk)); PTR_ERR(tve->di_sel_clk));
return PTR_ERR(tve->di_sel_clk); return PTR_ERR(tve->di_sel_clk);
} }
...@@ -688,11 +690,11 @@ static int imx_tve_probe(struct platform_device *pdev) ...@@ -688,11 +690,11 @@ static int imx_tve_probe(struct platform_device *pdev)
ret = regmap_read(tve->regmap, TVE_COM_CONF_REG, &val); ret = regmap_read(tve->regmap, TVE_COM_CONF_REG, &val);
if (ret < 0) { if (ret < 0) {
dev_err(&pdev->dev, "failed to read configuration register: %d\n", ret); dev_err(dev, "failed to read configuration register: %d\n", ret);
return ret; return ret;
} }
if (val != 0x00100000) { if (val != 0x00100000) {
dev_err(&pdev->dev, "configuration register default value indicates this is not a TVEv2\n"); dev_err(dev, "configuration register default value indicates this is not a TVEv2\n");
return -ENODEV; return -ENODEV;
} }
...@@ -705,14 +707,15 @@ static int imx_tve_probe(struct platform_device *pdev) ...@@ -705,14 +707,15 @@ static int imx_tve_probe(struct platform_device *pdev)
ret = imx_drm_encoder_add_possible_crtcs(tve->imx_drm_encoder, np); ret = imx_drm_encoder_add_possible_crtcs(tve->imx_drm_encoder, np);
platform_set_drvdata(pdev, tve); dev_set_drvdata(dev, tve);
return 0; return 0;
} }
static int imx_tve_remove(struct platform_device *pdev) static void imx_tve_unbind(struct device *dev, struct device *master,
void *data)
{ {
struct imx_tve *tve = platform_get_drvdata(pdev); struct imx_tve *tve = dev_get_drvdata(dev);
struct drm_connector *connector = &tve->connector; struct drm_connector *connector = &tve->connector;
struct drm_encoder *encoder = &tve->encoder; struct drm_encoder *encoder = &tve->encoder;
...@@ -723,7 +726,21 @@ static int imx_tve_remove(struct platform_device *pdev) ...@@ -723,7 +726,21 @@ static int imx_tve_remove(struct platform_device *pdev)
if (!IS_ERR(tve->dac_reg)) if (!IS_ERR(tve->dac_reg))
regulator_disable(tve->dac_reg); regulator_disable(tve->dac_reg);
}
static const struct component_ops imx_tve_ops = {
.bind = imx_tve_bind,
.unbind = imx_tve_unbind,
};
static int imx_tve_probe(struct platform_device *pdev)
{
return component_add(&pdev->dev, &imx_tve_ops);
}
static int imx_tve_remove(struct platform_device *pdev)
{
component_del(&pdev->dev, &imx_tve_ops);
return 0; return 0;
} }
......
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301, USA. * MA 02110-1301, USA.
*/ */
#include <linux/component.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/export.h> #include <linux/export.h>
#include <linux/device.h> #include <linux/device.h>
...@@ -400,43 +401,60 @@ static int ipu_crtc_init(struct ipu_crtc *ipu_crtc, ...@@ -400,43 +401,60 @@ static int ipu_crtc_init(struct ipu_crtc *ipu_crtc,
return ret; return ret;
} }
static int ipu_drm_probe(struct platform_device *pdev) static int ipu_drm_bind(struct device *dev, struct device *master, void *data)
{ {
struct ipu_client_platformdata *pdata = pdev->dev.platform_data; struct ipu_client_platformdata *pdata = dev->platform_data;
struct ipu_crtc *ipu_crtc; struct ipu_crtc *ipu_crtc;
int ret; int ret;
if (!pdata) ipu_crtc = devm_kzalloc(dev, sizeof(*ipu_crtc), GFP_KERNEL);
return -EINVAL;
ret = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32));
if (ret)
return ret;
ipu_crtc = devm_kzalloc(&pdev->dev, sizeof(*ipu_crtc), GFP_KERNEL);
if (!ipu_crtc) if (!ipu_crtc)
return -ENOMEM; return -ENOMEM;
ipu_crtc->dev = &pdev->dev; ipu_crtc->dev = dev;
ret = ipu_crtc_init(ipu_crtc, pdata); ret = ipu_crtc_init(ipu_crtc, pdata);
if (ret) if (ret)
return ret; return ret;
platform_set_drvdata(pdev, ipu_crtc); dev_set_drvdata(dev, ipu_crtc);
return 0; return 0;
} }
static int ipu_drm_remove(struct platform_device *pdev) static void ipu_drm_unbind(struct device *dev, struct device *master,
void *data)
{ {
struct ipu_crtc *ipu_crtc = platform_get_drvdata(pdev); struct ipu_crtc *ipu_crtc = dev_get_drvdata(dev);
imx_drm_remove_crtc(ipu_crtc->imx_crtc); imx_drm_remove_crtc(ipu_crtc->imx_crtc);
ipu_plane_put_resources(ipu_crtc->plane[0]); ipu_plane_put_resources(ipu_crtc->plane[0]);
ipu_put_resources(ipu_crtc); ipu_put_resources(ipu_crtc);
}
static const struct component_ops ipu_crtc_ops = {
.bind = ipu_drm_bind,
.unbind = ipu_drm_unbind,
};
static int ipu_drm_probe(struct platform_device *pdev)
{
int ret;
if (!pdev->dev.platform_data)
return -EINVAL;
ret = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32));
if (ret)
return ret;
return component_add(&pdev->dev, &ipu_crtc_ops);
}
static int ipu_drm_remove(struct platform_device *pdev)
{
component_del(&pdev->dev, &ipu_crtc_ops);
return 0; return 0;
} }
......
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
* MA 02110-1301, USA. * MA 02110-1301, USA.
*/ */
#include <linux/component.h>
#include <linux/module.h> #include <linux/module.h>
#include <drm/drmP.h> #include <drm/drmP.h>
#include <drm/drm_fb_helper.h> #include <drm/drm_fb_helper.h>
...@@ -192,15 +193,15 @@ static int imx_pd_register(struct imx_parallel_display *imxpd) ...@@ -192,15 +193,15 @@ static int imx_pd_register(struct imx_parallel_display *imxpd)
return 0; return 0;
} }
static int imx_pd_probe(struct platform_device *pdev) static int imx_pd_bind(struct device *dev, struct device *master, void *data)
{ {
struct device_node *np = pdev->dev.of_node; struct device_node *np = dev->of_node;
const u8 *edidp; const u8 *edidp;
struct imx_parallel_display *imxpd; struct imx_parallel_display *imxpd;
int ret; int ret;
const char *fmt; const char *fmt;
imxpd = devm_kzalloc(&pdev->dev, sizeof(*imxpd), GFP_KERNEL); imxpd = devm_kzalloc(dev, sizeof(*imxpd), GFP_KERNEL);
if (!imxpd) if (!imxpd)
return -ENOMEM; return -ENOMEM;
...@@ -218,7 +219,7 @@ static int imx_pd_probe(struct platform_device *pdev) ...@@ -218,7 +219,7 @@ static int imx_pd_probe(struct platform_device *pdev)
imxpd->interface_pix_fmt = V4L2_PIX_FMT_BGR666; imxpd->interface_pix_fmt = V4L2_PIX_FMT_BGR666;
} }
imxpd->dev = &pdev->dev; imxpd->dev = dev;
ret = imx_pd_register(imxpd); ret = imx_pd_register(imxpd);
if (ret) if (ret)
...@@ -226,14 +227,15 @@ static int imx_pd_probe(struct platform_device *pdev) ...@@ -226,14 +227,15 @@ static int imx_pd_probe(struct platform_device *pdev)
ret = imx_drm_encoder_add_possible_crtcs(imxpd->imx_drm_encoder, np); ret = imx_drm_encoder_add_possible_crtcs(imxpd->imx_drm_encoder, np);
platform_set_drvdata(pdev, imxpd); dev_set_drvdata(dev, imxpd);
return 0; return 0;
} }
static int imx_pd_remove(struct platform_device *pdev) static void imx_pd_unbind(struct device *dev, struct device *master,
void *data)
{ {
struct imx_parallel_display *imxpd = platform_get_drvdata(pdev); struct imx_parallel_display *imxpd = dev_get_drvdata(dev);
struct drm_connector *connector = &imxpd->connector; struct drm_connector *connector = &imxpd->connector;
struct drm_encoder *encoder = &imxpd->encoder; struct drm_encoder *encoder = &imxpd->encoder;
...@@ -241,7 +243,21 @@ static int imx_pd_remove(struct platform_device *pdev) ...@@ -241,7 +243,21 @@ static int imx_pd_remove(struct platform_device *pdev)
imx_drm_remove_connector(imxpd->imx_drm_connector); imx_drm_remove_connector(imxpd->imx_drm_connector);
imx_drm_remove_encoder(imxpd->imx_drm_encoder); imx_drm_remove_encoder(imxpd->imx_drm_encoder);
}
static const struct component_ops imx_pd_ops = {
.bind = imx_pd_bind,
.unbind = imx_pd_unbind,
};
static int imx_pd_probe(struct platform_device *pdev)
{
return component_add(&pdev->dev, &imx_pd_ops);
}
static int imx_pd_remove(struct platform_device *pdev)
{
component_del(&pdev->dev, &imx_pd_ops);
return 0; return 0;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment