Skip to content

Commit 91ca10d

Browse files
sbrandengregkh
authored andcommitted
misc: bcm-vk: add ttyVK support
Add ttyVK support to driver to allow console access to VK card from host. Device node will be in the follow form /dev/bcm-vk.x_ttyVKy where: x is the instance of the VK card y is the tty device number on the VK card Acked-by: Olof Johansson <olof@lixom.net> Signed-off-by: Scott Branden <scott.branden@broadcom.com> Link: https://lore.kernel.org/r/20210120175827.14820-14-scott.branden@broadcom.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent 68f1fae commit 91ca10d

File tree

4 files changed

+392
-2
lines changed

4 files changed

+392
-2
lines changed

drivers/misc/bcm-vk/Makefile

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,5 +7,6 @@ obj-$(CONFIG_BCM_VK) += bcm_vk.o
77
bcm_vk-objs := \
88
bcm_vk_dev.o \
99
bcm_vk_msg.o \
10-
bcm_vk_sg.o
10+
bcm_vk_sg.o \
11+
bcm_vk_tty.o
1112

drivers/misc/bcm-vk/bcm_vk.h

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,14 @@
88

99
#include <linux/atomic.h>
1010
#include <linux/firmware.h>
11+
#include <linux/irq.h>
1112
#include <linux/kref.h>
1213
#include <linux/miscdevice.h>
1314
#include <linux/mutex.h>
1415
#include <linux/pci.h>
1516
#include <linux/poll.h>
1617
#include <linux/sched/signal.h>
18+
#include <linux/tty.h>
1719
#include <linux/uaccess.h>
1820
#include <uapi/linux/misc/bcm_vk.h>
1921

@@ -84,6 +86,9 @@
8486
#define CODEPUSH_BOOT2_ENTRY 0x60000000
8587

8688
#define BAR_CARD_STATUS 0x410
89+
/* CARD_STATUS definitions */
90+
#define CARD_STATUS_TTYVK0_READY BIT(0)
91+
#define CARD_STATUS_TTYVK1_READY BIT(1)
8792

8893
#define BAR_BOOT1_STDALONE_PROGRESS 0x420
8994
#define BOOT1_STDALONE_SUCCESS (BIT(13) | BIT(14))
@@ -255,6 +260,19 @@ enum pci_barno {
255260

256261
#define BCM_VK_NUM_TTY 2
257262

263+
struct bcm_vk_tty {
264+
struct tty_port port;
265+
u32 to_offset; /* bar offset to use */
266+
u32 to_size; /* to VK buffer size */
267+
u32 wr; /* write offset shadow */
268+
u32 from_offset; /* bar offset to use */
269+
u32 from_size; /* from VK buffer size */
270+
u32 rd; /* read offset shadow */
271+
pid_t pid;
272+
bool irq_enabled;
273+
bool is_opened; /* tracks tty open/close */
274+
};
275+
258276
/* VK device max power state, supports 3, full, reduced and low */
259277
#define MAX_OPP 3
260278
#define MAX_CARD_INFO_TAG_SIZE 64
@@ -348,6 +366,12 @@ struct bcm_vk {
348366
struct miscdevice miscdev;
349367
int devid; /* dev id allocated */
350368

369+
struct tty_driver *tty_drv;
370+
struct timer_list serial_timer;
371+
struct bcm_vk_tty tty[BCM_VK_NUM_TTY];
372+
struct workqueue_struct *tty_wq_thread;
373+
struct work_struct tty_wq_work;
374+
351375
/* Reference-counting to handle file operations */
352376
struct kref kref;
353377

@@ -466,6 +490,7 @@ int bcm_vk_release(struct inode *inode, struct file *p_file);
466490
void bcm_vk_release_data(struct kref *kref);
467491
irqreturn_t bcm_vk_msgq_irqhandler(int irq, void *dev_id);
468492
irqreturn_t bcm_vk_notf_irqhandler(int irq, void *dev_id);
493+
irqreturn_t bcm_vk_tty_irqhandler(int irq, void *dev_id);
469494
int bcm_vk_msg_init(struct bcm_vk *vk);
470495
void bcm_vk_msg_remove(struct bcm_vk *vk);
471496
void bcm_vk_drain_msg_on_reset(struct bcm_vk *vk);
@@ -476,6 +501,9 @@ int bcm_vk_send_shutdown_msg(struct bcm_vk *vk, u32 shut_type,
476501
const pid_t pid, const u32 q_num);
477502
void bcm_to_v_q_doorbell(struct bcm_vk *vk, u32 q_num, u32 db_val);
478503
int bcm_vk_auto_load_all_images(struct bcm_vk *vk);
504+
int bcm_vk_tty_init(struct bcm_vk *vk, char *name);
505+
void bcm_vk_tty_exit(struct bcm_vk *vk);
506+
void bcm_vk_tty_terminate_tty_user(struct bcm_vk *vk);
479507
void bcm_vk_hb_init(struct bcm_vk *vk);
480508
void bcm_vk_hb_deinit(struct bcm_vk *vk);
481509
void bcm_vk_handle_notf(struct bcm_vk *vk);

drivers/misc/bcm-vk/bcm_vk_dev.c

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -525,6 +525,7 @@ void bcm_vk_blk_drv_access(struct bcm_vk *vk)
525525
}
526526
}
527527
}
528+
bcm_vk_tty_terminate_tty_user(vk);
528529
spin_unlock(&vk->ctx_lock);
529530
}
530531

@@ -1384,6 +1385,20 @@ static int bcm_vk_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
13841385
}
13851386
vk->num_irqs++;
13861387

1388+
for (i = 0;
1389+
(i < VK_MSIX_TTY_MAX) && (vk->num_irqs < irq);
1390+
i++, vk->num_irqs++) {
1391+
err = devm_request_irq(dev, pci_irq_vector(pdev, vk->num_irqs),
1392+
bcm_vk_tty_irqhandler,
1393+
IRQF_SHARED, DRV_MODULE_NAME, vk);
1394+
if (err) {
1395+
dev_err(dev, "failed request tty IRQ %d for MSIX %d\n",
1396+
pdev->irq + vk->num_irqs, vk->num_irqs + 1);
1397+
goto err_irq;
1398+
}
1399+
vk->tty[i].irq_enabled = true;
1400+
}
1401+
13871402
id = ida_simple_get(&bcm_vk_ida, 0, 0, GFP_KERNEL);
13881403
if (id < 0) {
13891404
err = id;
@@ -1436,6 +1451,11 @@ static int bcm_vk_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
14361451
goto err_destroy_workqueue;
14371452
}
14381453

1454+
snprintf(name, sizeof(name), KBUILD_MODNAME ".%d_ttyVK", id);
1455+
err = bcm_vk_tty_init(vk, name);
1456+
if (err)
1457+
goto err_unregister_panic_notifier;
1458+
14391459
/*
14401460
* lets trigger an auto download. We don't want to do it serially here
14411461
* because at probing time, it is not supposed to block for a long time.
@@ -1444,7 +1464,7 @@ static int bcm_vk_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
14441464
if (auto_load) {
14451465
if ((boot_status & BOOT_STATE_MASK) == BROM_RUNNING) {
14461466
if (bcm_vk_trigger_autoload(vk))
1447-
goto err_unregister_panic_notifier;
1467+
goto err_bcm_vk_tty_exit;
14481468
} else {
14491469
dev_err(dev,
14501470
"Auto-load skipped - BROM not in proper state (0x%x)\n",
@@ -1459,6 +1479,9 @@ static int bcm_vk_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
14591479

14601480
return 0;
14611481

1482+
err_bcm_vk_tty_exit:
1483+
bcm_vk_tty_exit(vk);
1484+
14621485
err_unregister_panic_notifier:
14631486
atomic_notifier_chain_unregister(&panic_notifier_list,
14641487
&vk->panic_nb);
@@ -1536,6 +1559,9 @@ static void bcm_vk_remove(struct pci_dev *pdev)
15361559
atomic_notifier_chain_unregister(&panic_notifier_list,
15371560
&vk->panic_nb);
15381561

1562+
bcm_vk_msg_remove(vk);
1563+
bcm_vk_tty_exit(vk);
1564+
15391565
if (vk->tdma_vaddr)
15401566
dma_free_coherent(&pdev->dev, nr_scratch_pages * PAGE_SIZE,
15411567
vk->tdma_vaddr, vk->tdma_addr);
@@ -1554,6 +1580,8 @@ static void bcm_vk_remove(struct pci_dev *pdev)
15541580

15551581
cancel_work_sync(&vk->wq_work);
15561582
destroy_workqueue(vk->wq_thread);
1583+
cancel_work_sync(&vk->tty_wq_work);
1584+
destroy_workqueue(vk->tty_wq_thread);
15571585

15581586
for (i = 0; i < MAX_BAR; i++) {
15591587
if (vk->bar[i])

0 commit comments

Comments
 (0)