Loading arch/arm/mach-msm/smd_tty.c +47 −16 Original line number Diff line number Diff line Loading @@ -21,7 +21,7 @@ #include <linux/device.h> #include <linux/interrupt.h> #include <linux/delay.h> #include <linux/wakelock.h> #include <linux/pm.h> #include <linux/platform_device.h> #include <linux/sched.h> Loading @@ -39,6 +39,7 @@ #define MODULE_NAME "msm_smdtty" #define MAX_SMD_TTYS 37 #define MAX_TTY_BUF_SIZE 2048 #define TTY_PUSH_WS_DELAY 500 #define MAX_RA_WAKE_LOCK_NAME_LEN 32 #define SMD_TTY_PROBE_WAIT_TIMEOUT 3000 #define SMD_TTY_LOG_PAGES 2 Loading @@ -63,11 +64,36 @@ static DEFINE_MUTEX(smd_tty_lock); static struct delayed_work smd_tty_probe_work; static int smd_tty_probe_done; /** * struct smd_tty_info - context for an individual SMD TTY device * * @ch: SMD channel handle * @port: TTY port context structure * @device_ptr: TTY device pointer * @pending_ws: pending-data wakeup source * @tty_tsklt: read tasklet * @buf_req_timer: RX buffer retry timer * @ch_allocated: completion set when SMD channel is allocated * @driver: SMD channel platform driver context structure * @pil: Peripheral Image Loader handle * @in_reset: True if SMD channel is closed / in SSR * @in_reset_updated: reset state changed * @is_open: True if SMD port is open * @open_wait: Timeout in seconds to wait for SMD port to be created / opened * @ch_opened_wait_queue: SMD port open/close wait queue * @reset_lock: lock for reset and open state * @ra_lock: Read-available lock - used to synchronize reads from SMD * @ra_wakeup_source_name: Name of the read-available wakeup source * @ra_wakeup_source: Read-available wakeup source * @edge: SMD edge associated with port * @ch_name: SMD channel name associated with port * @dev_name: SMD platform device name associated with port */ struct smd_tty_info { smd_channel_t *ch; struct tty_port port; struct device *device_ptr; struct wake_lock wake_lock; struct wakeup_source pending_ws; struct tasklet_struct tty_tsklt; struct timer_list buf_req_timer; struct completion ch_allocated; Loading @@ -80,8 +106,8 @@ struct smd_tty_info { wait_queue_head_t ch_opened_wait_queue; spinlock_t reset_lock; spinlock_t ra_lock; /* Read Available Lock*/ char ra_wake_lock_name[MAX_RA_WAKE_LOCK_NAME_LEN]; struct wake_lock ra_wake_lock; /* Read Available Wakelock */ char ra_wakeup_source_name[MAX_RA_WAKE_LOCK_NAME_LEN]; struct wakeup_source ra_wakeup_source; uint32_t edge; char ch_name[SMD_MAX_CH_NAME_LEN]; Loading Loading @@ -225,7 +251,7 @@ static void smd_tty_read(unsigned long param) spin_lock_irqsave(&info->ra_lock, flags); avail = smd_read_avail(info->ch); if (avail == 0) { wake_unlock(&info->ra_wake_lock); __pm_relax(&info->ra_wakeup_source); spin_unlock_irqrestore(&info->ra_lock, flags); break; } Loading @@ -252,7 +278,13 @@ static void smd_tty_read(unsigned long param) __func__, info->ch->name); } wake_lock_timeout(&info->wake_lock, HZ / 2); /* * Keep system awake long enough to allow the TTY * framework to pass the flip buffer to any waiting * userspace clients. */ __pm_wakeup_event(&info->pending_ws, TTY_PUSH_WS_DELAY); tty_flip_buffer_push(tty->port); } Loading Loading @@ -289,7 +321,7 @@ static void smd_tty_notify(void *priv, unsigned event) } spin_lock_irqsave(&info->ra_lock, flags); if (smd_read_avail(info->ch)) { wake_lock(&info->ra_wake_lock); __pm_stay_awake(&info->ra_wakeup_source); tasklet_hi_schedule(&info->tty_tsklt); } spin_unlock_irqrestore(&info->ra_lock, flags); Loading Loading @@ -407,12 +439,11 @@ static int smd_tty_port_activate(struct tty_port *tport, } tasklet_init(&info->tty_tsklt, smd_tty_read, (unsigned long)info); wake_lock_init(&info->wake_lock, WAKE_LOCK_SUSPEND, info->ch_name); scnprintf(info->ra_wake_lock_name, MAX_RA_WAKE_LOCK_NAME_LEN, wakeup_source_init(&info->pending_ws, info->ch_name); scnprintf(info->ra_wakeup_source_name, MAX_RA_WAKE_LOCK_NAME_LEN, "SMD_TTY_%s_RA", info->ch_name); wake_lock_init(&info->ra_wake_lock, WAKE_LOCK_SUSPEND, info->ra_wake_lock_name); wakeup_source_init(&info->ra_wakeup_source, info->ra_wakeup_source_name); res = smd_named_open_on_edge(info->ch_name, smd_tty[n].edge, &info->ch, info, Loading Loading @@ -444,8 +475,8 @@ close_ch: release_wl_tl: tasklet_kill(&info->tty_tsklt); wake_lock_destroy(&info->wake_lock); wake_lock_destroy(&info->ra_wake_lock); wakeup_source_trash(&info->pending_ws); wakeup_source_trash(&info->ra_wakeup_source); release_pil: subsystem_put(info->pil); Loading Loading @@ -474,8 +505,8 @@ static void smd_tty_port_shutdown(struct tty_port *tport) spin_unlock_irqrestore(&info->reset_lock, flags); tasklet_kill(&info->tty_tsklt); wake_lock_destroy(&info->wake_lock); wake_lock_destroy(&info->ra_wake_lock); wakeup_source_trash(&info->pending_ws); wakeup_source_trash(&info->ra_wakeup_source); SMD_TTY_INFO("%s with PID %u closed port %s", current->comm, current->pid, Loading Loading
arch/arm/mach-msm/smd_tty.c +47 −16 Original line number Diff line number Diff line Loading @@ -21,7 +21,7 @@ #include <linux/device.h> #include <linux/interrupt.h> #include <linux/delay.h> #include <linux/wakelock.h> #include <linux/pm.h> #include <linux/platform_device.h> #include <linux/sched.h> Loading @@ -39,6 +39,7 @@ #define MODULE_NAME "msm_smdtty" #define MAX_SMD_TTYS 37 #define MAX_TTY_BUF_SIZE 2048 #define TTY_PUSH_WS_DELAY 500 #define MAX_RA_WAKE_LOCK_NAME_LEN 32 #define SMD_TTY_PROBE_WAIT_TIMEOUT 3000 #define SMD_TTY_LOG_PAGES 2 Loading @@ -63,11 +64,36 @@ static DEFINE_MUTEX(smd_tty_lock); static struct delayed_work smd_tty_probe_work; static int smd_tty_probe_done; /** * struct smd_tty_info - context for an individual SMD TTY device * * @ch: SMD channel handle * @port: TTY port context structure * @device_ptr: TTY device pointer * @pending_ws: pending-data wakeup source * @tty_tsklt: read tasklet * @buf_req_timer: RX buffer retry timer * @ch_allocated: completion set when SMD channel is allocated * @driver: SMD channel platform driver context structure * @pil: Peripheral Image Loader handle * @in_reset: True if SMD channel is closed / in SSR * @in_reset_updated: reset state changed * @is_open: True if SMD port is open * @open_wait: Timeout in seconds to wait for SMD port to be created / opened * @ch_opened_wait_queue: SMD port open/close wait queue * @reset_lock: lock for reset and open state * @ra_lock: Read-available lock - used to synchronize reads from SMD * @ra_wakeup_source_name: Name of the read-available wakeup source * @ra_wakeup_source: Read-available wakeup source * @edge: SMD edge associated with port * @ch_name: SMD channel name associated with port * @dev_name: SMD platform device name associated with port */ struct smd_tty_info { smd_channel_t *ch; struct tty_port port; struct device *device_ptr; struct wake_lock wake_lock; struct wakeup_source pending_ws; struct tasklet_struct tty_tsklt; struct timer_list buf_req_timer; struct completion ch_allocated; Loading @@ -80,8 +106,8 @@ struct smd_tty_info { wait_queue_head_t ch_opened_wait_queue; spinlock_t reset_lock; spinlock_t ra_lock; /* Read Available Lock*/ char ra_wake_lock_name[MAX_RA_WAKE_LOCK_NAME_LEN]; struct wake_lock ra_wake_lock; /* Read Available Wakelock */ char ra_wakeup_source_name[MAX_RA_WAKE_LOCK_NAME_LEN]; struct wakeup_source ra_wakeup_source; uint32_t edge; char ch_name[SMD_MAX_CH_NAME_LEN]; Loading Loading @@ -225,7 +251,7 @@ static void smd_tty_read(unsigned long param) spin_lock_irqsave(&info->ra_lock, flags); avail = smd_read_avail(info->ch); if (avail == 0) { wake_unlock(&info->ra_wake_lock); __pm_relax(&info->ra_wakeup_source); spin_unlock_irqrestore(&info->ra_lock, flags); break; } Loading @@ -252,7 +278,13 @@ static void smd_tty_read(unsigned long param) __func__, info->ch->name); } wake_lock_timeout(&info->wake_lock, HZ / 2); /* * Keep system awake long enough to allow the TTY * framework to pass the flip buffer to any waiting * userspace clients. */ __pm_wakeup_event(&info->pending_ws, TTY_PUSH_WS_DELAY); tty_flip_buffer_push(tty->port); } Loading Loading @@ -289,7 +321,7 @@ static void smd_tty_notify(void *priv, unsigned event) } spin_lock_irqsave(&info->ra_lock, flags); if (smd_read_avail(info->ch)) { wake_lock(&info->ra_wake_lock); __pm_stay_awake(&info->ra_wakeup_source); tasklet_hi_schedule(&info->tty_tsklt); } spin_unlock_irqrestore(&info->ra_lock, flags); Loading Loading @@ -407,12 +439,11 @@ static int smd_tty_port_activate(struct tty_port *tport, } tasklet_init(&info->tty_tsklt, smd_tty_read, (unsigned long)info); wake_lock_init(&info->wake_lock, WAKE_LOCK_SUSPEND, info->ch_name); scnprintf(info->ra_wake_lock_name, MAX_RA_WAKE_LOCK_NAME_LEN, wakeup_source_init(&info->pending_ws, info->ch_name); scnprintf(info->ra_wakeup_source_name, MAX_RA_WAKE_LOCK_NAME_LEN, "SMD_TTY_%s_RA", info->ch_name); wake_lock_init(&info->ra_wake_lock, WAKE_LOCK_SUSPEND, info->ra_wake_lock_name); wakeup_source_init(&info->ra_wakeup_source, info->ra_wakeup_source_name); res = smd_named_open_on_edge(info->ch_name, smd_tty[n].edge, &info->ch, info, Loading Loading @@ -444,8 +475,8 @@ close_ch: release_wl_tl: tasklet_kill(&info->tty_tsklt); wake_lock_destroy(&info->wake_lock); wake_lock_destroy(&info->ra_wake_lock); wakeup_source_trash(&info->pending_ws); wakeup_source_trash(&info->ra_wakeup_source); release_pil: subsystem_put(info->pil); Loading Loading @@ -474,8 +505,8 @@ static void smd_tty_port_shutdown(struct tty_port *tport) spin_unlock_irqrestore(&info->reset_lock, flags); tasklet_kill(&info->tty_tsklt); wake_lock_destroy(&info->wake_lock); wake_lock_destroy(&info->ra_wake_lock); wakeup_source_trash(&info->pending_ws); wakeup_source_trash(&info->ra_wakeup_source); SMD_TTY_INFO("%s with PID %u closed port %s", current->comm, current->pid, Loading