summaryrefslogtreecommitdiff
path: root/drivers/video/tegra/host
diff options
context:
space:
mode:
authorMayuresh Kulkarni <mkulkarni@nvidia.com>2012-05-14 14:38:22 +0530
committerRohan Somvanshi <rsomvanshi@nvidia.com>2012-05-17 06:13:18 -0700
commita3b39fa6020e7c53236a50bbda1ca0a2ab78b2c2 (patch)
tree26fcb40c85645ef6ad1004ee65a3e28da8061288 /drivers/video/tegra/host
parente6ce6a3069e2a83c0343d6de8656aee95c6b49f3 (diff)
video: tegra: host: remove nvhost_channel from nvhost_master
- nvhost_master holds a reference to all the channels for a chip architecture - however, nvhost_master is a private data of host1x hardware device. so it should contain only members needed by host1x hardware device - add chip specific apis to allocate and free channels - this will also help to remove the static binding between nvhost_device and a channel per SoC in future Bug 871237 Change-Id: I2148db57b995b4cb60954ebb6e670f588552eca4 Signed-off-by: Mayuresh Kulkarni <mkulkarni@nvidia.com> Reviewed-on: http://git-master/r/91687 Reviewed-by: Automatic_Commit_Validation_User Reviewed-by: Terje Bergstrom <tbergstrom@nvidia.com>
Diffstat (limited to 'drivers/video/tegra/host')
-rw-r--r--drivers/video/tegra/host/bus_client.c7
-rw-r--r--drivers/video/tegra/host/chip_support.h5
-rw-r--r--drivers/video/tegra/host/dev.c23
-rw-r--r--drivers/video/tegra/host/dev.h4
-rw-r--r--drivers/video/tegra/host/nvhost_channel.c26
-rw-r--r--drivers/video/tegra/host/nvhost_channel.h12
-rw-r--r--drivers/video/tegra/host/t20/t20.c24
-rw-r--r--drivers/video/tegra/host/t30/t30.c23
8 files changed, 99 insertions, 25 deletions
diff --git a/drivers/video/tegra/host/bus_client.c b/drivers/video/tegra/host/bus_client.c
index 660e7956edba..9a32e5333d08 100644
--- a/drivers/video/tegra/host/bus_client.c
+++ b/drivers/video/tegra/host/bus_client.c
@@ -532,7 +532,11 @@ int nvhost_client_device_init(struct nvhost_device *dev)
{
int err;
struct nvhost_master *nvhost_master = nvhost_get_host(dev);
- struct nvhost_channel *ch = &nvhost_master->channels[dev->index];
+ struct nvhost_channel *ch;
+
+ ch = nvhost_alloc_channel(dev->index);
+ if (ch == NULL)
+ return -ENODEV;
/* store the pointer to this device for channel */
ch->dev = dev;
@@ -555,6 +559,7 @@ int nvhost_client_device_init(struct nvhost_device *dev)
fail:
/* Add clean-up */
+ nvhost_free_channel(ch);
return err;
}
diff --git a/drivers/video/tegra/host/chip_support.h b/drivers/video/tegra/host/chip_support.h
index 9f56a90d9953..c0d567df425a 100644
--- a/drivers/video/tegra/host/chip_support.h
+++ b/drivers/video/tegra/host/chip_support.h
@@ -138,8 +138,9 @@ struct nvhost_chip_support {
} intr;
struct {
- struct nvhost_device *(*get_nvhost_device)(struct nvhost_master *host,
- char *name);
+ struct nvhost_device *(*get_nvhost_device)(char *name);
+ struct nvhost_channel *(*alloc_nvhost_channel)(int chid);
+ void (*free_nvhost_channel)(struct nvhost_channel *ch);
} nvhost_dev;
};
diff --git a/drivers/video/tegra/host/dev.c b/drivers/video/tegra/host/dev.c
index 9142b52f72f2..f215b532d2bb 100644
--- a/drivers/video/tegra/host/dev.c
+++ b/drivers/video/tegra/host/dev.c
@@ -353,14 +353,23 @@ fail:
struct nvhost_device *nvhost_get_device(char *name)
{
BUG_ON(!host_device_op().get_nvhost_device);
- return host_device_op().get_nvhost_device(nvhost, name);
+ return host_device_op().get_nvhost_device(name);
}
-static void nvhost_free_resources(struct nvhost_master *host)
+struct nvhost_channel *nvhost_alloc_channel(int index)
+{
+ BUG_ON(!host_device_op().alloc_nvhost_channel);
+ return host_device_op().alloc_nvhost_channel(index);
+}
+
+void nvhost_free_channel(struct nvhost_channel *ch)
{
- kfree(host->channels);
- host->channels = 0;
+ BUG_ON(!host_device_op().free_nvhost_channel);
+ host_device_op().free_nvhost_channel(ch);
+}
+static void nvhost_free_resources(struct nvhost_master *host)
+{
kfree(host->intr.syncpt);
host->intr.syncpt = 0;
}
@@ -373,14 +382,10 @@ static int __devinit nvhost_alloc_resources(struct nvhost_master *host)
if (err)
return err;
- /* allocate items sized in chip specific support init */
- host->channels = kzalloc(sizeof(struct nvhost_channel) *
- host->nb_channels, GFP_KERNEL);
-
host->intr.syncpt = kzalloc(sizeof(struct nvhost_intr_syncpt) *
host->syncpt.nb_pts, GFP_KERNEL);
- if (!(host->channels && host->intr.syncpt)) {
+ if (!host->intr.syncpt) {
/* frees happen in the support removal phase */
return -ENOMEM;
}
diff --git a/drivers/video/tegra/host/dev.h b/drivers/video/tegra/host/dev.h
index 8360725ed88f..41c4fb59b264 100644
--- a/drivers/video/tegra/host/dev.h
+++ b/drivers/video/tegra/host/dev.h
@@ -43,8 +43,6 @@ struct nvhost_master {
struct nvmap_client *nvmap;
struct nvhost_intr intr;
struct nvhost_device *dev;
- struct nvhost_channel *channels;
- u32 nb_channels;
atomic_t clientid;
};
@@ -54,6 +52,8 @@ void nvhost_debug_init(struct nvhost_master *master);
void nvhost_debug_dump(struct nvhost_master *master);
struct nvhost_device *nvhost_get_device(char *name);
+struct nvhost_channel *nvhost_alloc_channel(int index);
+void nvhost_free_channel(struct nvhost_channel *ch);
extern pid_t nvhost_debug_null_kickoff_pid;
diff --git a/drivers/video/tegra/host/nvhost_channel.c b/drivers/video/tegra/host/nvhost_channel.c
index e09f50a6694e..8b79479bdc1a 100644
--- a/drivers/video/tegra/host/nvhost_channel.c
+++ b/drivers/video/tegra/host/nvhost_channel.c
@@ -125,3 +125,29 @@ int nvhost_channel_suspend(struct nvhost_channel *ch)
return ret;
}
+
+struct nvhost_channel *nvhost_alloc_channel_internal(int chindex,
+ int max_channels, int *current_channel_count)
+{
+ struct nvhost_channel *ch = NULL;
+
+ if ( (chindex > max_channels) ||
+ ( (*current_channel_count + 1) > max_channels) )
+ return NULL;
+ else {
+ ch = kzalloc(sizeof(*ch), GFP_KERNEL);
+ if (ch == NULL)
+ return NULL;
+ else {
+ (*current_channel_count)++;
+ return ch;
+ }
+ }
+}
+
+void nvhost_free_channel_internal(struct nvhost_channel *ch,
+ int *current_channel_count)
+{
+ kfree(ch);
+ (*current_channel_count)--;
+}
diff --git a/drivers/video/tegra/host/nvhost_channel.h b/drivers/video/tegra/host/nvhost_channel.h
index fd3dcbb58e9f..eac51731547b 100644
--- a/drivers/video/tegra/host/nvhost_channel.h
+++ b/drivers/video/tegra/host/nvhost_channel.h
@@ -70,10 +70,14 @@ int nvhost_channel_suspend(struct nvhost_channel *ch);
int nvhost_channel_drain_read_fifo(void __iomem *chan_regs,
u32 *ptr, unsigned int count, unsigned int *pending);
-int nvhost_channel_read_3d_reg(
- struct nvhost_channel *channel,
+int nvhost_channel_read_3d_reg(struct nvhost_channel *channel,
struct nvhost_hwctx *hwctx,
- u32 offset,
- u32 *value);
+ u32 offset, u32 *value);
+
+struct nvhost_channel *nvhost_alloc_channel_internal(int chindex,
+ int max_channels, int *current_channel_count);
+
+void nvhost_free_channel_internal(struct nvhost_channel *ch,
+ int *current_channel_count);
#endif
diff --git a/drivers/video/tegra/host/t20/t20.c b/drivers/video/tegra/host/t20/t20.c
index 02382cba50b7..673a81cd4966 100644
--- a/drivers/video/tegra/host/t20/t20.c
+++ b/drivers/video/tegra/host/t20/t20.c
@@ -43,7 +43,9 @@
#define NVMODMUTEX_VI (8)
#define NVMODMUTEX_DSI (9)
-#define NVHOST_NUMCHANNELS (NV_HOST1X_CHANNELS - 1)
+#define T20_NVHOST_NUMCHANNELS (NV_HOST1X_CHANNELS - 1)
+
+static int t20_num_alloc_channels = 0;
struct nvhost_device t20_devices[] = {
{
@@ -189,8 +191,6 @@ static int t20_channel_init(struct nvhost_channel *ch,
int nvhost_init_t20_channel_support(struct nvhost_master *host,
struct nvhost_chip_support *op)
{
- host->nb_channels = NVHOST_NUMCHANNELS;
-
op->channel.init = t20_channel_init;
op->channel.submit = host1x_channel_submit;
op->channel.read3dreg = host1x_channel_read_3d_reg;
@@ -198,8 +198,18 @@ int nvhost_init_t20_channel_support(struct nvhost_master *host,
return 0;
}
-struct nvhost_device *t20_get_nvhost_device(struct nvhost_master *host,
- char *name)
+static void t20_free_nvhost_channel(struct nvhost_channel *ch)
+{
+ nvhost_free_channel_internal(ch, &t20_num_alloc_channels);
+}
+
+static struct nvhost_channel *t20_alloc_nvhost_channel(int chindex)
+{
+ return nvhost_alloc_channel_internal(chindex,
+ T20_NVHOST_NUMCHANNELS, &t20_num_alloc_channels);
+}
+
+struct nvhost_device *t20_get_nvhost_device(char *name)
{
int i;
@@ -232,6 +242,10 @@ int nvhost_init_t20_support(struct nvhost_master *host,
err = nvhost_init_t20_intr_support(op);
if (err)
return err;
+
op->nvhost_dev.get_nvhost_device = t20_get_nvhost_device;
+ op->nvhost_dev.alloc_nvhost_channel = t20_alloc_nvhost_channel;
+ op->nvhost_dev.free_nvhost_channel = t20_free_nvhost_channel;
+
return 0;
}
diff --git a/drivers/video/tegra/host/t30/t30.c b/drivers/video/tegra/host/t30/t30.c
index 6e9b0afe9e43..d4113a898882 100644
--- a/drivers/video/tegra/host/t30/t30.c
+++ b/drivers/video/tegra/host/t30/t30.c
@@ -47,6 +47,10 @@
#define NVHOST_CHANNEL_BASE 0
+#define T30_NVHOST_NUMCHANNELS (NV_HOST1X_CHANNELS - 1)
+
+static int t30_num_alloc_channels = 0;
+
struct nvhost_device t30_devices[] = {
{
/* channel 0 */
@@ -209,6 +213,7 @@ int nvhost_init_t30_channel_support(struct nvhost_master *host,
return result;
}
+
int nvhost_init_t30_debug_support(struct nvhost_chip_support *op)
{
nvhost_init_t20_debug_support(op);
@@ -217,8 +222,18 @@ int nvhost_init_t30_debug_support(struct nvhost_chip_support *op)
return 0;
}
-struct nvhost_device *t30_get_nvhost_device(struct nvhost_master *host,
- char *name)
+static void t30_free_nvhost_channel(struct nvhost_channel *ch)
+{
+ nvhost_free_channel_internal(ch, &t30_num_alloc_channels);
+}
+
+static struct nvhost_channel *t30_alloc_nvhost_channel(int chindex)
+{
+ return nvhost_alloc_channel_internal(chindex,
+ T30_NVHOST_NUMCHANNELS, &t30_num_alloc_channels);
+}
+
+struct nvhost_device *t30_get_nvhost_device(char *name)
{
int i;
@@ -251,6 +266,10 @@ int nvhost_init_t30_support(struct nvhost_master *host,
err = nvhost_init_t20_intr_support(op);
if (err)
return err;
+
op->nvhost_dev.get_nvhost_device = t30_get_nvhost_device;
+ op->nvhost_dev.alloc_nvhost_channel = t30_alloc_nvhost_channel;
+ op->nvhost_dev.free_nvhost_channel = t30_free_nvhost_channel;
+
return 0;
}