Merge branch 'next-devicetree' of git://git.secretlab.ca/git/linux-2.6
authorLinus Torvalds <torvalds@linux-foundation.org>
Mon, 25 Oct 2010 15:19:14 +0000 (08:19 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Mon, 25 Oct 2010 15:19:14 +0000 (08:19 -0700)
* 'next-devicetree' of git://git.secretlab.ca/git/linux-2.6:
  mtd/m25p80: add support to parse the partitions by OF node
  of/irq: of_irq.c needs to include linux/irq.h
  of/mips: Cleanup some include directives/files.
  of/mips: Add device tree support to MIPS
  of/flattree: Eliminate need to provide early_init_dt_scan_chosen_arch
  of/device: Rework to use common platform_device_alloc() for allocating devices
  of/xsysace: Fix OF probing on little-endian systems
  of: use __be32 types for big-endian device tree data
  of/irq: remove references to NO_IRQ in drivers/of/platform.c
  of/promtree: add package-to-path support to pdt
  of/promtree: add of_pdt namespace to pdt code
  of/promtree: no longer call prom_ functions directly; use an ops structure
  of/promtree: make drivers/of/pdt.c no longer sparc-only
  sparc: break out some PROM device-tree building code out into drivers/of
  of/sparc: convert various prom_* functions to use phandle
  sparc: stop exporting openprom.h header
  powerpc, of_serial: Endianness issues setting up the serial ports
  of: MTD: Fix OF probing on little-endian systems
  of: GPIO: Fix OF probing on little-endian systems

1  2 
arch/mips/Kconfig
arch/powerpc/kernel/prom.c
arch/sparc/Kconfig
arch/sparc/mm/init_64.c
drivers/base/platform.c
drivers/block/xsysace.c
drivers/sbus/char/jsflash.c

diff --combined arch/mips/Kconfig
index 784cf822963afbee48cfafbaf0d799143aa3972b,21c75a89496aee69e95cdb318f4dbdc809b662e1..46cae2b163e4a1e6286584e28496f59d7e41d844
@@@ -13,7 -13,6 +13,7 @@@ config MIP
        select HAVE_KPROBES
        select HAVE_KRETPROBES
        select RTC_LIB if !MACH_LOONGSON
 +      select GENERIC_ATOMIC64 if !64BIT
  
  mainmenu "Linux/MIPS Kernel Configuration"
  
@@@ -881,15 -880,11 +881,15 @@@ config NO_IOPOR
  config GENERIC_ISA_DMA
        bool
        select ZONE_DMA if GENERIC_ISA_DMA_SUPPORT_BROKEN=n
 +      select ISA_DMA_API
  
  config GENERIC_ISA_DMA_SUPPORT_BROKEN
        bool
        select GENERIC_ISA_DMA
  
 +config ISA_DMA_API
 +      bool
 +
  config GENERIC_GPIO
        bool
  
@@@ -1651,16 -1646,8 +1651,16 @@@ config MIPS_MT_SM
        select SYS_SUPPORTS_SMP
        select SMP_UP
        help
 -        This is a kernel model which is also known a VSMP or lately
 -        has been marketesed into SMVP.
 +        This is a kernel model which is known a VSMP but lately has been
 +        marketesed into SMVP.
 +        Virtual SMP uses the processor's VPEs  to implement virtual
 +        processors. In currently available configuration of the 34K processor
 +        this allows for a dual processor. Both processors will share the same
 +        primary caches; each will obtain the half of the TLB for it's own
 +        exclusive use. For a layman this model can be described as similar to
 +        what Intel calls Hyperthreading.
 +
 +        For further information see http://www.linux-mips.org/wiki/34K#VSMP
  
  config MIPS_MT_SMTC
        bool "SMTC: Use all TCs on all VPEs for SMP"
        help
          This is a kernel model which is known a SMTC or lately has been
          marketesed into SMVP.
 +        is presenting the available TC's of the core as processors to Linux.
 +        On currently available 34K processors this means a Linux system will
 +        see up to 5 processors. The implementation of the SMTC kernel differs
 +        significantly from VSMP and cannot efficiently coexist in the same
 +        kernel binary so the choice between VSMP and SMTC is a compile time
 +        decision.
 +
 +        For further information see http://www.linux-mips.org/wiki/34K#SMTC
  
  endchoice
  
@@@ -2128,6 -2107,13 +2128,13 @@@ config SECCOM
  
          If unsure, say Y. Only embedded should say N here.
  
+ config USE_OF
+       bool "Flattened Device Tree support"
+       select OF
+       select OF_FLATTREE
+       help
+         Include support for flattened device tree machine descriptions.
  endmenu
  
  config LOCKDEP_SUPPORT
@@@ -2196,14 -2182,10 +2203,14 @@@ config T
        bool "TURBOchannel support"
        depends on MACH_DECSTATION
        help
 -        TurboChannel is a DEC (now Compaq (now HP)) bus for Alpha and MIPS
 -        processors.  Documentation on writing device drivers for TurboChannel
 -        is available at:
 -        <http://www.cs.arizona.edu/computer.help/policy/DIGITAL_unix/AA-PS3HD-TET1_html/TITLE.html>.
 +        TURBOchannel is a DEC (now Compaq (now HP)) bus for Alpha and MIPS
 +        processors.  TURBOchannel programming specifications are available
 +        at:
 +        <ftp://ftp.hp.com/pub/alphaserver/archive/triadd/>
 +        and:
 +        <http://www.computer-refuge.org/classiccmp/ftp.digital.com/pub/DEC/TriAdd/>
 +        Linux driver support status is documented at:
 +        <http://www.linux-mips.org/wiki/DECstation>
  
  #config ACCESSBUS
  #     bool "Access.Bus support"
index c3c6a88575441a5d68c75705a1ac68e0d130a5f7,e296aae63c607fb28e990f65033ccab1c23f4e72..9e3132db718b10115a076b0f3db09094afdb3d38
@@@ -66,7 -66,6 +66,7 @@@
  int __initdata iommu_is_off;
  int __initdata iommu_force_on;
  unsigned long tce_alloc_start, tce_alloc_end;
 +u64 ppc64_rma_size;
  #endif
  
  static int __init early_parse_mem(char *p)
@@@ -99,7 -98,7 +99,7 @@@ static void __init move_device_tree(voi
  
        if ((memory_limit && (start + size) > memory_limit) ||
                        overlaps_crashkernel(start, size)) {
 -              p = __va(memblock_alloc_base(size, PAGE_SIZE, memblock.rmo_size));
 +              p = __va(memblock_alloc(size, PAGE_SIZE));
                memcpy(p, initial_boot_params, size);
                initial_boot_params = (struct boot_param_header *)p;
                DBG("Moved device tree to 0x%p\n", p);
@@@ -364,10 -363,15 +364,15 @@@ static int __init early_init_dt_scan_cp
        return 0;
  }
  
- void __init early_init_dt_scan_chosen_arch(unsigned long node)
+ int __init early_init_dt_scan_chosen_ppc(unsigned long node, const char *uname,
+                                        int depth, void *data)
  {
        unsigned long *lprop;
  
+       /* Use common scan routine to determine if this is the chosen node */
+       if (early_init_dt_scan_chosen(node, uname, depth, data) == 0)
+               return 0;
  #ifdef CONFIG_PPC64
        /* check if iommu is forced on or off */
        if (of_get_flat_dt_prop(node, "linux,iommu-off", NULL) != NULL)
        if (lprop)
                crashk_res.end = crashk_res.start + *lprop - 1;
  #endif
+       /* break now */
+       return 1;
  }
  
  #ifdef CONFIG_PPC_PSERIES
@@@ -493,7 -500,7 +501,7 @@@ static int __init early_init_dt_scan_me
  
  void __init early_init_dt_add_memory_arch(u64 base, u64 size)
  {
 -#if defined(CONFIG_PPC64)
 +#ifdef CONFIG_PPC64
        if (iommu_is_off) {
                if (base >= 0x80000000ul)
                        return;
        }
  #endif
  
 -      memblock_add(base, size);
 -
 +      /* First MEMBLOCK added, do some special initializations */
 +      if (memstart_addr == ~(phys_addr_t)0)
 +              setup_initial_memory_limit(base, size);
        memstart_addr = min((u64)memstart_addr, base);
 +
 +      /* Add the chunk to the MEMBLOCK list */
 +      memblock_add(base, size);
  }
  
  u64 __init early_init_dt_alloc_memory_arch(u64 size, u64 align)
@@@ -660,6 -663,7 +668,6 @@@ static void __init phyp_dump_reserve_me
  static inline void __init phyp_dump_reserve_mem(void) {}
  #endif /* CONFIG_PHYP_DUMP  && CONFIG_PPC_RTAS */
  
 -
  void __init early_init_devtree(void *params)
  {
        phys_addr_t limit;
         * device-tree, including the platform type, initrd location and
         * size, TCE reserve, and more ...
         */
-       of_scan_flat_dt(early_init_dt_scan_chosen, NULL);
+       of_scan_flat_dt(early_init_dt_scan_chosen_ppc, NULL);
  
        /* Scan memory nodes and rebuild MEMBLOCKs */
        memblock_init();
 +
        of_scan_flat_dt(early_init_dt_scan_root, NULL);
        of_scan_flat_dt(early_init_dt_scan_memory_ppc, NULL);
  
diff --combined arch/sparc/Kconfig
index 3e9d31401fb24e9dd1b6b3e67add09a4ea7f1468,a06c9598c2ed2f1597ba1aaea8dc32e2c4dc8a76..8e7bafc5dd0eb412282c3c8f0ebfb1314e422cc0
@@@ -19,6 -19,7 +19,7 @@@ config SPAR
        bool
        default y
        select OF
+       select OF_PROMTREE
        select HAVE_IDE
        select HAVE_OPROFILE
        select HAVE_ARCH_KGDB if !SMP || SPARC64
        select ARCH_WANT_OPTIONAL_GPIOLIB
        select RTC_CLASS
        select RTC_DRV_M48T59
 +      select HAVE_IRQ_WORK
        select HAVE_PERF_EVENTS
        select PERF_USE_VMALLOC
        select HAVE_DMA_ATTRS
        select HAVE_DMA_API_DEBUG
 +      select HAVE_ARCH_JUMP_LABEL
  
  config SPARC32
        def_bool !64BIT
@@@ -55,7 -54,6 +56,7 @@@ config SPARC6
        select RTC_DRV_BQ4802
        select RTC_DRV_SUN4V
        select RTC_DRV_STARFIRE
 +      select HAVE_IRQ_WORK
        select HAVE_PERF_EVENTS
        select PERF_USE_VMALLOC
  
diff --combined arch/sparc/mm/init_64.c
index 4c2572773b55a330868933b633882f9520a155ba,9b020d674373d39507356e4b4a2201099d26551e..2f6ae1d1fb6b19c3475efec961812c991e417a79
@@@ -88,7 -88,7 +88,7 @@@ static void __init read_obp_memory(cons
                                   struct linux_prom64_registers *regs,
                                   int *num_ents)
  {
-       int node = prom_finddevice("/memory");
+       phandle node = prom_finddevice("/memory");
        int prop_size = prom_getproplen(node, property);
        int ents, ret, i;
  
@@@ -785,7 -785,8 +785,7 @@@ static int find_node(unsigned long addr
        return -1;
  }
  
 -static unsigned long long nid_range(unsigned long long start,
 -                                  unsigned long long end, int *nid)
 +u64 memblock_nid_range(u64 start, u64 end, int *nid)
  {
        *nid = find_node(start);
        start += PAGE_SIZE;
        return start;
  }
  #else
 -static unsigned long long nid_range(unsigned long long start,
 -                                  unsigned long long end, int *nid)
 +u64 memblock_nid_range(u64 start, u64 end, int *nid)
  {
        *nid = 0;
        return end;
@@@ -820,7 -822,8 +820,7 @@@ static void __init allocate_node_data(i
        struct pglist_data *p;
  
  #ifdef CONFIG_NEED_MULTIPLE_NODES
 -      paddr = memblock_alloc_nid(sizeof(struct pglist_data),
 -                            SMP_CACHE_BYTES, nid, nid_range);
 +      paddr = memblock_alloc_try_nid(sizeof(struct pglist_data), SMP_CACHE_BYTES, nid);
        if (!paddr) {
                prom_printf("Cannot allocate pglist_data for nid[%d]\n", nid);
                prom_halt();
        if (p->node_spanned_pages) {
                num_pages = bootmem_bootmap_pages(p->node_spanned_pages);
  
 -              paddr = memblock_alloc_nid(num_pages << PAGE_SHIFT, PAGE_SIZE, nid,
 -                                    nid_range);
 +              paddr = memblock_alloc_try_nid(num_pages << PAGE_SHIFT, PAGE_SIZE, nid);
                if (!paddr) {
                        prom_printf("Cannot allocate bootmap for nid[%d]\n",
                                  nid);
@@@ -968,19 -972,19 +968,19 @@@ int of_node_to_nid(struct device_node *
  
  static void __init add_node_ranges(void)
  {
 -      int i;
 +      struct memblock_region *reg;
  
 -      for (i = 0; i < memblock.memory.cnt; i++) {
 -              unsigned long size = memblock_size_bytes(&memblock.memory, i);
 +      for_each_memblock(memory, reg) {
 +              unsigned long size = reg->size;
                unsigned long start, end;
  
 -              start = memblock.memory.region[i].base;
 +              start = reg->base;
                end = start + size;
                while (start < end) {
                        unsigned long this_end;
                        int nid;
  
 -                      this_end = nid_range(start, end, &nid);
 +                      this_end = memblock_nid_range(start, end, &nid);
  
                        numadbg("Adding active range nid[%d] "
                                "start[%lx] end[%lx]\n",
@@@ -1277,7 -1281,7 +1277,7 @@@ static void __init bootmem_init_nonnuma
  {
        unsigned long top_of_ram = memblock_end_of_DRAM();
        unsigned long total_ram = memblock_phys_mem_size();
 -      unsigned int i;
 +      struct memblock_region *reg;
  
        numadbg("bootmem_init_nonnuma()\n");
  
  
        init_node_masks_nonnuma();
  
 -      for (i = 0; i < memblock.memory.cnt; i++) {
 -              unsigned long size = memblock_size_bytes(&memblock.memory, i);
 +      for_each_memblock(memory, reg) {
                unsigned long start_pfn, end_pfn;
  
 -              if (!size)
 +              if (!reg->size)
                        continue;
  
 -              start_pfn = memblock.memory.region[i].base >> PAGE_SHIFT;
 -              end_pfn = start_pfn + memblock_size_pages(&memblock.memory, i);
 +              start_pfn = memblock_region_memory_base_pfn(reg);
 +              end_pfn = memblock_region_memory_end_pfn(reg);
                add_active_range(0, start_pfn, end_pfn);
        }
  
@@@ -1313,7 -1318,7 +1313,7 @@@ static void __init reserve_range_in_nod
                unsigned long this_end;
                int n;
  
 -              this_end = nid_range(start, end, &n);
 +              this_end = memblock_nid_range(start, end, &n);
                if (n == nid) {
                        numadbg("      MATCH reserving range [%lx:%lx]\n",
                                start, this_end);
  
  static void __init trim_reserved_in_node(int nid)
  {
 -      int i;
 +      struct memblock_region *reg;
  
        numadbg("  trim_reserved_in_node(%d)\n", nid);
  
 -      for (i = 0; i < memblock.reserved.cnt; i++) {
 -              unsigned long start = memblock.reserved.region[i].base;
 -              unsigned long size = memblock_size_bytes(&memblock.reserved, i);
 -              unsigned long end = start + size;
 -
 -              reserve_range_in_node(nid, start, end);
 -      }
 +      for_each_memblock(reserved, reg)
 +              reserve_range_in_node(nid, reg->base, reg->base + reg->size);
  }
  
  static void __init bootmem_init_one_node(int nid)
diff --combined drivers/base/platform.c
index 3966e62ad01950921c8dd497b233642caaef4a5f,2fff59cef5051cc54366c3e11a8db0c990584d25..f051cfff18afe2e703bc6383d8b6277cdc652401
@@@ -147,6 -147,7 +147,7 @@@ static void platform_device_release(str
        struct platform_object *pa = container_of(dev, struct platform_object,
                                                  pdev.dev);
  
+       of_device_node_put(&pa->pdev.dev);
        kfree(pa->pdev.dev.platform_data);
        kfree(pa->pdev.resource);
        kfree(pa);
@@@ -192,9 -193,6 +193,9 @@@ int platform_device_add_resources(struc
  {
        struct resource *r;
  
 +      if (!res)
 +              return 0;
 +
        r = kmemdup(res, sizeof(struct resource) * num, GFP_KERNEL);
        if (r) {
                pdev->resource = r;
@@@ -218,12 -216,8 +219,12 @@@ EXPORT_SYMBOL_GPL(platform_device_add_r
  int platform_device_add_data(struct platform_device *pdev, const void *data,
                             size_t size)
  {
 -      void *d = kmemdup(data, size, GFP_KERNEL);
 +      void *d;
 +
 +      if (!data)
 +              return 0;
  
 +      d = kmemdup(data, size, GFP_KERNEL);
        if (d) {
                pdev->dev.platform_data = d;
                return 0;
@@@ -380,13 -374,17 +381,13 @@@ struct platform_device *__init_or_modul
  
        pdev->dev.parent = parent;
  
 -      if (res) {
 -              ret = platform_device_add_resources(pdev, res, num);
 -              if (ret)
 -                      goto err;
 -      }
 +      ret = platform_device_add_resources(pdev, res, num);
 +      if (ret)
 +              goto err;
  
 -      if (data) {
 -              ret = platform_device_add_data(pdev, data, size);
 -              if (ret)
 -                      goto err;
 -      }
 +      ret = platform_device_add_data(pdev, data, size);
 +      if (ret)
 +              goto err;
  
        ret = platform_device_add(pdev);
        if (ret) {
@@@ -491,12 -489,12 +492,12 @@@ int __init_or_module platform_driver_pr
         * if the probe was successful, and make sure any forced probes of
         * new devices fail.
         */
 -      spin_lock(&platform_bus_type.p->klist_drivers.k_lock);
 +      spin_lock(&drv->driver.bus->p->klist_drivers.k_lock);
        drv->probe = NULL;
        if (code == 0 && list_empty(&drv->driver.p->klist_devices.k_list))
                retval = -ENODEV;
        drv->driver.probe = platform_drv_probe_fail;
 -      spin_unlock(&platform_bus_type.p->klist_drivers.k_lock);
 +      spin_unlock(&drv->driver.bus->p->klist_drivers.k_lock);
  
        if (code != retval)
                platform_driver_unregister(drv);
@@@ -533,13 -531,17 +534,13 @@@ struct platform_device * __init_or_modu
                goto err_out;
        }
  
 -      if (res) {
 -              error = platform_device_add_resources(pdev, res, n_res);
 -              if (error)
 -                      goto err_pdev_put;
 -      }
 +      error = platform_device_add_resources(pdev, res, n_res);
 +      if (error)
 +              goto err_pdev_put;
  
 -      if (data) {
 -              error = platform_device_add_data(pdev, data, size);
 -              if (error)
 -                      goto err_pdev_put;
 -      }
 +      error = platform_device_add_data(pdev, data, size);
 +      if (error)
 +              goto err_pdev_put;
  
        error = platform_device_add(pdev);
        if (error)
@@@ -975,41 -977,6 +976,41 @@@ struct bus_type platform_bus_type = 
  };
  EXPORT_SYMBOL_GPL(platform_bus_type);
  
 +/**
 + * platform_bus_get_pm_ops() - return pointer to busses dev_pm_ops
 + *
 + * This function can be used by platform code to get the current
 + * set of dev_pm_ops functions used by the platform_bus_type.
 + */
 +const struct dev_pm_ops * __init platform_bus_get_pm_ops(void)
 +{
 +      return platform_bus_type.pm;
 +}
 +
 +/**
 + * platform_bus_set_pm_ops() - update dev_pm_ops for the platform_bus_type
 + *
 + * @pm: pointer to new dev_pm_ops struct to be used for platform_bus_type
 + *
 + * Platform code can override the dev_pm_ops methods of
 + * platform_bus_type by using this function.  It is expected that
 + * platform code will first do a platform_bus_get_pm_ops(), then
 + * kmemdup it, then customize selected methods and pass a pointer to
 + * the new struct dev_pm_ops to this function.
 + *
 + * Since platform-specific code is customizing methods for *all*
 + * devices (not just platform-specific devices) it is expected that
 + * any custom overrides of these functions will keep existing behavior
 + * and simply extend it.  For example, any customization of the
 + * runtime PM methods should continue to call the pm_generic_*
 + * functions as the default ones do in addition to the
 + * platform-specific behavior.
 + */
 +void __init platform_bus_set_pm_ops(const struct dev_pm_ops *pm)
 +{
 +      platform_bus_type.pm = pm;
 +}
 +
  int __init platform_bus_init(void)
  {
        int error;
diff --combined drivers/block/xsysace.c
index 6e968cd4893caea636246796fac124e7b34d83a6,66911d360ad6a0b1259f8ef46a4c57667bd2bec6..829161edae53034d0d97ac72a56e6e46f02346ae
@@@ -89,7 -89,7 +89,7 @@@
  #include <linux/delay.h>
  #include <linux/slab.h>
  #include <linux/blkdev.h>
 -#include <linux/smp_lock.h>
 +#include <linux/mutex.h>
  #include <linux/ata.h>
  #include <linux/hdreg.h>
  #include <linux/platform_device.h>
@@@ -214,7 -214,6 +214,7 @@@ struct ace_device 
        u16 cf_id[ATA_ID_WORDS];
  };
  
 +static DEFINE_MUTEX(xsysace_mutex);
  static int ace_major;
  
  /* ---------------------------------------------------------------------
@@@ -904,13 -903,13 +904,13 @@@ static int ace_open(struct block_devic
  
        dev_dbg(ace->dev, "ace_open() users=%i\n", ace->users + 1);
  
 -      lock_kernel();
 +      mutex_lock(&xsysace_mutex);
        spin_lock_irqsave(&ace->lock, flags);
        ace->users++;
        spin_unlock_irqrestore(&ace->lock, flags);
  
        check_disk_change(bdev);
 -      unlock_kernel();
 +      mutex_unlock(&xsysace_mutex);
  
        return 0;
  }
@@@ -923,7 -922,7 +923,7 @@@ static int ace_release(struct gendisk *
  
        dev_dbg(ace->dev, "ace_release() users=%i\n", ace->users - 1);
  
 -      lock_kernel();
 +      mutex_lock(&xsysace_mutex);
        spin_lock_irqsave(&ace->lock, flags);
        ace->users--;
        if (ace->users == 0) {
                ace_out(ace, ACE_CTRL, val & ~ACE_CTRL_LOCKREQ);
        }
        spin_unlock_irqrestore(&ace->lock, flags);
 -      unlock_kernel();
 +      mutex_unlock(&xsysace_mutex);
        return 0;
  }
  
@@@ -1225,7 -1224,8 +1225,8 @@@ ace_of_probe(struct platform_device *op
                bus_width = ACE_BUS_WIDTH_8;
  
        /* Call the bus-independant setup code */
-       return ace_alloc(&op->dev, id ? *id : 0, physaddr, irq, bus_width);
+       return ace_alloc(&op->dev, id ? be32_to_cpup(id) : 0,
+                                               physaddr, irq, bus_width);
  }
  
  static int __devexit ace_of_remove(struct platform_device *op)
index 13f48e28a1e1f3b8e4c80c73d9cfecb9eb50c077,513937160afdf28a60aabc7ad2af8166bc2f34de..a624f5af4320d4b5e7158d2be4032d1501eb5336
@@@ -27,7 -27,7 +27,7 @@@
   */
  
  #include <linux/module.h>
 -#include <linux/smp_lock.h>
 +#include <linux/mutex.h>
  #include <linux/types.h>
  #include <linux/errno.h>
  #include <linux/miscdevice.h>
@@@ -68,8 -68,6 +68,8 @@@
  #define JSF_PART_BITS  2      /* 2 bits of minors to cover JSF_NPART */
  #define JSF_PART_MASK  0x3    /* 2 bits mask */
  
 +static DEFINE_MUTEX(jsf_mutex);
 +
  /*
   * Access functions.
   * We could ioremap(), but it's easier this way.
@@@ -227,7 -225,7 +227,7 @@@ static loff_t jsf_lseek(struct file * f
  {
        loff_t ret;
  
 -      lock_kernel();
 +      mutex_lock(&jsf_mutex);
        switch (orig) {
                case 0:
                        file->f_pos = offset;
                default:
                        ret = -EINVAL;
        }
 -      unlock_kernel();
 +      mutex_unlock(&jsf_mutex);
        return ret;
  }
  
@@@ -386,18 -384,18 +386,18 @@@ static int jsf_ioctl_program(void __use
  
  static long jsf_ioctl(struct file *f, unsigned int cmd, unsigned long arg)
  {
 -      lock_kernel();
 +      mutex_lock(&jsf_mutex);
        int error = -ENOTTY;
        void __user *argp = (void __user *)arg;
  
        if (!capable(CAP_SYS_ADMIN)) {
 -              unlock_kernel();
 +              mutex_unlock(&jsf_mutex);
                return -EPERM;
        }
        switch (cmd) {
        case JSFLASH_IDENT:
                if (copy_to_user(argp, &jsf0.id, JSFIDSZ)) {
 -                      unlock_kernel();
 +                      mutex_unlock(&jsf_mutex);
                        return -EFAULT;
                }
                break;
                break;
        }
  
 -      unlock_kernel();
 +      mutex_unlock(&jsf_mutex);
        return error;
  }
  
@@@ -420,17 -418,17 +420,17 @@@ static int jsf_mmap(struct file * file
  
  static int jsf_open(struct inode * inode, struct file * filp)
  {
 -      lock_kernel();
 +      mutex_lock(&jsf_mutex);
        if (jsf0.base == 0) {
 -              unlock_kernel();
 +              mutex_unlock(&jsf_mutex);
                return -ENXIO;
        }
        if (test_and_set_bit(0, (void *)&jsf0.busy) != 0) {
 -              unlock_kernel();
 +              mutex_unlock(&jsf_mutex);
                return -EBUSY;
        }
  
 -      unlock_kernel();
 +      mutex_unlock(&jsf_mutex);
        return 0;       /* XXX What security? */
  }
  
@@@ -461,7 -459,7 +461,7 @@@ static int jsflash_init(void
  {
        int rc;
        struct jsflash *jsf;
-       int node;
+       phandle node;
        char banner[128];
        struct linux_prom_registers reg0;