17d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna/*
27d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna * drv_interface.c
37d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna *
47d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna * DSP-BIOS Bridge driver support functions for TI OMAP processors.
57d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna *
67d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna * DSP/BIOS Bridge driver interface.
77d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna *
87d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna * Copyright (C) 2005-2006 Texas Instruments, Inc.
97d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna *
107d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna * This package is free software; you can redistribute it and/or modify
117d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna * it under the terms of the GNU General Public License version 2 as
127d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna * published by the Free Software Foundation.
137d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna *
147d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
157d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
167d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
177d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna */
187d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna
1982d4b4776d575223c14b25546e0336541ef8ba94Felipe Contreras#include <plat/dsp.h>
2082d4b4776d575223c14b25546e0336541ef8ba94Felipe Contreras
212094f12d440c5a9fae032932266fa4a44135194cNishanth Menon#include <linux/types.h>
227d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna#include <linux/platform_device.h>
237d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna#include <linux/pm.h>
247d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna#include <linux/module.h>
257d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna#include <linux/device.h>
267d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna#include <linux/init.h>
277d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna#include <linux/moduleparam.h>
287d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna#include <linux/cdev.h>
297d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna
307d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna/*  ----------------------------------- DSP/BIOS Bridge */
317d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna#include <dspbridge/dbdefs.h>
327d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna
337d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna/*  ----------------------------------- OS Adaptation Layer */
347d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna#include <dspbridge/clk.h>
357d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna
367d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna/*  ----------------------------------- Platform Manager */
377d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna#include <dspbridge/dspapi.h>
387d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna#include <dspbridge/dspdrv.h>
397d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna
407d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna/*  ----------------------------------- Resource Manager */
417d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna#include <dspbridge/pwr.h>
427d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna
437d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna#include <dspbridge/resourcecleanup.h>
447d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna#include <dspbridge/proc.h>
457d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna#include <dspbridge/dev.h>
467d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna
47b3d23688a15c4c332942f9428e0d708e7362e29eFelipe Contreras#ifdef CONFIG_TIDSPBRIDGE_DVFS
487d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna#include <mach-omap2/omap3-opp.h>
497d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna#endif
507d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna
517d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna/*  ----------------------------------- Globals */
527d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna#define DSPBRIDGE_VERSION	"0.3"
537d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Lunas32 dsp_debug;
547d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna
557d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Lunastruct platform_device *omap_dspbridge_dev;
567d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Lunastruct device *bridge;
577d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna
587d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna/* This is a test variable used by Bridge to test different sleep states */
597d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Lunas32 dsp_test_sleepstate;
607d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna
617d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Lunastatic struct cdev bridge_cdev;
627d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna
637d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Lunastatic struct class *bridge_class;
647d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna
657d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Lunastatic u32 driver_context;
667d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Lunastatic s32 driver_major;
677d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Lunastatic char *base_img;
687d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Lunachar *iva_img;
697d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Lunastatic s32 shm_size = 0x500000;	/* 5 MB */
707d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Lunastatic int tc_wordswapon;	/* Default value is always false */
71b3d23688a15c4c332942f9428e0d708e7362e29eFelipe Contreras#ifdef CONFIG_TIDSPBRIDGE_RECOVERY
727d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna#define REC_TIMEOUT 5000	/*recovery timeout in msecs */
737d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Lunastatic atomic_t bridge_cref;	/* number of bridge open handles */
747d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Lunastatic struct workqueue_struct *bridge_rec_queue;
757d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Lunastatic struct work_struct bridge_recovery_work;
767d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Lunastatic DECLARE_COMPLETION(bridge_comp);
777d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Lunastatic DECLARE_COMPLETION(bridge_open_comp);
787d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Lunastatic bool recover;
797d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna#endif
807d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna
817d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna#ifdef CONFIG_PM
827d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Lunastruct omap34_xx_bridge_suspend_data {
837d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna	int suspended;
847d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna	wait_queue_head_t suspend_wq;
857d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna};
867d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna
877d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Lunastatic struct omap34_xx_bridge_suspend_data bridge_suspend_data;
887d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna
897d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Lunastatic int omap34_xxbridge_suspend_lockout(struct omap34_xx_bridge_suspend_data
907d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna					   *s, struct file *f)
917d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna{
927d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna	if ((s)->suspended) {
937d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna		if ((f)->f_flags & O_NONBLOCK)
947d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna			return -EPERM;
957d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna		wait_event_interruptible((s)->suspend_wq, (s)->suspended == 0);
967d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna	}
977d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna	return 0;
987d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna}
997d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna#endif
1007d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna
1017d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Lunamodule_param(dsp_debug, int, 0);
1027d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez LunaMODULE_PARM_DESC(dsp_debug, "Wait after loading DSP image. default = false");
1037d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna
1047d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Lunamodule_param(dsp_test_sleepstate, int, 0);
1057d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez LunaMODULE_PARM_DESC(dsp_test_sleepstate, "DSP Sleep state = 0");
1067d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna
1077d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Lunamodule_param(base_img, charp, 0);
1087d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez LunaMODULE_PARM_DESC(base_img, "DSP base image, default = NULL");
1097d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna
1107d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Lunamodule_param(shm_size, int, 0);
1117d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez LunaMODULE_PARM_DESC(shm_size, "shm size, default = 4 MB, minimum = 64 KB");
1127d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna
1137d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Lunamodule_param(tc_wordswapon, int, 0);
1147d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez LunaMODULE_PARM_DESC(tc_wordswapon, "TC Word Swap Option. default = 0");
1157d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna
1167d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez LunaMODULE_AUTHOR("Texas Instruments");
1177d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez LunaMODULE_LICENSE("GPL");
1187d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez LunaMODULE_VERSION(DSPBRIDGE_VERSION);
1197d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna
120518761dba1270ebb6f735d152f1fd808382705e8Víctor Manuel Jáquez Leal/*
121518761dba1270ebb6f735d152f1fd808382705e8Víctor Manuel Jáquez Leal * This function is called when an application opens handle to the
122518761dba1270ebb6f735d152f1fd808382705e8Víctor Manuel Jáquez Leal * bridge driver.
123518761dba1270ebb6f735d152f1fd808382705e8Víctor Manuel Jáquez Leal */
124518761dba1270ebb6f735d152f1fd808382705e8Víctor Manuel Jáquez Lealstatic int bridge_open(struct inode *ip, struct file *filp)
125518761dba1270ebb6f735d152f1fd808382705e8Víctor Manuel Jáquez Leal{
126518761dba1270ebb6f735d152f1fd808382705e8Víctor Manuel Jáquez Leal	int status = 0;
127518761dba1270ebb6f735d152f1fd808382705e8Víctor Manuel Jáquez Leal	struct process_context *pr_ctxt = NULL;
128518761dba1270ebb6f735d152f1fd808382705e8Víctor Manuel Jáquez Leal
129518761dba1270ebb6f735d152f1fd808382705e8Víctor Manuel Jáquez Leal	/*
130518761dba1270ebb6f735d152f1fd808382705e8Víctor Manuel Jáquez Leal	 * Allocate a new process context and insert it into global
131518761dba1270ebb6f735d152f1fd808382705e8Víctor Manuel Jáquez Leal	 * process context list.
132518761dba1270ebb6f735d152f1fd808382705e8Víctor Manuel Jáquez Leal	 */
133518761dba1270ebb6f735d152f1fd808382705e8Víctor Manuel Jáquez Leal
134518761dba1270ebb6f735d152f1fd808382705e8Víctor Manuel Jáquez Leal#ifdef CONFIG_TIDSPBRIDGE_RECOVERY
135518761dba1270ebb6f735d152f1fd808382705e8Víctor Manuel Jáquez Leal	if (recover) {
136518761dba1270ebb6f735d152f1fd808382705e8Víctor Manuel Jáquez Leal		if (filp->f_flags & O_NONBLOCK ||
1377724e8bfda8a5e7fd0a1f9819fd9b750c43e0495Víctor Manuel Jáquez Leal		    wait_for_completion_interruptible(&bridge_open_comp))
138518761dba1270ebb6f735d152f1fd808382705e8Víctor Manuel Jáquez Leal			return -EBUSY;
139518761dba1270ebb6f735d152f1fd808382705e8Víctor Manuel Jáquez Leal	}
140518761dba1270ebb6f735d152f1fd808382705e8Víctor Manuel Jáquez Leal#endif
141518761dba1270ebb6f735d152f1fd808382705e8Víctor Manuel Jáquez Leal	pr_ctxt = kzalloc(sizeof(struct process_context), GFP_KERNEL);
1422573897816e604952ee9f7dbe798094d80c1e31dOmar Ramirez Luna	if (!pr_ctxt)
1432573897816e604952ee9f7dbe798094d80c1e31dOmar Ramirez Luna		return -ENOMEM;
1442573897816e604952ee9f7dbe798094d80c1e31dOmar Ramirez Luna
1452573897816e604952ee9f7dbe798094d80c1e31dOmar Ramirez Luna	pr_ctxt->res_state = PROC_RES_ALLOCATED;
1462573897816e604952ee9f7dbe798094d80c1e31dOmar Ramirez Luna	spin_lock_init(&pr_ctxt->dmm_map_lock);
1472573897816e604952ee9f7dbe798094d80c1e31dOmar Ramirez Luna	INIT_LIST_HEAD(&pr_ctxt->dmm_map_list);
1482573897816e604952ee9f7dbe798094d80c1e31dOmar Ramirez Luna	spin_lock_init(&pr_ctxt->dmm_rsv_lock);
1492573897816e604952ee9f7dbe798094d80c1e31dOmar Ramirez Luna	INIT_LIST_HEAD(&pr_ctxt->dmm_rsv_list);
1502573897816e604952ee9f7dbe798094d80c1e31dOmar Ramirez Luna
1512573897816e604952ee9f7dbe798094d80c1e31dOmar Ramirez Luna	pr_ctxt->node_id = kzalloc(sizeof(struct idr), GFP_KERNEL);
1522573897816e604952ee9f7dbe798094d80c1e31dOmar Ramirez Luna	if (!pr_ctxt->node_id) {
153518761dba1270ebb6f735d152f1fd808382705e8Víctor Manuel Jáquez Leal		status = -ENOMEM;
1542573897816e604952ee9f7dbe798094d80c1e31dOmar Ramirez Luna		goto err1;
155518761dba1270ebb6f735d152f1fd808382705e8Víctor Manuel Jáquez Leal	}
1562573897816e604952ee9f7dbe798094d80c1e31dOmar Ramirez Luna
1572573897816e604952ee9f7dbe798094d80c1e31dOmar Ramirez Luna	idr_init(pr_ctxt->node_id);
1582573897816e604952ee9f7dbe798094d80c1e31dOmar Ramirez Luna
1592573897816e604952ee9f7dbe798094d80c1e31dOmar Ramirez Luna	pr_ctxt->stream_id = kzalloc(sizeof(struct idr), GFP_KERNEL);
1602573897816e604952ee9f7dbe798094d80c1e31dOmar Ramirez Luna	if (!pr_ctxt->stream_id) {
1612573897816e604952ee9f7dbe798094d80c1e31dOmar Ramirez Luna		status = -ENOMEM;
1622573897816e604952ee9f7dbe798094d80c1e31dOmar Ramirez Luna		goto err2;
1632573897816e604952ee9f7dbe798094d80c1e31dOmar Ramirez Luna	}
1642573897816e604952ee9f7dbe798094d80c1e31dOmar Ramirez Luna
1652573897816e604952ee9f7dbe798094d80c1e31dOmar Ramirez Luna	idr_init(pr_ctxt->stream_id);
1662573897816e604952ee9f7dbe798094d80c1e31dOmar Ramirez Luna
167518761dba1270ebb6f735d152f1fd808382705e8Víctor Manuel Jáquez Leal	filp->private_data = pr_ctxt;
1682573897816e604952ee9f7dbe798094d80c1e31dOmar Ramirez Luna
169518761dba1270ebb6f735d152f1fd808382705e8Víctor Manuel Jáquez Leal#ifdef CONFIG_TIDSPBRIDGE_RECOVERY
1702573897816e604952ee9f7dbe798094d80c1e31dOmar Ramirez Luna	atomic_inc(&bridge_cref);
171518761dba1270ebb6f735d152f1fd808382705e8Víctor Manuel Jáquez Leal#endif
1722573897816e604952ee9f7dbe798094d80c1e31dOmar Ramirez Luna	return 0;
1732573897816e604952ee9f7dbe798094d80c1e31dOmar Ramirez Luna
1742573897816e604952ee9f7dbe798094d80c1e31dOmar Ramirez Lunaerr2:
1752573897816e604952ee9f7dbe798094d80c1e31dOmar Ramirez Luna	kfree(pr_ctxt->node_id);
1762573897816e604952ee9f7dbe798094d80c1e31dOmar Ramirez Lunaerr1:
1772573897816e604952ee9f7dbe798094d80c1e31dOmar Ramirez Luna	kfree(pr_ctxt);
178518761dba1270ebb6f735d152f1fd808382705e8Víctor Manuel Jáquez Leal	return status;
179518761dba1270ebb6f735d152f1fd808382705e8Víctor Manuel Jáquez Leal}
180518761dba1270ebb6f735d152f1fd808382705e8Víctor Manuel Jáquez Leal
181518761dba1270ebb6f735d152f1fd808382705e8Víctor Manuel Jáquez Leal/*
182518761dba1270ebb6f735d152f1fd808382705e8Víctor Manuel Jáquez Leal * This function is called when an application closes handle to the bridge
183518761dba1270ebb6f735d152f1fd808382705e8Víctor Manuel Jáquez Leal * driver.
184518761dba1270ebb6f735d152f1fd808382705e8Víctor Manuel Jáquez Leal */
185518761dba1270ebb6f735d152f1fd808382705e8Víctor Manuel Jáquez Lealstatic int bridge_release(struct inode *ip, struct file *filp)
186518761dba1270ebb6f735d152f1fd808382705e8Víctor Manuel Jáquez Leal{
187518761dba1270ebb6f735d152f1fd808382705e8Víctor Manuel Jáquez Leal	int status = 0;
188518761dba1270ebb6f735d152f1fd808382705e8Víctor Manuel Jáquez Leal	struct process_context *pr_ctxt;
189518761dba1270ebb6f735d152f1fd808382705e8Víctor Manuel Jáquez Leal
190518761dba1270ebb6f735d152f1fd808382705e8Víctor Manuel Jáquez Leal	if (!filp->private_data) {
191518761dba1270ebb6f735d152f1fd808382705e8Víctor Manuel Jáquez Leal		status = -EIO;
192518761dba1270ebb6f735d152f1fd808382705e8Víctor Manuel Jáquez Leal		goto err;
193518761dba1270ebb6f735d152f1fd808382705e8Víctor Manuel Jáquez Leal	}
194518761dba1270ebb6f735d152f1fd808382705e8Víctor Manuel Jáquez Leal
195518761dba1270ebb6f735d152f1fd808382705e8Víctor Manuel Jáquez Leal	pr_ctxt = filp->private_data;
196518761dba1270ebb6f735d152f1fd808382705e8Víctor Manuel Jáquez Leal	flush_signals(current);
197518761dba1270ebb6f735d152f1fd808382705e8Víctor Manuel Jáquez Leal	drv_remove_all_resources(pr_ctxt);
198518761dba1270ebb6f735d152f1fd808382705e8Víctor Manuel Jáquez Leal	proc_detach(pr_ctxt);
1992573897816e604952ee9f7dbe798094d80c1e31dOmar Ramirez Luna	kfree(pr_ctxt->node_id);
2002573897816e604952ee9f7dbe798094d80c1e31dOmar Ramirez Luna	kfree(pr_ctxt->stream_id);
201518761dba1270ebb6f735d152f1fd808382705e8Víctor Manuel Jáquez Leal	kfree(pr_ctxt);
202518761dba1270ebb6f735d152f1fd808382705e8Víctor Manuel Jáquez Leal
203518761dba1270ebb6f735d152f1fd808382705e8Víctor Manuel Jáquez Leal	filp->private_data = NULL;
204518761dba1270ebb6f735d152f1fd808382705e8Víctor Manuel Jáquez Leal
205518761dba1270ebb6f735d152f1fd808382705e8Víctor Manuel Jáquez Lealerr:
206518761dba1270ebb6f735d152f1fd808382705e8Víctor Manuel Jáquez Leal#ifdef CONFIG_TIDSPBRIDGE_RECOVERY
207518761dba1270ebb6f735d152f1fd808382705e8Víctor Manuel Jáquez Leal	if (!atomic_dec_return(&bridge_cref))
208518761dba1270ebb6f735d152f1fd808382705e8Víctor Manuel Jáquez Leal		complete(&bridge_comp);
209518761dba1270ebb6f735d152f1fd808382705e8Víctor Manuel Jáquez Leal#endif
210518761dba1270ebb6f735d152f1fd808382705e8Víctor Manuel Jáquez Leal	return status;
211518761dba1270ebb6f735d152f1fd808382705e8Víctor Manuel Jáquez Leal}
212518761dba1270ebb6f735d152f1fd808382705e8Víctor Manuel Jáquez Leal
213518761dba1270ebb6f735d152f1fd808382705e8Víctor Manuel Jáquez Leal/* This function provides IO interface to the bridge driver. */
214518761dba1270ebb6f735d152f1fd808382705e8Víctor Manuel Jáquez Lealstatic long bridge_ioctl(struct file *filp, unsigned int code,
215518761dba1270ebb6f735d152f1fd808382705e8Víctor Manuel Jáquez Leal			 unsigned long args)
216518761dba1270ebb6f735d152f1fd808382705e8Víctor Manuel Jáquez Leal{
217518761dba1270ebb6f735d152f1fd808382705e8Víctor Manuel Jáquez Leal	int status;
218518761dba1270ebb6f735d152f1fd808382705e8Víctor Manuel Jáquez Leal	u32 retval = 0;
219518761dba1270ebb6f735d152f1fd808382705e8Víctor Manuel Jáquez Leal	union trapped_args buf_in;
220518761dba1270ebb6f735d152f1fd808382705e8Víctor Manuel Jáquez Leal
221518761dba1270ebb6f735d152f1fd808382705e8Víctor Manuel Jáquez Leal#ifdef CONFIG_TIDSPBRIDGE_RECOVERY
222518761dba1270ebb6f735d152f1fd808382705e8Víctor Manuel Jáquez Leal	if (recover) {
223518761dba1270ebb6f735d152f1fd808382705e8Víctor Manuel Jáquez Leal		status = -EIO;
224518761dba1270ebb6f735d152f1fd808382705e8Víctor Manuel Jáquez Leal		goto err;
225518761dba1270ebb6f735d152f1fd808382705e8Víctor Manuel Jáquez Leal	}
226518761dba1270ebb6f735d152f1fd808382705e8Víctor Manuel Jáquez Leal#endif
227518761dba1270ebb6f735d152f1fd808382705e8Víctor Manuel Jáquez Leal#ifdef CONFIG_PM
228518761dba1270ebb6f735d152f1fd808382705e8Víctor Manuel Jáquez Leal	status = omap34_xxbridge_suspend_lockout(&bridge_suspend_data, filp);
229518761dba1270ebb6f735d152f1fd808382705e8Víctor Manuel Jáquez Leal	if (status != 0)
230518761dba1270ebb6f735d152f1fd808382705e8Víctor Manuel Jáquez Leal		return status;
231518761dba1270ebb6f735d152f1fd808382705e8Víctor Manuel Jáquez Leal#endif
232518761dba1270ebb6f735d152f1fd808382705e8Víctor Manuel Jáquez Leal
233518761dba1270ebb6f735d152f1fd808382705e8Víctor Manuel Jáquez Leal	if (!filp->private_data) {
234518761dba1270ebb6f735d152f1fd808382705e8Víctor Manuel Jáquez Leal		status = -EIO;
235518761dba1270ebb6f735d152f1fd808382705e8Víctor Manuel Jáquez Leal		goto err;
236518761dba1270ebb6f735d152f1fd808382705e8Víctor Manuel Jáquez Leal	}
237518761dba1270ebb6f735d152f1fd808382705e8Víctor Manuel Jáquez Leal
238518761dba1270ebb6f735d152f1fd808382705e8Víctor Manuel Jáquez Leal	status = copy_from_user(&buf_in, (union trapped_args *)args,
239518761dba1270ebb6f735d152f1fd808382705e8Víctor Manuel Jáquez Leal				sizeof(union trapped_args));
240518761dba1270ebb6f735d152f1fd808382705e8Víctor Manuel Jáquez Leal
241518761dba1270ebb6f735d152f1fd808382705e8Víctor Manuel Jáquez Leal	if (!status) {
242518761dba1270ebb6f735d152f1fd808382705e8Víctor Manuel Jáquez Leal		status = api_call_dev_ioctl(code, &buf_in, &retval,
2437724e8bfda8a5e7fd0a1f9819fd9b750c43e0495Víctor Manuel Jáquez Leal					    filp->private_data);
244518761dba1270ebb6f735d152f1fd808382705e8Víctor Manuel Jáquez Leal
245518761dba1270ebb6f735d152f1fd808382705e8Víctor Manuel Jáquez Leal		if (!status) {
246518761dba1270ebb6f735d152f1fd808382705e8Víctor Manuel Jáquez Leal			status = retval;
247518761dba1270ebb6f735d152f1fd808382705e8Víctor Manuel Jáquez Leal		} else {
248518761dba1270ebb6f735d152f1fd808382705e8Víctor Manuel Jáquez Leal			dev_dbg(bridge, "%s: IOCTL Failed, code: 0x%x "
249518761dba1270ebb6f735d152f1fd808382705e8Víctor Manuel Jáquez Leal				"status 0x%x\n", __func__, code, status);
250518761dba1270ebb6f735d152f1fd808382705e8Víctor Manuel Jáquez Leal			status = -1;
251518761dba1270ebb6f735d152f1fd808382705e8Víctor Manuel Jáquez Leal		}
252518761dba1270ebb6f735d152f1fd808382705e8Víctor Manuel Jáquez Leal
253518761dba1270ebb6f735d152f1fd808382705e8Víctor Manuel Jáquez Leal	}
254518761dba1270ebb6f735d152f1fd808382705e8Víctor Manuel Jáquez Leal
255518761dba1270ebb6f735d152f1fd808382705e8Víctor Manuel Jáquez Lealerr:
256518761dba1270ebb6f735d152f1fd808382705e8Víctor Manuel Jáquez Leal	return status;
257518761dba1270ebb6f735d152f1fd808382705e8Víctor Manuel Jáquez Leal}
258518761dba1270ebb6f735d152f1fd808382705e8Víctor Manuel Jáquez Leal
259518761dba1270ebb6f735d152f1fd808382705e8Víctor Manuel Jáquez Leal/* This function maps kernel space memory to user space memory. */
260518761dba1270ebb6f735d152f1fd808382705e8Víctor Manuel Jáquez Lealstatic int bridge_mmap(struct file *filp, struct vm_area_struct *vma)
261518761dba1270ebb6f735d152f1fd808382705e8Víctor Manuel Jáquez Leal{
262518761dba1270ebb6f735d152f1fd808382705e8Víctor Manuel Jáquez Leal	u32 status;
263518761dba1270ebb6f735d152f1fd808382705e8Víctor Manuel Jáquez Leal
264518761dba1270ebb6f735d152f1fd808382705e8Víctor Manuel Jáquez Leal	vma->vm_flags |= VM_RESERVED | VM_IO;
265518761dba1270ebb6f735d152f1fd808382705e8Víctor Manuel Jáquez Leal	vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
266518761dba1270ebb6f735d152f1fd808382705e8Víctor Manuel Jáquez Leal
2674f8aae5375e429b003a72a37d8ece6e1b99e486eVíctor Manuel Jáquez Leal	dev_dbg(bridge, "%s: vm filp %p start %lx end %lx page_prot %ulx "
2684f8aae5375e429b003a72a37d8ece6e1b99e486eVíctor Manuel Jáquez Leal		"flags %lx\n", __func__, filp,
2699fdf6550613d1b7ac251a1e254829a4b9636c380Víctor Manuel Jáquez Leal		vma->vm_start, vma->vm_end, vma->vm_page_prot,
2709fdf6550613d1b7ac251a1e254829a4b9636c380Víctor Manuel Jáquez Leal		vma->vm_flags);
271518761dba1270ebb6f735d152f1fd808382705e8Víctor Manuel Jáquez Leal
272518761dba1270ebb6f735d152f1fd808382705e8Víctor Manuel Jáquez Leal	status = remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff,
273518761dba1270ebb6f735d152f1fd808382705e8Víctor Manuel Jáquez Leal				 vma->vm_end - vma->vm_start,
274518761dba1270ebb6f735d152f1fd808382705e8Víctor Manuel Jáquez Leal				 vma->vm_page_prot);
275518761dba1270ebb6f735d152f1fd808382705e8Víctor Manuel Jáquez Leal	if (status != 0)
276518761dba1270ebb6f735d152f1fd808382705e8Víctor Manuel Jáquez Leal		status = -EAGAIN;
277518761dba1270ebb6f735d152f1fd808382705e8Víctor Manuel Jáquez Leal
278518761dba1270ebb6f735d152f1fd808382705e8Víctor Manuel Jáquez Leal	return status;
279518761dba1270ebb6f735d152f1fd808382705e8Víctor Manuel Jáquez Leal}
2807d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna
2817d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Lunastatic const struct file_operations bridge_fops = {
2827d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna	.open = bridge_open,
2837d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna	.release = bridge_release,
2847d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna	.unlocked_ioctl = bridge_ioctl,
2857d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna	.mmap = bridge_mmap,
2866038f373a3dc1f1c26496e60b6c40b164716f07eArnd Bergmann	.llseek = noop_llseek,
2877d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna};
2887d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna
2897d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna#ifdef CONFIG_PM
2907d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Lunastatic u32 time_out = 1000;
291b3d23688a15c4c332942f9428e0d708e7362e29eFelipe Contreras#ifdef CONFIG_TIDSPBRIDGE_DVFS
2927d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Lunas32 dsp_max_opps = VDD1_OPP5;
2937d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna#endif
2947d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna
2957d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna/* Maximum Opps that can be requested by IVA */
2967d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna/*vdd1 rate table */
297b3d23688a15c4c332942f9428e0d708e7362e29eFelipe Contreras#ifdef CONFIG_TIDSPBRIDGE_DVFS
2987d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Lunaconst struct omap_opp vdd1_rate_table_bridge[] = {
2997d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna	{0, 0, 0},
3007d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna	/*OPP1 */
3017d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna	{S125M, VDD1_OPP1, 0},
3027d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna	/*OPP2 */
3037d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna	{S250M, VDD1_OPP2, 0},
3047d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna	/*OPP3 */
3057d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna	{S500M, VDD1_OPP3, 0},
3067d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna	/*OPP4 */
3077d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna	{S550M, VDD1_OPP4, 0},
3087d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna	/*OPP5 */
3097d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna	{S600M, VDD1_OPP5, 0},
3107d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna};
3117d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna#endif
3127d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna#endif
3137d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna
31482d4b4776d575223c14b25546e0336541ef8ba94Felipe Contrerasstruct omap_dsp_platform_data *omap_dspbridge_pdata;
3157d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna
3167d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Lunau32 vdd1_dsp_freq[6][4] = {
3177d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna	{0, 0, 0, 0},
3187d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna	/*OPP1 */
3197d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna	{0, 90000, 0, 86000},
3207d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna	/*OPP2 */
3217d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna	{0, 180000, 80000, 170000},
3227d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna	/*OPP3 */
3237d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna	{0, 360000, 160000, 340000},
3247d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna	/*OPP4 */
3257d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna	{0, 396000, 325000, 376000},
3267d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna	/*OPP5 */
3277d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna	{0, 430000, 355000, 430000},
3287d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna};
3297d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna
330b3d23688a15c4c332942f9428e0d708e7362e29eFelipe Contreras#ifdef CONFIG_TIDSPBRIDGE_RECOVERY
3317d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Lunastatic void bridge_recover(struct work_struct *work)
3327d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna{
3337d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna	struct dev_object *dev;
3347d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna	struct cfg_devnode *dev_node;
3357d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna	if (atomic_read(&bridge_cref)) {
3367d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna		INIT_COMPLETION(bridge_comp);
3377d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna		while (!wait_for_completion_timeout(&bridge_comp,
3387d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna						msecs_to_jiffies(REC_TIMEOUT)))
3397d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna			pr_info("%s:%d handle(s) still opened\n",
3407d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna					__func__, atomic_read(&bridge_cref));
3417d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna	}
3427d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna	dev = dev_get_first();
3437d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna	dev_get_dev_node(dev, &dev_node);
344b66e0986f900db194f637149e68c00345863195bErnesto Ramos	if (!dev_node || proc_auto_start(dev_node, dev))
3457d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna		pr_err("DSP could not be restarted\n");
3467d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna	recover = false;
3477d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna	complete_all(&bridge_open_comp);
3487d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna}
3497d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna
3507d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Lunavoid bridge_recover_schedule(void)
3517d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna{
3527d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna	INIT_COMPLETION(bridge_open_comp);
3537d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna	recover = true;
3547d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna	queue_work(bridge_rec_queue, &bridge_recovery_work);
3557d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna}
3567d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna#endif
357b3d23688a15c4c332942f9428e0d708e7362e29eFelipe Contreras#ifdef CONFIG_TIDSPBRIDGE_DVFS
3587d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Lunastatic int dspbridge_scale_notification(struct notifier_block *op,
3597724e8bfda8a5e7fd0a1f9819fd9b750c43e0495Víctor Manuel Jáquez Leal					unsigned long val, void *ptr)
3607d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna{
36182d4b4776d575223c14b25546e0336541ef8ba94Felipe Contreras	struct omap_dsp_platform_data *pdata =
3627724e8bfda8a5e7fd0a1f9819fd9b750c43e0495Víctor Manuel Jáquez Leal	    omap_dspbridge_dev->dev.platform_data;
3637d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna
3647d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna	if (CPUFREQ_POSTCHANGE == val && pdata->dsp_get_opp)
3657d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna		pwr_pm_post_scale(PRCM_VDD1, pdata->dsp_get_opp());
3667d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna
3677d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna	return 0;
3687d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna}
3697d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna
3707d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Lunastatic struct notifier_block iva_clk_notifier = {
3717d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna	.notifier_call = dspbridge_scale_notification,
3727d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna	NULL,
3737d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna};
3747d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna#endif
3757d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna
3767d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna/**
3777d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna * omap3_bridge_startup() - perform low lever initializations
3787d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna * @pdev:      pointer to platform device
3797d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna *
3807d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna * Initializes recovery, PM and DVFS required data, before calling
3817d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna * clk and memory init routines.
3827d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna */
3837d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Lunastatic int omap3_bridge_startup(struct platform_device *pdev)
3847d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna{
38582d4b4776d575223c14b25546e0336541ef8ba94Felipe Contreras	struct omap_dsp_platform_data *pdata = pdev->dev.platform_data;
3867d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna	struct drv_data *drv_datap = NULL;
3877d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna	u32 phys_membase, phys_memsize;
3887d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna	int err;
3897d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna
390b3d23688a15c4c332942f9428e0d708e7362e29eFelipe Contreras#ifdef CONFIG_TIDSPBRIDGE_RECOVERY
3917d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna	bridge_rec_queue = create_workqueue("bridge_rec_queue");
3927d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna	INIT_WORK(&bridge_recovery_work, bridge_recover);
3937d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna	INIT_COMPLETION(bridge_comp);
3947d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna#endif
3957d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna
3967d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna#ifdef CONFIG_PM
3977d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna	/* Initialize the wait queue */
3987d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna	bridge_suspend_data.suspended = 0;
3997d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna	init_waitqueue_head(&bridge_suspend_data.suspend_wq);
4007d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna
401b3d23688a15c4c332942f9428e0d708e7362e29eFelipe Contreras#ifdef CONFIG_TIDSPBRIDGE_DVFS
4027d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna	for (i = 0; i < 6; i++)
4037d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna		pdata->mpu_speed[i] = vdd1_rate_table_bridge[i].rate;
4047d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna
4057d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna	err = cpufreq_register_notifier(&iva_clk_notifier,
4067d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna					CPUFREQ_TRANSITION_NOTIFIER);
4077d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna	if (err)
4087d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna		pr_err("%s: clk_notifier_register failed for iva2_ck\n",
4097d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna								__func__);
4107d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna#endif
4117d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna#endif
4127d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna
4137d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna	dsp_clk_init();
4147d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna
4157d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna	drv_datap = kzalloc(sizeof(struct drv_data), GFP_KERNEL);
4167d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna	if (!drv_datap) {
4177d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna		err = -ENOMEM;
4187d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna		goto err1;
4197d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna	}
4207d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna
4217d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna	drv_datap->shm_size = shm_size;
4227d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna	drv_datap->tc_wordswapon = tc_wordswapon;
4237d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna
4247d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna	if (base_img) {
4257d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna		drv_datap->base_img = kmalloc(strlen(base_img) + 1, GFP_KERNEL);
4267d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna		if (!drv_datap->base_img) {
4277d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna			err = -ENOMEM;
4287d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna			goto err2;
4297d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna		}
4307d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna		strncpy(drv_datap->base_img, base_img, strlen(base_img) + 1);
4317d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna	}
4327d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna
4337d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna	dev_set_drvdata(bridge, drv_datap);
4347d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna
4357d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna	if (shm_size < 0x10000) {	/* 64 KB */
4367d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna		err = -EINVAL;
4377d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna		pr_err("%s: shm size must be at least 64 KB\n", __func__);
4387d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna		goto err3;
4397d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna	}
4407d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna	dev_dbg(bridge, "%s: requested shm_size = 0x%x\n", __func__, shm_size);
4417d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna
4427d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna	phys_membase = pdata->phys_mempool_base;
4437d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna	phys_memsize = pdata->phys_mempool_size;
4447d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna	if (phys_membase > 0 && phys_memsize > 0)
4457d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna		mem_ext_phys_pool_init(phys_membase, phys_memsize);
4467d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna
4477d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna	if (tc_wordswapon)
4487d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna		dev_dbg(bridge, "%s: TC Word Swap is enabled\n", __func__);
4497d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna
4507d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna	driver_context = dsp_init(&err);
4517d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna	if (err) {
4527d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna		pr_err("DSP Bridge driver initialization failed\n");
4537d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna		goto err4;
4547d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna	}
4557d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna
4567d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna	return 0;
4577d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna
4587d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Lunaerr4:
4597d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna	mem_ext_phys_pool_release();
4607d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Lunaerr3:
4617d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna	kfree(drv_datap->base_img);
4627d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Lunaerr2:
4637d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna	kfree(drv_datap);
4647d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Lunaerr1:
465b3d23688a15c4c332942f9428e0d708e7362e29eFelipe Contreras#ifdef CONFIG_TIDSPBRIDGE_DVFS
4667d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna	cpufreq_unregister_notifier(&iva_clk_notifier,
4677724e8bfda8a5e7fd0a1f9819fd9b750c43e0495Víctor Manuel Jáquez Leal				    CPUFREQ_TRANSITION_NOTIFIER);
4687d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna#endif
4697d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna	dsp_clk_exit();
4707d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna
4717d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna	return err;
4727d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna}
4737d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna
4747d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Lunastatic int __devinit omap34_xx_bridge_probe(struct platform_device *pdev)
4757d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna{
4767d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna	int err;
4777d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna	dev_t dev = 0;
478b3d23688a15c4c332942f9428e0d708e7362e29eFelipe Contreras#ifdef CONFIG_TIDSPBRIDGE_DVFS
4797d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna	int i = 0;
4807d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna#endif
4817d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna
4827d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna	omap_dspbridge_dev = pdev;
4837d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna
4847d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna	/* Global bridge device */
4857d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna	bridge = &omap_dspbridge_dev->dev;
4867d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna
4877d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna	/* Bridge low level initializations */
4887d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna	err = omap3_bridge_startup(pdev);
4897d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna	if (err)
4907d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna		goto err1;
4917d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna
4927d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna	/* use 2.6 device model */
4933bdb54fc548316196f752010a44dd221a220f53bVíctor Manuel Jáquez Leal	err = alloc_chrdev_region(&dev, 0, 1, "DspBridge");
4947d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna	if (err) {
4957d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna		pr_err("%s: Can't get major %d\n", __func__, driver_major);
4967d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna		goto err1;
4977d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna	}
4987d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna
4997d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna	cdev_init(&bridge_cdev, &bridge_fops);
5007d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna	bridge_cdev.owner = THIS_MODULE;
5017d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna
5027d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna	err = cdev_add(&bridge_cdev, dev, 1);
5037d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna	if (err) {
5047d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna		pr_err("%s: Failed to add bridge device\n", __func__);
5057d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna		goto err2;
5067d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna	}
5077d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna
5087d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna	/* udev support */
5097d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna	bridge_class = class_create(THIS_MODULE, "ti_bridge");
5107d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna	if (IS_ERR(bridge_class)) {
5117d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna		pr_err("%s: Error creating bridge class\n", __func__);
5127d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna		goto err3;
5137d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna	}
5147d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna
5157d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna	driver_major = MAJOR(dev);
5167d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna	device_create(bridge_class, NULL, MKDEV(driver_major, 0),
5177d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna		      NULL, "DspBridge");
5187d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna	pr_info("DSP Bridge driver loaded\n");
5197d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna
5207d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna	return 0;
5217d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna
5227d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Lunaerr3:
5237d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna	cdev_del(&bridge_cdev);
5247d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Lunaerr2:
5257d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna	unregister_chrdev_region(dev, 1);
5267d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Lunaerr1:
5277d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna	return err;
5287d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna}
5297d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna
5307d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Lunastatic int __devexit omap34_xx_bridge_remove(struct platform_device *pdev)
5317d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna{
5327d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna	dev_t devno;
5337d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna	int status = 0;
53473b87a916697999bfafd4c43956ba98a2905ecfeIvan Gomez Castellanos	struct drv_data *drv_datap = dev_get_drvdata(bridge);
5357d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna
53673b87a916697999bfafd4c43956ba98a2905ecfeIvan Gomez Castellanos	/* Retrieve the Object handle from the driver data */
53773b87a916697999bfafd4c43956ba98a2905ecfeIvan Gomez Castellanos	if (!drv_datap || !drv_datap->drv_object) {
53873b87a916697999bfafd4c43956ba98a2905ecfeIvan Gomez Castellanos		status = -ENODATA;
53973b87a916697999bfafd4c43956ba98a2905ecfeIvan Gomez Castellanos		pr_err("%s: Failed to retrieve the object handle\n", __func__);
5407d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna		goto func_cont;
54173b87a916697999bfafd4c43956ba98a2905ecfeIvan Gomez Castellanos	}
5427d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna
543b3d23688a15c4c332942f9428e0d708e7362e29eFelipe Contreras#ifdef CONFIG_TIDSPBRIDGE_DVFS
5447d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna	if (cpufreq_unregister_notifier(&iva_clk_notifier,
5457724e8bfda8a5e7fd0a1f9819fd9b750c43e0495Víctor Manuel Jáquez Leal					CPUFREQ_TRANSITION_NOTIFIER))
5467d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna		pr_err("%s: cpufreq_unregister_notifier failed for iva2_ck\n",
5477d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna		       __func__);
548b3d23688a15c4c332942f9428e0d708e7362e29eFelipe Contreras#endif /* #ifdef CONFIG_TIDSPBRIDGE_DVFS */
5497d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna
5507d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna	if (driver_context) {
5517d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna		/* Put the DSP in reset state */
552b8bfa4c57c003e85aefbc5aef14f1704ef37b403Víctor Manuel Jáquez Leal		dsp_deinit(driver_context);
5537d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna		driver_context = 0;
5547d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna	}
5557d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna
55644c5435064b5e6182167b40a7f259969dbcaf1b8Omar Ramirez Luna	kfree(drv_datap);
55744c5435064b5e6182167b40a7f259969dbcaf1b8Omar Ramirez Luna	dev_set_drvdata(bridge, NULL);
55844c5435064b5e6182167b40a7f259969dbcaf1b8Omar Ramirez Luna
5597d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Lunafunc_cont:
5607d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna	mem_ext_phys_pool_release();
5617d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna
5627d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna	dsp_clk_exit();
5637d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna
5647d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna	devno = MKDEV(driver_major, 0);
5657d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna	cdev_del(&bridge_cdev);
5667d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna	unregister_chrdev_region(devno, 1);
5677d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna	if (bridge_class) {
5687d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna		/* remove the device from sysfs */
5697d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna		device_destroy(bridge_class, MKDEV(driver_major, 0));
5707d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna		class_destroy(bridge_class);
5717d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna
5727d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna	}
5737d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna	return 0;
5747d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna}
5757d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna
5767d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna#ifdef CONFIG_PM
5774f1ef76165306577ad0cb708ea90fc19d311e7beVíctor Manuel Jáquez Lealstatic int bridge_suspend(struct platform_device *pdev, pm_message_t state)
5787d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna{
5797d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna	u32 status;
5807d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna	u32 command = PWR_EMERGENCYDEEPSLEEP;
5817d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna
5827d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna	status = pwr_sleep_dsp(command, time_out);
583b66e0986f900db194f637149e68c00345863195bErnesto Ramos	if (status)
5847d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna		return -1;
5857d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna
5867d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna	bridge_suspend_data.suspended = 1;
5877d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna	return 0;
5887d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna}
5897d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna
5904f1ef76165306577ad0cb708ea90fc19d311e7beVíctor Manuel Jáquez Lealstatic int bridge_resume(struct platform_device *pdev)
5917d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna{
5927d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna	u32 status;
5937d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna
5947d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna	status = pwr_wake_dsp(time_out);
595b66e0986f900db194f637149e68c00345863195bErnesto Ramos	if (status)
5967d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna		return -1;
5977d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna
5987d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna	bridge_suspend_data.suspended = 0;
5997d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna	wake_up(&bridge_suspend_data.suspend_wq);
6007d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna	return 0;
6017d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna}
6027d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna#endif
6037d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna
6047d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Lunastatic struct platform_driver bridge_driver = {
6057d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna	.driver = {
60695624b2d75617bd16ffe4d698b645f468fbd0f20Omar Ramirez Luna		   .name = "omap-dsp",
6077d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna		   },
6087d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna	.probe = omap34_xx_bridge_probe,
6097d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna	.remove = __devexit_p(omap34_xx_bridge_remove),
6104f1ef76165306577ad0cb708ea90fc19d311e7beVíctor Manuel Jáquez Leal#ifdef CONFIG_PM
6114f1ef76165306577ad0cb708ea90fc19d311e7beVíctor Manuel Jáquez Leal	.suspend = bridge_suspend,
6124f1ef76165306577ad0cb708ea90fc19d311e7beVíctor Manuel Jáquez Leal	.resume = bridge_resume,
6134f1ef76165306577ad0cb708ea90fc19d311e7beVíctor Manuel Jáquez Leal#endif
6147d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna};
6157d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna
6167d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Lunastatic int __init bridge_init(void)
6177d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna{
6187d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna	return platform_driver_register(&bridge_driver);
6197d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna}
6207d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna
6217d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Lunastatic void __exit bridge_exit(void)
6227d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna{
6237d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna	platform_driver_unregister(&bridge_driver);
6247d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna}
6257d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna
6267d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna/* To remove all process resources before removing the process from the
6277d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna * process context list */
628e68906924d742dfb33564d7eb4ea7db0b4e65ae4Rene Sapiensint drv_remove_all_resources(void *process_ctxt)
6297d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna{
6307d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna	int status = 0;
631e68906924d742dfb33564d7eb4ea7db0b4e65ae4Rene Sapiens	struct process_context *ctxt = (struct process_context *)process_ctxt;
6327d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna	drv_remove_all_strm_res_elements(ctxt);
6337d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna	drv_remove_all_node_res_elements(ctxt);
6347d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna	drv_remove_all_dmm_res_elements(ctxt);
6357d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna	ctxt->res_state = PROC_RES_FREED;
6367d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna	return status;
6377d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna}
6387d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna
6397d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Luna/* Bridge driver initialization and de-initialization functions */
6407d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Lunamodule_init(bridge_init);
6417d55524d3039e3e70756ee0a45f2fe59b7ed3fd2Omar Ramirez Lunamodule_exit(bridge_exit);
642