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, const u8 *buffer, int count) 190 { 191 int index; 192 struct bcm_vk *vk; 193 struct bcm_vk_tty *vktty; 194 int i; 195 196 index = tty->index; 197 vk = dev_get_drvdata(tty->dev); 198 vktty = &vk->tty[index]; 199 200 /* Simple write each byte to circular buffer */ 201 for (i = 0; i < count; i++) { 202 vkwrite8(vk, buffer[i], BAR_1, 203 VK_BAR_CHAN_DATA(vktty, to, vktty->wr)); 204 vktty->wr++; 205 if (vktty->wr >= vktty->to_size) 206 vktty->wr = 0; 207 } 208 /* Update write offset from shadow register to card */ 209 vkwrite32(vk, vktty->wr, BAR_1, VK_BAR_CHAN_WR(vktty, to)); 210 bcm_vk_tty_doorbell(vk, 0); 211 212 return count; 213 } 214 215 static unsigned int bcm_vk_tty_write_room(struct tty_struct *tty) 216 { 217 struct bcm_vk *vk = dev_get_drvdata(tty->dev); 218 219 return vk->tty[tty->index].to_size - 1; 220 } 221 222 static const struct tty_operations serial_ops = { 223 .open = bcm_vk_tty_open, 224 .close = bcm_vk_tty_close, 225 .write = bcm_vk_tty_write, 226 .write_room = bcm_vk_tty_write_room, 227 }; 228 229 int bcm_vk_tty_init(struct bcm_vk *vk, char *name) 230 { 231 int i; 232 int err; 233 struct tty_driver *tty_drv; 234 struct device *dev = &vk->pdev->dev; 235 236 tty_drv = tty_alloc_driver 237 (BCM_VK_NUM_TTY, 238 TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV); 239 if (IS_ERR(tty_drv)) 240 return PTR_ERR(tty_drv); 241 242 /* Save struct tty_driver for uninstalling the device */ 243 vk->tty_drv = tty_drv; 244 245 /* initialize the tty driver */ 246 tty_drv->driver_name = KBUILD_MODNAME; 247 tty_drv->name = kstrdup(name, GFP_KERNEL); 248 if (!tty_drv->name) { 249 err = -ENOMEM; 250 goto err_tty_driver_kref_put; 251 } 252 tty_drv->type = TTY_DRIVER_TYPE_SERIAL; 253 tty_drv->subtype = SERIAL_TYPE_NORMAL; 254 tty_drv->init_termios = tty_std_termios; 255 tty_set_operations(tty_drv, &serial_ops); 256 257 /* register the tty driver */ 258 err = tty_register_driver(tty_drv); 259 if (err) { 260 dev_err(dev, "tty_register_driver failed\n"); 261 goto err_kfree_tty_name; 262 } 263 264 for (i = 0; i < BCM_VK_NUM_TTY; i++) { 265 struct device *tty_dev; 266 267 tty_port_init(&vk->tty[i].port); 268 tty_dev = tty_port_register_device_attr(&vk->tty[i].port, 269 tty_drv, i, dev, vk, 270 NULL); 271 if (IS_ERR(tty_dev)) { 272 err = PTR_ERR(tty_dev); 273 goto unwind; 274 } 275 vk->tty[i].is_opened = false; 276 } 277 278 INIT_WORK(&vk->tty_wq_work, bcm_vk_tty_wq_handler); 279 vk->tty_wq_thread = create_singlethread_workqueue("tty"); 280 if (!vk->tty_wq_thread) { 281 dev_err(dev, "Fail to create tty workqueue thread\n"); 282 err = -ENOMEM; 283 goto unwind; 284 } 285 return 0; 286 287 unwind: 288 while (--i >= 0) 289 tty_port_unregister_device(&vk->tty[i].port, tty_drv, i); 290 tty_unregister_driver(tty_drv); 291 292 err_kfree_tty_name: 293 kfree(tty_drv->name); 294 tty_drv->name = NULL; 295 296 err_tty_driver_kref_put: 297 tty_driver_kref_put(tty_drv); 298 299 return err; 300 } 301 302 void bcm_vk_tty_exit(struct bcm_vk *vk) 303 { 304 int i; 305 306 del_timer_sync(&vk->serial_timer); 307 for (i = 0; i < BCM_VK_NUM_TTY; ++i) { 308 tty_port_unregister_device(&vk->tty[i].port, 309 vk->tty_drv, 310 i); 311 tty_port_destroy(&vk->tty[i].port); 312 } 313 tty_unregister_driver(vk->tty_drv); 314 315 kfree(vk->tty_drv->name); 316 vk->tty_drv->name = NULL; 317 318 tty_driver_kref_put(vk->tty_drv); 319 } 320 321 void bcm_vk_tty_terminate_tty_user(struct bcm_vk *vk) 322 { 323 struct bcm_vk_tty *vktty; 324 int i; 325 326 for (i = 0; i < BCM_VK_NUM_TTY; ++i) { 327 vktty = &vk->tty[i]; 328 if (vktty->pid) 329 kill_pid(find_vpid(vktty->pid), SIGKILL, 1); 330 } 331 } 332 333 void bcm_vk_tty_wq_exit(struct bcm_vk *vk) 334 { 335 cancel_work_sync(&vk->tty_wq_work); 336 destroy_workqueue(vk->tty_wq_thread); 337 } 338