Re: Driver Max310x called more than once

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hello,

You will find there the diff of the modifications that I made:
( the idea is to call once the function uart_register_driver ) . I can
see without problem the two uart on the /dev/ folder.
The first ttyMAX0 work well, but the ttyMAX1 don't give any spi signal.
If I'm using the second uart alone, it works well. So it's not a
problem of electronics, but more about the driver handling two max310x
( max3107 ) .

>From 5a672a9a33f31523611870f33fe74b1ed385916e Mon Sep 17 00:00:00 2001
From: michael musset <mickamusset@xxxxxxxxx>
Date: Mon, 4 Apr 2016 09:37:58 +0200
Subject: [PATCH] max310x multi device

Signed-off-by: michael musset <mickamusset@xxxxxxxxx>
---
 drivers/tty/serial/max310x.c           | 211 +++++++++++++++++++++------------

diff --git a/drivers/tty/serial/max310x.c b/drivers/tty/serial/max310x.c
index 182549f..81ef694 100644
--- a/drivers/tty/serial/max310x.c
+++ b/drivers/tty/serial/max310x.c
@@ -251,6 +251,8 @@
 #define MAX14830_BRGCFG_CLKDIS_BIT (1 << 6) /* Clock Disable */
 #define MAX14830_REV_ID (0xb0)

+#define MAX_MAX310X 5
+
 struct max310x_devtype {
  char name[9];
  int nr;
@@ -265,7 +267,9 @@ struct max310x_one {
 };

 struct max310x_port {
- struct uart_driver uart;
+ int nr;
+ int index;
+// struct uart_driver uart;
  struct max310x_devtype *devtype;
  struct regmap *regmap;
  struct mutex mutex;
@@ -276,11 +280,24 @@ struct max310x_port {
  struct max310x_one p[0];
 };

+static struct uart_driver max310x_uart_driver = {
+         .owner          = THIS_MODULE,
+         .driver_name    = "ttyMAX",
+         .dev_name       = "ttyMAX",
+         .major          = MAX310X_MAJOR,
+         .minor          = MAX310X_MINOR,
+         .nr             = MAX_MAX310X,
+};
+
+static struct max310x_port *max310xs[MAX_MAX310X]; /* the chips */
+static DEFINE_MUTEX(max310xs_lock);                /* race on probe */
+static int uart_driver_registered;
+
 static u8 max310x_port_read(struct uart_port *port, u8 reg)
 {
  struct max310x_port *s = dev_get_drvdata(port->dev);
  unsigned int val = 0;
-
+ printk("max310x_port_read %d\n", s->index);
  regmap_read(s->regmap, port->iobase + reg, &val);

  return val;
@@ -289,14 +306,14 @@ static u8 max310x_port_read(struct uart_port
*port, u8 reg)
 static void max310x_port_write(struct uart_port *port, u8 reg, u8 val)
 {
  struct max310x_port *s = dev_get_drvdata(port->dev);
-
+ printk("max310x_port_write %d\n", s->index);
  regmap_write(s->regmap, port->iobase + reg, val);
 }

 static void max310x_port_update(struct uart_port *port, u8 reg, u8
mask, u8 val)
 {
  struct max310x_port *s = dev_get_drvdata(port->dev);
-
+ printk("max310x_port_update %d\n", s->index);
  regmap_update_bits(s->regmap, port->iobase + reg, mask, val);
 }

@@ -715,13 +732,13 @@ static irqreturn_t max310x_ist(int irq, void *dev_id)
 {
  struct max310x_port *s = (struct max310x_port *)dev_id;

- if (s->uart.nr > 1) {
+ if (s->nr > 1) {
  do {
  unsigned int val = ~0;

  WARN_ON_ONCE(regmap_read(s->regmap,
  MAX310X_GLOBALIRQ_REG, &val));
- val = ((1 << s->uart.nr) - 1) & ~val;
+ val = ((1 << s->nr) - 1) & ~val;
  if (!val)
  break;
  max310x_port_irq(s, fls(val) - 1);
@@ -745,7 +762,8 @@ static void max310x_wq_proc(struct work_struct *ws)
 static void max310x_start_tx(struct uart_port *port)
 {
  struct max310x_one *one = container_of(port, struct max310x_one, port);
-
+ struct max310x_port *s = dev_get_drvdata(port->dev);
+        printk("max310x_start_tx %d", s->index);
  if (!work_pending(&one->tx_work))
  schedule_work(&one->tx_work);
 }
@@ -753,7 +771,8 @@ static void max310x_start_tx(struct uart_port *port)
 static unsigned int max310x_tx_empty(struct uart_port *port)
 {
  unsigned int lvl, sts;
-
+ struct max310x_port *s = dev_get_drvdata(port->dev);
+ printk("max310x_tx_empty %d", s->index);
  lvl = max310x_port_read(port, MAX310X_TXFIFOLVL_REG);
  sts = max310x_port_read(port, MAX310X_IRQSTS_REG);

@@ -914,7 +933,7 @@ static int max310x_startup(struct uart_port *port)
 {
  struct max310x_port *s = dev_get_drvdata(port->dev);
  unsigned int val;
-
+        printk("max310x_startup %d", s->index);
  s->devtype->power(port, 1);

  /* Configure MODE1 register */
@@ -1009,8 +1028,8 @@ static int __maybe_unused max310x_suspend(struct
device *dev)
  struct max310x_port *s = dev_get_drvdata(dev);
  int i;

- for (i = 0; i < s->uart.nr; i++) {
- uart_suspend_port(&s->uart, &s->p[i].port);
+ for (i = 0; i < s->nr; i++) {
+ uart_suspend_port(&max310x_uart_driver, &s->p[i].port);
  s->devtype->power(&s->p[i].port, 0);
  }

@@ -1022,9 +1041,9 @@ static int __maybe_unused max310x_resume(struct
device *dev)
  struct max310x_port *s = dev_get_drvdata(dev);
  int i;

- for (i = 0; i < s->uart.nr; i++) {
+ for (i = 0; i < s->nr; i++) {
  s->devtype->power(&s->p[i].port, 1);
- uart_resume_port(&s->uart, &s->p[i].port);
+ uart_resume_port(&max310x_uart_driver, &s->p[i].port);
  }

  return 0;
@@ -1081,48 +1100,87 @@ static int
max310x_gpio_direction_output(struct gpio_chip *chip,
 static int max310x_probe(struct device *dev, struct max310x_devtype *devtype,
  struct regmap *regmap, int irq, unsigned long flags)
 {
- int i, ret, fmin, fmax, freq, uartclk;
- struct clk *clk_osc, *clk_xtal;
- struct max310x_port *s;
- bool xtal = false;
+ int j,k;
+ int i, ret, fmin, fmax, freq=0, uartclk;
+ struct clk *clk_osc, *clk_xtal;
+ struct max310x_port *s;
+ bool xtal = false;
+ int retval = 0;

  if (IS_ERR(regmap))
  return PTR_ERR(regmap);

+ mutex_lock(&max310xs_lock);
+
+ if (!uart_driver_registered) {
+ printk("max310x init driver max310X\n");
+                 uart_driver_registered = 1;
+                 retval = uart_register_driver(&max310x_uart_driver);
+                 if (retval) {
+                         printk(KERN_ERR "max310x Couldn't register
max310x uart driver\n");
+                         mutex_unlock(&max310xs_lock);
+                         return retval;
+                 }
+ }
+        for (k = 0; k < MAX_MAX310X; k++)
+                 if (!max310xs[k])
+                         break;
+        if (k == MAX_MAX310X) {
+                dev_warn(dev, "too many MAX310X chips\n");
+                 mutex_unlock(&max310xs_lock);
+                 return -ENOMEM;
+        }
+ printk("max310x index %d\n", k);
+
+
  /* Alloc port structure */
- s = devm_kzalloc(dev, sizeof(*s) +
+ max310xs[k] =s = devm_kzalloc(dev, sizeof(*s) +
  sizeof(struct max310x_one) * devtype->nr, GFP_KERNEL);
+
+ mutex_unlock(&max310xs_lock);
+
  if (!s) {
  dev_err(dev, "Error allocating port structure\n");
  return -ENOMEM;
  }

- clk_osc = devm_clk_get(dev, "osc");
- clk_xtal = devm_clk_get(dev, "xtal");
- if (!IS_ERR(clk_osc)) {
- s->clk = clk_osc;
- fmin = 500000;
- fmax = 35000000;
- } else if (!IS_ERR(clk_xtal)) {
- s->clk = clk_xtal;
- fmin = 1000000;
- fmax = 4000000;
- xtal = true;
- } else if (PTR_ERR(clk_osc) == -EPROBE_DEFER ||
-   PTR_ERR(clk_xtal) == -EPROBE_DEFER) {
- return -EPROBE_DEFER;
- } else {
- dev_err(dev, "Cannot get clock\n");
- return -EINVAL;
+ s->index=k;
+
+ if (of_find_property(dev->of_node, "clock-frequency", NULL)){
+ of_property_read_u32(dev->of_node, "clock-frequency", &freq);
+               printk("max310x clock frequency detected %d\n", freq);
+        }
+        if(freq!=0){
+               fmin = 1000000;
+               fmax = 4000000;
+               xtal = 0;
+        }else{
+ clk_osc = devm_clk_get(dev, "osc");
+ clk_xtal = devm_clk_get(dev, "xtal");
+ if (!IS_ERR(clk_osc)) {
+ s->clk = clk_osc;
+ fmin = 500000;
+ fmax = 35000000;
+ } else if (!IS_ERR(clk_xtal)) {
+ s->clk = clk_xtal;
+ fmin = 1000000;
+ fmax = 4000000;
+ xtal = true;
+ } else if (PTR_ERR(clk_osc) == -EPROBE_DEFER ||
+   PTR_ERR(clk_xtal) == -EPROBE_DEFER) {
+ return -EPROBE_DEFER;
+ } else {
+ dev_err(dev, "Cannot get clock\n");
+ return -EINVAL;
+ }
+ ret = clk_prepare_enable(s->clk);
+ if (ret)
+ return ret;
+ freq = clk_get_rate(s->clk);
  }
-
- ret = clk_prepare_enable(s->clk);
- if (ret)
- return ret;
-
- freq = clk_get_rate(s->clk);
  /* Check frequency limits */
  if (freq < fmin || freq > fmax) {
+ printk("max310x error frequency\n");
  ret = -ERANGE;
  goto out_clk;
  }
@@ -1133,23 +1191,27 @@ static int max310x_probe(struct device *dev,
struct max310x_devtype *devtype,

  /* Check device to ensure we are talking to what we expect */
  ret = devtype->detect(dev);
- if (ret)
+ if (ret){
+ printk("max310x detection failed\n");
  goto out_clk;
-
+ }
  for (i = 0; i < devtype->nr; i++) {
  unsigned int offs = i << 5;

- /* Reset port */
- regmap_write(s->regmap, MAX310X_MODE2_REG + offs,
-     MAX310X_MODE2_RST_BIT);
- /* Clear port reset */
- regmap_write(s->regmap, MAX310X_MODE2_REG + offs, 0);
-
  /* Wait for port startup */
- do {
- regmap_read(s->regmap,
-    MAX310X_BRGDIVLSB_REG + offs, &ret);
- } while (ret != 0x01);
+ do{
+                /* Reset port */
+                 regmap_write(s->regmap, MAX310X_MODE2_REG + offs,
MAX310X_MODE2_RST_BIT);
+                 /* Clear port reset */
+                 regmap_write(s->regmap, MAX310X_MODE2_REG + offs, 0);
+
+ j=0;
+ ret=0;
+ for(j=0;(j<5 && ret!=0x01);j++){
+ regmap_read(s->regmap,
+    MAX310X_BRGDIVLSB_REG + offs, &ret);
+ }
+ }while(ret!=0x01);

  regmap_update_bits(s->regmap, MAX310X_MODE1_REG + offs,
    MAX310X_MODE1_AUTOSLEEP_BIT,
@@ -1157,19 +1219,8 @@ static int max310x_probe(struct device *dev,
struct max310x_devtype *devtype,
  }

  uartclk = max310x_set_ref_clk(s, freq, xtal);
- dev_dbg(dev, "Reference clock set to %i Hz\n", uartclk);
-
- /* Register UART driver */
- s->uart.owner = THIS_MODULE;
- s->uart.dev_name = "ttyMAX";
- s->uart.major = MAX310X_MAJOR;
- s->uart.minor = MAX310X_MINOR;
- s->uart.nr = devtype->nr;
- ret = uart_register_driver(&s->uart);
- if (ret) {
- dev_err(dev, "Registering UART driver failed\n");
- goto out_clk;
- }
+ printk("max310x Reference clock set to %i Hz\n", uartclk);
+ s->nr = devtype->nr;

 #ifdef CONFIG_GPIOLIB
  /* Setup GPIO cotroller */
@@ -1184,15 +1235,17 @@ static int max310x_probe(struct device *dev,
struct max310x_devtype *devtype,
  s->gpio.ngpio = devtype->nr * 4;
  s->gpio.can_sleep = 1;
  ret = gpiochip_add(&s->gpio);
- if (ret)
+ if (ret){
+ printk("max310x failed gpio add\n");
  goto out_uart;
+ }
 #endif

  mutex_init(&s->mutex);
-
+ printk("max310x devtype nr %d\n", devtype->nr);
  for (i = 0; i < devtype->nr; i++) {
  /* Initialize port data */
- s->p[i].port.line = i;
+ s->p[i].port.line = (k+i);
  s->p[i].port.dev = dev;
  s->p[i].port.irq = irq;
  s->p[i].port.type = PORT_MAX310X;
@@ -1217,7 +1270,8 @@ static int max310x_probe(struct device *dev,
struct max310x_devtype *devtype,
  /* Initialize queue for changing mode */
  INIT_WORK(&s->p[i].md_work, max310x_md_proc);
  /* Register port */
- uart_add_one_port(&s->uart, &s->p[i].port);
+ printk("max310x uart add one port\n");
+ uart_add_one_port( &max310x_uart_driver, &s->p[i].port);
  /* Go to suspend mode */
  devtype->power(&s->p[i].port, 0);
  }
@@ -1225,9 +1279,10 @@ static int max310x_probe(struct device *dev,
struct max310x_devtype *devtype,
  /* Setup interrupt */
  ret = devm_request_threaded_irq(dev, irq, NULL, max310x_ist,
  IRQF_ONESHOT | flags, dev_name(dev), s);
- if (!ret)
+ if (!ret){
+ printk("max310x add success\n");
  return 0;
-
+ }
  dev_err(dev, "Unable to reguest IRQ %i\n", irq);

  mutex_destroy(&s->mutex);
@@ -1237,7 +1292,7 @@ static int max310x_probe(struct device *dev,
struct max310x_devtype *devtype,

 out_uart:
 #endif
- uart_unregister_driver(&s->uart);
+ uart_unregister_driver(&max310x_uart_driver);

 out_clk:
  clk_disable_unprepare(s->clk);
@@ -1254,15 +1309,15 @@ static int max310x_remove(struct device *dev)
  gpiochip_remove(&s->gpio);
 #endif

- for (i = 0; i < s->uart.nr; i++) {
+ for (i = 0; i < s->nr; i++) {
  cancel_work_sync(&s->p[i].tx_work);
  cancel_work_sync(&s->p[i].md_work);
- uart_remove_one_port(&s->uart, &s->p[i].port);
+ uart_remove_one_port(&max310x_uart_driver, &s->p[i].port);
  s->devtype->power(&s->p[i].port, 0);
  }

  mutex_destroy(&s->mutex);
- uart_unregister_driver(&s->uart);
+ uart_unregister_driver(&max310x_uart_driver);
  clk_disable_unprepare(s->clk);

  return 0;
@@ -1335,7 +1390,7 @@ static const struct spi_device_id max310x_id_table[] = {
 };
 MODULE_DEVICE_TABLE(spi, max310x_id_table);

-static struct spi_driver max310x_uart_driver = {
+static struct spi_driver spi_max310x_uart_driver = {
  .driver = {
  .name = MAX310X_NAME,
  .owner = THIS_MODULE,
@@ -1346,7 +1401,7 @@ static struct spi_driver max310x_uart_driver = {
  .remove = max310x_spi_remove,
  .id_table = max310x_id_table,
 };
-module_spi_driver(max310x_uart_driver);
+module_spi_driver(spi_max310x_uart_driver);
 #endif




Le ven. 1 avr. 2016 à 16:55, Jiri Slaby <jslaby@xxxxxxx> a écrit :
>
> On 04/01/2016, 03:17 PM, Micka wrote:
> > Hi,
> >
> > I'm using your driver on the kernel 4.1, I tried to modify it, so that
> > it can be called multiple time, but it failed .....  I can see in the
> > folder /dev/ two file ttyMAX0 and ttyMAX1 . But the second uart doesn't
> > work. I don't see any spi frame !
> >
> > I don't want you to do my work, I just need some tips on where are the
> > error ! ^^
> >
> > You can find in attached the driver modified !
> ...
> > MODULE_AUTHOR("Alexander Shiyan <shc_work@xxxxxxx>");
>
> And consider this line when sending the question again with the diff.
>
> thanks,
> --
> js
> suse labs
--
To unsubscribe from this list: send the line "unsubscribe linux-serial" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[Index of Archives]     [Kernel Newbies]     [Security]     [Netfilter]     [Bugtraq]     [Linux PPP]     [Linux FS]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Samba]     [Video 4 Linux]     [Linmodem]     [Device Mapper]     [Linux Kernel for ARM]

  Powered by Linux