Merge branch 'sa1111' into sa11x0
Russell King [Sun, 25 Mar 2012 22:54:16 +0000 (23:54 +0100)]
Conflicts:
arch/arm/common/sa1111.c
arch/arm/mach-sa1100/neponset.c

Fixed:
arch/arm/mach-sa1100/assabet.c
for the neponset changes

1  2 
arch/arm/mach-sa1100/assabet.c
arch/arm/mach-sa1100/badge4.c
arch/arm/mach-sa1100/jornada720.c
arch/arm/mach-sa1100/neponset.c

@@@ -425,21 -412,21 +425,8 @@@ static void __init assabet_map_io(void
         */
        Ser1SDCR0 |= SDCR0_SUS;
  
--      if (machine_has_neponset()) {
--#ifdef CONFIG_ASSABET_NEPONSET
--              extern void neponset_map_io(void);
--
--              /*
--               * We map Neponset registers even if it isn't present since
--               * many drivers will try to probe their stuff (and fail).
--               * This is still more friendly than a kernel paging request
--               * crash.
--               */
--              neponset_map_io();
--#endif
--      } else {
++      if (!machine_has_neponset())
                sa1100_register_uart_fns(&assabet_port_fns);
--      }
  
        /*
         * When Neponset is attached, the first UART should be
  #include "generic.h"
  
  static struct resource sa1111_resources[] = {
 -      [0] = {
 -              .start          = BADGE4_SA1111_BASE,
 -              .end            = BADGE4_SA1111_BASE + 0x00001fff,
 -              .flags          = IORESOURCE_MEM,
 -      },
 -      [1] = {
 -              .start          = BADGE4_IRQ_GPIO_SA1111,
 -              .end            = BADGE4_IRQ_GPIO_SA1111,
 -              .flags          = IORESOURCE_IRQ,
 -      },
 +      [0] = DEFINE_RES_MEM(BADGE4_SA1111_BASE, 0x2000),
 +      [1] = DEFINE_RES_IRQ(BADGE4_IRQ_GPIO_SA1111),
  };
  
+ static int badge4_sa1111_enable(void *data, unsigned devid)
+ {
+       if (devid == SA1111_DEVID_USB)
+               badge4_set_5V(BADGE4_5V_USB, 1);
+       return 0;
+ }
+ static void badge4_sa1111_disable(void *data, unsigned devid)
+ {
+       if (devid == SA1111_DEVID_USB)
+               badge4_set_5V(BADGE4_5V_USB, 0);
+ }
  static struct sa1111_platform_data sa1111_info = {
        .irq_base       = IRQ_BOARD_END,
+       .disable_devs   = SA1111_DEVID_PS2_MSE,
+       .enable         = badge4_sa1111_enable,
+       .disable        = badge4_sa1111_disable,
  };
  
  static u64 sa1111_dmamask = 0xffffffffUL;
Simple merge
@@@ -229,220 -242,101 +229,207 @@@ static struct irq_chip nochip = 
  
  static struct sa1111_platform_data sa1111_info = {
        .irq_base       = IRQ_BOARD_END,
+       .disable_devs   = SA1111_DEVID_PS2_MSE,
  };
  
 -static u64 sa1111_dmamask = 0xffffffffUL;
 +static int __devinit neponset_probe(struct platform_device *dev)
 +{
 +      struct neponset_drvdata *d;
 +      struct resource *nep_res, *sa1111_res, *smc91x_res;
 +      struct resource sa1111_resources[] = {
 +              DEFINE_RES_MEM(0x40000000, SZ_8K),
 +              { .flags = IORESOURCE_IRQ },
 +      };
 +      struct platform_device_info sa1111_devinfo = {
 +              .parent = &dev->dev,
 +              .name = "sa1111",
 +              .id = 0,
 +              .res = sa1111_resources,
 +              .num_res = ARRAY_SIZE(sa1111_resources),
 +              .data = &sa1111_info,
 +              .size_data = sizeof(sa1111_info),
 +              .dma_mask = 0xffffffffUL,
 +      };
 +      struct resource smc91x_resources[] = {
 +              DEFINE_RES_MEM_NAMED(SA1100_CS3_PHYS,
 +                      0x02000000, "smc91x-regs"),
 +              DEFINE_RES_MEM_NAMED(SA1100_CS3_PHYS + 0x02000000,
 +                      0x02000000, "smc91x-attrib"),
 +              { .flags = IORESOURCE_IRQ },
 +      };
 +      struct platform_device_info smc91x_devinfo = {
 +              .parent = &dev->dev,
 +              .name = "smc91x",
 +              .id = 0,
 +              .res = smc91x_resources,
 +              .num_res = ARRAY_SIZE(smc91x_resources),
 +      };
 +      int ret, irq;
 +
 +      if (nep_base)
 +              return -EBUSY;
 +
 +      irq = ret = platform_get_irq(dev, 0);
 +      if (ret < 0)
 +              goto err_alloc;
 +
 +      nep_res = platform_get_resource(dev, IORESOURCE_MEM, 0);
 +      smc91x_res = platform_get_resource(dev, IORESOURCE_MEM, 1);
 +      sa1111_res = platform_get_resource(dev, IORESOURCE_MEM, 2);
 +      if (!nep_res || !smc91x_res || !sa1111_res) {
 +              ret = -ENXIO;
 +              goto err_alloc;
 +      }
  
 -static struct platform_device sa1111_device = {
 -      .name           = "sa1111",
 -      .id             = 0,
 -      .dev            = {
 -              .dma_mask = &sa1111_dmamask,
 -              .coherent_dma_mask = 0xffffffff,
 -              .platform_data = &sa1111_info,
 -      },
 -      .num_resources  = ARRAY_SIZE(sa1111_resources),
 -      .resource       = sa1111_resources,
 -};
 +      d = kzalloc(sizeof(*d), GFP_KERNEL);
 +      if (!d) {
 +              ret = -ENOMEM;
 +              goto err_alloc;
 +      }
  
 -static struct resource smc91x_resources[] = {
 -      [0] = {
 -              .name   = "smc91x-regs",
 -              .start  = SA1100_CS3_PHYS,
 -              .end    = SA1100_CS3_PHYS + 0x01ffffff,
 -              .flags  = IORESOURCE_MEM,
 -      },
 -      [1] = {
 -              .start  = IRQ_NEPONSET_SMC9196,
 -              .end    = IRQ_NEPONSET_SMC9196,
 -              .flags  = IORESOURCE_IRQ,
 -      },
 -      [2] = {
 -              .name   = "smc91x-attrib",
 -              .start  = SA1100_CS3_PHYS + 0x02000000,
 -              .end    = SA1100_CS3_PHYS + 0x03ffffff,
 -              .flags  = IORESOURCE_MEM,
 -      },
 -};
 +      d->base = ioremap(nep_res->start, SZ_4K);
 +      if (!d->base) {
 +              ret = -ENOMEM;
 +              goto err_ioremap;
 +      }
  
 -static struct platform_device smc91x_device = {
 -      .name           = "smc91x",
 -      .id             = 0,
 -      .num_resources  = ARRAY_SIZE(smc91x_resources),
 -      .resource       = smc91x_resources,
 -};
 +      if (readb_relaxed(d->base + WHOAMI) != 0x11) {
 +              dev_warn(&dev->dev, "Neponset board detected, but wrong ID: %02x\n",
 +                       readb_relaxed(d->base + WHOAMI));
 +              ret = -ENODEV;
 +              goto err_id;
 +      }
  
 -static struct platform_device *devices[] __initdata = {
 -      &neponset_device,
 -      &sa1111_device,
 -      &smc91x_device,
 -};
 +      ret = irq_alloc_descs(-1, IRQ_BOARD_START, NEP_IRQ_NR, -1);
 +      if (ret <= 0) {
 +              dev_err(&dev->dev, "unable to allocate %u irqs: %d\n",
 +                      NEP_IRQ_NR, ret);
 +              if (ret == 0)
 +                      ret = -ENOMEM;
 +              goto err_irq_alloc;
 +      }
  
 -extern void sa1110_mb_disable(void);
 +      d->irq_base = ret;
  
 -static int __init neponset_init(void)
 -{
 -      platform_driver_register(&neponset_device_driver);
 +      irq_set_chip_and_handler(d->irq_base + NEP_IRQ_SMC91X, &nochip,
 +              handle_simple_irq);
 +      set_irq_flags(d->irq_base + NEP_IRQ_SMC91X, IRQF_VALID | IRQF_PROBE);
 +      irq_set_chip_and_handler(d->irq_base + NEP_IRQ_USAR, &nochip,
 +              handle_simple_irq);
 +      set_irq_flags(d->irq_base + NEP_IRQ_USAR, IRQF_VALID | IRQF_PROBE);
 +      irq_set_chip(d->irq_base + NEP_IRQ_SA1111, &nochip);
  
 -      /*
 -       * The Neponset is only present on the Assabet machine type.
 -       */
 -      if (!machine_is_assabet())
 -              return -ENODEV;
 +      irq_set_irq_type(irq, IRQ_TYPE_EDGE_RISING);
 +      irq_set_handler_data(irq, d);
 +      irq_set_chained_handler(irq, neponset_irq_handler);
  
        /*
 -       * Ensure that the memory bus request/grant signals are setup,
 -       * and the grant is held in its inactive state, whether or not
 -       * we actually have a Neponset attached.
 +       * We would set IRQ_GPIO25 to be a wake-up IRQ, but unfortunately
 +       * something on the Neponset activates this IRQ on sleep (eth?)
         */
 +#if 0
 +      enable_irq_wake(irq);
 +#endif
 +
 +      dev_info(&dev->dev, "Neponset daughter board, providing IRQ%u-%u\n",
 +               d->irq_base, d->irq_base + NEP_IRQ_NR - 1);
 +      nep_base = d->base;
 +
 +      sa1100_register_uart_fns(&neponset_port_fns);
 +
 +      /* Ensure that the memory bus request/grant signals are setup */
        sa1110_mb_disable();
  
 -      if (!machine_has_neponset()) {
 -              printk(KERN_DEBUG "Neponset expansion board not present\n");
 -              return -ENODEV;
 -      }
 +      /* Disable GPIO 0/1 drivers so the buttons work on the Assabet */
 +      writeb_relaxed(NCR_GP01_OFF, d->base + NCR_0);
  
 -      if (WHOAMI != 0x11) {
 -              printk(KERN_WARNING "Neponset board detected, but "
 -                      "wrong ID: %02x\n", WHOAMI);
 -              return -ENODEV;
 -      }
 +      sa1111_resources[0].parent = sa1111_res;
 +      sa1111_resources[1].start = d->irq_base + NEP_IRQ_SA1111;
 +      sa1111_resources[1].end = d->irq_base + NEP_IRQ_SA1111;
 +      d->sa1111 = platform_device_register_full(&sa1111_devinfo);
 +
 +      smc91x_resources[0].parent = smc91x_res;
 +      smc91x_resources[1].parent = smc91x_res;
 +      smc91x_resources[2].start = d->irq_base + NEP_IRQ_SMC91X;
 +      smc91x_resources[2].end = d->irq_base + NEP_IRQ_SMC91X;
 +      d->smc91x = platform_device_register_full(&smc91x_devinfo);
 +
 +      platform_set_drvdata(dev, d);
  
 -      return platform_add_devices(devices, ARRAY_SIZE(devices));
 +      return 0;
 +
 + err_irq_alloc:
 + err_id:
 +      iounmap(d->base);
 + err_ioremap:
 +      kfree(d);
 + err_alloc:
 +      return ret;
  }
  
 -subsys_initcall(neponset_init);
 +static int __devexit neponset_remove(struct platform_device *dev)
 +{
 +      struct neponset_drvdata *d = platform_get_drvdata(dev);
 +      int irq = platform_get_irq(dev, 0);
 +
 +      if (!IS_ERR(d->sa1111))
 +              platform_device_unregister(d->sa1111);
 +      if (!IS_ERR(d->smc91x))
 +              platform_device_unregister(d->smc91x);
 +      irq_set_chained_handler(irq, NULL);
 +      irq_free_descs(d->irq_base, NEP_IRQ_NR);
 +      nep_base = NULL;
 +      iounmap(d->base);
 +      kfree(d);
  
 -static struct map_desc neponset_io_desc[] __initdata = {
 -      {       /* System Registers */
 -              .virtual        =  0xf3000000,
 -              .pfn            = __phys_to_pfn(0x10000000),
 -              .length         = SZ_1M,
 -              .type           = MT_DEVICE
 -      }
 +      return 0;
 +}
 +
 +#ifdef CONFIG_PM_SLEEP
 +static int neponset_suspend(struct device *dev)
 +{
 +      struct neponset_drvdata *d = dev_get_drvdata(dev);
 +
 +      d->ncr0 = readb_relaxed(d->base + NCR_0);
 +      d->mdm_ctl_0 = readb_relaxed(d->base + MDM_CTL_0);
 +
 +      return 0;
 +}
 +
 +static int neponset_resume(struct device *dev)
 +{
 +      struct neponset_drvdata *d = dev_get_drvdata(dev);
 +
 +      writeb_relaxed(d->ncr0, d->base + NCR_0);
 +      writeb_relaxed(d->mdm_ctl_0, d->base + MDM_CTL_0);
 +
 +      return 0;
 +}
 +
 +static const struct dev_pm_ops neponset_pm_ops = {
 +      .suspend_noirq = neponset_suspend,
 +      .resume_noirq = neponset_resume,
 +      .freeze_noirq = neponset_suspend,
 +      .restore_noirq = neponset_resume,
 +};
 +#define PM_OPS &neponset_pm_ops
 +#else
 +#define PM_OPS NULL
 +#endif
 +
 +static struct platform_driver neponset_device_driver = {
 +      .probe          = neponset_probe,
 +      .remove         = __devexit_p(neponset_remove),
 +      .driver         = {
 +              .name   = "neponset",
 +              .owner  = THIS_MODULE,
 +              .pm     = PM_OPS,
 +      },
  };
  
 -void __init neponset_map_io(void)
 +static int __init neponset_init(void)
  {
 -      iotable_init(neponset_io_desc, ARRAY_SIZE(neponset_io_desc));
 +      return platform_driver_register(&neponset_device_driver);
  }
 +
 +subsys_initcall(neponset_init);
- static struct map_desc neponset_io_desc[] __initdata = {
-       {       /* SA-1111 */
-               .virtual        =  0xf4000000,
-               .pfn            = __phys_to_pfn(0x40000000),
-               .length         = SZ_1M,
-               .type           = MT_DEVICE
-       }
- };
- void __init neponset_map_io(void)
- {
-       iotable_init(neponset_io_desc, ARRAY_SIZE(neponset_io_desc));
- }