pcmcia.c (e5451c8f8330e03ad3cfa16048b4daf961af434f) pcmcia.c (b8b6069cf2087545fe53ec920e8353133e9a70bf)
1/*
2 * Sonics Silicon Backplane
3 * PCMCIA-Hostbus related functions
4 *
5 * Copyright 2006 Johannes Berg <johannes@sipsolutions.net>
6 * Copyright 2007-2008 Michael Buesch <m@bues.ch>
7 *
8 * Licensed under the GNU/GPL. See COPYING for details.
9 */
10
1/*
2 * Sonics Silicon Backplane
3 * PCMCIA-Hostbus related functions
4 *
5 * Copyright 2006 Johannes Berg <johannes@sipsolutions.net>
6 * Copyright 2007-2008 Michael Buesch <m@bues.ch>
7 *
8 * Licensed under the GNU/GPL. See COPYING for details.
9 */
10
11#include "ssb_private.h"
12
11#include <linux/ssb/ssb.h>
12#include <linux/delay.h>
13#include <linux/io.h>
14#include <linux/etherdevice.h>
15
16#include <pcmcia/cistpl.h>
17#include <pcmcia/ciscode.h>
18#include <pcmcia/ds.h>
19#include <pcmcia/cisreg.h>
20
13#include <linux/ssb/ssb.h>
14#include <linux/delay.h>
15#include <linux/io.h>
16#include <linux/etherdevice.h>
17
18#include <pcmcia/cistpl.h>
19#include <pcmcia/ciscode.h>
20#include <pcmcia/ds.h>
21#include <pcmcia/cisreg.h>
22
21#include "ssb_private.h"
22
23
23
24/* Define the following to 1 to enable a printk on each coreswitch. */
25#define SSB_VERBOSE_PCMCIACORESWITCH_DEBUG 0
26
27
28/* PCMCIA configuration registers */
29#define SSB_PCMCIA_ADDRESS0 0x2E
30#define SSB_PCMCIA_ADDRESS1 0x30
31#define SSB_PCMCIA_ADDRESS2 0x32

--- 106 unchanged lines hidden (view full) ---

138 err = -ETIMEDOUT;
139 if (attempts++ > SSB_BAR0_MAX_RETRIES)
140 goto error;
141 udelay(10);
142 }
143
144 return 0;
145error:
24/* Define the following to 1 to enable a printk on each coreswitch. */
25#define SSB_VERBOSE_PCMCIACORESWITCH_DEBUG 0
26
27
28/* PCMCIA configuration registers */
29#define SSB_PCMCIA_ADDRESS0 0x2E
30#define SSB_PCMCIA_ADDRESS1 0x30
31#define SSB_PCMCIA_ADDRESS2 0x32

--- 106 unchanged lines hidden (view full) ---

138 err = -ETIMEDOUT;
139 if (attempts++ > SSB_BAR0_MAX_RETRIES)
140 goto error;
141 udelay(10);
142 }
143
144 return 0;
145error:
146 ssb_err("Failed to switch to core %u\n", coreidx);
146 pr_err("Failed to switch to core %u\n", coreidx);
147 return err;
148}
149
150static int ssb_pcmcia_switch_core(struct ssb_bus *bus, struct ssb_device *dev)
151{
152 int err;
153
154#if SSB_VERBOSE_PCMCIACORESWITCH_DEBUG
147 return err;
148}
149
150static int ssb_pcmcia_switch_core(struct ssb_bus *bus, struct ssb_device *dev)
151{
152 int err;
153
154#if SSB_VERBOSE_PCMCIACORESWITCH_DEBUG
155 ssb_info("Switching to %s core, index %d\n",
156 ssb_core_name(dev->id.coreid),
157 dev->core_index);
155 pr_info("Switching to %s core, index %d\n",
156 ssb_core_name(dev->id.coreid), dev->core_index);
158#endif
159
160 err = ssb_pcmcia_switch_coreidx(bus, dev->core_index);
161 if (!err)
162 bus->mapped_device = dev;
163
164 return err;
165}

--- 19 unchanged lines hidden (view full) ---

185 if (unlikely(attempts++ > SSB_BAR0_MAX_RETRIES))
186 goto error;
187 udelay(10);
188 }
189 bus->mapped_pcmcia_seg = seg;
190
191 return 0;
192error:
157#endif
158
159 err = ssb_pcmcia_switch_coreidx(bus, dev->core_index);
160 if (!err)
161 bus->mapped_device = dev;
162
163 return err;
164}

--- 19 unchanged lines hidden (view full) ---

184 if (unlikely(attempts++ > SSB_BAR0_MAX_RETRIES))
185 goto error;
186 udelay(10);
187 }
188 bus->mapped_pcmcia_seg = seg;
189
190 return 0;
191error:
193 ssb_err("Failed to switch pcmcia segment\n");
192 pr_err("Failed to switch pcmcia segment\n");
194 return err;
195}
196
197static int select_core_and_segment(struct ssb_device *dev,
198 u16 *offset)
199{
200 struct ssb_bus *bus = dev->bus;
201 int err;

--- 340 unchanged lines hidden (view full) ---

542
543/* Write the SPROM image. size is in 16bit words. */
544static int ssb_pcmcia_sprom_write_all(struct ssb_bus *bus, const u16 *sprom)
545{
546 int i, err;
547 bool failed = 0;
548 size_t size = SSB_PCMCIA_SPROM_SIZE;
549
193 return err;
194}
195
196static int select_core_and_segment(struct ssb_device *dev,
197 u16 *offset)
198{
199 struct ssb_bus *bus = dev->bus;
200 int err;

--- 340 unchanged lines hidden (view full) ---

541
542/* Write the SPROM image. size is in 16bit words. */
543static int ssb_pcmcia_sprom_write_all(struct ssb_bus *bus, const u16 *sprom)
544{
545 int i, err;
546 bool failed = 0;
547 size_t size = SSB_PCMCIA_SPROM_SIZE;
548
550 ssb_notice("Writing SPROM. Do NOT turn off the power! Please stand by...\n");
549 pr_notice("Writing SPROM. Do NOT turn off the power! Please stand by...\n");
551 err = ssb_pcmcia_sprom_command(bus, SSB_PCMCIA_SPROMCTL_WRITEEN);
552 if (err) {
550 err = ssb_pcmcia_sprom_command(bus, SSB_PCMCIA_SPROMCTL_WRITEEN);
551 if (err) {
553 ssb_notice("Could not enable SPROM write access\n");
552 pr_notice("Could not enable SPROM write access\n");
554 return -EBUSY;
555 }
553 return -EBUSY;
554 }
556 ssb_notice("[ 0%%");
555 pr_notice("[ 0%%");
557 msleep(500);
558 for (i = 0; i < size; i++) {
559 if (i == size / 4)
556 msleep(500);
557 for (i = 0; i < size; i++) {
558 if (i == size / 4)
560 ssb_cont("25%%");
559 pr_cont("25%%");
561 else if (i == size / 2)
560 else if (i == size / 2)
562 ssb_cont("50%%");
561 pr_cont("50%%");
563 else if (i == (size * 3) / 4)
562 else if (i == (size * 3) / 4)
564 ssb_cont("75%%");
563 pr_cont("75%%");
565 else if (i % 2)
564 else if (i % 2)
566 ssb_cont(".");
565 pr_cont(".");
567 err = ssb_pcmcia_sprom_write(bus, i, sprom[i]);
568 if (err) {
566 err = ssb_pcmcia_sprom_write(bus, i, sprom[i]);
567 if (err) {
569 ssb_notice("Failed to write to SPROM\n");
568 pr_notice("Failed to write to SPROM\n");
570 failed = 1;
571 break;
572 }
573 }
574 err = ssb_pcmcia_sprom_command(bus, SSB_PCMCIA_SPROMCTL_WRITEDIS);
575 if (err) {
569 failed = 1;
570 break;
571 }
572 }
573 err = ssb_pcmcia_sprom_command(bus, SSB_PCMCIA_SPROMCTL_WRITEDIS);
574 if (err) {
576 ssb_notice("Could not disable SPROM write access\n");
575 pr_notice("Could not disable SPROM write access\n");
577 failed = 1;
578 }
579 msleep(500);
580 if (!failed) {
576 failed = 1;
577 }
578 msleep(500);
579 if (!failed) {
581 ssb_cont("100%% ]\n");
582 ssb_notice("SPROM written\n");
580 pr_cont("100%% ]\n");
581 pr_notice("SPROM written\n");
583 }
584
585 return failed ? -EBUSY : 0;
586}
587
588static int ssb_pcmcia_sprom_check_crc(const u16 *sprom, size_t size)
589{
590 //TODO

--- 97 unchanged lines hidden (view full) ---

688 sprom->gpio1 = tuple->TupleData[2];
689 sprom->gpio2 = tuple->TupleData[3];
690 sprom->gpio3 = tuple->TupleData[4];
691 break;
692 }
693 return -ENOSPC; /* continue with next entry */
694
695error:
582 }
583
584 return failed ? -EBUSY : 0;
585}
586
587static int ssb_pcmcia_sprom_check_crc(const u16 *sprom, size_t size)
588{
589 //TODO

--- 97 unchanged lines hidden (view full) ---

687 sprom->gpio1 = tuple->TupleData[2];
688 sprom->gpio2 = tuple->TupleData[3];
689 sprom->gpio3 = tuple->TupleData[4];
690 break;
691 }
692 return -ENOSPC; /* continue with next entry */
693
694error:
696 ssb_err(
697 "PCMCIA: Failed to fetch device invariants: %s\n",
698 error_description);
695 pr_err("PCMCIA: Failed to fetch device invariants: %s\n",
696 error_description);
699 return -ENODEV;
700}
701
702
703int ssb_pcmcia_get_invariants(struct ssb_bus *bus,
704 struct ssb_init_invariants *iv)
705{
706 struct ssb_sprom *sprom = &iv->sprom;
707 int res;
708
709 memset(sprom, 0xFF, sizeof(*sprom));
710 sprom->revision = 1;
711 sprom->boardflags_lo = 0;
712 sprom->boardflags_hi = 0;
713
714 /* First fetch the MAC address. */
715 res = pcmcia_loop_tuple(bus->host_pcmcia, CISTPL_FUNCE,
716 ssb_pcmcia_get_mac, sprom);
717 if (res != 0) {
697 return -ENODEV;
698}
699
700
701int ssb_pcmcia_get_invariants(struct ssb_bus *bus,
702 struct ssb_init_invariants *iv)
703{
704 struct ssb_sprom *sprom = &iv->sprom;
705 int res;
706
707 memset(sprom, 0xFF, sizeof(*sprom));
708 sprom->revision = 1;
709 sprom->boardflags_lo = 0;
710 sprom->boardflags_hi = 0;
711
712 /* First fetch the MAC address. */
713 res = pcmcia_loop_tuple(bus->host_pcmcia, CISTPL_FUNCE,
714 ssb_pcmcia_get_mac, sprom);
715 if (res != 0) {
718 ssb_err(
719 "PCMCIA: Failed to fetch MAC address\n");
716 pr_err("PCMCIA: Failed to fetch MAC address\n");
720 return -ENODEV;
721 }
722
723 /* Fetch the vendor specific tuples. */
724 res = pcmcia_loop_tuple(bus->host_pcmcia, SSB_PCMCIA_CIS,
725 ssb_pcmcia_do_get_invariants, iv);
726 if ((res == 0) || (res == -ENOSPC))
727 return 0;
728
717 return -ENODEV;
718 }
719
720 /* Fetch the vendor specific tuples. */
721 res = pcmcia_loop_tuple(bus->host_pcmcia, SSB_PCMCIA_CIS,
722 ssb_pcmcia_do_get_invariants, iv);
723 if ((res == 0) || (res == -ENOSPC))
724 return 0;
725
729 ssb_err(
730 "PCMCIA: Failed to fetch device invariants\n");
726 pr_err("PCMCIA: Failed to fetch device invariants\n");
731 return -ENODEV;
732}
733
734static ssize_t ssb_pcmcia_attr_sprom_show(struct device *pcmciadev,
735 struct device_attribute *attr,
736 char *buf)
737{
738 struct pcmcia_device *pdev =

--- 92 unchanged lines hidden (view full) ---

831 bus->sprom_size = SSB_PCMCIA_SPROM_SIZE;
832 mutex_init(&bus->sprom_mutex);
833 err = device_create_file(&bus->host_pcmcia->dev, &dev_attr_ssb_sprom);
834 if (err)
835 goto error;
836
837 return 0;
838error:
727 return -ENODEV;
728}
729
730static ssize_t ssb_pcmcia_attr_sprom_show(struct device *pcmciadev,
731 struct device_attribute *attr,
732 char *buf)
733{
734 struct pcmcia_device *pdev =

--- 92 unchanged lines hidden (view full) ---

827 bus->sprom_size = SSB_PCMCIA_SPROM_SIZE;
828 mutex_init(&bus->sprom_mutex);
829 err = device_create_file(&bus->host_pcmcia->dev, &dev_attr_ssb_sprom);
830 if (err)
831 goto error;
832
833 return 0;
834error:
839 ssb_err("Failed to initialize PCMCIA host device\n");
835 pr_err("Failed to initialize PCMCIA host device\n");
840 return err;
841}
836 return err;
837}