1 /* chmc.c: Driver for UltraSPARC-III memory controller.
3 * Copyright (C) 2001, 2007, 2008 David S. Miller (davem@davemloft.net)
6 #include <linux/module.h>
7 #include <linux/kernel.h>
8 #include <linux/types.h>
9 #include <linux/slab.h>
10 #include <linux/list.h>
11 #include <linux/string.h>
12 #include <linux/sched.h>
13 #include <linux/smp.h>
14 #include <linux/errno.h>
15 #include <linux/init.h>
17 #include <linux/of_device.h>
18 #include <asm/spitfire.h>
19 #include <asm/chmctrl.h>
20 #include <asm/cpudata.h>
21 #include <asm/oplib.h>
25 #include <asm/memctrl.h>
27 #define DRV_MODULE_NAME "chmc"
28 #define PFX DRV_MODULE_NAME ": "
29 #define DRV_MODULE_VERSION "0.2"
31 MODULE_AUTHOR("David S. Miller (davem@davemloft.net)");
32 MODULE_DESCRIPTION("UltraSPARC-III memory controller driver");
33 MODULE_LICENSE("GPL");
34 MODULE_VERSION(DRV_MODULE_VERSION
);
37 #define MC_TYPE_SAFARI 1
38 #define MC_TYPE_JBUS 2
40 static dimm_printer_t us3mc_dimm_printer
;
42 #define CHMCTRL_NDGRPS 2
43 #define CHMCTRL_NDIMMS 4
45 #define CHMC_DIMMS_PER_MC (CHMCTRL_NDGRPS * CHMCTRL_NDIMMS)
47 /* OBP memory-layout property format. */
49 unsigned char dimm_map
[144];
50 unsigned char pin_map
[576];
53 #define DIMM_LABEL_SZ 8
55 struct chmc_obp_mem_layout
{
56 /* One max 8-byte string label per DIMM. Usually
57 * this matches the label on the motherboard where
60 char dimm_labels
[CHMC_DIMMS_PER_MC
][DIMM_LABEL_SZ
];
62 /* If symmetric use map[0], else it is
63 * asymmetric and map[1] should be used.
67 struct chmc_obp_map map
[2];
70 #define CHMCTRL_NBANKS 4
72 struct chmc_bank_info
{
88 struct list_head list
;
91 struct chmc_obp_mem_layout layout_prop
;
102 struct chmc_bank_info logical_banks
[CHMCTRL_NBANKS
];
105 #define JBUSMC_REGS_SIZE 8
107 #define JB_MC_REG1_DIMM2_BANK3 0x8000000000000000UL
108 #define JB_MC_REG1_DIMM1_BANK1 0x4000000000000000UL
109 #define JB_MC_REG1_DIMM2_BANK2 0x2000000000000000UL
110 #define JB_MC_REG1_DIMM1_BANK0 0x1000000000000000UL
111 #define JB_MC_REG1_XOR 0x0000010000000000UL
112 #define JB_MC_REG1_ADDR_GEN_2 0x000000e000000000UL
113 #define JB_MC_REG1_ADDR_GEN_2_SHIFT 37
114 #define JB_MC_REG1_ADDR_GEN_1 0x0000001c00000000UL
115 #define JB_MC_REG1_ADDR_GEN_1_SHIFT 34
116 #define JB_MC_REG1_INTERLEAVE 0x0000000001800000UL
117 #define JB_MC_REG1_INTERLEAVE_SHIFT 23
118 #define JB_MC_REG1_DIMM2_PTYPE 0x0000000000200000UL
119 #define JB_MC_REG1_DIMM2_PTYPE_SHIFT 21
120 #define JB_MC_REG1_DIMM1_PTYPE 0x0000000000100000UL
121 #define JB_MC_REG1_DIMM1_PTYPE_SHIFT 20
123 #define PART_TYPE_X8 0
124 #define PART_TYPE_X4 1
126 #define INTERLEAVE_NONE 0
127 #define INTERLEAVE_SAME 1
128 #define INTERLEAVE_INTERNAL 2
129 #define INTERLEAVE_BOTH 3
131 #define ADDR_GEN_128MB 0
132 #define ADDR_GEN_256MB 1
133 #define ADDR_GEN_512MB 2
134 #define ADDR_GEN_1GB 3
136 #define JB_NUM_DIMM_GROUPS 2
137 #define JB_NUM_DIMMS_PER_GROUP 2
138 #define JB_NUM_DIMMS (JB_NUM_DIMM_GROUPS * JB_NUM_DIMMS_PER_GROUP)
140 struct jbusmc_obp_map
{
141 unsigned char dimm_map
[18];
142 unsigned char pin_map
[144];
145 struct jbusmc_obp_mem_layout
{
146 /* One max 8-byte string label per DIMM. Usually
147 * this matches the label on the motherboard where
150 char dimm_labels
[JB_NUM_DIMMS
][DIMM_LABEL_SZ
];
152 /* If symmetric use map[0], else it is
153 * asymmetric and map[1] should be used.
157 struct jbusmc_obp_map map
;
162 struct jbusmc_dimm_group
{
163 struct jbusmc
*controller
;
173 struct jbusmc_obp_mem_layout layout
;
176 struct jbusmc_dimm_group dimm_groups
[JB_NUM_DIMM_GROUPS
];
177 struct list_head list
;
180 static DEFINE_SPINLOCK(mctrl_list_lock
);
181 static LIST_HEAD(mctrl_list
);
183 static void mc_list_add(struct list_head
*list
)
185 spin_lock(&mctrl_list_lock
);
186 list_add(list
, &mctrl_list
);
187 spin_unlock(&mctrl_list_lock
);
190 static void mc_list_del(struct list_head
*list
)
192 spin_lock(&mctrl_list_lock
);
194 spin_unlock(&mctrl_list_lock
);
197 #define SYNDROME_MIN -1
198 #define SYNDROME_MAX 144
200 /* Covert syndrome code into the way the bits are positioned
203 static int syndrome_to_qword_code(int syndrome_code
)
205 if (syndrome_code
< 128)
207 else if (syndrome_code
< 128 + 9)
208 syndrome_code
-= (128 - 7);
209 else if (syndrome_code
< (128 + 9 + 3))
210 syndrome_code
-= (128 + 9 - 4);
212 syndrome_code
-= (128 + 9 + 3);
213 return syndrome_code
;
216 /* All this magic has to do with how a cache line comes over the wire
217 * on Safari and JBUS. A 64-bit line comes over in 1 or more quadword
218 * cycles, each of which transmit ECC/MTAG info as well as the actual
221 #define L2_LINE_SIZE 64
222 #define L2_LINE_ADDR_MSK (L2_LINE_SIZE - 1)
223 #define QW_PER_LINE 4
224 #define QW_BYTES (L2_LINE_SIZE / QW_PER_LINE)
226 #define SAFARI_LAST_BIT (576 - 1)
227 #define JBUS_LAST_BIT (144 - 1)
229 static void get_pin_and_dimm_str(int syndrome_code
, unsigned long paddr
,
230 int *pin_p
, char **dimm_str_p
, void *_prop
,
231 int base_dimm_offset
)
233 int qword_code
= syndrome_to_qword_code(syndrome_code
);
234 int cache_line_offset
;
239 if (mc_type
== MC_TYPE_JBUS
) {
240 struct jbusmc_obp_mem_layout
*p
= _prop
;
243 cache_line_offset
= qword_code
;
244 offset_inverse
= (JBUS_LAST_BIT
- cache_line_offset
);
245 dimm_map_index
= offset_inverse
/ 8;
246 map_val
= p
->map
.dimm_map
[dimm_map_index
];
247 map_val
= ((map_val
>> ((7 - (offset_inverse
& 7)))) & 1);
248 *dimm_str_p
= p
->dimm_labels
[base_dimm_offset
+ map_val
];
249 *pin_p
= p
->map
.pin_map
[cache_line_offset
];
251 struct chmc_obp_mem_layout
*p
= _prop
;
252 struct chmc_obp_map
*mp
;
261 qword
= (paddr
& L2_LINE_ADDR_MSK
) / QW_BYTES
;
262 cache_line_offset
= ((3 - qword
) * QW_BITS
) + qword_code
;
263 offset_inverse
= (SAFARI_LAST_BIT
- cache_line_offset
);
264 dimm_map_index
= offset_inverse
>> 2;
265 map_val
= mp
->dimm_map
[dimm_map_index
];
266 map_val
= ((map_val
>> ((3 - (offset_inverse
& 3)) << 1)) & 0x3);
267 *dimm_str_p
= p
->dimm_labels
[base_dimm_offset
+ map_val
];
268 *pin_p
= mp
->pin_map
[cache_line_offset
];
272 static struct jbusmc_dimm_group
*jbusmc_find_dimm_group(unsigned long phys_addr
)
276 list_for_each_entry(p
, &mctrl_list
, list
) {
279 for (i
= 0; i
< p
->num_dimm_groups
; i
++) {
280 struct jbusmc_dimm_group
*dp
= &p
->dimm_groups
[i
];
282 if (phys_addr
< dp
->base_addr
||
283 (dp
->base_addr
+ dp
->size
) <= phys_addr
)
292 static int jbusmc_print_dimm(int syndrome_code
,
293 unsigned long phys_addr
,
294 char *buf
, int buflen
)
296 struct jbusmc_obp_mem_layout
*prop
;
297 struct jbusmc_dimm_group
*dp
;
301 dp
= jbusmc_find_dimm_group(phys_addr
);
303 syndrome_code
< SYNDROME_MIN
||
304 syndrome_code
> SYNDROME_MAX
) {
314 first_dimm
= dp
->index
* JB_NUM_DIMMS_PER_GROUP
;
316 if (syndrome_code
!= SYNDROME_MIN
) {
320 get_pin_and_dimm_str(syndrome_code
, phys_addr
, &pin
,
321 &dimm_str
, prop
, first_dimm
);
322 sprintf(buf
, "%s, pin %3d", dimm_str
, pin
);
326 /* Multi-bit error, we just dump out all the
327 * dimm labels associated with this dimm group.
329 for (dimm
= 0; dimm
< JB_NUM_DIMMS_PER_GROUP
; dimm
++) {
331 prop
->dimm_labels
[first_dimm
+ dimm
]);
339 static u64 __devinit
jbusmc_dimm_group_size(u64 base
,
340 const struct linux_prom64_registers
*mem_regs
,
343 u64 max
= base
+ (8UL * 1024 * 1024 * 1024);
347 for (i
= 0; i
< num_mem_regs
; i
++) {
348 const struct linux_prom64_registers
*ent
;
353 this_base
= ent
->phys_addr
;
354 this_end
= this_base
+ ent
->reg_size
;
355 if (base
< this_base
|| base
>= this_end
)
359 if (this_end
> max_seen
)
363 return max_seen
- base
;
366 static void __devinit
jbusmc_construct_one_dimm_group(struct jbusmc
*p
,
368 const struct linux_prom64_registers
*mem_regs
,
371 struct jbusmc_dimm_group
*dp
= &p
->dimm_groups
[index
];
376 dp
->base_addr
= (p
->portid
* (64UL * 1024 * 1024 * 1024));
377 dp
->base_addr
+= (index
* (8UL * 1024 * 1024 * 1024));
378 dp
->size
= jbusmc_dimm_group_size(dp
->base_addr
, mem_regs
, num_mem_regs
);
381 static void __devinit
jbusmc_construct_dimm_groups(struct jbusmc
*p
,
382 const struct linux_prom64_registers
*mem_regs
,
385 if (p
->mc_reg_1
& JB_MC_REG1_DIMM1_BANK0
) {
386 jbusmc_construct_one_dimm_group(p
, 0, mem_regs
, num_mem_regs
);
387 p
->num_dimm_groups
++;
389 if (p
->mc_reg_1
& JB_MC_REG1_DIMM2_BANK2
) {
390 jbusmc_construct_one_dimm_group(p
, 1, mem_regs
, num_mem_regs
);
391 p
->num_dimm_groups
++;
395 static int __devinit
jbusmc_probe(struct of_device
*op
,
396 const struct of_device_id
*match
)
398 const struct linux_prom64_registers
*mem_regs
;
399 struct device_node
*mem_node
;
400 int err
, len
, num_mem_regs
;
406 mem_node
= of_find_node_by_path("/memory");
408 printk(KERN_ERR PFX
"Cannot find /memory node.\n");
411 mem_regs
= of_get_property(mem_node
, "reg", &len
);
413 printk(KERN_ERR PFX
"Cannot get reg property of /memory node.\n");
416 num_mem_regs
= len
/ sizeof(*mem_regs
);
419 p
= kzalloc(sizeof(*p
), GFP_KERNEL
);
421 printk(KERN_ERR PFX
"Cannot allocate struct jbusmc.\n");
425 INIT_LIST_HEAD(&p
->list
);
428 prop
= of_get_property(op
->node
, "portid", &len
);
429 if (!prop
|| len
!= 4) {
430 printk(KERN_ERR PFX
"Cannot find portid.\n");
436 prop
= of_get_property(op
->node
, "memory-control-register-1", &len
);
437 if (!prop
|| len
!= 8) {
438 printk(KERN_ERR PFX
"Cannot get memory control register 1.\n");
442 p
->mc_reg_1
= ((u64
)prop
[0] << 32) | (u64
) prop
[1];
445 p
->regs
= of_ioremap(&op
->resource
[0], 0, JBUSMC_REGS_SIZE
, "jbusmc");
447 printk(KERN_ERR PFX
"Cannot map jbusmc regs.\n");
452 ml
= of_get_property(op
->node
, "memory-layout", &p
->layout_len
);
454 printk(KERN_ERR PFX
"Cannot get memory layout property.\n");
457 if (p
->layout_len
> sizeof(p
->layout
)) {
458 printk(KERN_ERR PFX
"Unexpected memory-layout size %d\n",
462 memcpy(&p
->layout
, ml
, p
->layout_len
);
464 jbusmc_construct_dimm_groups(p
, mem_regs
, num_mem_regs
);
466 mc_list_add(&p
->list
);
468 printk(KERN_INFO PFX
"UltraSPARC-IIIi memory controller at %s\n",
469 op
->node
->full_name
);
471 dev_set_drvdata(&op
->dev
, p
);
479 of_iounmap(&op
->resource
[0], p
->regs
, JBUSMC_REGS_SIZE
);
486 /* Does BANK decode PHYS_ADDR? */
487 static int chmc_bank_match(struct chmc_bank_info
*bp
, unsigned long phys_addr
)
489 unsigned long upper_bits
= (phys_addr
& PA_UPPER_BITS
) >> PA_UPPER_BITS_SHIFT
;
490 unsigned long lower_bits
= (phys_addr
& PA_LOWER_BITS
) >> PA_LOWER_BITS_SHIFT
;
492 /* Bank must be enabled to match. */
496 /* Would BANK match upper bits? */
497 upper_bits
^= bp
->um
; /* What bits are different? */
498 upper_bits
= ~upper_bits
; /* Invert. */
499 upper_bits
|= bp
->uk
; /* What bits don't matter for matching? */
500 upper_bits
= ~upper_bits
; /* Invert. */
505 /* Would BANK match lower bits? */
506 lower_bits
^= bp
->lm
; /* What bits are different? */
507 lower_bits
= ~lower_bits
; /* Invert. */
508 lower_bits
|= bp
->lk
; /* What bits don't matter for matching? */
509 lower_bits
= ~lower_bits
; /* Invert. */
514 /* I always knew you'd be the one. */
518 /* Given PHYS_ADDR, search memory controller banks for a match. */
519 static struct chmc_bank_info
*chmc_find_bank(unsigned long phys_addr
)
523 list_for_each_entry(p
, &mctrl_list
, list
) {
526 for (bank_no
= 0; bank_no
< CHMCTRL_NBANKS
; bank_no
++) {
527 struct chmc_bank_info
*bp
;
529 bp
= &p
->logical_banks
[bank_no
];
530 if (chmc_bank_match(bp
, phys_addr
))
538 /* This is the main purpose of this driver. */
539 static int chmc_print_dimm(int syndrome_code
,
540 unsigned long phys_addr
,
541 char *buf
, int buflen
)
543 struct chmc_bank_info
*bp
;
544 struct chmc_obp_mem_layout
*prop
;
545 int bank_in_controller
, first_dimm
;
547 bp
= chmc_find_bank(phys_addr
);
549 syndrome_code
< SYNDROME_MIN
||
550 syndrome_code
> SYNDROME_MAX
) {
558 prop
= &bp
->p
->layout_prop
;
559 bank_in_controller
= bp
->bank_id
& (CHMCTRL_NBANKS
- 1);
560 first_dimm
= (bank_in_controller
& (CHMCTRL_NDGRPS
- 1));
561 first_dimm
*= CHMCTRL_NDIMMS
;
563 if (syndrome_code
!= SYNDROME_MIN
) {
567 get_pin_and_dimm_str(syndrome_code
, phys_addr
, &pin
,
568 &dimm_str
, prop
, first_dimm
);
569 sprintf(buf
, "%s, pin %3d", dimm_str
, pin
);
573 /* Multi-bit error, we just dump out all the
574 * dimm labels associated with this bank.
576 for (dimm
= 0; dimm
< CHMCTRL_NDIMMS
; dimm
++) {
578 prop
->dimm_labels
[first_dimm
+ dimm
]);
585 /* Accessing the registers is slightly complicated. If you want
586 * to get at the memory controller which is on the same processor
587 * the code is executing, you must use special ASI load/store else
588 * you go through the global mapping.
590 static u64
chmc_read_mcreg(struct chmc
*p
, unsigned long offset
)
592 unsigned long ret
, this_cpu
;
596 this_cpu
= real_hard_smp_processor_id();
598 if (p
->portid
== this_cpu
) {
599 __asm__
__volatile__("ldxa [%1] %2, %0"
601 : "r" (offset
), "i" (ASI_MCU_CTRL_REG
));
603 __asm__
__volatile__("ldxa [%1] %2, %0"
605 : "r" (p
->regs
+ offset
),
606 "i" (ASI_PHYS_BYPASS_EC_E
));
614 #if 0 /* currently unused */
615 static void chmc_write_mcreg(struct chmc
*p
, unsigned long offset
, u64 val
)
617 if (p
->portid
== smp_processor_id()) {
618 __asm__
__volatile__("stxa %0, [%1] %2"
620 "r" (offset
), "i" (ASI_MCU_CTRL_REG
));
622 __asm__
__volatile__("ldxa %0, [%1] %2"
624 "r" (p
->regs
+ offset
),
625 "i" (ASI_PHYS_BYPASS_EC_E
));
630 static void chmc_interpret_one_decode_reg(struct chmc
*p
, int which_bank
, u64 val
)
632 struct chmc_bank_info
*bp
= &p
->logical_banks
[which_bank
];
635 bp
->bank_id
= (CHMCTRL_NBANKS
* p
->portid
) + which_bank
;
637 bp
->valid
= (val
& MEM_DECODE_VALID
) >> MEM_DECODE_VALID_SHIFT
;
638 bp
->uk
= (val
& MEM_DECODE_UK
) >> MEM_DECODE_UK_SHIFT
;
639 bp
->um
= (val
& MEM_DECODE_UM
) >> MEM_DECODE_UM_SHIFT
;
640 bp
->lk
= (val
& MEM_DECODE_LK
) >> MEM_DECODE_LK_SHIFT
;
641 bp
->lm
= (val
& MEM_DECODE_LM
) >> MEM_DECODE_LM_SHIFT
;
644 bp
->base
&= ~(bp
->uk
);
645 bp
->base
<<= PA_UPPER_BITS_SHIFT
;
670 /* UK[10] is reserved, and UK[11] is not set for the SDRAM
671 * bank size definition.
673 bp
->size
= (((unsigned long)bp
->uk
&
674 ((1UL << 10UL) - 1UL)) + 1UL) << PA_UPPER_BITS_SHIFT
;
675 bp
->size
/= bp
->interleave
;
678 static void chmc_fetch_decode_regs(struct chmc
*p
)
680 if (p
->layout_size
== 0)
683 chmc_interpret_one_decode_reg(p
, 0,
684 chmc_read_mcreg(p
, CHMCTRL_DECODE1
));
685 chmc_interpret_one_decode_reg(p
, 1,
686 chmc_read_mcreg(p
, CHMCTRL_DECODE2
));
687 chmc_interpret_one_decode_reg(p
, 2,
688 chmc_read_mcreg(p
, CHMCTRL_DECODE3
));
689 chmc_interpret_one_decode_reg(p
, 3,
690 chmc_read_mcreg(p
, CHMCTRL_DECODE4
));
693 static int __devinit
chmc_probe(struct of_device
*op
,
694 const struct of_device_id
*match
)
696 struct device_node
*dp
= op
->node
;
704 __asm__ ("rdpr %%ver, %0" : "=r" (ver
));
705 if ((ver
>> 32UL) == __JALAPENO_ID
||
706 (ver
>> 32UL) == __SERRANO_ID
)
709 portid
= of_getintprop_default(dp
, "portid", -1);
713 pval
= of_get_property(dp
, "memory-layout", &len
);
714 if (pval
&& len
> sizeof(p
->layout_prop
)) {
715 printk(KERN_ERR PFX
"Unexpected memory-layout property "
721 p
= kzalloc(sizeof(*p
), GFP_KERNEL
);
723 printk(KERN_ERR PFX
"Could not allocate struct chmc.\n");
728 p
->layout_size
= len
;
732 memcpy(&p
->layout_prop
, pval
, len
);
734 p
->regs
= of_ioremap(&op
->resource
[0], 0, 0x48, "chmc");
736 printk(KERN_ERR PFX
"Could not map registers.\n");
740 if (p
->layout_size
!= 0UL) {
741 p
->timing_control1
= chmc_read_mcreg(p
, CHMCTRL_TCTRL1
);
742 p
->timing_control2
= chmc_read_mcreg(p
, CHMCTRL_TCTRL2
);
743 p
->timing_control3
= chmc_read_mcreg(p
, CHMCTRL_TCTRL3
);
744 p
->timing_control4
= chmc_read_mcreg(p
, CHMCTRL_TCTRL4
);
745 p
->memaddr_control
= chmc_read_mcreg(p
, CHMCTRL_MACTRL
);
748 chmc_fetch_decode_regs(p
);
750 mc_list_add(&p
->list
);
752 printk(KERN_INFO PFX
"UltraSPARC-III memory controller at %s [%s]\n",
754 (p
->layout_size
? "ACTIVE" : "INACTIVE"));
756 dev_set_drvdata(&op
->dev
, p
);
768 static int __devinit
us3mc_probe(struct of_device
*op
,
769 const struct of_device_id
*match
)
771 if (mc_type
== MC_TYPE_SAFARI
)
772 return chmc_probe(op
, match
);
773 else if (mc_type
== MC_TYPE_JBUS
)
774 return jbusmc_probe(op
, match
);
778 static void __devexit
chmc_destroy(struct of_device
*op
, struct chmc
*p
)
781 of_iounmap(&op
->resource
[0], p
->regs
, 0x48);
785 static void __devexit
jbusmc_destroy(struct of_device
*op
, struct jbusmc
*p
)
787 mc_list_del(&p
->list
);
788 of_iounmap(&op
->resource
[0], p
->regs
, JBUSMC_REGS_SIZE
);
792 static int __devexit
us3mc_remove(struct of_device
*op
)
794 void *p
= dev_get_drvdata(&op
->dev
);
797 if (mc_type
== MC_TYPE_SAFARI
)
799 else if (mc_type
== MC_TYPE_JBUS
)
800 jbusmc_destroy(op
, p
);
805 static const struct of_device_id us3mc_match
[] = {
807 .name
= "memory-controller",
811 MODULE_DEVICE_TABLE(of
, us3mc_match
);
813 static struct of_platform_driver us3mc_driver
= {
815 .match_table
= us3mc_match
,
816 .probe
= us3mc_probe
,
817 .remove
= __devexit_p(us3mc_remove
),
820 static inline bool us3mc_platform(void)
822 if (tlb_type
== cheetah
|| tlb_type
== cheetah_plus
)
827 static int __init
us3mc_init(void)
832 if (!us3mc_platform())
835 __asm__
__volatile__("rdpr %%ver, %0" : "=r" (ver
));
836 if ((ver
>> 32UL) == __JALAPENO_ID
||
837 (ver
>> 32UL) == __SERRANO_ID
) {
838 mc_type
= MC_TYPE_JBUS
;
839 us3mc_dimm_printer
= jbusmc_print_dimm
;
841 mc_type
= MC_TYPE_SAFARI
;
842 us3mc_dimm_printer
= chmc_print_dimm
;
845 ret
= register_dimm_printer(us3mc_dimm_printer
);
848 ret
= of_register_driver(&us3mc_driver
, &of_bus_type
);
850 unregister_dimm_printer(us3mc_dimm_printer
);
855 static void __exit
us3mc_cleanup(void)
857 if (us3mc_platform()) {
858 unregister_dimm_printer(us3mc_dimm_printer
);
859 of_unregister_driver(&us3mc_driver
);
863 module_init(us3mc_init
);
864 module_exit(us3mc_cleanup
);