summaryrefslogtreecommitdiff
path: root/drivers/media
diff options
context:
space:
mode:
authorMayuresh Kulkarni <mkulkarni@nvidia.com>2012-10-26 18:47:24 +0530
committerSimone Willett <swillett@nvidia.com>2012-11-02 15:43:11 -0700
commita38513038c22fbb97705bbb69e51abd4548fa2a6 (patch)
tree4b3d79e831d675abfe744133e30421ade9dd9986 /drivers/media
parentcd236755b4147de6402298f6a2b7562a5f497e73 (diff)
video: tegra: host: use platform bus/driver/device
- this commit replaces the custom nvhost bus/driver/device with platform bus/driver/device - this is in preparation to add DT support - following is the list of notable changes done: 1. chip_ops: The per SoC differences is encapsulated by chip_ops structure. With nvhost_bus: - It is hidden in nvhost_bus and exposed APIs to rest of the code. These APIs land up in correct implementation for current SoC. With platform_bus: - I had to make this global and adjust the API accordingly. 2. nvhost_device With nvhost_bus: - The struct nvhost_device encapsulates both Linux device driver parts as well as tegra specific parts. With platform_bus: - I had to move the current nvhost_device as a platform_data for each platform_device. For this I renamed the struct nvhost_device to struct nvhost_device_data. - Also, since nvhost_driver is gone, I had to move all the function pointers in it to struct nvhost_device_data. 3. Device specific private data: Host1x master device has its own static data (called nvhost_master) which stores the per SoC sync-point, IRQ info etc. With nvhost_bus: - This was stored as device specific platform_data. With platform_bus: - The device specific platform_data is now struct nvhost_device_data (as mentioned above). - I need to keep it common for all the devices whose code is part of host1x directory, so that other parts of code that need per-device info have a unique interface of platform_get_drvdata. - As a result, I had to add a void * field in struct nvhost_device_data which now holds per-device specific data and expose APIs to get/set this data. - As of now, only host1x master parent device code uses this. 4. Per SoC device names: With nvhost_bus: - Per SoC device name is SAME for all the SoCs. - The correct driver get linked to this device via the concept of id_table. This id_table allows us to connect multiple devices to single driver code and pass appropriate function pointer specific to SoC (you can check gr3d.c for details). With platform_bus: - The id_table usage of platform_bus is different from above. - To adhere to its need, I had to append the per-SoC device name with a version field (so gr3d for t20 became gr3d01, for t30 became gr3d02 etc). - I adjusted the correct names in _probe of such devices. Also, I adjusted the node names exposed to user space (/dev/host-gr3d etc) to be consistent across SoCs. - But this fails for the sysfs entries created by device registration code of Linux, since during this time the _probe is not called. So, device name is still appended with version field. 5. Per SoC device registration function: tegraXXX_register_host1x_devices is the per SoC specific APIs which is called by board-file to register the host1x and client devices. Host1x has strict requirements for the parent->child relations i.e. any client of host1x device should have the parent set properly BEFORE device registration. With nvhost_bus: - Setting of parent was taken care by nvhost_device_register call and other helpers. With platform_bus: - It is not possible to change parent till _probe of client device returns (meaning not much of control in our hand). The device driver core, takes a mutex lock of parent BEFORE calling _probe to avoid changing parent during _probe. - So, to set correct parent, I changed the return type of tegraXXX_register_host1x_devices to return pointer to master host1x parent device. 6. platform_get_drvdata calls: With nvhost_bus: - Only host1x master parent calls this. With platform_bus: - Almost all the common code ends up calling this. Fortunately, we had designed the APIs such that they take nvhost_device * as argument. So changing them to platform_device * is in a way easy. 7. Device list: The debug-fs dump code & module-reg-read-write functionality rely on having a list of host1x devices registered currently. With nvhost_bus: - This is readily available since struct bus_type of Linux holds this list. Moreover, it provides an iterators to access this list. With platform_bus: - Since it holds large number of devices in system, it is inefficient to use the above iterators. Also, it is difficult to have a common matching criteria for all the devices who have different platform_data. - As a result, I had to add a simple list using Linux kernel's list implementation. It holds the list of devices which have their code within host1x directory and actually use channels (remember tegra-dc and nvavp are outside host1x code && do not use physical channels they only need sync-point and host1x hardware alive when they are alive). I also had to provide 2 iterators one which is used for module-reg-read-write and other for debug-fs dump. 8. I changed how tegra-dc and nvavp called the host1x externally exposed APIs (such APIs end with _ext). In current code, they know little too much of host1x code internals. I now changed to make them independent of host1x internal implementation and structure know-how. They now simply send their own platform_device * to the external visible APIs and these APIs ensures that the call ends up in correct function call. bug 1041377 Change-Id: I9cd4d506e6f3bde805923ce7c7bbbd37c9ec13c4 Signed-off-by: Mayuresh Kulkarni <mkulkarni@nvidia.com> Reviewed-on: http://git-master/r/131403 Reviewed-by: Simone Willett <swillett@nvidia.com> Tested-by: Simone Willett <swillett@nvidia.com>
Diffstat (limited to 'drivers/media')
-rw-r--r--drivers/media/video/tegra/nvavp/nvavp_dev.c41
1 files changed, 20 insertions, 21 deletions
diff --git a/drivers/media/video/tegra/nvavp/nvavp_dev.c b/drivers/media/video/tegra/nvavp/nvavp_dev.c
index 01bb253f2b9a..704cf8703e9f 100644
--- a/drivers/media/video/tegra/nvavp/nvavp_dev.c
+++ b/drivers/media/video/tegra/nvavp/nvavp_dev.c
@@ -144,7 +144,7 @@ struct nvavp_info {
u32 syncpt_id;
u32 syncpt_value;
- struct nvhost_device *nvhost_dev;
+ struct platform_device *nvhost_dev;
struct miscdevice video_misc_dev;
#if defined(CONFIG_TEGRA_NVAVP_AUDIO)
struct miscdevice audio_misc_dev;
@@ -295,7 +295,7 @@ static int nvavp_unpowergate_vde(struct nvavp_info *nvavp)
static void nvavp_clks_enable(struct nvavp_info *nvavp)
{
if (nvavp->clk_enabled++ == 0) {
- nvhost_module_busy_ext(nvhost_get_parent(nvavp->nvhost_dev));
+ nvhost_module_busy_ext(nvavp->nvhost_dev);
clk_prepare_enable(nvavp->bsev_clk);
clk_prepare_enable(nvavp->vde_clk);
nvavp_unpowergate_vde(nvavp);
@@ -316,7 +316,7 @@ static void nvavp_clks_disable(struct nvavp_info *nvavp)
clk_set_rate(nvavp->emc_clk, 0);
clk_set_rate(nvavp->sclk, 0);
nvavp_powergate_vde(nvavp);
- nvhost_module_idle_ext(nvhost_get_parent(nvavp->nvhost_dev));
+ nvhost_module_idle_ext(nvavp->nvhost_dev);
dev_dbg(&nvavp->nvhost_dev->dev, "%s: resetting emc_clk "
"and sclk\n", __func__);
}
@@ -1533,16 +1533,16 @@ static const struct file_operations tegra_audio_nvavp_fops = {
#endif
static ssize_t boost_sclk_show(struct device *dev,
- struct device_attribute *attr, char *buf)
+ struct device_attribute *attr, char *buf)
{
return snprintf(buf, PAGE_SIZE, "%d\n", boost_sclk);
}
static ssize_t boost_sclk_store(struct device *dev,
- struct device_attribute *attr, const char *buf, size_t count)
+ struct device_attribute *attr, const char *buf, size_t count)
{
- struct nvhost_device *ndev = to_nvhost_device(dev);
- struct nvavp_info *nvavp = nvhost_get_drvdata(ndev);
+ struct platform_device *ndev = to_platform_device(dev);
+ struct nvavp_info *nvavp = platform_get_drvdata(ndev);
unsigned long val = 0;
if (kstrtoul(buf, 10, &val) < 0)
@@ -1558,10 +1558,9 @@ static ssize_t boost_sclk_store(struct device *dev,
return count;
}
-DEVICE_ATTR(boost_sclk, S_IRUGO|S_IWUSR, boost_sclk_show, boost_sclk_store);
+DEVICE_ATTR(boost_sclk, S_IRUGO | S_IWUSR, boost_sclk_show, boost_sclk_store);
-static int tegra_nvavp_probe(struct nvhost_device *ndev,
- struct nvhost_device_id *id_table)
+static int tegra_nvavp_probe(struct platform_device *ndev)
{
struct nvavp_info *nvavp;
int irq;
@@ -1569,7 +1568,7 @@ static int tegra_nvavp_probe(struct nvhost_device *ndev,
u32 iovmm_addr;
int ret = 0, channel_id;
- irq = nvhost_get_irq_byname(ndev, "mbox_from_nvavp_pending");
+ irq = platform_get_irq_byname(ndev, "mbox_from_nvavp_pending");
if (irq < 0) {
dev_err(&ndev->dev, "invalid nvhost data\n");
return -EINVAL;
@@ -1766,8 +1765,8 @@ static int tegra_nvavp_probe(struct nvhost_device *ndev,
}
disable_irq(nvavp->mbox_from_avp_pend_irq);
- nvhost_set_drvdata(ndev, nvavp);
nvavp->nvhost_dev = ndev;
+ platform_set_drvdata(ndev, nvavp);
device_create_file(&ndev->dev, &dev_attr_boost_sclk);
@@ -1813,9 +1812,9 @@ err_get_syncpt:
return ret;
}
-static int tegra_nvavp_remove(struct nvhost_device *ndev)
+static int tegra_nvavp_remove(struct platform_device *ndev)
{
- struct nvavp_info *nvavp = nvhost_get_drvdata(ndev);
+ struct nvavp_info *nvavp = platform_get_drvdata(ndev);
if (!nvavp)
return 0;
@@ -1853,9 +1852,9 @@ static int tegra_nvavp_remove(struct nvhost_device *ndev)
}
#ifdef CONFIG_PM
-static int tegra_nvavp_suspend(struct nvhost_device *ndev, pm_message_t state)
+static int tegra_nvavp_suspend(struct platform_device *ndev, pm_message_t state)
{
- struct nvavp_info *nvavp = nvhost_get_drvdata(ndev);
+ struct nvavp_info *nvavp = platform_get_drvdata(ndev);
int ret = 0;
mutex_lock(&nvavp->open_lock);
@@ -1885,9 +1884,9 @@ static int tegra_nvavp_suspend(struct nvhost_device *ndev, pm_message_t state)
return ret;
}
-static int tegra_nvavp_resume(struct nvhost_device *ndev)
+static int tegra_nvavp_resume(struct platform_device *ndev)
{
- struct nvavp_info *nvavp = nvhost_get_drvdata(ndev);
+ struct nvavp_info *nvavp = platform_get_drvdata(ndev);
mutex_lock(&nvavp->open_lock);
@@ -1903,7 +1902,7 @@ static int tegra_nvavp_resume(struct nvhost_device *ndev)
}
#endif
-static struct nvhost_driver tegra_nvavp_driver = {
+static struct platform_driver tegra_nvavp_driver = {
.driver = {
.name = TEGRA_NVAVP_NAME,
.owner = THIS_MODULE,
@@ -1918,12 +1917,12 @@ static struct nvhost_driver tegra_nvavp_driver = {
static int __init tegra_nvavp_init(void)
{
- return nvhost_driver_register(&tegra_nvavp_driver);
+ return platform_driver_register(&tegra_nvavp_driver);
}
static void __exit tegra_nvavp_exit(void)
{
- nvhost_driver_unregister(&tegra_nvavp_driver);
+ platform_driver_unregister(&tegra_nvavp_driver);
}
module_init(tegra_nvavp_init);