1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Copyright 2018-2020 Broadcom. 4 */ 5 6 #include <linux/tty.h> 7 #include <linux/tty_driver.h> 8 #include <linux/tty_flip.h> 9 10 #include "bcm_vk.h" 11 12 /* TTYVK base offset is 0x30000 into BAR1 */ 13 #define BAR1_TTYVK_BASE_OFFSET 0x300000 14 /* Each TTYVK channel (TO or FROM) is 0x10000 */ 15 #define BAR1_TTYVK_CHAN_OFFSET 0x100000 16 /* Each TTYVK channel has TO and FROM, hence the * 2 */ 17 #define BAR1_TTYVK_BASE(index) (BAR1_TTYVK_BASE_OFFSET + \ 18 ((index) * BAR1_TTYVK_CHAN_OFFSET * 2)) 19 /* TO TTYVK channel base comes before FROM for each index */ 20 #define TO_TTYK_BASE(index) BAR1_TTYVK_BASE(index) 21 #define FROM_TTYK_BASE(index) (BAR1_TTYVK_BASE(index) + \ 22 BAR1_TTYVK_CHAN_OFFSET) 23 24 struct bcm_vk_tty_chan { 25 u32 reserved; 26 u32 size; 27 u32 wr; 28 u32 rd; 29 u32 *data; 30 }; 31 32 #define VK_BAR_CHAN(v, DIR, e) ((v)->DIR##_offset \ 33 + offsetof(struct bcm_vk_tty_chan, e)) 34 #define VK_BAR_CHAN_SIZE(v, DIR) VK_BAR_CHAN(v, DIR, size) 35 #define VK_BAR_CHAN_WR(v, DIR) VK_BAR_CHAN(v, DIR, wr) 36 #define VK_BAR_CHAN_RD(v, DIR) VK_BAR_CHAN(v, DIR, rd) 37 #define VK_BAR_CHAN_DATA(v, DIR, off) (VK_BAR_CHAN(v, DIR, data) + (off)) 38 39 #define VK_BAR0_REGSEG_TTY_DB_OFFSET 0x86c 40 41 /* Poll every 1/10 of second - temp hack till we use MSI interrupt */ 42 #define SERIAL_TIMER_VALUE (HZ / 10) 43 44 static void bcm_vk_tty_poll(struct timer_list *t) 45 { 46 struct bcm_vk *vk = from_timer(vk, t, serial_timer); 47 48 queue_work(vk->tty_wq_thread, &vk->tty_wq_work); 49 mod_timer(&vk->serial_timer, jiffies + SERIAL_TIMER_VALUE); 50 } 51 52 irqreturn_t bcm_vk_tty_irqhandler(int irq, void *dev_id) 53 { 54 struct bcm_vk *vk = dev_id; 55 56 queue_work(vk->tty_wq_thread, &vk->tty_wq_work); 57 58 return IRQ_HANDLED; 59 } 60 61 static void bcm_vk_tty_wq_handler(struct work_struct *work) 62 { 63 struct bcm_vk *vk = container_of(work, struct bcm_vk, tty_wq_work); 64 struct bcm_vk_tty *vktty; 65 int card_status; 66 int count; 67 unsigned char c; 68 int i; 69 int wr; 70 71 card_status = vkread32(vk, BAR_0, BAR_CARD_STATUS); 72 if (BCM_VK_INTF_IS_DOWN(card_status)) 73 return; 74 75 for (i = 0; i < BCM_VK_NUM_TTY; i++) { 76 count = 0; 77 /* Check the card status that the tty channel is ready */ 78 if ((card_status & BIT(i)) == 0) 79 continue; 80 81 vktty = &vk->tty[i]; 82 83 /* Don't increment read index if tty app is closed */ 84 if (!vktty->is_opened) 85 continue; 86 87 /* Fetch the wr offset in buffer from VK */ 88 wr = vkread32(vk, BAR_1, VK_BAR_CHAN_WR(vktty, from)); 89 90 /* safe to ignore until bar read gives proper size */ 91 if (vktty->from_size == 0) 92 continue; 93 94 if (wr >= vktty->from_size) { 95 dev_err(&vk->pdev->dev, 96 "ERROR: wq handler ttyVK%d wr:0x%x > 0x%x\n", 97 i, wr, vktty->from_size); 98 /* Need to signal and close device in this case */ 99 continue; 100 } 101 102 /* 103 * Simple read of circular buffer and 104 * insert into tty flip buffer 105 */ 106 while (vk->tty[i].rd != wr) { 107 c = vkread8(vk, BAR_1, 108 VK_BAR_CHAN_DATA(vktty, from, vktty->rd)); 109 vktty->rd++; 110 if (vktty->rd >= vktty->from_size) 111 vktty->rd = 0; 112 tty_insert_flip_char(&vktty->port, c, TTY_NORMAL); 113 count++; 114 } 115 116 if (count) { 117 tty_flip_buffer_push(&vktty->port); 118 119 /* Update read offset from shadow register to card */ 120 vkwrite32(vk, vktty->rd, BAR_1, 121 VK_BAR_CHAN_RD(vktty, from)); 122 } 123 } 124 } 125 126 static int bcm_vk_tty_open(struct tty_struct *tty, struct file *file) 127 { 128 int card_status; 129 struct bcm_vk *vk; 130 struct bcm_vk_tty *vktty; 131 int index; 132 133 /* initialize the pointer in case something fails */ 134 tty->driver_data = NULL; 135 136 vk = (struct bcm_vk *)dev_get_drvdata(tty->dev); 137 index = tty->index; 138 139 if (index >= BCM_VK_NUM_TTY) 140 return -EINVAL; 141 142 vktty = &vk->tty[index]; 143 144 vktty->pid = task_pid_nr(current); 145 vktty->to_offset = TO_TTYK_BASE(index); 146 vktty->from_offset = FROM_TTYK_BASE(index); 147 148 /* Do not allow tty device to be opened if tty on card not ready */ 149 card_status = vkread32(vk, BAR_0, BAR_CARD_STATUS); 150 if (BCM_VK_INTF_IS_DOWN(card_status) || ((card_status & BIT(index)) == 0)) 151 return -EBUSY; 152 153 /* 154 * Get shadow registers of the buffer sizes and the "to" write offset 155 * and "from" read offset 156 */ 157 vktty->to_size = vkread32(vk, BAR_1, VK_BAR_CHAN_SIZE(vktty, to)); 158 vktty->wr = vkread32(vk, BAR_1, VK_BAR_CHAN_WR(vktty, to)); 159 vktty->from_size = vkread32(vk, BAR_1, VK_BAR_CHAN_SIZE(vktty, from)); 160 vktty->rd = vkread32(vk, BAR_1, VK_BAR_CHAN_RD(vktty, from)); 161 vktty->is_opened = true; 162 163 if (tty->count == 1 && !vktty->irq_enabled) { 164 timer_setup(&vk->serial_timer, bcm_vk_tty_poll, 0); 165 mod_timer(&vk->serial_timer, jiffies + SERIAL_TIMER_VALUE); 166 } 167 return 0; 168 } 169 170 static void bcm_vk_tty_close(struct tty_struct *tty, struct file *file) 171 { 172 struct bcm_vk *vk = dev_get_drvdata(tty->dev); 173 174 if (tty->index >= BCM_VK_NUM_TTY) 175 return; 176 177 vk->tty[tty->index].is_opened = false; 178 179 if (tty->count == 1) 180 del_timer_sync(&vk->serial_timer); 181 } 182 183 static void bcm_vk_tty_doorbell(struct bcm_vk *vk, u32 db_val) 184 { 185 vkwrite32(vk, db_val, BAR_0, 186 VK_BAR0_REGSEG_DB_BASE + VK_BAR0_REGSEG_TTY_DB_OFFSET); 187 } 188 189 static int bcm_vk_tty_write(struct tty_struct *tty, 190 const unsigned char *buffer, 191 int count) 192 { 193 int index; 194 struct bcm_vk *vk; 195 struct bcm_vk_tty *vktty; 196 int i; 197 198 index = tty->index; 199 vk = dev_get_drvdata(tty->dev); 200 vktty = &vk->tty[index]; 201 202 /* Simple write each byte to circular buffer */ 203 for (i = 0; i < count; i++) { 204 vkwrite8(vk, buffer[i], BAR_1, 205 VK_BAR_CHAN_DATA(vktty, to, vktty->wr)); 206 vktty->wr++; 207 if (vktty->wr >= vktty->to_size) 208 vktty->wr = 0; 209 } 210 /* Update write offset from shadow register to card */ 211 vkwrite32(vk, vktty->wr, BAR_1, VK_BAR_CHAN_WR(vktty, to)); 212 bcm_vk_tty_doorbell(vk, 0); 213 214 return count; 215 } 216 217 static int bcm_vk_tty_write_room(struct tty_struct *tty) 218 { 219 struct bcm_vk *vk = dev_get_drvdata(tty->dev); 220 221 return vk->tty[tty->index].to_size - 1; 222 } 223 224 static const struct tty_operations serial_ops = { 225 .open = bcm_vk_tty_open, 226 .close = bcm_vk_tty_close, 227 .write = bcm_vk_tty_write, 228 .write_room = bcm_vk_tty_write_room, 229 }; 230 231 int bcm_vk_tty_init(struct bcm_vk *vk, char *name) 232 { 233 int i; 234 int err; 235 struct tty_driver *tty_drv; 236 struct device *dev = &vk->pdev->dev; 237 238 tty_drv = tty_alloc_driver 239 (BCM_VK_NUM_TTY, 240 TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV); 241 if (IS_ERR(tty_drv)) 242 return PTR_ERR(tty_drv); 243 244 /* Save struct tty_driver for uninstalling the device */ 245 vk->tty_drv = tty_drv; 246 247 /* initialize the tty driver */ 248 tty_drv->driver_name = KBUILD_MODNAME; 249 tty_drv->name = kstrdup(name, GFP_KERNEL); 250 if (!tty_drv->name) { 251 err = -ENOMEM; 252 goto err_put_tty_driver; 253 } 254 tty_drv->type = TTY_DRIVER_TYPE_SERIAL; 255 tty_drv->subtype = SERIAL_TYPE_NORMAL; 256 tty_drv->init_termios = tty_std_termios; 257 tty_set_operations(tty_drv, &serial_ops); 258 259 /* register the tty driver */ 260 err = tty_register_driver(tty_drv); 261 if (err) { 262 dev_err(dev, "tty_register_driver failed\n"); 263 goto err_kfree_tty_name; 264 } 265 266 for (i = 0; i < BCM_VK_NUM_TTY; i++) { 267 struct device *tty_dev; 268 269 tty_port_init(&vk->tty[i].port); 270 tty_dev = tty_port_register_device(&vk->tty[i].port, tty_drv, 271 i, dev); 272 if (IS_ERR(tty_dev)) { 273 err = PTR_ERR(tty_dev); 274 goto unwind; 275 } 276 dev_set_drvdata(tty_dev, vk); 277 vk->tty[i].is_opened = false; 278 } 279 280 INIT_WORK(&vk->tty_wq_work, bcm_vk_tty_wq_handler); 281 vk->tty_wq_thread = create_singlethread_workqueue("tty"); 282 if (!vk->tty_wq_thread) { 283 dev_err(dev, "Fail to create tty workqueue thread\n"); 284 err = -ENOMEM; 285 goto unwind; 286 } 287 return 0; 288 289 unwind: 290 while (--i >= 0) 291 tty_port_unregister_device(&vk->tty[i].port, tty_drv, i); 292 tty_unregister_driver(tty_drv); 293 294 err_kfree_tty_name: 295 kfree(tty_drv->name); 296 tty_drv->name = NULL; 297 298 err_put_tty_driver: 299 put_tty_driver(tty_drv); 300 301 return err; 302 } 303 304 void bcm_vk_tty_exit(struct bcm_vk *vk) 305 { 306 int i; 307 308 del_timer_sync(&vk->serial_timer); 309 for (i = 0; i < BCM_VK_NUM_TTY; ++i) { 310 tty_port_unregister_device(&vk->tty[i].port, 311 vk->tty_drv, 312 i); 313 tty_port_destroy(&vk->tty[i].port); 314 } 315 tty_unregister_driver(vk->tty_drv); 316 317 kfree(vk->tty_drv->name); 318 vk->tty_drv->name = NULL; 319 320 put_tty_driver(vk->tty_drv); 321 } 322 323 void bcm_vk_tty_terminate_tty_user(struct bcm_vk *vk) 324 { 325 struct bcm_vk_tty *vktty; 326 int i; 327 328 for (i = 0; i < BCM_VK_NUM_TTY; ++i) { 329 vktty = &vk->tty[i]; 330 if (vktty->pid) 331 kill_pid(find_vpid(vktty->pid), SIGKILL, 1); 332 } 333 } 334 335 void bcm_vk_tty_wq_exit(struct bcm_vk *vk) 336 { 337 cancel_work_sync(&vk->tty_wq_work); 338 destroy_workqueue(vk->tty_wq_thread); 339 } 340