aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/arm/mach-sa1100/assabet.c1
-rw-r--r--arch/arm/mach-sa1100/cerf.c1
-rw-r--r--arch/arm/mach-sa1100/collie.c8
-rw-r--r--arch/arm/mach-sa1100/include/mach/mcp.h2
-rw-r--r--arch/arm/mach-sa1100/lart.c1
-rw-r--r--arch/arm/mach-sa1100/shannon.c1
-rw-r--r--arch/arm/mach-sa1100/simpad.c8
-rw-r--r--drivers/mfd/mcp-core.c44
-rw-r--r--drivers/mfd/mcp-sa11x0.c7
-rw-r--r--drivers/mfd/ucb1x00-core.c48
-rw-r--r--drivers/mfd/ucb1x00-ts.c2
-rw-r--r--include/linux/mfd/mcp.h7
-rw-r--r--include/linux/mfd/ucb1x00.h5
-rw-r--r--include/linux/mod_devicetable.h11
-rw-r--r--scripts/mod/file2alias.c13
15 files changed, 138 insertions, 21 deletions
diff --git a/arch/arm/mach-sa1100/assabet.c b/arch/arm/mach-sa1100/assabet.c
index 3dd133f18415..14b31f116ef9 100644
--- a/arch/arm/mach-sa1100/assabet.c
+++ b/arch/arm/mach-sa1100/assabet.c
@@ -202,6 +202,7 @@ static struct irda_platform_data assabet_irda_data = {
202static struct mcp_plat_data assabet_mcp_data = { 202static struct mcp_plat_data assabet_mcp_data = {
203 .mccr0 = MCCR0_ADM, 203 .mccr0 = MCCR0_ADM,
204 .sclk_rate = 11981000, 204 .sclk_rate = 11981000,
205 .codec = "ucb1x00",
205}; 206};
206 207
207static void __init assabet_init(void) 208static void __init assabet_init(void)
diff --git a/arch/arm/mach-sa1100/cerf.c b/arch/arm/mach-sa1100/cerf.c
index 7f3da4b11ec9..b7db7cd08305 100644
--- a/arch/arm/mach-sa1100/cerf.c
+++ b/arch/arm/mach-sa1100/cerf.c
@@ -124,6 +124,7 @@ static void __init cerf_map_io(void)
124static struct mcp_plat_data cerf_mcp_data = { 124static struct mcp_plat_data cerf_mcp_data = {
125 .mccr0 = MCCR0_ADM, 125 .mccr0 = MCCR0_ADM,
126 .sclk_rate = 11981000, 126 .sclk_rate = 11981000,
127 .codec = "ucb1x00",
127}; 128};
128 129
129static void __init cerf_init(void) 130static void __init cerf_init(void)
diff --git a/arch/arm/mach-sa1100/collie.c b/arch/arm/mach-sa1100/collie.c
index 2965cc9d424e..b0b5efee683b 100644
--- a/arch/arm/mach-sa1100/collie.c
+++ b/arch/arm/mach-sa1100/collie.c
@@ -27,6 +27,7 @@
27#include <linux/timer.h> 27#include <linux/timer.h>
28#include <linux/gpio.h> 28#include <linux/gpio.h>
29#include <linux/pda_power.h> 29#include <linux/pda_power.h>
30#include <linux/mfd/ucb1x00.h>
30 31
31#include <mach/hardware.h> 32#include <mach/hardware.h>
32#include <asm/mach-types.h> 33#include <asm/mach-types.h>
@@ -85,10 +86,15 @@ static struct scoop_pcmcia_config collie_pcmcia_config = {
85 .num_devs = 1, 86 .num_devs = 1,
86}; 87};
87 88
89static struct ucb1x00_plat_data collie_ucb1x00_data = {
90 .gpio_base = COLLIE_TC35143_GPIO_BASE,
91};
92
88static struct mcp_plat_data collie_mcp_data = { 93static struct mcp_plat_data collie_mcp_data = {
89 .mccr0 = MCCR0_ADM | MCCR0_ExtClk, 94 .mccr0 = MCCR0_ADM | MCCR0_ExtClk,
90 .sclk_rate = 9216000, 95 .sclk_rate = 9216000,
91 .gpio_base = COLLIE_TC35143_GPIO_BASE, 96 .codec = "ucb1x00",
97 .codec_pdata = &collie_ucb1x00_data,
92}; 98};
93 99
94/* 100/*
diff --git a/arch/arm/mach-sa1100/include/mach/mcp.h b/arch/arm/mach-sa1100/include/mach/mcp.h
index ed1a331508a7..586cec898b35 100644
--- a/arch/arm/mach-sa1100/include/mach/mcp.h
+++ b/arch/arm/mach-sa1100/include/mach/mcp.h
@@ -17,6 +17,8 @@ struct mcp_plat_data {
17 u32 mccr1; 17 u32 mccr1;
18 unsigned int sclk_rate; 18 unsigned int sclk_rate;
19 int gpio_base; 19 int gpio_base;
20 const char *codec;
21 void *codec_pdata;
20}; 22};
21 23
22#endif 24#endif
diff --git a/arch/arm/mach-sa1100/lart.c b/arch/arm/mach-sa1100/lart.c
index 5bc59d0947ba..34bbdd986e43 100644
--- a/arch/arm/mach-sa1100/lart.c
+++ b/arch/arm/mach-sa1100/lart.c
@@ -24,6 +24,7 @@
24static struct mcp_plat_data lart_mcp_data = { 24static struct mcp_plat_data lart_mcp_data = {
25 .mccr0 = MCCR0_ADM, 25 .mccr0 = MCCR0_ADM,
26 .sclk_rate = 11981000, 26 .sclk_rate = 11981000,
27 .codec = "ucb1x00",
27}; 28};
28 29
29static void __init lart_init(void) 30static void __init lart_init(void)
diff --git a/arch/arm/mach-sa1100/shannon.c b/arch/arm/mach-sa1100/shannon.c
index 1cccbf5b9e9a..252faa5e2395 100644
--- a/arch/arm/mach-sa1100/shannon.c
+++ b/arch/arm/mach-sa1100/shannon.c
@@ -55,6 +55,7 @@ static struct resource shannon_flash_resource = {
55static struct mcp_plat_data shannon_mcp_data = { 55static struct mcp_plat_data shannon_mcp_data = {
56 .mccr0 = MCCR0_ADM, 56 .mccr0 = MCCR0_ADM,
57 .sclk_rate = 11981000, 57 .sclk_rate = 11981000,
58 .codec = "ucb1x00",
58}; 59};
59 60
60static void __init shannon_init(void) 61static void __init shannon_init(void)
diff --git a/arch/arm/mach-sa1100/simpad.c b/arch/arm/mach-sa1100/simpad.c
index 4790f3f3d008..7eac8ebab94e 100644
--- a/arch/arm/mach-sa1100/simpad.c
+++ b/arch/arm/mach-sa1100/simpad.c
@@ -14,6 +14,7 @@
14#include <linux/mtd/partitions.h> 14#include <linux/mtd/partitions.h>
15#include <linux/io.h> 15#include <linux/io.h>
16#include <linux/gpio.h> 16#include <linux/gpio.h>
17#include <linux/mfd/ucb1x00.h>
17 18
18#include <asm/irq.h> 19#include <asm/irq.h>
19#include <mach/hardware.h> 20#include <mach/hardware.h>
@@ -187,10 +188,15 @@ static struct resource simpad_flash_resources [] = {
187 } 188 }
188}; 189};
189 190
191static struct ucb1x00_plat_data simpad_ucb1x00_data = {
192 .gpio_base = SIMPAD_UCB1X00_GPIO_BASE,
193};
194
190static struct mcp_plat_data simpad_mcp_data = { 195static struct mcp_plat_data simpad_mcp_data = {
191 .mccr0 = MCCR0_ADM, 196 .mccr0 = MCCR0_ADM,
192 .sclk_rate = 11981000, 197 .sclk_rate = 11981000,
193 .gpio_base = SIMPAD_UCB1X00_GPIO_BASE, 198 .codec = "ucb1300",
199 .codec_pdata = &simpad_ucb1x00_data,
194}; 200};
195 201
196 202
diff --git a/drivers/mfd/mcp-core.c b/drivers/mfd/mcp-core.c
index 84815f9ef636..63be60bc3455 100644
--- a/drivers/mfd/mcp-core.c
+++ b/drivers/mfd/mcp-core.c
@@ -26,9 +26,35 @@
26#define to_mcp(d) container_of(d, struct mcp, attached_device) 26#define to_mcp(d) container_of(d, struct mcp, attached_device)
27#define to_mcp_driver(d) container_of(d, struct mcp_driver, drv) 27#define to_mcp_driver(d) container_of(d, struct mcp_driver, drv)
28 28
29static const struct mcp_device_id *mcp_match_id(const struct mcp_device_id *id,
30 const char *codec)
31{
32 while (id->name[0]) {
33 if (strcmp(codec, id->name) == 0)
34 return id;
35 id++;
36 }
37 return NULL;
38}
39
40const struct mcp_device_id *mcp_get_device_id(const struct mcp *mcp)
41{
42 const struct mcp_driver *driver =
43 to_mcp_driver(mcp->attached_device.driver);
44
45 return mcp_match_id(driver->id_table, mcp->codec);
46}
47EXPORT_SYMBOL(mcp_get_device_id);
48
29static int mcp_bus_match(struct device *dev, struct device_driver *drv) 49static int mcp_bus_match(struct device *dev, struct device_driver *drv)
30{ 50{
31 return 1; 51 const struct mcp *mcp = to_mcp(dev);
52 const struct mcp_driver *driver = to_mcp_driver(drv);
53
54 if (driver->id_table)
55 return !!mcp_match_id(driver->id_table, mcp->codec);
56
57 return 0;
32} 58}
33 59
34static int mcp_bus_probe(struct device *dev) 60static int mcp_bus_probe(struct device *dev)
@@ -74,9 +100,18 @@ static int mcp_bus_resume(struct device *dev)
74 return ret; 100 return ret;
75} 101}
76 102
103static int mcp_bus_uevent(struct device *dev, struct kobj_uevent_env *env)
104{
105 struct mcp *mcp = to_mcp(dev);
106
107 add_uevent_var(env, "MODALIAS=%s%s", MCP_MODULE_PREFIX, mcp->codec);
108 return 0;
109}
110
77static struct bus_type mcp_bus_type = { 111static struct bus_type mcp_bus_type = {
78 .name = "mcp", 112 .name = "mcp",
79 .match = mcp_bus_match, 113 .match = mcp_bus_match,
114 .uevent = mcp_bus_uevent,
80 .probe = mcp_bus_probe, 115 .probe = mcp_bus_probe,
81 .remove = mcp_bus_remove, 116 .remove = mcp_bus_remove,
82 .suspend = mcp_bus_suspend, 117 .suspend = mcp_bus_suspend,
@@ -212,9 +247,14 @@ struct mcp *mcp_host_alloc(struct device *parent, size_t size)
212} 247}
213EXPORT_SYMBOL(mcp_host_alloc); 248EXPORT_SYMBOL(mcp_host_alloc);
214 249
215int mcp_host_register(struct mcp *mcp) 250int mcp_host_register(struct mcp *mcp, void *pdata)
216{ 251{
252 if (!mcp->codec)
253 return -EINVAL;
254
255 mcp->attached_device.platform_data = pdata;
217 dev_set_name(&mcp->attached_device, "mcp0"); 256 dev_set_name(&mcp->attached_device, "mcp0");
257 request_module("%s%s", MCP_MODULE_PREFIX, mcp->codec);
218 return device_register(&mcp->attached_device); 258 return device_register(&mcp->attached_device);
219} 259}
220EXPORT_SYMBOL(mcp_host_register); 260EXPORT_SYMBOL(mcp_host_register);
diff --git a/drivers/mfd/mcp-sa11x0.c b/drivers/mfd/mcp-sa11x0.c
index 02c53a0766c4..da4e077a1bee 100644
--- a/drivers/mfd/mcp-sa11x0.c
+++ b/drivers/mfd/mcp-sa11x0.c
@@ -146,6 +146,9 @@ static int mcp_sa11x0_probe(struct platform_device *pdev)
146 if (!data) 146 if (!data)
147 return -ENODEV; 147 return -ENODEV;
148 148
149 if (!data->codec)
150 return -ENODEV;
151
149 if (!request_mem_region(0x80060000, 0x60, "sa11x0-mcp")) 152 if (!request_mem_region(0x80060000, 0x60, "sa11x0-mcp"))
150 return -EBUSY; 153 return -EBUSY;
151 154
@@ -162,7 +165,7 @@ static int mcp_sa11x0_probe(struct platform_device *pdev)
162 mcp->dma_audio_wr = DMA_Ser4MCP0Wr; 165 mcp->dma_audio_wr = DMA_Ser4MCP0Wr;
163 mcp->dma_telco_rd = DMA_Ser4MCP1Rd; 166 mcp->dma_telco_rd = DMA_Ser4MCP1Rd;
164 mcp->dma_telco_wr = DMA_Ser4MCP1Wr; 167 mcp->dma_telco_wr = DMA_Ser4MCP1Wr;
165 mcp->gpio_base = data->gpio_base; 168 mcp->codec = data->codec;
166 169
167 platform_set_drvdata(pdev, mcp); 170 platform_set_drvdata(pdev, mcp);
168 171
@@ -195,7 +198,7 @@ static int mcp_sa11x0_probe(struct platform_device *pdev)
195 mcp->rw_timeout = (64 * 3 * 1000000 + mcp->sclk_rate - 1) / 198 mcp->rw_timeout = (64 * 3 * 1000000 + mcp->sclk_rate - 1) /
196 mcp->sclk_rate; 199 mcp->sclk_rate;
197 200
198 ret = mcp_host_register(mcp); 201 ret = mcp_host_register(mcp, data->codec_pdata);
199 if (ret == 0) 202 if (ret == 0)
200 goto out; 203 goto out;
201 204
diff --git a/drivers/mfd/ucb1x00-core.c b/drivers/mfd/ucb1x00-core.c
index b281217334eb..91c4f25e0e55 100644
--- a/drivers/mfd/ucb1x00-core.c
+++ b/drivers/mfd/ucb1x00-core.c
@@ -36,6 +36,15 @@ static DEFINE_MUTEX(ucb1x00_mutex);
36static LIST_HEAD(ucb1x00_drivers); 36static LIST_HEAD(ucb1x00_drivers);
37static LIST_HEAD(ucb1x00_devices); 37static LIST_HEAD(ucb1x00_devices);
38 38
39static struct mcp_device_id ucb1x00_id[] = {
40 { "ucb1x00", 0 }, /* auto-detection */
41 { "ucb1200", UCB_ID_1200 },
42 { "ucb1300", UCB_ID_1300 },
43 { "tc35143", UCB_ID_TC35143 },
44 { }
45};
46MODULE_DEVICE_TABLE(mcp, ucb1x00_id);
47
39/** 48/**
40 * ucb1x00_io_set_dir - set IO direction 49 * ucb1x00_io_set_dir - set IO direction
41 * @ucb: UCB1x00 structure describing chip 50 * @ucb: UCB1x00 structure describing chip
@@ -527,17 +536,33 @@ static struct class ucb1x00_class = {
527 536
528static int ucb1x00_probe(struct mcp *mcp) 537static int ucb1x00_probe(struct mcp *mcp)
529{ 538{
539 const struct mcp_device_id *mid;
530 struct ucb1x00 *ucb; 540 struct ucb1x00 *ucb;
531 struct ucb1x00_driver *drv; 541 struct ucb1x00_driver *drv;
542 struct ucb1x00_plat_data *pdata;
532 unsigned int id; 543 unsigned int id;
533 int ret = -ENODEV; 544 int ret = -ENODEV;
534 int temp; 545 int temp;
535 546
536 mcp_enable(mcp); 547 mcp_enable(mcp);
537 id = mcp_reg_read(mcp, UCB_ID); 548 id = mcp_reg_read(mcp, UCB_ID);
549 mid = mcp_get_device_id(mcp);
538 550
539 if (id != UCB_ID_1200 && id != UCB_ID_1300 && id != UCB_ID_TC35143) { 551 if (mid && mid->driver_data) {
540 printk(KERN_WARNING "UCB1x00 ID not found: %04x\n", id); 552 if (id != mid->driver_data) {
553 printk(KERN_WARNING "%s wrong ID %04x found: %04x\n",
554 mid->name, (unsigned int) mid->driver_data, id);
555 goto err_disable;
556 }
557 } else {
558 mid = &ucb1x00_id[1];
559 while (mid->driver_data) {
560 if (id == mid->driver_data)
561 break;
562 mid++;
563 }
564 printk(KERN_WARNING "%s ID not found: %04x\n",
565 ucb1x00_id[0].name, id);
541 goto err_disable; 566 goto err_disable;
542 } 567 }
543 568
@@ -546,28 +571,28 @@ static int ucb1x00_probe(struct mcp *mcp)
546 if (!ucb) 571 if (!ucb)
547 goto err_disable; 572 goto err_disable;
548 573
549 574 pdata = mcp->attached_device.platform_data;
550 ucb->dev.class = &ucb1x00_class; 575 ucb->dev.class = &ucb1x00_class;
551 ucb->dev.parent = &mcp->attached_device; 576 ucb->dev.parent = &mcp->attached_device;
552 dev_set_name(&ucb->dev, "ucb1x00"); 577 dev_set_name(&ucb->dev, mid->name);
553 578
554 spin_lock_init(&ucb->lock); 579 spin_lock_init(&ucb->lock);
555 spin_lock_init(&ucb->io_lock); 580 spin_lock_init(&ucb->io_lock);
556 sema_init(&ucb->adc_sem, 1); 581 sema_init(&ucb->adc_sem, 1);
557 582
558 ucb->id = id; 583 ucb->id = mid;
559 ucb->mcp = mcp; 584 ucb->mcp = mcp;
560 ucb->irq = ucb1x00_detect_irq(ucb); 585 ucb->irq = ucb1x00_detect_irq(ucb);
561 if (ucb->irq == NO_IRQ) { 586 if (ucb->irq == NO_IRQ) {
562 printk(KERN_ERR "UCB1x00: IRQ probe failed\n"); 587 printk(KERN_ERR "%s: IRQ probe failed\n", mid->name);
563 ret = -ENODEV; 588 ret = -ENODEV;
564 goto err_free; 589 goto err_free;
565 } 590 }
566 591
567 ucb->gpio.base = -1; 592 ucb->gpio.base = -1;
568 if (mcp->gpio_base != 0) { 593 if (pdata && (pdata->gpio_base >= 0)) {
569 ucb->gpio.label = dev_name(&ucb->dev); 594 ucb->gpio.label = dev_name(&ucb->dev);
570 ucb->gpio.base = mcp->gpio_base; 595 ucb->gpio.base = pdata->gpio_base;
571 ucb->gpio.ngpio = 10; 596 ucb->gpio.ngpio = 10;
572 ucb->gpio.set = ucb1x00_gpio_set; 597 ucb->gpio.set = ucb1x00_gpio_set;
573 ucb->gpio.get = ucb1x00_gpio_get; 598 ucb->gpio.get = ucb1x00_gpio_get;
@@ -580,10 +605,10 @@ static int ucb1x00_probe(struct mcp *mcp)
580 dev_info(&ucb->dev, "gpio_base not set so no gpiolib support"); 605 dev_info(&ucb->dev, "gpio_base not set so no gpiolib support");
581 606
582 ret = request_irq(ucb->irq, ucb1x00_irq, IRQF_TRIGGER_RISING, 607 ret = request_irq(ucb->irq, ucb1x00_irq, IRQF_TRIGGER_RISING,
583 "UCB1x00", ucb); 608 mid->name, ucb);
584 if (ret) { 609 if (ret) {
585 printk(KERN_ERR "ucb1x00: unable to grab irq%d: %d\n", 610 printk(KERN_ERR "%s: unable to grab irq%d: %d\n",
586 ucb->irq, ret); 611 mid->name, ucb->irq, ret);
587 goto err_gpio; 612 goto err_gpio;
588 } 613 }
589 614
@@ -705,6 +730,7 @@ static struct mcp_driver ucb1x00_driver = {
705 .remove = ucb1x00_remove, 730 .remove = ucb1x00_remove,
706 .suspend = ucb1x00_suspend, 731 .suspend = ucb1x00_suspend,
707 .resume = ucb1x00_resume, 732 .resume = ucb1x00_resume,
733 .id_table = ucb1x00_id,
708}; 734};
709 735
710static int __init ucb1x00_init(void) 736static int __init ucb1x00_init(void)
diff --git a/drivers/mfd/ucb1x00-ts.c b/drivers/mfd/ucb1x00-ts.c
index 38ffbd50a0d2..40ec3c118868 100644
--- a/drivers/mfd/ucb1x00-ts.c
+++ b/drivers/mfd/ucb1x00-ts.c
@@ -382,7 +382,7 @@ static int ucb1x00_ts_add(struct ucb1x00_dev *dev)
382 ts->adcsync = adcsync ? UCB_SYNC : UCB_NOSYNC; 382 ts->adcsync = adcsync ? UCB_SYNC : UCB_NOSYNC;
383 383
384 idev->name = "Touchscreen panel"; 384 idev->name = "Touchscreen panel";
385 idev->id.product = ts->ucb->id; 385 idev->id.product = ts->ucb->id->driver_data;
386 idev->open = ucb1x00_ts_open; 386 idev->open = ucb1x00_ts_open;
387 idev->close = ucb1x00_ts_close; 387 idev->close = ucb1x00_ts_close;
388 388
diff --git a/include/linux/mfd/mcp.h b/include/linux/mfd/mcp.h
index ee496708e38b..1515e64e3663 100644
--- a/include/linux/mfd/mcp.h
+++ b/include/linux/mfd/mcp.h
@@ -10,6 +10,7 @@
10#ifndef MCP_H 10#ifndef MCP_H
11#define MCP_H 11#define MCP_H
12 12
13#include <linux/mod_devicetable.h>
13#include <mach/dma.h> 14#include <mach/dma.h>
14 15
15struct mcp_ops; 16struct mcp_ops;
@@ -26,7 +27,7 @@ struct mcp {
26 dma_device_t dma_telco_rd; 27 dma_device_t dma_telco_rd;
27 dma_device_t dma_telco_wr; 28 dma_device_t dma_telco_wr;
28 struct device attached_device; 29 struct device attached_device;
29 int gpio_base; 30 const char *codec;
30}; 31};
31 32
32struct mcp_ops { 33struct mcp_ops {
@@ -44,10 +45,11 @@ void mcp_reg_write(struct mcp *, unsigned int, unsigned int);
44unsigned int mcp_reg_read(struct mcp *, unsigned int); 45unsigned int mcp_reg_read(struct mcp *, unsigned int);
45void mcp_enable(struct mcp *); 46void mcp_enable(struct mcp *);
46void mcp_disable(struct mcp *); 47void mcp_disable(struct mcp *);
48const struct mcp_device_id *mcp_get_device_id(const struct mcp *mcp);
47#define mcp_get_sclk_rate(mcp) ((mcp)->sclk_rate) 49#define mcp_get_sclk_rate(mcp) ((mcp)->sclk_rate)
48 50
49struct mcp *mcp_host_alloc(struct device *, size_t); 51struct mcp *mcp_host_alloc(struct device *, size_t);
50int mcp_host_register(struct mcp *); 52int mcp_host_register(struct mcp *, void *);
51void mcp_host_unregister(struct mcp *); 53void mcp_host_unregister(struct mcp *);
52 54
53struct mcp_driver { 55struct mcp_driver {
@@ -56,6 +58,7 @@ struct mcp_driver {
56 void (*remove)(struct mcp *); 58 void (*remove)(struct mcp *);
57 int (*suspend)(struct mcp *, pm_message_t); 59 int (*suspend)(struct mcp *, pm_message_t);
58 int (*resume)(struct mcp *); 60 int (*resume)(struct mcp *);
61 const struct mcp_device_id *id_table;
59}; 62};
60 63
61int mcp_driver_register(struct mcp_driver *); 64int mcp_driver_register(struct mcp_driver *);
diff --git a/include/linux/mfd/ucb1x00.h b/include/linux/mfd/ucb1x00.h
index 4321f044d1e4..bc19e5fb7ea8 100644
--- a/include/linux/mfd/ucb1x00.h
+++ b/include/linux/mfd/ucb1x00.h
@@ -104,6 +104,9 @@
104#define UCB_MODE_DYN_VFLAG_ENA (1 << 12) 104#define UCB_MODE_DYN_VFLAG_ENA (1 << 12)
105#define UCB_MODE_AUD_OFF_CAN (1 << 13) 105#define UCB_MODE_AUD_OFF_CAN (1 << 13)
106 106
107struct ucb1x00_plat_data {
108 int gpio_base;
109};
107 110
108struct ucb1x00_irq { 111struct ucb1x00_irq {
109 void *devid; 112 void *devid;
@@ -116,7 +119,7 @@ struct ucb1x00 {
116 unsigned int irq; 119 unsigned int irq;
117 struct semaphore adc_sem; 120 struct semaphore adc_sem;
118 spinlock_t io_lock; 121 spinlock_t io_lock;
119 u16 id; 122 const struct mcp_device_id *id;
120 u16 io_dir; 123 u16 io_dir;
121 u16 io_out; 124 u16 io_out;
122 u16 adc_cr; 125 u16 adc_cr;
diff --git a/include/linux/mod_devicetable.h b/include/linux/mod_devicetable.h
index 468819cdde87..bc50d9a80d89 100644
--- a/include/linux/mod_devicetable.h
+++ b/include/linux/mod_devicetable.h
@@ -436,6 +436,17 @@ struct spi_device_id {
436 __attribute__((aligned(sizeof(kernel_ulong_t)))); 436 __attribute__((aligned(sizeof(kernel_ulong_t))));
437}; 437};
438 438
439/* mcp */
440
441#define MCP_NAME_SIZE 20
442#define MCP_MODULE_PREFIX "mcp:"
443
444struct mcp_device_id {
445 char name[MCP_NAME_SIZE];
446 kernel_ulong_t driver_data /* Data private to the driver */
447 __attribute__((aligned(sizeof(kernel_ulong_t))));
448};
449
439/* dmi */ 450/* dmi */
440enum dmi_field { 451enum dmi_field {
441 DMI_NONE, 452 DMI_NONE,
diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c
index f936d1fa969d..e8c7eb16c0ea 100644
--- a/scripts/mod/file2alias.c
+++ b/scripts/mod/file2alias.c
@@ -774,6 +774,15 @@ static int do_spi_entry(const char *filename, struct spi_device_id *id,
774 return 1; 774 return 1;
775} 775}
776 776
777/* Looks like: mcp:S */
778static int do_mcp_entry(const char *filename, struct mcp_device_id *id,
779 char *alias)
780{
781 sprintf(alias, MCP_MODULE_PREFIX "%s", id->name);
782
783 return 1;
784}
785
777static const struct dmifield { 786static const struct dmifield {
778 const char *prefix; 787 const char *prefix;
779 int field; 788 int field;
@@ -1027,6 +1036,10 @@ void handle_moddevtable(struct module *mod, struct elf_info *info,
1027 do_table(symval, sym->st_size, 1036 do_table(symval, sym->st_size,
1028 sizeof(struct spi_device_id), "spi", 1037 sizeof(struct spi_device_id), "spi",
1029 do_spi_entry, mod); 1038 do_spi_entry, mod);
1039 else if (sym_is(symname, "__mod_mcp_device_table"))
1040 do_table(symval, sym->st_size,
1041 sizeof(struct mcp_device_id), "mcp",
1042 do_mcp_entry, mod);
1030 else if (sym_is(symname, "__mod_dmi_device_table")) 1043 else if (sym_is(symname, "__mod_dmi_device_table"))
1031 do_table(symval, sym->st_size, 1044 do_table(symval, sym->st_size,
1032 sizeof(struct dmi_system_id), "dmi", 1045 sizeof(struct dmi_system_id), "dmi",