Merge branch 'upstream-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jgarzi...
authorLinus Torvalds <torvalds@linux-foundation.org>
Thu, 18 Mar 2010 23:49:24 +0000 (16:49 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Thu, 18 Mar 2010 23:49:24 +0000 (16:49 -0700)
* 'upstream-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jgarzik/libata-dev:
  ahci: pp->active_link is not reliable when FBS is enabled
  ahci: use BIOS date in broken_suspend list
  ahci: add missing nv IDs

126 files changed:
Documentation/networking/Makefile
Documentation/networking/timestamping/Makefile
Documentation/networking/timestamping/timestamping.c
MAINTAINERS
drivers/acpi/video.c
drivers/atm/lanai.c
drivers/base/memory.c
drivers/char/hpet.c
drivers/gpu/drm/nouveau/nouveau_backlight.c
drivers/isdn/gigaset/capi.c
drivers/isdn/gigaset/common.c
drivers/isdn/gigaset/dummyll.c
drivers/isdn/gigaset/ev-layer.c
drivers/isdn/gigaset/gigaset.h
drivers/isdn/gigaset/i4l.c
drivers/isdn/gigaset/interface.c
drivers/isdn/hardware/eicon/message.c
drivers/isdn/hardware/mISDN/hfcmulti.c
drivers/isdn/hysdn/hysdn_boot.c
drivers/leds/Kconfig
drivers/leds/Makefile
drivers/leds/dell-led.c [new file with mode: 0644]
drivers/leds/led-class.c
drivers/leds/leds-gpio.c
drivers/leds/leds-ss4200.c
drivers/macintosh/via-pmu-backlight.c
drivers/net/benet/be_cmds.c
drivers/net/bnx2x_main.c
drivers/net/davinci_emac.c
drivers/net/e100.c
drivers/net/irda/w83977af_ir.c
drivers/net/ksz884x.c
drivers/net/myri10ge/myri10ge.c
drivers/net/ne.c
drivers/net/pppol2tp.c
drivers/net/s2io.c
drivers/net/usb/Kconfig
drivers/net/usb/Makefile
drivers/net/usb/hso.c
drivers/net/usb/smsc75xx.c [new file with mode: 0644]
drivers/net/usb/smsc75xx.h [new file with mode: 0644]
drivers/net/usb/smsc95xx.c
drivers/pcmcia/i82092.c
drivers/pcmcia/i82365.h
drivers/pcmcia/pcmcia_resource.c
drivers/pcmcia/pd6729.c
drivers/pcmcia/ti113x.h
drivers/pcmcia/vrc4171_card.c
drivers/pcmcia/yenta_socket.c
drivers/platform/x86/acer-wmi.c
drivers/platform/x86/asus-laptop.c
drivers/platform/x86/asus_acpi.c
drivers/platform/x86/classmate-laptop.c
drivers/platform/x86/compal-laptop.c
drivers/platform/x86/dell-laptop.c
drivers/platform/x86/eeepc-laptop.c
drivers/platform/x86/fujitsu-laptop.c
drivers/platform/x86/msi-laptop.c
drivers/platform/x86/msi-wmi.c
drivers/platform/x86/panasonic-laptop.c
drivers/platform/x86/sony-laptop.c
drivers/platform/x86/thinkpad_acpi.c
drivers/platform/x86/toshiba_acpi.c
drivers/s390/char/sclp_cmd.c
drivers/scsi/pcmcia/nsp_cs.c
drivers/serial/sunsab.c
drivers/staging/samsung-laptop/samsung-laptop.c
drivers/usb/misc/appledisplay.c
drivers/video/Kconfig
drivers/video/atmel_lcdfb.c
drivers/video/aty/aty128fb.c
drivers/video/aty/atyfb_base.c
drivers/video/aty/radeon_backlight.c
drivers/video/backlight/88pm860x_bl.c
drivers/video/backlight/Kconfig
drivers/video/backlight/Makefile
drivers/video/backlight/adp5520_bl.c
drivers/video/backlight/adx_bl.c
drivers/video/backlight/atmel-pwm-bl.c
drivers/video/backlight/backlight.c
drivers/video/backlight/corgi_lcd.c
drivers/video/backlight/cr_bllcd.c
drivers/video/backlight/da903x_bl.c
drivers/video/backlight/generic_bl.c
drivers/video/backlight/hp680_bl.c
drivers/video/backlight/jornada720_bl.c
drivers/video/backlight/kb3886_bl.c
drivers/video/backlight/l4f00242t03.c [new file with mode: 0644]
drivers/video/backlight/locomolcd.c
drivers/video/backlight/max8925_bl.c
drivers/video/backlight/mbp_nvidia_bl.c
drivers/video/backlight/omap1_bl.c
drivers/video/backlight/progear_bl.c
drivers/video/backlight/pwm_bl.c
drivers/video/backlight/tosa_bl.c
drivers/video/backlight/wm831x_bl.c
drivers/video/bf54x-lq043fb.c
drivers/video/bfin-t350mcqb-fb.c
drivers/video/nvidia/nv_backlight.c
drivers/video/omap2/displays/panel-taal.c
drivers/video/riva/fbdev.c
fs/jffs2/readinode.c
fs/ntfs/super.c
fs/xfs/linux-2.6/xfs_aops.c
fs/xfs/linux-2.6/xfs_buf.c
include/linux/backlight.h
include/linux/memory.h
include/linux/spi/l4f00242t03.h [new file with mode: 0644]
mm/page_cgroup.c
net/bridge/br_device.c
net/bridge/br_forward.c
net/bridge/br_input.c
net/bridge/br_multicast.c
net/bridge/br_private.h
net/core/netpoll.c
net/dccp/ipv4.c
net/dccp/ipv6.c
net/dccp/proto.c
net/ipv4/route.c
net/phonet/pn_dev.c
net/phonet/pn_netlink.c
net/tipc/ref.c
sound/oss/sequencer.c
sound/pci/hda/hda_codec.c
sound/pci/hda/hda_intel.c
sound/pci/hda/patch_realtek.c

index 6d8af1a..5aba7a3 100644 (file)
@@ -6,3 +6,5 @@ hostprogs-y := ifenslave
 
 # Tell kbuild to always build the programs
 always := $(hostprogs-y)
+
+obj-m := timestamping/
index 2a1489f..e799734 100644 (file)
@@ -1,6 +1,13 @@
-CPPFLAGS = -I../../../include
+# kbuild trick to avoid linker error. Can be omitted if a module is built.
+obj- := dummy.o
 
-timestamping: timestamping.c
+# List of programs to build
+hostprogs-y := timestamping
+
+# Tell kbuild to always build the programs
+always := $(hostprogs-y)
+
+HOSTCFLAGS_timestamping.o += -I$(objtree)/usr/include
 
 clean:
        rm -f timestamping
index bab619a..8ba82bf 100644 (file)
@@ -41,9 +41,9 @@
 #include <arpa/inet.h>
 #include <net/if.h>
 
-#include "asm/types.h"
-#include "linux/net_tstamp.h"
-#include "linux/errqueue.h"
+#include <asm/types.h>
+#include <linux/net_tstamp.h>
+#include <linux/errqueue.h>
 
 #ifndef SO_TIMESTAMPING
 # define SO_TIMESTAMPING         37
@@ -164,7 +164,7 @@ static void printpacket(struct msghdr *msg, int res,
 
        gettimeofday(&now, 0);
 
-       printf("%ld.%06ld: received %s data, %d bytes from %s, %d bytes control messages\n",
+       printf("%ld.%06ld: received %s data, %d bytes from %s, %zu bytes control messages\n",
               (long)now.tv_sec, (long)now.tv_usec,
               (recvmsg_flags & MSG_ERRQUEUE) ? "error" : "regular",
               res,
@@ -173,7 +173,7 @@ static void printpacket(struct msghdr *msg, int res,
        for (cmsg = CMSG_FIRSTHDR(msg);
             cmsg;
             cmsg = CMSG_NXTHDR(msg, cmsg)) {
-               printf("   cmsg len %d: ", cmsg->cmsg_len);
+               printf("   cmsg len %zu: ", cmsg->cmsg_len);
                switch (cmsg->cmsg_level) {
                case SOL_SOCKET:
                        printf("SOL_SOCKET ");
index 47cc449..382eaa4 100644 (file)
@@ -5214,6 +5214,21 @@ T:       git git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc-next-2.6.git
 S:     Maintained
 F:     arch/sparc/
 
+SPARC SERIAL DRIVERS
+M:     "David S. Miller" <davem@davemloft.net>
+L:     sparclinux@vger.kernel.org
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc-2.6.git
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc-next-2.6.git
+S:     Maintained
+F:     drivers/serial/suncore.c
+F:     drivers/serial/suncore.h
+F:     drivers/serial/sunhv.c
+F:     drivers/serial/sunsab.c
+F:     drivers/serial/sunsab.h
+F:     drivers/serial/sunsu.c
+F:     drivers/serial/sunzilog.c
+F:     drivers/serial/sunzilog.h
+
 SPECIALIX IO8+ MULTIPORT SERIAL CARD DRIVER
 M:     Roger Wolff <R.E.Wolff@BitWizard.nl>
 S:     Supported
index 2ff2b6a..cbe6f39 100644 (file)
@@ -998,6 +998,7 @@ static void acpi_video_device_find_cap(struct acpi_video_device *device)
        }
 
        if (acpi_video_backlight_support()) {
+               struct backlight_properties props;
                int result;
                static int count = 0;
                char *name;
@@ -1010,12 +1011,14 @@ static void acpi_video_device_find_cap(struct acpi_video_device *device)
                        return;
 
                sprintf(name, "acpi_video%d", count++);
-               device->backlight = backlight_device_register(name,
-                       NULL, device, &acpi_backlight_ops);
+               memset(&props, 0, sizeof(struct backlight_properties));
+               props.max_brightness = device->brightness->count - 3;
+               device->backlight = backlight_device_register(name, NULL, device,
+                                                             &acpi_backlight_ops,
+                                                             &props);
                kfree(name);
                if (IS_ERR(device->backlight))
                        return;
-               device->backlight->props.max_brightness = device->brightness->count-3;
 
                result = sysfs_create_link(&device->backlight->dev.kobj,
                                           &device->dev->dev.kobj, "device");
index 7fe7c32..23d9505 100644 (file)
@@ -306,11 +306,10 @@ static void vci_bitfield_iterate(struct lanai_dev *lanai,
        const unsigned long *lp,
        void (*func)(struct lanai_dev *,vci_t vci))
 {
-       vci_t vci = find_first_bit(lp, NUM_VCI);
-       while (vci < NUM_VCI) {
+       vci_t vci;
+
+       for_each_set_bit(vci, lp, NUM_VCI)
                func(lanai, vci);
-               vci = find_next_bit(lp, NUM_VCI, vci + 1);
-       }
 }
 
 /* -------------------- BUFFER  UTILITIES: */
index 2f86915..db0848e 100644 (file)
@@ -429,12 +429,16 @@ static inline int memory_fail_init(void)
  * differentiation between which *physical* devices each
  * section belongs to...
  */
+int __weak arch_get_memory_phys_device(unsigned long start_pfn)
+{
+       return 0;
+}
 
 static int add_memory_block(int nid, struct mem_section *section,
-                       unsigned long state, int phys_device,
-                       enum mem_add_context context)
+                       unsigned long state, enum mem_add_context context)
 {
        struct memory_block *mem = kzalloc(sizeof(*mem), GFP_KERNEL);
+       unsigned long start_pfn;
        int ret = 0;
 
        if (!mem)
@@ -443,7 +447,8 @@ static int add_memory_block(int nid, struct mem_section *section,
        mem->phys_index = __section_nr(section);
        mem->state = state;
        mutex_init(&mem->state_mutex);
-       mem->phys_device = phys_device;
+       start_pfn = section_nr_to_pfn(mem->phys_index);
+       mem->phys_device = arch_get_memory_phys_device(start_pfn);
 
        ret = register_memory(mem, section);
        if (!ret)
@@ -515,7 +520,7 @@ int remove_memory_block(unsigned long node_id, struct mem_section *section,
  */
 int register_new_memory(int nid, struct mem_section *section)
 {
-       return add_memory_block(nid, section, MEM_OFFLINE, 0, HOTPLUG);
+       return add_memory_block(nid, section, MEM_OFFLINE, HOTPLUG);
 }
 
 int unregister_memory_section(struct mem_section *section)
@@ -548,7 +553,7 @@ int __init memory_dev_init(void)
                if (!present_section_nr(i))
                        continue;
                err = add_memory_block(0, __nr_to_section(i), MEM_ONLINE,
-                                       0, BOOT);
+                                      BOOT);
                if (!ret)
                        ret = err;
        }
index e481c59..9c5eea3 100644 (file)
@@ -215,9 +215,7 @@ static void hpet_timer_set_irq(struct hpet_dev *devp)
        else
                v &= ~0xffff;
 
-       for (irq = find_first_bit(&v, HPET_MAX_IRQ); irq < HPET_MAX_IRQ;
-               irq = find_next_bit(&v, HPET_MAX_IRQ, 1 + irq)) {
-
+       for_each_set_bit(irq, &v, HPET_MAX_IRQ) {
                if (irq >= nr_irqs) {
                        irq = HPET_MAX_IRQ;
                        break;
index 20564f8..406228f 100644 (file)
@@ -89,19 +89,21 @@ static struct backlight_ops nv50_bl_ops = {
 
 static int nouveau_nv40_backlight_init(struct drm_device *dev)
 {
+       struct backlight_properties props;
        struct drm_nouveau_private *dev_priv = dev->dev_private;
        struct backlight_device *bd;
 
        if (!(nv_rd32(dev, NV40_PMC_BACKLIGHT) & NV40_PMC_BACKLIGHT_MASK))
                return 0;
 
+       memset(&props, 0, sizeof(struct backlight_properties));
+       props.max_brightness = 31;
        bd = backlight_device_register("nv_backlight", &dev->pdev->dev, dev,
-                                      &nv40_bl_ops);
+                                      &nv40_bl_ops, &props);
        if (IS_ERR(bd))
                return PTR_ERR(bd);
 
        dev_priv->backlight = bd;
-       bd->props.max_brightness = 31;
        bd->props.brightness = nv40_get_intensity(bd);
        backlight_update_status(bd);
 
@@ -110,19 +112,21 @@ static int nouveau_nv40_backlight_init(struct drm_device *dev)
 
 static int nouveau_nv50_backlight_init(struct drm_device *dev)
 {
+       struct backlight_properties props;
        struct drm_nouveau_private *dev_priv = dev->dev_private;
        struct backlight_device *bd;
 
        if (!nv_rd32(dev, NV50_PDISPLAY_SOR_BACKLIGHT))
                return 0;
 
+       memset(&props, 0, sizeof(struct backlight_properties));
+       props.max_brightness = 1025;
        bd = backlight_device_register("nv_backlight", &dev->pdev->dev, dev,
-                                      &nv50_bl_ops);
+                                      &nv50_bl_ops, &props);
        if (IS_ERR(bd))
                return PTR_ERR(bd);
 
        dev_priv->backlight = bd;
-       bd->props.max_brightness = 1025;
        bd->props.brightness = nv50_get_intensity(bd);
        backlight_update_status(bd);
        return 0;
index 6643d65..0220c19 100644 (file)
@@ -1301,7 +1301,7 @@ static void do_connect_req(struct gigaset_capi_ctr *iif,
        }
 
        /* check parameter: CIP Value */
-       if (cmsg->CIPValue > ARRAY_SIZE(cip2bchlc) ||
+       if (cmsg->CIPValue >= ARRAY_SIZE(cip2bchlc) ||
            (cmsg->CIPValue > 0 && cip2bchlc[cmsg->CIPValue].bc == NULL)) {
                dev_notice(cs->dev, "%s: unknown CIP value %d\n",
                           "CONNECT_REQ", cmsg->CIPValue);
@@ -2191,36 +2191,24 @@ static const struct file_operations gigaset_proc_fops = {
        .release        = single_release,
 };
 
-static struct capi_driver capi_driver_gigaset = {
-       .name           = "gigaset",
-       .revision       = "1.0",
-};
-
 /**
- * gigaset_isdn_register() - register to LL
+ * gigaset_isdn_regdev() - register device to LL
  * @cs:                device descriptor structure.
  * @isdnid:    device name.
  *
- * Called by main module to register the device with the LL.
- *
  * Return value: 1 for success, 0 for failure
  */
-int gigaset_isdn_register(struct cardstate *cs, const char *isdnid)
+int gigaset_isdn_regdev(struct cardstate *cs, const char *isdnid)
 {
        struct gigaset_capi_ctr *iif;
        int rc;
 
-       pr_info("Kernel CAPI interface\n");
-
        iif = kmalloc(sizeof(*iif), GFP_KERNEL);
        if (!iif) {
                pr_err("%s: out of memory\n", __func__);
                return 0;
        }
 
-       /* register driver with CAPI (ToDo: what for?) */
-       register_capi_driver(&capi_driver_gigaset);
-
        /* prepare controller structure */
        iif->ctr.owner         = THIS_MODULE;
        iif->ctr.driverdata    = cs;
@@ -2241,7 +2229,6 @@ int gigaset_isdn_register(struct cardstate *cs, const char *isdnid)
        rc = attach_capi_ctr(&iif->ctr);
        if (rc) {
                pr_err("attach_capi_ctr failed (%d)\n", rc);
-               unregister_capi_driver(&capi_driver_gigaset);
                kfree(iif);
                return 0;
        }
@@ -2252,17 +2239,36 @@ int gigaset_isdn_register(struct cardstate *cs, const char *isdnid)
 }
 
 /**
- * gigaset_isdn_unregister() - unregister from LL
+ * gigaset_isdn_unregdev() - unregister device from LL
  * @cs:                device descriptor structure.
- *
- * Called by main module to unregister the device from the LL.
  */
-void gigaset_isdn_unregister(struct cardstate *cs)
+void gigaset_isdn_unregdev(struct cardstate *cs)
 {
        struct gigaset_capi_ctr *iif = cs->iif;
 
        detach_capi_ctr(&iif->ctr);
        kfree(iif);
        cs->iif = NULL;
+}
+
+static struct capi_driver capi_driver_gigaset = {
+       .name           = "gigaset",
+       .revision       = "1.0",
+};
+
+/**
+ * gigaset_isdn_regdrv() - register driver to LL
+ */
+void gigaset_isdn_regdrv(void)
+{
+       pr_info("Kernel CAPI interface\n");
+       register_capi_driver(&capi_driver_gigaset);
+}
+
+/**
+ * gigaset_isdn_unregdrv() - unregister driver from LL
+ */
+void gigaset_isdn_unregdrv(void)
+{
        unregister_capi_driver(&capi_driver_gigaset);
 }
index 85de339..bdc01cb 100644 (file)
@@ -507,7 +507,7 @@ void gigaset_freecs(struct cardstate *cs)
        case 2: /* error in initcshw */
                /* Deregister from LL */
                make_invalid(cs, VALID_ID);
-               gigaset_isdn_unregister(cs);
+               gigaset_isdn_unregdev(cs);
 
                /* fall through */
        case 1: /* error when registering to LL */
@@ -769,7 +769,7 @@ struct cardstate *gigaset_initcs(struct gigaset_driver *drv, int channels,
        cs->cmdbytes = 0;
 
        gig_dbg(DEBUG_INIT, "setting up iif");
-       if (!gigaset_isdn_register(cs, modulename)) {
+       if (!gigaset_isdn_regdev(cs, modulename)) {
                pr_err("error registering ISDN device\n");
                goto error;
        }
@@ -1205,11 +1205,13 @@ static int __init gigaset_init_module(void)
                gigaset_debuglevel = DEBUG_DEFAULT;
 
        pr_info(DRIVER_DESC DRIVER_DESC_DEBUG "\n");
+       gigaset_isdn_regdrv();
        return 0;
 }
 
 static void __exit gigaset_exit_module(void)
 {
+       gigaset_isdn_unregdrv();
 }
 
 module_init(gigaset_init_module);
index 5b27c99..bd0b1ea 100644 (file)
@@ -57,12 +57,20 @@ void gigaset_isdn_stop(struct cardstate *cs)
 {
 }
 
-int gigaset_isdn_register(struct cardstate *cs, const char *isdnid)
+int gigaset_isdn_regdev(struct cardstate *cs, const char *isdnid)
 {
-       pr_info("no ISDN subsystem interface\n");
        return 1;
 }
 
-void gigaset_isdn_unregister(struct cardstate *cs)
+void gigaset_isdn_unregdev(struct cardstate *cs)
+{
+}
+
+void gigaset_isdn_regdrv(void)
+{
+       pr_info("no ISDN subsystem interface\n");
+}
+
+void gigaset_isdn_unregdrv(void)
 {
 }
index c8f89b7..206c380 100644 (file)
@@ -1258,14 +1258,10 @@ static void do_action(int action, struct cardstate *cs,
                 * note that bcs may be NULL if no B channel is free
                 */
                at_state2->ConState = 700;
-               kfree(at_state2->str_var[STR_NMBR]);
-               at_state2->str_var[STR_NMBR] = NULL;
-               kfree(at_state2->str_var[STR_ZCPN]);
-               at_state2->str_var[STR_ZCPN] = NULL;
-               kfree(at_state2->str_var[STR_ZBC]);
-               at_state2->str_var[STR_ZBC] = NULL;
-               kfree(at_state2->str_var[STR_ZHLC]);
-               at_state2->str_var[STR_ZHLC] = NULL;
+               for (i = 0; i < STR_NUM; ++i) {
+                       kfree(at_state2->str_var[i]);
+                       at_state2->str_var[i] = NULL;
+               }
                at_state2->int_var[VAR_ZCTP] = -1;
 
                spin_lock_irqsave(&cs->lock, flags);
index 1875ab8..cdd144e 100644 (file)
@@ -675,8 +675,10 @@ int gigaset_isowbuf_getbytes(struct isowbuf_t *iwb, int size);
  */
 
 /* Called from common.c for setting up/shutting down with the ISDN subsystem */
-int gigaset_isdn_register(struct cardstate *cs, const char *isdnid);
-void gigaset_isdn_unregister(struct cardstate *cs);
+void gigaset_isdn_regdrv(void);
+void gigaset_isdn_unregdrv(void);
+int gigaset_isdn_regdev(struct cardstate *cs, const char *isdnid);
+void gigaset_isdn_unregdev(struct cardstate *cs);
 
 /* Called from hardware module to indicate completion of an skb */
 void gigaset_skb_sent(struct bc_state *bcs, struct sk_buff *skb);
index f0acb9d..c22e5ac 100644 (file)
@@ -592,15 +592,13 @@ void gigaset_isdn_stop(struct cardstate *cs)
 }
 
 /**
- * gigaset_isdn_register() - register to LL
+ * gigaset_isdn_regdev() - register to LL
  * @cs:                device descriptor structure.
  * @isdnid:    device name.
  *
- * Called by main module to register the device with the LL.
- *
  * Return value: 1 for success, 0 for failure
  */
-int gigaset_isdn_register(struct cardstate *cs, const char *isdnid)
+int gigaset_isdn_regdev(struct cardstate *cs, const char *isdnid)
 {
        isdn_if *iif;
 
@@ -650,15 +648,29 @@ int gigaset_isdn_register(struct cardstate *cs, const char *isdnid)
 }
 
 /**
- * gigaset_isdn_unregister() - unregister from LL
+ * gigaset_isdn_unregdev() - unregister device from LL
  * @cs:                device descriptor structure.
- *
- * Called by main module to unregister the device from the LL.
  */
-void gigaset_isdn_unregister(struct cardstate *cs)
+void gigaset_isdn_unregdev(struct cardstate *cs)
 {
        gig_dbg(DEBUG_CMD, "sending UNLOAD");
        gigaset_i4l_cmd(cs, ISDN_STAT_UNLOAD);
        kfree(cs->iif);
        cs->iif = NULL;
 }
+
+/**
+ * gigaset_isdn_regdrv() - register driver to LL
+ */
+void gigaset_isdn_regdrv(void)
+{
+       /* nothing to do */
+}
+
+/**
+ * gigaset_isdn_unregdrv() - unregister driver from LL
+ */
+void gigaset_isdn_unregdrv(void)
+{
+       /* nothing to do */
+}
index a1bcbc2..f0dc6c9 100644 (file)
@@ -628,7 +628,6 @@ void gigaset_if_receive(struct cardstate *cs,
        if (tty == NULL)
                gig_dbg(DEBUG_IF, "receive on closed device");
        else {
-               tty_buffer_request_room(tty, len);
                tty_insert_flip_string(tty, buffer, len);
                tty_flip_buffer_push(tty);
        }
index ae89fb8..341ef17 100644 (file)
@@ -2754,7 +2754,7 @@ static byte connect_b3_req(dword Id, word Number, DIVA_CAPI_ADAPTER *a,
                     for (i = 0; i < w; i++)
                       ((T30_INFO   *)(plci->fax_connect_info_buffer))->station_id[i] = fax_parms[4].info[1+i];
                     ((T30_INFO   *)(plci->fax_connect_info_buffer))->head_line_len = 0;
-                    len = offsetof(T30_INFO, station_id) + 20;
+                    len = offsetof(T30_INFO, station_id) + T30_MAX_STATION_ID_LENGTH;
                     w = fax_parms[5].length;
                     if (w > 20)
                       w = 20;
@@ -2892,7 +2892,7 @@ static byte connect_b3_res(dword Id, word Number, DIVA_CAPI_ADAPTER *a,
     && (plci->nsf_control_bits & T30_NSF_CONTROL_BIT_ENABLE_NSF)
     && (plci->nsf_control_bits & T30_NSF_CONTROL_BIT_NEGOTIATE_RESP))
    {
-            len = offsetof(T30_INFO, station_id) + 20;
+            len = offsetof(T30_INFO, station_id) + T30_MAX_STATION_ID_LENGTH;
             if (plci->fax_connect_info_length < len)
             {
               ((T30_INFO *)(plci->fax_connect_info_buffer))->station_id_len = 0;
@@ -3802,7 +3802,7 @@ static byte manufacturer_res(dword Id, word Number, DIVA_CAPI_ADAPTER *a,
       break;
     }
     ncpi = &m_parms[1];
-    len = offsetof(T30_INFO, station_id) + 20;
+    len = offsetof(T30_INFO, station_id) + T30_MAX_STATION_ID_LENGTH;
     if (plci->fax_connect_info_length < len)
     {
       ((T30_INFO *)(plci->fax_connect_info_buffer))->station_id_len = 0;
@@ -6830,7 +6830,7 @@ static void nl_ind(PLCI *plci)
         if(((T30_INFO   *)plci->NL.RBuffer->P)->station_id_len)
         {
           plci->ncpi_buffer[len] = 20;
-          for (i = 0; i < 20; i++)
+          for (i = 0; i < T30_MAX_STATION_ID_LENGTH; i++)
             plci->ncpi_buffer[++len] = ((T30_INFO   *)plci->NL.RBuffer->P)->station_id[i];
         }
         if (((plci->NL.Ind & 0x0f) == N_DISC) || ((plci->NL.Ind & 0x0f) == N_DISC_ACK))
@@ -6844,7 +6844,7 @@ static void nl_ind(PLCI *plci)
         if ((plci->requested_options_conn | plci->requested_options | a->requested_options_table[plci->appl->Id-1])
           & ((1L << PRIVATE_FAX_SUB_SEP_PWD) | (1L << PRIVATE_FAX_NONSTANDARD)))
         {
-          i = offsetof(T30_INFO, station_id) + 20 + ((T30_INFO   *)plci->NL.RBuffer->P)->head_line_len;
+          i = offsetof(T30_INFO, station_id) + T30_MAX_STATION_ID_LENGTH + ((T30_INFO   *)plci->NL.RBuffer->P)->head_line_len;
           while (i < plci->NL.RBuffer->length)
             plci->ncpi_buffer[++len] = plci->NL.RBuffer->P[i++];
         }
@@ -8400,7 +8400,7 @@ static word add_b23(PLCI *plci, API_PARSE *bp)
         }
       }
       /* copy station id to NLC */
-      for(i=0; i<20; i++)
+      for(i=0; i < T30_MAX_STATION_ID_LENGTH; i++)
       {
         if(i<b3_config_parms[2].length)
         {
@@ -8411,29 +8411,29 @@ static word add_b23(PLCI *plci, API_PARSE *bp)
           ((T30_INFO *)&nlc[1])->station_id[i] = ' ';
         }
       }
-      ((T30_INFO *)&nlc[1])->station_id_len = 20;
+      ((T30_INFO *)&nlc[1])->station_id_len = T30_MAX_STATION_ID_LENGTH;
       /* copy head line to NLC */
       if(b3_config_parms[3].length)
       {
 
-        pos = (byte)(fax_head_line_time (&(((T30_INFO *)&nlc[1])->station_id[20])));
+        pos = (byte)(fax_head_line_time (&(((T30_INFO *)&nlc[1])->station_id[T30_MAX_STATION_ID_LENGTH])));
         if (pos != 0)
         {
           if (CAPI_MAX_DATE_TIME_LENGTH + 2 + b3_config_parms[3].length > CAPI_MAX_HEAD_LINE_SPACE)
             pos = 0;
           else
           {
-            ((T30_INFO *)&nlc[1])->station_id[20 + pos++] = ' ';
-            ((T30_INFO *)&nlc[1])->station_id[20 + pos++] = ' ';
+            nlc[1 + offsetof(T30_INFO, station_id) + T30_MAX_STATION_ID_LENGTH + pos++] = ' ';
+            nlc[1 + offsetof(T30_INFO, station_id) + T30_MAX_STATION_ID_LENGTH + pos++] = ' ';
             len = (byte)b3_config_parms[2].length;
             if (len > 20)
               len = 20;
             if (CAPI_MAX_DATE_TIME_LENGTH + 2 + len + 2 + b3_config_parms[3].length <= CAPI_MAX_HEAD_LINE_SPACE)
             {
               for (i = 0; i < len; i++)
-                ((T30_INFO *)&nlc[1])->station_id[20 + pos++] = ((byte   *)b3_config_parms[2].info)[1+i];
-              ((T30_INFO *)&nlc[1])->station_id[20 + pos++] = ' ';
-              ((T30_INFO *)&nlc[1])->station_id[20 + pos++] = ' ';
+                nlc[1 + offsetof(T30_INFO, station_id) + T30_MAX_STATION_ID_LENGTH + pos++] = ((byte   *)b3_config_parms[2].info)[1+i];
+              nlc[1 + offsetof(T30_INFO, station_id) + T30_MAX_STATION_ID_LENGTH + pos++] = ' ';
+              nlc[1 + offsetof(T30_INFO, station_id) + T30_MAX_STATION_ID_LENGTH + pos++] = ' ';
             }
           }
         }
@@ -8444,9 +8444,8 @@ static word add_b23(PLCI *plci, API_PARSE *bp)
         ((T30_INFO *)&nlc[1])->head_line_len = (byte)(pos + len);
         nlc[0] += (byte)(pos + len);
         for (i = 0; i < len; i++)
-          ((T30_INFO *)&nlc[1])->station_id[20 + pos++] = ((byte   *)b3_config_parms[3].info)[1+i];
-        }
-      else
+          nlc[1 + offsetof(T30_INFO, station_id) + T30_MAX_STATION_ID_LENGTH + pos++] =  ((byte   *)b3_config_parms[3].info)[1+i];
+      } else
         ((T30_INFO *)&nlc[1])->head_line_len = 0;
 
       plci->nsf_control_bits = 0;
@@ -8473,7 +8472,7 @@ static word add_b23(PLCI *plci, API_PARSE *bp)
             fax_control_bits |= T30_CONTROL_BIT_ACCEPT_SEL_POLLING;
           }
             len = nlc[0];
-          pos = offsetof(T30_INFO, station_id) + 20;
+          pos = offsetof(T30_INFO, station_id) + T30_MAX_STATION_ID_LENGTH;
    if (pos < plci->fax_connect_info_length)
    {
      for (i = 1 + plci->fax_connect_info_buffer[pos]; i != 0; i--)
@@ -8525,7 +8524,7 @@ static word add_b23(PLCI *plci, API_PARSE *bp)
       }
 
       PUT_WORD(&(((T30_INFO *)&nlc[1])->control_bits_low), fax_control_bits);
-      len = offsetof(T30_INFO, station_id) + 20;
+      len = offsetof(T30_INFO, station_id) + T30_MAX_STATION_ID_LENGTH;
       for (i = 0; i < len; i++)
         plci->fax_connect_info_buffer[i] = nlc[1+i];
       ((T30_INFO   *) plci->fax_connect_info_buffer)->head_line_len = 0;
index ad36df9..8affba3 100644 (file)
@@ -5265,6 +5265,8 @@ static const struct hm_map hfcm_map[] = {
 /*31*/ {VENDOR_CCD, "XHFC-4S Speech Design", 5, 4, 0, 0, 0, 0,
                HFC_IO_MODE_EMBSD, XHFC_IRQ},
 /*32*/ {VENDOR_JH, "HFC-8S (junghanns)", 8, 8, 1, 0, 0, 0, 0, 0},
+/*33*/ {VENDOR_BN, "HFC-2S Beronet Card PCIe", 4, 2, 1, 3, 0, DIP_4S, 0, 0},
+/*34*/ {VENDOR_BN, "HFC-4S Beronet Card PCIe", 4, 4, 1, 2, 0, DIP_4S, 0, 0},
 };
 
 #undef H
@@ -5300,6 +5302,10 @@ static struct pci_device_id hfmultipci_ids[] __devinitdata = {
                PCI_SUBDEVICE_ID_CCD_OV4S, 0, 0, H(28)}, /* OpenVox 4 */
        { PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC4S, PCI_VENDOR_ID_CCD,
                PCI_SUBDEVICE_ID_CCD_OV2S, 0, 0, H(29)}, /* OpenVox 2 */
+       { PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC4S, PCI_VENDOR_ID_CCD,
+               0xb761, 0, 0, H(33)}, /* BN2S PCIe */
+       { PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC4S, PCI_VENDOR_ID_CCD,
+               0xb762, 0, 0, H(34)}, /* BN4S PCIe */
 
        /* Cards with HFC-8S Chip */
        { PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC8S, PCI_VENDOR_ID_CCD,
index be787e1..4f541ef 100644 (file)
@@ -143,7 +143,7 @@ pof_handle_data(hysdn_card * card, int datlen)
                                             (boot->pof_recid == TAG_CABSDATA) ? "CABSDATA" : "ABSDATA",
                                             datlen, boot->pof_recoffset);
 
-                       if ((boot->last_error = card->writebootseq(card, boot->buf.BootBuf, datlen) < 0))
+                       if ((boot->last_error = card->writebootseq(card, boot->buf.BootBuf, datlen)) < 0)
                                return (boot->last_error);      /* error writing data */
 
                        if (boot->pof_recoffset + datlen >= boot->pof_reclen)
index e0b6431..505eb64 100644 (file)
@@ -15,6 +15,8 @@ config LEDS_CLASS
          This option enables the led sysfs class in /sys/class/leds.  You'll
          need this to do anything useful with LEDs.  If unsure, say N.
 
+if LEDS_CLASS
+
 comment "LED drivers"
 
 config LEDS_88PM860X
@@ -26,73 +28,73 @@ config LEDS_88PM860X
 
 config LEDS_ATMEL_PWM
        tristate "LED Support using Atmel PWM outputs"
-       depends on LEDS_CLASS && ATMEL_PWM
+       depends on ATMEL_PWM
        help
          This option enables support for LEDs driven using outputs
          of the dedicated PWM controller found on newer Atmel SOCs.
 
 config LEDS_LOCOMO
        tristate "LED Support for Locomo device"
-       depends on LEDS_CLASS && SHARP_LOCOMO
+       depends on SHARP_LOCOMO
        help
          This option enables support for the LEDs on Sharp Locomo.
          Zaurus models SL-5500 and SL-5600.
 
 config LEDS_MIKROTIK_RB532
        tristate "LED Support for Mikrotik Routerboard 532"
-       depends on LEDS_CLASS && MIKROTIK_RB532
+       depends on MIKROTIK_RB532
        help
          This option enables support for the so called "User LED" of
          Mikrotik's Routerboard 532.
 
 config LEDS_S3C24XX
        tristate "LED Support for Samsung S3C24XX GPIO LEDs"
-       depends on LEDS_CLASS && ARCH_S3C2410
+       depends on ARCH_S3C2410
        help
          This option enables support for LEDs connected to GPIO lines
          on Samsung S3C24XX series CPUs, such as the S3C2410 and S3C2440.
 
 config LEDS_AMS_DELTA
        tristate "LED Support for the Amstrad Delta (E3)"
-       depends on LEDS_CLASS && MACH_AMS_DELTA
+       depends on MACH_AMS_DELTA
        help
          This option enables support for the LEDs on Amstrad Delta (E3).
 
 config LEDS_NET48XX
        tristate "LED Support for Soekris net48xx series Error LED"
-       depends on LEDS_CLASS && SCx200_GPIO
+       depends on SCx200_GPIO
        help
          This option enables support for the Soekris net4801 and net4826 error
          LED.
 
 config LEDS_FSG
        tristate "LED Support for the Freecom FSG-3"
-       depends on LEDS_CLASS && MACH_FSG
+       depends on MACH_FSG
        help
          This option enables support for the LEDs on the Freecom FSG-3.
 
 config LEDS_WRAP
        tristate "LED Support for the WRAP series LEDs"
-       depends on LEDS_CLASS && SCx200_GPIO
+       depends on SCx200_GPIO
        help
          This option enables support for the PCEngines WRAP programmable LEDs.
 
 config LEDS_ALIX2
        tristate "LED Support for ALIX.2 and ALIX.3 series"
-       depends on LEDS_CLASS && X86 && EXPERIMENTAL
+       depends on X86 && !GPIO_CS5535 && !CS5535_GPIO
        help
          This option enables support for the PCEngines ALIX.2 and ALIX.3 LEDs.
          You have to set leds-alix2.force=1 for boards with Award BIOS.
 
 config LEDS_H1940
        tristate "LED Support for iPAQ H1940 device"
-       depends on LEDS_CLASS && ARCH_H1940
+       depends on ARCH_H1940
        help
          This option enables support for the LEDs on the h1940.
 
 config LEDS_COBALT_QUBE
        tristate "LED Support for the Cobalt Qube series front LED"
-       depends on LEDS_CLASS && MIPS_COBALT
+       depends on MIPS_COBALT
        help
          This option enables support for the front LED on Cobalt Qube series
 
@@ -105,7 +107,7 @@ config LEDS_COBALT_RAQ
 
 config LEDS_SUNFIRE
        tristate "LED support for SunFire servers."
-       depends on LEDS_CLASS && SPARC64
+       depends on SPARC64
        select LEDS_TRIGGERS
        help
          This option enables support for the Left, Middle, and Right
@@ -113,14 +115,14 @@ config LEDS_SUNFIRE
 
 config LEDS_HP6XX
        tristate "LED Support for the HP Jornada 6xx"
-       depends on LEDS_CLASS && SH_HP6XX
+       depends on SH_HP6XX
        help
          This option enables LED support for the handheld
          HP Jornada 620/660/680/690.
 
 config LEDS_PCA9532
        tristate "LED driver for PCA9532 dimmer"
-       depends on LEDS_CLASS && I2C && INPUT && EXPERIMENTAL
+       depends on I2C && INPUT && EXPERIMENTAL
        help
          This option enables support for NXP pca9532
          LED controller. It is generally only useful
@@ -128,7 +130,7 @@ config LEDS_PCA9532
 
 config LEDS_GPIO
        tristate "LED Support for GPIO connected LEDs"
-       depends on LEDS_CLASS && GENERIC_GPIO
+       depends on GENERIC_GPIO
        help
          This option enables support for the LEDs connected to GPIO
          outputs. To be useful the particular board must have LEDs
@@ -155,7 +157,7 @@ config LEDS_GPIO_OF
 
 config LEDS_LP3944
        tristate "LED Support for N.S. LP3944 (Fun Light) I2C chip"
-       depends on LEDS_CLASS && I2C
+       depends on I2C
        help
          This option enables support for LEDs connected to the National
          Semiconductor LP3944 Lighting Management Unit (LMU) also known as
@@ -166,7 +168,7 @@ config LEDS_LP3944
 
 config LEDS_CLEVO_MAIL
        tristate "Mail LED on Clevo notebook"
-       depends on LEDS_CLASS && X86 && SERIO_I8042 && DMI
+       depends on X86 && SERIO_I8042 && DMI
        help
          This driver makes the mail LED accessible from userspace
          programs through the leds subsystem. This LED have three
@@ -196,7 +198,7 @@ config LEDS_CLEVO_MAIL
 
 config LEDS_PCA955X
        tristate "LED Support for PCA955x I2C chips"
-       depends on LEDS_CLASS && I2C
+       depends on I2C
        help
          This option enables support for LEDs connected to PCA955x
          LED driver chips accessed via the I2C bus.  Supported
@@ -204,54 +206,54 @@ config LEDS_PCA955X
 
 config LEDS_WM831X_STATUS
        tristate "LED support for status LEDs on WM831x PMICs"
-       depends on LEDS_CLASS && MFD_WM831X
+       depends on MFD_WM831X
        help
          This option enables support for the status LEDs of the WM831x
           series of PMICs.
 
 config LEDS_WM8350
        tristate "LED Support for WM8350 AudioPlus PMIC"
-       depends on LEDS_CLASS && MFD_WM8350
+       depends on MFD_WM8350
        help
          This option enables support for LEDs driven by the Wolfson
          Microelectronics WM8350 AudioPlus PMIC.
 
 config LEDS_DA903X
        tristate "LED Support for DA9030/DA9034 PMIC"
-       depends on LEDS_CLASS && PMIC_DA903X
+       depends on PMIC_DA903X
        help
          This option enables support for on-chip LED drivers found
          on Dialog Semiconductor DA9030/DA9034 PMICs.
 
 config LEDS_DAC124S085
        tristate "LED Support for DAC124S085 SPI DAC"
-       depends on LEDS_CLASS && SPI
+       depends on SPI
        help
          This option enables support for DAC124S085 SPI DAC from NatSemi,
          which can be used to control up to four LEDs.
 
 config LEDS_PWM
        tristate "PWM driven LED Support"
-       depends on LEDS_CLASS && HAVE_PWM
+       depends on HAVE_PWM
        help
          This option enables support for pwm driven LEDs
 
 config LEDS_REGULATOR
        tristate "REGULATOR driven LED support"
-       depends on LEDS_CLASS && REGULATOR
+       depends on REGULATOR
        help
          This option enables support for regulator driven LEDs.
 
 config LEDS_BD2802
        tristate "LED driver for BD2802 RGB LED"
-       depends on LEDS_CLASS && I2C
+       depends on I2C
        help
          This option enables support for BD2802GU RGB LED driver chips
          accessed via the I2C bus.
 
 config LEDS_INTEL_SS4200
        tristate "LED driver for Intel NAS SS4200 series"
-       depends on LEDS_CLASS && PCI && DMI
+       depends on PCI && DMI
        help
          This option enables support for the Intel SS4200 series of
          Network Attached Storage servers.  You may control the hard
@@ -260,7 +262,7 @@ config LEDS_INTEL_SS4200
 
 config LEDS_LT3593
        tristate "LED driver for LT3593 controllers"
-       depends on LEDS_CLASS && GENERIC_GPIO
+       depends on GENERIC_GPIO
        help
          This option enables support for LEDs driven by a Linear Technology
          LT3593 controller. This controller uses a special one-wire pulse
@@ -268,7 +270,7 @@ config LEDS_LT3593
 
 config LEDS_ADP5520
        tristate "LED Support for ADP5520/ADP5501 PMIC"
-       depends on LEDS_CLASS && PMIC_ADP5520
+       depends on PMIC_ADP5520
        help
          This option enables support for on-chip LED drivers found
          on Analog Devices ADP5520/ADP5501 PMICs.
@@ -276,7 +278,12 @@ config LEDS_ADP5520
          To compile this driver as a module, choose M here: the module will
          be called leds-adp5520.
 
-comment "LED Triggers"
+config LEDS_DELL_NETBOOKS
+       tristate "External LED on Dell Business Netbooks"
+       depends on X86 && ACPI_WMI
+       help
+         This adds support for the Latitude 2100 and similar
+         notebooks that have an external LED.
 
 config LEDS_TRIGGERS
        bool "LED Trigger support"
@@ -285,9 +292,12 @@ config LEDS_TRIGGERS
          These triggers allow kernel events to drive the LEDs and can
          be configured via sysfs. If unsure, say Y.
 
+if LEDS_TRIGGERS
+
+comment "LED Triggers"
+
 config LEDS_TRIGGER_TIMER
        tristate "LED Timer Trigger"
-       depends on LEDS_TRIGGERS
        help
          This allows LEDs to be controlled by a programmable timer
          via sysfs. Some LED hardware can be programmed to start
@@ -298,14 +308,13 @@ config LEDS_TRIGGER_TIMER
 
 config LEDS_TRIGGER_IDE_DISK
        bool "LED IDE Disk Trigger"
-       depends on LEDS_TRIGGERS && IDE_GD_ATA
+       depends on IDE_GD_ATA
        help
          This allows LEDs to be controlled by IDE disk activity.
          If unsure, say Y.
 
 config LEDS_TRIGGER_HEARTBEAT
        tristate "LED Heartbeat Trigger"
-       depends on LEDS_TRIGGERS
        help
          This allows LEDs to be controlled by a CPU load average.
          The flash frequency is a hyperbolic function of the 1-minute
@@ -314,7 +323,6 @@ config LEDS_TRIGGER_HEARTBEAT
 
 config LEDS_TRIGGER_BACKLIGHT
        tristate "LED backlight Trigger"
-       depends on LEDS_TRIGGERS
        help
          This allows LEDs to be controlled as a backlight device: they
          turn off and on when the display is blanked and unblanked.
@@ -323,7 +331,6 @@ config LEDS_TRIGGER_BACKLIGHT
 
 config LEDS_TRIGGER_GPIO
        tristate "LED GPIO Trigger"
-       depends on LEDS_TRIGGERS
        depends on GPIOLIB
        help
          This allows LEDs to be controlled by gpio events. It's good
@@ -336,7 +343,6 @@ config LEDS_TRIGGER_GPIO
 
 config LEDS_TRIGGER_DEFAULT_ON
        tristate "LED Default ON Trigger"
-       depends on LEDS_TRIGGERS
        help
          This allows LEDs to be initialised in the ON state.
          If unsure, say Y.
@@ -344,4 +350,8 @@ config LEDS_TRIGGER_DEFAULT_ON
 comment "iptables trigger is under Netfilter config (LED target)"
        depends on LEDS_TRIGGERS
 
+endif # LEDS_TRIGGERS
+
+endif # LEDS_CLASS
+
 endif # NEW_LEDS
index d76fb32..0cd8b99 100644 (file)
@@ -34,6 +34,7 @@ obj-$(CONFIG_LEDS_REGULATOR)          += leds-regulator.o
 obj-$(CONFIG_LEDS_INTEL_SS4200)                += leds-ss4200.o
 obj-$(CONFIG_LEDS_LT3593)              += leds-lt3593.o
 obj-$(CONFIG_LEDS_ADP5520)             += leds-adp5520.o
+obj-$(CONFIG_LEDS_DELL_NETBOOKS)       += dell-led.o
 
 # LED SPI Drivers
 obj-$(CONFIG_LEDS_DAC124S085)          += leds-dac124s085.o
diff --git a/drivers/leds/dell-led.c b/drivers/leds/dell-led.c
new file mode 100644 (file)
index 0000000..ee31089
--- /dev/null
@@ -0,0 +1,200 @@
+/*
+ * dell_led.c - Dell LED Driver
+ *
+ * Copyright (C) 2010 Dell Inc.
+ * Louis Davis <louis_davis@dell.com>
+ * Jim Dailey <jim_dailey@dell.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/acpi.h>
+#include <linux/leds.h>
+
+MODULE_AUTHOR("Louis Davis/Jim Dailey");
+MODULE_DESCRIPTION("Dell LED Control Driver");
+MODULE_LICENSE("GPL");
+
+#define DELL_LED_BIOS_GUID "F6E4FE6E-909D-47cb-8BAB-C9F6F2F8D396"
+MODULE_ALIAS("wmi:" DELL_LED_BIOS_GUID);
+
+/* Error Result Codes: */
+#define INVALID_DEVICE_ID      250
+#define INVALID_PARAMETER      251
+#define INVALID_BUFFER         252
+#define INTERFACE_ERROR                253
+#define UNSUPPORTED_COMMAND    254
+#define UNSPECIFIED_ERROR      255
+
+/* Device ID */
+#define DEVICE_ID_PANEL_BACK   1
+
+/* LED Commands */
+#define CMD_LED_ON     16
+#define CMD_LED_OFF    17
+#define CMD_LED_BLINK  18
+
+struct bios_args {
+       unsigned char length;
+       unsigned char result_code;
+       unsigned char device_id;
+       unsigned char command;
+       unsigned char on_time;
+       unsigned char off_time;
+};
+
+static int dell_led_perform_fn(u8 length,
+               u8 result_code,
+               u8 device_id,
+               u8 command,
+               u8 on_time,
+               u8 off_time)
+{
+       struct bios_args *bios_return;
+       u8 return_code;
+       union acpi_object *obj;
+       struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL };
+       struct acpi_buffer input;
+       acpi_status status;
+
+       struct bios_args args;
+       args.length = length;
+       args.result_code = result_code;
+       args.device_id = device_id;
+       args.command = command;
+       args.on_time = on_time;
+       args.off_time = off_time;
+
+       input.length = sizeof(struct bios_args);
+       input.pointer = &args;
+
+       status = wmi_evaluate_method(DELL_LED_BIOS_GUID,
+               1,
+               1,
+               &input,
+               &output);
+
+       if (ACPI_FAILURE(status))
+               return status;
+
+       obj = output.pointer;
+
+       if (!obj)
+               return -EINVAL;
+       else if (obj->type != ACPI_TYPE_BUFFER) {
+               kfree(obj);
+               return -EINVAL;
+       }
+
+       bios_return = ((struct bios_args *)obj->buffer.pointer);
+       return_code = bios_return->result_code;
+
+       kfree(obj);
+
+       return return_code;
+}
+
+static int led_on(void)
+{
+       return dell_led_perform_fn(3,   /* Length of command */
+               INTERFACE_ERROR,        /* Init to  INTERFACE_ERROR */
+               DEVICE_ID_PANEL_BACK,   /* Device ID */
+               CMD_LED_ON,             /* Command */
+               0,                      /* not used */
+               0);                     /* not used */
+}
+
+static int led_off(void)
+{
+       return dell_led_perform_fn(3,   /* Length of command */
+               INTERFACE_ERROR,        /* Init to  INTERFACE_ERROR */
+               DEVICE_ID_PANEL_BACK,   /* Device ID */
+               CMD_LED_OFF,            /* Command */
+               0,                      /* not used */
+               0);                     /* not used */
+}
+
+static int led_blink(unsigned char on_eighths,
+               unsigned char off_eighths)
+{
+       return dell_led_perform_fn(5,   /* Length of command */
+               INTERFACE_ERROR,        /* Init to  INTERFACE_ERROR */
+               DEVICE_ID_PANEL_BACK,   /* Device ID */
+               CMD_LED_BLINK,          /* Command */
+               on_eighths,             /* blink on in eigths of a second */
+               off_eighths);           /* blink off in eights of a second */
+}
+
+static void dell_led_set(struct led_classdev *led_cdev,
+               enum led_brightness value)
+{
+       if (value == LED_OFF)
+               led_off();
+       else
+               led_on();
+}
+
+static int dell_led_blink(struct led_classdev *led_cdev,
+               unsigned long *delay_on,
+               unsigned long *delay_off)
+{
+       unsigned long on_eighths;
+       unsigned long off_eighths;
+
+       /* The Dell LED delay is based on 125ms intervals.
+          Need to round up to next interval. */
+
+       on_eighths = (*delay_on + 124) / 125;
+       if (0 == on_eighths)
+               on_eighths = 1;
+       if (on_eighths > 255)
+               on_eighths = 255;
+       *delay_on = on_eighths * 125;
+
+       off_eighths = (*delay_off + 124) / 125;
+       if (0 == off_eighths)
+               off_eighths = 1;
+       if (off_eighths > 255)
+               off_eighths = 255;
+       *delay_off = off_eighths * 125;
+
+       led_blink(on_eighths, off_eighths);
+
+       return 0;
+}
+
+static struct led_classdev dell_led = {
+       .name           = "dell::lid",
+       .brightness     = LED_OFF,
+       .max_brightness = 1,
+       .brightness_set = dell_led_set,
+       .blink_set      = dell_led_blink,
+       .flags          = LED_CORE_SUSPENDRESUME,
+};
+
+static int __init dell_led_init(void)
+{
+       int error = 0;
+
+       if (!wmi_has_guid(DELL_LED_BIOS_GUID))
+               return -ENODEV;
+
+       error = led_off();
+       if (error != 0)
+               return -ENODEV;
+
+       return led_classdev_register(NULL, &dell_led);
+}
+
+static void __exit dell_led_exit(void)
+{
+       led_classdev_unregister(&dell_led);
+
+       led_off();
+}
+
+module_init(dell_led_init);
+module_exit(dell_led_exit);
index 782f958..69e7d86 100644 (file)
@@ -72,11 +72,14 @@ static ssize_t led_max_brightness_show(struct device *dev,
        return sprintf(buf, "%u\n", led_cdev->max_brightness);
 }
 
-static DEVICE_ATTR(brightness, 0644, led_brightness_show, led_brightness_store);
-static DEVICE_ATTR(max_brightness, 0444, led_max_brightness_show, NULL);
+static struct device_attribute led_class_attrs[] = {
+       __ATTR(brightness, 0644, led_brightness_show, led_brightness_store),
+       __ATTR(max_brightness, 0644, led_max_brightness_show, NULL),
 #ifdef CONFIG_LEDS_TRIGGERS
-static DEVICE_ATTR(trigger, 0644, led_trigger_show, led_trigger_store);
+       __ATTR(trigger, 0644, led_trigger_show, led_trigger_store),
 #endif
+       __ATTR_NULL,
+};
 
 /**
  * led_classdev_suspend - suspend an led_classdev.
@@ -127,18 +130,11 @@ static int led_resume(struct device *dev)
  */
 int led_classdev_register(struct device *parent, struct led_classdev *led_cdev)
 {
-       int rc;
-
        led_cdev->dev = device_create(leds_class, parent, 0, led_cdev,
                                      "%s", led_cdev->name);
        if (IS_ERR(led_cdev->dev))
                return PTR_ERR(led_cdev->dev);
 
-       /* register the attributes */
-       rc = device_create_file(led_cdev->dev, &dev_attr_brightness);
-       if (rc)
-               goto err_out;
-
 #ifdef CONFIG_LEDS_TRIGGERS
        init_rwsem(&led_cdev->trigger_lock);
 #endif
@@ -150,36 +146,18 @@ int led_classdev_register(struct device *parent, struct led_classdev *led_cdev)
        if (!led_cdev->max_brightness)
                led_cdev->max_brightness = LED_FULL;
 
-       rc = device_create_file(led_cdev->dev, &dev_attr_max_brightness);
-       if (rc)
-               goto err_out_attr_max;
-
        led_update_brightness(led_cdev);
 
 #ifdef CONFIG_LEDS_TRIGGERS
-       rc = device_create_file(led_cdev->dev, &dev_attr_trigger);
-       if (rc)
-               goto err_out_led_list;
-
        led_trigger_set_default(led_cdev);
 #endif
 
-       printk(KERN_INFO "Registered led device: %s\n",
+       printk(KERN_DEBUG "Registered led device: %s\n",
                        led_cdev->name);
 
        return 0;
-
-#ifdef CONFIG_LEDS_TRIGGERS
-err_out_led_list:
-       device_remove_file(led_cdev->dev, &dev_attr_max_brightness);
-#endif
-err_out_attr_max:
-       device_remove_file(led_cdev->dev, &dev_attr_brightness);
-       list_del(&led_cdev->node);
-err_out:
-       device_unregister(led_cdev->dev);
-       return rc;
 }
+
 EXPORT_SYMBOL_GPL(led_classdev_register);
 
 /**
@@ -190,10 +168,7 @@ EXPORT_SYMBOL_GPL(led_classdev_register);
  */
 void led_classdev_unregister(struct led_classdev *led_cdev)
 {
-       device_remove_file(led_cdev->dev, &dev_attr_max_brightness);
-       device_remove_file(led_cdev->dev, &dev_attr_brightness);
 #ifdef CONFIG_LEDS_TRIGGERS
-       device_remove_file(led_cdev->dev, &dev_attr_trigger);
        down_write(&led_cdev->trigger_lock);
        if (led_cdev->trigger)
                led_trigger_set(led_cdev, NULL);
@@ -215,6 +190,7 @@ static int __init leds_init(void)
                return PTR_ERR(leds_class);
        leds_class->suspend = led_suspend;
        leds_class->resume = led_resume;
+       leds_class->dev_attrs = led_class_attrs;
        return 0;
 }
 
index e5225d2..0823e26 100644 (file)
@@ -211,7 +211,6 @@ static int __devinit of_gpio_leds_probe(struct of_device *ofdev,
                                        const struct of_device_id *match)
 {
        struct device_node *np = ofdev->node, *child;
-       struct gpio_led led;
        struct gpio_led_of_platform_data *pdata;
        int count = 0, ret;
 
@@ -226,8 +225,8 @@ static int __devinit of_gpio_leds_probe(struct of_device *ofdev,
        if (!pdata)
                return -ENOMEM;
 
-       memset(&led, 0, sizeof(led));
        for_each_child_of_node(np, child) {
+               struct gpio_led led = {};
                enum of_gpio_flags flags;
                const char *state;
 
index 97f0498..51477ec 100644 (file)
@@ -63,7 +63,7 @@ MODULE_LICENSE("GPL");
 /*
  * PCI ID of the Intel ICH7 LPC Device within which the GPIO block lives.
  */
-static struct pci_device_id ich7_lpc_pci_id[] =
+static const struct pci_device_id ich7_lpc_pci_id[] =
 {
        { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_0) },
        { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_1) },
index 4f3c447..1cec02f 100644 (file)
@@ -144,6 +144,7 @@ void pmu_backlight_set_sleep(int sleep)
 
 void __init pmu_backlight_init()
 {
+       struct backlight_properties props;
        struct backlight_device *bd;
        char name[10];
        int level, autosave;
@@ -161,13 +162,15 @@ void __init pmu_backlight_init()
 
        snprintf(name, sizeof(name), "pmubl");
 
-       bd = backlight_device_register(name, NULL, NULL, &pmu_backlight_data);
+       memset(&props, 0, sizeof(struct backlight_properties));
+       props.max_brightness = FB_BACKLIGHT_LEVELS - 1;
+       bd = backlight_device_register(name, NULL, NULL, &pmu_backlight_data,
+                                      &props);
        if (IS_ERR(bd)) {
                printk(KERN_ERR "PMU Backlight registration failed\n");
                return;
        }
        uses_pmu_bl = 1;
-       bd->props.max_brightness = FB_BACKLIGHT_LEVELS - 1;
        pmu_backlight_init_curve(0x7F, 0x46, 0x0E);
 
        level = bd->props.max_brightness;
index c592153..50e6259 100644 (file)
@@ -673,7 +673,7 @@ int be_cmd_mccq_create(struct be_adapter *adapter,
        be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
                        OPCODE_COMMON_MCC_CREATE, sizeof(*req));
 
-       req->num_pages = PAGES_4K_SPANNED(q_mem->va, q_mem->size);
+       req->num_pages = cpu_to_le16(PAGES_4K_SPANNED(q_mem->va, q_mem->size));
 
        AMAP_SET_BITS(struct amap_mcc_context, valid, ctxt, 1);
        AMAP_SET_BITS(struct amap_mcc_context, ring_size, ctxt,
index ed785a3..6c042a7 100644 (file)
@@ -893,7 +893,6 @@ static inline u16 bnx2x_tx_avail(struct bnx2x_fastpath *fp)
        u16 prod;
        u16 cons;
 
-       barrier(); /* Tell compiler that prod and cons can change */
        prod = fp->tx_bd_prod;
        cons = fp->tx_bd_cons;
 
@@ -963,7 +962,7 @@ static int bnx2x_tx_int(struct bnx2x_fastpath *fp)
         * start_xmit() will miss it and cause the queue to be stopped
         * forever.
         */
-       smp_wmb();
+       smp_mb();
 
        /* TBD need a thresh? */
        if (unlikely(netif_tx_queue_stopped(txq))) {
@@ -11429,9 +11428,12 @@ static netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev)
 
        if (unlikely(bnx2x_tx_avail(fp) < MAX_SKB_FRAGS + 3)) {
                netif_tx_stop_queue(txq);
-               /* We want bnx2x_tx_int to "see" the updated tx_bd_prod
-                  if we put Tx into XOFF state. */
+
+               /* paired memory barrier is in bnx2x_tx_int(), we have to keep
+                * ordering of set_bit() in netif_tx_stop_queue() and read of
+                * fp->bd_tx_cons */
                smp_mb();
+
                fp->eth_q_stats.driver_xoff++;
                if (bnx2x_tx_avail(fp) >= MAX_SKB_FRAGS + 3)
                        netif_tx_wake_queue(txq);
index 8bd086a..2b8edd2 100644 (file)
  *     PHY layer usage
  */
 
-/** Pending Items in this driver:
- * 1. Use Linux cache infrastcture for DMA'ed memory (dma_xxx functions)
- */
-
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
@@ -504,12 +500,6 @@ static unsigned long mdio_max_freq;
 
 /* Cache macros - Packet buffers would be from skb pool which is cached */
 #define EMAC_VIRT_NOCACHE(addr) (addr)
-#define EMAC_CACHE_INVALIDATE(addr, size) \
-       dma_cache_maint((void *)addr, size, DMA_FROM_DEVICE)
-#define EMAC_CACHE_WRITEBACK(addr, size) \
-       dma_cache_maint((void *)addr, size, DMA_TO_DEVICE)
-#define EMAC_CACHE_WRITEBACK_INVALIDATE(addr, size) \
-       dma_cache_maint((void *)addr, size, DMA_BIDIRECTIONAL)
 
 /* DM644x does not have BD's in cached memory - so no cache functions */
 #define BD_CACHE_INVALIDATE(addr, size)
@@ -1235,6 +1225,10 @@ static void emac_txch_teardown(struct emac_priv *priv, u32 ch)
        if (1 == txch->queue_active) {
                curr_bd = txch->active_queue_head;
                while (curr_bd != NULL) {
+                       dma_unmap_single(emac_dev, curr_bd->buff_ptr,
+                               curr_bd->off_b_len & EMAC_RX_BD_BUF_SIZE,
+                               DMA_TO_DEVICE);
+
                        emac_net_tx_complete(priv, (void __force *)
                                        &curr_bd->buf_token, 1, ch);
                        if (curr_bd != txch->active_queue_tail)
@@ -1327,6 +1321,11 @@ static int emac_tx_bdproc(struct emac_priv *priv, u32 ch, u32 budget)
                                txch->queue_active = 0; /* end of queue */
                        }
                }
+
+               dma_unmap_single(emac_dev, curr_bd->buff_ptr,
+                               curr_bd->off_b_len & EMAC_RX_BD_BUF_SIZE,
+                               DMA_TO_DEVICE);
+
                *tx_complete_ptr = (u32) curr_bd->buf_token;
                ++tx_complete_ptr;
                ++tx_complete_cnt;
@@ -1387,8 +1386,8 @@ static int emac_send(struct emac_priv *priv, struct emac_netpktobj *pkt, u32 ch)
 
        txch->bd_pool_head = curr_bd->next;
        curr_bd->buf_token = buf_list->buf_token;
-       /* FIXME buff_ptr = dma_map_single(... data_ptr ...) */
-       curr_bd->buff_ptr = virt_to_phys(buf_list->data_ptr);
+       curr_bd->buff_ptr = dma_map_single(&priv->ndev->dev, buf_list->data_ptr,
+                       buf_list->length, DMA_TO_DEVICE);
        curr_bd->off_b_len = buf_list->length;
        curr_bd->h_next = 0;
        curr_bd->next = NULL;
@@ -1468,7 +1467,6 @@ static int emac_dev_xmit(struct sk_buff *skb, struct net_device *ndev)
        tx_buf.length = skb->len;
        tx_buf.buf_token = (void *)skb;
        tx_buf.data_ptr = skb->data;
-       EMAC_CACHE_WRITEBACK((unsigned long)skb->data, skb->len);
        ndev->trans_start = jiffies;
        ret_code = emac_send(priv, &tx_packet, EMAC_DEF_TX_CH);
        if (unlikely(ret_code != 0)) {
@@ -1543,7 +1541,6 @@ static void *emac_net_alloc_rx_buf(struct emac_priv *priv, int buf_size,
        p_skb->dev = ndev;
        skb_reserve(p_skb, NET_IP_ALIGN);
        *data_token = (void *) p_skb;
-       EMAC_CACHE_WRITEBACK_INVALIDATE((unsigned long)p_skb->data, buf_size);
        return p_skb->data;
 }
 
@@ -1612,8 +1609,8 @@ static int emac_init_rxch(struct emac_priv *priv, u32 ch, char *param)
                /* populate the hardware descriptor */
                curr_bd->h_next = emac_virt_to_phys(rxch->active_queue_head,
                                priv);
-               /* FIXME buff_ptr = dma_map_single(... data_ptr ...) */
-               curr_bd->buff_ptr = virt_to_phys(curr_bd->data_ptr);
+               curr_bd->buff_ptr = dma_map_single(emac_dev, curr_bd->data_ptr,
+                               rxch->buf_size, DMA_FROM_DEVICE);
                curr_bd->off_b_len = rxch->buf_size;
                curr_bd->mode = EMAC_CPPI_OWNERSHIP_BIT;
 
@@ -1697,6 +1694,12 @@ static void emac_cleanup_rxch(struct emac_priv *priv, u32 ch)
                curr_bd = rxch->active_queue_head;
                while (curr_bd) {
                        if (curr_bd->buf_token) {
+                               dma_unmap_single(&priv->ndev->dev,
+                                       curr_bd->buff_ptr,
+                                       curr_bd->off_b_len
+                                               & EMAC_RX_BD_BUF_SIZE,
+                                       DMA_FROM_DEVICE);
+
                                dev_kfree_skb_any((struct sk_buff *)\
                                                  curr_bd->buf_token);
                        }
@@ -1871,8 +1874,8 @@ static void emac_addbd_to_rx_queue(struct emac_priv *priv, u32 ch,
 
        /* populate the hardware descriptor */
        curr_bd->h_next = 0;
-       /* FIXME buff_ptr = dma_map_single(... buffer ...) */
-       curr_bd->buff_ptr = virt_to_phys(buffer);
+       curr_bd->buff_ptr = dma_map_single(&priv->ndev->dev, buffer,
+                               rxch->buf_size, DMA_FROM_DEVICE);
        curr_bd->off_b_len = rxch->buf_size;
        curr_bd->mode = EMAC_CPPI_OWNERSHIP_BIT;
        curr_bd->next = NULL;
@@ -1927,7 +1930,6 @@ static int emac_net_rx_cb(struct emac_priv *priv,
        p_skb = (struct sk_buff *)net_pkt_list->pkt_token;
        /* set length of packet */
        skb_put(p_skb, net_pkt_list->pkt_length);
-       EMAC_CACHE_INVALIDATE((unsigned long)p_skb->data, p_skb->len);
        p_skb->protocol = eth_type_trans(p_skb, priv->ndev);
        netif_receive_skb(p_skb);
        priv->net_dev_stats.rx_bytes += net_pkt_list->pkt_length;
@@ -1990,6 +1992,11 @@ static int emac_rx_bdproc(struct emac_priv *priv, u32 ch, u32 budget)
                rx_buf_obj->data_ptr = (char *)curr_bd->data_ptr;
                rx_buf_obj->length = curr_bd->off_b_len & EMAC_RX_BD_BUF_SIZE;
                rx_buf_obj->buf_token = curr_bd->buf_token;
+
+               dma_unmap_single(&priv->ndev->dev, curr_bd->buff_ptr,
+                               curr_bd->off_b_len & EMAC_RX_BD_BUF_SIZE,
+                               DMA_FROM_DEVICE);
+
                curr_pkt->pkt_token = curr_pkt->buf_list->buf_token;
                curr_pkt->num_bufs = 1;
                curr_pkt->pkt_length =
@@ -2820,31 +2827,37 @@ static int __devexit davinci_emac_remove(struct platform_device *pdev)
        return 0;
 }
 
-static
-int davinci_emac_suspend(struct platform_device *pdev, pm_message_t state)
+static int davinci_emac_suspend(struct device *dev)
 {
-       struct net_device *dev = platform_get_drvdata(pdev);
+       struct platform_device *pdev = to_platform_device(dev);
+       struct net_device *ndev = platform_get_drvdata(pdev);
 
-       if (netif_running(dev))
-               emac_dev_stop(dev);
+       if (netif_running(ndev))
+               emac_dev_stop(ndev);
 
        clk_disable(emac_clk);
 
        return 0;
 }
 
-static int davinci_emac_resume(struct platform_device *pdev)
+static int davinci_emac_resume(struct device *dev)
 {
-       struct net_device *dev = platform_get_drvdata(pdev);
+       struct platform_device *pdev = to_platform_device(dev);
+       struct net_device *ndev = platform_get_drvdata(pdev);
 
        clk_enable(emac_clk);
 
-       if (netif_running(dev))
-               emac_dev_open(dev);
+       if (netif_running(ndev))
+               emac_dev_open(ndev);
 
        return 0;
 }
 
+static const struct dev_pm_ops davinci_emac_pm_ops = {
+       .suspend        = davinci_emac_suspend,
+       .resume         = davinci_emac_resume,
+};
+
 /**
  * davinci_emac_driver: EMAC platform driver structure
  */
@@ -2852,11 +2865,10 @@ static struct platform_driver davinci_emac_driver = {
        .driver = {
                .name    = "davinci_emac",
                .owner   = THIS_MODULE,
+               .pm      = &davinci_emac_pm_ops,
        },
        .probe = davinci_emac_probe,
        .remove = __devexit_p(davinci_emac_remove),
-       .suspend = davinci_emac_suspend,
-       .resume = davinci_emac_resume,
 };
 
 /**
index a26ccab..b997e57 100644 (file)
@@ -2858,7 +2858,7 @@ static int __devinit e100_probe(struct pci_dev *pdev,
        }
        nic->cbs_pool = pci_pool_create(netdev->name,
                           nic->pdev,
-                          nic->params.cbs.count * sizeof(struct cb),
+                          nic->params.cbs.max * sizeof(struct cb),
                           sizeof(u32),
                           0);
        DPRINTK(PROBE, INFO, "addr 0x%llx, irq %d, MAC addr %pM\n",
index 551810f..980625f 100644 (file)
@@ -65,7 +65,6 @@
 #undef  CONFIG_NETWINDER_TX_DMA_PROBLEMS /* Not needed */
 #define CONFIG_NETWINDER_RX_DMA_PROBLEMS /* Must have this one! */
 #endif
-#undef  CONFIG_USE_INTERNAL_TIMER  /* Just cannot make that timer work */
 #define CONFIG_USE_W977_PNP        /* Currently needed */
 #define PIO_MAX_SPEED       115200 
 
@@ -533,25 +532,6 @@ static netdev_tx_t w83977af_hard_xmit(struct sk_buff *skb,
                self->tx_buff.len = skb->len;
                
                mtt = irda_get_mtt(skb);
-#ifdef CONFIG_USE_INTERNAL_TIMER
-               if (mtt > 50) {
-                       /* Adjust for timer resolution */
-                       mtt /= 1000+1;
-
-                       /* Setup timer */
-                       switch_bank(iobase, SET4);
-                       outb(mtt & 0xff, iobase+TMRL);
-                       outb((mtt >> 8) & 0x0f, iobase+TMRH);
-                       
-                       /* Start timer */
-                       outb(IR_MSL_EN_TMR, iobase+IR_MSL);
-                       self->io.direction = IO_XMIT;
-                       
-                       /* Enable timer interrupt */
-                       switch_bank(iobase, SET0);
-                       outb(ICR_ETMRI, iobase+ICR);
-               } else {
-#endif
                        IRDA_DEBUG(4, "%s(%ld), mtt=%d\n", __func__ , jiffies, mtt);
                        if (mtt)
                                udelay(mtt);
@@ -560,9 +540,6 @@ static netdev_tx_t w83977af_hard_xmit(struct sk_buff *skb,
                        switch_bank(iobase, SET0);
                        outb(ICR_EDMAI, iobase+ICR);
                        w83977af_dma_write(self, iobase);
-#ifdef CONFIG_USE_INTERNAL_TIMER
-               }
-#endif
        } else {
                self->tx_buff.data = self->tx_buff.head;
                self->tx_buff.len = async_wrap_skb(skb, self->tx_buff.data, 
@@ -876,20 +853,7 @@ static int w83977af_dma_receive_complete(struct w83977af_ir *self)
                        /* Check if we have transferred all data to memory */
                        switch_bank(iobase, SET0);
                        if (inb(iobase+USR) & USR_RDR) {
-#ifdef CONFIG_USE_INTERNAL_TIMER
-                               /* Put this entry back in fifo */
-                               st_fifo->head--;
-                               st_fifo->len++;
-                               st_fifo->entries[st_fifo->head].status = status;
-                               st_fifo->entries[st_fifo->head].len = len;
-                               
-                               /* Restore set register */
-                               outb(set, iobase+SSR);
-                       
-                               return FALSE;   /* I'll be back! */
-#else
                                udelay(80); /* Should be enough!? */
-#endif
                        }
                                                
                        skb = dev_alloc_skb(len+1);
index 7264a3e..0f59099 100644 (file)
@@ -4899,8 +4899,10 @@ static int netdev_tx(struct sk_buff *skb, struct net_device *dev)
                        struct sk_buff *org_skb = skb;
 
                        skb = dev_alloc_skb(org_skb->len);
-                       if (!skb)
-                               return NETDEV_TX_BUSY;
+                       if (!skb) {
+                               rc = NETDEV_TX_BUSY;
+                               goto unlock;
+                       }
                        skb_copy_and_csum_dev(org_skb, skb->data);
                        org_skb->ip_summed = 0;
                        skb->len = org_skb->len;
@@ -4914,7 +4916,7 @@ static int netdev_tx(struct sk_buff *skb, struct net_device *dev)
                netif_stop_queue(dev);
                rc = NETDEV_TX_BUSY;
        }
-
+unlock:
        spin_unlock_irq(&hw_priv->hwlock);
 
        return rc;
index 676c513..e84dd3e 100644 (file)
@@ -3687,7 +3687,6 @@ static void myri10ge_probe_slices(struct myri10ge_priv *mgp)
        if (status != 0) {
                dev_err(&mgp->pdev->dev, "failed reset\n");
                goto abort_with_fw;
-               return;
        }
 
        mgp->max_intr_slots = cmd.data0 / sizeof(struct mcp_slot);
index 992dbff..f4347f8 100644 (file)
@@ -142,7 +142,7 @@ bad_clone_list[] __initdata = {
     {"PCM-4823", "PCM-4823", {0x00, 0xc0, 0x6c}}, /* Broken Advantech MoBo */
     {"REALTEK", "RTL8019", {0x00, 0x00, 0xe8}}, /* no-name with Realtek chip */
 #ifdef CONFIG_MACH_TX49XX
-    {"RBHMA4X00-RTL8019", "RBHMA4X00/RTL8019", {0x00, 0x60, 0x0a}},  /* Toshiba built-in */
+    {"RBHMA4X00-RTL8019", "RBHMA4X00-RTL8019", {0x00, 0x60, 0x0a}},  /* Toshiba built-in */
 #endif
     {"LCS-8834", "LCS-8836", {0x04, 0x04, 0x37}}, /* ShinyNet (SET) */
     {NULL,}
index 9fbb2eb..449a982 100644 (file)
@@ -756,6 +756,7 @@ static int pppol2tp_recv_core(struct sock *sock, struct sk_buff *skb)
 
        /* Try to dequeue as many skbs from reorder_q as we can. */
        pppol2tp_recv_dequeue(session);
+       sock_put(sock);
 
        return 0;
 
@@ -772,6 +773,7 @@ discard_bad_csum:
        UDP_INC_STATS_USER(&init_net, UDP_MIB_INERRORS, 0);
        tunnel->stats.rx_errors++;
        kfree_skb(skb);
+       sock_put(sock);
 
        return 0;
 
@@ -1180,7 +1182,8 @@ static int pppol2tp_xmit(struct ppp_channel *chan, struct sk_buff *skb)
        /* Calculate UDP checksum if configured to do so */
        if (sk_tun->sk_no_check == UDP_CSUM_NOXMIT)
                skb->ip_summed = CHECKSUM_NONE;
-       else if (!(skb_dst(skb)->dev->features & NETIF_F_V4_CSUM)) {
+       else if ((skb_dst(skb) && skb_dst(skb)->dev) &&
+                (!(skb_dst(skb)->dev->features & NETIF_F_V4_CSUM))) {
                skb->ip_summed = CHECKSUM_COMPLETE;
                csum = skb_checksum(skb, 0, udp_len, 0);
                uh->check = csum_tcpudp_magic(inet->inet_saddr,
@@ -1661,6 +1664,7 @@ static int pppol2tp_connect(struct socket *sock, struct sockaddr *uservaddr,
                if (tunnel_sock == NULL)
                        goto end;
 
+               sock_hold(tunnel_sock);
                tunnel = tunnel_sock->sk_user_data;
        } else {
                tunnel = pppol2tp_tunnel_find(sock_net(sk), sp->pppol2tp.s_tunnel);
index df70657..2eb7f8a 100644 (file)
@@ -5819,10 +5819,8 @@ static void s2io_vpd_read(struct s2io_nic *nic)
                }
        }
 
-       if ((!fail) && (vpd_data[1] < VPD_STRING_LEN)) {
-               memset(nic->product_name, 0, vpd_data[1]);
+       if ((!fail) && (vpd_data[1] < VPD_STRING_LEN))
                memcpy(nic->product_name, &vpd_data[3], vpd_data[1]);
-       }
        kfree(vpd_data);
        swstats->mem_freed += 256;
 }
index 32d9356..ba56ce4 100644 (file)
@@ -204,6 +204,14 @@ config USB_NET_DM9601
          This option adds support for Davicom DM9601 based USB 1.1
          10/100 Ethernet adapters.
 
+config USB_NET_SMSC75XX
+       tristate "SMSC LAN75XX based USB 2.0 gigabit ethernet devices"
+       depends on USB_USBNET
+       select CRC32
+       help
+         This option adds support for SMSC LAN95XX based USB 2.0
+         Gigabit Ethernet adapters.
+
 config USB_NET_SMSC95XX
        tristate "SMSC LAN95XX based USB 2.0 10/100 ethernet devices"
        depends on USB_USBNET
index e17afb7..82ea629 100644 (file)
@@ -11,6 +11,7 @@ obj-$(CONFIG_USB_NET_AX8817X) += asix.o
 obj-$(CONFIG_USB_NET_CDCETHER) += cdc_ether.o
 obj-$(CONFIG_USB_NET_CDC_EEM)  += cdc_eem.o
 obj-$(CONFIG_USB_NET_DM9601)   += dm9601.o
+obj-$(CONFIG_USB_NET_SMSC75XX) += smsc75xx.o
 obj-$(CONFIG_USB_NET_SMSC95XX) += smsc95xx.o
 obj-$(CONFIG_USB_NET_GL620A)   += gl620a.o
 obj-$(CONFIG_USB_NET_NET1080)  += net1080.o
index 6895f15..be0cc99 100644 (file)
@@ -1155,9 +1155,6 @@ static void _hso_serial_set_termios(struct tty_struct *tty,
 static void hso_resubmit_rx_bulk_urb(struct hso_serial *serial, struct urb *urb)
 {
        int result;
-#ifdef CONFIG_HSO_AUTOPM
-       usb_mark_last_busy(urb->dev);
-#endif
        /* We are done with this URB, resubmit it. Prep the USB to wait for
         * another frame */
        usb_fill_bulk_urb(urb, serial->parent->usb,
diff --git a/drivers/net/usb/smsc75xx.c b/drivers/net/usb/smsc75xx.c
new file mode 100644 (file)
index 0000000..300e3e7
--- /dev/null
@@ -0,0 +1,1288 @@
+ /***************************************************************************
+ *
+ * Copyright (C) 2007-2010 SMSC
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ *****************************************************************************/
+
+#include <linux/module.h>
+#include <linux/kmod.h>
+#include <linux/init.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/ethtool.h>
+#include <linux/mii.h>
+#include <linux/usb.h>
+#include <linux/crc32.h>
+#include <linux/usb/usbnet.h>
+#include "smsc75xx.h"
+
+#define SMSC_CHIPNAME                  "smsc75xx"
+#define SMSC_DRIVER_VERSION            "1.0.0"
+#define HS_USB_PKT_SIZE                        (512)
+#define FS_USB_PKT_SIZE                        (64)
+#define DEFAULT_HS_BURST_CAP_SIZE      (16 * 1024 + 5 * HS_USB_PKT_SIZE)
+#define DEFAULT_FS_BURST_CAP_SIZE      (6 * 1024 + 33 * FS_USB_PKT_SIZE)
+#define DEFAULT_BULK_IN_DELAY          (0x00002000)
+#define MAX_SINGLE_PACKET_SIZE         (9000)
+#define LAN75XX_EEPROM_MAGIC           (0x7500)
+#define EEPROM_MAC_OFFSET              (0x01)
+#define DEFAULT_TX_CSUM_ENABLE         (true)
+#define DEFAULT_RX_CSUM_ENABLE         (true)
+#define DEFAULT_TSO_ENABLE             (true)
+#define SMSC75XX_INTERNAL_PHY_ID       (1)
+#define SMSC75XX_TX_OVERHEAD           (8)
+#define MAX_RX_FIFO_SIZE               (20 * 1024)
+#define MAX_TX_FIFO_SIZE               (12 * 1024)
+#define USB_VENDOR_ID_SMSC             (0x0424)
+#define USB_PRODUCT_ID_LAN7500         (0x7500)
+#define USB_PRODUCT_ID_LAN7505         (0x7505)
+
+#define check_warn(ret, fmt, args...) \
+       ({ if (ret < 0) netdev_warn(dev->net, fmt, ##args); })
+
+#define check_warn_return(ret, fmt, args...) \
+       ({ if (ret < 0) { netdev_warn(dev->net, fmt, ##args); return ret; } })
+
+#define check_warn_goto_done(ret, fmt, args...) \
+       ({ if (ret < 0) { netdev_warn(dev->net, fmt, ##args); goto done; } })
+
+struct smsc75xx_priv {
+       struct usbnet *dev;
+       u32 rfe_ctl;
+       u32 multicast_hash_table[DP_SEL_VHF_HASH_LEN];
+       bool use_rx_csum;
+       struct mutex dataport_mutex;
+       spinlock_t rfe_ctl_lock;
+       struct work_struct set_multicast;
+};
+
+struct usb_context {
+       struct usb_ctrlrequest req;
+       struct usbnet *dev;
+};
+
+static int turbo_mode = true;
+module_param(turbo_mode, bool, 0644);
+MODULE_PARM_DESC(turbo_mode, "Enable multiple frames per Rx transaction");
+
+static int __must_check smsc75xx_read_reg(struct usbnet *dev, u32 index,
+                                         u32 *data)
+{
+       u32 *buf = kmalloc(4, GFP_KERNEL);
+       int ret;
+
+       BUG_ON(!dev);
+
+       if (!buf)
+               return -ENOMEM;
+
+       ret = usb_control_msg(dev->udev, usb_rcvctrlpipe(dev->udev, 0),
+               USB_VENDOR_REQUEST_READ_REGISTER,
+               USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+               00, index, buf, 4, USB_CTRL_GET_TIMEOUT);
+
+       if (unlikely(ret < 0))
+               netdev_warn(dev->net,
+                       "Failed to read register index 0x%08x", index);
+
+       le32_to_cpus(buf);
+       *data = *buf;
+       kfree(buf);
+
+       return ret;
+}
+
+static int __must_check smsc75xx_write_reg(struct usbnet *dev, u32 index,
+                                          u32 data)
+{
+       u32 *buf = kmalloc(4, GFP_KERNEL);
+       int ret;
+
+       BUG_ON(!dev);
+
+       if (!buf)
+               return -ENOMEM;
+
+       *buf = data;
+       cpu_to_le32s(buf);
+
+       ret = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, 0),
+               USB_VENDOR_REQUEST_WRITE_REGISTER,
+               USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+               00, index, buf, 4, USB_CTRL_SET_TIMEOUT);
+
+       if (unlikely(ret < 0))
+               netdev_warn(dev->net,
+                       "Failed to write register index 0x%08x", index);
+
+       kfree(buf);
+
+       return ret;
+}
+
+/* Loop until the read is completed with timeout
+ * called with phy_mutex held */
+static int smsc75xx_phy_wait_not_busy(struct usbnet *dev)
+{
+       unsigned long start_time = jiffies;
+       u32 val;
+       int ret;
+
+       do {
+               ret = smsc75xx_read_reg(dev, MII_ACCESS, &val);
+               check_warn_return(ret, "Error reading MII_ACCESS");
+
+               if (!(val & MII_ACCESS_BUSY))
+                       return 0;
+       } while (!time_after(jiffies, start_time + HZ));
+
+       return -EIO;
+}
+
+static int smsc75xx_mdio_read(struct net_device *netdev, int phy_id, int idx)
+{
+       struct usbnet *dev = netdev_priv(netdev);
+       u32 val, addr;
+       int ret;
+
+       mutex_lock(&dev->phy_mutex);
+
+       /* confirm MII not busy */
+       ret = smsc75xx_phy_wait_not_busy(dev);
+       check_warn_goto_done(ret, "MII is busy in smsc75xx_mdio_read");
+
+       /* set the address, index & direction (read from PHY) */
+       phy_id &= dev->mii.phy_id_mask;
+       idx &= dev->mii.reg_num_mask;
+       addr = ((phy_id << MII_ACCESS_PHY_ADDR_SHIFT) & MII_ACCESS_PHY_ADDR)
+               | ((idx << MII_ACCESS_REG_ADDR_SHIFT) & MII_ACCESS_REG_ADDR)
+               | MII_ACCESS_READ;
+       ret = smsc75xx_write_reg(dev, MII_ACCESS, addr);
+       check_warn_goto_done(ret, "Error writing MII_ACCESS");
+
+       ret = smsc75xx_phy_wait_not_busy(dev);
+       check_warn_goto_done(ret, "Timed out reading MII reg %02X", idx);
+
+       ret = smsc75xx_read_reg(dev, MII_DATA, &val);
+       check_warn_goto_done(ret, "Error reading MII_DATA");
+
+       ret = (u16)(val & 0xFFFF);
+
+done:
+       mutex_unlock(&dev->phy_mutex);
+       return ret;
+}
+
+static void smsc75xx_mdio_write(struct net_device *netdev, int phy_id, int idx,
+                               int regval)
+{
+       struct usbnet *dev = netdev_priv(netdev);
+       u32 val, addr;
+       int ret;
+
+       mutex_lock(&dev->phy_mutex);
+
+       /* confirm MII not busy */
+       ret = smsc75xx_phy_wait_not_busy(dev);
+       check_warn_goto_done(ret, "MII is busy in smsc75xx_mdio_write");
+
+       val = regval;
+       ret = smsc75xx_write_reg(dev, MII_DATA, val);
+       check_warn_goto_done(ret, "Error writing MII_DATA");
+
+       /* set the address, index & direction (write to PHY) */
+       phy_id &= dev->mii.phy_id_mask;
+       idx &= dev->mii.reg_num_mask;
+       addr = ((phy_id << MII_ACCESS_PHY_ADDR_SHIFT) & MII_ACCESS_PHY_ADDR)
+               | ((idx << MII_ACCESS_REG_ADDR_SHIFT) & MII_ACCESS_REG_ADDR)
+               | MII_ACCESS_WRITE;
+       ret = smsc75xx_write_reg(dev, MII_ACCESS, addr);
+       check_warn_goto_done(ret, "Error writing MII_ACCESS");
+
+       ret = smsc75xx_phy_wait_not_busy(dev);
+       check_warn_goto_done(ret, "Timed out writing MII reg %02X", idx);
+
+done:
+       mutex_unlock(&dev->phy_mutex);
+}
+
+static int smsc75xx_wait_eeprom(struct usbnet *dev)
+{
+       unsigned long start_time = jiffies;
+       u32 val;
+       int ret;
+
+       do {
+               ret = smsc75xx_read_reg(dev, E2P_CMD, &val);
+               check_warn_return(ret, "Error reading E2P_CMD");
+
+               if (!(val & E2P_CMD_BUSY) || (val & E2P_CMD_TIMEOUT))
+                       break;
+               udelay(40);
+       } while (!time_after(jiffies, start_time + HZ));
+
+       if (val & (E2P_CMD_TIMEOUT | E2P_CMD_BUSY)) {
+               netdev_warn(dev->net, "EEPROM read operation timeout");
+               return -EIO;
+       }
+
+       return 0;
+}
+
+static int smsc75xx_eeprom_confirm_not_busy(struct usbnet *dev)
+{
+       unsigned long start_time = jiffies;
+       u32 val;
+       int ret;
+
+       do {
+               ret = smsc75xx_read_reg(dev, E2P_CMD, &val);
+               check_warn_return(ret, "Error reading E2P_CMD");
+
+               if (!(val & E2P_CMD_BUSY))
+                       return 0;
+
+               udelay(40);
+       } while (!time_after(jiffies, start_time + HZ));
+
+       netdev_warn(dev->net, "EEPROM is busy");
+       return -EIO;
+}
+
+static int smsc75xx_read_eeprom(struct usbnet *dev, u32 offset, u32 length,
+                               u8 *data)
+{
+       u32 val;
+       int i, ret;
+
+       BUG_ON(!dev);
+       BUG_ON(!data);
+
+       ret = smsc75xx_eeprom_confirm_not_busy(dev);
+       if (ret)
+               return ret;
+
+       for (i = 0; i < length; i++) {
+               val = E2P_CMD_BUSY | E2P_CMD_READ | (offset & E2P_CMD_ADDR);
+               ret = smsc75xx_write_reg(dev, E2P_CMD, val);
+               check_warn_return(ret, "Error writing E2P_CMD");
+
+               ret = smsc75xx_wait_eeprom(dev);
+               if (ret < 0)
+                       return ret;
+
+               ret = smsc75xx_read_reg(dev, E2P_DATA, &val);
+               check_warn_return(ret, "Error reading E2P_DATA");
+
+               data[i] = val & 0xFF;
+               offset++;
+       }
+
+       return 0;
+}
+
+static int smsc75xx_write_eeprom(struct usbnet *dev, u32 offset, u32 length,
+                                u8 *data)
+{
+       u32 val;
+       int i, ret;
+
+       BUG_ON(!dev);
+       BUG_ON(!data);
+
+       ret = smsc75xx_eeprom_confirm_not_busy(dev);
+       if (ret)
+               return ret;
+
+       /* Issue write/erase enable command */
+       val = E2P_CMD_BUSY | E2P_CMD_EWEN;
+       ret = smsc75xx_write_reg(dev, E2P_CMD, val);
+       check_warn_return(ret, "Error writing E2P_CMD");
+
+       ret = smsc75xx_wait_eeprom(dev);
+       if (ret < 0)
+               return ret;
+
+       for (i = 0; i < length; i++) {
+
+               /* Fill data register */
+               val = data[i];
+               ret = smsc75xx_write_reg(dev, E2P_DATA, val);
+               check_warn_return(ret, "Error writing E2P_DATA");
+
+               /* Send "write" command */
+               val = E2P_CMD_BUSY | E2P_CMD_WRITE | (offset & E2P_CMD_ADDR);
+               ret = smsc75xx_write_reg(dev, E2P_CMD, val);
+               check_warn_return(ret, "Error writing E2P_CMD");
+
+               ret = smsc75xx_wait_eeprom(dev);
+               if (ret < 0)
+                       return ret;
+
+               offset++;
+       }
+
+       return 0;
+}
+
+static int smsc75xx_dataport_wait_not_busy(struct usbnet *dev)
+{
+       int i, ret;
+
+       for (i = 0; i < 100; i++) {
+               u32 dp_sel;
+               ret = smsc75xx_read_reg(dev, DP_SEL, &dp_sel);
+               check_warn_return(ret, "Error reading DP_SEL");
+
+               if (dp_sel & DP_SEL_DPRDY)
+                       return 0;
+
+               udelay(40);
+       }
+
+       netdev_warn(dev->net, "smsc75xx_dataport_wait_not_busy timed out");
+
+       return -EIO;
+}
+
+static int smsc75xx_dataport_write(struct usbnet *dev, u32 ram_select, u32 addr,
+                                  u32 length, u32 *buf)
+{
+       struct smsc75xx_priv *pdata = (struct smsc75xx_priv *)(dev->data[0]);
+       u32 dp_sel;
+       int i, ret;
+
+       mutex_lock(&pdata->dataport_mutex);
+
+       ret = smsc75xx_dataport_wait_not_busy(dev);
+       check_warn_goto_done(ret, "smsc75xx_dataport_write busy on entry");
+
+       ret = smsc75xx_read_reg(dev, DP_SEL, &dp_sel);
+       check_warn_goto_done(ret, "Error reading DP_SEL");
+
+       dp_sel &= ~DP_SEL_RSEL;
+       dp_sel |= ram_select;
+       ret = smsc75xx_write_reg(dev, DP_SEL, dp_sel);
+       check_warn_goto_done(ret, "Error writing DP_SEL");
+
+       for (i = 0; i < length; i++) {
+               ret = smsc75xx_write_reg(dev, DP_ADDR, addr + i);
+               check_warn_goto_done(ret, "Error writing DP_ADDR");
+
+               ret = smsc75xx_write_reg(dev, DP_DATA, buf[i]);
+               check_warn_goto_done(ret, "Error writing DP_DATA");
+
+               ret = smsc75xx_write_reg(dev, DP_CMD, DP_CMD_WRITE);
+               check_warn_goto_done(ret, "Error writing DP_CMD");
+
+               ret = smsc75xx_dataport_wait_not_busy(dev);
+               check_warn_goto_done(ret, "smsc75xx_dataport_write timeout");
+       }
+
+done:
+       mutex_unlock(&pdata->dataport_mutex);
+       return ret;
+}
+
+/* returns hash bit number for given MAC address */
+static u32 smsc75xx_hash(char addr[ETH_ALEN])
+{
+       return (ether_crc(ETH_ALEN, addr) >> 23) & 0x1ff;
+}
+
+static void smsc75xx_deferred_multicast_write(struct work_struct *param)
+{
+       struct smsc75xx_priv *pdata =
+               container_of(param, struct smsc75xx_priv, set_multicast);
+       struct usbnet *dev = pdata->dev;
+       int ret;
+
+       netif_dbg(dev, drv, dev->net, "deferred multicast write 0x%08x",
+               pdata->rfe_ctl);
+
+       smsc75xx_dataport_write(dev, DP_SEL_VHF, DP_SEL_VHF_VLAN_LEN,
+               DP_SEL_VHF_HASH_LEN, pdata->multicast_hash_table);
+
+       ret = smsc75xx_write_reg(dev, RFE_CTL, pdata->rfe_ctl);
+       check_warn(ret, "Error writing RFE_CRL");
+}
+
+static void smsc75xx_set_multicast(struct net_device *netdev)
+{
+       struct usbnet *dev = netdev_priv(netdev);
+       struct smsc75xx_priv *pdata = (struct smsc75xx_priv *)(dev->data[0]);
+       unsigned long flags;
+       int i;
+
+       spin_lock_irqsave(&pdata->rfe_ctl_lock, flags);
+
+       pdata->rfe_ctl &=
+               ~(RFE_CTL_AU | RFE_CTL_AM | RFE_CTL_DPF | RFE_CTL_MHF);
+       pdata->rfe_ctl |= RFE_CTL_AB;
+
+       for (i = 0; i < DP_SEL_VHF_HASH_LEN; i++)
+               pdata->multicast_hash_table[i] = 0;
+
+       if (dev->net->flags & IFF_PROMISC) {
+               netif_dbg(dev, drv, dev->net, "promiscuous mode enabled");
+               pdata->rfe_ctl |= RFE_CTL_AM | RFE_CTL_AU;
+       } else if (dev->net->flags & IFF_ALLMULTI) {
+               netif_dbg(dev, drv, dev->net, "receive all multicast enabled");
+               pdata->rfe_ctl |= RFE_CTL_AM | RFE_CTL_DPF;
+       } else if (!netdev_mc_empty(dev->net)) {
+               struct dev_mc_list *mc_list;
+
+               netif_dbg(dev, drv, dev->net, "receive multicast hash filter");
+
+               pdata->rfe_ctl |= RFE_CTL_MHF | RFE_CTL_DPF;
+
+               netdev_for_each_mc_addr(mc_list, netdev) {
+                       u32 bitnum = smsc75xx_hash(mc_list->dmi_addr);
+                       pdata->multicast_hash_table[bitnum / 32] |=
+                               (1 << (bitnum % 32));
+               }
+       } else {
+               netif_dbg(dev, drv, dev->net, "receive own packets only");
+               pdata->rfe_ctl |= RFE_CTL_DPF;
+       }
+
+       spin_unlock_irqrestore(&pdata->rfe_ctl_lock, flags);
+
+       /* defer register writes to a sleepable context */
+       schedule_work(&pdata->set_multicast);
+}
+
+static int smsc75xx_update_flowcontrol(struct usbnet *dev, u8 duplex,
+                                           u16 lcladv, u16 rmtadv)
+{
+       u32 flow = 0, fct_flow = 0;
+       int ret;
+
+       if (duplex == DUPLEX_FULL) {
+               u8 cap = mii_resolve_flowctrl_fdx(lcladv, rmtadv);
+
+               if (cap & FLOW_CTRL_TX) {
+                       flow = (FLOW_TX_FCEN | 0xFFFF);
+                       /* set fct_flow thresholds to 20% and 80% */
+                       fct_flow = (8 << 8) | 32;
+               }
+
+               if (cap & FLOW_CTRL_RX)
+                       flow |= FLOW_RX_FCEN;
+
+               netif_dbg(dev, link, dev->net, "rx pause %s, tx pause %s",
+                       (cap & FLOW_CTRL_RX ? "enabled" : "disabled"),
+                       (cap & FLOW_CTRL_TX ? "enabled" : "disabled"));
+       } else {
+               netif_dbg(dev, link, dev->net, "half duplex");
+       }
+
+       ret = smsc75xx_write_reg(dev, FLOW, flow);
+       check_warn_return(ret, "Error writing FLOW");
+
+       ret = smsc75xx_write_reg(dev, FCT_FLOW, fct_flow);
+       check_warn_return(ret, "Error writing FCT_FLOW");
+
+       return 0;
+}
+
+static int smsc75xx_link_reset(struct usbnet *dev)
+{
+       struct mii_if_info *mii = &dev->mii;
+       struct ethtool_cmd ecmd;
+       u16 lcladv, rmtadv;
+       int ret;
+
+       /* clear interrupt status */
+       ret = smsc75xx_mdio_read(dev->net, mii->phy_id, PHY_INT_SRC);
+       check_warn_return(ret, "Error reading PHY_INT_SRC");
+
+       ret = smsc75xx_write_reg(dev, INT_STS, INT_STS_CLEAR_ALL);
+       check_warn_return(ret, "Error writing INT_STS");
+
+       mii_check_media(mii, 1, 1);
+       mii_ethtool_gset(&dev->mii, &ecmd);
+       lcladv = smsc75xx_mdio_read(dev->net, mii->phy_id, MII_ADVERTISE);
+       rmtadv = smsc75xx_mdio_read(dev->net, mii->phy_id, MII_LPA);
+
+       netif_dbg(dev, link, dev->net, "speed: %d duplex: %d lcladv: %04x"
+               " rmtadv: %04x", ecmd.speed, ecmd.duplex, lcladv, rmtadv);
+
+       return smsc75xx_update_flowcontrol(dev, ecmd.duplex, lcladv, rmtadv);
+}
+
+static void smsc75xx_status(struct usbnet *dev, struct urb *urb)
+{
+       u32 intdata;
+
+       if (urb->actual_length != 4) {
+               netdev_warn(dev->net,
+                       "unexpected urb length %d", urb->actual_length);
+               return;
+       }
+
+       memcpy(&intdata, urb->transfer_buffer, 4);
+       le32_to_cpus(&intdata);
+
+       netif_dbg(dev, link, dev->net, "intdata: 0x%08X", intdata);
+
+       if (intdata & INT_ENP_PHY_INT)
+               usbnet_defer_kevent(dev, EVENT_LINK_RESET);
+       else
+               netdev_warn(dev->net,
+                       "unexpected interrupt, intdata=0x%08X", intdata);
+}
+
+/* Enable or disable Rx checksum offload engine */
+static int smsc75xx_set_rx_csum_offload(struct usbnet *dev)
+{
+       struct smsc75xx_priv *pdata = (struct smsc75xx_priv *)(dev->data[0]);
+       unsigned long flags;
+       int ret;
+
+       spin_lock_irqsave(&pdata->rfe_ctl_lock, flags);
+
+       if (pdata->use_rx_csum)
+               pdata->rfe_ctl |= RFE_CTL_TCPUDP_CKM | RFE_CTL_IP_CKM;
+       else
+               pdata->rfe_ctl &= ~(RFE_CTL_TCPUDP_CKM | RFE_CTL_IP_CKM);
+
+       spin_unlock_irqrestore(&pdata->rfe_ctl_lock, flags);
+
+       ret = smsc75xx_write_reg(dev, RFE_CTL, pdata->rfe_ctl);
+       check_warn_return(ret, "Error writing RFE_CTL");
+
+       return 0;
+}
+
+static int smsc75xx_ethtool_get_eeprom_len(struct net_device *net)
+{
+       return MAX_EEPROM_SIZE;
+}
+
+static int smsc75xx_ethtool_get_eeprom(struct net_device *netdev,
+                                      struct ethtool_eeprom *ee, u8 *data)
+{
+       struct usbnet *dev = netdev_priv(netdev);
+
+       ee->magic = LAN75XX_EEPROM_MAGIC;
+
+       return smsc75xx_read_eeprom(dev, ee->offset, ee->len, data);
+}
+
+static int smsc75xx_ethtool_set_eeprom(struct net_device *netdev,
+                                      struct ethtool_eeprom *ee, u8 *data)
+{
+       struct usbnet *dev = netdev_priv(netdev);
+
+       if (ee->magic != LAN75XX_EEPROM_MAGIC) {
+               netdev_warn(dev->net,
+                       "EEPROM: magic value mismatch: 0x%x", ee->magic);
+               return -EINVAL;
+       }
+
+       return smsc75xx_write_eeprom(dev, ee->offset, ee->len, data);
+}
+
+static u32 smsc75xx_ethtool_get_rx_csum(struct net_device *netdev)
+{
+       struct usbnet *dev = netdev_priv(netdev);
+       struct smsc75xx_priv *pdata = (struct smsc75xx_priv *)(dev->data[0]);
+
+       return pdata->use_rx_csum;
+}
+
+static int smsc75xx_ethtool_set_rx_csum(struct net_device *netdev, u32 val)
+{
+       struct usbnet *dev = netdev_priv(netdev);
+       struct smsc75xx_priv *pdata = (struct smsc75xx_priv *)(dev->data[0]);
+
+       pdata->use_rx_csum = !!val;
+
+       return smsc75xx_set_rx_csum_offload(dev);
+}
+
+static int smsc75xx_ethtool_set_tso(struct net_device *netdev, u32 data)
+{
+       if (data)
+               netdev->features |= NETIF_F_TSO | NETIF_F_TSO6;
+       else
+               netdev->features &= ~(NETIF_F_TSO | NETIF_F_TSO6);
+
+       return 0;
+}
+
+static const struct ethtool_ops smsc75xx_ethtool_ops = {
+       .get_link       = usbnet_get_link,
+       .nway_reset     = usbnet_nway_reset,
+       .get_drvinfo    = usbnet_get_drvinfo,
+       .get_msglevel   = usbnet_get_msglevel,
+       .set_msglevel   = usbnet_set_msglevel,
+       .get_settings   = usbnet_get_settings,
+       .set_settings   = usbnet_set_settings,
+       .get_eeprom_len = smsc75xx_ethtool_get_eeprom_len,
+       .get_eeprom     = smsc75xx_ethtool_get_eeprom,
+       .set_eeprom     = smsc75xx_ethtool_set_eeprom,
+       .get_tx_csum    = ethtool_op_get_tx_csum,
+       .set_tx_csum    = ethtool_op_set_tx_hw_csum,
+       .get_rx_csum    = smsc75xx_ethtool_get_rx_csum,
+       .set_rx_csum    = smsc75xx_ethtool_set_rx_csum,
+       .get_tso        = ethtool_op_get_tso,
+       .set_tso        = smsc75xx_ethtool_set_tso,
+};
+
+static int smsc75xx_ioctl(struct net_device *netdev, struct ifreq *rq, int cmd)
+{
+       struct usbnet *dev = netdev_priv(netdev);
+
+       if (!netif_running(netdev))
+               return -EINVAL;
+
+       return generic_mii_ioctl(&dev->mii, if_mii(rq), cmd, NULL);
+}
+
+static void smsc75xx_init_mac_address(struct usbnet *dev)
+{
+       /* try reading mac address from EEPROM */
+       if (smsc75xx_read_eeprom(dev, EEPROM_MAC_OFFSET, ETH_ALEN,
+                       dev->net->dev_addr) == 0) {
+               if (is_valid_ether_addr(dev->net->dev_addr)) {
+                       /* eeprom values are valid so use them */
+                       netif_dbg(dev, ifup, dev->net,
+                               "MAC address read from EEPROM");
+                       return;
+               }
+       }
+
+       /* no eeprom, or eeprom values are invalid. generate random MAC */
+       random_ether_addr(dev->net->dev_addr);
+       netif_dbg(dev, ifup, dev->net, "MAC address set to random_ether_addr");
+}
+
+static int smsc75xx_set_mac_address(struct usbnet *dev)
+{
+       u32 addr_lo = dev->net->dev_addr[0] | dev->net->dev_addr[1] << 8 |
+               dev->net->dev_addr[2] << 16 | dev->net->dev_addr[3] << 24;
+       u32 addr_hi = dev->net->dev_addr[4] | dev->net->dev_addr[5] << 8;
+
+       int ret = smsc75xx_write_reg(dev, RX_ADDRH, addr_hi);
+       check_warn_return(ret, "Failed to write RX_ADDRH: %d", ret);
+
+       ret = smsc75xx_write_reg(dev, RX_ADDRL, addr_lo);
+       check_warn_return(ret, "Failed to write RX_ADDRL: %d", ret);
+
+       addr_hi |= ADDR_FILTX_FB_VALID;
+       ret = smsc75xx_write_reg(dev, ADDR_FILTX, addr_hi);
+       check_warn_return(ret, "Failed to write ADDR_FILTX: %d", ret);
+
+       ret = smsc75xx_write_reg(dev, ADDR_FILTX + 4, addr_lo);
+       check_warn_return(ret, "Failed to write ADDR_FILTX+4: %d", ret);
+
+       return 0;
+}
+
+static int smsc75xx_phy_initialize(struct usbnet *dev)
+{
+       int bmcr, timeout = 0;
+
+       /* Initialize MII structure */
+       dev->mii.dev = dev->net;
+       dev->mii.mdio_read = smsc75xx_mdio_read;
+       dev->mii.mdio_write = smsc75xx_mdio_write;
+       dev->mii.phy_id_mask = 0x1f;
+       dev->mii.reg_num_mask = 0x1f;
+       dev->mii.phy_id = SMSC75XX_INTERNAL_PHY_ID;
+
+       /* reset phy and wait for reset to complete */
+       smsc75xx_mdio_write(dev->net, dev->mii.phy_id, MII_BMCR, BMCR_RESET);
+
+       do {
+               msleep(10);
+               bmcr = smsc75xx_mdio_read(dev->net, dev->mii.phy_id, MII_BMCR);
+               check_warn_return(bmcr, "Error reading MII_BMCR");
+               timeout++;
+       } while ((bmcr & MII_BMCR) && (timeout < 100));
+
+       if (timeout >= 100) {
+               netdev_warn(dev->net, "timeout on PHY Reset");
+               return -EIO;
+       }
+
+       smsc75xx_mdio_write(dev->net, dev->mii.phy_id, MII_ADVERTISE,
+               ADVERTISE_ALL | ADVERTISE_CSMA | ADVERTISE_PAUSE_CAP |
+               ADVERTISE_PAUSE_ASYM);
+
+       /* read to clear */
+       smsc75xx_mdio_read(dev->net, dev->mii.phy_id, PHY_INT_SRC);
+       check_warn_return(bmcr, "Error reading PHY_INT_SRC");
+
+       smsc75xx_mdio_write(dev->net, dev->mii.phy_id, PHY_INT_MASK,
+               PHY_INT_MASK_DEFAULT);
+       mii_nway_restart(&dev->mii);
+
+       netif_dbg(dev, ifup, dev->net, "phy initialised successfully");
+       return 0;
+}
+
+static int smsc75xx_set_rx_max_frame_length(struct usbnet *dev, int size)
+{
+       int ret = 0;
+       u32 buf;
+       bool rxenabled;
+
+       ret = smsc75xx_read_reg(dev, MAC_RX, &buf);
+       check_warn_return(ret, "Failed to read MAC_RX: %d", ret);
+
+       rxenabled = ((buf & MAC_RX_RXEN) != 0);
+
+       if (rxenabled) {
+               buf &= ~MAC_RX_RXEN;
+               ret = smsc75xx_write_reg(dev, MAC_RX, buf);
+               check_warn_return(ret, "Failed to write MAC_RX: %d", ret);
+       }
+
+       /* add 4 to size for FCS */
+       buf &= ~MAC_RX_MAX_SIZE;
+       buf |= (((size + 4) << MAC_RX_MAX_SIZE_SHIFT) & MAC_RX_MAX_SIZE);
+
+       ret = smsc75xx_write_reg(dev, MAC_RX, buf);
+       check_warn_return(ret, "Failed to write MAC_RX: %d", ret);
+
+       if (rxenabled) {
+               buf |= MAC_RX_RXEN;
+               ret = smsc75xx_write_reg(dev, MAC_RX, buf);
+               check_warn_return(ret, "Failed to write MAC_RX: %d", ret);
+       }
+
+       return 0;
+}
+
+static int smsc75xx_change_mtu(struct net_device *netdev, int new_mtu)
+{
+       struct usbnet *dev = netdev_priv(netdev);
+
+       int ret = smsc75xx_set_rx_max_frame_length(dev, new_mtu);
+       check_warn_return(ret, "Failed to set mac rx frame length");
+
+       return usbnet_change_mtu(netdev, new_mtu);
+}
+
+static int smsc75xx_reset(struct usbnet *dev)
+{
+       struct smsc75xx_priv *pdata = (struct smsc75xx_priv *)(dev->data[0]);
+       u32 buf;
+       int ret = 0, timeout;
+
+       netif_dbg(dev, ifup, dev->net, "entering smsc75xx_reset");
+
+       ret = smsc75xx_read_reg(dev, HW_CFG, &buf);
+       check_warn_return(ret, "Failed to read HW_CFG: %d", ret);
+
+       buf |= HW_CFG_LRST;
+
+       ret = smsc75xx_write_reg(dev, HW_CFG, buf);
+       check_warn_return(ret, "Failed to write HW_CFG: %d", ret);
+
+       timeout = 0;
+       do {
+               msleep(10);
+               ret = smsc75xx_read_reg(dev, HW_CFG, &buf);
+               check_warn_return(ret, "Failed to read HW_CFG: %d", ret);
+               timeout++;
+       } while ((buf & HW_CFG_LRST) && (timeout < 100));
+
+       if (timeout >= 100) {
+               netdev_warn(dev->net, "timeout on completion of Lite Reset");
+               return -EIO;
+       }
+
+       netif_dbg(dev, ifup, dev->net, "Lite reset complete, resetting PHY");
+
+       ret = smsc75xx_read_reg(dev, PMT_CTL, &buf);
+       check_warn_return(ret, "Failed to read PMT_CTL: %d", ret);
+
+       buf |= PMT_CTL_PHY_RST;
+
+       ret = smsc75xx_write_reg(dev, PMT_CTL, buf);
+       check_warn_return(ret, "Failed to write PMT_CTL: %d", ret);
+
+       timeout = 0;
+       do {
+               msleep(10);
+               ret = smsc75xx_read_reg(dev, PMT_CTL, &buf);
+               check_warn_return(ret, "Failed to read PMT_CTL: %d", ret);
+               timeout++;
+       } while ((buf & PMT_CTL_PHY_RST) && (timeout < 100));
+
+       if (timeout >= 100) {
+               netdev_warn(dev->net, "timeout waiting for PHY Reset");
+               return -EIO;
+       }
+
+       netif_dbg(dev, ifup, dev->net, "PHY reset complete");
+
+       smsc75xx_init_mac_address(dev);
+
+       ret = smsc75xx_set_mac_address(dev);
+       check_warn_return(ret, "Failed to set mac address");
+
+       netif_dbg(dev, ifup, dev->net, "MAC Address: %pM", dev->net->dev_addr);
+
+       ret = smsc75xx_read_reg(dev, HW_CFG, &buf);
+       check_warn_return(ret, "Failed to read HW_CFG: %d", ret);
+
+       netif_dbg(dev, ifup, dev->net, "Read Value from HW_CFG : 0x%08x", buf);
+
+       buf |= HW_CFG_BIR;
+
+       ret = smsc75xx_write_reg(dev, HW_CFG, buf);
+       check_warn_return(ret, "Failed to write HW_CFG: %d", ret);
+
+       ret = smsc75xx_read_reg(dev, HW_CFG, &buf);
+       check_warn_return(ret, "Failed to read HW_CFG: %d", ret);
+
+       netif_dbg(dev, ifup, dev->net, "Read Value from HW_CFG after "
+                       "writing HW_CFG_BIR: 0x%08x", buf);
+
+       if (!turbo_mode) {
+               buf = 0;
+               dev->rx_urb_size = MAX_SINGLE_PACKET_SIZE;
+       } else if (dev->udev->speed == USB_SPEED_HIGH) {
+               buf = DEFAULT_HS_BURST_CAP_SIZE / HS_USB_PKT_SIZE;
+               dev->rx_urb_size = DEFAULT_HS_BURST_CAP_SIZE;
+       } else {
+               buf = DEFAULT_FS_BURST_CAP_SIZE / FS_USB_PKT_SIZE;
+               dev->rx_urb_size = DEFAULT_FS_BURST_CAP_SIZE;
+       }
+
+       netif_dbg(dev, ifup, dev->net, "rx_urb_size=%ld",
+               (ulong)dev->rx_urb_size);
+
+       ret = smsc75xx_write_reg(dev, BURST_CAP, buf);
+       check_warn_return(ret, "Failed to write BURST_CAP: %d", ret);
+
+       ret = smsc75xx_read_reg(dev, BURST_CAP, &buf);
+       check_warn_return(ret, "Failed to read BURST_CAP: %d", ret);
+
+       netif_dbg(dev, ifup, dev->net,
+               "Read Value from BURST_CAP after writing: 0x%08x", buf);
+
+       ret = smsc75xx_write_reg(dev, BULK_IN_DLY, DEFAULT_BULK_IN_DELAY);
+       check_warn_return(ret, "Failed to write BULK_IN_DLY: %d", ret);
+
+       ret = smsc75xx_read_reg(dev, BULK_IN_DLY, &buf);
+       check_warn_return(ret, "Failed to read BULK_IN_DLY: %d", ret);
+
+       netif_dbg(dev, ifup, dev->net,
+               "Read Value from BULK_IN_DLY after writing: 0x%08x", buf);
+
+       if (turbo_mode) {
+               ret = smsc75xx_read_reg(dev, HW_CFG, &buf);
+               check_warn_return(ret, "Failed to read HW_CFG: %d", ret);
+
+               netif_dbg(dev, ifup, dev->net, "HW_CFG: 0x%08x", buf);
+
+               buf |= (HW_CFG_MEF | HW_CFG_BCE);
+
+               ret = smsc75xx_write_reg(dev, HW_CFG, buf);
+               check_warn_return(ret, "Failed to write HW_CFG: %d", ret);
+
+               ret = smsc75xx_read_reg(dev, HW_CFG, &buf);
+               check_warn_return(ret, "Failed to read HW_CFG: %d", ret);
+
+               netif_dbg(dev, ifup, dev->net, "HW_CFG: 0x%08x", buf);
+       }
+
+       /* set FIFO sizes */
+       buf = (MAX_RX_FIFO_SIZE - 512) / 512;
+       ret = smsc75xx_write_reg(dev, FCT_RX_FIFO_END, buf);
+       check_warn_return(ret, "Failed to write FCT_RX_FIFO_END: %d", ret);
+
+       netif_dbg(dev, ifup, dev->net, "FCT_RX_FIFO_END set to 0x%08x", buf);
+
+       buf = (MAX_TX_FIFO_SIZE - 512) / 512;
+       ret = smsc75xx_write_reg(dev, FCT_TX_FIFO_END, buf);
+       check_warn_return(ret, "Failed to write FCT_TX_FIFO_END: %d", ret);
+
+       netif_dbg(dev, ifup, dev->net, "FCT_TX_FIFO_END set to 0x%08x", buf);
+
+       ret = smsc75xx_write_reg(dev, INT_STS, INT_STS_CLEAR_ALL);
+       check_warn_return(ret, "Failed to write INT_STS: %d", ret);
+
+       ret = smsc75xx_read_reg(dev, ID_REV, &buf);
+       check_warn_return(ret, "Failed to read ID_REV: %d", ret);
+
+       netif_dbg(dev, ifup, dev->net, "ID_REV = 0x%08x", buf);
+
+       /* Configure GPIO pins as LED outputs */
+       ret = smsc75xx_read_reg(dev, LED_GPIO_CFG, &buf);
+       check_warn_return(ret, "Failed to read LED_GPIO_CFG: %d", ret);
+
+       buf &= ~(LED_GPIO_CFG_LED2_FUN_SEL | LED_GPIO_CFG_LED10_FUN_SEL);
+       buf |= LED_GPIO_CFG_LEDGPIO_EN | LED_GPIO_CFG_LED2_FUN_SEL;
+
+       ret = smsc75xx_write_reg(dev, LED_GPIO_CFG, buf);
+       check_warn_return(ret, "Failed to write LED_GPIO_CFG: %d", ret);
+
+       ret = smsc75xx_write_reg(dev, FLOW, 0);
+       check_warn_return(ret, "Failed to write FLOW: %d", ret);
+
+       ret = smsc75xx_write_reg(dev, FCT_FLOW, 0);
+       check_warn_return(ret, "Failed to write FCT_FLOW: %d", ret);
+
+       /* Don't need rfe_ctl_lock during initialisation */
+       ret = smsc75xx_read_reg(dev, RFE_CTL, &pdata->rfe_ctl);
+       check_warn_return(ret, "Failed to read RFE_CTL: %d", ret);
+
+       pdata->rfe_ctl |= RFE_CTL_AB | RFE_CTL_DPF;
+
+       ret = smsc75xx_write_reg(dev, RFE_CTL, pdata->rfe_ctl);
+       check_warn_return(ret, "Failed to write RFE_CTL: %d", ret);
+
+       ret = smsc75xx_read_reg(dev, RFE_CTL, &pdata->rfe_ctl);
+       check_warn_return(ret, "Failed to read RFE_CTL: %d", ret);
+
+       netif_dbg(dev, ifup, dev->net, "RFE_CTL set to 0x%08x", pdata->rfe_ctl);
+
+       /* Enable or disable checksum offload engines */
+       ethtool_op_set_tx_hw_csum(dev->net, DEFAULT_TX_CSUM_ENABLE);
+       ret = smsc75xx_set_rx_csum_offload(dev);
+       check_warn_return(ret, "Failed to set rx csum offload: %d", ret);
+
+       smsc75xx_ethtool_set_tso(dev->net, DEFAULT_TSO_ENABLE);
+
+       smsc75xx_set_multicast(dev->net);
+
+       ret = smsc75xx_phy_initialize(dev);
+       check_warn_return(ret, "Failed to initialize PHY: %d", ret);
+
+       ret = smsc75xx_read_reg(dev, INT_EP_CTL, &buf);
+       check_warn_return(ret, "Failed to read INT_EP_CTL: %d", ret);
+
+       /* enable PHY interrupts */
+       buf |= INT_ENP_PHY_INT;
+
+       ret = smsc75xx_write_reg(dev, INT_EP_CTL, buf);
+       check_warn_return(ret, "Failed to write INT_EP_CTL: %d", ret);
+
+       ret = smsc75xx_read_reg(dev, MAC_TX, &buf);
+       check_warn_return(ret, "Failed to read MAC_TX: %d", ret);
+
+       buf |= MAC_TX_TXEN;
+
+       ret = smsc75xx_write_reg(dev, MAC_TX, buf);
+       check_warn_return(ret, "Failed to write MAC_TX: %d", ret);
+
+       netif_dbg(dev, ifup, dev->net, "MAC_TX set to 0x%08x", buf);
+
+       ret = smsc75xx_read_reg(dev, FCT_TX_CTL, &buf);
+       check_warn_return(ret, "Failed to read FCT_TX_CTL: %d", ret);
+
+       buf |= FCT_TX_CTL_EN;
+
+       ret = smsc75xx_write_reg(dev, FCT_TX_CTL, buf);
+       check_warn_return(ret, "Failed to write FCT_TX_CTL: %d", ret);
+
+       netif_dbg(dev, ifup, dev->net, "FCT_TX_CTL set to 0x%08x", buf);
+
+       ret = smsc75xx_set_rx_max_frame_length(dev, 1514);
+       check_warn_return(ret, "Failed to set max rx frame length");
+
+       ret = smsc75xx_read_reg(dev, MAC_RX, &buf);
+       check_warn_return(ret, "Failed to read MAC_RX: %d", ret);
+
+       buf |= MAC_RX_RXEN;
+
+       ret = smsc75xx_write_reg(dev, MAC_RX, buf);
+       check_warn_return(ret, "Failed to write MAC_RX: %d", ret);
+
+       netif_dbg(dev, ifup, dev->net, "MAC_RX set to 0x%08x", buf);
+
+       ret = smsc75xx_read_reg(dev, FCT_RX_CTL, &buf);
+       check_warn_return(ret, "Failed to read FCT_RX_CTL: %d", ret);
+
+       buf |= FCT_RX_CTL_EN;
+
+       ret = smsc75xx_write_reg(dev, FCT_RX_CTL, buf);
+       check_warn_return(ret, "Failed to write FCT_RX_CTL: %d", ret);
+
+       netif_dbg(dev, ifup, dev->net, "FCT_RX_CTL set to 0x%08x", buf);
+
+       netif_dbg(dev, ifup, dev->net, "smsc75xx_reset, return 0");
+       return 0;
+}
+
+static const struct net_device_ops smsc75xx_netdev_ops = {
+       .ndo_open               = usbnet_open,
+       .ndo_stop               = usbnet_stop,
+       .ndo_start_xmit         = usbnet_start_xmit,
+       .ndo_tx_timeout         = usbnet_tx_timeout,
+       .ndo_change_mtu         = smsc75xx_change_mtu,
+       .ndo_set_mac_address    = eth_mac_addr,
+       .ndo_validate_addr      = eth_validate_addr,
+       .ndo_do_ioctl           = smsc75xx_ioctl,
+       .ndo_set_multicast_list = smsc75xx_set_multicast,
+};
+
+static int smsc75xx_bind(struct usbnet *dev, struct usb_interface *intf)
+{
+       struct smsc75xx_priv *pdata = NULL;
+       int ret;
+
+       printk(KERN_INFO SMSC_CHIPNAME " v" SMSC_DRIVER_VERSION "\n");
+
+       ret = usbnet_get_endpoints(dev, intf);
+       check_warn_return(ret, "usbnet_get_endpoints failed: %d", ret);
+
+       dev->data[0] = (unsigned long)kzalloc(sizeof(struct smsc75xx_priv),
+               GFP_KERNEL);
+
+       pdata = (struct smsc75xx_priv *)(dev->data[0]);
+       if (!pdata) {
+               netdev_warn(dev->net, "Unable to allocate smsc75xx_priv");
+               return -ENOMEM;
+       }
+
+       pdata->dev = dev;
+
+       spin_lock_init(&pdata->rfe_ctl_lock);
+       mutex_init(&pdata->dataport_mutex);
+
+       INIT_WORK(&pdata->set_multicast, smsc75xx_deferred_multicast_write);
+
+       pdata->use_rx_csum = DEFAULT_RX_CSUM_ENABLE;
+
+       /* We have to advertise SG otherwise TSO cannot be enabled */
+       dev->net->features |= NETIF_F_SG;
+
+       /* Init all registers */
+       ret = smsc75xx_reset(dev);
+
+       dev->net->netdev_ops = &smsc75xx_netdev_ops;
+       dev->net->ethtool_ops = &smsc75xx_ethtool_ops;
+       dev->net->flags |= IFF_MULTICAST;
+       dev->net->hard_header_len += SMSC75XX_TX_OVERHEAD;
+       return 0;
+}
+
+static void smsc75xx_unbind(struct usbnet *dev, struct usb_interface *intf)
+{
+       struct smsc75xx_priv *pdata = (struct smsc75xx_priv *)(dev->data[0]);
+       if (pdata) {
+               netif_dbg(dev, ifdown, dev->net, "free pdata");
+               kfree(pdata);
+               pdata = NULL;
+               dev->data[0] = 0;
+       }
+}
+
+static void smsc75xx_rx_csum_offload(struct sk_buff *skb, u32 rx_cmd_a,
+                                    u32 rx_cmd_b)
+{
+       if (unlikely(rx_cmd_a & RX_CMD_A_LCSM)) {
+               skb->ip_summed = CHECKSUM_NONE;
+       } else {
+               skb->csum = ntohs((u16)(rx_cmd_b >> RX_CMD_B_CSUM_SHIFT));
+               skb->ip_summed = CHECKSUM_COMPLETE;
+       }
+}
+
+static int smsc75xx_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
+{
+       struct smsc75xx_priv *pdata = (struct smsc75xx_priv *)(dev->data[0]);
+
+       while (skb->len > 0) {
+               u32 rx_cmd_a, rx_cmd_b, align_count, size;
+               struct sk_buff *ax_skb;
+               unsigned char *packet;
+
+               memcpy(&rx_cmd_a, skb->data, sizeof(rx_cmd_a));
+               le32_to_cpus(&rx_cmd_a);
+               skb_pull(skb, 4);
+
+               memcpy(&rx_cmd_b, skb->data, sizeof(rx_cmd_b));
+               le32_to_cpus(&rx_cmd_b);
+               skb_pull(skb, 4 + NET_IP_ALIGN);
+
+               packet = skb->data;
+
+               /* get the packet length */
+               size = (rx_cmd_a & RX_CMD_A_LEN) - NET_IP_ALIGN;
+               align_count = (4 - ((size + NET_IP_ALIGN) % 4)) % 4;
+
+               if (unlikely(rx_cmd_a & RX_CMD_A_RED)) {
+                       netif_dbg(dev, rx_err, dev->net,
+                               "Error rx_cmd_a=0x%08x", rx_cmd_a);
+                       dev->net->stats.rx_errors++;
+                       dev->net->stats.rx_dropped++;
+
+                       if (rx_cmd_a & RX_CMD_A_FCS)
+                               dev->net->stats.rx_crc_errors++;
+                       else if (rx_cmd_a & (RX_CMD_A_LONG | RX_CMD_A_RUNT))
+                               dev->net->stats.rx_frame_errors++;
+               } else {
+                       /* ETH_FRAME_LEN + 4(CRC) + 2(COE) + 4(Vlan) */
+                       if (unlikely(size > (ETH_FRAME_LEN + 12))) {
+                               netif_dbg(dev, rx_err, dev->net,
+                                       "size err rx_cmd_a=0x%08x", rx_cmd_a);
+                               return 0;
+                       }
+
+                       /* last frame in this batch */
+                       if (skb->len == size) {
+                               if (pdata->use_rx_csum)
+                                       smsc75xx_rx_csum_offload(skb, rx_cmd_a,
+                                               rx_cmd_b);
+                               else
+                                       skb->ip_summed = CHECKSUM_NONE;
+
+                               skb_trim(skb, skb->len - 4); /* remove fcs */
+                               skb->truesize = size + sizeof(struct sk_buff);
+
+                               return 1;
+                       }
+
+                       ax_skb = skb_clone(skb, GFP_ATOMIC);
+                       if (unlikely(!ax_skb)) {
+                               netdev_warn(dev->net, "Error allocating skb");
+                               return 0;
+                       }
+
+                       ax_skb->len = size;
+                       ax_skb->data = packet;
+                       skb_set_tail_pointer(ax_skb, size);
+
+                       if (pdata->use_rx_csum)
+                               smsc75xx_rx_csum_offload(ax_skb, rx_cmd_a,
+                                       rx_cmd_b);
+                       else
+                               ax_skb->ip_summed = CHECKSUM_NONE;
+
+                       skb_trim(ax_skb, ax_skb->len - 4); /* remove fcs */
+                       ax_skb->truesize = size + sizeof(struct sk_buff);
+
+                       usbnet_skb_return(dev, ax_skb);
+               }
+
+               skb_pull(skb, size);
+
+               /* padding bytes before the next frame starts */
+               if (skb->len)
+                       skb_pull(skb, align_count);
+       }
+
+       if (unlikely(skb->len < 0)) {
+               netdev_warn(dev->net, "invalid rx length<0 %d", skb->len);
+               return 0;
+       }
+
+       return 1;
+}
+
+static struct sk_buff *smsc75xx_tx_fixup(struct usbnet *dev,
+                                        struct sk_buff *skb, gfp_t flags)
+{
+       u32 tx_cmd_a, tx_cmd_b;
+
+       skb_linearize(skb);
+
+       if (skb_headroom(skb) < SMSC75XX_TX_OVERHEAD) {
+               struct sk_buff *skb2 =
+                       skb_copy_expand(skb, SMSC75XX_TX_OVERHEAD, 0, flags);
+               dev_kfree_skb_any(skb);
+               skb = skb2;
+               if (!skb)
+                       return NULL;
+       }
+
+       tx_cmd_a = (u32)(skb->len & TX_CMD_A_LEN) | TX_CMD_A_FCS;
+
+       if (skb->ip_summed == CHECKSUM_PARTIAL)
+               tx_cmd_a |= TX_CMD_A_IPE | TX_CMD_A_TPE;
+
+       if (skb_is_gso(skb)) {
+               u16 mss = max(skb_shinfo(skb)->gso_size, TX_MSS_MIN);
+               tx_cmd_b = (mss << TX_CMD_B_MSS_SHIFT) & TX_CMD_B_MSS;
+
+               tx_cmd_a |= TX_CMD_A_LSO;
+       } else {
+               tx_cmd_b = 0;
+       }
+
+       skb_push(skb, 4);
+       cpu_to_le32s(&tx_cmd_b);
+       memcpy(skb->data, &tx_cmd_b, 4);
+
+       skb_push(skb, 4);
+       cpu_to_le32s(&tx_cmd_a);
+       memcpy(skb->data, &tx_cmd_a, 4);
+
+       return skb;
+}
+
+static const struct driver_info smsc75xx_info = {
+       .description    = "smsc75xx USB 2.0 Gigabit Ethernet",
+       .bind           = smsc75xx_bind,
+       .unbind         = smsc75xx_unbind,
+       .link_reset     = smsc75xx_link_reset,
+       .reset          = smsc75xx_reset,
+       .rx_fixup       = smsc75xx_rx_fixup,
+       .tx_fixup       = smsc75xx_tx_fixup,
+       .status         = smsc75xx_status,
+       .flags          = FLAG_ETHER | FLAG_SEND_ZLP,
+};
+
+static const struct usb_device_id products[] = {
+       {
+               /* SMSC7500 USB Gigabit Ethernet Device */
+               USB_DEVICE(USB_VENDOR_ID_SMSC, USB_PRODUCT_ID_LAN7500),
+               .driver_info = (unsigned long) &smsc75xx_info,
+       },
+       {
+               /* SMSC7500 USB Gigabit Ethernet Device */
+               USB_DEVICE(USB_VENDOR_ID_SMSC, USB_PRODUCT_ID_LAN7505),
+               .driver_info = (unsigned long) &smsc75xx_info,
+       },
+       { },            /* END */
+};
+MODULE_DEVICE_TABLE(usb, products);
+
+static struct usb_driver smsc75xx_driver = {
+       .name           = SMSC_CHIPNAME,
+       .id_table       = products,
+       .probe          = usbnet_probe,
+       .suspend        = usbnet_suspend,
+       .resume         = usbnet_resume,
+       .disconnect     = usbnet_disconnect,
+};
+
+static int __init smsc75xx_init(void)
+{
+       return usb_register(&smsc75xx_driver);
+}
+module_init(smsc75xx_init);
+
+static void __exit smsc75xx_exit(void)
+{
+       usb_deregister(&smsc75xx_driver);
+}
+module_exit(smsc75xx_exit);
+
+MODULE_AUTHOR("Nancy Lin");
+MODULE_AUTHOR("Steve Glendinning <steve.glendinning@smsc.com>");
+MODULE_DESCRIPTION("SMSC75XX USB 2.0 Gigabit Ethernet Devices");
+MODULE_LICENSE("GPL");
diff --git a/drivers/net/usb/smsc75xx.h b/drivers/net/usb/smsc75xx.h
new file mode 100644 (file)
index 0000000..16e98c7
--- /dev/null
@@ -0,0 +1,421 @@
+ /***************************************************************************
+ *
+ * Copyright (C) 2007-2010 SMSC
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ *****************************************************************************/
+
+#ifndef _SMSC75XX_H
+#define _SMSC75XX_H
+
+/* Tx command words */
+#define TX_CMD_A_LSO                   (0x08000000)
+#define TX_CMD_A_IPE                   (0x04000000)
+#define TX_CMD_A_TPE                   (0x02000000)
+#define TX_CMD_A_IVTG                  (0x01000000)
+#define TX_CMD_A_RVTG                  (0x00800000)
+#define TX_CMD_A_FCS                   (0x00400000)
+#define TX_CMD_A_LEN                   (0x000FFFFF)
+
+#define TX_CMD_B_MSS                   (0x3FFF0000)
+#define TX_CMD_B_MSS_SHIFT             (16)
+#define TX_MSS_MIN                     ((u16)8)
+#define TX_CMD_B_VTAG                  (0x0000FFFF)
+
+/* Rx command words */
+#define RX_CMD_A_ICE                   (0x80000000)
+#define RX_CMD_A_TCE                   (0x40000000)
+#define RX_CMD_A_IPV                   (0x20000000)
+#define RX_CMD_A_PID                   (0x18000000)
+#define RX_CMD_A_PID_NIP               (0x00000000)
+#define RX_CMD_A_PID_TCP               (0x08000000)
+#define RX_CMD_A_PID_UDP               (0x10000000)
+#define RX_CMD_A_PID_PP                        (0x18000000)
+#define RX_CMD_A_PFF                   (0x04000000)
+#define RX_CMD_A_BAM                   (0x02000000)
+#define RX_CMD_A_MAM                   (0x01000000)
+#define RX_CMD_A_FVTG                  (0x00800000)
+#define RX_CMD_A_RED                   (0x00400000)
+#define RX_CMD_A_RWT                   (0x00200000)
+#define RX_CMD_A_RUNT                  (0x00100000)
+#define RX_CMD_A_LONG                  (0x00080000)
+#define RX_CMD_A_RXE                   (0x00040000)
+#define RX_CMD_A_DRB                   (0x00020000)
+#define RX_CMD_A_FCS                   (0x00010000)
+#define RX_CMD_A_UAM                   (0x00008000)
+#define RX_CMD_A_LCSM                  (0x00004000)
+#define RX_CMD_A_LEN                   (0x00003FFF)
+
+#define RX_CMD_B_CSUM                  (0xFFFF0000)
+#define RX_CMD_B_CSUM_SHIFT            (16)
+#define RX_CMD_B_VTAG                  (0x0000FFFF)
+
+/* SCSRs */
+#define ID_REV                         (0x0000)
+
+#define FPGA_REV                       (0x0004)
+
+#define BOND_CTL                       (0x0008)
+
+#define INT_STS                                (0x000C)
+#define INT_STS_RDFO_INT               (0x00400000)
+#define INT_STS_TXE_INT                        (0x00200000)
+#define INT_STS_MACRTO_INT             (0x00100000)
+#define INT_STS_TX_DIS_INT             (0x00080000)
+#define INT_STS_RX_DIS_INT             (0x00040000)
+#define INT_STS_PHY_INT_               (0x00020000)
+#define INT_STS_MAC_ERR_INT            (0x00008000)
+#define INT_STS_TDFU                   (0x00004000)
+#define INT_STS_TDFO                   (0x00002000)
+#define INT_STS_GPIOS                  (0x00000FFF)
+#define INT_STS_CLEAR_ALL              (0xFFFFFFFF)
+
+#define HW_CFG                         (0x0010)
+#define HW_CFG_SMDET_STS               (0x00008000)
+#define HW_CFG_SMDET_EN                        (0x00004000)
+#define HW_CFG_EEM                     (0x00002000)
+#define HW_CFG_RST_PROTECT             (0x00001000)
+#define HW_CFG_PORT_SWAP               (0x00000800)
+#define HW_CFG_PHY_BOOST               (0x00000600)
+#define HW_CFG_PHY_BOOST_NORMAL                (0x00000000)
+#define HW_CFG_PHY_BOOST_4             (0x00002000)
+#define HW_CFG_PHY_BOOST_8             (0x00004000)
+#define HW_CFG_PHY_BOOST_12            (0x00006000)
+#define HW_CFG_LEDB                    (0x00000100)
+#define HW_CFG_BIR                     (0x00000080)
+#define HW_CFG_SBP                     (0x00000040)
+#define HW_CFG_IME                     (0x00000020)
+#define HW_CFG_MEF                     (0x00000010)
+#define HW_CFG_ETC                     (0x00000008)
+#define HW_CFG_BCE                     (0x00000004)
+#define HW_CFG_LRST                    (0x00000002)
+#define HW_CFG_SRST                    (0x00000001)
+
+#define PMT_CTL                                (0x0014)
+#define PMT_CTL_PHY_PWRUP              (0x00000400)
+#define PMT_CTL_RES_CLR_WKP_EN         (0x00000100)
+#define PMT_CTL_DEV_RDY                        (0x00000080)
+#define PMT_CTL_SUS_MODE               (0x00000060)
+#define PMT_CTL_SUS_MODE_0             (0x00000000)
+#define PMT_CTL_SUS_MODE_1             (0x00000020)
+#define PMT_CTL_SUS_MODE_2             (0x00000040)
+#define PMT_CTL_SUS_MODE_3             (0x00000060)
+#define PMT_CTL_PHY_RST                        (0x00000010)
+#define PMT_CTL_WOL_EN                 (0x00000008)
+#define PMT_CTL_ED_EN                  (0x00000004)
+#define PMT_CTL_WUPS                   (0x00000003)
+#define PMT_CTL_WUPS_NO                        (0x00000000)
+#define PMT_CTL_WUPS_ED                        (0x00000001)
+#define PMT_CTL_WUPS_WOL               (0x00000002)
+#define PMT_CTL_WUPS_MULTI             (0x00000003)
+
+#define LED_GPIO_CFG                   (0x0018)
+#define LED_GPIO_CFG_LED2_FUN_SEL      (0x80000000)
+#define LED_GPIO_CFG_LED10_FUN_SEL     (0x40000000)
+#define LED_GPIO_CFG_LEDGPIO_EN                (0x0000F000)
+#define LED_GPIO_CFG_LEDGPIO_EN_0      (0x00001000)
+#define LED_GPIO_CFG_LEDGPIO_EN_1      (0x00002000)
+#define LED_GPIO_CFG_LEDGPIO_EN_2      (0x00004000)
+#define LED_GPIO_CFG_LEDGPIO_EN_3      (0x00008000)
+#define LED_GPIO_CFG_GPBUF             (0x00000F00)
+#define LED_GPIO_CFG_GPBUF_0           (0x00000100)
+#define LED_GPIO_CFG_GPBUF_1           (0x00000200)
+#define LED_GPIO_CFG_GPBUF_2           (0x00000400)
+#define LED_GPIO_CFG_GPBUF_3           (0x00000800)
+#define LED_GPIO_CFG_GPDIR             (0x000000F0)
+#define LED_GPIO_CFG_GPDIR_0           (0x00000010)
+#define LED_GPIO_CFG_GPDIR_1           (0x00000020)
+#define LED_GPIO_CFG_GPDIR_2           (0x00000040)
+#define LED_GPIO_CFG_GPDIR_3           (0x00000080)
+#define LED_GPIO_CFG_GPDATA            (0x0000000F)
+#define LED_GPIO_CFG_GPDATA_0          (0x00000001)
+#define LED_GPIO_CFG_GPDATA_1          (0x00000002)
+#define LED_GPIO_CFG_GPDATA_2          (0x00000004)
+#define LED_GPIO_CFG_GPDATA_3          (0x00000008)
+
+#define GPIO_CFG                       (0x001C)
+#define GPIO_CFG_SHIFT                 (24)
+#define GPIO_CFG_GPEN                  (0xFF000000)
+#define GPIO_CFG_GPBUF                 (0x00FF0000)
+#define GPIO_CFG_GPDIR                 (0x0000FF00)
+#define GPIO_CFG_GPDATA                        (0x000000FF)
+
+#define GPIO_WAKE                      (0x0020)
+#define GPIO_WAKE_PHY_LINKUP_EN                (0x80000000)
+#define GPIO_WAKE_POL                  (0x0FFF0000)
+#define GPIO_WAKE_POL_SHIFT            (16)
+#define GPIO_WAKE_WK                   (0x00000FFF)
+
+#define DP_SEL                         (0x0024)
+#define DP_SEL_DPRDY                   (0x80000000)
+#define DP_SEL_RSEL                    (0x0000000F)
+#define DP_SEL_URX                     (0x00000000)
+#define DP_SEL_VHF                     (0x00000001)
+#define DP_SEL_VHF_HASH_LEN            (16)
+#define DP_SEL_VHF_VLAN_LEN            (128)
+#define DP_SEL_LSO_HEAD                        (0x00000002)
+#define DP_SEL_FCT_RX                  (0x00000003)
+#define DP_SEL_FCT_TX                  (0x00000004)
+#define DP_SEL_DESCRIPTOR              (0x00000005)
+#define DP_SEL_WOL                     (0x00000006)
+
+#define DP_CMD                         (0x0028)
+#define DP_CMD_WRITE                   (0x01)
+#define DP_CMD_READ                    (0x00)
+
+#define DP_ADDR                                (0x002C)
+
+#define DP_DATA                                (0x0030)
+
+#define BURST_CAP                      (0x0034)
+#define BURST_CAP_MASK                 (0x0000000F)
+
+#define INT_EP_CTL                     (0x0038)
+#define INT_EP_CTL_INTEP_ON            (0x80000000)
+#define INT_EP_CTL_RDFO_EN             (0x00400000)
+#define INT_EP_CTL_TXE_EN              (0x00200000)
+#define INT_EP_CTL_MACROTO_EN          (0x00100000)
+#define INT_EP_CTL_TX_DIS_EN           (0x00080000)
+#define INT_EP_CTL_RX_DIS_EN           (0x00040000)
+#define INT_EP_CTL_PHY_EN_             (0x00020000)
+#define INT_EP_CTL_MAC_ERR_EN          (0x00008000)
+#define INT_EP_CTL_TDFU_EN             (0x00004000)
+#define INT_EP_CTL_TDFO_EN             (0x00002000)
+#define INT_EP_CTL_RX_FIFO_EN          (0x00001000)
+#define INT_EP_CTL_GPIOX_EN            (0x00000FFF)
+
+#define BULK_IN_DLY                    (0x003C)
+#define BULK_IN_DLY_MASK               (0xFFFF)
+
+#define E2P_CMD                                (0x0040)
+#define E2P_CMD_BUSY                   (0x80000000)
+#define E2P_CMD_MASK                   (0x70000000)
+#define E2P_CMD_READ                   (0x00000000)
+#define E2P_CMD_EWDS                   (0x10000000)
+#define E2P_CMD_EWEN                   (0x20000000)
+#define E2P_CMD_WRITE                  (0x30000000)
+#define E2P_CMD_WRAL                   (0x40000000)
+#define E2P_CMD_ERASE                  (0x50000000)
+#define E2P_CMD_ERAL                   (0x60000000)
+#define E2P_CMD_RELOAD                 (0x70000000)
+#define E2P_CMD_TIMEOUT                        (0x00000400)
+#define E2P_CMD_LOADED                 (0x00000200)
+#define E2P_CMD_ADDR                   (0x000001FF)
+
+#define MAX_EEPROM_SIZE                        (512)
+
+#define E2P_DATA                       (0x0044)
+#define E2P_DATA_MASK_                 (0x000000FF)
+
+#define RFE_CTL                                (0x0060)
+#define RFE_CTL_TCPUDP_CKM             (0x00001000)
+#define RFE_CTL_IP_CKM                 (0x00000800)
+#define RFE_CTL_AB                     (0x00000400)
+#define RFE_CTL_AM                     (0x00000200)
+#define RFE_CTL_AU                     (0x00000100)
+#define RFE_CTL_VS                     (0x00000080)
+#define RFE_CTL_UF                     (0x00000040)
+#define RFE_CTL_VF                     (0x00000020)
+#define RFE_CTL_SPF                    (0x00000010)
+#define RFE_CTL_MHF                    (0x00000008)
+#define RFE_CTL_DHF                    (0x00000004)
+#define RFE_CTL_DPF                    (0x00000002)
+#define RFE_CTL_RST_RF                 (0x00000001)
+
+#define VLAN_TYPE                      (0x0064)
+#define VLAN_TYPE_MASK                 (0x0000FFFF)
+
+#define FCT_RX_CTL                     (0x0090)
+#define FCT_RX_CTL_EN                  (0x80000000)
+#define FCT_RX_CTL_RST                 (0x40000000)
+#define FCT_RX_CTL_SBF                 (0x02000000)
+#define FCT_RX_CTL_OVERFLOW            (0x01000000)
+#define FCT_RX_CTL_FRM_DROP            (0x00800000)
+#define FCT_RX_CTL_RX_NOT_EMPTY                (0x00400000)
+#define FCT_RX_CTL_RX_EMPTY            (0x00200000)
+#define FCT_RX_CTL_RX_DISABLED         (0x00100000)
+#define FCT_RX_CTL_RXUSED              (0x0000FFFF)
+
+#define FCT_TX_CTL                     (0x0094)
+#define FCT_TX_CTL_EN                  (0x80000000)
+#define FCT_TX_CTL_RST                 (0x40000000)
+#define FCT_TX_CTL_TX_NOT_EMPTY                (0x00400000)
+#define FCT_TX_CTL_TX_EMPTY            (0x00200000)
+#define FCT_TX_CTL_TX_DISABLED         (0x00100000)
+#define FCT_TX_CTL_TXUSED              (0x0000FFFF)
+
+#define FCT_RX_FIFO_END                        (0x0098)
+#define FCT_RX_FIFO_END_MASK           (0x0000007F)
+
+#define FCT_TX_FIFO_END                        (0x009C)
+#define FCT_TX_FIFO_END_MASK           (0x0000003F)
+
+#define FCT_FLOW                       (0x00A0)
+#define FCT_FLOW_THRESHOLD_OFF         (0x00007F00)
+#define FCT_FLOW_THRESHOLD_OFF_SHIFT   (8)
+#define FCT_FLOW_THRESHOLD_ON          (0x0000007F)
+
+/* MAC CSRs */
+#define MAC_CR                         (0x100)
+#define MAC_CR_ADP                     (0x00002000)
+#define MAC_CR_ADD                     (0x00001000)
+#define MAC_CR_ASD                     (0x00000800)
+#define MAC_CR_INT_LOOP                        (0x00000400)
+#define MAC_CR_BOLMT                   (0x000000C0)
+#define MAC_CR_FDPX                    (0x00000008)
+#define MAC_CR_CFG                     (0x00000006)
+#define MAC_CR_CFG_10                  (0x00000000)
+#define MAC_CR_CFG_100                 (0x00000002)
+#define MAC_CR_CFG_1000                        (0x00000004)
+#define MAC_CR_RST                     (0x00000001)
+
+#define MAC_RX                         (0x104)
+#define MAC_RX_MAX_SIZE                        (0x3FFF0000)
+#define MAC_RX_MAX_SIZE_SHIFT          (16)
+#define MAC_RX_FCS_STRIP               (0x00000010)
+#define MAC_RX_FSE                     (0x00000004)
+#define MAC_RX_RXD                     (0x00000002)
+#define MAC_RX_RXEN                    (0x00000001)
+
+#define MAC_TX                         (0x108)
+#define MAC_TX_BFCS                    (0x00000004)
+#define MAC_TX_TXD                     (0x00000002)
+#define MAC_TX_TXEN                    (0x00000001)
+
+#define FLOW                           (0x10C)
+#define FLOW_FORCE_FC                  (0x80000000)
+#define FLOW_TX_FCEN                   (0x40000000)
+#define FLOW_RX_FCEN                   (0x20000000)
+#define FLOW_FPF                       (0x10000000)
+#define FLOW_PAUSE_TIME                        (0x0000FFFF)
+
+#define RAND_SEED                      (0x110)
+#define RAND_SEED_MASK                 (0x0000FFFF)
+
+#define ERR_STS                                (0x114)
+#define ERR_STS_FCS_ERR                        (0x00000100)
+#define ERR_STS_LFRM_ERR               (0x00000080)
+#define ERR_STS_RUNT_ERR               (0x00000040)
+#define ERR_STS_COLLISION_ERR          (0x00000010)
+#define ERR_STS_ALIGN_ERR              (0x00000008)
+#define ERR_STS_URUN_ERR               (0x00000004)
+
+#define RX_ADDRH                       (0x118)
+#define RX_ADDRH_MASK                  (0x0000FFFF)
+
+#define RX_ADDRL                       (0x11C)
+
+#define MII_ACCESS                     (0x120)
+#define MII_ACCESS_PHY_ADDR            (0x0000F800)
+#define MII_ACCESS_PHY_ADDR_SHIFT      (11)
+#define MII_ACCESS_REG_ADDR            (0x000007C0)
+#define MII_ACCESS_REG_ADDR_SHIFT      (6)
+#define MII_ACCESS_READ                        (0x00000000)
+#define MII_ACCESS_WRITE               (0x00000002)
+#define MII_ACCESS_BUSY                        (0x00000001)
+
+#define MII_DATA                       (0x124)
+#define MII_DATA_MASK                  (0x0000FFFF)
+
+#define WUCSR                          (0x140)
+#define WUCSR_PFDA_FR                  (0x00000080)
+#define WUCSR_WUFR                     (0x00000040)
+#define WUCSR_MPR                      (0x00000020)
+#define WUCSR_BCAST_FR                 (0x00000010)
+#define WUCSR_PFDA_EN                  (0x00000008)
+#define WUCSR_WUEN                     (0x00000004)
+#define WUCSR_MPEN                     (0x00000002)
+#define WUCSR_BCST_EN                  (0x00000001)
+
+#define WUF_CFGX                       (0x144)
+#define WUF_CFGX_EN                    (0x80000000)
+#define WUF_CFGX_ATYPE                 (0x03000000)
+#define WUF_CFGX_ATYPE_UNICAST         (0x00000000)
+#define WUF_CFGX_ATYPE_MULTICAST       (0x02000000)
+#define WUF_CFGX_ATYPE_ALL             (0x03000000)
+#define WUF_CFGX_PATTERN_OFFSET                (0x007F0000)
+#define WUF_CFGX_PATTERN_OFFSET_SHIFT  (16)
+#define WUF_CFGX_CRC16                 (0x0000FFFF)
+#define WUF_NUM                                (8)
+
+#define WUF_MASKX                      (0x170)
+#define WUF_MASKX_AVALID               (0x80000000)
+#define WUF_MASKX_ATYPE                        (0x40000000)
+
+#define ADDR_FILTX                     (0x300)
+#define ADDR_FILTX_FB_VALID            (0x80000000)
+#define ADDR_FILTX_FB_TYPE             (0x40000000)
+#define ADDR_FILTX_FB_ADDRHI           (0x0000FFFF)
+#define ADDR_FILTX_SB_ADDRLO           (0xFFFFFFFF)
+
+#define WUCSR2                         (0x500)
+#define WUCSR2_NS_RCD                  (0x00000040)
+#define WUCSR2_ARP_RCD                 (0x00000020)
+#define WUCSR2_TCPSYN_RCD              (0x00000010)
+#define WUCSR2_NS_OFFLOAD              (0x00000004)
+#define WUCSR2_ARP_OFFLOAD             (0x00000002)
+#define WUCSR2_TCPSYN_OFFLOAD          (0x00000001)
+
+#define WOL_FIFO_STS                   (0x504)
+
+#define IPV6_ADDRX                     (0x510)
+
+#define IPV4_ADDRX                     (0x590)
+
+
+/* Vendor-specific PHY Definitions */
+
+/* Mode Control/Status Register */
+#define PHY_MODE_CTRL_STS              (17)
+#define MODE_CTRL_STS_EDPWRDOWN                ((u16)0x2000)
+#define MODE_CTRL_STS_ENERGYON         ((u16)0x0002)
+
+#define PHY_INT_SRC                    (29)
+#define PHY_INT_SRC_ENERGY_ON          ((u16)0x0080)
+#define PHY_INT_SRC_ANEG_COMP          ((u16)0x0040)
+#define PHY_INT_SRC_REMOTE_FAULT       ((u16)0x0020)
+#define PHY_INT_SRC_LINK_DOWN          ((u16)0x0010)
+
+#define PHY_INT_MASK                   (30)
+#define PHY_INT_MASK_ENERGY_ON         ((u16)0x0080)
+#define PHY_INT_MASK_ANEG_COMP         ((u16)0x0040)
+#define PHY_INT_MASK_REMOTE_FAULT      ((u16)0x0020)
+#define PHY_INT_MASK_LINK_DOWN         ((u16)0x0010)
+#define PHY_INT_MASK_DEFAULT           (PHY_INT_MASK_ANEG_COMP | \
+                                        PHY_INT_MASK_LINK_DOWN)
+
+#define PHY_SPECIAL                    (31)
+#define PHY_SPECIAL_SPD                        ((u16)0x001C)
+#define PHY_SPECIAL_SPD_10HALF         ((u16)0x0004)
+#define PHY_SPECIAL_SPD_10FULL         ((u16)0x0014)
+#define PHY_SPECIAL_SPD_100HALF                ((u16)0x0008)
+#define PHY_SPECIAL_SPD_100FULL                ((u16)0x0018)
+
+/* USB Vendor Requests */
+#define USB_VENDOR_REQUEST_WRITE_REGISTER      0xA0
+#define USB_VENDOR_REQUEST_READ_REGISTER       0xA1
+#define USB_VENDOR_REQUEST_GET_STATS           0xA2
+
+/* Interrupt Endpoint status word bitfields */
+#define INT_ENP_RDFO_INT               ((u32)BIT(22))
+#define INT_ENP_TXE_INT                        ((u32)BIT(21))
+#define INT_ENP_TX_DIS_INT             ((u32)BIT(19))
+#define INT_ENP_RX_DIS_INT             ((u32)BIT(18))
+#define INT_ENP_PHY_INT                        ((u32)BIT(17))
+#define INT_ENP_MAC_ERR_INT            ((u32)BIT(15))
+#define INT_ENP_RX_FIFO_DATA_INT       ((u32)BIT(12))
+
+#endif /* _SMSC75XX_H */
index df9179a..d222d7e 100644 (file)
@@ -709,6 +709,8 @@ static void smsc95xx_start_rx_path(struct usbnet *dev)
 
 static int smsc95xx_phy_initialize(struct usbnet *dev)
 {
+       int bmcr, timeout = 0;
+
        /* Initialize MII structure */
        dev->mii.dev = dev->net;
        dev->mii.mdio_read = smsc95xx_mdio_read;
@@ -717,7 +719,20 @@ static int smsc95xx_phy_initialize(struct usbnet *dev)
        dev->mii.reg_num_mask = 0x1f;
        dev->mii.phy_id = SMSC95XX_INTERNAL_PHY_ID;
 
+       /* reset phy and wait for reset to complete */
        smsc95xx_mdio_write(dev->net, dev->mii.phy_id, MII_BMCR, BMCR_RESET);
+
+       do {
+               msleep(10);
+               bmcr = smsc95xx_mdio_read(dev->net, dev->mii.phy_id, MII_BMCR);
+               timeout++;
+       } while ((bmcr & MII_BMCR) && (timeout < 100));
+
+       if (timeout >= 100) {
+               netdev_warn(dev->net, "timeout on PHY Reset");
+               return -EIO;
+       }
+
        smsc95xx_mdio_write(dev->net, dev->mii.phy_id, MII_ADVERTISE,
                ADVERTISE_ALL | ADVERTISE_CSMA | ADVERTISE_PAUSE_CAP |
                ADVERTISE_PAUSE_ASYM);
index a04f21c..f5da626 100644 (file)
@@ -133,6 +133,7 @@ static int __devinit i82092aa_pci_probe(struct pci_dev *dev, const struct pci_de
                sockets[i].socket.map_size = 0x1000;
                sockets[i].socket.irq_mask = 0;
                sockets[i].socket.pci_irq  = dev->irq;
+               sockets[i].socket.cb_dev  = dev;
                sockets[i].socket.owner = THIS_MODULE;
 
                sockets[i].number = i;
index 849ef1b..3f84d7a 100644 (file)
@@ -95,6 +95,7 @@
 #define I365_CSC_DETECT        0x08
 #define I365_CSC_ANY   0x0F
 #define I365_CSC_GPI   0x10
+#define I365_CSC_IRQ_MASK      0xF0
 
 /* Flags for I365_ADDRWIN */
 #define I365_ENA_IO(map)       (0x40 << (map))
index b2df041..c4612c5 100644 (file)
@@ -256,6 +256,7 @@ int pcmcia_modify_configuration(struct pcmcia_device *p_dev,
 {
        struct pcmcia_socket *s;
        config_t *c;
+       int ret;
 
        s = p_dev->socket;
 
@@ -264,13 +265,13 @@ int pcmcia_modify_configuration(struct pcmcia_device *p_dev,
 
        if (!(s->state & SOCKET_PRESENT)) {
                dev_dbg(&s->dev, "No card present\n");
-               mutex_unlock(&s->ops_mutex);
-               return -ENODEV;
+               ret = -ENODEV;
+               goto unlock;
        }
        if (!(c->state & CONFIG_LOCKED)) {
                dev_dbg(&s->dev, "Configuration isnt't locked\n");
-               mutex_unlock(&s->ops_mutex);
-               return -EACCES;
+               ret = -EACCES;
+               goto unlock;
        }
 
        if (mod->Attributes & CONF_IRQ_CHANGE_VALID) {
@@ -286,7 +287,8 @@ int pcmcia_modify_configuration(struct pcmcia_device *p_dev,
 
        if (mod->Attributes & CONF_VCC_CHANGE_VALID) {
                dev_dbg(&s->dev, "changing Vcc is not allowed at this time\n");
-               return -EINVAL;
+               ret = -EINVAL;
+               goto unlock;
        }
 
        /* We only allow changing Vpp1 and Vpp2 to the same value */
@@ -294,21 +296,21 @@ int pcmcia_modify_configuration(struct pcmcia_device *p_dev,
            (mod->Attributes & CONF_VPP2_CHANGE_VALID)) {
                if (mod->Vpp1 != mod->Vpp2) {
                        dev_dbg(&s->dev, "Vpp1 and Vpp2 must be the same\n");
-                       mutex_unlock(&s->ops_mutex);
-                       return -EINVAL;
+                       ret = -EINVAL;
+                       goto unlock;
                }
                s->socket.Vpp = mod->Vpp1;
                if (s->ops->set_socket(s, &s->socket)) {
-                       mutex_unlock(&s->ops_mutex);
                        dev_printk(KERN_WARNING, &s->dev,
                                   "Unable to set VPP\n");
-                       return -EIO;
+                       ret = -EIO;
+                       goto unlock;
                }
        } else if ((mod->Attributes & CONF_VPP1_CHANGE_VALID) ||
                   (mod->Attributes & CONF_VPP2_CHANGE_VALID)) {
                dev_dbg(&s->dev, "changing Vcc is not allowed at this time\n");
-               mutex_unlock(&s->ops_mutex);
-               return -EINVAL;
+               ret = -EINVAL;
+               goto unlock;
        }
 
        if (mod->Attributes & CONF_IO_CHANGE_WIDTH) {
@@ -332,9 +334,11 @@ int pcmcia_modify_configuration(struct pcmcia_device *p_dev,
                        s->ops->set_io_map(s, &io_on);
                }
        }
+       ret = 0;
+unlock:
        mutex_unlock(&s->ops_mutex);
 
-       return 0;
+       return ret;
 } /* modify_configuration */
 EXPORT_SYMBOL(pcmcia_modify_configuration);
 
@@ -752,14 +756,6 @@ int pcmcia_request_irq(struct pcmcia_device *p_dev, irq_req_t *req)
 
 #ifdef CONFIG_PCMCIA_PROBE
 
-#ifdef IRQ_NOAUTOEN
-       /* if the underlying IRQ infrastructure allows for it, only allocate
-        * the IRQ, but do not enable it
-        */
-       if (!(req->Handler))
-               type |= IRQ_NOAUTOEN;
-#endif /* IRQ_NOAUTOEN */
-
        if (s->irq.AssignedIRQ != 0) {
                /* If the interrupt is already assigned, it must be the same */
                irq = s->irq.AssignedIRQ;
index 7c20491..7ba57a5 100644 (file)
@@ -671,6 +671,7 @@ static int __devinit pd6729_pci_probe(struct pci_dev *dev,
                socket[i].socket.map_size = 0x1000;
                socket[i].socket.irq_mask = mask;
                socket[i].socket.pci_irq  = dev->irq;
+               socket[i].socket.cb_dev = dev;
                socket[i].socket.owner = THIS_MODULE;
 
                socket[i].number = i;
index aaa7022..9ffa97d 100644 (file)
@@ -296,7 +296,7 @@ static int ti_init(struct yenta_socket *socket)
        u8 new, reg = exca_readb(socket, I365_INTCTL);
 
        new = reg & ~I365_INTR_ENA;
-       if (socket->cb_irq)
+       if (socket->dev->irq)
                new |= I365_INTR_ENA;
        if (new != reg)
                exca_writeb(socket, I365_INTCTL, new);
@@ -316,14 +316,47 @@ static int ti_override(struct yenta_socket *socket)
        return 0;
 }
 
+static void ti113x_use_isa_irq(struct yenta_socket *socket)
+{
+       int isa_irq = -1;
+       u8 intctl;
+       u32 isa_irq_mask = 0;
+
+       if (!isa_probe)
+               return;
+
+       /* get a free isa int */
+       isa_irq_mask = yenta_probe_irq(socket, isa_interrupts);
+       if (!isa_irq_mask)
+               return; /* no useable isa irq found */
+
+       /* choose highest available */
+       for (; isa_irq_mask; isa_irq++)
+               isa_irq_mask >>= 1;
+       socket->cb_irq = isa_irq;
+
+       exca_writeb(socket, I365_CSCINT, (isa_irq << 4));
+
+       intctl = exca_readb(socket, I365_INTCTL);
+       intctl &= ~(I365_INTR_ENA | I365_IRQ_MASK);     /* CSC Enable */
+       exca_writeb(socket, I365_INTCTL, intctl);
+
+       dev_info(&socket->dev->dev,
+               "Yenta TI113x: using isa irq %d for CardBus\n", isa_irq);
+}
+
+
 static int ti113x_override(struct yenta_socket *socket)
 {
        u8 cardctl;
 
        cardctl = config_readb(socket, TI113X_CARD_CONTROL);
        cardctl &= ~(TI113X_CCR_PCI_IRQ_ENA | TI113X_CCR_PCI_IREQ | TI113X_CCR_PCI_CSC);
-       if (socket->cb_irq)
+       if (socket->dev->irq)
                cardctl |= TI113X_CCR_PCI_IRQ_ENA | TI113X_CCR_PCI_CSC | TI113X_CCR_PCI_IREQ;
+       else
+               ti113x_use_isa_irq(socket);
+
        config_writeb(socket, TI113X_CARD_CONTROL, cardctl);
 
        return ti_override(socket);
index c9fcbdc..aaccdb9 100644 (file)
@@ -105,6 +105,7 @@ typedef struct vrc4171_socket {
        char name[24];
        int csc_irq;
        int io_irq;
+       spinlock_t lock;
 } vrc4171_socket_t;
 
 static vrc4171_socket_t vrc4171_sockets[CARD_MAX_SLOTS];
@@ -327,7 +328,7 @@ static int pccard_set_socket(struct pcmcia_socket *sock, socket_state_t *state)
        slot = sock->sock;
        socket = &vrc4171_sockets[slot];
 
-       spin_lock_irq(&sock->lock);
+       spin_lock_irq(&socket->lock);
 
        voltage = set_Vcc_value(state->Vcc);
        exca_write_byte(slot, CARD_VOLTAGE_SELECT, voltage);
@@ -370,7 +371,7 @@ static int pccard_set_socket(struct pcmcia_socket *sock, socket_state_t *state)
                cscint |= I365_CSC_DETECT;
         exca_write_byte(slot, I365_CSCINT, cscint);
 
-       spin_unlock_irq(&sock->lock);
+       spin_unlock_irq(&socket->lock);
 
        return 0;
 }
index 967c766..418988a 100644 (file)
@@ -42,6 +42,18 @@ module_param_string(o2_speedup, o2_speedup, sizeof(o2_speedup), 0444);
 MODULE_PARM_DESC(o2_speedup, "Use prefetch/burst for O2-bridges: 'on', 'off' "
        "or 'default' (uses recommended behaviour for the detected bridge)");
 
+/*
+ * Only probe "regular" interrupts, don't
+ * touch dangerous spots like the mouse irq,
+ * because there are mice that apparently
+ * get really confused if they get fondled
+ * too intimately.
+ *
+ * Default to 11, 10, 9, 7, 6, 5, 4, 3.
+ */
+static u32 isa_interrupts = 0x0ef8;
+
+
 #define debug(x, s, args...) dev_dbg(&s->dev->dev, x, ##args)
 
 /* Don't ask.. */
@@ -54,6 +66,8 @@ MODULE_PARM_DESC(o2_speedup, "Use prefetch/burst for O2-bridges: 'on', 'off' "
  */
 #ifdef CONFIG_YENTA_TI
 static int yenta_probe_cb_irq(struct yenta_socket *socket);
+static unsigned int yenta_probe_irq(struct yenta_socket *socket,
+                               u32 isa_irq_mask);
 #endif
 
 
@@ -329,8 +343,8 @@ static int yenta_set_socket(struct pcmcia_socket *sock, socket_state_t *state)
                /* ISA interrupt control? */
                intr = exca_readb(socket, I365_INTCTL);
                intr = (intr & ~0xf);
-               if (!socket->cb_irq) {
-                       intr |= state->io_irq;
+               if (!socket->dev->irq) {
+                       intr |= socket->cb_irq ? socket->cb_irq : state->io_irq;
                        bridge |= CB_BRIDGE_INTR;
                }
                exca_writeb(socket, I365_INTCTL, intr);
@@ -340,7 +354,7 @@ static int yenta_set_socket(struct pcmcia_socket *sock, socket_state_t *state)
                reg = exca_readb(socket, I365_INTCTL) & (I365_RING_ENA | I365_INTR_ENA);
                reg |= (state->flags & SS_RESET) ? 0 : I365_PC_RESET;
                reg |= (state->flags & SS_IOCARD) ? I365_PC_IOCARD : 0;
-               if (state->io_irq != socket->cb_irq) {
+               if (state->io_irq != socket->dev->irq) {
                        reg |= state->io_irq;
                        bridge |= CB_BRIDGE_INTR;
                }
@@ -356,7 +370,9 @@ static int yenta_set_socket(struct pcmcia_socket *sock, socket_state_t *state)
                        exca_writeb(socket, I365_POWER, reg);
 
                /* CSC interrupt: no ISA irq for CSC */
-               reg = I365_CSC_DETECT;
+               reg = exca_readb(socket, I365_CSCINT);
+               reg &= I365_CSC_IRQ_MASK;
+               reg |= I365_CSC_DETECT;
                if (state->flags & SS_IOCARD) {
                        if (state->csc_mask & SS_STSCHG)
                                reg |= I365_CSC_STSCHG;
@@ -896,22 +912,12 @@ static struct cardbus_type cardbus_type[] = {
 };
 
 
-/*
- * Only probe "regular" interrupts, don't
- * touch dangerous spots like the mouse irq,
- * because there are mice that apparently
- * get really confused if they get fondled
- * too intimately.
- *
- * Default to 11, 10, 9, 7, 6, 5, 4, 3.
- */
-static u32 isa_interrupts = 0x0ef8;
-
 static unsigned int yenta_probe_irq(struct yenta_socket *socket, u32 isa_irq_mask)
 {
        int i;
        unsigned long val;
        u32 mask;
+       u8 reg;
 
        /*
         * Probe for usable interrupts using the force
@@ -919,6 +925,7 @@ static unsigned int yenta_probe_irq(struct yenta_socket *socket, u32 isa_irq_mas
         */
        cb_writel(socket, CB_SOCKET_EVENT, -1);
        cb_writel(socket, CB_SOCKET_MASK, CB_CSTSMASK);
+       reg = exca_readb(socket, I365_CSCINT);
        exca_writeb(socket, I365_CSCINT, 0);
        val = probe_irq_on() & isa_irq_mask;
        for (i = 1; i < 16; i++) {
@@ -930,7 +937,7 @@ static unsigned int yenta_probe_irq(struct yenta_socket *socket, u32 isa_irq_mas
                cb_writel(socket, CB_SOCKET_EVENT, -1);
        }
        cb_writel(socket, CB_SOCKET_MASK, 0);
-       exca_writeb(socket, I365_CSCINT, 0);
+       exca_writeb(socket, I365_CSCINT, reg);
 
        mask = probe_irq_mask(val) & 0xffff;
 
@@ -967,6 +974,8 @@ static irqreturn_t yenta_probe_handler(int irq, void *dev_id)
 /* probes the PCI interrupt, use only on override functions */
 static int yenta_probe_cb_irq(struct yenta_socket *socket)
 {
+       u8 reg;
+
        if (!socket->cb_irq)
                return -1;
 
@@ -979,7 +988,8 @@ static int yenta_probe_cb_irq(struct yenta_socket *socket)
        }
 
        /* generate interrupt, wait */
-       exca_writeb(socket, I365_CSCINT, I365_CSC_STSCHG);
+       reg = exca_readb(socket, I365_CSCINT);
+       exca_writeb(socket, I365_CSCINT, reg | I365_CSC_STSCHG);
        cb_writel(socket, CB_SOCKET_EVENT, -1);
        cb_writel(socket, CB_SOCKET_MASK, CB_CSTSMASK);
        cb_writel(socket, CB_SOCKET_FORCE, CB_FCARDSTS);
@@ -988,7 +998,7 @@ static int yenta_probe_cb_irq(struct yenta_socket *socket)
 
        /* disable interrupts */
        cb_writel(socket, CB_SOCKET_MASK, 0);
-       exca_writeb(socket, I365_CSCINT, 0);
+       exca_writeb(socket, I365_CSCINT, reg);
        cb_writel(socket, CB_SOCKET_EVENT, -1);
        exca_readb(socket, I365_CSC);
 
index 226b3e9..cbca40a 100644 (file)
@@ -922,9 +922,13 @@ static struct backlight_ops acer_bl_ops = {
 
 static int __devinit acer_backlight_init(struct device *dev)
 {
+       struct backlight_properties props;
        struct backlight_device *bd;
 
-       bd = backlight_device_register("acer-wmi", dev, NULL, &acer_bl_ops);
+       memset(&props, 0, sizeof(struct backlight_properties));
+       props.max_brightness = max_brightness;
+       bd = backlight_device_register("acer-wmi", dev, NULL, &acer_bl_ops,
+                                      &props);
        if (IS_ERR(bd)) {
                printk(ACER_ERR "Could not register Acer backlight device\n");
                acer_backlight_device = NULL;
@@ -935,7 +939,6 @@ static int __devinit acer_backlight_init(struct device *dev)
 
        bd->props.power = FB_BLANK_UNBLANK;
        bd->props.brightness = read_brightness(bd);
-       bd->props.max_brightness = max_brightness;
        backlight_update_status(bd);
        return 0;
 }
index 791fcf3..db5f7db 100644 (file)
@@ -639,12 +639,16 @@ static int asus_backlight_init(struct asus_laptop *asus)
 {
        struct backlight_device *bd;
        struct device *dev = &asus->platform_device->dev;
+       struct backlight_properties props;
 
        if (!acpi_check_handle(asus->handle, METHOD_BRIGHTNESS_GET, NULL) &&
            !acpi_check_handle(asus->handle, METHOD_BRIGHTNESS_SET, NULL) &&
            lcd_switch_handle) {
+               memset(&props, 0, sizeof(struct backlight_properties));
+               props.max_brightness = 15;
+
                bd = backlight_device_register(ASUS_LAPTOP_FILE, dev,
-                                              asus, &asusbl_ops);
+                                              asus, &asusbl_ops, &props);
                if (IS_ERR(bd)) {
                        pr_err("Could not register asus backlight device\n");
                        asus->backlight_device = NULL;
@@ -653,7 +657,6 @@ static int asus_backlight_init(struct asus_laptop *asus)
 
                asus->backlight_device = bd;
 
-               bd->props.max_brightness = 15;
                bd->props.power = FB_BLANK_UNBLANK;
                bd->props.brightness = asus_read_brightness(bd);
                backlight_update_status(bd);
index 1381430..ee52035 100644 (file)
@@ -1481,6 +1481,7 @@ static void asus_acpi_exit(void)
 
 static int __init asus_acpi_init(void)
 {
+       struct backlight_properties props;
        int result;
 
        result = acpi_bus_register_driver(&asus_hotk_driver);
@@ -1507,15 +1508,17 @@ static int __init asus_acpi_init(void)
                return -ENODEV;
        }
 
+       memset(&props, 0, sizeof(struct backlight_properties));
+       props.max_brightness = 15;
        asus_backlight_device = backlight_device_register("asus", NULL, NULL,
-                                                         &asus_backlight_data);
+                                                         &asus_backlight_data,
+                                                         &props);
        if (IS_ERR(asus_backlight_device)) {
                printk(KERN_ERR "Could not register asus backlight device\n");
                asus_backlight_device = NULL;
                asus_acpi_exit();
                return -ENODEV;
        }
-       asus_backlight_device->props.max_brightness = 15;
 
        return 0;
 }
index 035a7dd..c696cf1 100644 (file)
@@ -455,18 +455,22 @@ static int cmpc_bl_update_status(struct backlight_device *bd)
                return -1;
 }
 
-static struct backlight_ops cmpc_bl_ops = {
+static const struct backlight_ops cmpc_bl_ops = {
        .get_brightness = cmpc_bl_get_brightness,
        .update_status = cmpc_bl_update_status
 };
 
 static int cmpc_bl_add(struct acpi_device *acpi)
 {
+       struct backlight_properties props;
        struct backlight_device *bd;
 
-       bd = backlight_device_register("cmpc_bl", &acpi->dev,
-                                      acpi->handle, &cmpc_bl_ops);
-       bd->props.max_brightness = 7;
+       memset(&props, 0, sizeof(struct backlight_properties));
+       props.max_brightness = 7;
+       bd = backlight_device_register("cmpc_bl", &acpi->dev, acpi->handle,
+                                      &cmpc_bl_ops, &props);
+       if (IS_ERR(bd))
+               return PTR_ERR(bd);
        dev_set_drvdata(&acpi->dev, bd);
        return 0;
 }
index 2740b40..71ff154 100644 (file)
@@ -291,12 +291,15 @@ static int __init compal_init(void)
        /* Register backlight stuff */
 
        if (!acpi_video_backlight_support()) {
-               compalbl_device = backlight_device_register("compal-laptop", NULL, NULL,
-                                                           &compalbl_ops);
+               struct backlight_properties props;
+               memset(&props, 0, sizeof(struct backlight_properties));
+               props.max_brightness = COMPAL_LCD_LEVEL_MAX - 1;
+               compalbl_device = backlight_device_register("compal-laptop",
+                                                           NULL, NULL,
+                                                           &compalbl_ops,
+                                                           &props);
                if (IS_ERR(compalbl_device))
                        return PTR_ERR(compalbl_device);
-
-               compalbl_device->props.max_brightness = COMPAL_LCD_LEVEL_MAX-1;
        }
 
        ret = platform_driver_register(&compal_driver);
index ef61497..46435ac 100644 (file)
@@ -559,10 +559,14 @@ static int __init dell_init(void)
        release_buffer();
 
        if (max_intensity) {
-               dell_backlight_device = backlight_device_register(
-                       "dell_backlight",
-                       &platform_device->dev, NULL,
-                       &dell_ops);
+               struct backlight_properties props;
+               memset(&props, 0, sizeof(struct backlight_properties));
+               props.max_brightness = max_intensity;
+               dell_backlight_device = backlight_device_register("dell_backlight",
+                                                                 &platform_device->dev,
+                                                                 NULL,
+                                                                 &dell_ops,
+                                                                 &props);
 
                if (IS_ERR(dell_backlight_device)) {
                        ret = PTR_ERR(dell_backlight_device);
@@ -570,7 +574,6 @@ static int __init dell_init(void)
                        goto fail_backlight;
                }
 
-               dell_backlight_device->props.max_brightness = max_intensity;
                dell_backlight_device->props.brightness =
                        dell_get_intensity(dell_backlight_device);
                backlight_update_status(dell_backlight_device);
index 9a844ca..3fdf21e 100644 (file)
@@ -1131,18 +1131,20 @@ static int eeepc_backlight_notify(struct eeepc_laptop *eeepc)
 
 static int eeepc_backlight_init(struct eeepc_laptop *eeepc)
 {
+       struct backlight_properties props;
        struct backlight_device *bd;
 
+       memset(&props, 0, sizeof(struct backlight_properties));
+       props.max_brightness = 15;
        bd = backlight_device_register(EEEPC_LAPTOP_FILE,
-                                      &eeepc->platform_device->dev,
-                                      eeepc, &eeepcbl_ops);
+                                      &eeepc->platform_device->dev, eeepc,
+                                      &eeepcbl_ops, &props);
        if (IS_ERR(bd)) {
                pr_err("Could not register eeepc backlight device\n");
                eeepc->backlight_device = NULL;
                return PTR_ERR(bd);
        }
        eeepc->backlight_device = bd;
-       bd->props.max_brightness = 15;
        bd->props.brightness = read_brightness(bd);
        bd->props.power = FB_BLANK_UNBLANK;
        backlight_update_status(bd);
index 5f3320d..c1074b3 100644 (file)
@@ -1126,16 +1126,20 @@ static int __init fujitsu_init(void)
        /* Register backlight stuff */
 
        if (!acpi_video_backlight_support()) {
-               fujitsu->bl_device =
-                       backlight_device_register("fujitsu-laptop", NULL, NULL,
-                                                 &fujitsubl_ops);
+               struct backlight_properties props;
+
+               memset(&props, 0, sizeof(struct backlight_properties));
+               max_brightness = fujitsu->max_brightness;
+               props.max_brightness = max_brightness - 1;
+               fujitsu->bl_device = backlight_device_register("fujitsu-laptop",
+                                                              NULL, NULL,
+                                                              &fujitsubl_ops,
+                                                              &props);
                if (IS_ERR(fujitsu->bl_device)) {
                        ret = PTR_ERR(fujitsu->bl_device);
                        fujitsu->bl_device = NULL;
                        goto fail_sysfs_group;
                }
-               max_brightness = fujitsu->max_brightness;
-               fujitsu->bl_device->props.max_brightness = max_brightness - 1;
                fujitsu->bl_device->props.brightness = fujitsu->brightness_level;
        }
 
index c2b05da..996223a 100644 (file)
@@ -683,11 +683,14 @@ static int __init msi_init(void)
                printk(KERN_INFO "MSI: Brightness ignored, must be controlled "
                       "by ACPI video driver\n");
        } else {
+               struct backlight_properties props;
+               memset(&props, 0, sizeof(struct backlight_properties));
+               props.max_brightness = MSI_LCD_LEVEL_MAX - 1;
                msibl_device = backlight_device_register("msi-laptop-bl", NULL,
-                                                        NULL, &msibl_ops);
+                                                        NULL, &msibl_ops,
+                                                        &props);
                if (IS_ERR(msibl_device))
                        return PTR_ERR(msibl_device);
-               msibl_device->props.max_brightness = MSI_LCD_LEVEL_MAX-1;
        }
 
        ret = platform_driver_register(&msipf_driver);
index f5f70d4..367caaa 100644 (file)
@@ -138,7 +138,7 @@ static int bl_set_status(struct backlight_device *bd)
        return msi_wmi_set_block(0, backlight_map[bright]);
 }
 
-static struct backlight_ops msi_backlight_ops = {
+static const struct backlight_ops msi_backlight_ops = {
        .get_brightness = bl_get,
        .update_status  = bl_set_status,
 };
@@ -249,12 +249,17 @@ static int __init msi_wmi_init(void)
                goto err_uninstall_notifier;
 
        if (!acpi_video_backlight_support()) {
-               backlight = backlight_device_register(DRV_NAME,
-                               NULL, NULL, &msi_backlight_ops);
-               if (IS_ERR(backlight))
+               struct backlight_properties props;
+               memset(&props, 0, sizeof(struct backlight_properties));
+               props.max_brightness = ARRAY_SIZE(backlight_map) - 1;
+               backlight = backlight_device_register(DRV_NAME, NULL, NULL,
+                                                     &msi_backlight_ops,
+                                                     &props);
+               if (IS_ERR(backlight)) {
+                       err = PTR_ERR(backlight);
                        goto err_free_input;
+               }
 
-               backlight->props.max_brightness = ARRAY_SIZE(backlight_map) - 1;
                err = bl_get(NULL);
                if (err < 0)
                        goto err_free_backlight;
index c9fc479..726f02a 100644 (file)
@@ -352,7 +352,7 @@ static int bl_set_status(struct backlight_device *bd)
        return acpi_pcc_write_sset(pcc, SINF_DC_CUR_BRIGHT, bright);
 }
 
-static struct backlight_ops pcc_backlight_ops = {
+static const struct backlight_ops pcc_backlight_ops = {
        .get_brightness = bl_get,
        .update_status  = bl_set_status,
 };
@@ -600,6 +600,7 @@ static int acpi_pcc_hotkey_resume(struct acpi_device *device)
 
 static int acpi_pcc_hotkey_add(struct acpi_device *device)
 {
+       struct backlight_properties props;
        struct pcc_acpi *pcc;
        int num_sifr, result;
 
@@ -637,24 +638,25 @@ static int acpi_pcc_hotkey_add(struct acpi_device *device)
        if (result) {
                ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
                                  "Error installing keyinput handler\n"));
-               goto out_sinf;
+               goto out_hotkey;
        }
 
-       /* initialize backlight */
-       pcc->backlight = backlight_device_register("panasonic", NULL, pcc,
-                                                  &pcc_backlight_ops);
-       if (IS_ERR(pcc->backlight))
-               goto out_input;
-
        if (!acpi_pcc_retrieve_biosdata(pcc, pcc->sinf)) {
                ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
                                 "Couldn't retrieve BIOS data\n"));
-               goto out_backlight;
+               goto out_input;
+       }
+       /* initialize backlight */
+       memset(&props, 0, sizeof(struct backlight_properties));
+       props.max_brightness = pcc->sinf[SINF_AC_MAX_BRIGHT];
+       pcc->backlight = backlight_device_register("panasonic", NULL, pcc,
+                                                  &pcc_backlight_ops, &props);
+       if (IS_ERR(pcc->backlight)) {
+               result = PTR_ERR(pcc->backlight);
+               goto out_sinf;
        }
 
        /* read the initial brightness setting from the hardware */
-       pcc->backlight->props.max_brightness =
-                                       pcc->sinf[SINF_AC_MAX_BRIGHT];
        pcc->backlight->props.brightness = pcc->sinf[SINF_AC_CUR_BRIGHT];
 
        /* read the initial sticky key mode from the hardware */
@@ -669,12 +671,12 @@ static int acpi_pcc_hotkey_add(struct acpi_device *device)
 
 out_backlight:
        backlight_device_unregister(pcc->backlight);
+out_sinf:
+       kfree(pcc->sinf);
 out_input:
        input_unregister_device(pcc->input_dev);
        /* no need to input_free_device() since core input API refcount and
         * free()s the device */
-out_sinf:
-       kfree(pcc->sinf);
 out_hotkey:
        kfree(pcc);
 
index 5a3d851..6553b91 100644 (file)
@@ -1291,9 +1291,13 @@ static int sony_nc_add(struct acpi_device *device)
                       "controlled by ACPI video driver\n");
        } else if (ACPI_SUCCESS(acpi_get_handle(sony_nc_acpi_handle, "GBRT",
                                                &handle))) {
+                                                       struct backlight_properties props;
+               memset(&props, 0, sizeof(struct backlight_properties));
+               props.max_brightness = SONY_MAX_BRIGHTNESS - 1;
                sony_backlight_device = backlight_device_register("sony", NULL,
                                                                  NULL,
-                                                                 &sony_backlight_ops);
+                                                                 &sony_backlight_ops,
+                                                                 &props);
 
                if (IS_ERR(sony_backlight_device)) {
                        printk(KERN_WARNING DRV_PFX "unable to register backlight device\n");
@@ -1302,8 +1306,6 @@ static int sony_nc_add(struct acpi_device *device)
                        sony_backlight_device->props.brightness =
                            sony_backlight_get_brightness
                            (sony_backlight_device);
-                       sony_backlight_device->props.max_brightness =
-                           SONY_MAX_BRIGHTNESS - 1;
                }
 
        }
index c64e352..770b853 100644 (file)
@@ -6170,6 +6170,7 @@ static const struct tpacpi_quirk brightness_quirk_table[] __initconst = {
 
 static int __init brightness_init(struct ibm_init_struct *iibm)
 {
+       struct backlight_properties props;
        int b;
        unsigned long quirks;
 
@@ -6259,9 +6260,12 @@ static int __init brightness_init(struct ibm_init_struct *iibm)
                printk(TPACPI_INFO
                       "detected a 16-level brightness capable ThinkPad\n");
 
-       ibm_backlight_device = backlight_device_register(
-                                       TPACPI_BACKLIGHT_DEV_NAME, NULL, NULL,
-                                       &ibm_backlight_data);
+       memset(&props, 0, sizeof(struct backlight_properties));
+       props.max_brightness = (tp_features.bright_16levels) ? 15 : 7;
+       ibm_backlight_device = backlight_device_register(TPACPI_BACKLIGHT_DEV_NAME,
+                                                        NULL, NULL,
+                                                        &ibm_backlight_data,
+                                                        &props);
        if (IS_ERR(ibm_backlight_device)) {
                int rc = PTR_ERR(ibm_backlight_device);
                ibm_backlight_device = NULL;
@@ -6280,8 +6284,6 @@ static int __init brightness_init(struct ibm_init_struct *iibm)
                        "or not on your ThinkPad\n", TPACPI_MAIL);
        }
 
-       ibm_backlight_device->props.max_brightness =
-                               (tp_features.bright_16levels)? 15 : 7;
        ibm_backlight_device->props.brightness = b & TP_EC_BACKLIGHT_LVLMSK;
        backlight_update_status(ibm_backlight_device);
 
index 789240d..def4841 100644 (file)
@@ -924,6 +924,7 @@ static int __init toshiba_acpi_init(void)
        u32 hci_result;
        bool bt_present;
        int ret = 0;
+       struct backlight_properties props;
 
        if (acpi_disabled)
                return -ENODEV;
@@ -974,10 +975,12 @@ static int __init toshiba_acpi_init(void)
                }
        }
 
+       props.max_brightness = HCI_LCD_BRIGHTNESS_LEVELS - 1;
        toshiba_backlight_device = backlight_device_register("toshiba",
-                                               &toshiba_acpi.p_dev->dev,
-                                               NULL,
-                                               &toshiba_backlight_data);
+                                                            &toshiba_acpi.p_dev->dev,
+                                                            NULL,
+                                                            &toshiba_backlight_data,
+                                                            &props);
         if (IS_ERR(toshiba_backlight_device)) {
                ret = PTR_ERR(toshiba_backlight_device);
 
@@ -986,7 +989,6 @@ static int __init toshiba_acpi_init(void)
                toshiba_acpi_exit();
                return ret;
        }
-        toshiba_backlight_device->props.max_brightness = HCI_LCD_BRIGHTNESS_LEVELS - 1;
 
        /* Register rfkill switch for Bluetooth */
        if (hci_get_bt_present(&bt_present) == HCI_SUCCESS && bt_present) {
index b3beab6..fc7ae05 100644 (file)
@@ -704,6 +704,13 @@ int sclp_chp_deconfigure(struct chp_id chpid)
        return do_chp_configure(SCLP_CMDW_DECONFIGURE_CHPATH | chpid.id << 8);
 }
 
+int arch_get_memory_phys_device(unsigned long start_pfn)
+{
+       if (!rzm)
+               return 0;
+       return PFN_PHYS(start_pfn) / rzm;
+}
+
 struct chp_info_sccb {
        struct sccb_header header;
        u8 recognized[SCLP_CHP_INFO_MASK_SIZE];
index c2341af..0212464 100644 (file)
@@ -1717,6 +1717,7 @@ static int nsp_cs_config(struct pcmcia_device *link)
        cfg_mem->data = data;
 
        ret = pcmcia_loop_config(link, nsp_cs_config_check, cfg_mem);
+       if (ret)
                goto cs_failed;
 
        if (link->conf.Attributes & CONF_ENABLE_IRQ) {
index d514e28..d2e0321 100644 (file)
@@ -474,7 +474,7 @@ static void sunsab_stop_rx(struct uart_port *port)
 {
        struct uart_sunsab_port *up = (struct uart_sunsab_port *) port;
 
-       up->interrupt_mask0 |= SAB82532_ISR0_TCD;
+       up->interrupt_mask0 |= SAB82532_IMR0_TCD;
        writeb(up->interrupt_mask1, &up->regs->w.imr0);
 }
 
index dd7ea4c..eb44b60 100644 (file)
@@ -394,6 +394,7 @@ MODULE_DEVICE_TABLE(dmi, samsung_dmi_table);
 
 static int __init samsung_init(void)
 {
+       struct backlight_properties props;
        struct sabi_retval sretval;
        const char *testStr = "SECLINUX";
        void __iomem *memcheck;
@@ -486,12 +487,14 @@ static int __init samsung_init(void)
                goto error_no_platform;
 
        /* create a backlight device to talk to this one */
+       memset(&props, 0, sizeof(struct backlight_properties));
+       props.max_brightness = MAX_BRIGHT;
        backlight_device = backlight_device_register("samsung", &sdev->dev,
-                                                    NULL, &backlight_ops);
+                                                    NULL, &backlight_ops,
+                                                    &props);
        if (IS_ERR(backlight_device))
                goto error_no_backlight;
 
-       backlight_device->props.max_brightness = MAX_BRIGHT;
        backlight_device->props.brightness = read_brightness();
        backlight_device->props.power = FB_BLANK_UNBLANK;
        backlight_update_status(backlight_device);
index 4d2952f..3adab04 100644 (file)
@@ -202,6 +202,7 @@ static void appledisplay_work(struct work_struct *work)
 static int appledisplay_probe(struct usb_interface *iface,
        const struct usb_device_id *id)
 {
+       struct backlight_properties props;
        struct appledisplay *pdata;
        struct usb_device *udev = interface_to_usbdev(iface);
        struct usb_host_interface *iface_desc;
@@ -279,16 +280,16 @@ static int appledisplay_probe(struct usb_interface *iface,
        /* Register backlight device */
        snprintf(bl_name, sizeof(bl_name), "appledisplay%d",
                atomic_inc_return(&count_displays) - 1);
+       memset(&props, 0, sizeof(struct backlight_properties));
+       props.max_brightness = 0xff;
        pdata->bd = backlight_device_register(bl_name, NULL, pdata,
-                                               &appledisplay_bl_data);
+                                             &appledisplay_bl_data, &props);
        if (IS_ERR(pdata->bd)) {
                dev_err(&iface->dev, "Backlight registration failed\n");
                retval = PTR_ERR(pdata->bd);
                goto error;
        }
 
-       pdata->bd->props.max_brightness = 0xff;
-
        /* Try to get brightness */
        brightness = appledisplay_bl_get_brightness(pdata->bd);
 
index dabe804..feaff4f 100644 (file)
@@ -914,7 +914,7 @@ config FB_XVR2500
 
 config FB_XVR1000
        bool "Sun XVR-1000 support"
-       depends on SPARC64
+       depends on (FB = y) && SPARC64
        select FB_CFB_FILLRECT
        select FB_CFB_COPYAREA
        select FB_CFB_IMAGEBLIT
index 3d886c6..11de3bf 100644 (file)
@@ -117,6 +117,7 @@ static struct backlight_ops atmel_lcdc_bl_ops = {
 
 static void init_backlight(struct atmel_lcdfb_info *sinfo)
 {
+       struct backlight_properties props;
        struct backlight_device *bl;
 
        sinfo->bl_power = FB_BLANK_UNBLANK;
@@ -124,8 +125,10 @@ static void init_backlight(struct atmel_lcdfb_info *sinfo)
        if (sinfo->backlight)
                return;
 
-       bl = backlight_device_register("backlight", &sinfo->pdev->dev,
-                       sinfo, &atmel_lcdc_bl_ops);
+       memset(&props, 0, sizeof(struct backlight_properties));
+       props.max_brightness = 0xff;
+       bl = backlight_device_register("backlight", &sinfo->pdev->dev, sinfo,
+                                      &atmel_lcdc_bl_ops, &props);
        if (IS_ERR(bl)) {
                dev_err(&sinfo->pdev->dev, "error %ld on backlight register\n",
                                PTR_ERR(bl));
@@ -135,7 +138,6 @@ static void init_backlight(struct atmel_lcdfb_info *sinfo)
 
        bl->props.power = FB_BLANK_UNBLANK;
        bl->props.fb_blank = FB_BLANK_UNBLANK;
-       bl->props.max_brightness = 0xff;
        bl->props.brightness = atmel_bl_get_brightness(bl);
 }
 
index 9ee67d6..a489be0 100644 (file)
@@ -1802,6 +1802,7 @@ static void aty128_bl_set_power(struct fb_info *info, int power)
 
 static void aty128_bl_init(struct aty128fb_par *par)
 {
+       struct backlight_properties props;
        struct fb_info *info = pci_get_drvdata(par->pdev);
        struct backlight_device *bd;
        char name[12];
@@ -1817,7 +1818,10 @@ static void aty128_bl_init(struct aty128fb_par *par)
 
        snprintf(name, sizeof(name), "aty128bl%d", info->node);
 
-       bd = backlight_device_register(name, info->dev, par, &aty128_bl_data);
+       memset(&props, 0, sizeof(struct backlight_properties));
+       props.max_brightness = FB_BACKLIGHT_LEVELS - 1;
+       bd = backlight_device_register(name, info->dev, par, &aty128_bl_data,
+                                      &props);
        if (IS_ERR(bd)) {
                info->bl_dev = NULL;
                printk(KERN_WARNING "aty128: Backlight registration failed\n");
@@ -1829,7 +1833,6 @@ static void aty128_bl_init(struct aty128fb_par *par)
                 63 * FB_BACKLIGHT_MAX / MAX_LEVEL,
                219 * FB_BACKLIGHT_MAX / MAX_LEVEL);
 
-       bd->props.max_brightness = FB_BACKLIGHT_LEVELS - 1;
        bd->props.brightness = bd->props.max_brightness;
        bd->props.power = FB_BLANK_UNBLANK;
        backlight_update_status(bd);
index e45ab8d..29d7285 100644 (file)
@@ -2232,6 +2232,7 @@ static struct backlight_ops aty_bl_data = {
 
 static void aty_bl_init(struct atyfb_par *par)
 {
+       struct backlight_properties props;
        struct fb_info *info = pci_get_drvdata(par->pdev);
        struct backlight_device *bd;
        char name[12];
@@ -2243,7 +2244,10 @@ static void aty_bl_init(struct atyfb_par *par)
 
        snprintf(name, sizeof(name), "atybl%d", info->node);
 
-       bd = backlight_device_register(name, info->dev, par, &aty_bl_data);
+       memset(&props, 0, sizeof(struct backlight_properties));
+       props.max_brightness = FB_BACKLIGHT_LEVELS - 1;
+       bd = backlight_device_register(name, info->dev, par, &aty_bl_data,
+                                      &props);
        if (IS_ERR(bd)) {
                info->bl_dev = NULL;
                printk(KERN_WARNING "aty: Backlight registration failed\n");
@@ -2255,7 +2259,6 @@ static void aty_bl_init(struct atyfb_par *par)
                            0x3F * FB_BACKLIGHT_MAX / MAX_LEVEL,
                            0xFF * FB_BACKLIGHT_MAX / MAX_LEVEL);
 
-       bd->props.max_brightness = FB_BACKLIGHT_LEVELS - 1;
        bd->props.brightness = bd->props.max_brightness;
        bd->props.power = FB_BLANK_UNBLANK;
        backlight_update_status(bd);
index fa1198c..9fc8c66 100644 (file)
@@ -134,6 +134,7 @@ static struct backlight_ops radeon_bl_data = {
 
 void radeonfb_bl_init(struct radeonfb_info *rinfo)
 {
+       struct backlight_properties props;
        struct backlight_device *bd;
        struct radeon_bl_privdata *pdata;
        char name[12];
@@ -155,7 +156,10 @@ void radeonfb_bl_init(struct radeonfb_info *rinfo)
 
        snprintf(name, sizeof(name), "radeonbl%d", rinfo->info->node);
 
-       bd = backlight_device_register(name, rinfo->info->dev, pdata, &radeon_bl_data);
+       memset(&props, 0, sizeof(struct backlight_properties));
+       props.max_brightness = FB_BACKLIGHT_LEVELS - 1;
+       bd = backlight_device_register(name, rinfo->info->dev, pdata,
+                                      &radeon_bl_data, &props);
        if (IS_ERR(bd)) {
                rinfo->info->bl_dev = NULL;
                printk("radeonfb: Backlight registration failed\n");
@@ -185,7 +189,6 @@ void radeonfb_bl_init(struct radeonfb_info *rinfo)
                 63 * FB_BACKLIGHT_MAX / MAX_RADEON_LEVEL,
                217 * FB_BACKLIGHT_MAX / MAX_RADEON_LEVEL);
 
-       bd->props.max_brightness = FB_BACKLIGHT_LEVELS - 1;
        bd->props.brightness = bd->props.max_brightness;
        bd->props.power = FB_BLANK_UNBLANK;
        backlight_update_status(bd);
index b8f705c..93e25c7 100644 (file)
@@ -187,6 +187,7 @@ static int pm860x_backlight_probe(struct platform_device *pdev)
        struct pm860x_backlight_data *data;
        struct backlight_device *bl;
        struct resource *res;
+       struct backlight_properties props;
        unsigned char value;
        char name[MFD_NAME_SIZE];
        int ret;
@@ -223,14 +224,15 @@ static int pm860x_backlight_probe(struct platform_device *pdev)
                return -EINVAL;
        }
 
+       memset(&props, 0, sizeof(struct backlight_properties));
+       props.max_brightness = MAX_BRIGHTNESS;
        bl = backlight_device_register(name, &pdev->dev, data,
-                                       &pm860x_backlight_ops);
+                                       &pm860x_backlight_ops, &props);
        if (IS_ERR(bl)) {
                dev_err(&pdev->dev, "failed to register backlight\n");
                kfree(data);
                return PTR_ERR(bl);
        }
-       bl->props.max_brightness = MAX_BRIGHTNESS;
        bl->props.brightness = MAX_BRIGHTNESS;
 
        platform_set_drvdata(pdev, bl);
index 0c77fc6..c025c84 100644 (file)
@@ -31,6 +31,13 @@ config LCD_CORGI
          Say y here to support the LCD panels usually found on SHARP
          corgi (C7x0) and spitz (Cxx00) models.
 
+config LCD_L4F00242T03
+       tristate "Epson L4F00242T03 LCD"
+       depends on LCD_CLASS_DEVICE && SPI_MASTER && GENERIC_GPIO
+       help
+         SPI driver for Epson L4F00242T03. This provides basic support
+         for init and powering the LCD up/down through a sysfs interface.
+
 config LCD_LMS283GF05
        tristate "Samsung LMS283GF05 LCD"
        depends on LCD_CLASS_DEVICE && SPI_MASTER && GENERIC_GPIO
index 6c704d4..09d1f14 100644 (file)
@@ -3,6 +3,7 @@
 obj-$(CONFIG_LCD_CLASS_DEVICE)     += lcd.o
 obj-$(CONFIG_LCD_CORGI)                   += corgi_lcd.o
 obj-$(CONFIG_LCD_HP700)                   += jornada720_lcd.o
+obj-$(CONFIG_LCD_L4F00242T03)     += l4f00242t03.o
 obj-$(CONFIG_LCD_LMS283GF05)      += lms283gf05.o
 obj-$(CONFIG_LCD_LTV350QV)        += ltv350qv.o
 obj-$(CONFIG_LCD_ILI9320)         += ili9320.o
index 86d95c2..5183f0e 100644 (file)
@@ -278,6 +278,7 @@ static const struct attribute_group adp5520_bl_attr_group = {
 
 static int __devinit adp5520_bl_probe(struct platform_device *pdev)
 {
+       struct backlight_properties props;
        struct backlight_device *bl;
        struct adp5520_bl *data;
        int ret = 0;
@@ -300,17 +301,17 @@ static int __devinit adp5520_bl_probe(struct platform_device *pdev)
 
        mutex_init(&data->lock);
 
-       bl = backlight_device_register(pdev->name, data->master,
-                       data, &adp5520_bl_ops);
+       memset(&props, 0, sizeof(struct backlight_properties));
+       props.max_brightness = ADP5020_MAX_BRIGHTNESS;
+       bl = backlight_device_register(pdev->name, data->master, data,
+                                      &adp5520_bl_ops, &props);
        if (IS_ERR(bl)) {
                dev_err(&pdev->dev, "failed to register backlight\n");
                kfree(data);
                return PTR_ERR(bl);
        }
 
-       bl->props.max_brightness =
-               bl->props.brightness = ADP5020_MAX_BRIGHTNESS;
-
+       bl->props.brightness = ADP5020_MAX_BRIGHTNESS;
        if (data->pdata->en_ambl_sens)
                ret = sysfs_create_group(&bl->dev.kobj,
                        &adp5520_bl_attr_group);
index d769b0b..b0624b9 100644 (file)
@@ -56,7 +56,7 @@ static int adx_backlight_get_brightness(struct backlight_device *bldev)
        return brightness & 0xff;
 }
 
-static int adx_backlight_check_fb(struct fb_info *fb)
+static int adx_backlight_check_fb(struct backlight_device *bldev, struct fb_info *fb)
 {
        return 1;
 }
@@ -70,6 +70,7 @@ static const struct backlight_ops adx_backlight_ops = {
 
 static int __devinit adx_backlight_probe(struct platform_device *pdev)
 {
+       struct backlight_properties props;
        struct backlight_device *bldev;
        struct resource *res;
        struct adxbl *bl;
@@ -101,14 +102,15 @@ static int __devinit adx_backlight_probe(struct platform_device *pdev)
                goto out;
        }
 
-       bldev = backlight_device_register(dev_name(&pdev->dev), &pdev->dev, bl,
-                       &adx_backlight_ops);
+       memset(&props, 0, sizeof(struct backlight_properties));
+       props.max_brightness = 0xff;
+       bldev = backlight_device_register(dev_name(&pdev->dev), &pdev->dev,
+                                         bl, &adx_backlight_ops, &props);
        if (!bldev) {
                ret = -ENOMEM;
                goto out;
        }
 
-       bldev->props.max_brightness = 0xff;
        bldev->props.brightness = 0xff;
        bldev->props.power = FB_BLANK_UNBLANK;
 
index f625ffc..2d97605 100644 (file)
@@ -120,6 +120,7 @@ static const struct backlight_ops atmel_pwm_bl_ops = {
 
 static int atmel_pwm_bl_probe(struct platform_device *pdev)
 {
+       struct backlight_properties props;
        const struct atmel_pwm_bl_platform_data *pdata;
        struct backlight_device *bldev;
        struct atmel_pwm_bl *pwmbl;
@@ -165,8 +166,10 @@ static int atmel_pwm_bl_probe(struct platform_device *pdev)
                        goto err_free_gpio;
        }
 
-       bldev = backlight_device_register("atmel-pwm-bl",
-                       &pdev->dev, pwmbl, &atmel_pwm_bl_ops);
+       memset(&props, 0, sizeof(struct backlight_properties));
+       props.max_brightness = pdata->pwm_duty_max - pdata->pwm_duty_min;
+       bldev = backlight_device_register("atmel-pwm-bl", &pdev->dev, pwmbl,
+                                         &atmel_pwm_bl_ops, &props);
        if (IS_ERR(bldev)) {
                retval = PTR_ERR(bldev);
                goto err_free_gpio;
@@ -178,7 +181,6 @@ static int atmel_pwm_bl_probe(struct platform_device *pdev)
 
        /* Power up the backlight by default at middle intesity. */
        bldev->props.power = FB_BLANK_UNBLANK;
-       bldev->props.max_brightness = pdata->pwm_duty_max - pdata->pwm_duty_min;
        bldev->props.brightness = bldev->props.max_brightness / 2;
 
        retval = atmel_pwm_bl_init_pwm(pwmbl);
index 18829cf..68bb838 100644 (file)
@@ -38,7 +38,7 @@ static int fb_notifier_callback(struct notifier_block *self,
        mutex_lock(&bd->ops_lock);
        if (bd->ops)
                if (!bd->ops->check_fb ||
-                   bd->ops->check_fb(evdata->info)) {
+                   bd->ops->check_fb(bd, evdata->info)) {
                        bd->props.fb_blank = *(int *)evdata->data;
                        if (bd->props.fb_blank == FB_BLANK_UNBLANK)
                                bd->props.state &= ~BL_CORE_FBBLANK;
@@ -269,7 +269,8 @@ EXPORT_SYMBOL(backlight_force_update);
  * ERR_PTR() or a pointer to the newly allocated device.
  */
 struct backlight_device *backlight_device_register(const char *name,
-               struct device *parent, void *devdata, const struct backlight_ops *ops)
+       struct device *parent, void *devdata, const struct backlight_ops *ops,
+       const struct backlight_properties *props)
 {
        struct backlight_device *new_bd;
        int rc;
@@ -289,6 +290,11 @@ struct backlight_device *backlight_device_register(const char *name,
        dev_set_name(&new_bd->dev, name);
        dev_set_drvdata(&new_bd->dev, devdata);
 
+       /* Set default properties */
+       if (props)
+               memcpy(&new_bd->props, props,
+                      sizeof(struct backlight_properties));
+
        rc = device_register(&new_bd->dev);
        if (rc) {
                kfree(new_bd);
index b4bcf80..73bdd84 100644 (file)
@@ -533,6 +533,7 @@ err_free_backlight_on:
 
 static int __devinit corgi_lcd_probe(struct spi_device *spi)
 {
+       struct backlight_properties props;
        struct corgi_lcd_platform_data *pdata = spi->dev.platform_data;
        struct corgi_lcd *lcd;
        int ret = 0;
@@ -559,13 +560,14 @@ static int __devinit corgi_lcd_probe(struct spi_device *spi)
        lcd->power = FB_BLANK_POWERDOWN;
        lcd->mode = (pdata) ? pdata->init_mode : CORGI_LCD_MODE_VGA;
 
-       lcd->bl_dev = backlight_device_register("corgi_bl", &spi->dev,
-                                       lcd, &corgi_bl_ops);
+       memset(&props, 0, sizeof(struct backlight_properties));
+       props.max_brightness = pdata->max_intensity;
+       lcd->bl_dev = backlight_device_register("corgi_bl", &spi->dev, lcd,
+                                               &corgi_bl_ops, &props);
        if (IS_ERR(lcd->bl_dev)) {
                ret = PTR_ERR(lcd->bl_dev);
                goto err_unregister_lcd;
        }
-       lcd->bl_dev->props.max_brightness = pdata->max_intensity;
        lcd->bl_dev->props.brightness = pdata->default_intensity;
        lcd->bl_dev->props.power = FB_BLANK_UNBLANK;
 
index da86db4..1cce603 100644 (file)
@@ -170,6 +170,7 @@ static struct lcd_ops cr_lcd_ops = {
 
 static int cr_backlight_probe(struct platform_device *pdev)
 {
+       struct backlight_properties props;
        struct backlight_device *bdp;
        struct lcd_device *ldp;
        struct cr_panel *crp;
@@ -190,8 +191,9 @@ static int cr_backlight_probe(struct platform_device *pdev)
                return -ENODEV;
        }
 
-       bdp = backlight_device_register("cr-backlight",
-                                       &pdev->dev, NULL, &cr_backlight_ops);
+       memset(&props, 0, sizeof(struct backlight_properties));
+       bdp = backlight_device_register("cr-backlight", &pdev->dev, NULL,
+                                       &cr_backlight_ops, &props);
        if (IS_ERR(bdp)) {
                pci_dev_put(lpc_dev);
                return PTR_ERR(bdp);
@@ -220,9 +222,7 @@ static int cr_backlight_probe(struct platform_device *pdev)
        crp->cr_lcd_device = ldp;
        crp->cr_backlight_device->props.power = FB_BLANK_UNBLANK;
        crp->cr_backlight_device->props.brightness = 0;
-       crp->cr_backlight_device->props.max_brightness = 0;
        cr_backlight_set_intensity(crp->cr_backlight_device);
-
        cr_lcd_set_power(crp->cr_lcd_device, FB_BLANK_UNBLANK);
 
        platform_set_drvdata(pdev, crp);
index 74cdc64..686e4a7 100644 (file)
@@ -105,6 +105,7 @@ static int da903x_backlight_probe(struct platform_device *pdev)
        struct da9034_backlight_pdata *pdata = pdev->dev.platform_data;
        struct da903x_backlight_data *data;
        struct backlight_device *bl;
+       struct backlight_properties props;
        int max_brightness;
 
        data = kzalloc(sizeof(*data), GFP_KERNEL);
@@ -134,15 +135,15 @@ static int da903x_backlight_probe(struct platform_device *pdev)
                da903x_write(data->da903x_dev, DA9034_WLED_CONTROL2,
                                DA9034_WLED_ISET(pdata->output_current));
 
-       bl = backlight_device_register(pdev->name, data->da903x_dev,
-                       data, &da903x_backlight_ops);
+       props.max_brightness = max_brightness;
+       bl = backlight_device_register(pdev->name, data->da903x_dev, data,
+                                      &da903x_backlight_ops, &props);
        if (IS_ERR(bl)) {
                dev_err(&pdev->dev, "failed to register backlight\n");
                kfree(data);
                return PTR_ERR(bl);
        }
 
-       bl->props.max_brightness = max_brightness;
        bl->props.brightness = max_brightness;
 
        platform_set_drvdata(pdev, bl);
index e6d348e..312ca61 100644 (file)
@@ -78,6 +78,7 @@ static const struct backlight_ops genericbl_ops = {
 
 static int genericbl_probe(struct platform_device *pdev)
 {
+       struct backlight_properties props;
        struct generic_bl_info *machinfo = pdev->dev.platform_data;
        const char *name = "generic-bl";
        struct backlight_device *bd;
@@ -89,14 +90,15 @@ static int genericbl_probe(struct platform_device *pdev)
        if (machinfo->name)
                name = machinfo->name;
 
-       bd = backlight_device_register (name,
-               &pdev->dev, NULL, &genericbl_ops);
+       memset(&props, 0, sizeof(struct backlight_properties));
+       props.max_brightness = machinfo->max_intensity;
+       bd = backlight_device_register(name, &pdev->dev, NULL, &genericbl_ops,
+                                      &props);
        if (IS_ERR (bd))
                return PTR_ERR (bd);
 
        platform_set_drvdata(pdev, bd);
 
-       bd->props.max_brightness = machinfo->max_intensity;
        bd->props.power = FB_BLANK_UNBLANK;
        bd->props.brightness = machinfo->default_intensity;
        backlight_update_status(bd);
index f7cc528..267d23f 100644 (file)
@@ -105,16 +105,18 @@ static const struct backlight_ops hp680bl_ops = {
 
 static int __devinit hp680bl_probe(struct platform_device *pdev)
 {
+       struct backlight_properties props;
        struct backlight_device *bd;
 
-       bd = backlight_device_register ("hp680-bl", &pdev->dev, NULL,
-                   &hp680bl_ops);
+       memset(&props, 0, sizeof(struct backlight_properties));
+       props.max_brightness = HP680_MAX_INTENSITY;
+       bd = backlight_device_register("hp680-bl", &pdev->dev, NULL,
+                                      &hp680bl_ops, &props);
        if (IS_ERR(bd))
                return PTR_ERR(bd);
 
        platform_set_drvdata(pdev, bd);
 
-       bd->props.max_brightness = HP680_MAX_INTENSITY;
        bd->props.brightness = HP680_DEFAULT_INTENSITY;
        hp680bl_send_intensity(bd);
 
index db9071f..2f177b3 100644 (file)
@@ -101,10 +101,14 @@ static const struct backlight_ops jornada_bl_ops = {
 
 static int jornada_bl_probe(struct platform_device *pdev)
 {
+       struct backlight_properties props;
        int ret;
        struct backlight_device *bd;
 
-       bd = backlight_device_register(S1D_DEVICENAME, &pdev->dev, NULL, &jornada_bl_ops);
+       memset(&props, 0, sizeof(struct backlight_properties));
+       props.max_brightness = BL_MAX_BRIGHT;
+       bd = backlight_device_register(S1D_DEVICENAME, &pdev->dev, NULL,
+                                      &jornada_bl_ops, &props);
 
        if (IS_ERR(bd)) {
                ret = PTR_ERR(bd);
@@ -117,7 +121,6 @@ static int jornada_bl_probe(struct platform_device *pdev)
        /* note. make sure max brightness is set otherwise
           you will get seemingly non-related errors when
           trying to change brightness */
-       bd->props.max_brightness = BL_MAX_BRIGHT;
        jornada_bl_update_status(bd);
 
        platform_set_drvdata(pdev, bd);
index 939e7b8..f439a86 100644 (file)
@@ -141,20 +141,24 @@ static const struct backlight_ops kb3886bl_ops = {
 
 static int kb3886bl_probe(struct platform_device *pdev)
 {
+       struct backlight_properties props;
        struct kb3886bl_machinfo *machinfo = pdev->dev.platform_data;
 
        bl_machinfo = machinfo;
        if (!machinfo->limit_mask)
                machinfo->limit_mask = -1;
 
+       memset(&props, 0, sizeof(struct backlight_properties));
+       props.max_brightness = machinfo->max_intensity;
        kb3886_backlight_device = backlight_device_register("kb3886-bl",
-               &pdev->dev, NULL, &kb3886bl_ops);
+                                                           &pdev->dev, NULL,
+                                                           &kb3886bl_ops,
+                                                           &props);
        if (IS_ERR(kb3886_backlight_device))
                return PTR_ERR(kb3886_backlight_device);
 
        platform_set_drvdata(pdev, kb3886_backlight_device);
 
-       kb3886_backlight_device->props.max_brightness = machinfo->max_intensity;
        kb3886_backlight_device->props.power = FB_BLANK_UNBLANK;
        kb3886_backlight_device->props.brightness = machinfo->default_intensity;
        backlight_update_status(kb3886_backlight_device);
diff --git a/drivers/video/backlight/l4f00242t03.c b/drivers/video/backlight/l4f00242t03.c
new file mode 100644 (file)
index 0000000..74abd69
--- /dev/null
@@ -0,0 +1,257 @@
+/*
+ * l4f00242t03.c -- support for Epson L4F00242T03 LCD
+ *
+ * Copyright 2007-2009 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * Copyright (c) 2009 Alberto Panizzo <maramaopercheseimorto@gmail.com>
+ *     Inspired by Marek Vasut work in l4f00242t03.c
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/device.h>
+#include <linux/kernel.h>
+#include <linux/delay.h>
+#include <linux/gpio.h>
+#include <linux/lcd.h>
+#include <linux/regulator/consumer.h>
+
+#include <linux/spi/spi.h>
+#include <linux/spi/l4f00242t03.h>
+
+struct l4f00242t03_priv {
+       struct spi_device       *spi;
+       struct lcd_device       *ld;
+       int lcd_on:1;
+       struct regulator *io_reg;
+       struct regulator *core_reg;
+};
+
+
+static void l4f00242t03_reset(unsigned int gpio)
+{
+       pr_debug("l4f00242t03_reset.\n");
+       gpio_set_value(gpio, 1);
+       mdelay(100);
+       gpio_set_value(gpio, 0);
+       mdelay(10);     /* tRES >= 100us */
+       gpio_set_value(gpio, 1);
+       mdelay(20);
+}
+
+#define param(x) ((x) | 0x100)
+
+static void l4f00242t03_lcd_init(struct spi_device *spi)
+{
+       struct l4f00242t03_pdata *pdata = spi->dev.platform_data;
+       struct l4f00242t03_priv *priv = dev_get_drvdata(&spi->dev);
+       const u16 cmd[] = { 0x36, param(0), 0x3A, param(0x60) };
+
+       dev_dbg(&spi->dev, "initializing LCD\n");
+
+       if (priv->io_reg) {
+               regulator_set_voltage(priv->io_reg, 1800000, 1800000);
+               regulator_enable(priv->io_reg);
+       }
+
+       if (priv->core_reg) {
+               regulator_set_voltage(priv->core_reg, 2800000, 2800000);
+               regulator_enable(priv->core_reg);
+       }
+
+       gpio_set_value(pdata->data_enable_gpio, 1);
+       msleep(60);
+       spi_write(spi, (const u8 *)cmd, ARRAY_SIZE(cmd) * sizeof(u16));
+}
+
+static int l4f00242t03_lcd_power_set(struct lcd_device *ld, int power)
+{
+       struct l4f00242t03_priv *priv = lcd_get_data(ld);
+       struct spi_device *spi = priv->spi;
+
+       const u16 slpout = 0x11;
+       const u16 dison = 0x29;
+
+       const u16 slpin = 0x10;
+       const u16 disoff = 0x28;
+
+       if (power) {
+               if (priv->lcd_on)
+                       return 0;
+
+               dev_dbg(&spi->dev, "turning on LCD\n");
+
+               spi_write(spi, (const u8 *)&slpout, sizeof(u16));
+               msleep(60);
+               spi_write(spi, (const u8 *)&dison, sizeof(u16));
+
+               priv->lcd_on = 1;
+       } else {
+               if (!priv->lcd_on)
+                       return 0;
+
+               dev_dbg(&spi->dev, "turning off LCD\n");
+
+               spi_write(spi, (const u8 *)&disoff, sizeof(u16));
+               msleep(60);
+               spi_write(spi, (const u8 *)&slpin, sizeof(u16));
+
+               priv->lcd_on = 0;
+       }
+
+       return 0;
+}
+
+static struct lcd_ops l4f_ops = {
+       .set_power      = l4f00242t03_lcd_power_set,
+       .get_power      = NULL,
+};
+
+static int __devinit l4f00242t03_probe(struct spi_device *spi)
+{
+       struct l4f00242t03_priv *priv;
+       struct l4f00242t03_pdata *pdata = spi->dev.platform_data;
+       int ret;
+
+       if (pdata == NULL) {
+               dev_err(&spi->dev, "Uninitialized platform data.\n");
+               return -EINVAL;
+       }
+
+       priv = kzalloc(sizeof(struct l4f00242t03_priv), GFP_KERNEL);
+
+       if (priv == NULL) {
+               dev_err(&spi->dev, "No memory for this device.\n");
+               ret = -ENOMEM;
+               goto err;
+       }
+
+       dev_set_drvdata(&spi->dev, priv);
+       spi->bits_per_word = 9;
+       spi_setup(spi);
+
+       priv->spi = spi;
+
+       ret = gpio_request(pdata->reset_gpio, "lcd l4f00242t03 reset");
+       if (ret) {
+               dev_err(&spi->dev,
+                       "Unable to get the lcd l4f00242t03 reset gpio.\n");
+               return ret;
+       }
+
+       ret = gpio_direction_output(pdata->reset_gpio, 1);
+       if (ret)
+               goto err2;
+
+       ret = gpio_request(pdata->data_enable_gpio,
+                               "lcd l4f00242t03 data enable");
+       if (ret) {
+               dev_err(&spi->dev,
+                       "Unable to get the lcd l4f00242t03 data en gpio.\n");
+               return ret;
+       }
+
+       ret = gpio_direction_output(pdata->data_enable_gpio, 0);
+       if (ret)
+               goto err3;
+
+       if (pdata->io_supply) {
+               priv->io_reg = regulator_get(NULL, pdata->io_supply);
+
+               if (IS_ERR(priv->io_reg)) {
+                       pr_err("%s: Unable to get the IO regulator\n",
+                                                               __func__);
+                       goto err3;
+               }
+       }
+
+       if (pdata->core_supply) {
+               priv->core_reg = regulator_get(NULL, pdata->core_supply);
+
+               if (IS_ERR(priv->core_reg)) {
+                       pr_err("%s: Unable to get the core regulator\n",
+                                                               __func__);
+                       goto err4;
+               }
+       }
+
+       priv->ld = lcd_device_register("l4f00242t03",
+                                       &spi->dev, priv, &l4f_ops);
+       if (IS_ERR(priv->ld)) {
+               ret = PTR_ERR(priv->ld);
+               goto err5;
+       }
+
+       /* Init the LCD */
+       l4f00242t03_reset(pdata->reset_gpio);
+       l4f00242t03_lcd_init(spi);
+       l4f00242t03_lcd_power_set(priv->ld, 1);
+
+       dev_info(&spi->dev, "Epson l4f00242t03 lcd probed.\n");
+
+       return 0;
+
+err5:
+       if (priv->core_reg)
+               regulator_put(priv->core_reg);
+err4:
+       if (priv->io_reg)
+               regulator_put(priv->io_reg);
+err3:
+       gpio_free(pdata->data_enable_gpio);
+err2:
+       gpio_free(pdata->reset_gpio);
+err:
+       kfree(priv);
+
+       return ret;
+}
+
+static int __devexit l4f00242t03_remove(struct spi_device *spi)
+{
+       struct l4f00242t03_priv *priv = dev_get_drvdata(&spi->dev);
+       struct l4f00242t03_pdata *pdata = priv->spi->dev.platform_data;
+
+       l4f00242t03_lcd_power_set(priv->ld, 0);
+       lcd_device_unregister(priv->ld);
+
+       gpio_free(pdata->data_enable_gpio);
+       gpio_free(pdata->reset_gpio);
+
+       if (priv->io_reg)
+               regulator_put(priv->core_reg);
+       if (priv->core_reg)
+               regulator_put(priv->io_reg);
+
+       kfree(priv);
+
+       return 0;
+}
+
+static struct spi_driver l4f00242t03_driver = {
+       .driver = {
+               .name   = "l4f00242t03",
+               .owner  = THIS_MODULE,
+       },
+       .probe          = l4f00242t03_probe,
+       .remove         = __devexit_p(l4f00242t03_remove),
+};
+
+static __init int l4f00242t03_init(void)
+{
+       return spi_register_driver(&l4f00242t03_driver);
+}
+
+static __exit void l4f00242t03_exit(void)
+{
+       spi_unregister_driver(&l4f00242t03_driver);
+}
+
+module_init(l4f00242t03_init);
+module_exit(l4f00242t03_exit);
+
+MODULE_AUTHOR("Alberto Panizzo <maramaopercheseimorto@gmail.com>");
+MODULE_DESCRIPTION("EPSON L4F00242T03 LCD");
+MODULE_LICENSE("GPL v2");
index 00a9591..7571bc2 100644 (file)
@@ -167,6 +167,7 @@ static int locomolcd_resume(struct locomo_dev *dev)
 
 static int locomolcd_probe(struct locomo_dev *ldev)
 {
+       struct backlight_properties props;
        unsigned long flags;
 
        local_irq_save(flags);
@@ -182,13 +183,16 @@ static int locomolcd_probe(struct locomo_dev *ldev)
 
        local_irq_restore(flags);
 
-       locomolcd_bl_device = backlight_device_register("locomo-bl", &ldev->dev, NULL, &locomobl_data);
+       memset(&props, 0, sizeof(struct backlight_properties));
+       props.max_brightness = 4;
+       locomolcd_bl_device = backlight_device_register("locomo-bl",
+                                                       &ldev->dev, NULL,
+                                                       &locomobl_data, &props);
 
        if (IS_ERR (locomolcd_bl_device))
                return PTR_ERR (locomolcd_bl_device);
 
        /* Set up frontlight so that screen is readable */
-       locomolcd_bl_device->props.max_brightness = 4,
        locomolcd_bl_device->props.brightness = 2;
        locomolcd_set_intensity(locomolcd_bl_device);
 
index c267069..c91adaf 100644 (file)
@@ -104,6 +104,7 @@ static int __devinit max8925_backlight_probe(struct platform_device *pdev)
        struct max8925_backlight_pdata *pdata = NULL;
        struct max8925_backlight_data *data;
        struct backlight_device *bl;
+       struct backlight_properties props;
        struct resource *res;
        char name[MAX8925_NAME_SIZE];
        unsigned char value;
@@ -133,14 +134,15 @@ static int __devinit max8925_backlight_probe(struct platform_device *pdev)
        data->chip = chip;
        data->current_brightness = 0;
 
+       memset(&props, 0, sizeof(struct backlight_properties));
+       props.max_brightness = MAX_BRIGHTNESS;
        bl = backlight_device_register(name, &pdev->dev, data,
-                                       &max8925_backlight_ops);
+                                       &max8925_backlight_ops, &props);
        if (IS_ERR(bl)) {
                dev_err(&pdev->dev, "failed to register backlight\n");
                kfree(data);
                return PTR_ERR(bl);
        }
-       bl->props.max_brightness = MAX_BRIGHTNESS;
        bl->props.brightness = MAX_BRIGHTNESS;
 
        platform_set_drvdata(pdev, bl);
index 2e78b07..1b5d3fe 100644 (file)
@@ -137,6 +137,51 @@ static int mbp_dmi_match(const struct dmi_system_id *id)
 }
 
 static const struct dmi_system_id __initdata mbp_device_table[] = {
+       {
+               .callback       = mbp_dmi_match,
+               .ident          = "MacBook 1,1",
+               .matches        = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "MacBook1,1"),
+               },
+               .driver_data    = (void *)&intel_chipset_data,
+       },
+       {
+               .callback       = mbp_dmi_match,
+               .ident          = "MacBook 2,1",
+               .matches        = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "MacBook2,1"),
+               },
+               .driver_data    = (void *)&intel_chipset_data,
+       },
+       {
+               .callback       = mbp_dmi_match,
+               .ident          = "MacBook 3,1",
+               .matches        = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "MacBook3,1"),
+               },
+               .driver_data    = (void *)&intel_chipset_data,
+       },
+       {
+               .callback       = mbp_dmi_match,
+               .ident          = "MacBook 4,1",
+               .matches        = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "MacBook4,1"),
+               },
+               .driver_data    = (void *)&intel_chipset_data,
+       },
+       {
+               .callback       = mbp_dmi_match,
+               .ident          = "MacBook 4,2",
+               .matches        = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "MacBook4,2"),
+               },
+               .driver_data    = (void *)&intel_chipset_data,
+       },
        {
                .callback       = mbp_dmi_match,
                .ident          = "MacBookPro 3,1",
@@ -250,6 +295,7 @@ static const struct dmi_system_id __initdata mbp_device_table[] = {
 
 static int __init mbp_init(void)
 {
+       struct backlight_properties props;
        if (!dmi_check_system(mbp_device_table))
                return -ENODEV;
 
@@ -257,14 +303,17 @@ static int __init mbp_init(void)
                                                "Macbook Pro backlight"))
                return -ENXIO;
 
-       mbp_backlight_device = backlight_device_register("mbp_backlight",
-                                       NULL, NULL, &driver_data->backlight_ops);
+       memset(&props, 0, sizeof(struct backlight_properties));
+       props.max_brightness = 15;
+       mbp_backlight_device = backlight_device_register("mbp_backlight", NULL,
+                                                        NULL,
+                                                        &driver_data->backlight_ops,
+                                                        &props);
        if (IS_ERR(mbp_backlight_device)) {
                release_region(driver_data->iostart, driver_data->iolen);
                return PTR_ERR(mbp_backlight_device);
        }
 
-       mbp_backlight_device->props.max_brightness = 15;
        mbp_backlight_device->props.brightness =
                driver_data->backlight_ops.get_brightness(mbp_backlight_device);
        backlight_update_status(mbp_backlight_device);
index a3a7f89..333d28e 100644 (file)
@@ -132,6 +132,7 @@ static const struct backlight_ops omapbl_ops = {
 
 static int omapbl_probe(struct platform_device *pdev)
 {
+       struct backlight_properties props;
        struct backlight_device *dev;
        struct omap_backlight *bl;
        struct omap_backlight_config *pdata = pdev->dev.platform_data;
@@ -143,7 +144,10 @@ static int omapbl_probe(struct platform_device *pdev)
        if (unlikely(!bl))
                return -ENOMEM;
 
-       dev = backlight_device_register("omap-bl", &pdev->dev, bl, &omapbl_ops);
+       memset(&props, 0, sizeof(struct backlight_properties));
+       props.max_brightness = OMAPBL_MAX_INTENSITY;
+       dev = backlight_device_register("omap-bl", &pdev->dev, bl, &omapbl_ops,
+                                       &props);
        if (IS_ERR(dev)) {
                kfree(bl);
                return PTR_ERR(dev);
@@ -160,7 +164,6 @@ static int omapbl_probe(struct platform_device *pdev)
        omap_cfg_reg(PWL);      /* Conflicts with UART3 */
 
        dev->props.fb_blank = FB_BLANK_UNBLANK;
-       dev->props.max_brightness = OMAPBL_MAX_INTENSITY;
        dev->props.brightness = pdata->default_intensity;
        omapbl_update_status(dev);
 
index 075786e..809278c 100644 (file)
@@ -61,8 +61,10 @@ static const struct backlight_ops progearbl_ops = {
 
 static int progearbl_probe(struct platform_device *pdev)
 {
+       struct backlight_properties props;
        u8 temp;
        struct backlight_device *progear_backlight_device;
+       int ret;
 
        pmu_dev = pci_get_device(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M7101, NULL);
        if (!pmu_dev) {
@@ -73,28 +75,37 @@ static int progearbl_probe(struct platform_device *pdev)
        sb_dev = pci_get_device(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M1533, NULL);
        if (!sb_dev) {
                printk("ALI 1533 SB not found.\n");
-               pci_dev_put(pmu_dev);
-               return -ENODEV;
+               ret = -ENODEV;
+               goto put_pmu;
        }
 
        /*     Set SB_MPS1 to enable brightness control. */
        pci_read_config_byte(sb_dev, SB_MPS1, &temp);
        pci_write_config_byte(sb_dev, SB_MPS1, temp | 0x20);
 
+       memset(&props, 0, sizeof(struct backlight_properties));
+       props.max_brightness = HW_LEVEL_MAX - HW_LEVEL_MIN;
        progear_backlight_device = backlight_device_register("progear-bl",
                                                             &pdev->dev, NULL,
-                                                            &progearbl_ops);
-       if (IS_ERR(progear_backlight_device))
-               return PTR_ERR(progear_backlight_device);
+                                                            &progearbl_ops,
+                                                            &props);
+       if (IS_ERR(progear_backlight_device)) {
+               ret = PTR_ERR(progear_backlight_device);
+               goto put_sb;
+       }
 
        platform_set_drvdata(pdev, progear_backlight_device);
 
        progear_backlight_device->props.power = FB_BLANK_UNBLANK;
        progear_backlight_device->props.brightness = HW_LEVEL_MAX - HW_LEVEL_MIN;
-       progear_backlight_device->props.max_brightness = HW_LEVEL_MAX - HW_LEVEL_MIN;
        progearbl_set_intensity(progear_backlight_device);
 
        return 0;
+put_sb:
+       pci_dev_put(sb_dev);
+put_pmu:
+       pci_dev_put(pmu_dev);
+       return ret;
 }
 
 static int progearbl_remove(struct platform_device *pdev)
index 9d2ec2a..b89eebc 100644 (file)
@@ -65,6 +65,7 @@ static const struct backlight_ops pwm_backlight_ops = {
 
 static int pwm_backlight_probe(struct platform_device *pdev)
 {
+       struct backlight_properties props;
        struct platform_pwm_backlight_data *data = pdev->dev.platform_data;
        struct backlight_device *bl;
        struct pwm_bl_data *pb;
@@ -100,15 +101,16 @@ static int pwm_backlight_probe(struct platform_device *pdev)
        } else
                dev_dbg(&pdev->dev, "got pwm for backlight\n");
 
-       bl = backlight_device_register(dev_name(&pdev->dev), &pdev->dev,
-                       pb, &pwm_backlight_ops);
+       memset(&props, 0, sizeof(struct backlight_properties));
+       props.max_brightness = data->max_brightness;
+       bl = backlight_device_register(dev_name(&pdev->dev), &pdev->dev, pb,
+                                      &pwm_backlight_ops, &props);
        if (IS_ERR(bl)) {
                dev_err(&pdev->dev, "failed to register backlight\n");
                ret = PTR_ERR(bl);
                goto err_bl;
        }
 
-       bl->props.max_brightness = data->max_brightness;
        bl->props.brightness = data->dft_brightness;
        backlight_update_status(bl);
 
index e14ce4d..f57bbf1 100644 (file)
@@ -80,6 +80,7 @@ static const struct backlight_ops bl_ops = {
 static int __devinit tosa_bl_probe(struct i2c_client *client,
                const struct i2c_device_id *id)
 {
+       struct backlight_properties props;
        struct tosa_bl_data *data = kzalloc(sizeof(struct tosa_bl_data), GFP_KERNEL);
        int ret = 0;
        if (!data)
@@ -99,15 +100,16 @@ static int __devinit tosa_bl_probe(struct i2c_client *client,
        i2c_set_clientdata(client, data);
        data->i2c = client;
 
-       data->bl = backlight_device_register("tosa-bl", &client->dev,
-                       data, &bl_ops);
+       memset(&props, 0, sizeof(struct backlight_properties));
+       props.max_brightness = 512 - 1;
+       data->bl = backlight_device_register("tosa-bl", &client->dev, data,
+                                            &bl_ops, &props);
        if (IS_ERR(data->bl)) {
                ret = PTR_ERR(data->bl);
                goto err_reg;
        }
 
        data->bl->props.brightness = 69;
-       data->bl->props.max_brightness = 512 - 1;
        data->bl->props.power = FB_BLANK_UNBLANK;
 
        backlight_update_status(data->bl);
index e32add3..a431270 100644 (file)
@@ -125,6 +125,7 @@ static int wm831x_backlight_probe(struct platform_device *pdev)
        struct wm831x_backlight_pdata *pdata;
        struct wm831x_backlight_data *data;
        struct backlight_device *bl;
+       struct backlight_properties props;
        int ret, i, max_isel, isink_reg, dcdc_cfg;
 
        /* We need platform data */
@@ -191,15 +192,15 @@ static int wm831x_backlight_probe(struct platform_device *pdev)
        data->current_brightness = 0;
        data->isink_reg = isink_reg;
 
-       bl = backlight_device_register("wm831x", &pdev->dev,
-                       data, &wm831x_backlight_ops);
+       props.max_brightness = max_isel;
+       bl = backlight_device_register("wm831x", &pdev->dev, data,
+                                      &wm831x_backlight_ops, &props);
        if (IS_ERR(bl)) {
                dev_err(&pdev->dev, "failed to register backlight\n");
                kfree(data);
                return PTR_ERR(bl);
        }
 
-       bl->props.max_brightness = max_isel;
        bl->props.brightness = max_isel;
 
        platform_set_drvdata(pdev, bl);
index 814312a..23b2a8c 100644 (file)
@@ -433,7 +433,7 @@ static int bl_get_brightness(struct backlight_device *bd)
        return 0;
 }
 
-static struct backlight_ops bfin_lq043fb_bl_ops = {
+static const struct backlight_ops bfin_lq043fb_bl_ops = {
        .get_brightness = bl_get_brightness,
 };
 
@@ -501,6 +501,7 @@ static irqreturn_t bfin_bf54x_irq_error(int irq, void *dev_id)
 
 static int __devinit bfin_bf54x_probe(struct platform_device *pdev)
 {
+       struct backlight_properties props;
        struct bfin_bf54xfb_info *info;
        struct fb_info *fbinfo;
        int ret;
@@ -645,10 +646,16 @@ static int __devinit bfin_bf54x_probe(struct platform_device *pdev)
                goto out8;
        }
 #ifndef NO_BL_SUPPORT
-       bl_dev =
-           backlight_device_register("bf54x-bl", NULL, NULL,
-                                     &bfin_lq043fb_bl_ops);
-       bl_dev->props.max_brightness = 255;
+       memset(&props, 0, sizeof(struct backlight_properties));
+       props.max_brightness = 255;
+       bl_dev = backlight_device_register("bf54x-bl", NULL, NULL,
+                                          &bfin_lq043fb_bl_ops, &props);
+       if (IS_ERR(bl_dev)) {
+               printk(KERN_ERR DRIVER_NAME
+                       ": unable to register backlight.\n");
+               ret = -EINVAL;
+               goto out9;
+       }
 
        lcd_dev = lcd_device_register(DRIVER_NAME, &pdev->dev, NULL, &bfin_lcd_ops);
        lcd_dev->props.max_contrast = 255, printk(KERN_INFO "Done.\n");
@@ -656,6 +663,8 @@ static int __devinit bfin_bf54x_probe(struct platform_device *pdev)
 
        return 0;
 
+out9:
+       unregister_framebuffer(fbinfo);
 out8:
        free_irq(info->irq, info);
 out7:
index 5653d08..31a2dec 100644 (file)
@@ -352,7 +352,7 @@ static int bl_get_brightness(struct backlight_device *bd)
        return 0;
 }
 
-static struct backlight_ops bfin_lq043fb_bl_ops = {
+static const struct backlight_ops bfin_lq043fb_bl_ops = {
        .get_brightness = bl_get_brightness,
 };
 
@@ -419,6 +419,7 @@ static irqreturn_t bfin_t350mcqb_irq_error(int irq, void *dev_id)
 
 static int __devinit bfin_t350mcqb_probe(struct platform_device *pdev)
 {
+       struct backlight_properties props;
        struct bfin_t350mcqbfb_info *info;
        struct fb_info *fbinfo;
        int ret;
@@ -540,10 +541,16 @@ static int __devinit bfin_t350mcqb_probe(struct platform_device *pdev)
                goto out8;
        }
 #ifndef NO_BL_SUPPORT
-       bl_dev =
-           backlight_device_register("bf52x-bl", NULL, NULL,
-                                     &bfin_lq043fb_bl_ops);
-       bl_dev->props.max_brightness = 255;
+       memset(&props, 0, sizeof(struct backlight_properties));
+       props.max_brightness = 255;
+       bl_dev = backlight_device_register("bf52x-bl", NULL, NULL,
+                                          &bfin_lq043fb_bl_ops, &props);
+       if (IS_ERR(bl_dev)) {
+               printk(KERN_ERR DRIVER_NAME
+                       ": unable to register backlight.\n");
+               ret = -EINVAL;
+               goto out9;
+       }
 
        lcd_dev = lcd_device_register(DRIVER_NAME, NULL, &bfin_lcd_ops);
        lcd_dev->props.max_contrast = 255, printk(KERN_INFO "Done.\n");
@@ -551,6 +558,8 @@ static int __devinit bfin_t350mcqb_probe(struct platform_device *pdev)
 
        return 0;
 
+out9:
+       unregister_framebuffer(fbinfo);
 out8:
        free_irq(info->irq, info);
 out7:
index 443e3c8..2fb552a 100644 (file)
@@ -94,6 +94,7 @@ static struct backlight_ops nvidia_bl_ops = {
 
 void nvidia_bl_init(struct nvidia_par *par)
 {
+       struct backlight_properties props;
        struct fb_info *info = pci_get_drvdata(par->pci_dev);
        struct backlight_device *bd;
        char name[12];
@@ -109,7 +110,10 @@ void nvidia_bl_init(struct nvidia_par *par)
 
        snprintf(name, sizeof(name), "nvidiabl%d", info->node);
 
-       bd = backlight_device_register(name, info->dev, par, &nvidia_bl_ops);
+       memset(&props, 0, sizeof(struct backlight_properties));
+       props.max_brightness = FB_BACKLIGHT_LEVELS - 1;
+       bd = backlight_device_register(name, info->dev, par, &nvidia_bl_ops,
+                                      &props);
        if (IS_ERR(bd)) {
                info->bl_dev = NULL;
                printk(KERN_WARNING "nvidia: Backlight registration failed\n");
@@ -121,7 +125,6 @@ void nvidia_bl_init(struct nvidia_par *par)
                0x158 * FB_BACKLIGHT_MAX / MAX_LEVEL,
                0x534 * FB_BACKLIGHT_MAX / MAX_LEVEL);
 
-       bd->props.max_brightness = FB_BACKLIGHT_LEVELS - 1;
        bd->props.brightness = bd->props.max_brightness;
        bd->props.power = FB_BLANK_UNBLANK;
        backlight_update_status(bd);
index fcd6a61..59769e8 100644 (file)
@@ -486,6 +486,7 @@ static struct attribute_group taal_attr_group = {
 
 static int taal_probe(struct omap_dss_device *dssdev)
 {
+       struct backlight_properties props;
        struct taal_data *td;
        struct backlight_device *bldev;
        int r;
@@ -520,11 +521,16 @@ static int taal_probe(struct omap_dss_device *dssdev)
 
        /* if no platform set_backlight() defined, presume DSI backlight
         * control */
+       memset(&props, 0, sizeof(struct backlight_properties));
        if (!dssdev->set_backlight)
                td->use_dsi_bl = true;
 
+       if (td->use_dsi_bl)
+               props.max_brightness = 255;
+       else
+               props.max_brightness = 127;
        bldev = backlight_device_register("taal", &dssdev->dev, dssdev,
-                       &taal_bl_ops);
+                                         &taal_bl_ops, &props);
        if (IS_ERR(bldev)) {
                r = PTR_ERR(bldev);
                goto err2;
@@ -534,13 +540,10 @@ static int taal_probe(struct omap_dss_device *dssdev)
 
        bldev->props.fb_blank = FB_BLANK_UNBLANK;
        bldev->props.power = FB_BLANK_UNBLANK;
-       if (td->use_dsi_bl) {
-               bldev->props.max_brightness = 255;
+       if (td->use_dsi_bl)
                bldev->props.brightness = 255;
-       } else {
-               bldev->props.max_brightness = 127;
+       else
                bldev->props.brightness = 127;
-       }
 
        taal_bl_update_status(bldev);
 
index d94c57f..618f36b 100644 (file)
@@ -338,6 +338,7 @@ static struct backlight_ops riva_bl_ops = {
 
 static void riva_bl_init(struct riva_par *par)
 {
+       struct backlight_properties props;
        struct fb_info *info = pci_get_drvdata(par->pdev);
        struct backlight_device *bd;
        char name[12];
@@ -353,7 +354,10 @@ static void riva_bl_init(struct riva_par *par)
 
        snprintf(name, sizeof(name), "rivabl%d", info->node);
 
-       bd = backlight_device_register(name, info->dev, par, &riva_bl_ops);
+       memset(&props, 0, sizeof(struct backlight_properties));
+       props.max_brightness = FB_BACKLIGHT_LEVELS - 1;
+       bd = backlight_device_register(name, info->dev, par, &riva_bl_ops,
+                                      &props);
        if (IS_ERR(bd)) {
                info->bl_dev = NULL;
                printk(KERN_WARNING "riva: Backlight registration failed\n");
@@ -365,7 +369,6 @@ static void riva_bl_init(struct riva_par *par)
                MIN_LEVEL * FB_BACKLIGHT_MAX / MAX_LEVEL,
                FB_BACKLIGHT_MAX);
 
-       bd->props.max_brightness = FB_BACKLIGHT_LEVELS - 1;
        bd->props.brightness = bd->props.max_brightness;
        bd->props.power = FB_BLANK_UNBLANK;
        backlight_update_status(bd);
index e22de83..d32ee94 100644 (file)
@@ -567,7 +567,7 @@ static void jffs2_free_tmp_dnode_info_list(struct rb_root *list)
                        else BUG();
                }
        }
-       list->rb_node = NULL;
+       *list = RB_ROOT;
 }
 
 static void jffs2_free_full_dirent_list(struct jffs2_full_dirent *fd)
index 1cf39df..0de1db6 100644 (file)
@@ -31,6 +31,7 @@
 #include <linux/vfs.h>
 #include <linux/moduleparam.h>
 #include <linux/smp_lock.h>
+#include <linux/bitmap.h>
 
 #include "sysctl.h"
 #include "logfile.h"
@@ -2458,7 +2459,6 @@ static void ntfs_put_super(struct super_block *sb)
 static s64 get_nr_free_clusters(ntfs_volume *vol)
 {
        s64 nr_free = vol->nr_clusters;
-       u32 *kaddr;
        struct address_space *mapping = vol->lcnbmp_ino->i_mapping;
        struct page *page;
        pgoff_t index, max_index;
@@ -2477,7 +2477,8 @@ static s64 get_nr_free_clusters(ntfs_volume *vol)
        ntfs_debug("Reading $Bitmap, max_index = 0x%lx, max_size = 0x%lx.",
                        max_index, PAGE_CACHE_SIZE / 4);
        for (index = 0; index < max_index; index++) {
-               unsigned int i;
+               unsigned long *kaddr;
+
                /*
                 * Read the page from page cache, getting it from backing store
                 * if necessary, and increment the use count.
@@ -2490,16 +2491,16 @@ static s64 get_nr_free_clusters(ntfs_volume *vol)
                        nr_free -= PAGE_CACHE_SIZE * 8;
                        continue;
                }
-               kaddr = (u32*)kmap_atomic(page, KM_USER0);
+               kaddr = kmap_atomic(page, KM_USER0);
                /*
-                * For each 4 bytes, subtract the number of set bits. If this
+                * Subtract the number of set bits. If this
                 * is the last page and it is partial we don't really care as
                 * it just means we do a little extra work but it won't affect
                 * the result as all out of range bytes are set to zero by
                 * ntfs_readpage().
                 */
-               for (i = 0; i < PAGE_CACHE_SIZE / 4; i++)
-                       nr_free -= (s64)hweight32(kaddr[i]);
+               nr_free -= bitmap_weight(kaddr,
+                                       PAGE_CACHE_SIZE * BITS_PER_BYTE);
                kunmap_atomic(kaddr, KM_USER0);
                page_cache_release(page);
        }
@@ -2538,7 +2539,6 @@ static s64 get_nr_free_clusters(ntfs_volume *vol)
 static unsigned long __get_nr_free_mft_records(ntfs_volume *vol,
                s64 nr_free, const pgoff_t max_index)
 {
-       u32 *kaddr;
        struct address_space *mapping = vol->mftbmp_ino->i_mapping;
        struct page *page;
        pgoff_t index;
@@ -2548,7 +2548,8 @@ static unsigned long __get_nr_free_mft_records(ntfs_volume *vol,
        ntfs_debug("Reading $MFT/$BITMAP, max_index = 0x%lx, max_size = "
                        "0x%lx.", max_index, PAGE_CACHE_SIZE / 4);
        for (index = 0; index < max_index; index++) {
-               unsigned int i;
+               unsigned long *kaddr;
+
                /*
                 * Read the page from page cache, getting it from backing store
                 * if necessary, and increment the use count.
@@ -2561,16 +2562,16 @@ static unsigned long __get_nr_free_mft_records(ntfs_volume *vol,
                        nr_free -= PAGE_CACHE_SIZE * 8;
                        continue;
                }
-               kaddr = (u32*)kmap_atomic(page, KM_USER0);
+               kaddr = kmap_atomic(page, KM_USER0);
                /*
-                * For each 4 bytes, subtract the number of set bits. If this
+                * Subtract the number of set bits. If this
                 * is the last page and it is partial we don't really care as
                 * it just means we do a little extra work but it won't affect
                 * the result as all out of range bytes are set to zero by
                 * ntfs_readpage().
                 */
-               for (i = 0; i < PAGE_CACHE_SIZE / 4; i++)
-                       nr_free -= (s64)hweight32(kaddr[i]);
+               nr_free -= bitmap_weight(kaddr,
+                                       PAGE_CACHE_SIZE * BITS_PER_BYTE);
                kunmap_atomic(kaddr, KM_USER0);
                page_cache_release(page);
        }
index 9083357..9962850 100644 (file)
@@ -932,6 +932,9 @@ xfs_aops_discard_page(
        if (!xfs_is_delayed_page(page, IOMAP_DELAY))
                goto out_invalidate;
 
+       if (XFS_FORCED_SHUTDOWN(ip->i_mount))
+               goto out_invalidate;
+
        xfs_fs_cmn_err(CE_ALERT, ip->i_mount,
                "page discard on page %p, inode 0x%llx, offset %llu.",
                        page, ip->i_ino, offset);
@@ -964,8 +967,10 @@ xfs_aops_discard_page(
 
                if (error) {
                        /* something screwed, just bail */
-                       xfs_fs_cmn_err(CE_ALERT, ip->i_mount,
-                       "page discard failed delalloc mapping lookup.");
+                       if (!XFS_FORCED_SHUTDOWN(ip->i_mount)) {
+                               xfs_fs_cmn_err(CE_ALERT, ip->i_mount,
+                               "page discard failed delalloc mapping lookup.");
+                       }
                        break;
                }
                if (!nimaps) {
@@ -991,8 +996,10 @@ xfs_aops_discard_page(
                ASSERT(!flist.xbf_count && !flist.xbf_first);
                if (error) {
                        /* something screwed, just bail */
-                       xfs_fs_cmn_err(CE_ALERT, ip->i_mount,
+                       if (!XFS_FORCED_SHUTDOWN(ip->i_mount)) {
+                               xfs_fs_cmn_err(CE_ALERT, ip->i_mount,
                        "page discard unable to remove delalloc mapping.");
+                       }
                        break;
                }
 next_buffer:
index 6f76ba8..bd111b7 100644 (file)
@@ -167,75 +167,6 @@ test_page_region(
        return (mask && (page_private(page) & mask) == mask);
 }
 
-/*
- *     Mapping of multi-page buffers into contiguous virtual space
- */
-
-typedef struct a_list {
-       void            *vm_addr;
-       struct a_list   *next;
-} a_list_t;
-
-static a_list_t                *as_free_head;
-static int             as_list_len;
-static DEFINE_SPINLOCK(as_lock);
-
-/*
- *     Try to batch vunmaps because they are costly.
- */
-STATIC void
-free_address(
-       void            *addr)
-{
-       a_list_t        *aentry;
-
-#ifdef CONFIG_XEN
-       /*
-        * Xen needs to be able to make sure it can get an exclusive
-        * RO mapping of pages it wants to turn into a pagetable.  If
-        * a newly allocated page is also still being vmap()ed by xfs,
-        * it will cause pagetable construction to fail.  This is a
-        * quick workaround to always eagerly unmap pages so that Xen
-        * is happy.
-        */
-       vunmap(addr);
-       return;
-#endif
-
-       aentry = kmalloc(sizeof(a_list_t), GFP_NOWAIT);
-       if (likely(aentry)) {
-               spin_lock(&as_lock);
-               aentry->next = as_free_head;
-               aentry->vm_addr = addr;
-               as_free_head = aentry;
-               as_list_len++;
-               spin_unlock(&as_lock);