2525#include <linux/notifier.h>
2626#include <linux/hsi_driver_if.h>
2727
28- #include <asm/clkdev.h>
29-
3028#include <plat/omap_hsi.h>
3129#include <plat/omap_hwmod.h>
3230#include <plat/omap_device.h>
3533#include "clock.h"
3634#include "mux.h"
3735#include "control.h"
36+ #include "pm.h"
3837
3938static int omap_hsi_wakeup_enable (int hsi_port );
4039static int omap_hsi_wakeup_disable (int hsi_port );
4140#define OMAP_HSI_PLATFORM_DEVICE_DRIVER_NAME "omap_hsi"
4241#define OMAP_HSI_PLATFORM_DEVICE_NAME "omap_hsi.0"
4342#define OMAP_HSI_HWMOD_NAME "hsi"
4443#define OMAP_HSI_HWMOD_CLASSNAME "hsi"
45- #define OMAP_HSI_PADCONF_CAWAKE_PIN "usbb1_ulpitll_clk.hsi1_cawake"
46- #define OMAP_HSI_PADCONF_CAWAKE_MODE OMAP_MUX_MODE1
4744
4845
4946#define OMAP_MUX_MODE_MASK 0x7
@@ -85,8 +82,9 @@ static int omap_mux_disable_wakeup(const char *muxname)
8582 */
8683
8784
88- static struct port_ctx hsi_port_ctx [] = {
85+ static struct hsi_port_ctx omap_hsi_port_ctx [] = {
8986 [0 ] = {
87+ .port_number = 1 ,
9088 .hst .mode = HSI_MODE_FRAME ,
9189 .hst .flow = HSI_FLOW_SYNCHRONIZED ,
9290 .hst .frame_size = HSI_FRAMESIZE_DEFAULT ,
@@ -101,21 +99,23 @@ static struct port_ctx hsi_port_ctx[] = {
10199 .hsr .counters = HSI_COUNTERS_FT_DEFAULT |
102100 HSI_COUNTERS_TB_DEFAULT |
103101 HSI_COUNTERS_FB_DEFAULT ,
102+ .cawake_padconf_name = "usbb1_ulpitll_clk.hsi1_cawake" ,
103+ .cawake_padconf_hsi_mode = OMAP_MUX_MODE1 ,
104104 },
105105};
106106
107- static struct ctrl_ctx hsi_ctx = {
107+ static struct hsi_ctrl_ctx omap_hsi_ctrl_ctx = {
108108 .sysconfig = 0 ,
109109 .gdd_gcr = 0 ,
110110 .dll = 0 ,
111- .pctx = hsi_port_ctx ,
111+ .pctx = omap_hsi_port_ctx ,
112112};
113113
114114static struct hsi_platform_data omap_hsi_platform_data = {
115- .num_ports = ARRAY_SIZE (hsi_port_ctx ),
115+ .num_ports = ARRAY_SIZE (omap_hsi_port_ctx ),
116116 .hsi_gdd_chan_count = HSI_HSI_DMA_CHANNEL_MAX ,
117117 .default_hsi_fclk = HSI_DEFAULT_FCLK ,
118- .ctx = & hsi_ctx ,
118+ .ctx = & omap_hsi_ctrl_ctx ,
119119 .device_enable = omap_device_enable ,
120120 .device_idle = omap_device_idle ,
121121 .device_shutdown = omap_device_shutdown ,
@@ -166,24 +166,50 @@ static struct hsi_dev *hsi_get_hsi_controller_data(struct platform_device *pd)
166166 return hsi_ctrl ;
167167}
168168
169+ /**
170+ * hsi_get_hsi_port_ctx_data - Returns a pointer on the port context
171+ *
172+ * @hsi_port - port number to obtain context. Range [1, 2]
173+ *
174+ * Return value :* If success: pointer on the HSI port context requested
175+ * * else NULL
176+ */
177+ static struct hsi_port_ctx * hsi_get_hsi_port_ctx_data (int hsi_port )
178+ {
179+ int i ;
180+
181+ for (i = 0 ; i < omap_hsi_platform_data .num_ports ; i ++ )
182+ if (omap_hsi_platform_data .ctx -> pctx [i ].port_number == hsi_port )
183+ return & omap_hsi_platform_data .ctx -> pctx [i ];
184+
185+ return NULL ;
186+ }
187+
169188/**
170189* omap_hsi_is_io_pad_hsi - Indicates if IO Pad has been muxed for HSI CAWAKE
171190*
191+ * @hsi_port - port number to check for HSI muxing. Range [1, 2]
192+ *
172193* Return value :* 0 if CAWAKE Padconf has not been found or CAWAKE not muxed for
173194* CAWAKE
174195* * else 1
175196*/
176- static int omap_hsi_is_io_pad_hsi (void )
197+ static int omap_hsi_is_io_pad_hsi (int hsi_port )
177198{
199+ struct hsi_port_ctx * port_ctx ;
178200 u16 val ;
179201
202+ port_ctx = hsi_get_hsi_port_ctx_data (hsi_port );
203+ if (!port_ctx )
204+ return 0 ;
205+
180206 /* Check for IO pad */
181- val = omap_mux_read_signal (OMAP_HSI_PADCONF_CAWAKE_PIN );
207+ val = omap_mux_read_signal (port_ctx -> cawake_padconf_name );
182208 if (val == - ENODEV )
183209 return 0 ;
184210
185211 /* Continue only if CAWAKE is muxed */
186- if ((val & OMAP_MUX_MODE_MASK ) != OMAP_HSI_PADCONF_CAWAKE_MODE )
212+ if ((val & OMAP_MUX_MODE_MASK ) != port_ctx -> cawake_padconf_hsi_mode )
187213 return 0 ;
188214
189215 return 1 ;
@@ -192,26 +218,39 @@ static int omap_hsi_is_io_pad_hsi(void)
192218/**
193219* omap_hsi_is_io_wakeup_from_hsi - Indicates an IO wakeup from HSI CAWAKE
194220*
221+ * @hsi_port - returns port number which triggered wakeup. Range [1, 2].
222+ * Only valid if return value is 1 (HSI wakeup detected)
223+ *
195224* Return value :* 0 if CAWAKE Padconf has not been found or no IOWAKEUP event
196- * occured for CAWAKE
197- * * else 1
198- * TODO : return value should indicate the HSI port which has awaken
225+ * occured for CAWAKE.
226+ * * 1 if HSI wakeup detected on port *hsi_port
199227*/
200- int omap_hsi_is_io_wakeup_from_hsi (void )
228+ int omap_hsi_is_io_wakeup_from_hsi (int * hsi_port )
201229{
230+ struct hsi_port_ctx * port_ctx ;
202231 u16 val ;
232+ int i ;
233+
234+ for (i = 0 ; i < omap_hsi_platform_data .num_ports ; i ++ ) {
235+ port_ctx = & omap_hsi_platform_data .ctx -> pctx [i ];
203236
204237 /* Check for IO pad wakeup */
205- val = omap_mux_read_signal (OMAP_HSI_PADCONF_CAWAKE_PIN );
238+ val = omap_mux_read_signal (port_ctx -> cawake_padconf_name );
206239 if (val == - ENODEV )
207- return 0 ;
240+ continue ;
208241
209242 /* Continue only if CAWAKE is muxed */
210- if ((val & OMAP_MUX_MODE_MASK ) != OMAP_HSI_PADCONF_CAWAKE_MODE )
211- return 0 ;
243+ if ((val & OMAP_MUX_MODE_MASK ) !=
244+ port_ctx -> cawake_padconf_hsi_mode )
245+ continue ;
212246
213- if (val & OMAP44XX_PADCONF_WAKEUPEVENT0 )
247+ if (val & OMAP44XX_PADCONF_WAKEUPEVENT0 ) {
248+ * hsi_port = port_ctx -> port_number ;
214249 return 1 ;
250+ }
251+ }
252+
253+ * hsi_port = 0 ;
215254
216255 return 0 ;
217256}
@@ -220,50 +259,60 @@ int omap_hsi_is_io_wakeup_from_hsi(void)
220259* omap_hsi_wakeup_enable - Enable HSI wakeup feature from RET/OFF mode
221260*
222261* @hsi_port - reference to the HSI port onto which enable wakeup feature.
262+ * Range [1, 2]
223263*
224264* Return value :* 0 if CAWAKE has been configured to wakeup platform
225265* * -ENODEV if CAWAKE is not muxed on padconf
226266*/
227267static int omap_hsi_wakeup_enable (int hsi_port )
228268{
269+ struct hsi_port_ctx * port_ctx ;
229270 int ret = - ENODEV ;
230271
231- if (omap_hsi_is_io_pad_hsi ())
232- ret = omap_mux_enable_wakeup (OMAP_HSI_PADCONF_CAWAKE_PIN );
233- else
234- pr_debug ("Trying to enable HSI IO wakeup on non HSI board\n" );
235-
272+ if (omap_hsi_is_io_pad_hsi (hsi_port )) {
273+ port_ctx = hsi_get_hsi_port_ctx_data (hsi_port );
274+ ret = omap_mux_enable_wakeup (port_ctx -> cawake_padconf_name );
275+ omap4_trigger_ioctrl ();
276+ } else {
277+ pr_debug ("HSI port %d not muxed, failed to enable IO wakeup\n" ,
278+ hsi_port );
279+ }
236280
237- /* TODO: handle hsi_port param and use it to find the correct Pad */
238281 return ret ;
239282}
240283
241284/**
242285* omap_hsi_wakeup_disable - Disable HSI wakeup feature from RET/OFF mode
243286*
244287* @hsi_port - reference to the HSI port onto which disable wakeup feature.
288+ * Range [1, 2]
245289*
246290* Return value :* 0 if CAWAKE has been configured to not wakeup platform
247291* * -ENODEV if CAWAKE is not muxed on padconf
248292*/
249293static int omap_hsi_wakeup_disable (int hsi_port )
250294{
295+ struct hsi_port_ctx * port_ctx ;
251296 int ret = - ENODEV ;
252297
253- if (omap_hsi_is_io_pad_hsi ())
254- ret = omap_mux_disable_wakeup (OMAP_HSI_PADCONF_CAWAKE_PIN );
255- else
256- pr_debug ("Trying to disable HSI IO wakeup on non HSI board\n" );
257-
258-
259- /* TODO: handle hsi_port param and use it to find the correct Pad */
298+ if (omap_hsi_is_io_pad_hsi (hsi_port )) {
299+ port_ctx = hsi_get_hsi_port_ctx_data (hsi_port );
300+ ret = omap_mux_disable_wakeup (port_ctx -> cawake_padconf_name );
301+ omap4_trigger_ioctrl ();
302+ } else {
303+ pr_debug ("HSI port %d not muxed, failed to disable IO wakeup\n" ,
304+ hsi_port );
305+ }
260306
261307 return ret ;
262308}
263309
264310/**
265311* omap_hsi_prepare_suspend - Prepare HSI for suspend mode
266312*
313+ * @hsi_port - reference to the HSI port. Range [1, 2]
314+ * @dev_may_wakeup - value of sysfs flag indicating device wakeup capability
315+ *
267316* Return value :* 0 if CAWAKE padconf has been configured properly
268317* * -ENODEV if CAWAKE is not muxed on padconf.
269318*
@@ -280,6 +329,24 @@ int omap_hsi_prepare_suspend(int hsi_port, bool dev_may_wakeup)
280329 return ret ;
281330}
282331
332+ /**
333+ * omap_hsi_io_wakeup_check - Check if IO wakeup is from HSI and schedule HSI
334+ * processing tasklet
335+ *
336+ * Return value : * 0 if HSI tasklet scheduled.
337+ * * negative value else.
338+ */
339+ int omap_hsi_io_wakeup_check (void )
340+ {
341+ int hsi_port , ret = -1 ;
342+
343+ /* Modem HSI wakeup */
344+ if (omap_hsi_is_io_wakeup_from_hsi (& hsi_port ))
345+ ret = omap_hsi_wakeup (hsi_port );
346+
347+ return ret ;
348+ }
349+
283350/**
284351* omap_hsi_wakeup - Prepare HSI for wakeup from suspend mode (RET/OFF)
285352*
@@ -293,6 +360,7 @@ int omap_hsi_wakeup(int hsi_port)
293360{
294361 static struct platform_device * pdev ;
295362 static struct hsi_dev * hsi_ctrl ;
363+ int i ;
296364
297365 if (!pdev ) {
298366 pdev = hsi_get_hsi_platform_device ();
@@ -301,7 +369,7 @@ int omap_hsi_wakeup(int hsi_port)
301369 }
302370
303371 if (!device_may_wakeup (& pdev -> dev )) {
304- dev_info (& pdev -> dev , "Modem not allowed to wakeup platform" );
372+ dev_info (& pdev -> dev , "Modem not allowed to wakeup platform\n " );
305373 return - EPERM ;
306374 }
307375
@@ -311,20 +379,30 @@ int omap_hsi_wakeup(int hsi_port)
311379 return - ENODEV ;
312380 }
313381
382+ for (i = 0 ; i < omap_hsi_platform_data .num_ports ; i ++ ) {
383+ if (omap_hsi_platform_data .ctx -> pctx [i ].port_number == hsi_port )
384+ break ;
385+ }
386+
387+ if (i == omap_hsi_platform_data .num_ports )
388+ return - ENODEV ;
389+
390+
314391 /* Check no other interrupt handler has already scheduled the tasklet */
315392 if (test_and_set_bit (HSI_FLAGS_TASKLET_LOCK ,
316- & hsi_ctrl -> hsi_port -> flags ))
393+ & hsi_ctrl -> hsi_port [ i ]. flags ))
317394 return - EBUSY ;
318395
319- dev_dbg (hsi_ctrl -> dev , "Modem wakeup detected from HSI CAWAKE Pad" );
396+ dev_dbg (hsi_ctrl -> dev , "Modem wakeup detected from HSI CAWAKE Pad port "
397+ "%d\n" , hsi_port );
320398
321399 /* CAWAKE falling or rising edge detected */
322- hsi_ctrl -> hsi_port -> cawake_off_event = true;
323- tasklet_hi_schedule (& hsi_ctrl -> hsi_port -> hsi_tasklet );
400+ hsi_ctrl -> hsi_port [ i ]. cawake_off_event = true;
401+ tasklet_hi_schedule (& hsi_ctrl -> hsi_port [ i ]. hsi_tasklet );
324402
325403 /* Disable interrupt until Bottom Half has cleared */
326404 /* the IRQ status register */
327- disable_irq_nosync (hsi_ctrl -> hsi_port -> irq );
405+ disable_irq_nosync (hsi_ctrl -> hsi_port [ i ]. irq );
328406
329407 return 0 ;
330408}
0 commit comments