ARM/SAMSUNG S5P SERIES Multi Format Codec (MFC) SUPPORT
M: Kyungmin Park <kyungmin.park@samsung.com>
M: Kamil Debski <k.debski@samsung.com>
+M: Jeongtae Park <jtp.park@samsung.com>
L: linux-arm-kernel@lists.infradead.org
L: linux-media@vger.kernel.org
S: Maintained
F: net/wireless/*
X: net/wireless/wext*
+CHAR and MISC DRIVERS
+M: Arnd Bergmann <arnd@arndb.de>
+M: Greg Kroah-Hartman <greg@kroah.com>
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc.git
+S: Maintained
+F: drivers/char/*
+F: drivers/misc/*
+
CHECKPATCH
M: Andy Whitcroft <apw@canonical.com>
S: Supported
F: drivers/connector/
CONTROL GROUPS (CGROUPS)
-M: Paul Menage <paul@paulmenage.org>
+M: Tejun Heo <tj@kernel.org>
M: Li Zefan <lizf@cn.fujitsu.com>
L: containers@lists.linux-foundation.org
+L: cgroups@vger.kernel.org
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/tj/cgroup.git
S: Maintained
F: include/linux/cgroup*
F: kernel/cgroup*
F: drivers/gpu/drm/i915
F: include/drm/i915*
+DRM DRIVERS FOR EXYNOS
+M: Inki Dae <inki.dae@samsung.com>
+L: dri-devel@lists.freedesktop.org
+S: Supported
+F: drivers/gpu/drm/exynos
+F: include/drm/exynos*
+
DSCC4 DRIVER
M: Francois Romieu <romieu@fr.zoreil.com>
L: netdev@vger.kernel.org
F: drivers/net/ethernet/i825xx/eexpress.*
ETHERNET BRIDGE
-M: Stephen Hemminger <shemminger@linux-foundation.org>
+M: Stephen Hemminger <shemminger@vyatta.com>
L: bridge@lists.linux-foundation.org
L: netdev@vger.kernel.org
W: http://www.linuxfoundation.org/en/Net:Bridge
F: include/linux/jbd2.h
JSM Neo PCI based serial card
-M: Breno Leitao <leitao@linux.vnet.ibm.com>
+M: Lucas Tavares <lucaskt@linux.vnet.ibm.com>
L: linux-serial@vger.kernel.org
S: Maintained
F: drivers/tty/serial/jsm/
M: Balbir Singh <bsingharora@gmail.com>
M: Daisuke Nishimura <nishimura@mxp.nes.nec.co.jp>
M: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>
+L: cgroups@vger.kernel.org
L: linux-mm@kvack.org
S: Maintained
F: mm/memcontrol.c
M: Ralf Baechle <ralf@linux-mips.org>
L: linux-mips@linux-mips.org
W: http://www.linux-mips.org/
-T: git git://git.linux-mips.org/pub/scm/linux.git
+T: git git://git.linux-mips.org/pub/scm/ralf/linux.git
Q: http://patchwork.linux-mips.org/project/linux-mips/list/
S: Supported
F: Documentation/mips/
F: drivers/infiniband/hw/nes/
NETEM NETWORK EMULATOR
-M: Stephen Hemminger <shemminger@linux-foundation.org>
+M: Stephen Hemminger <shemminger@vyatta.com>
L: netem@lists.linux-foundation.org
S: Maintained
F: net/sched/sch_netem.c
F: include/linux/ppdev.h
PARAVIRT_OPS INTERFACE
-M: Jeremy Fitzhardinge <jeremy@xensource.com>
+M: Jeremy Fitzhardinge <jeremy@goop.org>
M: Chris Wright <chrisw@sous-sol.org>
M: Alok Kataria <akataria@vmware.com>
M: Rusty Russell <rusty@rustcorp.com.au>
F: drivers/usb/misc/sisusbvga/
SKGE, SKY2 10/100/1000 GIGABIT ETHERNET DRIVERS
-M: Stephen Hemminger <shemminger@linux-foundation.org>
+M: Stephen Hemminger <shemminger@vyatta.com>
L: netdev@vger.kernel.org
S: Maintained
F: drivers/net/ethernet/marvell/sk*
SOUND - SOC LAYER / DYNAMIC AUDIO POWER MANAGEMENT (ASoC)
M: Liam Girdwood <lrg@ti.com>
M: Mark Brown <broonie@opensource.wolfsonmicro.com>
-T: git git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound-2.6.git
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git
L: alsa-devel@alsa-project.org (moderated for non-subscribers)
W: http://alsa-project.org/main/index.php/ASoC
S: Supported
STABLE BRANCH
M: Greg Kroah-Hartman <greg@kroah.com>
- L: stable@kernel.org
+ L: stable@vger.kernel.org
S: Maintained
STAGING SUBSYSTEM
F: arch/x86/kernel/cpu/mcheck/*
XEN HYPERVISOR INTERFACE
-M: Jeremy Fitzhardinge <jeremy.fitzhardinge@citrix.com>
M: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
+M: Jeremy Fitzhardinge <jeremy@goop.org>
L: xen-devel@lists.xensource.com (moderated for non-subscribers)
L: virtualization@lists.linux-foundation.org
S: Supported
XFS FILESYSTEM
P: Silicon Graphics Inc
-M: Alex Elder <aelder@sgi.com>
+M: Ben Myers <bpm@sgi.com>
+M: Alex Elder <elder@kernel.org>
M: xfs-masters@oss.sgi.com
L: xfs@oss.sgi.com
W: http://oss.sgi.com/projects/xfs
#include <linux/kallsyms.h>
#include <linux/mutex.h>
#include <linux/async.h>
+#include <linux/pm_runtime.h>
#include "base.h"
#include "power/power.h"
.store = dev_attr_store,
};
+ #define to_ext_attr(x) container_of(x, struct dev_ext_attribute, attr)
+
+ ssize_t device_store_ulong(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t size)
+ {
+ struct dev_ext_attribute *ea = to_ext_attr(attr);
+ char *end;
+ unsigned long new = simple_strtoul(buf, &end, 0);
+ if (end == buf)
+ return -EINVAL;
+ *(unsigned long *)(ea->var) = new;
+ /* Always return full write size even if we didn't consume all */
+ return size;
+ }
+ EXPORT_SYMBOL_GPL(device_store_ulong);
+
+ ssize_t device_show_ulong(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+ {
+ struct dev_ext_attribute *ea = to_ext_attr(attr);
+ return snprintf(buf, PAGE_SIZE, "%lx\n", *(unsigned long *)(ea->var));
+ }
+ EXPORT_SYMBOL_GPL(device_show_ulong);
+
+ ssize_t device_store_int(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t size)
+ {
+ struct dev_ext_attribute *ea = to_ext_attr(attr);
+ char *end;
+ long new = simple_strtol(buf, &end, 0);
+ if (end == buf || new > INT_MAX || new < INT_MIN)
+ return -EINVAL;
+ *(int *)(ea->var) = new;
+ /* Always return full write size even if we didn't consume all */
+ return size;
+ }
+ EXPORT_SYMBOL_GPL(device_store_int);
+
+ ssize_t device_show_int(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+ {
+ struct dev_ext_attribute *ea = to_ext_attr(attr);
+
+ return snprintf(buf, PAGE_SIZE, "%d\n", *(int *)(ea->var));
+ }
+ EXPORT_SYMBOL_GPL(device_show_int);
/**
* device_release - free device structure.
static struct device_attribute devt_attr =
__ATTR(dev, S_IRUGO, show_dev, NULL);
- /* kset to create /sys/devices/ */
+ /* /sys/devices/ */
struct kset *devices_kset;
/**
return k;
}
+ /* subsystems can specify a default root directory for their devices */
+ if (!parent && dev->bus && dev->bus->dev_root)
+ return &dev->bus->dev_root->kobj;
+
if (parent)
return &parent->kobj;
return NULL;
cleanup_glue_dir(dev, dev->kobj.parent);
}
- static void setup_parent(struct device *dev, struct device *parent)
- {
- struct kobject *kobj;
- kobj = get_device_parent(dev, parent);
- if (kobj)
- dev->kobj.parent = kobj;
- }
-
static int device_add_class_symlinks(struct device *dev)
{
int error;
int device_add(struct device *dev)
{
struct device *parent = NULL;
+ struct kobject *kobj;
struct class_interface *class_intf;
int error = -EINVAL;
dev->init_name = NULL;
}
+ /* subsystems can specify simple device enumeration */
+ if (!dev_name(dev) && dev->bus && dev->bus->dev_name)
+ dev_set_name(dev, "%s%u", dev->bus->dev_name, dev->id);
+
if (!dev_name(dev)) {
error = -EINVAL;
goto name_error;
pr_debug("device: '%s': %s\n", dev_name(dev), __func__);
parent = get_device(dev->parent);
- setup_parent(dev, parent);
+ kobj = get_device_parent(dev, parent);
+ if (kobj)
+ dev->kobj.parent = kobj;
/* use parent numa_node */
if (parent)
&parent->p->klist_children);
if (dev->class) {
- mutex_lock(&dev->class->p->class_mutex);
+ mutex_lock(&dev->class->p->mutex);
/* tie the class to the device */
klist_add_tail(&dev->knode_class,
&dev->class->p->klist_devices);
/* notify any interfaces that the device is here */
list_for_each_entry(class_intf,
- &dev->class->p->class_interfaces, node)
+ &dev->class->p->interfaces, node)
if (class_intf->add_dev)
class_intf->add_dev(dev, class_intf);
- mutex_unlock(&dev->class->p->class_mutex);
+ mutex_unlock(&dev->class->p->mutex);
}
done:
put_device(dev);
if (dev->class) {
device_remove_class_symlinks(dev);
- mutex_lock(&dev->class->p->class_mutex);
+ mutex_lock(&dev->class->p->mutex);
/* notify any interfaces that the device is now gone */
list_for_each_entry(class_intf,
- &dev->class->p->class_interfaces, node)
+ &dev->class->p->interfaces, node)
if (class_intf->remove_dev)
class_intf->remove_dev(dev, class_intf);
/* remove the device from the class list */
klist_del(&dev->knode_class);
- mutex_unlock(&dev->class->p->class_mutex);
+ mutex_unlock(&dev->class->p->mutex);
}
device_remove_file(dev, &uevent_attr);
device_remove_attrs(dev);
*/
list_del_init(&dev->kobj.entry);
spin_unlock(&devices_kset->list_lock);
+ /* Disable all device's runtime power management */
+ pm_runtime_disable(dev);
if (dev->bus && dev->bus->shutdown) {
dev_dbg(dev, "shutdown\n");
/* Canyon CN-BTU1 with HID interfaces */
{ USB_DEVICE(0x0c10, 0x0000) },
+ /* Broadcom BCM20702A0 */
+ { USB_DEVICE(0x413c, 0x8197) },
+
{ } /* Terminating entry */
};
.supports_autosuspend = 1,
};
- static int __init btusb_init(void)
- {
- BT_INFO("Generic Bluetooth USB driver ver %s", VERSION);
-
- return usb_register(&btusb_driver);
- }
-
- static void __exit btusb_exit(void)
- {
- usb_deregister(&btusb_driver);
- }
-
- module_init(btusb_init);
- module_exit(btusb_exit);
+ module_usb_driver(btusb_driver);
module_param(ignore_dga, bool, 0644);
MODULE_PARM_DESC(ignore_dga, "Ignore devices with id 08fd:0001");
#include <linux/usb/usbnet.h>
#include <linux/slab.h>
-#define DRIVER_VERSION "26-Sep-2011"
+#define DRIVER_VERSION "08-Nov-2011"
#define DRIVER_NAME "asix"
/* ASIX AX8817X based USB 2.0 Ethernet Devices */
#define MARVELL_CTRL_TXDELAY 0x0002
#define MARVELL_CTRL_RXDELAY 0x0080
-#define PHY_MODE_RTL8211CL 0x0004
+#define PHY_MODE_RTL8211CL 0x000C
/* This structure cannot exceed sizeof(unsigned long [5]) AKA 20 bytes */
struct asix_data {
{
int phy_reg;
u32 phy_id;
+ int i;
- phy_reg = asix_mdio_read(dev->net, dev->mii.phy_id, MII_PHYSID1);
- if (phy_reg < 0)
+ /* Poll for the rare case the FW or phy isn't ready yet. */
+ for (i = 0; i < 100; i++) {
+ phy_reg = asix_mdio_read(dev->net, dev->mii.phy_id, MII_PHYSID1);
+ if (phy_reg != 0 && phy_reg != 0xFFFF)
+ break;
+ mdelay(1);
+ }
+
+ if (phy_reg <= 0 || phy_reg == 0xFFFF)
return 0;
phy_id = (phy_reg & 0xffff) << 16;
static int ax88772_bind(struct usbnet *dev, struct usb_interface *intf)
{
- int ret;
+ int ret, embd_phy;
struct asix_data *data = (struct asix_data *)&dev->data;
u8 buf[ETH_ALEN];
u32 phyid;
dev->mii.reg_num_mask = 0x1f;
dev->mii.phy_id = asix_get_phy_addr(dev);
- phyid = asix_get_phyid(dev);
- dbg("PHYID=0x%08x", phyid);
-
dev->net->netdev_ops = &ax88772_netdev_ops;
dev->net->ethtool_ops = &ax88772_ethtool_ops;
- ret = ax88772_reset(dev);
+ embd_phy = ((dev->mii.phy_id & 0x1f) == 0x10 ? 1 : 0);
+
+ /* Reset the PHY to normal operation mode */
+ ret = asix_write_cmd(dev, AX_CMD_SW_PHY_SELECT, embd_phy, 0, 0, NULL);
+ if (ret < 0) {
+ dbg("Select PHY #1 failed: %d", ret);
+ return ret;
+ }
+
+ ret = asix_sw_reset(dev, AX_SWRESET_IPPD | AX_SWRESET_PRL);
+ if (ret < 0)
+ return ret;
+
+ msleep(150);
+
+ ret = asix_sw_reset(dev, AX_SWRESET_CLEAR);
if (ret < 0)
return ret;
+ msleep(150);
+
+ ret = asix_sw_reset(dev, embd_phy ? AX_SWRESET_IPRL : AX_SWRESET_PRTE);
+
+ /* Read PHYID register *AFTER* the PHY was reset properly */
+ phyid = asix_get_phyid(dev);
+ dbg("PHYID=0x%08x", phyid);
+
/* Asix framing packs multiple eth frames into a 2K usb bulk transfer */
if (dev->driver_info->flags & FLAG_FRAMING_AX) {
/* hard_mtu is still the default - the device does not support
__le16 eeprom;
u8 status;
int gpio0 = 0;
+ u32 phyid;
asix_read_cmd(dev, AX_CMD_READ_GPIOS, 0, 0, 1, &status);
dbg("GPIO Status: 0x%04x", status);
data->ledmode = 0;
gpio0 = 1;
} else {
- data->phymode = le16_to_cpu(eeprom) & 7;
+ data->phymode = le16_to_cpu(eeprom) & 0x7F;
data->ledmode = le16_to_cpu(eeprom) >> 8;
gpio0 = (le16_to_cpu(eeprom) & 0x80) ? 0 : 1;
}
dbg("GPIO0: %d, PhyMode: %d", gpio0, data->phymode);
+ /* Power up external GigaPHY through AX88178 GPIO pin */
asix_write_gpio(dev, AX_GPIO_RSE | AX_GPIO_GPO_1 | AX_GPIO_GPO1EN, 40);
if ((le16_to_cpu(eeprom) >> 8) != 1) {
asix_write_gpio(dev, 0x003c, 30);
asix_write_gpio(dev, AX_GPIO_GPO1EN | AX_GPIO_GPO_1, 30);
}
+ /* Read PHYID register *AFTER* powering up PHY */
+ phyid = asix_get_phyid(dev);
+ dbg("PHYID=0x%08x", phyid);
+
+ /* Set AX88178 to enable MII/GMII/RGMII interface for external PHY */
+ asix_write_cmd(dev, AX_CMD_SW_PHY_SELECT, 0, 0, 0, NULL);
+
asix_sw_reset(dev, 0);
msleep(150);
{
int ret;
u8 buf[ETH_ALEN];
- u32 phyid;
struct asix_data *data = (struct asix_data *)&dev->data;
data->eeprom_len = AX88772_EEPROM_LEN;
dev->net->netdev_ops = &ax88178_netdev_ops;
dev->net->ethtool_ops = &ax88178_ethtool_ops;
- phyid = asix_get_phyid(dev);
- dbg("PHYID=0x%08x", phyid);
+ /* Blink LEDS so users know driver saw dongle */
+ asix_sw_reset(dev, 0);
+ msleep(150);
- ret = ax88178_reset(dev);
- if (ret < 0)
- return ret;
+ asix_sw_reset(dev, AX_SWRESET_PRL | AX_SWRESET_IPPD);
+ msleep(150);
/* Asix framing packs multiple eth frames into a 2K usb bulk transfer */
if (dev->driver_info->flags & FLAG_FRAMING_AX) {
.supports_autosuspend = 1,
};
- static int __init asix_init(void)
- {
- return usb_register(&asix_driver);
- }
- module_init(asix_init);
-
- static void __exit asix_exit(void)
- {
- usb_deregister(&asix_driver);
- }
- module_exit(asix_exit);
+ module_usb_driver(asix_driver);
MODULE_AUTHOR("David Hollis");
MODULE_VERSION(DRIVER_VERSION);
int status;
struct cdc_state *info = (void *) &dev->data;
+ BUILD_BUG_ON((sizeof(((struct usbnet *)0)->data)
+ < sizeof(struct cdc_state)));
+
status = usbnet_generic_cdc_bind(dev, intf);
if (status < 0)
return status;
{
USB_DEVICE_AND_INTERFACE_INFO(0x1004, 0x61aa, USB_CLASS_COMM,
USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE),
- .driver_info = (unsigned long)&wwan_info,
+ .driver_info = 0,
},
/*
.supports_autosuspend = 1,
};
-
- static int __init cdc_init(void)
- {
- BUILD_BUG_ON((sizeof(((struct usbnet *)0)->data)
- < sizeof(struct cdc_state)));
-
- return usb_register(&cdc_driver);
- }
- module_init(cdc_init);
-
- static void __exit cdc_exit(void)
- {
- usb_deregister(&cdc_driver);
- }
- module_exit(cdc_exit);
+ module_usb_driver(cdc_driver);
MODULE_AUTHOR("David Brownell");
MODULE_DESCRIPTION("USB CDC Ethernet devices");
}
frame = (struct vl600_frame_hdr *) buf->data;
- /* NOTE: Should check that frame->magic == 0x53544448?
- * Otherwise if we receive garbage at the beginning of the frame
- * we may end up allocating a huge buffer and saving all the
- * future incoming data into it. */
+ /* Yes, check that frame->magic == 0x53544448 (or 0x44544d48),
+ * otherwise we may run out of memory w/a bad packet */
+ if (ntohl(frame->magic) != 0x53544448 &&
+ ntohl(frame->magic) != 0x44544d48)
+ goto error;
if (buf->len < sizeof(*frame) ||
buf->len != le32_to_cpup(&frame->len)) {
* overwrite the remaining fields.
*/
packet = (struct vl600_pkt_hdr *) skb->data;
+ /* The VL600 wants IPv6 packets to have an IPv4 ethertype
+ * Since this modem only supports IPv4 and IPv6, just set all
+ * frames to 0x0800 (ETH_P_IP)
+ */
+ packet->h_proto = htons(ETH_P_IP);
memset(&packet->dummy, 0, sizeof(packet->dummy));
packet->len = cpu_to_le32(orig_len);
if (skb->len < full_len) /* Pad */
skb_put(skb, full_len - skb->len);
- /* The VL600 wants IPv6 packets to have an IPv4 ethertype
- * Check if this is an IPv6 packet, and set the ethertype
- * to 0x800
- */
- if ((skb->data[sizeof(struct vl600_pkt_hdr *) + 0x22] & 0xf0) == 0x60) {
- skb->data[sizeof(struct vl600_pkt_hdr *) + 0x20] = 0x08;
- skb->data[sizeof(struct vl600_pkt_hdr *) + 0x21] = 0;
- }
-
return skb;
}
static const struct driver_info vl600_info = {
.description = "LG VL600 modem",
- .flags = FLAG_ETHER | FLAG_RX_ASSEMBLE,
+ .flags = FLAG_RX_ASSEMBLE | FLAG_WWAN,
.bind = vl600_bind,
.unbind = vl600_unbind,
.status = usbnet_cdc_status,
.resume = usbnet_resume,
};
- static int __init vl600_init(void)
- {
- return usb_register(&lg_vl600_driver);
- }
- module_init(vl600_init);
-
- static void __exit vl600_exit(void)
- {
- usb_deregister(&lg_vl600_driver);
- }
- module_exit(vl600_exit);
+ module_usb_driver(lg_vl600_driver);
MODULE_AUTHOR("Anrzej Zaborowski");
MODULE_DESCRIPTION("LG-VL600 modem's ethernet link");
#define USB_VENDOR_ID_SMSC (0x0424)
#define USB_PRODUCT_ID_LAN7500 (0x7500)
#define USB_PRODUCT_ID_LAN7505 (0x7505)
+#define RXW_PADDING 2
#define check_warn(ret, fmt, args...) \
({ if (ret < 0) netdev_warn(dev->net, fmt, ##args); })
memcpy(&rx_cmd_b, skb->data, sizeof(rx_cmd_b));
le32_to_cpus(&rx_cmd_b);
- skb_pull(skb, 4 + NET_IP_ALIGN);
+ skb_pull(skb, 4 + RXW_PADDING);
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;
+ size = (rx_cmd_a & RX_CMD_A_LEN) - RXW_PADDING;
+ align_count = (4 - ((size + RXW_PADDING) % 4)) % 4;
if (unlikely(rx_cmd_a & RX_CMD_A_RED)) {
netif_dbg(dev, rx_err, dev->net,
.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_usb_driver(smsc75xx_driver);
MODULE_AUTHOR("Nancy Lin");
MODULE_AUTHOR("Steve Glendinning <steve.glendinning@smsc.com>");
{ USB_DEVICE(0x050d, 0x935b) },
/* Buffalo */
{ USB_DEVICE(0x0411, 0x00e8) },
+ { USB_DEVICE(0x0411, 0x0158) },
{ USB_DEVICE(0x0411, 0x016f) },
{ USB_DEVICE(0x0411, 0x01a2) },
/* Corega */
.resume = rt2x00usb_resume,
};
- static int __init rt2800usb_init(void)
- {
- return usb_register(&rt2800usb_driver);
- }
-
- static void __exit rt2800usb_exit(void)
- {
- usb_deregister(&rt2800usb_driver);
- }
-
- module_init(rt2800usb_init);
- module_exit(rt2800usb_exit);
+ module_usb_driver(rt2800usb_driver);
result = ene_send_scsi_cmd(us, FDIR_WRITE, scsi_sglist(srb), 1);
} else {
void *buf;
- int offset;
+ int offset = 0;
u16 PhyBlockAddr;
u8 PageNum;
- u32 result;
u16 len, oldphy, newphy;
buf = kmalloc(blenByte, GFP_KERNEL);
.soft_unbind = 1,
};
- static int __init ene_ub6250_init(void)
- {
- return usb_register(&ene_ub6250_driver);
- }
-
- static void __exit ene_ub6250_exit(void)
- {
- usb_deregister(&ene_ub6250_driver);
- }
-
- module_init(ene_ub6250_init);
- module_exit(ene_ub6250_exit);
+ module_usb_driver(ene_ub6250_driver);
* struct bus_type - The bus type of the device
*
* @name: The name of the bus.
+ * @dev_name: Used for subsystems to enumerate devices like ("foo%u", dev->id).
+ * @dev_root: Default device to use as the parent.
* @bus_attrs: Default attributes of the bus.
* @dev_attrs: Default attributes of the devices on the bus.
* @drv_attrs: Default attributes of the device drivers on the bus.
* @resume: Called to bring a device on this bus out of sleep mode.
* @pm: Power management operations of this bus, callback the specific
* device driver's pm-ops.
- * @iommu_ops IOMMU specific operations for this bus, used to attach IOMMU
+ * @iommu_ops: IOMMU specific operations for this bus, used to attach IOMMU
* driver implementations to a bus and allow the driver to do
* bus-specific setup
* @p: The private data of the driver core, only the driver core can
*/
struct bus_type {
const char *name;
+ const char *dev_name;
+ struct device *dev_root;
struct bus_attribute *bus_attrs;
struct device_attribute *dev_attrs;
struct driver_attribute *drv_attrs;
struct subsys_private *p;
};
- extern int __must_check bus_register(struct bus_type *bus);
+ /* This is a #define to keep the compiler from merging different
+ * instances of the __key variable */
+ #define bus_register(subsys) \
+ ({ \
+ static struct lock_class_key __key; \
+ __bus_register(subsys, &__key); \
+ })
+ extern int __must_check __bus_register(struct bus_type *bus,
+ struct lock_class_key *key);
extern void bus_unregister(struct bus_type *bus);
extern int __must_check bus_rescan_devices(struct bus_type *bus);
/* iterator helpers for buses */
+ struct subsys_dev_iter {
+ struct klist_iter ki;
+ const struct device_type *type;
+ };
+ void subsys_dev_iter_init(struct subsys_dev_iter *iter,
+ struct bus_type *subsys,
+ struct device *start,
+ const struct device_type *type);
+ struct device *subsys_dev_iter_next(struct subsys_dev_iter *iter);
+ void subsys_dev_iter_exit(struct subsys_dev_iter *iter);
int bus_for_each_dev(struct bus_type *bus, struct device *start, void *data,
int (*fn)(struct device *dev, void *data));
struct device *bus_find_device_by_name(struct bus_type *bus,
struct device *start,
const char *name);
-
+ struct device *subsys_find_device_by_id(struct bus_type *bus, unsigned int id,
+ struct device *hint);
int bus_for_each_drv(struct bus_type *bus, struct device_driver *start,
void *data, int (*fn)(struct device_driver *, void *));
-
void bus_sort_breadthfirst(struct bus_type *bus,
int (*compare)(const struct device *a,
const struct device *b));
struct device *start, void *data,
int (*match)(struct device *dev, void *data));
+ /**
+ * struct subsys_interface - interfaces to device functions
+ * @name name of the device function
+ * @subsystem subsytem of the devices to attach to
+ * @node the list of functions registered at the subsystem
+ * @add device hookup to device function handler
+ * @remove device hookup to device function handler
+ *
+ * Simple interfaces attached to a subsystem. Multiple interfaces can
+ * attach to a subsystem and its devices. Unlike drivers, they do not
+ * exclusively claim or control devices. Interfaces usually represent
+ * a specific functionality of a subsystem/class of devices.
+ */
+ struct subsys_interface {
+ const char *name;
+ struct bus_type *subsys;
+ struct list_head node;
+ int (*add_dev)(struct device *dev, struct subsys_interface *sif);
+ int (*remove_dev)(struct device *dev, struct subsys_interface *sif);
+ };
+
+ int subsys_interface_register(struct subsys_interface *sif);
+ void subsys_interface_unregister(struct subsys_interface *sif);
+
+ int subsys_system_register(struct bus_type *subsys,
+ const struct attribute_group **groups);
+
/**
* struct class - device classes
* @name: Name of the class.
const char *buf, size_t count);
};
+ struct dev_ext_attribute {
+ struct device_attribute attr;
+ void *var;
+ };
+
+ ssize_t device_show_ulong(struct device *dev, struct device_attribute *attr,
+ char *buf);
+ ssize_t device_store_ulong(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count);
+ ssize_t device_show_int(struct device *dev, struct device_attribute *attr,
+ char *buf);
+ ssize_t device_store_int(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count);
+
#define DEVICE_ATTR(_name, _mode, _show, _store) \
- struct device_attribute dev_attr_##_name = __ATTR(_name, _mode, _show, _store)
+ struct device_attribute dev_attr_##_name = __ATTR(_name, _mode, _show, _store)
+ #define DEVICE_ULONG_ATTR(_name, _mode, _var) \
+ struct dev_ext_attribute dev_attr_##_name = \
+ { __ATTR(_name, _mode, device_show_ulong, device_store_ulong), &(_var) }
+ #define DEVICE_INT_ATTR(_name, _mode, _var) \
+ struct dev_ext_attribute dev_attr_##_name = \
+ { __ATTR(_name, _mode, device_show_ulong, device_store_ulong), &(_var) }
extern int __must_check device_create_file(struct device *device,
const struct device_attribute *entry);
extern void *devm_kzalloc(struct device *dev, size_t size, gfp_t gfp);
extern void devm_kfree(struct device *dev, void *p);
+ void __iomem *devm_request_and_ioremap(struct device *dev,
+ struct resource *res);
+
struct device_dma_parameters {
/*
* a low level driver may set these to teach IOMMU code about
struct device_node *of_node; /* associated device tree node */
dev_t devt; /* dev_t, creates the sysfs "dev" */
+ u32 id; /* device instance */
spinlock_t devres_lock;
struct list_head devres_head;
return !!dev->power.async_suspend;
}
+static inline void pm_suspend_ignore_children(struct device *dev, bool enable)
+{
+ dev->power.ignore_children = enable;
+}
+
static inline void device_lock(struct device *dev)
{
mutex_lock(&dev->mutex);
#define sysfs_deprecated 0
#endif
+ /**
+ * module_driver() - Helper macro for drivers that don't do anything
+ * special in module init/exit. This eliminates a lot of boilerplate.
+ * Each module may only use this macro once, and calling it replaces
+ * module_init() and module_exit().
+ *
+ * Use this macro to construct bus specific macros for registering
+ * drivers, and do not use it on its own.
+ */
+ #define module_driver(__driver, __register, __unregister) \
+ static int __init __driver##_init(void) \
+ { \
+ return __register(&(__driver)); \
+ } \
+ module_init(__driver##_init); \
+ static void __exit __driver##_exit(void) \
+ { \
+ __unregister(&(__driver)); \
+ } \
+ module_exit(__driver##_exit);
+
#endif /* _DEVICE_H_ */
/* Internal numbers to terminate lists */
#define I2C_CLIENT_END 0xfffeU
-/* The numbers to use to set I2C bus address */
-#define ANY_I2C_BUS 0xffff
-
/* Construct an I2C_CLIENT_END-terminated array of i2c addresses */
#define I2C_ADDRS(addr, addrs...) \
((const unsigned short []){ addr, ## addrs, I2C_CLIENT_END })
{
return adap->nr;
}
+
+ /**
+ * module_i2c_driver() - Helper macro for registering a I2C driver
+ * @__i2c_driver: i2c_driver struct
+ *
+ * Helper macro for I2C drivers which do not do anything special in module
+ * init/exit. This eliminates a lot of boilerplate. Each module may only
+ * use this macro once, and calling it replaces module_init() and module_exit()
+ */
+ #define module_i2c_driver(__i2c_driver) \
+ module_driver(__i2c_driver, i2c_add_driver, \
+ i2c_del_driver)
+
#endif /* I2C */
#endif /* __KERNEL__ */