8250_ioc3.c 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * SGI IOC3 8250 UART driver
  4. *
  5. * Copyright (C) 2019 Thomas Bogendoerfer <[email protected]>
  6. *
  7. * based on code Copyright (C) 2005 Stanislaw Skowronek <[email protected]>
  8. * Copyright (C) 2014 Joshua Kinard <[email protected]>
  9. */
  10. #include <linux/module.h>
  11. #include <linux/errno.h>
  12. #include <linux/io.h>
  13. #include <linux/platform_device.h>
  14. #include "8250.h"
  15. #define IOC3_UARTCLK (22000000 / 3)
  16. struct ioc3_8250_data {
  17. int line;
  18. };
  19. static unsigned int ioc3_serial_in(struct uart_port *p, int offset)
  20. {
  21. return readb(p->membase + (offset ^ 3));
  22. }
  23. static void ioc3_serial_out(struct uart_port *p, int offset, int value)
  24. {
  25. writeb(value, p->membase + (offset ^ 3));
  26. }
  27. static int serial8250_ioc3_probe(struct platform_device *pdev)
  28. {
  29. struct ioc3_8250_data *data;
  30. struct uart_8250_port up;
  31. struct resource *r;
  32. void __iomem *membase;
  33. int irq, line;
  34. r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  35. if (!r)
  36. return -ENODEV;
  37. data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
  38. if (!data)
  39. return -ENOMEM;
  40. membase = devm_ioremap(&pdev->dev, r->start, resource_size(r));
  41. if (!membase)
  42. return -ENOMEM;
  43. irq = platform_get_irq(pdev, 0);
  44. if (irq < 0)
  45. irq = 0; /* no interrupt -> use polling */
  46. /* Register serial ports with 8250.c */
  47. memset(&up, 0, sizeof(struct uart_8250_port));
  48. up.port.iotype = UPIO_MEM;
  49. up.port.uartclk = IOC3_UARTCLK;
  50. up.port.type = PORT_16550A;
  51. up.port.irq = irq;
  52. up.port.flags = (UPF_BOOT_AUTOCONF | UPF_SHARE_IRQ);
  53. up.port.dev = &pdev->dev;
  54. up.port.membase = membase;
  55. up.port.mapbase = r->start;
  56. up.port.serial_in = ioc3_serial_in;
  57. up.port.serial_out = ioc3_serial_out;
  58. line = serial8250_register_8250_port(&up);
  59. if (line < 0)
  60. return line;
  61. platform_set_drvdata(pdev, data);
  62. return 0;
  63. }
  64. static int serial8250_ioc3_remove(struct platform_device *pdev)
  65. {
  66. struct ioc3_8250_data *data = platform_get_drvdata(pdev);
  67. serial8250_unregister_port(data->line);
  68. return 0;
  69. }
  70. static struct platform_driver serial8250_ioc3_driver = {
  71. .probe = serial8250_ioc3_probe,
  72. .remove = serial8250_ioc3_remove,
  73. .driver = {
  74. .name = "ioc3-serial8250",
  75. }
  76. };
  77. module_platform_driver(serial8250_ioc3_driver);
  78. MODULE_AUTHOR("Thomas Bogendoerfer <[email protected]>");
  79. MODULE_DESCRIPTION("SGI IOC3 8250 UART driver");
  80. MODULE_LICENSE("GPL");