summaryrefslogtreecommitdiff
path: root/drivers/usb/otg/ab8500-usb.c
diff options
context:
space:
mode:
authorSakethram Bommisetti <sakethram.bommisetti@stericsson.com>2011-09-12 19:37:44 +0530
committerLee Jones <lee.jones@linaro.org>2012-01-05 10:16:41 +0000
commit95fb255055d9f24cf93dcddacdcf5eb6e1ef500b (patch)
treeadee5c4dc85b7c06297a86d6036a758b80c210b4 /drivers/usb/otg/ab8500-usb.c
parent0e1a6cb491c7d54fb5f332badfd60cda4438c995 (diff)
USB: Generating unique serial number for USB
This patch adds code to extract Public ID which is unique for each board and use it as serial number for USB. This will enable us to connect multiple boards to host as usb devices and access individually. ST-Ericsson ID: 277646 Change-Id: I8daf882106a28127e18684da7a289cce6967f842 Signed-off-by: Sakethram Bommisetti <sakethram.bommisetti@stericsson.com> Signed-off-by: dushyanth.sr <dushyanth.sr@stericsson.com> Reviewed-on: http://gerrit.lud.stericsson.com/gerrit/30809 Reviewed-by: Praveena NADAHALLY <praveen.nadahally@stericsson.com>
Diffstat (limited to 'drivers/usb/otg/ab8500-usb.c')
-rw-r--r--drivers/usb/otg/ab8500-usb.c64
1 files changed, 64 insertions, 0 deletions
diff --git a/drivers/usb/otg/ab8500-usb.c b/drivers/usb/otg/ab8500-usb.c
index 4eb9ba06468..64876c36494 100644
--- a/drivers/usb/otg/ab8500-usb.c
+++ b/drivers/usb/otg/ab8500-usb.c
@@ -72,6 +72,9 @@
#define USB_PROBE_DELAY 1000 /* 1 seconds */
#define USB_LIMIT (200) /* If we have more than 200 irqs per second */
+#define PUBLIC_ID_BACKUPRAM1 (U8500_BACKUPRAM1_BASE + 0x0FC0)
+#define MAX_USB_SERIAL_NUMBER_LEN 31
+
/* Usb line status register */
enum ab8500_usb_link_status {
USB_LINK_NOT_CONFIGURED = 0,
@@ -119,6 +122,7 @@ struct ab8500_usb {
struct regulator *v_ulpi;
struct ab8500_usbgpio_platform_data *usb_gpio;
struct delayed_work work_usb_workaround;
+ struct kobject *serial_number_kobj;
};
static inline struct ab8500_usb *xceiv_to_ab(struct otg_transceiver *x)
@@ -698,6 +702,50 @@ irq_fail:
return err;
}
+/* Sys interfaces */
+static ssize_t usb_serial_number
+ (struct kobject *kobj, struct attribute *attr, char *buf)
+{
+ u32 bufer[5];
+ void __iomem *backup_ram = NULL;
+
+ backup_ram = ioremap(PUBLIC_ID_BACKUPRAM1, 0x14);
+
+ if (backup_ram) {
+ bufer[0] = readl(backup_ram);
+ bufer[1] = readl(backup_ram + 4);
+ bufer[2] = readl(backup_ram + 8);
+ bufer[3] = readl(backup_ram + 0x0c);
+ bufer[4] = readl(backup_ram + 0x10);
+
+ snprintf(buf, MAX_USB_SERIAL_NUMBER_LEN+1,
+ "%.8X%.8X%.8X%.8X%.8X",
+ bufer[0], bufer[1], bufer[2], bufer[3], bufer[4]);
+
+ iounmap(backup_ram);
+ } else
+ printk(KERN_ERR "$$ ioremap failed\n");
+
+ return strlen(buf);
+}
+
+static struct attribute usb_serial_number_attribute = \
+ {.name = "serial_number", .mode = S_IRUGO};
+
+static struct attribute *serial_number[] = {
+ &usb_serial_number_attribute,
+ NULL
+};
+
+const struct sysfs_ops usb_sysfs_ops = {
+ .show = usb_serial_number,
+};
+
+static struct kobj_type ktype_serial_number = {
+ .sysfs_ops = &usb_sysfs_ops,
+ .default_attrs = serial_number,
+};
+
static int __devinit ab8500_usb_probe(struct platform_device *pdev)
{
struct ab8500_usb *ab;
@@ -814,6 +862,22 @@ static int __devinit ab8500_usb_probe(struct platform_device *pdev)
/* Needed to enable ID detection. */
ab8500_usb_wd_workaround(ab);
+ ab->serial_number_kobj = kzalloc(sizeof(struct kobject), GFP_KERNEL);
+
+ if (ab->serial_number_kobj == NULL)
+ ret = -ENOMEM;
+ ab->serial_number_kobj->ktype = &ktype_serial_number;
+ kobject_init(ab->serial_number_kobj, ab->serial_number_kobj->ktype);
+
+ ret = kobject_set_name(ab->serial_number_kobj, "usb_serial_number");
+ if (ret)
+ kfree(ab->serial_number_kobj);
+
+ ret = kobject_add(ab->serial_number_kobj, NULL, "usb_serial_number");
+ if (ret)
+ kfree(ab->serial_number_kobj);
+
+
err = ab->usb_gpio->get(ab->dev);
if (err < 0)
goto fail3;